aboutsummaryrefslogtreecommitdiff
path: root/internal/bible
diff options
context:
space:
mode:
Diffstat (limited to 'internal/bible')
-rw-r--r--internal/bible/booktable.go32
-rw-r--r--internal/bible/booktable_test.go31
2 files changed, 63 insertions, 0 deletions
diff --git a/internal/bible/booktable.go b/internal/bible/booktable.go
index eb3b4e4..007e75e 100644
--- a/internal/bible/booktable.go
+++ b/internal/bible/booktable.go
@@ -141,6 +141,38 @@ func (t *BookTable) ParseRef(dialect, input string) (string, bool) {
return "", false
}
+// shortcut returns the dialect's primary abbreviation (the first form) for a
+// canonical book, or "" when the dialect has no entry for it.
+func (t *BookTable) shortcut(dialect, canonical string) string {
+ if forms := t.forms[dialect][canonical]; len(forms) > 0 {
+ return forms[0]
+ }
+ return ""
+}
+
+// FormatRef renders a canonical English reference ("John 20:1,11-18") in the
+// dialect's sigla: the dialect's book shortcut plus its number style -- English
+// "Jn 20:1,11-18" (colon chapter:verse, comma groups); Polish "J 20, 1. 11-18"
+// (comma chapter, verse; period groups). It is the inverse of ParseRef's
+// normalizeSigla. If canonicalRef can't be parsed or the book is not in the
+// dialect, it is returned unchanged (a safe, still-readable fallback).
+func (t *BookTable) FormatRef(dialect, canonicalRef string) string {
+ m := refRe.FindStringSubmatch(strings.TrimSpace(canonicalRef))
+ if m == nil {
+ return canonicalRef
+ }
+ canon, chap, verses := m[1], m[2], m[3]
+ abbrev := t.shortcut(dialect, canon)
+ if abbrev == "" {
+ return canonicalRef
+ }
+ if dialect == "pl" {
+ verses = strings.ReplaceAll(verses, ",", ". ") // disjoint groups
+ return abbrev + " " + chap + ", " + verses
+ }
+ return abbrev + " " + chap + ":" + verses
+}
+
// normalizeSigla rewrites a dialect's verse-reference tail into the colon/comma
// form bible.Lookup expects: "<chap>:<groups>", groups comma-separated, ranges
// with "-". Polish uses a comma (with or without a space) as the chapter/verse
diff --git a/internal/bible/booktable_test.go b/internal/bible/booktable_test.go
index ededad3..2a57d80 100644
--- a/internal/bible/booktable_test.go
+++ b/internal/bible/booktable_test.go
@@ -64,6 +64,37 @@ func TestParseRefDialects(t *testing.T) {
}
}
+func TestFormatRef(t *testing.T) {
+ tbl, _ := LoadBookTable(nil)
+ cases := []struct {
+ dialect, canonical, want string
+ }{
+ {"en", "John 20:1,11-18", "Jn 20:1,11-18"},
+ {"pl", "John 20:1,11-18", "J 20, 1. 11-18"},
+ {"en", "Matthew 13:18-23", "Matt 13:18-23"},
+ {"pl", "Matthew 13:18-23", "Mt 13, 18-23"},
+ {"en", "Luke 16:1-9", "Lk 16:1-9"},
+ // Round-trip: ParseRef then FormatRef in the same dialect is stable.
+ }
+ for _, c := range cases {
+ if got := tbl.FormatRef(c.dialect, c.canonical); got != c.want {
+ t.Errorf("FormatRef(%q,%q)=%q want %q", c.dialect, c.canonical, got, c.want)
+ }
+ }
+ // Unparseable / unknown book -> unchanged (safe fallback).
+ if got := tbl.FormatRef("en", "not a ref"); got != "not a ref" {
+ t.Errorf("unparseable ref should be unchanged, got %q", got)
+ }
+ // Round-trip through both dialects.
+ canon, ok := tbl.ParseRef("pl", "J 20, 1. 11-18")
+ if !ok || canon != "John 20:1,11-18" {
+ t.Fatalf("ParseRef round-trip canon=%q ok=%v", canon, ok)
+ }
+ if got := tbl.FormatRef("pl", canon); got != "J 20, 1. 11-18" {
+ t.Errorf("pl round-trip = %q", got)
+ }
+}
+
func TestBookTableMergeAndMalformed(t *testing.T) {
// User adds an alias "Jhn" to English John; other books stay default.
user := []byte("[en]\nJohn = [\"Jn\", \"Jhn\", \"John\"]\n")