aboutsummaryrefslogtreecommitdiff
path: root/man
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-18 13:55:18 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-18 13:55:18 +0200
commit36daf47dde9b0c16dacef31163ea74effdd5e7f3 (patch)
treefa7e5bdd618902fd1bcfc34318395a181f531254 /man
parent150f8c550d2f9ebbac61d195eb342eb2b2ec6b95 (diff)
downloadcolitur-36daf47dde9b0c16dacef31163ea74effdd5e7f3.tar.gz
colitur-36daf47dde9b0c16dacef31163ea74effdd5e7f3.zip
feat(overlay): a flat INI front end, which verifies its own output
A convenience format for calendars that add a few local feasts and drop one or two universal entries. Section names are slugs, a [overlay] section carries the id, and status/subject/layer default so the common case -- an ordinary local saint's feast -- says only what distinguishes it. It is a FRONT DOOR, not a second data model. It parses to exactly the Overlay.t the S-expression form parses to, and everything downstream is the same code on the same values; a test asserts an INI overlay and its hand-written sexp equivalent produce identical Overlay.t values. It is also deliberately less expressive -- Add, Suppress and single-field Edit only -- and refuses Replace, multi-field edits and citation edits BY NAME rather than dropping them silently. Anything it cannot say is a reason to write sexp. Little of this is new machinery: tools/bootstrap_sanctoral.ml has parsed INI and mapped it to celebrations since the sanctoral was bootstrapped from lectio. The dates needed extending, since that mapping handled only MM-DD; the flat forms are easter+N/easter-N and mon/day/nth, with nth negative to count from the end. `colitur convert` is a separate step rather than --overlay sniffing the extension, so the author can read what their INI became. When a date form was mistyped, "what did the engine actually get" is the question, and an invisible transpile cannot answer it. The conversion verifies its own output: the emitted text is parsed back with the same function that loads an overlay and must equal what the INI denoted, or nothing is written. That is the point of the module. A transpiler emitting valid-but-wrong sexp is the failure a convenience format invites, and `colitur check` could never catch it -- the output would parse cleanly and mean something else. That check was WRONG on the first attempt, in exactly the way it exists to prevent. It re-serialised the parsed value instead of parsing the text being returned, so it verified t -> sexp -> t, which is true by construction and proves nothing. Found by mutation: corrupting the renderer to emit a different overlay id sailed through and exited 0. It now parses the returned text, the mutation is caught with exit 2, and two tests fail under it where none did before.
Diffstat (limited to 'man')
-rw-r--r--man/colitur-overlay.592
-rw-r--r--man/colitur.19
2 files changed, 101 insertions, 0 deletions
diff --git a/man/colitur-overlay.5 b/man/colitur-overlay.5
index 00a84a7..a2d2dae 100644
--- a/man/colitur-overlay.5
+++ b/man/colitur-overlay.5
@@ -251,6 +251,98 @@ accordingly. A local feast that never appears in output has usually lost that
contest rather than failed to load \(em
.B colitur check
will confirm it loaded.
+.SH THE FLAT INI FORM
+For a calendar that only adds a few local feasts, drops one or two universal
+entries, and recolours nothing complicated, there is a flatter form converted
+by
+.BR "colitur convert" .
+Section names are slugs; a
+.RB [ overlay ]
+section carries the id.
+.RS
+.nf
+
+[overlay]
+id = my\-parish
+
+[our\-patron]
+date = 07\-11
+rank = class\-3
+colour = white
+name.en = St Example, Patron
+
+[our\-dedication]
+date = oct/sun/1
+rank = class\-1
+colour = white
+name.en = Dedication of Our Church
+
+[stanislaus]
+edit = yes
+colour = red
+
+[barbara]
+suppress = yes
+.fi
+.RE
+.PP
+.I status
+defaults to
+.BR feast ,
+.I subject
+to
+.BR saint ,
+and
+.I layer
+to the file's id, so the common case \(em an ordinary local saint's feast \(em
+says only what distinguishes it. Dates take the three forms
+.IR MM\-DD ,
+.IB easter + N
+or
+.IB easter - N
+, and
+.IB mon / day / nth
+such as
+.B oct/sun/1
+or
+.B oct/sun/\-1
+for the last.
+.PP
+.B This form is deliberately less expressive.
+It covers
+.BR Add ", " Suppress
+and single\-field
+.BR Edit .
+.B Replace
+, multi\-field edits, citation edits and
+.B Remove_name
+are not expressible, and the converter refuses them
+.I by name
+rather than dropping them silently. Anything it cannot say is a reason to
+write the S\-expression form, not a reason to grow this one.
+.PP
+.B The conversion verifies its own output.
+The generated text is parsed back with the same function that loads an
+overlay, and must equal what the INI denoted; nothing is written if it does
+not. This matters because a transpiler emitting
+.I valid but wrong
+S\-expressions is the failure a convenience format invites, and
+.B colitur check
+could never catch it \(em the output would parse cleanly and simply mean
+something else.
+.RS
+.nf
+
+.B colitur convert my\-parish.ini > my\-parish.sexp
+.B colitur check my\-parish.sexp
+.fi
+.RE
+.PP
+The conversion is a separate step rather than something
+.B \-\-overlay
+does invisibly, so you can read what your INI became. When a date form was
+mistyped, "what did the engine actually get" is the question, and an invisible
+transpile cannot answer it.
.SH SEE ALSO
.BR colitur (1)
.SH LICENSE
diff --git a/man/colitur.1 b/man/colitur.1
index 6463415..58e46ff 100644
--- a/man/colitur.1
+++ b/man/colitur.1
@@ -65,6 +65,15 @@ occurrence, commemoration and transfer.
.BI readings " YEAR"
The Mass reading citations, one line per day.
.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
+parsed back with the same function that loads an overlay, and must mean
+exactly what the INI said. A separate step rather than teaching
+.B \-\-overlay
+to sniff the extension, so you can see what your INI became. See
+.BR colitur\-overlay (5).
+.TP
.B new\-overlay
Print a starter overlay file to standard output, for redirection. Every value
in it is a placeholder that will appear in