1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
package bible
import (
"embed"
"sort"
"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]
}
// Chapters returns the chapter numbers present for a book in a version, sorted
// ascending (empty if the version has no such book).
func Chapters(version, book string) []int {
chapMap := load(version).books[book]
chaps := make([]int, 0, len(chapMap))
for ch := range chapMap {
chaps = append(chaps, ch)
}
sort.Ints(chaps)
return chaps
}
|