diff options
Diffstat (limited to 'internal/render')
| -rw-r--r-- | internal/render/render.go | 66 | ||||
| -rw-r--r-- | internal/render/render_test.go | 82 |
2 files changed, 125 insertions, 23 deletions
diff --git a/internal/render/render.go b/internal/render/render.go index b8d778c..c5a2ab0 100644 --- a/internal/render/render.go +++ b/internal/render/render.go @@ -9,17 +9,43 @@ import ( "strings" "github.com/lukaszkasprzak/lectio/internal/bible" + "github.com/lukaszkasprzak/lectio/internal/i18n" "github.com/lukaszkasprzak/lectio/internal/liturgy" ) -// versionLabels names each version for column headers / prose. Ported -// verbatim from ewangelia.py VERSION_LABELS. -var versionLabels = map[string]string{ - "pl": "Polski (niedziela.pl)", - "wuj": "Wujek (pol.)", - "vul": "Wulgata (lac.)", - "grb": "Grecki", - "drb": "Douay-Rheims (ang.)", +// versionLabel returns version's column-header/prose label in lang (see +// internal/i18n.Get), falling back to the bare version code if lang has no +// entry for it. lang="pl" reproduces ewangelia.py's original VERSION_LABELS +// exactly. +func versionLabel(version, lang string) string { + if l, ok := i18n.Get(lang).Version[version]; ok { + return l + } + return version +} + +// 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. +// +// 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. +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 + } + enLabel := i18n.Get(lang).PartLabel[partID] + return enLabel + heading[len(plLabel):] } // versionSystem maps a bible version to the Psalter system bible.ToEnglishRef @@ -49,8 +75,10 @@ const incipit = "Słowa Ewangelii" // lectionary selects how sec.Citation is read: "new" (modern/niedziela.pl) // citations are Polish and go through bible.ToEnglishRef; "traditional" // (missalemeum) citations are already English kjv-style and are used as-is. -func GatherVersion(version string, sec liturgy.Section, lectionary string) (label string, blocks []string) { - label = versionLabels[version] +// lang selects the UI chrome language the label comes from (see +// internal/i18n); it never affects the verse text/citation itself. +func GatherVersion(version string, sec liturgy.Section, lectionary, lang string) (label string, blocks []string) { + label = versionLabel(version, lang) if version == "pl" { return label, gatherPL(sec) } @@ -105,9 +133,10 @@ func resolveRef(version string, sec liturgy.Section, lectionary string) (string, // GatherVerses returns one version's verses for a section as raw bible.Verse // structs (for column/interlinear alignment). versified is false for "pl" // (paragraph text, no verse numbers) and on any resolution/lookup failure -- -// callers fall back to GatherVersion's string blocks for those. -func GatherVerses(version string, sec liturgy.Section, lectionary string) (label string, verses []bible.Verse, versified bool) { - label = versionLabels[version] +// callers fall back to GatherVersion's string blocks for those. lang selects +// the UI chrome language the label comes from, same as GatherVersion. +func GatherVerses(version string, sec liturgy.Section, lectionary, lang string) (label string, verses []bible.Verse, versified bool) { + label = versionLabel(version, lang) if version == "pl" { return label, nil, false } @@ -177,16 +206,17 @@ func OfflineVersions(versions []string) []string { } // Compare lays the versions of one reading section out as parallel columns, -// side by side, wrapped to fit width. Ports render_compare. -func Compare(secs []liturgy.Section, versions []string, width int, lectionary string) string { +// side by side, wrapped to fit width. Ports render_compare. lang selects the +// column-header label language (see GatherVersion). +func Compare(secs []liturgy.Section, versions []string, width int, lectionary, lang string) string { var out []string for _, sec := range secs { - out = append(out, compareSection(sec, versions, width, lectionary)) + out = append(out, compareSection(sec, versions, width, lectionary, lang)) } return strings.Join(out, "\n\n") } -func compareSection(sec liturgy.Section, versions []string, width int, lectionary string) string { +func compareSection(sec liturgy.Section, versions []string, width int, lectionary, lang string) string { type column struct { label string lines []string @@ -205,7 +235,7 @@ func compareSection(sec liturgy.Section, versions []string, width int, lectionar cols := make([]column, 0, n) height := 0 for _, v := range versions { - label, blocks := GatherVersion(v, sec, lectionary) + label, blocks := GatherVersion(v, sec, lectionary, lang) var lines []string for _, b := range blocks { lines = append(lines, strings.Split(wrap(b, w), "\n")...) diff --git a/internal/render/render_test.go b/internal/render/render_test.go index 1b338a0..b016d6b 100644 --- a/internal/render/render_test.go +++ b/internal/render/render_test.go @@ -12,7 +12,7 @@ func TestGatherPLDedup(t *testing.T) { Heading: "Psalm (Ps 1)", Paragraphs: [][]string{{"stanza one"}, {"refrain"}, {"stanza two"}, {"refrain"}}, } - _, blocks := GatherVersion("pl", sec, "new") + _, blocks := GatherVersion("pl", sec, "new", "pl") n := 0 for _, b := range blocks { if b == "refrain" { @@ -26,7 +26,7 @@ func TestGatherPLDedup(t *testing.T) { func TestGatherBible(t *testing.T) { sec := liturgy.Section{Heading: "Ewangelia (J 20, 1. 11-18)"} - label, blocks := GatherVersion("wuj", sec, "new") + label, blocks := GatherVersion("wuj", sec, "new", "pl") if !strings.Contains(label, "Wujek") { t.Errorf("label = %q", label) } @@ -37,12 +37,45 @@ func TestGatherBible(t *testing.T) { func TestGatherTraditional(t *testing.T) { sec := liturgy.Section{Citation: "Luke 7:36-50"} - _, blocks := GatherVersion("vul", sec, "traditional") + _, blocks := GatherVersion("vul", sec, "traditional", "pl") if len(blocks) == 0 || !strings.HasPrefix(blocks[0], "7:36") { t.Errorf("first block = %q", blocks) } } +// TestGatherVersionLabelLang checks that the label's language follows the +// lang parameter -- pl reproduces today's Polish labels exactly, en gives +// the English set from internal/i18n. +func TestGatherVersionLabelLang(t *testing.T) { + sec := liturgy.Section{Heading: "Ewangelia (J 20, 1. 11-18)"} + + label, _ := GatherVersion("vul", sec, "new", "pl") + if label != "Wulgata (lac.)" { + t.Errorf(`GatherVersion(..., "pl") label = %q, want "Wulgata (lac.)"`, label) + } + + label, _ = GatherVersion("vul", sec, "new", "en") + if label != "Vulgate (Latin)" { + t.Errorf(`GatherVersion(..., "en") label = %q, want "Vulgate (Latin)"`, label) + } +} + +// TestCompareLabelLang checks Compare's column-header row follows lang, +// same as GatherVersion (which it wraps via compareSection). +func TestCompareLabelLang(t *testing.T) { + sec := liturgy.Section{Heading: "Ewangelia (J 20, 1. 11-18)"} + + out := Compare([]liturgy.Section{sec}, []string{"vul"}, 80, "new", "pl") + if !strings.Contains(out, "Wulgata (lac.)") { + t.Errorf(`Compare(..., "pl") = %q, want it to contain "Wulgata (lac.)"`, out) + } + + out = Compare([]liturgy.Section{sec}, []string{"vul"}, 80, "new", "en") + if !strings.Contains(out, "Vulgate (Latin)") { + t.Errorf(`Compare(..., "en") = %q, want it to contain "Vulgate (Latin)"`, out) + } +} + func TestOfflineVersions(t *testing.T) { got := OfflineVersions([]string{"pl", "wuj", "vul"}) for _, v := range got { @@ -54,7 +87,7 @@ func TestOfflineVersions(t *testing.T) { func TestGatherVersesBible(t *testing.T) { sec := liturgy.Section{Heading: "Ewangelia (J 20, 1. 11-18)"} - label, verses, versified := GatherVerses("wuj", sec, "new") + label, verses, versified := GatherVerses("wuj", sec, "new", "pl") if !strings.Contains(label, "Wujek") { t.Errorf("label = %q", label) } @@ -74,7 +107,7 @@ func TestGatherVersesPL(t *testing.T) { Heading: "Psalm (Ps 1)", Paragraphs: [][]string{{"stanza one"}}, } - _, verses, versified := GatherVerses("pl", sec, "new") + _, verses, versified := GatherVerses("pl", sec, "new", "pl") if versified { t.Error("versified = true, want false for pl (paragraph text, no verse numbers)") } @@ -82,3 +115,42 @@ func TestGatherVersesPL(t *testing.T) { t.Errorf("verses = %+v, want nil for pl", verses) } } + +// TestGatherVersesLabelLang checks GatherVerses' label also follows lang, +// same as GatherVersion. +func TestGatherVersesLabelLang(t *testing.T) { + sec := liturgy.Section{Heading: "Ewangelia (J 20, 1. 11-18)"} + label, _, _ := GatherVerses("vul", sec, "new", "en") + if label != "Vulgate (Latin)" { + t.Errorf(`GatherVerses(..., "en") label = %q, want "Vulgate (Latin)"`, label) + } +} + +// TestLocalizeHeading covers render.LocalizeHeading's part-label swap +// (brief §3b): the pl label prefix of a modern (niedziela.pl) heading is +// replaced by its en label, the citation kept exactly as scraped, and every +// other case (pl, unknown/traditional partID, prefix mismatch) is a safe +// no-op that returns heading unchanged. +func TestLocalizeHeading(t *testing.T) { + cases := []struct { + name, heading, partID, lang, want string + }{ + {"gospel en", "Ewangelia (J 20, 1. 11-18)", "ewangelia", "en", "Gospel (J 20, 1. 11-18)"}, + {"first reading en", "1. czytanie (Dz 2, 14. 22-33)", "pierwsze_czytanie", "en", "1st reading (Dz 2, 14. 22-33)"}, + {"psalm en", "Psalm (Ps 15)", "psalm", "en", "Psalm (Ps 15)"}, + {"acclamation en", "Aklamacja (Alleluja)", "aklamacja", "en", "Acclamation (Alleluja)"}, + {"pl unchanged", "Ewangelia (J 20, 1. 11-18)", "ewangelia", "pl", "Ewangelia (J 20, 1. 11-18)"}, + {"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)"}, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + got := LocalizeHeading(c.heading, c.partID, c.lang) + if got != c.want { + t.Errorf("LocalizeHeading(%q, %q, %q) = %q, want %q", c.heading, c.partID, c.lang, got, c.want) + } + }) + } +} |
