aboutsummaryrefslogtreecommitdiff
path: root/man
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-19 09:35:52 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-19 09:35:52 +0200
commit99172c86c518fdb2104c098b7b7a79e6c13ba8ea (patch)
tree62d7e82300c13136aa7ffb668c5ddb774ca049b6 /man
parentd71504ad9fc39b735689da32fa0be8a63c2cc7f8 (diff)
downloadcolitur-99172c86c518fdb2104c098b7b7a79e6c13ba8ea.tar.gz
colitur-99172c86c518fdb2104c098b7b7a79e6c13ba8ea.zip
feat(cli): colitur table and render
Computes and renders in one process. There is deliberately no stdin-fed render: honouring the pipe would need a JSON parser we would have to write, purely to serialise and immediately re-parse our own view -- a second hand-rolled component and a second place for the contract to drift, for no benefit. colitur emit --format json | jq still composes. An unknown extension with no --flavour is an error naming the six valid flavours, never a silent fallback to none: guessing wrong produces malformed output that looks fine until it does not. A malformed template reports the parser's own reason and exits 2. A template is user input; it must never crash the program.
Diffstat (limited to 'man')
-rw-r--r--man/colitur.1183
1 files changed, 182 insertions, 1 deletions
diff --git a/man/colitur.1 b/man/colitur.1
index 1db7f9a..da08a36 100644
--- a/man/colitur.1
+++ b/man/colitur.1
@@ -21,6 +21,13 @@ colitur \- deterministic liturgical calendar and lectionary engine (Roman rite,
.RB [ \-\-dtstamp " STAMP" ]
.br
.B colitur
+.BR table | render
+.BI \-\-year " YEAR"
+.BI \-\-template " FILE"
+.RB [ \-\-flavour " FLAVOUR" ]
+.RB [ \-\-overlay " FILE" " ...]"
+.br
+.B colitur
.BR \-h | \-\-help
.SH DESCRIPTION
.B colitur
@@ -80,6 +87,17 @@ See
.B EMIT
below.
.TP
+.BR table | render
+Compute one civil year and render it through a user\-supplied template, in one
+process.
+.B table
+and
+.B render
+are the same operation under two names \(em see
+.B RENDERING
+below for why there is no separate, stdin\-fed
+.B render .
+.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
@@ -112,7 +130,7 @@ below.
.TP
.BI \-\-overlay " FILE"
Apply a user calendar on top of the shipped one. Repeatable and ordered;
-.BR day ", " readings " and " emit
+.BR day ", " readings ", " emit ", " table " and " render
only. See
.B OVERLAYS
below.
@@ -145,6 +163,28 @@ is the emitted year. Never a clock read either way \(em see
.B EMIT
below.
.TP
+.BI \-\-year " YEAR"
+.RB ( "colitur table" " and " "colitur render" " only)"
+The civil year to compute,
+.B 1583..9999
+as elsewhere. Required.
+.TP
+.BI \-\-template " FILE"
+.RB ( "colitur table" " and " "colitur render" " only)"
+The template file to render the year through. Required. See
+.B RENDERING
+below.
+.TP
+.BI \-\-flavour " FLAVOUR"
+.RB ( "colitur table" " and " "colitur render" " only)"
+One of
+.BR latex ", " groff ", " html ", " xml ", " ics " or " none .
+Overrides the flavour that would otherwise be inferred from
+.BR \-\-template 's
+own extension. See
+.B RENDERING
+below.
+.TP
.BR \-h ", " \-\-help
Print a usage summary to standard output and exit 0.
.TP
@@ -299,6 +339,139 @@ applied on top of the shipped calendar, in order, before the range is
rendered. See
.B OVERLAYS
below.
+.SH RENDERING
+.BI "colitur table " \-\-year " YEAR " \-\-template " FILE"
+and
+.BI "colitur render " \-\-template " FILE " \-\-year " YEAR"
+are the
+.I same
+operation under two names: compute the resolved year, shape it into the
+same view
+.B emit
+uses, and render it through
+.I FILE
+in one process. Both accept
+.BR \-\-flavour " and " \-\-overlay
+identically.
+.SS Why there is no stdin\-fed render
+The design this project followed originally sketched a Unix pipe,
+.BR "compute | render" ,
+with
+.B render
+reading a serialised view back from standard input. That is deliberately
+.I not
+built.
+Honouring the pipe would require a JSON
+.I parser
+inside
+.B colitur
+\(em a second hand\-rolled component, purely so this program could read back a
+view it had just serialised itself, and a second place for the published
+output schema to drift out of step with what the parser actually accepts.
+That is a real cost for no benefit over calling the same view builder
+directly in the same process, which is what
+.B table
+and
+.B render
+both do.
+.PP
+Unix composition is not abandoned, only narrowed to where it is cheap and
+honest:
+.B "colitur emit \-\-format json | jq"
+still composes fine, because that JSON is the
+.I output
+of the pipeline, never something
+.B colitur
+itself has to parse back in.
+.SS Templates
+.I FILE
+is a deliberately logic\-less, Mustache\-family template: it is
+.I data,
+never a program. The only constructs are
+.BR {{placeholder}} ,
+.BR {{#section}}...{{/section}} ,
+.BR {{^inverted}}...{{/inverted}}
+and
+.BR {{!comment}} .
+There are no partials, no lambdas, no expression evaluation, no arithmetic,
+and no filesystem or process access from inside a template. There is
+deliberately no "raw" or triple\-brace form either \(em a template cannot opt
+out of its flavour's escaping.
+.PP
+The template renders against the same schema
+.B emit
+uses (season, week, slug, rank, colour, subject, names, citations,
+commemorations), reshaped for two artefacts from one model: a flat booklet
+(the
+.B days
+list, one entry per day of the year) and a month grid (the
+.B weeks
+list, with padding cells flagged for the leading and trailing blanks a grid
+needs and a booklet does not). A key absent on a given day (an optional field
+a rite does not always set) renders as the empty string rather than an error
+\(em the one deliberate silence, so a template survives a day that does not
+carry every optional field.
+.SS Flavours
+.BI \-\-flavour
+controls how interpolated
+.I values
+are escaped for the target format. It never touches the template's own
+literal markup, which is the author's and is trusted as\-is. One of:
+.RS
+.nf
+
+latex groff html xml ics none
+.fi
+.RE
+.PP
+When
+.B \-\-flavour
+is omitted it is inferred from
+.BR \-\-template 's
+own file extension:
+.RS
+.nf
+
+.I .tex -> latex
+.I .ms .mom .me -> groff
+.I .html .htm -> html
+.I .xml -> xml
+.I .ics -> ics
+.I .md .adoc .txt -> none
+.fi
+.RE
+.PP
+.B none
+escapes nothing: Markdown, AsciiDoc and plain text have no fixed
+metacharacter set, so escaping them here would produce worse output than
+leaving them alone.
+.PP
+An extension
+.B colitur
+does not recognise is a hard error naming the six flavours above; it is
+.I never
+a silent fallback to
+.BR none .
+Guessing the flavour wrong produces output that looks fine right up until
+the metacharacters it silently failed to escape show up in a rendered
+document.
+.RS
+.nf
+
+.B colitur table \-\-year 2027 \-\-template invite.wat
+colitur: cannot infer a flavour from ".wat"; pass \-\-flavour latex|groff|html|xml|ics|none
+.fi
+.RE
+.PP
+A malformed template reports the parser's own reason and exits 2, never a
+crash \(em a template is user input, exactly like an overlay file.
+.RS
+.nf
+
+.B colitur table \-\-year 2027 \-\-template bad.txt
+colitur: template bad.txt: unclosed section {{#days}}
+.fi
+.RE
.SH OVERLAYS
.TP
.BI \-\-overlay " FILE"
@@ -484,6 +657,14 @@ Run against a checkout's data rather than the installed copy:
.B COLITUR_DATA_DIR=~/git/projects/colitur/data/ef colitur day 2026
.fi
.RE
+.PP
+Render a year through a template, flavour inferred from the extension:
+.RS
+.nf
+
+.B colitur table \-\-year 2026 \-\-template booklet.tex > booklet.tex.out
+.fi
+.RE
.SH SOURCES
The calendar is computed against the 1962
.I Missale Romanum