aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: c9937ec4c410f9798cb751348da043e26a0f734f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
# 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 14 built-in, colour-only themes (they set colours — with
all fonts, spacing, borders and layout fixed in `base.css`). A theme may
additionally set `--theme-font` to change the reading face, and a monospace
reading face can be turned on for any theme (see `web_mono` and the "mono"
top-bar toggle below):

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,
monospace), `dominicans` (black & white).

Liturgical seasons and feasts: `advent` (dark violet), `nativity` (light
white/gold), `lent` (dark ashen violet), `easter` (light radiant gold),
`pentecost` (red/white/gold), `ordinary` (light green), `epiphany` (dark
indigo/gold), `marian` (light blue/white/gold).

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`.