aboutsummaryrefslogtreecommitdiff
path: root/internal/bible/ofref.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/bible/ofref.go')
-rw-r--r--internal/bible/ofref.go71
1 files changed, 71 insertions, 0 deletions
diff --git a/internal/bible/ofref.go b/internal/bible/ofref.go
new file mode 100644
index 0000000..8a72342
--- /dev/null
+++ b/internal/bible/ofref.go
@@ -0,0 +1,71 @@
+package bible
+
+import (
+ "regexp"
+ "strconv"
+ "strings"
+
+ "github.com/lukaszkasprzak/lectio/internal/psalter"
+)
+
+var (
+ // ofCiteRe splits an English-canonical citation into book, chapter and the
+ // verse tail: "2 Samuel 6:12b-15,17-19" -> ("2 Samuel", "6", "12b-15,17-19").
+ // The book is non-greedy so a leading ordinal ("2 Samuel") stays with it.
+ ofCiteRe = regexp.MustCompile(`^(.*?)\s+(\d+):(.+)$`)
+ // ofVerseLetterRe drops sub-verse part letters so lookups resolve at whole
+ // verses: "12b" -> "12", "3ab" -> "3", "3cd" -> "3".
+ ofVerseLetterRe = regexp.MustCompile(`(\d)[a-z]+`)
+)
+
+// normalizeOFVerses rewrites a citation's verse tail into the shape
+// bible.Lookup parses: cross-chapter semicolons become commas, ranges use a
+// plain hyphen, sub-verse letters are dropped, and spaces are removed.
+func normalizeOFVerses(tail string) string {
+ tail = strings.ReplaceAll(tail, ";", ",")
+ tail = dashRe.ReplaceAllString(tail, "-")
+ tail = ofVerseLetterRe.ReplaceAllString(tail, "$1")
+ tail = strings.ReplaceAll(tail, " ", "")
+ return tail
+}
+
+// OFRef turns an English-canonical Ordinary Form citation (lectio's authored
+// form) into a bible.Lookup-ready reference for the target corpus's Psalter.
+//
+// Every citation's verse tail is normalized (see normalizeOFVerses). Only the
+// Psalms differ between Psalters, so their chapter/verse is additionally
+// renumbered:
+//
+// - "vulgate" (vul/grb/wuj): shift the Hebrew chapter to its Vulgate
+// equivalent (Ps 27 -> 26, Ps 147 -> 146). Verse numbers are kept, so the
+// rare intra-psalm verse-boundary shifts are not corrected here.
+// - "drb": the Douay-Rheims corpus keeps modern (Hebrew) chapter numbers, so
+// the chapter is kept; only the DRB title-fold verse shift applies (see
+// psalter.DrbVerse).
+// - "hebrew" / anything else: already in the corpus's numbering.
+//
+// A citation OFRef cannot parse (no "chapter:verse") is returned unchanged for
+// bible.Lookup to accept or reject.
+func OFRef(citation, system string) string {
+ m := ofCiteRe.FindStringSubmatch(citation)
+ if m == nil {
+ return citation
+ }
+ book, chap, verses := m[1], m[2], normalizeOFVerses(m[3])
+
+ if book == "Psalms" {
+ heb, err := strconv.Atoi(chap)
+ if err == nil {
+ switch system {
+ case "vulgate":
+ chap = strconv.Itoa(psalter.HebrewToVulgateChapter(heb))
+ case "drb":
+ verses = digitsRe.ReplaceAllStringFunc(verses, func(s string) string {
+ n, _ := strconv.Atoi(s)
+ return strconv.Itoa(psalter.DrbVerse(heb, n))
+ })
+ }
+ }
+ }
+ return book + " " + chap + ":" + verses
+}