diff options
| author | Łukasz <lukasz@arcofasiagroup.com> | 2026-07-23 12:28:09 +0200 |
|---|---|---|
| committer | Łukasz <lukasz@arcofasiagroup.com> | 2026-07-23 12:28:09 +0200 |
| commit | 71da73c4a8c01595118c196db5b8a37611f672ec (patch) | |
| tree | d7d7f6ea469839fd7c83a9494bb156789ad6d749 /docs/superpowers/specs/2026-07-23-lectio-go-rewrite-design.md | |
| parent | fd5f75e4080ee1c6c17a70414349eea8ea1903d2 (diff) | |
| download | lectio-71da73c4a8c01595118c196db5b8a37611f672ec.tar.gz lectio-71da73c4a8c01595118c196db5b8a37611f672ec.zip | |
Spec+plan: traditional lectionary (missalemeum) + per-part config
- config: lectionary=new|traditional, traditional_lang=pl|en, and
commented-out [parts.new]/[parts.traditional] per-part toggles (parsed
as a map: a part shows unless explicitly false).
- traditional source: missalemeum API (en/pl only; no Latin) mapped to
the shared []Section; scripture parts get the version-compare via their
citation + embedded vul, prayers are vernacular-only.
- new internal/tradlit package + Load router by lectionary; plan addendum
A with the tradlit task and amendments to Section/config/Load/render/cli.
Diffstat (limited to 'docs/superpowers/specs/2026-07-23-lectio-go-rewrite-design.md')
| -rw-r--r-- | docs/superpowers/specs/2026-07-23-lectio-go-rewrite-design.md | 106 |
1 files changed, 96 insertions, 10 deletions
diff --git a/docs/superpowers/specs/2026-07-23-lectio-go-rewrite-design.md b/docs/superpowers/specs/2026-07-23-lectio-go-rewrite-design.md index f0889e3..2c6824b 100644 --- a/docs/superpowers/specs/2026-07-23-lectio-go-rewrite-design.md +++ b/docs/superpowers/specs/2026-07-23-lectio-go-rewrite-design.md @@ -51,7 +51,8 @@ Module: `github.com/lukaszkasprzak/lectio`. Location: `~/git/projects/lectio`. ``` cmd/lectio/main.go -> cli.Run(args, stdin, stdout, stderr) int cmd/lectio-ui/main.go -> load config+data, tui.New(...), tea.NewProgram(...).Run() -internal/liturgy/ fetch + parse niedziela.pl; cache; sigla harvest/offline +internal/liturgy/ Section type; fetch + parse niedziela.pl; cache; harvest/offline; Load router +internal/tradlit/ missalemeum API: fetch + parse 1962 propers into []Section internal/bible/ embedded corpora + reference lookup + book aliases internal/psalter/ psalm versification (port of psalm_versify.py) internal/render/ text rendering: compare columns, section text (CLI) @@ -103,7 +104,10 @@ subset the tool actually feeds it: (`tabnowy0all`), fall back to `tabstary0all` with a warning; extract each section's heading, subtitle, citation, and paragraphs. Fail loudly if the tab is present but empty or absent (layout change). -- `Section{Heading, Subtitle, Citation, Paragraphs}`. +- `Section{Heading, Subtitle, Citation, PartID string; Paragraphs [][]string}` + (shared by both lectionaries; `PartID` drives part-filtering — see Config). +- `Load(cfg, opts) ([]Section, error)` routes to this modern source or to + `tradlit` by `cfg.Lectionary`, then applies part-filtering. ### Caching (fast repeat loads) Two layers under `~/.cache/lectio/` (honor `XDG_CACHE_HOME`): @@ -145,6 +149,42 @@ Tysiąclecia) is online-only and not embedded (copyright); **offline, `wuj` replaced by `wuj` where needed (see Config → `offline`). A date absent from the harvest gives a clear "run `lectio update` online" error. +## Lectionaries: new vs traditional + +The `lectionary` config selects the source; both produce a `[]Section`, so the +render/CLI/TUI/cache layers are shared. + +- **`new`** (default) — the modern Ordinary-Form readings from niezbednik.niedziela.pl + (`internal/liturgy`), as described above. +- **`traditional`** — the 1962-Missal propers from the missalemeum API + (`internal/tradlit`): `GET https://www.missalemeum.com/{lang}/api/v5/proper/{date}`, + `lang` = `traditional_lang` (`pl` or `en` — the only two the API serves). The + JSON is `[{info{title,...}, sections:[{id,label,body:[["...text..."]]}]}]`. Each + section becomes a `Section{Heading:label, PartID:lower(id), Paragraphs, Citation}`; + the citation is extracted from the `*Book c:v*` marker embedded in a reading's + body. Section ids: `Introitus, Oratio, Lectio, Graduale, Evangelium, + Offertorium, Secreta, Communio, Postcommunio` (plus Alleluia/Tractus/commemorations). + +**How the versions apply.** A traditional `Section` carries missalemeum's +vernacular text as its `Paragraphs` (the `pl`-role source text) and, for scripture +propers, a `Citation`. So the scripture parts (Introit, Epistle, Gradual, Gospel, +Offertory, Communion) flow through the *same* version-compare as the modern mode — +`vul` (Latin), `wuj`, `grb`, `drb` looked up from the embedded corpora by citation. +The prayer parts (Collect, Secret, Postcommunion) have no citation, so they render +only the missalemeum vernacular. + +**Latin caveat.** The missalemeum v5 API returns vernacular only (en/pl) — no +Latin. Latin for the *readings* comes from the embedded `vul` corpus via the +citation; Latin for the *prayers* is not available and those show vernacular only. +This is a documented limitation, surfaced with a short note on prayer sections. + +**Caching / offline.** Traditional pages cache like modern ones (`{date}.json` +under a `traditional/` subdir so the two lectionaries don't collide). `lectio +update` harvests whichever lectionary is active into its own sigla file +(`sigla.tsv` / `sigla-traditional.tsv`); offline builds the scripture-part +sections from the harvested citations. Prayer text is not harvested (it is not a +citation), so offline traditional shows the readings only. + ## Versions and psalm systems Ported from `ewangelia.py` constants: @@ -202,6 +242,8 @@ lectio help | lectio -h | lectio <cmd> -h - `--refresh` bypasses the cache and re-fetches. - `--offline` (global) skips the network and uses the sigla TSV; also applied automatically when a fetch fails. +- `--lectionary new|traditional` and `--lang pl|en` (global) override the config + `lectionary` / `traditional_lang` for one run. - `update` harvests forward from today (or `--from D`) up to `--days N` (default: until the unpublished horizon), writing the sigla TSV. - Flags override config. Exit codes: 0 ok, 1 runtime error (fetch/parse), 2 @@ -252,16 +294,55 @@ fixed. The CLI stays plain text (colour is a TUI concern). run, honoring `XDG_CONFIG_HOME`) → built-in defaults. Flags override. ```toml -schema_version = 1 -versions = ["pl", "wuj", "vul", "grb", "drb"] # compare set + TUI cycle order -default_version = "pl" # TUI start / `lectio show` default -width = 0 # CLI wrap width; 0 = detect terminal -all = false # default to all readings (true) or just the gospel (false) -offline = false # true = never fetch; read only harvested sigla + cache +schema_version = 1 +lectionary = "new" # "new" (niedziela.pl) or "traditional" (missalemeum, 1962) +traditional_lang = "pl" # vernacular for traditional propers: "pl" or "en" +versions = ["pl", "wuj", "vul", "grb", "drb"] # compare set + TUI cycle order +default_version = "pl" # TUI start / `lectio show` default +width = 0 # CLI wrap width; 0 = detect terminal +all = false # default to all parts (true) or just the gospel (false) +offline = false # true = never fetch; read only harvested sigla + cache + +# Which parts to show. Both tables are commented out -> every part is shown. +# Uncomment a table and set a part to false to hide it; parts you don't list +# stay shown. (Parsed as a map: a part is hidden only if explicitly false.) +# +# [parts.new] +# pierwsze_czytanie = true # 1. czytanie (1st reading) +# psalm = true # Psalm +# drugie_czytanie = true # 2. czytanie (2nd reading, on feasts) +# aklamacja = true # Aklamacja (acclamation) +# ewangelia = true # Ewangelia (gospel) +# +# [parts.traditional] +# introitus = true # Introit +# oratio = true # Collect +# lectio = true # Epistle +# graduale = true # Gradual / Alleluia / Tract +# evangelium = true # Gospel +# offertorium = true # Offertory +# secreta = true # Secret +# communio = true # Communion +# postcommunio = true # Postcommunion ``` -Unknown versions in config are rejected with a clear error. Invalid TOML falls -back to defaults with a stderr warning. +`Config` fields: `SchemaVersion int`, `Lectionary string`, `TraditionalLang +string`, `Versions []string`, `DefaultVersion string`, `Width int`, `All bool`, +`Offline bool`, and `Parts map[string]map[string]bool` (the `[parts.new]` / +`[parts.traditional]` tables). `Lectionary` must be `new` or `traditional`; +`TraditionalLang` must be `pl` or `en`; unknown versions/values are rejected with +a clear error. Invalid TOML falls back to defaults with a stderr warning. + +**Part filtering.** `Config.PartShown(lectionary, partID string) bool` returns +`true` unless `Parts[lectionary][partID]` is present and `false`. So a commented +(empty) `Parts` shows everything, and a user hides a part by uncommenting the +table and setting just that part to `false`. Part IDs: for `new`, +`pierwsze_czytanie`/`psalm`/`drugie_czytanie`/`aklamacja`/`ewangelia` (matched +from the niedziela heading); for `traditional`, the missalemeum section ids +lower-cased (`introitus`, `oratio`, `lectio`, `graduale`, `evangelium`, +`offertorium`, `secreta`, `communio`, `postcommunio`). Filtering applies whenever +all parts are in play (`--all`, `compare`, the TUI); the gospel-only default +(`all = false`) always shows just the gospel / `evangelium`. `offline = true` (or the `--offline` flag) makes lectio work purely from the `lectio update` harvest and cache — it never touches the network, and `pl` @@ -311,6 +392,11 @@ network-free daily read. - **psalter**: unit tests for `drb_verse` on titled/untitled/2-line-title psalms. - **liturgy.Parse**: fixture tests against a few cached HTML pages (a normal day, a split-reading feast, an unpublished date), asserting sections/citations. +- **tradlit.Parse**: fixture test against a saved missalemeum JSON response + (2026-07-22), asserting the proper sections, part ids, the extracted Gospel + citation, and vernacular paragraphs. +- **config.PartShown**: a commented (empty) `Parts` shows all; `{new:{psalm:false}}` + hides only the psalm and keeps the rest shown. - **liturgy cache + sigla**: round-trip the parsed JSON cache; harvest sigla from fixture pages into a temp TSV and read them back; offline `Load` builds sections from the TSV and renders the embedded versions with `pl` noted unavailable. |
