diff options
Diffstat (limited to 'internal/bible/ref.go')
| -rw-r--r-- | internal/bible/ref.go | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/internal/bible/ref.go b/internal/bible/ref.go new file mode 100644 index 0000000..c88e722 --- /dev/null +++ b/internal/bible/ref.go @@ -0,0 +1,78 @@ +package bible + +import ( + "regexp" + "strconv" + "strings" +) + +var refRe = regexp.MustCompile(`^(.*?)\s+(\d+):(.+)$`) + +// SplitRef splits a ref whose verse list mixes single verses and ranges into +// one ref per group (the kjv tools reject a mixed list in a single query). +func SplitRef(ref string) []string { + m := refRe.FindStringSubmatch(ref) + if m == nil { + return []string{ref} + } + book, chap, verses := m[1], m[2], m[3] + if !strings.Contains(verses, ",") { + return []string{ref} + } + var out []string + for _, g := range strings.Split(verses, ",") { + g = strings.TrimSpace(g) + if g == "" { + continue + } + if strings.Contains(g, ":") { + out = append(out, book+" "+g) + } else { + out = append(out, book+" "+chap+":"+g) + } + } + return out +} + +// Lookup resolves an English-style reference against a version, returning the +// matched verses (in order) and the sub-refs the corpus had no entry for. +func Lookup(version, ref string) ([]Verse, []string) { + var verses []Verse + var missing []string + for _, part := range SplitRef(ref) { + m := refRe.FindStringSubmatch(part) + if m == nil { + missing = append(missing, part) + continue + } + book, ok := ResolveBook(m[1]) + if !ok { + missing = append(missing, part) + continue + } + chap, _ := strconv.Atoi(m[2]) + from, to := verseRange(m[3]) + found := false + for _, v := range Verses(version, book, chap) { + if v.Verse >= from && v.Verse <= to { + verses = append(verses, v) + found = true + } + } + if !found { + missing = append(missing, part) + } + } + return verses, missing +} + +func verseRange(s string) (int, int) { + s = strings.TrimSpace(s) + if i := strings.IndexAny(s, "-–—"); i >= 0 { + from, _ := strconv.Atoi(strings.TrimSpace(s[:i])) + to, _ := strconv.Atoi(strings.TrimSpace(s[i+1:])) + return from, to + } + n, _ := strconv.Atoi(s) + return n, n +} |
