From 28699aa44df1d791fb48618a8f06627f230432d4 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Mon, 27 Jul 2026 15:10:45 +0200 Subject: fix(bible): resolve + format cross-chapter citations (13:22-25; 15:10) normalizeSigla treats ';' as a group separator so SplitRef resolves each chapter; FormatRef renders multi-chapter refs per chapter in the dialect's sigla. Restored the full Assumption (Judith 13:22-25; 15:10) and St Lucy (2 Cor 10:17-18; 11:1-2) epistles. --- internal/bible/booktable.go | 40 ++++++++++++++++++++++++++++---- internal/caldata/tridentine-calendar.ini | 4 ++-- 2 files changed, 38 insertions(+), 6 deletions(-) (limited to 'internal') diff --git a/internal/bible/booktable.go b/internal/bible/booktable.go index ae005a5..de8995c 100644 --- a/internal/bible/booktable.go +++ b/internal/bible/booktable.go @@ -186,16 +186,45 @@ func (t *BookTable) FormatRef(dialect, canonicalRef string) string { if m == nil { return canonicalRef } - canon, chap, verses := m[1], m[2], m[3] + canon, chap, rest := m[1], m[2], m[3] abbrev := t.shortcut(dialect, canon) if abbrev == "" { return canonicalRef } + // rest is a comma-separated group list; a group with ":" opens a new chapter. + var b strings.Builder + b.WriteString(abbrev + " ") + for i, g := range strings.Split(rest, ",") { + g = strings.TrimSpace(g) + if g == "" { + continue + } + newChap := "" + if idx := strings.IndexByte(g, ':'); idx >= 0 { + newChap, g = g[:idx], g[idx+1:] + } + switch { + case i == 0: // first group uses the chapter from refRe + b.WriteString(chapVerse(dialect, chap, g)) + case newChap != "" && newChap != chap: // cross-chapter group + chap = newChap + b.WriteString("; " + chapVerse(dialect, chap, g)) + case dialect == "pl": // another verse group in the same chapter + b.WriteString(". " + g) + default: + b.WriteString("," + g) + } + } + return b.String() +} + +// chapVerse renders one "chapter + verses" in the dialect's style: English +// "5:15-17", Polish "5, 15-17". +func chapVerse(dialect, chap, verses string) string { if dialect == "pl" { - verses = strings.ReplaceAll(verses, ",", ". ") // disjoint groups - return abbrev + " " + chap + ", " + verses + return chap + ", " + verses } - return abbrev + " " + chap + ":" + verses + return chap + ":" + verses } // normalizeSigla rewrites a dialect's verse-reference tail into the colon/comma @@ -213,6 +242,9 @@ func normalizeSigla(dialect, tail string) string { } else { tail = strings.ReplaceAll(tail, ".", ",") // disjoint groups (comma already fine) } + // A semicolon separates cross-chapter groups ("13:22-25; 15:10"); treat it + // as a group separator so bible.SplitRef resolves each chapter. + tail = strings.ReplaceAll(tail, ";", ",") tail = dashRe.ReplaceAllString(tail, "-") tail = verseLetterRe.ReplaceAllString(tail, "$1") tail = strings.ReplaceAll(tail, " ", "") diff --git a/internal/caldata/tridentine-calendar.ini b/internal/caldata/tridentine-calendar.ini index 81b6349..30951bb 100644 --- a/internal/caldata/tridentine-calendar.ini +++ b/internal/caldata/tridentine-calendar.ini @@ -57,7 +57,7 @@ colour = red name.en = Saints Peter and Paul, Apostles [assumption] -reading.first = Judith 13:22-25 +reading.first = Judith 13:22-25; 15:10 reading.gospel = Luke 1:41-50 date = 08-15 rank = class-1 @@ -134,7 +134,7 @@ colour = white name.en = The Conversion of Saint Paul the Apostle [st-lucy] -reading.first = 2 Cor 10:17-18 +reading.first = 2 Cor 10:17-18; 11:1-2 reading.gospel = Matt 13:44-52 date = 12-13 rank = class-3 -- cgit v1.3