aboutsummaryrefslogtreecommitdiff
path: root/internal/render
diff options
context:
space:
mode:
Diffstat (limited to 'internal/render')
-rw-r--r--internal/render/render.go62
-rw-r--r--internal/render/render_test.go56
2 files changed, 97 insertions, 21 deletions
diff --git a/internal/render/render.go b/internal/render/render.go
index c5a2ab0..6bccc65 100644
--- a/internal/render/render.go
+++ b/internal/render/render.go
@@ -24,28 +24,45 @@ func versionLabel(version, lang string) string {
return version
}
+// modernPartOrder is the fixed, deterministic order LocalizeHeading tries
+// the known modern (niedziela.pl) pl part labels in -- a plain slice rather
+// than ranging over i18n.UI.PartLabel (a map, so Go randomises its
+// iteration order). None of the five labels is a prefix of another, so the
+// order never changes which one matches, only determinism.
+var modernPartOrder = []string{"pierwsze_czytanie", "drugie_czytanie", "psalm", "aklamacja", "ewangelia"}
+
// LocalizeHeading swaps a modern (niedziela.pl) section heading's leading
// label word for its lang translation, keeping the rest of the heading (the
// parenthetical citation, exactly as scraped) untouched: e.g.
-// "Ewangelia (J 20, 1. 11-18)" with partID "ewangelia" and lang "en" becomes
-// "Gospel (J 20, 1. 11-18)". It only ever localises the label word, never
-// the citation or the verse text.
+// "Ewangelia (J 20, 1. 11-18)" with lang "en" becomes "Gospel (J 20, 1.
+// 11-18)". It only ever localises the label word, never the citation or the
+// verse text.
+//
+// It matches against heading's own leading text, not partID: a split
+// (two-reading) feast day scrapes PartID="drugie_czytanie" onto a heading
+// that niedziela.pl still literally titles "1. czytanie ..." (its own
+// numbering quirk carries over from the undivided day), so looking up the
+// Polish label by partID and checking heading's prefix against only that
+// one label misses it. Instead every known pl label (modernPartOrder) is
+// tried against heading in turn; partID itself is unused -- kept in the
+// signature for callers, which all have it in hand already (sec.PartID).
//
-// It is a safe no-op (returns heading unchanged) unless all of: lang is
-// "en", partID names a known modern-lectionary part (see
-// internal/i18n.UI.PartLabel), and heading actually starts with that part's
-// Polish label -- which excludes traditional (missalemeum) headings, already
-// in the requested language, and anything unrecognised.
+// It is a safe no-op (returns heading unchanged) unless lang is "en" and
+// heading actually starts with one of the known pl labels -- which excludes
+// traditional (missalemeum) headings, already in the requested language,
+// and anything unrecognised.
func LocalizeHeading(heading, partID, lang string) string {
if lang != "en" {
return heading
}
- plLabel, ok := i18n.Get("pl").PartLabel[partID]
- if !ok || !strings.HasPrefix(heading, plLabel) {
- return heading
+ plUI, enUI := i18n.Get("pl"), i18n.Get("en")
+ for _, id := range modernPartOrder {
+ plLabel := plUI.PartLabel[id]
+ if strings.HasPrefix(heading, plLabel) {
+ return enUI.PartLabel[id] + heading[len(plLabel):]
+ }
}
- enLabel := i18n.Get(lang).PartLabel[partID]
- return enLabel + heading[len(plLabel):]
+ return heading
}
// versionSystem maps a bible version to the Psalter system bible.ToEnglishRef
@@ -83,14 +100,14 @@ func GatherVersion(version string, sec liturgy.Section, lectionary, lang string)
return label, gatherPL(sec)
}
- ref, err := resolveRef(version, sec, lectionary)
+ ref, err := resolveRef(version, sec, lectionary, lang)
if err != nil {
return label, []string{err.Error()}
}
verses, missing := bible.Lookup(version, ref)
if len(verses) == 0 {
- return label, []string{fmt.Sprintf("(brak w „%s”)", version)}
+ return label, []string{fmt.Sprintf(i18n.Get(lang).NoVersion, version)}
}
blocks = make([]string, 0, len(verses))
@@ -98,7 +115,7 @@ func GatherVersion(version string, sec liturgy.Section, lectionary, lang string)
blocks = append(blocks, fmt.Sprintf("%d:%d %s", v.Chapter, v.Verse, v.Text))
}
if len(missing) > 0 {
- blocks = append(blocks, fmt.Sprintf("(brak w „%s”: %s)", version, strings.Join(missing, ", ")))
+ blocks = append(blocks, fmt.Sprintf(i18n.Get(lang).NoVersionPartial, version, strings.Join(missing, ", ")))
}
return label, blocks
}
@@ -108,8 +125,11 @@ func GatherVersion(version string, sec liturgy.Section, lectionary, lang string)
// converted to English/kjv-style via bible.ToEnglishRef when
// lectionary=="new" (a "traditional" citation is already English-style and
// used as-is). Shared by GatherVersion and GatherVerses so both apply the
-// exact same resolution.
-func resolveRef(version string, sec liturgy.Section, lectionary string) (string, error) {
+// exact same resolution. lang selects the wording of the two failure
+// messages it can return (see internal/i18n.UI.NoReference/NoReferenceErr);
+// it never affects which reference is resolved.
+func resolveRef(version string, sec liturgy.Section, lectionary, lang string) (string, error) {
+ ui := i18n.Get(lang)
citation := sec.Citation
if citation == "" {
if c, err := liturgy.ExtractCitation(sec.Heading); err == nil {
@@ -117,7 +137,7 @@ func resolveRef(version string, sec liturgy.Section, lectionary string) (string,
}
}
if citation == "" {
- return "", fmt.Errorf("(brak odwołania)")
+ return "", fmt.Errorf("%s", ui.NoReference)
}
if lectionary != "new" {
@@ -125,7 +145,7 @@ func resolveRef(version string, sec liturgy.Section, lectionary string) (string,
}
ref, err := bible.ToEnglishRef(citation, system(version))
if err != nil {
- return "", fmt.Errorf("(brak odwołania: %w)", err)
+ return "", fmt.Errorf(ui.NoReferenceErr, err)
}
return ref, nil
}
@@ -141,7 +161,7 @@ func GatherVerses(version string, sec liturgy.Section, lectionary, lang string)
return label, nil, false
}
- ref, err := resolveRef(version, sec, lectionary)
+ ref, err := resolveRef(version, sec, lectionary, lang)
if err != nil {
return label, nil, false
}
diff --git a/internal/render/render_test.go b/internal/render/render_test.go
index b016d6b..affaaf8 100644
--- a/internal/render/render_test.go
+++ b/internal/render/render_test.go
@@ -76,6 +76,56 @@ func TestCompareLabelLang(t *testing.T) {
}
}
+// TestGatherVersionNoVersionLang checks that the "(not in %s)" block
+// (bible.Lookup finding nothing at all) follows lang -- pl reproduces the
+// original Polish wording exactly, en uses internal/i18n's English wording.
+func TestGatherVersionNoVersionLang(t *testing.T) {
+ sec := liturgy.Section{Heading: "Ewangelia (J 20, 1. 11-18)"}
+
+ _, blocks := GatherVersion("zzz", sec, "new", "pl")
+ if len(blocks) == 0 || blocks[0] != `(brak w „zzz”)` {
+ t.Errorf(`GatherVersion(..., "pl") blocks = %v, want [(brak w „zzz”)]`, blocks)
+ }
+
+ _, blocks = GatherVersion("zzz", sec, "new", "en")
+ if len(blocks) == 0 || blocks[0] != "(not in zzz)" {
+ t.Errorf(`GatherVersion(..., "en") blocks = %v, want [(not in zzz)]`, blocks)
+ }
+}
+
+// TestGatherVersionNoReferenceLang checks the "(no reference)" block (no
+// citation resolvable at all) follows lang.
+func TestGatherVersionNoReferenceLang(t *testing.T) {
+ sec := liturgy.Section{Heading: "Bez odwołania"}
+
+ _, blocks := GatherVersion("wuj", sec, "new", "pl")
+ if len(blocks) == 0 || blocks[0] != "(brak odwołania)" {
+ t.Errorf(`GatherVersion(..., "pl") blocks = %v, want [(brak odwołania)]`, blocks)
+ }
+
+ _, blocks = GatherVersion("wuj", sec, "new", "en")
+ if len(blocks) == 0 || blocks[0] != "(no reference)" {
+ t.Errorf(`GatherVersion(..., "en") blocks = %v, want [(no reference)]`, blocks)
+ }
+}
+
+// TestGatherVersionNoReferenceErrLang checks the "(no reference: ...)" block
+// (a citation that bible.ToEnglishRef fails to convert, e.g. an unrecognised
+// book) follows lang.
+func TestGatherVersionNoReferenceErrLang(t *testing.T) {
+ sec := liturgy.Section{Citation: "Xyz 1, 1-2"}
+
+ _, blocks := GatherVersion("wuj", sec, "new", "pl")
+ if len(blocks) == 0 || !strings.HasPrefix(blocks[0], "(brak odwołania: ") {
+ t.Errorf(`GatherVersion(..., "pl") blocks = %v, want prefix "(brak odwołania: "`, blocks)
+ }
+
+ _, blocks = GatherVersion("wuj", sec, "new", "en")
+ if len(blocks) == 0 || !strings.HasPrefix(blocks[0], "(no reference: ") {
+ t.Errorf(`GatherVersion(..., "en") blocks = %v, want prefix "(no reference: "`, blocks)
+ }
+}
+
func TestOfflineVersions(t *testing.T) {
got := OfflineVersions([]string{"pl", "wuj", "vul"})
for _, v := range got {
@@ -143,6 +193,12 @@ func TestLocalizeHeading(t *testing.T) {
{"unknown partID unchanged", "Coś innego (X 1)", "", "en", "Coś innego (X 1)"},
{"already-English heading unchanged (traditional lectionary, no pl prefix to match)", "Gospel (Luke 7:36-50)", "ewangelia", "en", "Gospel (Luke 7:36-50)"},
{"prefix mismatch unchanged", "Nieoczekiwany tytuł (J 1)", "ewangelia", "en", "Nieoczekiwany tytuł (J 1)"},
+ // Split (two-reading) feast day: niedziela.pl scrapes
+ // PartID="drugie_czytanie" onto a heading that still literally
+ // starts with "1. czytanie" (its own numbering quirk). Matching
+ // must follow the heading's actual text, not partID's label, so
+ // this localises to "1st reading", not staying Polish.
+ {"drugie_czytanie partID with a 1. czytanie heading (split feast day)", "1. czytanie (Dz 2, 14. 22-33)", "drugie_czytanie", "en", "1st reading (Dz 2, 14. 22-33)"},
}
for _, c := range cases {