From 2f20d41921a4ed08d0a7b16246215e0eee5ac512 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Mon, 27 Jul 2026 23:54:29 +0200 Subject: feat(bible): resolve and display cross-chapter verse ranges (N:M-P:Q) Lookup now detects a verse-tail range that crosses a chapter boundary ("M-P:Q", e.g. "30-28:7" in "Sirach 27:30-28:7") and fetches chapter N from verse M to its end, any whole chapters between, and chapter P from verse 1 through Q, instead of misreading the tail as a plain from-to range and coming up empty. SplitRef expands the same pattern inside a comma list so a trailing group after the jump (e.g. the ",8-10" in "Malachi 1:14-2:2,8-10") resolves against the new current chapter. FormatRef renders the range intact as " N:M-P:Q" instead of splitting off a fake new-chapter marker from the embedded "P:" and mangling the display (previously "Sir 27:7"). No sentinel value is ever stored in a ref string; it only bounds an internal verse-filter loop in Lookup. --- internal/bible/booktable.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'internal/bible/booktable.go') diff --git a/internal/bible/booktable.go b/internal/bible/booktable.go index 360f526..2d4b5b2 100644 --- a/internal/bible/booktable.go +++ b/internal/bible/booktable.go @@ -216,6 +216,21 @@ func (t *BookTable) FormatRef(dialect, canonicalRef string) string { if g == "" { continue } + if cm := crossChapRangeRe.FindStringSubmatch(g); cm != nil { + // "M-P:Q": a range crossing a chapter boundary. Keep it intact -- + // it already reads naturally as ":M-P:Q" -- rather than + // peeling a fake newChap off the "P:" embedded inside it. + switch { + case i == 0: + b.WriteString(chapVerse(dialect, chap, g)) + case dialect == "pl": + b.WriteString(". " + g) + default: + b.WriteString("," + g) + } + chap = cm[2] // later groups (if any) belong to chapter P + continue + } newChap := "" if idx := strings.IndexByte(g, ':'); idx >= 0 { newChap, g = g[:idx], g[idx+1:] -- cgit v1.3