From 0e82fa3e5544ac6c534acc297491a87a361ccd97 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Mon, 27 Jul 2026 20:00:04 +0200 Subject: docs: add reading_lang field to national-bibles spec reading_lang (any language code) drives corpus auto-selection; empty follows ui_language. Resolver: reading_version > reading_lang match > ui_language match > Latin vul. traditional_lang dropped from selection entirely (scraper-only). --- .../specs/2026-07-27-lectio-national-bibles-design.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'docs/superpowers/specs') diff --git a/docs/superpowers/specs/2026-07-27-lectio-national-bibles-design.md b/docs/superpowers/specs/2026-07-27-lectio-national-bibles-design.md index 03851c3..daad3aa 100644 --- a/docs/superpowers/specs/2026-07-27-lectio-national-bibles-design.md +++ b/docs/superpowers/specs/2026-07-27-lectio-national-bibles-design.md @@ -13,8 +13,9 @@ - **Metadata sidecar:** `.ini`, full-line-comment INI (parsed by `internal/ini`), keys: `lang` (required), `name` (required), `psalm_system` (required: `vulgate`|`hebrew`|`drb`), `sigla` (optional, a `books.ini` dialect id). - **Delivery:** both compile-in (glob `go:embed` + Makefile validate/embed) and runtime drop-in (a user directory, overrides built-ins). Same format and validator for both. - **User corpus directory:** `~/.config/lectio/corpora/` (consistent with `~/.config/lectio/calendars/`; see Open Decision D1). -- **Selection order (offline reading text):** `reading_version` (explicit config) → corpus whose `lang` matches `ui_language`/`traditional_lang` → Latin `vul` fallback. Defaults preserved: en→drb, pl→vul. -- **`traditional_lang` is not extended and is deprecated:** it stays `pl`/`en`, keeps its role as the missalemeum-scraper language knob for the still-live daily view, and gains no new semantics. The corpus resolver may read it as one of the *existing* language signals (to preserve current pl/en selection behaviour), but no new field, value, or meaning is added to it, and it is removed only when the scraper is retired (separate future work). New-language selection goes through `reading_version`, never through `traditional_lang`. +- **Selection order (offline reading text):** `reading_version` (explicit corpus code) → corpus whose `lang` matches `reading_lang` → corpus whose `lang` matches `ui_language` → Latin `vul` fallback. Defaults preserved via the `ui_language` step (en→drb; pl→no pl corpus→vul). +- **`reading_lang` is the reading-language knob:** a new config field, any language code (`fr`, `de`, `pl`, `en`, …), default empty. When set it auto-selects a corpus of that language; when empty the reading language follows `ui_language`. +- **`traditional_lang` is not read by the corpus resolver at all and is deprecated:** it stays `pl`/`en`, keeps its sole role as the missalemeum-scraper language knob for the still-live daily view, gains no new semantics, and `reading_lang` now owns the reading-language role it used to imply. It is removed only when the scraper is retired (separate future work). - **Purity:** `internal/bible` imports only stdlib + `internal/ini` + `internal/psalter`. No network, no new third-party deps. - **Non-breaking:** existing `--ref`, version comparison, TUI/web daily view, and the scraper path keep working unchanged. @@ -64,14 +65,14 @@ Built-in corpora gain their own sidecars (`vul.ini`, `drb.ini`, `grb.ini`, `wuj. ### 4. Selection & fallback -- `config.Config` gains `ReadingVersion string` (`toml:"reading_version"`, INI key `reading_version`), default empty. +- `config.Config` gains two fields, both default empty: `ReadingLang string` (INI key `reading_lang`, any language code) and `ReadingVersion string` (INI key `reading_version`, an explicit corpus code). - New `config.Config.ReadingCorpus() string`: - 1. if `ReadingVersion` set and that corpus exists → it; - 2. else the first corpus (deterministic order) whose `lang` == `NormalizeUILanguage(UILanguage)`, then whose `lang` == `TraditionalLang`; - 3. else `""` (caller applies the Latin `vul` fallback already implemented in `readingLine`). -- `internal/cli/liturgy.go` `vernacularVersion(cfg)` is replaced by a call to this resolver; if it returns `""`, keep the existing `drb`-for-en / `vul`-for-others defaults so current behaviour is preserved when no corpus matches. + 1. if `ReadingVersion` is set and that corpus exists → it; + 2. else, for each candidate language in order [`ReadingLang`, `NormalizeUILanguage(UILanguage)`] that is non-empty, the first corpus (deterministic order) whose `lang` equals that language → that corpus; + 3. else `""`. +- `internal/cli/liturgy.go` `vernacularVersion(cfg)` becomes `code := cfg.ReadingCorpus(); if code == "" { code = "vul" }; return code`. The old special-case defaults collapse into step 2: `drb` is selected for English via its own `lang = en` metadata, and Polish (no `pl` corpus) falls through to the Latin `vul`. - The existing `latinFallback = "vul"` mechanism in `readingLine` is unchanged and still covers per-verse gaps in whatever corpus is chosen. -- **Scope of lang-auto (step 2):** because `ui_language`/`traditional_lang` are `pl`/`en` only, auto-match can select a corpus only for those two languages. This is deliberate and does two useful things: it preserves today's pl/en defaults, and it lets a dropped-in corpus that declares `lang = pl` (e.g. a corrected Wujek) auto-serve Polish users with **zero config**, superseding the `vul` default. A genuinely new language (fr, de, …) has no matching signal, so it is selected only via an explicit `reading_version` — which is exactly the one line a French user adds. +- **Behaviour:** `reading_lang = fr` auto-selects a `lang = fr` corpus — any language, not just pl/en. Leaving `reading_lang` empty makes the reading language follow `ui_language`. A dropped-in corpus declaring `lang = pl` (e.g. a corrected Wujek) auto-serves Polish users with **zero config** as soon as `reading_lang` or `ui_language` is `pl`, superseding the `vul` fallback. `traditional_lang` is never consulted. ### 5. Psalm versification -- cgit v1.3