diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-07-27 14:59:14 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-07-27 14:59:14 +0200 |
| commit | cb3379f41c06a94085c77fe359709b46712850dc (patch) | |
| tree | 032801111764c83c3ab089ed101ba4d1222a9abd /internal/bible | |
| parent | a13dd6224a095242da54062e4775570c4f16a718 (diff) | |
| download | lectio-cb3379f41c06a94085c77fe359709b46712850dc.tar.gz lectio-cb3379f41c06a94085c77fe359709b46712850dc.zip | |
feat: books.toml -> books.ini, multi-language (add Latin dialect), config-scoped citation display
books.ini with [en]/[pl]/[la]; parseBooks reads INI (bible drops go-toml).
Latin dialect resolves EF citations (Eccli->Sirach, Apoc->Revelation, Luc...);
sigla_style gains 'latin'. Reading citations now DISPLAY in the configured
sigla (FormatRef(SiglaLang)), not raw English. One-shot books.toml->books.ini
user migration (go-toml now config-only). Web settings editor -> books.ini.
Diffstat (limited to 'internal/bible')
| -rw-r--r-- | internal/bible/books.ini | 243 | ||||
| -rw-r--r-- | internal/bible/booktable.go | 46 | ||||
| -rw-r--r-- | internal/bible/booktable_test.go | 10 |
3 files changed, 277 insertions, 22 deletions
diff --git a/internal/bible/books.ini b/internal/bible/books.ini new file mode 100644 index 0000000..5d8f633 --- /dev/null +++ b/internal/bible/books.ini @@ -0,0 +1,243 @@ +# lectio book names & abbreviations, per dialect (en, pl, la). +# +# This is the built-in default, embedded in the binary. To customise, copy any +# lines you want to change into ~/.config/lectio/books.ini (next to config.ini). +# Your file is MERGED over these defaults per book: you only list the books you +# want to change; every book you don't mention keeps the default below. +# +# Each entry is a flat list of forms for one book, in ONE language: +# - the FIRST form is the shortcut shown by `lectio --list` +# - the LAST form is the full name shown by `lectio --list` +# - EVERY form (first, last, and any in between) resolves in `lectio --ref` +# Resolution is language-scoped and idiomatic: in English mode only the [en] +# forms resolve (so "Jn" works, "Łk" does not); in Polish mode only [pl]. +# +# The table KEY is the book's English canonical name -- it must match the Bible +# corpus, so do not change the keys, only the forms. Books appear in `--list` +# in scriptural order regardless of the order here. + +[en] +Genesis = Gen, Genesis +Exodus = Exod, Exodus +Leviticus = Lev, Leviticus +Numbers = Num, Numbers +Deuteronomy = Deut, Deuteronomy +Joshua = Josh, Joshua +Judges = Judg, Judges +Ruth = Ru, Ruth +1 Samuel = 1 Sam, 1 Samuel +2 Samuel = 2 Sam, 2 Samuel +1 Kings = 1 Kgs, 1 Kings +2 Kings = 2 Kgs, 2 Kings +1 Chronicles = 1 Chr, 1 Chronicles +2 Chronicles = 2 Chr, 2 Chronicles +Ezra = Ezra, Ezra +Nehemiah = Neh, Nehemiah +Tobit = Tob, Tobit +Judith = Jdt, Judith +Esther = Esth, Esther +1 Maccabees = 1 Macc, 1 Maccabees +2 Maccabees = 2 Macc, 2 Maccabees +Job = Jb, Job +Psalms = Ps, Psalm, Psalms +Proverbs = Prov, Proverbs +Ecclesiastes = Eccl, Ecclesiastes +Song of Solomon = Song, Song of Songs +Wisdom = Wis, Wisdom +Sirach = Sir, Ecclus, Eccli, Ecclesiasticus, Sirach +Isaiah = Isa, Isaiah +Jeremiah = Jer, Jeremiah +Lamentations = Lam, Lamentations +Baruch = Bar, Baruch +Ezekiel = Ezek, Ezekiel +Daniel = Dan, Daniel +Hosea = Hos, Hosea +Joel = Jl, Joel +Amos = Am, Amos +Obadiah = Obad, Obadiah +Jonah = Jon, Jonah +Micah = Mic, Micah +Nahum = Nah, Nahum +Habakkuk = Hab, Habakkuk +Zephaniah = Zeph, Zephaniah +Haggai = Hag, Haggai +Zechariah = Zech, Zechariah +Malachi = Mal, Malachi +Matthew = Matt, Matthew +Mark = Mk, Mark +Luke = Lk, Luke +John = Jn, John +The Acts = Acts, Acts +Romans = Rom, Romans +1 Corinthians = 1 Cor, 1 Corinthians +2 Corinthians = 2 Cor, 2 Corinthians +Galatians = Gal, Galatians +Ephesians = Eph, Ephesians +Philippians = Phil, Philippians +Colossians = Col, Colossians +1 Thessalonians = 1 Thess, 1 Thessalonians +2 Thessalonians = 2 Thess, 2 Thessalonians +1 Timothy = 1 Tim, 1 Timothy +2 Timothy = 2 Tim, 2 Timothy +Titus = Ti, Titus +Philemon = Phlm, Philemon +Hebrews = Heb, Hebrews +James = Jas, James +1 Peter = 1 Pet, 1 Peter +2 Peter = 2 Pet, 2 Peter +1 John = 1 Jn, 1 John +2 John = 2 Jn, 2 John +3 John = 3 Jn, 3 John +Jude = Jude, Jude +Revelation = Rev, Apoc, Apocalypse, Revelation + +[pl] +Genesis = Rdz, Rodzaju +Exodus = Wj, Wyjścia +Leviticus = Kpł, Kapłańska +Numbers = Lb, Liczb +Deuteronomy = Pwt, Powtórzonego Prawa +Joshua = Joz, Jozuego +Judges = Sdz, Sędziów +Ruth = Rt, Rut +1 Samuel = 1 Sm, 1 Samuela +2 Samuel = 2 Sm, 2 Samuela +1 Kings = 1 Krl, 1 Królewska +2 Kings = 2 Krl, 2 Królewska +1 Chronicles = 1 Krn, 1 Kronik +2 Chronicles = 2 Krn, 2 Kronik +Ezra = Ezd, Ezdrasza +Nehemiah = Ne, Nehemiasza +Tobit = Tb, Tobiasza +Judith = Jdt, Judyty +Esther = Est, Estery +1 Maccabees = 1 Mch, 1 Machabejska +2 Maccabees = 2 Mch, 2 Machabejska +Job = Hi, Hioba +Psalms = Ps, Psalm, Psalmy +Proverbs = Prz, Przysłów +Ecclesiastes = Koh, Koheleta +Song of Solomon = Pnp, Pieśń nad Pieśniami +Wisdom = Mdr, Mądrości +Sirach = Syr, Syracha +Isaiah = Iz, Izajasza +Jeremiah = Jr, Jeremiasza +Lamentations = Lm, Lamentacje +Baruch = Ba, Barucha +Ezekiel = Ez, Ezechiela +Daniel = Dn, Daniela +Hosea = Oz, Ozeasza +Joel = Jl, Joela +Amos = Am, Amosa +Obadiah = Ab, Abdiasza +Jonah = Jon, Jonasza +Micah = Mi, Micheasza +Nahum = Na, Nahuma +Habakkuk = Ha, Habakuka +Zephaniah = So, Sofoniasza +Haggai = Ag, Aggeusza +Zechariah = Za, Zachariasza +Malachi = Ml, Malachiasza +Matthew = Mt, Mateusza +Mark = Mk, Marka +Luke = Łk, Łukasza +John = J, Jana +The Acts = Dz, Dzieje Apostolskie +Romans = Rz, Rzymian +1 Corinthians = 1 Kor, 1 Koryntian +2 Corinthians = 2 Kor, 2 Koryntian +Galatians = Ga, Galatów +Ephesians = Ef, Efezjan +Philippians = Flp, Filipian +Colossians = Kol, Kolosan +1 Thessalonians = 1 Tes, 1 Tesaloniczan +2 Thessalonians = 2 Tes, 2 Tesaloniczan +1 Timothy = 1 Tm, 1 Tymoteusza +2 Timothy = 2 Tm, 2 Tymoteusza +Titus = Tt, Tytusa +Philemon = Flm, Filemona +Hebrews = Hbr, Hebrajczyków +James = Jk, Jakuba +1 Peter = 1 P, 1 Piotra +2 Peter = 2 P, 2 Piotra +1 John = 1 J, 1 Jana +2 John = 2 J, 2 Jana +3 John = 3 J, 3 Jana +Jude = Jud, Judy +Revelation = Ap, Apokalipsa + +# Latin (Vulgate) — book names/abbreviations for EF citations and Latin sigla. +[la] +Genesis = Gen, Genesis +Exodus = Ex, Exodus +Leviticus = Lev, Leviticus +Numbers = Num, Numeri +Deuteronomy = Deut, Deuteronomium +Joshua = Ios, Iosue +Judges = Idc, Iudicum +Ruth = Ruth +1 Samuel = 1 Reg, 1 Sam, 1 Samuelis, 1 Regum +2 Samuel = 2 Reg, 2 Sam, 2 Samuelis, 2 Regum +1 Kings = 3 Reg, 3 Regum +2 Kings = 4 Reg, 4 Regum +1 Chronicles = 1 Par, 1 Paralipomenon +2 Chronicles = 2 Par, 2 Paralipomenon +Ezra = Esd, 1 Esdrae, Esdrae +Nehemiah = Neh, 2 Esd, Nehemiae +Tobit = Tob, Tobiae, Tobias +Judith = Idt, Iudith +Esther = Esth, Esther +1 Maccabees = 1 Mac, 1 Machabaeorum +2 Maccabees = 2 Mac, 2 Machabaeorum +Job = Iob +Psalms = Ps, Psalmi +Proverbs = Prov, Proverbia +Ecclesiastes = Eccle, Ecclesiastes +Song of Solomon = Cant, Canticum, Canticum Canticorum +Wisdom = Sap, Sapientia +Sirach = Eccli, Ecclus, Sir, Ecclesiasticus +Isaiah = Is, Isaias +Jeremiah = Ier, Ieremias +Lamentations = Lam, Threni, Lamentationes +Baruch = Bar, Baruch +Ezekiel = Ez, Ezechiel +Daniel = Dan, Daniel +Hosea = Os, Osee +Joel = Ioel +Amos = Am, Amos +Obadiah = Abd, Abdias +Jonah = Ion, Ionas +Micah = Mich, Michaeas +Nahum = Nah, Nahum +Habakkuk = Hab, Habacuc +Zephaniah = Soph, Sophonias +Haggai = Agg, Aggaeus +Zechariah = Zach, Zacharias +Malachi = Mal, Malachias +Matthew = Matt, Matthaeus +Mark = Marc, Marcus +Luke = Luc, Lucas +John = Ioann, Ioannes +The Acts = Act, Actus, Actus Apostolorum +Romans = Rom, Romanos +1 Corinthians = 1 Cor, 1 Corinthios +2 Corinthians = 2 Cor, 2 Corinthios +Galatians = Gal, Galatas +Ephesians = Eph, Ephesios +Philippians = Phil, Philippenses +Colossians = Col, Colossenses +1 Thessalonians = 1 Thess, 1 Thessalonicenses +2 Thessalonians = 2 Thess, 2 Thessalonicenses +1 Timothy = 1 Tim, 1 Timotheum +2 Timothy = 2 Tim, 2 Timotheum +Titus = Tit, Titum +Philemon = Philem, Philemonem +Hebrews = Hebr, Hebraeos +James = Iac, Iacobi +1 Peter = 1 Pet, 1 Petri +2 Peter = 2 Pet, 2 Petri +1 John = 1 Ioann, 1 Ioannis +2 John = 2 Ioann, 2 Ioannis +3 John = 3 Ioann, 3 Ioannis +Jude = Iud, Iudae +Revelation = Apoc, Apocalypsis diff --git a/internal/bible/booktable.go b/internal/bible/booktable.go index ac7ea95..ae005a5 100644 --- a/internal/bible/booktable.go +++ b/internal/bible/booktable.go @@ -6,13 +6,13 @@ import ( "sort" "strings" - "github.com/pelletier/go-toml/v2" + "github.com/lukaszkasprzak/lectio/internal/ini" ) -// booksFS embeds the built-in default book table (names + abbreviations per UI -// language). Users override it per book via ~/.config/lectio/books.toml. +// booksFS embeds the built-in default book table (names + abbreviations per +// dialect: en/pl/la). Users override it per book via ~/.config/lectio/books.ini. // -//go:embed books.toml +//go:embed books.ini var booksFS embed.FS // BookInfo is one book's display data in one dialect, for `lectio --list` and @@ -23,8 +23,8 @@ type BookInfo struct { Shortcut string // primary abbreviation in the dialect, e.g. "Jn" / "J" } -// BookTable resolves book references and lists books per "dialect" -- a books.toml -// section, keyed by the same codes as the UI languages ("en"/"pl"). It is built +// BookTable resolves book references and lists books per "dialect" -- a books.ini +// section, keyed by dialect ("en"/"pl"/"la"). It is built // from the embedded default merged with an optional user override. type BookTable struct { forms map[string]map[string][]string // dialect -> canonical -> forms (first=shortcut, last=name) @@ -38,16 +38,16 @@ type BookTable struct { // It always returns a usable table; a non-nil error means userTOML was present // but unparseable (the returned table is defaults-only, so callers can warn and // proceed). -func LoadBookTable(userTOML []byte) (*BookTable, error) { +func LoadBookTable(userINI []byte) (*BookTable, error) { def, err := parseBooks(mustReadEmbedded()) if err != nil { - return nil, fmt.Errorf("embedded books.toml: %w", err) // our bug, not the user's + return nil, fmt.Errorf("embedded books.ini: %w", err) // our bug, not the user's } var uerr error - if len(strings.TrimSpace(string(userTOML))) > 0 { - user, perr := parseBooks(userTOML) + if len(strings.TrimSpace(string(userINI))) > 0 { + user, perr := parseBooks(userINI) if perr != nil { - uerr = fmt.Errorf("ignoring malformed books.toml: %w", perr) + uerr = fmt.Errorf("ignoring malformed books.ini: %w", perr) } else { for dialect, books := range user { if def[dialect] == nil { @@ -84,20 +84,32 @@ func LoadBookTable(userTOML []byte) (*BookTable, error) { } func mustReadEmbedded() []byte { - b, _ := booksFS.ReadFile("books.toml") // embedded: always present + b, _ := booksFS.ReadFile("books.ini") // embedded: always present return b } -// DefaultBooksTOML returns the embedded default books.toml (the seed the +// DefaultBooksTOML returns the embedded default books.ini (the seed the // /settings editor shows when the user has no override yet). -func DefaultBooksTOML() []byte { return mustReadEmbedded() } +func DefaultBooksINI() []byte { return mustReadEmbedded() } func parseBooks(data []byte) (map[string]map[string][]string, error) { - var raw map[string]map[string][]string - if err := toml.Unmarshal(data, &raw); err != nil { + secs, err := ini.Parse(data) + if err != nil { return nil, err } - return raw, nil + out := map[string]map[string][]string{} + for _, s := range secs { + if s.Name == "" { // no top-level pairs in the book table + continue + } + if out[s.Name] == nil { + out[s.Name] = map[string][]string{} + } + for _, p := range s.Pairs { + out[s.Name][p.Key] = ini.List(p.Val) + } + } + return out, nil } // Books returns every book of the dialect in scriptural (canonOrder) order. diff --git a/internal/bible/booktable_test.go b/internal/bible/booktable_test.go index 2a57d80..2fdd891 100644 --- a/internal/bible/booktable_test.go +++ b/internal/bible/booktable_test.go @@ -97,7 +97,7 @@ func TestFormatRef(t *testing.T) { func TestBookTableMergeAndMalformed(t *testing.T) { // User adds an alias "Jhn" to English John; other books stay default. - user := []byte("[en]\nJohn = [\"Jn\", \"Jhn\", \"John\"]\n") + user := []byte("[en]\nJohn = Jn, Jhn, John\n") tbl, err := LoadBookTable(user) if err != nil { t.Fatalf("merge err: %v", err) @@ -108,12 +108,12 @@ func TestBookTableMergeAndMalformed(t *testing.T) { if got, ok := tbl.ParseRef("en", "Gen 1:1"); !ok || got != "Genesis 1:1" { t.Errorf("unlisted book lost after merge: %q,%v", got, ok) } - // Malformed user TOML -> non-nil error but a usable defaults table. - tbl2, err := LoadBookTable([]byte("this is not [valid toml")) + // Malformed user INI -> non-nil error but a usable defaults table. + tbl2, err := LoadBookTable([]byte("this is not valid ini")) if err == nil { - t.Error("expected error for malformed user toml") + t.Error("expected error for malformed user ini") } if got, ok := tbl2.ParseRef("en", "Jn 3:16"); !ok || got != "John 3:16" { - t.Errorf("defaults unusable after malformed user toml: %q,%v", got, ok) + t.Errorf("defaults unusable after malformed user ini: %q,%v", got, ok) } } |
