<feed xmlns='http://www.w3.org/2005/Atom'>
<title>colitur.git/lib/citation, branch v0.8.0</title>
<subtitle>deterministic OCaml engine to compute and validate liturgical calendars for multiple rites, template-driven output to year 9999</subtitle>
<id>https://git.labunix.xyz/colitur.git/atom?h=v0.8.0</id>
<link rel='self' href='https://git.labunix.xyz/colitur.git/atom?h=v0.8.0'/>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/'/>
<updated>2026-08-20T17:03:02Z</updated>
<entry>
<title>fix(citation): close the final review's blocking findings</title>
<updated>2026-08-20T17:03:02Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-20T17:03:02Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=1da70dc7ac03fe33fb92b172a0e26932764170d6'/>
<id>urn:sha1:1da70dc7ac03fe33fb92b172a0e26932764170d6</id>
<content type='text'>
The branch was RED and reported green. `dune test` exited 1: test/cli.t
pinned the pre-fix output `kings_1 19:3-8`, which the previous commit had
already fixed to `1 Reg 19:3-8`. The gate command piped dune through
`tail`, so it reported tail's exit status, and cram prints its diff
BEFORE the alcotest summary, so the two lines shown were the passing
ones. Verify with `dune test; echo $?`, never through a pipe.

A style file's own `book` key was unreachable. sigla_book resolved
against a hardcoded "abbr" and the result was applied unconditionally,
so the documented `[sigla] book = full` could never win. Render gains
book_string, and the style's own value is now the default that a flag or
config overrides. The unit test pinned style_of_fields correctly while
the wiring defeated it.

`lang --check` filtered the reference set to the celebration prefix, so
a file with no [bible] section at all reported a clean bill of health --
contradicting both the reason the keys change was made and lang.ml's own
comment. It now reports missing book names too.

The token test missed a FOURTH citation-bearing file: adjustments.sexp
writes citations as `Set_citation`, not `(reference ...)`. Its 16
citations all parse, so nothing was broken, but nothing was checking.
The first attempt at this fix read the file and extracted NOTHING -- the
marker stopped before the opening quote, so every payload was the part
label -- which is recorded in the code rather than left as a trap.

Also: colitur-config(5) claimed a trailing period the data does not
carry, and two la.ini scan quotes silently corrected OCR damage
("Ionae 3, I - I O", "Epistolse") while presenting themselves as
verbatim. Both are now marked as corrections.
</content>
</entry>
<entry>
<title>feat(citation): the Sigla facade, total by construction</title>
<updated>2026-08-20T13:44:29Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-20T13:44:29Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=987175105ead0ea78b960c0e638a81c6fd2384cf'/>
<id>urn:sha1:987175105ead0ea78b960c0e638a81c6fd2384cf</id>
<content type='text'>
format never raises and returns an unparseable citation unchanged, so a
gap degrades to today's behaviour rather than to a crash. The coverage
test asserts separately that no shipped citation takes that path.

verbatim is what --raw uses: an identity name table would still reformat
punctuation and renumber, which would break byte-exact diffing against
lectio.

The existing citation-coverage walk (1970-2070) now also drives a
round-trip check in the same pass: parse -&gt; render -&gt; parse must reach
the same structure, using Book.default_spelling for names (Book.to_string
returns the internal id, which is not a registered token and cannot be
read back). Proved with a mutation: changing the default style's
part_sep to a separator the parser does not accept reddened the
round-trip case on 31 multi-part citations and nothing else; reverted.
</content>
</entry>
<entry>
<title>feat(citation): default_spelling, and close two test gaps</title>
<updated>2026-08-20T13:13:37Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-20T13:13:37Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=ec70286daa72fd2a2a78a1cbab0fe2c268e5c743'/>
<id>urn:sha1:ec70286daa72fd2a2a78a1cbab0fe2c268e5c743</id>
<content type='text'>
Book.default_spelling returns the first registered spelling for an id. It
is the fallback display name, and it exists because the alternative is
worse: a language file's [bible] lookup is total and returns THE KEY on a
miss, so a book with no entry would render as "luke.abbr 5:12-14".
Falling back to the data's own spelling makes it render as "Luke
5:12-14" instead -- what colitur printed before this feature existed.
The degraded case is the old behaviour, the same principle Lang states
for its own key-returning misses.

Two test gaps closed, both found by mutation rather than by reading:

Parse's split_book scans a leading ordinal digit over '1'..'4', and no
case in the suite used an ordinal above 1. Narrowing the range to
'1'..'3' passed every test while seven real citations depend on it
("3 Kings 17:8-16", "4 Kings 5:1-15"). Parse-layer cases added; the
first attempt at this test asserted through Book.of_token, which is a
table lookup and never reaches split_book at all.

default_spelling is asserted to round-trip: every cited id's fallback
spelling must itself resolve back to that id, or Render and Parse
disagree the moment a book goes unnamed.
</content>
</entry>
<entry>
<title>feat(citation): render a parsed citation in a configurable style</title>
<updated>2026-08-20T13:09:49Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-20T13:09:49Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=a2cbb6b85e79fbc59b0879362c0f853757d51c07'/>
<id>urn:sha1:a2cbb6b85e79fbc59b0879362c0f853757d51c07</id>
<content type='text'>
A style is a set of format strings, so punctuation convention is data.

Values are unquoted here rather than in Overlay_ini: that parser trims
every value and is shared with overlays and [defaults], so teaching it
about quotes would change behaviour this feature has no business
changing.
</content>
</entry>
<entry>
<title>feat(citation): parse citations into structure</title>
<updated>2026-08-20T12:59:03Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-20T12:59:03Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=56e36188c6afc208b96b15b9a1d3d62bbbe2f705'/>
<id>urn:sha1:56e36188c6afc208b96b15b9a1d3d62bbbe2f705</id>
<content type='text'>
The parsed form is a book and a LIST of chapter-parts: the data cites
across chapters and lists disjoint verse ranges within one.

Two rules the shipped data forces and that are not obvious: a
semicolon-separated part may inherit the previous chapter rather than
restate it, and a chapter may be separated from its verses by a comma.
</content>
</entry>
<entry>
<title>fix(citation): survey all three citation-bearing files, not just the lectionary</title>
<updated>2026-08-20T12:54:01Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-20T12:54:01Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=a4eb9ed3cd93cbac493a873991dd5817906aad56'/>
<id>urn:sha1:a4eb9ed3cd93cbac493a873991dd5817906aad56</id>
<content type='text'>
The book table was built against data/ef/lectionary.sexp alone. That
undercounts: sanctoral.sexp carries more citations than the lectionary
and, together with commons.sexp, cites 21 book tokens the table was
missing entirely (62 distinct tokens across all three files, not 42),
several of them common (2 Tim appears 8+ times).

Add the missing spellings to existing ids (2 Cor, Col., Exod, Ezek,
James, Sir, Eccli) and ten new ids for books not cited before (1-2
Timothy, 2 Peter, Apocalypse, Judith, Malachi, Proverbs, Song of Songs,
Tobit, Wisdom). Sir and Rev are modern spellings sitting inside
Vulgate data, so both resolve to their Vulgate ids (ecclesiasticus,
apocalypse) rather than to the sirach/revelation tradition targets --
mapping them to a second id would double-map the same book.

Add a duplicate-spelling invariant test (List.assoc_opt would silently
prefer the first match on a collision) and a test that re-derives the
token set from all three data files at test time and asserts every
token resolves, rather than trusting a survey performed once by hand.
</content>
</entry>
<entry>
<title>feat(citation): canonical book ids and tradition mapping</title>
<updated>2026-08-20T12:40:12Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-20T12:40:12Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=405910d2fd245e7a11e09eecb8c6fffb68d2169c'/>
<id>urn:sha1:405910d2fd245e7a11e09eecb8c6fffb68d2169c</id>
<content type='text'>
Seven books arrive in two spellings, inherited from lectio's ini and
ultimately from Divinum Officium. Collapse them onto one id here rather
than editing generated data.

Naming and renumbering are kept apart: a tradition decides which book an
id denotes, a language file decides what it is called.
</content>
</entry>
</feed>
