aboutsummaryrefslogtreecommitdiff
path: root/internal/bible/bible.go
blob: 0254cebaf9e28ff0a4948902abdde4cc97dad737 (plain) (blame)
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
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]
}