aboutsummaryrefslogtreecommitdiff

clectio

tiny, fast, suckless daily readings.

clectio prints the Catholic liturgical day and its Mass readings for any date. It computes nothing at run time: the calendar, the reading citations and the scripture text are all compiled in. One table lookup, no config file, no network, no dependencies beyond libc. The default text is the public-domain Latin Vulgate, and the whole program fits on a 1.44 MB floppy.

It is the small cousin of lectio, the Go engine that computes and generates clectio's data.

Build

make                      # Ordinary Form, English sigla, Latin Vulgate
./clectio                 # today
./clectio 2026-12-25      # a given date
./clectio -g 2026-12-25   # the Gospel only
./clectio -a              # all readings (override a Gospel-only build)
./clectio --month         # this month at a glance (day, colour, celebration)
./clectio --month 2026-04 > apr.txt   # a month to a file for reference
make install              # binary into $PREFIX/bin, man page into $PREFIX/share/man

Needs only a C99 compiler and libc. It builds in about a second.

The run-time options are -a/--all, -g/--gospel (which reading set to print, overriding the compiled default), --month [YYYY-MM | N] (one line per day of a month — weekday, colour and celebration, no readings; defaults to the current month) and -h/--help. Everything else is compile-time. Reading text wraps to the terminal width by default (see WRAP); piped output is left one line per verse.

Configure (suckless style)

Edit config.h (copied from config.def.h on first build), then make:

  • FORM_OF / FORM_EF — Ordinary Form (1969) or Extraordinary Form (1962)
  • SIGLA_ENGLISH / SIGLA_LATIN — citation dialect (Jer 14 vs Ier 14)
  • COLOR — colour the day name with its liturgical colour
  • GOSPEL_ONLY — default reading set: every reading (0) or the Gospel only (1); override per run with -a / -g
  • WRAP — wrap reading text at N columns; 0 fits the terminal (and leaves piped output unwrapped)

One form per binary; for both, build twice. The interface is English only.

Bring your own Bible

The default build embeds the Latin Vulgate. clectio compiles in only the ~12,000 verses the lectionary actually cites (never a whole Bible), so it stays well under 1 MiB with any text. To build with a different translation, point make at a corpus and it repacks exactly those verses from it:

make CC=gcc CORPUS=/path/to/mybible.tsv

You already have four corpora in the required format under lectio's internal/bible/: the Vulgate (vul) lives in corpora/; Douay-Rheims (drb), Wujek (wuj) and Greek (grb) are opt-in under corpora_optional/. So an English (Douay-Rheims) or Polish (Wujek) build is just:

make CC=gcc CORPUS=~/git/projects/lectio/internal/bible/corpora_optional/drb.tsv
make CC=gcc CORPUS=~/git/projects/lectio/internal/bible/corpora_optional/wuj.tsv

The build repacks the text blob for whichever form config.h selects: the default (Ordinary Form) writes text_of.lz; add #define FORM_EF to config.h first for an Extraordinary Form build, which writes text_ef.lz instead.

Corpus format

A plain UTF-8 file, six columns separated by a single TAB, one verse per line. These three real rows show the shape (arrows mark the tabs):

Genesis → Ge   → 1  → 1  → 1  → In the beginning God created heaven, and earth.
John    → John → 43 → 20 → 1  → AND on the first day of the week, Mary Magdalen …
1 John  → 1Jn  → 62 → 5  → 11 → And this is the testimony, that God hath given …

column: 1 Book   2 Abbrev  3 BookNum  4 Chapter  5 Verse  6 Text

clectio matches a citation to a row on Book + Chapter + Verse (columns 1, 4, 5) and prints column 6. What that means for your file:

  • Book (col 1) must be the full name the calendar's keys use — e.g. 1 John, Song of Songs, Numbers, not 1Jn or Cant. Copy the exact spellings from any shipped *.tsv (the safest start is to take vul.tsv and replace only the text column).
  • Chapter and Verse (cols 4, 5) must follow Vulgate numbering — the versification the lectionary is keyed to. A Bible numbered differently (modern Psalm numbers, split or renamed books) will silently misalign, so a translation not already Vulgate-numbered has to be re-numbered first.
  • Abbrev (col 2) and BookNum (col 3) are ignored by clectio, but the columns must still be present so every line has six fields (a line with fewer is skipped).
  • Text (col 6) is the verse; runs of whitespace are collapsed to one space.

A verse the corpus does not contain prints blank — it never fails the day; the build just warns how many verses were missing. The default Vulgate build needs only a C compiler; a CORPUS= rebuild also needs gzip (which mktext uses to pack the text).

Switching back to the Vulgate

The shipped text_of.lz / text_ef.lz hold the packed Vulgate text and are git-tracked; a CORPUS= build overwrites the one for the form you built. To restore it:

git checkout text_of.lz          # or text_ef.lz for an EF build
make CC=gcc clean && make CC=gcc

Bring your own calendar

The calendar is data too. Out of the box it is the universal Roman calendar, compiled in. You can change it in two ways, sized to how much you need — bounded by one hard limit: clectio has no calendar engine, it looks the calendar up in a compiled table rather than computing one.

Minor: name + colour of a fixed date — standalone, in calendar.h

For a local name and colour on a fixed date (a diocesan patron, a national memorial, a renaming), edit calendar.h — same suckless flow as config.h: it is copied from calendar.def.h on first build; edit it and make. No lectio, no toolchain.

static const Override overrides[] = {
    { 5, 16, RED,   "Saint Andrew Bobola, priest and martyr" },
    { 8, 15, WHITE, "Assumption of Our Lady, Patroness" },
    { 0, 0, 0, 0 }   /* keep this row last */
};

Fields are { month, day, colour, "name" }; colours are GREEN WHITE RED VIOLET ROSE BLACK. Overrides apply to both the single-day and --month output, every year.

Limits (all because there is no engine): - fixed dates only — no movable / computed feasts; - changes the name and colour only, not a day's readings or its rank / precedence (the table stores neither). The readings shown stay the underlying day's — which is correct for a memorial, since it uses the weekday readings; - an override wins unconditionally, so only override a date whose celebration you truly mean to replace.

Full: readings, ranks, movable feasts — via lectio, then recompile

Anything the engine must compute — proper readings, a changed rank, a movable feast — is done in lectio (its Go engine is where clectio's tables come from) and baked back into gen/. The running clectio stays standalone; only regenerating needs lectio and a Go toolchain.

  1. Describe the change as a lectio calendar layer (see lectio's README, "Calendar of saints"). A layer entry can set rank, colour, name.<lang>, and reading.first|psalm|second|acclamation|gospel:

    lectio --cal-dump mine        # writes ~/.config/lectio/calendars/mine.ini
    $EDITOR ~/.config/lectio/calendars/mine.ini
    lectio --cal-check mine
    
  2. Regenerate clectio's tables with that layer applied (old for the EF):

    cd ~/git/projects/lectio
    go run ./cmd/clectio-gen -caldir ~/.config/lectio/calendars -use mine \
        new 2025 2054 ~/git/projects/clectio/gen/
    

(-sanctorale DIR instead applies a full of.ini/ef.ini replacement. The book table stays embedded, so a stale books.ini can't affect the result. The 30-year range takes roughly a minute.)

  1. Rebuild clectio, repacking the text so any newly-cited verses are included:
    cd ~/git/projects/clectio
    make CC=gcc clean
    make CC=gcc CORPUS=~/git/projects/lectio/internal/bible/corpora/vul.tsv
    

(A change that cites only already-embedded verses would build without CORPUS=, but repacking is the safe default.)

To undo it and return to the shipped calendar: git checkout gen/ text_of.lz (or text_ef.lz) and rebuild.

Coverage

The compiled calendar runs 2025–2054. Dates outside that range are reported, not guessed. To extend the range, regenerate gen/ with lectio's clectio-gen (see "Bring your own calendar" above).

Files

clectio.c        the program: date -> table lookup -> print
config.def.h     compile-time configuration
calendar.def.h   local calendar overrides (name + colour by fixed date)
puff.c/.h        DEFLATE decompressor (Mark Adler's puff, public domain)
mktext.c         build tool: resolve verse keys against a corpus, gzip-pack the text
bin2h.c          build tool: embed the packed text as C
clectio.1        the manual page (installed by make install)
gen/             generated, corpus-independent data (calendar + citations)
text_of.lz       the default Vulgate text, DEFLATE-packed (one per form)

Licence

clectio's own code is GPL-3.0-or-later (see LICENSE). puff.c is Mark Adler's public-domain inflate, bundled unchanged. The data in gen/ is generated from lectio and is dates and scripture references — facts, not copyrightable. The compiled scripture text is a separate work under its own terms; the default, the Latin Vulgate, is public domain. Distribute a build made with a different Bible only where that translation permits it.