aboutsummaryrefslogtreecommitdiff
path: root/internal/bible
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-07-24 10:47:48 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-07-24 10:47:48 +0200
commite50b003d84b091b60c8028468edc633f04e39731 (patch)
treef68b4efc14b133bacd571550d86869aa450cf97d /internal/bible
parentc9f3bf46f0de09edb796e35f3dcff349febf75c9 (diff)
downloadlectio-e50b003d84b091b60c8028468edc633f04e39731.tar.gz
lectio-e50b003d84b091b60c8028468edc633f04e39731.zip
bible-lookup: add --ref passage lookup + --list-pl/--list-en book lists; v0.6.0
Diffstat (limited to 'internal/bible')
-rw-r--r--internal/bible/books.go45
-rw-r--r--internal/bible/books_test.go40
2 files changed, 85 insertions, 0 deletions
diff --git a/internal/bible/books.go b/internal/bible/books.go
index 045509a..f3af4af 100644
--- a/internal/bible/books.go
+++ b/internal/bible/books.go
@@ -112,3 +112,48 @@ func ResolveBook(query string) (string, bool) {
}
return "", false
}
+
+// canonOrder lists every aliasSeed book in scriptural (Catholic canon) order:
+// 46 Old Testament books then 27 New Testament. It is the ONLY hand-maintained
+// ordering; the display names are still derived from aliasSeed so there is one
+// source of truth for spellings. A test asserts canonOrder and aliasSeed hold
+// exactly the same set.
+var canonOrder = []string{
+ // Old Testament
+ "Genesis", "Exodus", "Leviticus", "Numbers", "Deuteronomy",
+ "Joshua", "Judges", "Ruth", "1 Samuel", "2 Samuel",
+ "1 Kings", "2 Kings", "1 Chronicles", "2 Chronicles", "Ezra",
+ "Nehemiah", "Tobit", "Judith", "Esther", "1 Maccabees",
+ "2 Maccabees", "Job", "Psalms", "Proverbs", "Ecclesiastes",
+ "Song of Solomon", "Wisdom", "Sirach", "Isaiah", "Jeremiah",
+ "Lamentations", "Baruch", "Ezekiel", "Daniel", "Hosea",
+ "Joel", "Amos", "Obadiah", "Jonah", "Micah",
+ "Nahum", "Habakkuk", "Zephaniah", "Haggai", "Zechariah",
+ "Malachi",
+ // New Testament
+ "Matthew", "Mark", "Luke", "John", "The Acts",
+ "Romans", "1 Corinthians", "2 Corinthians", "Galatians", "Ephesians",
+ "Philippians", "Colossians", "1 Thessalonians", "2 Thessalonians", "1 Timothy",
+ "2 Timothy", "Titus", "Philemon", "Hebrews", "James",
+ "1 Peter", "2 Peter", "1 John", "2 John", "3 John",
+ "Jude", "Revelation",
+}
+
+// BookInfo is one Biblical book's display data for the --list-pl/--list-en
+// commands (and, in later phases, the reader book pickers).
+type BookInfo struct {
+ English string // canonical English name, e.g. "John" (the aliasSeed key)
+ Polish string // Polish name, e.g. "Jan" (aliasSeed value [1])
+ Abbrev string // Polish citation abbreviation, e.g. "J" (aliasSeed value [0])
+}
+
+// Books returns every Biblical book in scriptural order with its English name,
+// Polish name and citation abbreviation, all derived from aliasSeed.
+func Books() []BookInfo {
+ out := make([]BookInfo, 0, len(canonOrder))
+ for _, name := range canonOrder {
+ a := aliasSeed[name]
+ out = append(out, BookInfo{English: name, Polish: a[1], Abbrev: a[0]})
+ }
+ return out
+}
diff --git a/internal/bible/books_test.go b/internal/bible/books_test.go
index 43a67cf..e1a65ca 100644
--- a/internal/bible/books_test.go
+++ b/internal/bible/books_test.go
@@ -24,3 +24,43 @@ func TestResolveBook(t *testing.T) {
t.Error("ResolveBook(Nonsense) should fail")
}
}
+
+func TestBooksTableIntegrity(t *testing.T) {
+ if len(canonOrder) != len(aliasSeed) {
+ t.Fatalf("canonOrder has %d names, aliasSeed has %d", len(canonOrder), len(aliasSeed))
+ }
+ seen := map[string]bool{}
+ for _, name := range canonOrder {
+ if seen[name] {
+ t.Errorf("canonOrder duplicate %q", name)
+ }
+ seen[name] = true
+ a, ok := aliasSeed[name]
+ if !ok {
+ t.Errorf("canonOrder name %q missing from aliasSeed", name)
+ continue
+ }
+ if len(a) < 2 {
+ t.Errorf("book %q has %d aliases, need >=2 (abbrev, pl-name)", name, len(a))
+ }
+ }
+ for name := range aliasSeed {
+ if !seen[name] {
+ t.Errorf("aliasSeed name %q missing from canonOrder", name)
+ }
+ }
+}
+
+func TestBooksResolve(t *testing.T) {
+ for _, b := range Books() {
+ if b.English == "" || b.Polish == "" || b.Abbrev == "" {
+ t.Errorf("incomplete BookInfo %+v", b)
+ }
+ if c, ok := ResolveBook(b.Abbrev); !ok || c != b.English {
+ t.Errorf("abbrev %q resolved to (%q,%v), want %q", b.Abbrev, c, ok, b.English)
+ }
+ }
+ if got := len(Books()); got != 73 {
+ t.Errorf("Books() len = %d, want 73", got)
+ }
+}