aboutsummaryrefslogtreecommitdiff
path: root/man
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-19 10:18:24 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-19 10:18:24 +0200
commit2760d43d695ba08fc33f65357590675707b6570d (patch)
tree8c139100c5babd6fce6c7af6d55b7f4938a86efd /man
parent24de019a3e1d5b9a6d4601bdd65489813baa7e58 (diff)
downloadcolitur-2760d43d695ba08fc33f65357590675707b6570d.tar.gz
colitur-2760d43d695ba08fc33f65357590675707b6570d.zip
feat(cli): colitur publish -- the static tree
Writes ef/<year>.{json,csv,xml,ics}, one JSON per day, the schema and a generated index. That tree is the API: any web server or git repo serves it, and nothing runs at request time. Deterministic: publishing twice is byte-identical, asserted in cli.t. That is what makes publishing into a git repo safe -- the diff shows only real change, and you review it before pushing. Non-destructive: a manifest records exactly the files this tool wrote, so --prune can only remove files a previous run created. A file you put in the output directory yourself is never touched, with or without --prune. Asserted in both directions. Pruning a stale file also removes any directory it leaves empty behind it (e.g. an old year's own ef/<year>/ tree), stopping at --out itself -- without this, a pruned year's own directory would survive empty and test -d would still see it. schema/day-v1.json is resolved the same prefix-relative way data/ef's own sexp files are (installed vs build-tree, probed rather than assumed), never from cwd, and a missing schema fails with one line on stderr before anything is written rather than emitting an empty file. Needed schema/day-v1.json wired into the root dune file's default alias and into test/dune's cram deps -- unlike data/ and templates/, nothing made dune mirror schema/ into the build tree before this. unix is added to bin/dune's libraries for mkdir_p; it ships with the compiler, so colitur.opam and dune-project are unchanged.
Diffstat (limited to 'man')
-rw-r--r--man/colitur.1157
1 files changed, 154 insertions, 3 deletions
diff --git a/man/colitur.1 b/man/colitur.1
index da08a36..d015a49 100644
--- a/man/colitur.1
+++ b/man/colitur.1
@@ -28,6 +28,15 @@ colitur \- deterministic liturgical calendar and lectionary engine (Roman rite,
.RB [ \-\-overlay " FILE" " ...]"
.br
.B colitur
+.B publish
+.BI \-\-from " YEAR"
+.BI \-\-to " YEAR"
+.BI \-\-out " DIR"
+.RB [ \-\-overlay " FILE" " ...]"
+.RB [ \-\-prune ]
+.RB [ \-\-dtstamp " STAMP" ]
+.br
+.B colitur
.BR \-h | \-\-help
.SH DESCRIPTION
.B colitur
@@ -98,6 +107,14 @@ are the same operation under two names \(em see
below for why there is no separate, stdin\-fed
.B render .
.TP
+.B publish
+Write the static tree that
+.I is
+this program's API: a civil\-year range rendered once, as files, so any web
+server or git repository can serve it and nothing runs at request time. See
+.B PUBLISH
+below.
+.TP
.BI convert " FILE" .ini
Convert a flat INI overlay to the S\-expression form, on standard output. The
conversion verifies its own output before emitting it: the generated text is
@@ -130,7 +147,7 @@ below.
.TP
.BI \-\-overlay " FILE"
Apply a user calendar on top of the shipped one. Repeatable and ordered;
-.BR day ", " readings ", " emit ", " table " and " render
+.BR day ", " readings ", " emit ", " table ", " render " and " publish
only. See
.B OVERLAYS
below.
@@ -144,7 +161,7 @@ Required. See
below.
.TP
.BI \-\-from " YEAR" ", " \-\-to " YEAR"
-.RB ( "colitur emit" " only)"
+.RB ( "colitur emit" " and " "colitur publish" " only)"
The inclusive civil\-year range to render, each
.B 1583..9999
as elsewhere.
@@ -154,7 +171,7 @@ must not be after
Both required.
.TP
.BI \-\-dtstamp " STAMP"
-.RB ( "colitur emit \-\-format ics" " only)"
+.RB ( "colitur emit \-\-format ics" " and " "colitur publish" " only)"
Fix the feed's own DTSTAMP instead of the default
.IR YYYY0101T000000Z ,
where
@@ -163,6 +180,26 @@ is the emitted year. Never a clock read either way \(em see
.B EMIT
below.
.TP
+.BI \-\-out " DIR"
+.RB ( "colitur publish" " only)"
+The directory to write the static tree into. Created if it does not exist.
+Required. See
+.B PUBLISH
+below.
+.TP
+.B \-\-prune
+.RB ( "colitur publish" " only)"
+Remove files a previous
+.B publish
+run into the same
+.B \-\-out
+wrote that this run did not rewrite. Never removes a file that is not
+recorded in
+.IR out /.colitur\-manifest ,
+regardless of this flag. See
+.B PUBLISH
+below.
+.TP
.BI \-\-year " YEAR"
.RB ( "colitur table" " and " "colitur render" " only)"
The civil year to compute,
@@ -472,6 +509,109 @@ crash \(em a template is user input, exactly like an overlay file.
colitur: template bad.txt: unclosed section {{#days}}
.fi
.RE
+.SH PUBLISH
+.BI "colitur publish " \-\-from " YEAR " \-\-to " YEAR " \-\-out " DIR"
+writes the static tree that
+.I is
+this program's API: every file a civil\-year range can be asked for,
+computed once and written out, so any web server or git repository can
+serve the result as\-is and nothing runs at request time.
+.RS
+.nf
+
+ef/<year>.json one civil year, all days, whole\-year emitters
+ef/<year>.csv
+ef/<year>.xml
+ef/<year>.ics
+ef/<year>/<mm>/<dd>.json one file per day
+schema/day\-v1.json the published JSON contract
+index.html a generated index page, not a template
+\&.colitur\-manifest every path this run wrote, one per line
+.fi
+.RE
+.PP
+Every emitted file goes through the same emitters
+.B emit
+uses; a published
+.I .ics
+file for a given year is byte\-for\-byte what
+.B "colitur emit \-\-format ics"
+would print for that year, and
+.B \-\-dtstamp
+means exactly what it means there. The per\-day JSON files carry the same
+shape as the whole\-year one, scoped to a single day \(em
+.B "colitur table"
+and template authors needing one day's data can read either.
+.PP
+.B Deterministic.
+Publishing the same
+.B \-\-from / \-\-to
+range into an empty directory twice produces a byte\-identical tree. Nothing
+in the publish path reads the wall clock; the
+.I .ics
+files' own DTSTAMP defaults to a fixed value derived from the emitted year,
+exactly as it does under
+.B emit
+(see
+.B EMIT
+above), and
+.B \-\-dtstamp
+overrides it the same way. This is what makes publishing into a git
+repository safe:
+.B git status
+shows only genuine change, and you review an actual diff before pushing,
+never a rewrite of files that did not change.
+.PP
+.B Non\-destructive.
+.B publish
+writes only files it owns, and records the relative path of every one of
+them in
+.IR out /.colitur\-manifest
+(itself never subject to pruning). A file you put in the output directory
+yourself \(em by hand, or from some other tool \(em is never named in that
+manifest, so it is never touched,
+.I whether or not
+.B \-\-prune
+is given.
+.RS
+.nf
+
+.B "touch out/MY\-NOTES.txt"
+.B "colitur publish \-\-from 2027 \-\-to 2027 \-\-out out \-\-prune"
+.B "test \-f out/MY\-NOTES.txt && echo kept"
+kept
+.fi
+.RE
+.PP
+.B \-\-prune
+removes exactly the entries a
+.I previous
+publish into the same
+.B \-\-out
+wrote that this run did not rewrite \(em typically an earlier year's own
+per\-day files, when a later
+.B publish
+targets a different
+.B \-\-from / \-\-to
+range into the same directory. A directory a stale entry's removal leaves
+empty is removed too (so, for example,
+.I out/ef/2027/
+itself goes away once every file under it is gone), but nothing above
+.B \-\-out
+is ever touched, and
+.B \-\-out
+itself is never removed even when nothing is left in it. Without
+.BR \-\-prune ,
+old entries are left in place, and only the manifest is rewritten to
+describe the current run.
+.PP
+.BR \-\-overlay
+is accepted exactly as on
+.BR day ", " readings " and " emit :
+applied on top of the shipped calendar, in order, before each year in the
+range is rendered. See
+.B OVERLAYS
+below.
.SH OVERLAYS
.TP
.BI \-\-overlay " FILE"
@@ -665,6 +805,17 @@ Render a year through a template, flavour inferred from the extension:
.B colitur table \-\-year 2026 \-\-template booklet.tex > booklet.tex.out
.fi
.RE
+.PP
+Publish a year range as a static tree, then keep it in step with
+.B \-\-prune
+as the range moves:
+.RS
+.nf
+
+.B colitur publish \-\-from 2026 \-\-to 2027 \-\-out ~/public/colitur
+.B colitur publish \-\-from 2027 \-\-to 2028 \-\-out ~/public/colitur \-\-prune
+.fi
+.RE
.SH SOURCES
The calendar is computed against the 1962
.I Missale Romanum