aboutsummaryrefslogtreecommitdiff
path: root/internal/tui/tui.go
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-07-23 23:28:15 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-07-23 23:28:15 +0200
commit9ec2c438a39542ec485e221d485c43b04d692aca (patch)
tree88e881306215de030ef70279be4de9c6d533e112 /internal/tui/tui.go
parentf73decedab916d336247d4ea43ead2b7f7da1e83 (diff)
downloadlectio-9ec2c438a39542ec485e221d485c43b04d692aca.tar.gz
lectio-9ec2c438a39542ec485e221d485c43b04d692aca.zip
tui: fix width-wrap garbling + straight-aligned verse column (export render.Wrap, hanging indent); strip niedziela summary subtitle (tui/cli/web); web verse grid alignment; refrain-italic pl-only
Diffstat (limited to 'internal/tui/tui.go')
-rw-r--r--internal/tui/tui.go57
1 files changed, 46 insertions, 11 deletions
diff --git a/internal/tui/tui.go b/internal/tui/tui.go
index 06ad19f..a4c14b9 100644
--- a/internal/tui/tui.go
+++ b/internal/tui/tui.go
@@ -306,16 +306,16 @@ func (m Model) bodyLines(w int) []string {
}
heading := render.LocalizeHeading(sec.Heading, sec.PartID, m.cfg.UILanguage)
lines = append(lines, headingStyle.Render(heading))
- if sec.Subtitle != "" {
- lines = append(lines, citationStyle.Render(sec.Subtitle))
- }
lines = append(lines, "")
_, blocks := render.GatherVersion(ver, sec, m.cfg.Lectionary, m.cfg.UILanguage)
- isPsalm := sec.PartID == "psalm"
+ numW := maxNumWidth(blocks)
+ // The refrain-italic only applies to the pl responsorial-psalm block
+ // (its first, deduped paragraph); bible versions have no refrain block.
+ isPsalm := sec.PartID == "psalm" && ver == "pl"
for bi, b := range blocks {
refrain := isPsalm && bi == 0
- lines = append(lines, styleBlock(b, refrain, w)...)
+ lines = append(lines, styleBlock(b, refrain, w, numW)...)
lines = append(lines, "")
}
}
@@ -330,18 +330,53 @@ var verseNumRe = regexp.MustCompile(`^(\d+:\d+) (.*)$`)
// block gets its "chapter:verse" prefix in the muted verse-number style and
// its text in the default verse style; a psalm's first (refrain) block
// renders italic; everything else renders in the default verse style.
-func styleBlock(b string, refrain bool, w int) []string {
+func styleBlock(b string, refrain bool, w, numW int) []string {
+ if w < 1 {
+ w = 1
+ }
if g := verseNumRe.FindStringSubmatch(b); g != nil {
num, text := g[1], g[2]
- wrapped := verseTextStyle.Width(w).Render(text)
- wlines := strings.Split(wrapped, "\n")
- wlines[0] = verseNumStyle.Render(num+" ") + wlines[0]
- return wlines
+ col := numW + 2 // verse-number column: widest "chapter:verse" + 2 spaces
+ indent := strings.Repeat(" ", col)
+ tw := w - col
+ if tw < 1 {
+ tw = 1
+ }
+ lines := strings.Split(render.Wrap(text, tw), "\n")
+ out := make([]string, 0, len(lines))
+ for i, ln := range lines {
+ if i == 0 {
+ pad := strings.Repeat(" ", col-len([]rune(num)))
+ out = append(out, verseNumStyle.Render(num)+pad+verseTextStyle.Render(ln))
+ } else {
+ out = append(out, indent+verseTextStyle.Render(ln))
+ }
+ }
+ return out
}
style := verseTextStyle
if refrain {
style = refrainStyle
}
- return strings.Split(style.Width(w).Render(b), "\n")
+ lines := strings.Split(render.Wrap(b, w), "\n")
+ out := make([]string, 0, len(lines))
+ for _, ln := range lines {
+ out = append(out, style.Render(ln))
+ }
+ return out
+}
+
+// maxNumWidth returns the widest "chapter:verse" prefix rune-width among the
+// verse blocks, so styleBlock can align every verse's text to one column.
+func maxNumWidth(blocks []string) int {
+ m := 0
+ for _, b := range blocks {
+ if g := verseNumRe.FindStringSubmatch(b); g != nil {
+ if n := len([]rune(g[1])); n > m {
+ m = n
+ }
+ }
+ }
+ return m
}