From 998e0d5bb2aa4412ca05d28f27592ae54727e2ba Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Thu, 23 Jul 2026 12:49:21 +0200 Subject: bible: embed corpora + chapter lookup --- internal/bible/bible.go | 60 ++++++++++++++++++++++++++++++++++++++++++++ internal/bible/bible_test.go | 30 ++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 internal/bible/bible.go create mode 100644 internal/bible/bible_test.go (limited to 'internal/bible') diff --git a/internal/bible/bible.go b/internal/bible/bible.go new file mode 100644 index 0000000..0254ceb --- /dev/null +++ b/internal/bible/bible.go @@ -0,0 +1,60 @@ +package bible + +import ( + "embed" + "strconv" + "strings" + "sync" +) + +//go:embed corpora/wuj.tsv corpora/vul.tsv corpora/grb.tsv corpora/drb.tsv +var corporaFS embed.FS + +// Verse is a single verse. +type Verse struct { + Chapter, Verse int + Text string +} + +type corpus struct { + books map[string]map[int][]Verse // book -> chapter -> verses (verse-ordered) +} + +var ( + corpora = map[string]*corpus{} + corporaMu sync.Mutex +) + +func load(version string) *corpus { + corporaMu.Lock() + defer corporaMu.Unlock() + if c, ok := corpora[version]; ok { + return c + } + data, err := corporaFS.ReadFile("corpora/" + version + ".tsv") + if err != nil { + corpora[version] = &corpus{books: map[string]map[int][]Verse{}} + return corpora[version] + } + c := &corpus{books: map[string]map[int][]Verse{}} + for _, line := range strings.Split(string(data), "\n") { + f := strings.Split(line, "\t") + if len(f) != 6 { + continue + } + chap, _ := strconv.Atoi(f[3]) + vn, _ := strconv.Atoi(f[4]) + book := f[0] + if c.books[book] == nil { + c.books[book] = map[int][]Verse{} + } + c.books[book][chap] = append(c.books[book][chap], Verse{chap, vn, f[5]}) + } + corpora[version] = c + return c +} + +// Verses returns all verses of one chapter of a book in a version (may be empty). +func Verses(version, book string, chap int) []Verse { + return load(version).books[book][chap] +} diff --git a/internal/bible/bible_test.go b/internal/bible/bible_test.go new file mode 100644 index 0000000..efd22d6 --- /dev/null +++ b/internal/bible/bible_test.go @@ -0,0 +1,30 @@ +package bible + +import "testing" + +func TestVerses(t *testing.T) { + cases := []struct { + version, book string + chap, verse int + wantPrefix string + }{ + {"wuj", "Genesis", 1, 1, "Na początku stworzył Bóg"}, + {"vul", "Genesis", 1, 1, "In principio creavit Deus"}, + {"drb", "John", 20, 1, "AND on the first day of the week"}, + {"wuj", "Wisdom", 3, 1, "A dusze sprawiedliwych"}, // deuterocanonical + } + for _, c := range cases { + vs := Verses(c.version, c.book, c.chap) + var got string + for _, v := range vs { + if v.Verse == c.verse { + got = v.Text + } + } + if !hasPrefix(got, c.wantPrefix) { + t.Errorf("%s %s %d:%d = %q want prefix %q", c.version, c.book, c.chap, c.verse, got, c.wantPrefix) + } + } +} + +func hasPrefix(s, p string) bool { return len(s) >= len(p) && s[:len(p)] == p } -- cgit v1.3