<feed xmlns='http://www.w3.org/2005/Atom'>
<title>colitur.git/lib/render/emit_json.mli, branch v0.10.1</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.10.1</id>
<link rel='self' href='https://git.labunix.xyz/colitur.git/atom?h=v0.10.1'/>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/'/>
<updated>2026-08-19T06:41:23Z</updated>
<entry>
<title>feat(render): CSV and JSON emitters, and the published contract</title>
<updated>2026-08-19T06:41:23Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-19T06:41:23Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=063d4058346f7dc03eb0aa5ba394b9a872d3f1e3'/>
<id>urn:sha1:063d4058346f7dc03eb0aa5ba394b9a872d3f1e3</id>
<content type='text'>
Both consume the VIEW, not the kernel, so every emitter and every
template describe exactly the same fields -- there is one vocabulary,
not five.

CSV is RFC 4180: a field with a comma is quoted. That is live on real
data, not hypothetical -- 'St. Joseph, Spouse of the Bl. Virgin Mary'
would otherwise split into two columns.

JSON is hand-rolled because the dependency list is frozen and escaping
is the only subtlety. Control characters below 0x20 are \u-escaped per
RFC 8259 section 7.

There are no numbers in the view, deliberately: a consumer never has to
guess whether week is 2 or "2".

schema/day-v1.json pins the shape. Once a phone subscribes or a site
fetches this, it is a promise to strangers -- adding a field is minor,
renaming one means /v2/.
</content>
</entry>
</feed>
