aboutsummaryrefslogtreecommitdiff
path: root/man/colitur.1
blob: d015a494d49c7e4b8519a017dadb531dfb637b52 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
.TH COLITUR 1 "2026" "colitur" "User Commands"
.SH NAME
colitur \- deterministic liturgical calendar and lectionary engine (Roman rite, 1962)
.SH SYNOPSIS
.B colitur
.BR easter | temporal | day | readings
.I YEAR
.br
.B colitur
.BR day | readings
.I YEAR
.BI \-\-overlay " FILE"
.RI [ ... ]
.br
.B colitur
.B emit
.BI \-\-format " FMT"
.BI \-\-from " YEAR"
.BI \-\-to " YEAR"
.RB [ \-\-overlay " FILE" " ...]"
.RB [ \-\-dtstamp " STAMP" ]
.br
.B colitur
.BR table | render
.BI \-\-year " YEAR"
.BI \-\-template " FILE"
.RB [ \-\-flavour " FLAVOUR" ]
.RB [ \-\-overlay " FILE" " ...]"
.br
.B colitur
.B publish
.BI \-\-from " YEAR"
.BI \-\-to " YEAR"
.BI \-\-out " DIR"
.RB [ \-\-overlay " FILE" " ...]"
.RB [ \-\-prune ]
.RB [ \-\-dtstamp " STAMP" ]
.br
.B colitur
.BR \-h | \-\-help
.SH DESCRIPTION
.B colitur
computes the liturgical calendar of the 1962 Roman Missal \(em the
Extraordinary Form \(em and the Mass reading citations for every day, entirely
offline and without a network. Its name is
.I computus liturgicus
crossed with the Latin
.IR colitur ,
"He is worshipped".
.PP
For each day it resolves the season, the week, the observed celebration with
its rank and colour, any commemorations, any transfers, and the day's Epistle
and Gospel. It emits reading
.I references
only \(em
.RB \(lq "Jn 3:16" \(rq
\(em and never scripture text.
.PP
The engine is total and deterministic over the whole domain
.BR "1583..9999" .
It reads no clock, draws no randomness, and given the same data produces the
same answer for any year in range. Years outside the domain are refused at the
boundary rather than approximated.
.PP
Each report covers 1 January to 31 December of the civil
.IR YEAR .
That is deliberately not a liturgical year, which is Advent\-anchored and
straddles two civil years;
.B colitur
resolves both liturgical years that touch the requested civil one and prints
the civil slice.
.SH COMMANDS
.TP
.BI easter " YEAR"
Easter and the movable feasts anchored to it \(em Ash Wednesday, Palm Sunday,
Ascension, Pentecost, Corpus Christi \(em one per line, as
.RI \(lq name " " date \(rq.
.TP
.BI temporal " YEAR"
The temporal cycle alone, one line per day, before the sanctoral calendar is
resolved against it. Chiefly useful for inspecting season and week boundaries
in isolation.
.TP
.BI day " YEAR"
The resolved day identity, one line per day: the temporal cycle and the
sanctoral calendar reconciled by the rite's own rules of precedence,
occurrence, commemoration and transfer.
.TP
.BI readings " YEAR"
The Mass reading citations, one line per day.
.TP
.B emit
Render a civil\-year range through one of five emitters \(em
.BR csv ", " json ", " sexp ", " xml " or " ics .
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
.B publish
Write the static tree that
.I is
this program's API: a civil\-year range rendered once, as files, so any web
server or git repository can serve it and nothing runs at request time. See
.B PUBLISH
below.
.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
.B day
output if left unedited, so a half\-finished overlay is visible rather than
silently inert.
.TP
.BI check " FILE" ...
Load each overlay, apply it to the shipped calendar, and report what it does:
the directive counts, the slug each targets, and any directive that matched
nothing. Exits
.B 2
if a file fails to load or a directive found no target, so it composes into a
Makefile or a pre\-commit hook. It answers three narrow questions \(em does
the file parse, does every directive find its target, and what does the merged
result contain. It does
.I not
validate a calendar against the rubrics, and cannot: see
.B OVERLAYS
below.
.TP
.BI \-\-overlay " FILE"
Apply a user calendar on top of the shipped one. Repeatable and ordered;
.BR day ", " readings ", " emit ", " table ", " render " and " publish
only. See
.B OVERLAYS
below.
.TP
.BI \-\-format " FMT"
.RB ( "colitur emit" " only)"
One of
.BR csv ", " json ", " sexp ", " xml " or " ics .
Required. See
.B EMIT
below.
.TP
.BI \-\-from " YEAR" ", " \-\-to " YEAR"
.RB ( "colitur emit" " and " "colitur publish" " only)"
The inclusive civil\-year range to render, each
.B 1583..9999
as elsewhere.
.I FROM
must not be after
.IR TO .
Both required.
.TP
.BI \-\-dtstamp " STAMP"
.RB ( "colitur emit \-\-format ics" " and " "colitur publish" " only)"
Fix the feed's own DTSTAMP instead of the default
.IR YYYY0101T000000Z ,
where
.I YYYY
is the emitted year. Never a clock read either way \(em see
.B EMIT
below.
.TP
.BI \-\-out " DIR"
.RB ( "colitur publish" " only)"
The directory to write the static tree into. Created if it does not exist.
Required. See
.B PUBLISH
below.
.TP
.B \-\-prune
.RB ( "colitur publish" " only)"
Remove files a previous
.B publish
run into the same
.B \-\-out
wrote that this run did not rewrite. Never removes a file that is not
recorded in
.IR out /.colitur\-manifest ,
regardless of this flag. See
.B PUBLISH
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
.BR \-V ", " \-\-version
Print the version and exit 0.
.SH OUTPUT FORMAT
.SS day
.RS
.nf
date weekday season week slug rank colour [+commemoration ...]
.fi
.RE
.PP
Space\-separated, with one
.BI + slug
suffix per admitted commemoration. A
.B \-
in the week column means the day carries no week number.
.RS
.nf

2026\-04\-05 sunday paschaltide 1 ef\-easter\-sunday class\-1 white
2026\-11\-02 monday time\-after\-pentecost 23 commemoration\-of\-all\-souls class\-1 black
2057\-03\-26 monday lent 3 annunciation\-of\-the\-blessed\-virgin\-mary class\-1 white +ef\-lent\-3\-monday
.fi
.RE
.SS readings
.RS
.nf
date slug | Epistle | Gospel
.fi
.RE
.PP
A reading citation contains spaces and commas, so this report separates its
fields with
.RB \(lq " | " \(rq
where
.B day
stays space\-separated. That is the reason the citations are a separate command
rather than extra columns on
.BR day :
appended there, no field number could recover where the Epistle ended. A
.B \-
in either citation field means none was resolved.
.RS
.nf

2026\-12\-25 ef\-nativity | Heb 1:1\-12 | John 1:1\-14
2038\-03\-06 sts\-felicitas\-perpetua | Ecclus 51:1\-8, 12 | Matt 13:44\-52
.fi
.RE
.PP
Both reports are one line per day and ordered by date, so they compose with
.BR grep (1),
.BR awk (1)
and
.BR join (1)
in the ordinary way.
.SH EMIT
.BI "colitur emit " \-\-format " FMT " \-\-from " YEAR " \-\-to " YEAR"
renders the same resolved day \(em season, week, slug, rank, colour,
subject, Latin and English names, citations, commemorations \(em through one
of five emitters, for every day in the inclusive civil\-year range
.IR FROM .. TO .
Every emitter consumes one shared view of the data, so all five describe
exactly the same fields.
.TP
.B csv
RFC 4180. One header row for the whole run, not one per year, so a
multi\-year range still has exactly one header and
.BR wc (1)
or
.B "awk 'NR>1'"
behave as expected.
.RS
.nf

.B colitur emit \-\-format csv \-\-from 2026 \-\-to 2026 | head \-2
date,rite,season,week,slug,rank,colour,subject,name_la,name_en,first,gospel,comms
2026\-01\-01,ef,christmastide,,ef\-circumcision,class\-1,white,temporal,,,Titus 2:11\-15,Luke 2:21,
.fi
.RE
.TP
.B json
One JSON object per requested year, concatenated. Shape pinned by
.IR schema/day\-v1.json .
.RS
.nf

.B colitur emit \-\-format json \-\-from 2026 \-\-to 2026 | head \-c 40
{"rite":"ef","year":"2026","months":[{...
.fi
.RE
.TP
.B sexp
One S\-expression per day, one per line \(em the same
.I Liturgical_day.t
shape used internally, printed with
.IR sexplib "'s " to_string_hum .
.TP
.B xml
Element\-per\-field, one
.I <calendar>
document per requested year, concatenated. Attributes carry identity only
(rite, year, date); everything else is an element. Shape pinned by
.IR schema/colitur\-v1.xsd ,
checked by
.B make check\-schema
when
.BR xmllint (1)
is installed.
.TP
.B ics
RFC 5545. One
.I VCALENDAR
per requested year, concatenated, one all\-day
.I VEVENT
per day. Lines are folded at 75 octets and end
.RI ( CRLF ),
matching the protocol exactly \(em
.RB \(lq " cat \-A " \(rq
on the output shows
.B ^M$
at each line end.
.RS
.nf

.B colitur emit \-\-format ics \-\-from 2026 \-\-to 2026 | head \-1
BEGIN:VCALENDAR
.fi
.RE
.PP
.B \-\-dtstamp
fixes the feed's own
.I DTSTAMP
field, which RFC 5545 requires on every event. Without it the value defaults
to
.I YYYY0101T000000Z
for the emitted year \(em a fixed value, not a clock read \(em so two
.B emit \-\-format ics
runs over identical data are byte\-identical, which matters for a
reproducible build or a diffable published calendar file. Nothing in the
.B emit
path reads the wall clock, for any format.
.PP
.BR \-\-overlay
is accepted exactly as on
.B day
and
.BR readings :
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 PUBLISH
.BI "colitur publish " \-\-from " YEAR " \-\-to " YEAR " \-\-out " DIR"
writes the static tree that
.I is
this program's API: every file a civil\-year range can be asked for,
computed once and written out, so any web server or git repository can
serve the result as\-is and nothing runs at request time.
.RS
.nf

ef/<year>.json          one civil year, all days, whole\-year emitters
ef/<year>.csv
ef/<year>.xml
ef/<year>.ics
ef/<year>/<mm>/<dd>.json         one file per day
schema/day\-v1.json      the published JSON contract
index.html               a generated index page, not a template
\&.colitur\-manifest      every path this run wrote, one per line
.fi
.RE
.PP
Every emitted file goes through the same emitters
.B emit
uses; a published
.I .ics
file for a given year is byte\-for\-byte what
.B "colitur emit \-\-format ics"
would print for that year, and
.B \-\-dtstamp
means exactly what it means there. The per\-day JSON files carry the same
shape as the whole\-year one, scoped to a single day \(em
.B "colitur table"
and template authors needing one day's data can read either.
.PP
.B Deterministic.
Publishing the same
.B \-\-from / \-\-to
range into an empty directory twice produces a byte\-identical tree. Nothing
in the publish path reads the wall clock; the
.I .ics
files' own DTSTAMP defaults to a fixed value derived from the emitted year,
exactly as it does under
.B emit
(see
.B EMIT
above), and
.B \-\-dtstamp
overrides it the same way. This is what makes publishing into a git
repository safe:
.B git status
shows only genuine change, and you review an actual diff before pushing,
never a rewrite of files that did not change.
.PP
.B Non\-destructive.
.B publish
writes only files it owns, and records the relative path of every one of
them in
.IR out /.colitur\-manifest
(itself never subject to pruning). A file you put in the output directory
yourself \(em by hand, or from some other tool \(em is never named in that
manifest, so it is never touched,
.I whether or not
.B \-\-prune
is given.
.RS
.nf

.B "touch out/MY\-NOTES.txt"
.B "colitur publish \-\-from 2027 \-\-to 2027 \-\-out out \-\-prune"
.B "test \-f out/MY\-NOTES.txt && echo kept"
kept
.fi
.RE
.PP
.B \-\-prune
removes exactly the entries a
.I previous
publish into the same
.B \-\-out
wrote that this run did not rewrite \(em typically an earlier year's own
per\-day files, when a later
.B publish
targets a different
.B \-\-from / \-\-to
range into the same directory. A directory a stale entry's removal leaves
empty is removed too (so, for example,
.I out/ef/2027/
itself goes away once every file under it is gone), but nothing above
.B \-\-out
is ever touched, and
.B \-\-out
itself is never removed even when nothing is left in it. Without
.BR \-\-prune ,
old entries are left in place, and only the manifest is rewritten to
describe the current run.
.PP
.BR \-\-overlay
is accepted exactly as on
.BR day ", " readings " and " emit :
applied on top of the shipped calendar, in order, before each year in the
range is rendered. See
.B OVERLAYS
below.
.SH OVERLAYS
.TP
.BI \-\-overlay " FILE"
.RB ( \-o )
Apply a user\-supplied calendar on top of the shipped universal one. Repeatable
and ordered.
.PP
Overlays are applied
.I on top of
the 1962 universal calendar, never instead of it. The shipped adjustments \(em
which carry the inseparable Peter/Paul commemoration, the Major Litanies, St
Barbara and Rogation Wednesday \(em are applied first, then each
.B \-\-overlay
in the order given. Last writer wins, so a later file may deliberately override
an earlier one, or a universal entry, by naming its slug.
.PP
The workflow:
.RS
.nf

.B colitur new\-overlay > my\-parish.sexp
.B $EDITOR my\-parish.sexp
.B colitur check my\-parish.sexp
.B colitur day 2026 \-\-overlay my\-parish.sexp
.fi
.RE
.PP
The format is documented in full in
.BR colitur\-overlay (5).
In brief, an overlay is an S\-expression file with an
.I id
and a list of directives:
.BR Add ", " Suppress ", " Replace " and " Edit .
An added entry carries its own date specification, which may be a fixed
.RI ( month ", " day )
pair, an
.I Easter_offset
in days (signed; Easter itself is 0), or an
.I Nth_weekday
of a month \(em the
.I nth
may be negative to count from the end, so
.B \-1
is the last \(em so a patronal feast on "the first Sunday of October" or a
dedication anniversary reckoned from Easter are both expressible.
.PP
In an added celebration the
.I citations
and
.I layer
fields may be omitted: they default to empty and to the overlay's own
.IR id .
The remaining six are required, and each is a closed set \(em
.I rank
is
.BR Class1 ", " Class2 ", " Class3 " or " Class4 ,
.I status
is
.B Feast
or
.BR Commemoration_only ,
.I colour
is
.BR White ", " Red ", " Violet ", " Green ", " Black " or " Rose ,
and
.I subject
is
.BR Lord ", " Bvm ", " Saint " or " Temporal .
See
.I <prefix>/share/colitur/examples/diocesan\-example.sexp
for a worked, runnable example of all four directives and all three date
shapes:
.RS
.nf

.B colitur day 2026 \-\-overlay <prefix>/share/colitur/examples/diocesan\-example.sexp
.fi
.RE
.PP
Accepted on
.B day
and
.B readings
only. The other commands read no sanctoral data at all, so the flag would have
no effect there and is
.I refused
rather than silently ignored.
.PP
.B An overlay is applied, not validated.
This program's test layers \(em properties over every year in the domain, a
differential against a sibling engine, two published\-calendar oracles, and
hand\-verified pins \(em assert things about the
.I shipped
calendar. None of them can vouch for a file you supply. A directive naming a
slug that does not exist prints a warning to standard error and the run
continues, so a typo in a local calendar is visible rather than silent; a file
that fails to load is fatal.
.SH ENVIRONMENT
.TP
.B COLITUR_DATA_DIR
Read the calendar data from this directory instead of the installed or
build\-tree location. If it is set and contains no
.IR sanctoral.sexp ,
.B colitur
exits 2 naming the directory; it does
.I not
fall back to another copy. Naming a directory states an intent, and quietly
computing a calendar from different data than the one requested is a failure
mode this program refuses.
.SH FILES
.TP
.I <prefix>/share/colitur/ef/
The installed calendar data: the sanctoral calendar, its one hand\-authored
overlay, the temporal lectionary and the Commons. Four S\-expression files.
.TP
.I <prefix>/share/colitur/examples/diocesan\-example.sexp
A worked example overlay, shipped as runnable documentation. Every
celebration in it is invented; copy it and put your own calendar in its place.
.TP
.I <exedir>/../data/ef/
The build\-tree location, used when running from a source checkout.
.PP
Resolution order is
.B COLITUR_DATA_DIR
first, then the installed directory, then the build tree. A directory counts
only if it actually contains
.IR sanctoral.sexp ,
so a failed or half\-removed installation falls through to a working checkout
instead of shadowing it.
.SH EXIT STATUS
.TP
.B 0
Success.
.TP
.B 2
Bad usage, a year outside 1583..9999, or the calendar data could not be read.
.SH EXAMPLES
Easter and its dependent feasts:
.RS
.nf

.B colitur easter 2026
.fi
.RE
.PP
One date:
.RS
.nf

.B colitur day 2026 | grep '^2026\-12\-25'
.fi
.RE
.PP
Every first\-class day of a year:
.RS
.nf

.B colitur day 2026 | awk '$6 == "class\-1"'
.fi
.RE
.PP
Days carrying at least one commemoration:
.RS
.nf

.B colitur day 2027 | grep '+'
.fi
.RE
.PP
A local calendar on top of the universal one:
.RS
.nf

.B colitur day 2026 \-\-overlay ~/calendars/diocese.sexp
.B colitur day 2026 \-\-overlay ~/calendars/diocese.sexp \-\-overlay ~/calendars/parish.sexp
.fi
.RE
.PP
Run against a checkout's data rather than the installed copy:
.RS
.nf

.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
.PP
Publish a year range as a static tree, then keep it in step with
.B \-\-prune
as the range moves:
.RS
.nf

.B colitur publish \-\-from 2026 \-\-to 2027 \-\-out ~/public/colitur
.B colitur publish \-\-from 2027 \-\-to 2028 \-\-out ~/public/colitur \-\-prune
.fi
.RE
.SH SOURCES
The calendar is computed against the 1962
.I Missale Romanum
and its
.IR "Rubricae Generales" ,
which are the sole authority for what
.B colitur
emits. Published calendars \(em missalemeum, Divinum Officium, gcatholic \(em
are used as comparison oracles in the test suite only: a divergence from one
is flagged loudly and adjudicated against the Missal, never silently adopted.
Several such divergences have been resolved in this engine's favour.
.SH LIMITATIONS
Only the Extraordinary Form (1962) is implemented; the Ordinary Form is a
planned peer module, not an overlay of this one.
.PP
Only the Epistle and the Gospel are emitted. The chants \(em Psalm, Gradual,
Tract, Alleluia, Sequence \(em are deliberately not computed: they have no
source in this engine's data and no oracle to validate them against, and the
engine rejects any citation part outside those two rather than emit one it
cannot stand behind.
.PP
The votive Office of the Blessed Virgin Mary on Saturday is kept, but the
seasonal selection among its five Masses is not yet implemented, so its
reading citations fall back to the day's ordinary ones.
.SH SEE ALSO
.BR colitur\-overlay (5)
for the overlay file format \(em every directive, every field, the three date
shapes and worked examples.
.PP
.BR lectio (1)
.SH LICENSE
AGPL\-3.0\-or\-later.