From 0f94c388880972f8e665ed01a6b38190bcc61499 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Thu, 20 Aug 2026 09:28:08 +0200 Subject: feat(cli): --lang and --raw, colitur lang, colitur config Names are Latin by default now; --raw restores the old byte-exact output, verified against a pre-branch binary built from a clean HEAD checkout, not merely asserted. day and readings gain a trailing display-name field (day's own name suffix, readings' own " | name" suffix) rather than a substitution in the slug's existing position: a name contains spaces and would otherwise break the space-separated columns, the same reasoning that already keeps readings a separate command. The field is present only when it differs from the slug already shown, which is a direct consequence of Lang.raw being the identity table (no lookup ever misses), not a special case threaded through day_line/readings_line -- under --raw, or any language with no entry for a given day, the trailing field is simply absent, byte for byte what this project printed before naming existed. An unknown language is an error naming what is available, never a silent fallback to Latin: a booklet quietly printed in the wrong language is worse than one that refuses to print. A declared fallback still chains, so a partial translation shows its fallback language rather than slugs. lang_dir mirrors data_dir's probe order exactly -- installed prefix, then build tree -- because an installed binary that finds calendar data but no language files is the failure this would otherwise ship. Config (lang/overlay/template/format) is loaded once, unconditionally, before dispatch: a config file that exists but fails to parse is fatal on every command, not only the ones that consult it, because a config the user wrote and colitur cannot honour is not something to silently carry on past. An unknown key or unknown section is reported and ignored, worded differently so a misspelled section reads differently from a misspelled key inside a recognised one. overlay's config default applies only when zero --overlay flags were given, never merged with a partial CLI list, so precedence stays flag > config > default in one direction throughout. colitur lang --list/--dump/--check and colitur config --show are what make "anyone can write a language file" true rather than merely permitted, the same pattern the overlay system already established with new-overlay and check. --check reports what is missing AND rejects an unknown slug (exit 1), because a key matching nothing is silently dead and its author would otherwise never learn why their own name does not appear. --dump emits sections in a fixed order (Lang.keys' own global sort keeps every section's keys contiguous), so two dumps of the same table are byte-identical. config --show resolves through the same Config.resolve every other command uses -- deliberately no separate provenance function, so the two cannot disagree -- and previews exactly what flags given on the same command line would resolve to anywhere else. One authorized change outside this task's own file list: emit_ics.ml's SUMMARY line was reading the unlocalised rank/colour pair ("class-1, white") beside an already-localised name, where the JSON schema right next to it correctly carries rank_name/colour_name ("II classis"/"albus"). Found while reviewing the published site; fixed at the source. --- lib/render/emit_ics.ml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/render/emit_ics.ml b/lib/render/emit_ics.ml index 4e06eae..b212930 100644 --- a/lib/render/emit_ics.ml +++ b/lib/render/emit_ics.ml @@ -57,9 +57,18 @@ let event b ~rite ~dtstamp d = if iso <> "" then begin (* [name] is the view's own resolved display string (view.ml) -- no further fallback needed here: under [Lang.raw] it already equals - [slug], which is what a miss used to require picking by hand. *) + [slug], which is what a miss used to require picking by hand. + + [rank_name]/[colour_name], not the bare [rank]/[colour]: those two + carry the kernel's own unlocalised strings ("class-1", "white"), + exactly the raw-slug shape [name] itself moved away from -- SUMMARY + is a human-facing calendar entry, and printing "(class-1, white)" + beside a properly resolved name (e.g. "II classis, albus") was the + one field this emitter had not yet been updated to localise; the + JSON/CSV/XML emitters already expose both pairs and a template author + already has to choose the localised one deliberately. *) let name = s d "name" in - let summary = Printf.sprintf "%s (%s, %s)" name (s d "rank") (s d "colour") in + let summary = Printf.sprintf "%s (%s, %s)" name (s d "rank_name") (s d "colour_name") in let desc = String.concat "\n" (List.filter (fun x -> x <> "") -- cgit v1.3