diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Makefile | 18 | ||||
| -rw-r--r-- | README.md | 287 |
3 files changed, 299 insertions, 7 deletions
@@ -1,5 +1,6 @@ /lectio /lectio-ui +/lectio-web dist/ *.test *.out @@ -1,21 +1,24 @@ -LECTIO := lectio -LECTIO_UI := lectio-ui +LECTIO := lectio +LECTIO_UI := lectio-ui +LECTIO_WEB := lectio-web PREFIX ?= $(HOME)/.local BINDIR := $(PREFIX)/bin .PHONY: help build install uninstall test vet fmt clean cross help: ## show this help @grep -hE '^[a-z-]+:.*##' $(MAKEFILE_LIST) | sed -E 's/:.*## /\t/' | sort -build: ## build ./lectio and ./lectio-ui +build: ## build ./lectio, ./lectio-ui and ./lectio-web go build -o $(LECTIO) ./cmd/lectio go build -o $(LECTIO_UI) ./cmd/lectio-ui -install: ## build and install both to $(BINDIR) + go build -o $(LECTIO_WEB) ./cmd/lectio-web +install: ## build and install all three to $(BINDIR) @mkdir -p $(BINDIR) go build -o $(BINDIR)/$(LECTIO) ./cmd/lectio go build -o $(BINDIR)/$(LECTIO_UI) ./cmd/lectio-ui - @echo "installed $(BINDIR)/$(LECTIO) and $(BINDIR)/$(LECTIO_UI)" + go build -o $(BINDIR)/$(LECTIO_WEB) ./cmd/lectio-web + @echo "installed $(BINDIR)/$(LECTIO), $(BINDIR)/$(LECTIO_UI) and $(BINDIR)/$(LECTIO_WEB)" uninstall: ## remove installed binaries - rm -f $(BINDIR)/$(LECTIO) $(BINDIR)/$(LECTIO_UI) + rm -f $(BINDIR)/$(LECTIO) $(BINDIR)/$(LECTIO_UI) $(BINDIR)/$(LECTIO_WEB) test: ## run tests go test ./... vet: ## go vet @@ -23,7 +26,7 @@ vet: ## go vet fmt: ## gofmt the tree gofmt -w . clean: ## remove build artifacts - rm -f $(LECTIO) $(LECTIO_UI); rm -rf dist + rm -f $(LECTIO) $(LECTIO_UI) $(LECTIO_WEB); rm -rf dist cross: ## cross-compile into dist/ @mkdir -p dist @for t in linux/amd64 linux/arm64 darwin/arm64 darwin/amd64 windows/amd64; do \ @@ -31,4 +34,5 @@ cross: ## cross-compile into dist/ echo " $$os/$$arch"; \ GOOS=$$os GOARCH=$$arch go build -o dist/$(LECTIO)-$$os-$$arch$$ext ./cmd/lectio; \ GOOS=$$os GOARCH=$$arch go build -o dist/$(LECTIO_UI)-$$os-$$arch$$ext ./cmd/lectio-ui; \ + GOOS=$$os GOARCH=$$arch go build -o dist/$(LECTIO_WEB)-$$os-$$arch$$ext ./cmd/lectio-web; \ done diff --git a/README.md b/README.md new file mode 100644 index 0000000..9b87c65 --- /dev/null +++ b/README.md @@ -0,0 +1,287 @@ +# lectio + +`lectio` is a self-contained Go rewrite of the Python `daily-reading` tool +(`ewangelia.py`). It fetches the day's Catholic liturgical readings and +shows them across five scripture versions with correct psalm +versification, and can run entirely offline once a date has been +harvested. There are no external tool dependencies at runtime, and no +network dependency at all in offline mode. + +Three binaries share the same config and reading pipeline: + +- **`lectio`** — subcommand CLI (`today`, `date`, `show`, `compare`, `update`) +- **`lectio-ui`** — a colored, scrollable Bubble Tea terminal reader +- **`lectio-web`** — a local HTMX browser UI (bundled, no CDN — works offline) + +## Install + +```sh +make build # ./lectio, ./lectio-ui, ./lectio-web in the current directory +make install # builds and installs all three to $PREFIX/bin (default ~/.local/bin) +make uninstall # removes them again +``` + +`PREFIX` can be overridden, e.g. `make install PREFIX=/usr/local`. + +Cross-compiled binaries for linux/darwin (amd64+arm64) and windows/amd64 +land in `dist/` via `make cross`. + +Requires Go 1.24+ to build. No other dependencies (`go.mod` only pulls in +Bubble Tea/Lipgloss for the TUI and go-toml for config parsing). + +## `lectio` — the CLI + +``` +lectio [today] [--all] [--raw] [--width N] [--refresh] +lectio date D [--all] [--raw] [--width N] [--refresh] D = YYYY-MM-DD +lectio show VERSION [--date D] [--all] [--raw] [--width N] [--refresh] +lectio compare LIST [--date D] [--all] [--width N] [--refresh] [--raw] +lectio update [--days N] [--from D] +lectio --version | -v +lectio help | -h | lectio <cmd> -h +``` + +Versions: `pl` (Polski, niedziela.pl), `wuj` (Wujek), `vul` (Wulgata), +`grb` (Grecki), `drb` (Douay-Rheims). + +Global flags (any subcommand, any position): + +- `--offline` — skip the network, use cached/harvested data only +- `--lectionary new|traditional` — override config `lectionary` for this run +- `--lang pl|en` — override config `traditional_lang` for this run + +Per-command flags: + +- `--all` — show every reading part (1st/2nd reading, psalm, acclamation, + gospel); default is the gospel only, unless config `all = true` +- `--raw` — omit the banner/headings (for piping) +- `--width N` — wrap width; `0` detects the terminal width, else falls + back to 80 (120 for `compare`) +- `--refresh` — bypass the cache and re-fetch +- `--date D` — date as `YYYY-MM-DD` (`show`/`compare` only; default: today) + +Exit codes: `0` ok, `1` runtime error (fetch/parse), `2` usage error. + +### Subcommands + +`today` (also the default with no subcommand) — the gospel (or `--all`) +for today, in the config's `default_version`: + +```sh +lectio +lectio today --all --width 100 +``` + +`date D` — same, for an arbitrary date: + +```sh +lectio date 2026-12-25 --all +``` + +`show VERSION` — one version's text, defaulting to today: + +```sh +lectio show wuj --date 2026-12-25 +``` + +`compare LIST` — several versions side by side (LIST is comma-separated; +falls back to config `versions` if omitted): + +```sh +lectio compare pl,wuj,drb --date 2026-04-05 +``` + +`update [--days N] [--from D]` — harvest future dates' scripture +citations into the offline sigla store (see "Offline mode" below); does +not respect `--lectionary`/`--offline`, it always harvests the modern +(niedziela.pl) lectionary: + +```sh +lectio update --days 30 +``` + +## `lectio-ui` — the terminal reader + +```sh +lectio-ui +``` + +A full-day, scrollable, colored view built on Bubble Tea. Key bindings: + +| Key | Action | +|---|---| +| `tab` / `shift+tab` | cycle to next/previous version | +| `←` / `→` | previous/next day | +| `j`/`↓`, `k`/`↑` | scroll down/up one line | +| `space` / `b` | page down/up | +| `g` / `G` | jump to top/bottom | +| `r` | refresh (re-fetch the current date) | +| `q` / `ctrl+c` | quit | + +Colors are a fixed light/dark-adaptive palette (Catppuccin-style, not +configurable per instance): the heading is accented, the citation line is +faint, verse numbers are muted, verse/paragraph text is the default +foreground, a psalm's refrain line is italic, and the header/footer bars +use an inverted background. Colors degrade automatically to plain text +when `NO_COLOR` is set or the terminal doesn't support them. + +## `lectio-web` — the browser UI + +```sh +lectio-web +``` + +Starts a local HTTP server, prints its URL, and best-effort opens it in +your default browser (failure to open — headless box, no browser — is +silent; just visit the printed URL). The port comes from config +`web_port`: `0` (the default) tries `1099` first, then falls back to any +free OS-assigned port if `1099` is taken; a non-zero value binds that +port exactly and fails if it's already in use. + +All static assets (htmx, base CSS, theme CSS) are embedded in the binary +and served locally — there is no CDN, so the page works fully offline +once running. + +Page controls: + +- **Date navigation** — a date picker plus `←`/`→` buttons +- **Lekcjonarz (lectionary)** — new vs traditional, same as `--lectionary` +- **Version checkboxes** — pl/wuj/vul/grb/drb, independent of any one + visitor's config +- **Zakres (all-parts toggle)** — gospel-only vs every part, same as `--all` +- **Układ (display mode)** — horizontal / vertical / interlinear, see below +- **Motyw (theme picker)** — swaps the theme stylesheet client-side + instantly, no server round trip +- **Passage lookup** — a free-text reference box (e.g. `J 20:1`) rendered + against the currently checked versions + +### Display modes (`web_display`) + +- **horizontal** (default) — each version's text stacked in its own block + under a shared heading +- **vertical** — the same per-version text laid out as side-by-side + columns, like the CLI's `compare` +- **interlinear** — every version interleaved verse-by-verse by + chapter:verse. `pl` cannot participate (niedziela.pl prose carries no + verse numbers), so it is silently substituted with `wuj` (dropped + entirely if `wuj` is already selected) + +## Configuration + +Config file: `~/.config/lectio/config.toml` (XDG-aware; auto-seeded with +the built-in defaults on first run), or the path in `$LECTIO_CONFIG` if +set. An invalid file falls back to defaults with a warning on stderr. + +```toml +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 +web_theme = "transfiguration" # built-in order/season theme or a user theme in ~/.config/lectio/themes/ +web_port = 0 # lectio-web port; 0 = try 1099, then any free port +web_display = "horizontal" # lectio-web layout: "horizontal" (stacked), "vertical" (columns), "interlinear" (verse-by-verse) + +# 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 +``` + +CLI flags (`--offline`, `--lectionary`, `--lang`) and `lectio-web` query +parameters override the corresponding config values for that run/request +only; the file itself is never rewritten. + +## Themes + +`lectio-web` ships 12 built-in, colour-only themes (they set colours +only — no fonts, spacing, borders, or layout, which all live in the fixed +`base.css`): + +Religious orders: `transfiguration` (dark, gold/olive — the default), +`desert_fathers` (light, sand/umber), `benedictines` (dark, black/gold), +`franciscans` (dark, brown/terracotta), `memento_mori` (dark, greyscale), +`camaldolese` (light, slate-blue). + +Liturgical seasons: `advent` (dark violet), `nativity` (light white/gold), +`lent` (dark ashen violet), `easter` (light radiant gold), `pentecost` +(dark ember/red), `ordinary` (light green). + +Set the default with `web_theme` in config, or pick one live from the +"motyw" dropdown in the browser UI. + +To write your own theme, drop a CSS file defining the required role +variables/classes (`--bg`, `--fg`, `.heading`, `.citation`, `.vnum`, +`.refrain`, link colours, border colours — see `docs/THEMES.md` for the +full list and a template) at: + +``` +~/.config/lectio/themes/<yourname>.css +``` + +Restart (or reload) `lectio-web`; `<yourname>` appears in the theme list +and overrides any built-in theme of the same name. + +## Offline mode and `lectio update` + +Two data stores back offline use, both outside the config file: + +- **Cache** (`~/.cache/lectio/`) — parsed HTML/JSON of dates already + fetched normally; used automatically before hitting the network. +- **Sigla store** (`~/.local/share/lectio/sigla.tsv`) — just the + section labels and scripture citations (no reading text) for dates + harvested by `lectio update`. + +Workflow: while online, run + +```sh +lectio update --days 30 +``` + +to walk forward from today (or `--from D`) harvesting citations into the +sigla TSV, stopping at niedziela.pl's unpublished horizon (or after +`--days N` days; `0`, the default, means "until unpublished"). Later, +with `offline = true` in config (or `--offline` on any command), reads +come only from the cache/sigla store, never the network — and since the +sigla store holds no `pl` text, `pl` is transparently substituted with +`wuj` wherever a version list would otherwise include it (CLI, TUI, and +`lectio-web`'s interlinear mode all apply this the same way). + +Offline mode currently only supports the "new" (modern) lectionary — +`lectionary = traditional` combined with offline is rejected with an +error, since traditional propers aren't harvested by `update`. + +## Lectionaries + +- **new** (default) — scrapes the modern Polish lectionary from + `niezbednik.niedziela.pl`, one page per day. +- **traditional** — the 1962 Roman Missal's propers of the day, fetched + from the `missalemeum.com` JSON API in either Polish or English + (`traditional_lang` / `--lang`; no other language is supported). + +Switch per run with `--lectionary new|traditional`, or set `lectionary` +in config for a permanent default. + +## License + +MIT — see `LICENSE`. |
