aboutsummaryrefslogtreecommitdiff
path: root/internal/render
diff options
context:
space:
mode:
Diffstat (limited to 'internal/render')
-rw-r--r--internal/render/render.go66
-rw-r--r--internal/render/render_test.go82
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)
+ }
+ })
+ }
+}