| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
| |
Christmas Time runs to 13 January inclusive (RG 72-73) and time after Epiphany
opens on 14 January (RG 77), diverging from lectio, which starts
time-after-epiphany at 6 January. Holy Saturday stays in Passiontide: the
Easter Vigil is a night Mass, and a per-day calendar assigns a date by the
season governing its day-hours.
|
| |
|
|
|
|
|
| |
Eight seasons in canonical liturgical-year order, each carrying its RG
citation, and the four classes. season_slug_word is deliberately distinct from
season_to_string: slugs are lectionary keys adopted verbatim from lectio,
which calls Paschaltide 'easter' and Christmastide 'christmas'.
|
| |
|
|
|
|
|
|
|
| |
Make alignment impossible: both headers and to_row are derived from a single
list of (name, extractor) pairs, so reordering one without the other is
impossible. CSV schema cannot silently mislabel columns.
Add a meaningful test that pins the header names in order, not just length.
This catches column reordering regressions.
|
| |
|
|
|
|
|
| |
The boundary where rite-parametric types stop. CSV, JSON and the template
engine all render from this one schema, so they never see a type variable.
headers/to_row cover the scalar columns; names and citations are
variable-arity and wait for the richer encoders in Plan 5.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Five review findings, all in the test suite the task designates as the
algebra's specification:
- test_diagnostics's headline assertion was vacuous: it checked slug
presence after an add-over-existing, but hilary was already present
before the Add ran, so a broken implementation that recorded the
diagnostic and skipped applying the entry would still pass. Add now
carries a rank that genuinely differs from base()'s default, and the
assertion checks the field actually changed.
- Set_subject, Set_name, Remove_name, Set_citation and Remove_citation
were implemented but never exercised. Added coverage for all five,
including the case that matters most for Set_citation: setting a part
that already exists must replace it, not append a duplicate.
- Replace had zero coverage. Added tests for both its existing-slug path
(entry swapped, no diagnostic) and its absent-slug path (diagnostic
recorded, entry still added).
- merge's diagnostic accumulation was untested; test_merge_order discarded
the diagnostics it got back. Added a test asserting two overlays' each
producing one diagnostic come back in application order.
Extended the cel/entry test helpers with optional subject/names/citations
so the new tests can build fixtures with those fields populated.
|
| |
|
|
|
|
|
| |
add/suppress/replace/field-edit folded in order, last writer wins per field,
empty the identity. A directive naming an unknown slug, or adding one that
already exists, yields a diagnostic rather than silence or a hard failure:
overlays must survive a shifted base while still surfacing authoring errors.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
load previously had zero coverage despite being the module's only fallible-
I/O function and the one place the brief's literal code would have let an
exception escape on this sexplib version (Failure instead of Parse_error).
Add cases for a missing file, a malformed/unterminated sexp, an invalid slug
embedded in an otherwise well-formed layer, and a success round-trip.
Also add a same-date index case with three entries inserted out of slug
order, pinning that the by-date index accumulates rather than overwrites and
returns buckets in canonical order regardless of insertion order -- the
previous two-entry fixture only ever touched bucket sizes 0 and 1.
|
| |
|
|
|
|
|
| |
Entries sort by slug so equal layers serialise identically. The by-date index
is built once per layer rather than per year, since fixed dates are
year-independent; a full-domain sweep would otherwise rescan every entry for
every day. load turns parse and validation failures into result.
|
| |
|
|
|
|
|
|
|
|
| |
The comment explaining Celebration's single type parameter claimed OCaml
rejects a type variable that appears in no field. That is false: a phantom
season parameter compiles cleanly. The real reason is a design choice, not a
compiler constraint -- a celebration has no season of its own (season is
contextual to the day, and lives in Temporal.t), and a phantom parameter
would carry no information while forcing every consumer to thread a
meaningless variable.
|
| |
|
|
|
|
|
|
| |
Rite specificity is carried by type parameters plus a vocab record of
operations rather than by functors: the same guarantee that a rite cannot name
another rite's season, without threading module plumbing through every kernel
module. Celebration takes only the rank parameter, since it has no season
field and OCaml rejects a type variable that appears in no field.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Use [@@deriving sexp] with open Sexplib0.Sexp_conv instead of hand-rolling
converters (fixes non-standard Citation shape and missing field validation).
Names.t_of_sexp wraps derived version to enforce canonical sort on load.
Add tests:
- Names of_list duplicate handling
- Names sexp canonical sort guarantee (identical serialization)
- Names and Date_spec sexp roundtrips
Fix Names.remove to canonicalize output (defensive against non-canonical input).
|
| |
|
|
|
|
|
| |
Names is an open language-keyed assoc kept in canonical order so equal name
sets serialise identically. Citation carries references only, never text.
Date_spec ships the one form the EF sanctoral needs; 29 February is
constructible and resolves to None in common years.
|
| |
|
|
|
|
|
|
| |
test_lang exercised only of_string. Add a sexp round-trip plus a
check_raises proving a malformed-but-plausible code ("e1": right length,
fails the lowercase rule) is rejected by t_of_sexp rather than silently
accepted -- mirrors test_slug_sexp's guard against a future regression to
[@@deriving sexp].
|
| |
|
|
|
|
| |
Both parse through a smart constructor returning result, and both hand-write
t_of_sexp so a malformed value in a data file is rejected at load rather than
silently accepted -- deriving the converter would have bypassed validation.
|
| |
|
|
|
|
| |
The six liturgical colours and the Lord/BVM/saint/temporal distinction are
common to both Roman forms, so they are shared closed variants rather than
rite-parametric. Subject is so named because class is an OCaml keyword.
|
| |
|
|
|
|
|
| |
Adds sexplib and ppx_sexp_conv to the project and wires the ppx into the
kernel library. Date's sexp form is an ISO-8601 atom rather than the opaque
rata die, so data files stay human-editable and parsing revalidates the
1583..9999 domain.
|
| |
|
|
|
|
|
| |
Orients a fresh session: what colitur is, the authoritative docs, the
binding decisions, the architecture, the five validation layers, current
state and what comes next. The design spec and research register it points
at stay local (docs/ is gitignored).
|
| |
|
|
|
| |
Argv-parsed subcommand; validates the 1583..9999 domain (exit 2 otherwise);
prints 'name YYYY-MM-DD' lines. Cram test covers the output and the exit codes.
|
| |
|
|
|
|
| |
Ash Wednesday/Palm Sunday/Ascension/Pentecost/Corpus Christi as Easter+/-N.
Verified vs 2026 dates; exhaustive weekday invariants 1583..9999 (Ash Wed=Wed,
Ascension/Corpus Christi=Thu, Palm/Pentecost=Sun).
|
| |
|
|
|
|
|
| |
Anonymous Gregorian (Meeus/Jones/Butcher) for OF+EF; Meeus Julian mapped to the
proleptic-Gregorian date for future eastern rites. Verified vs known dates
(2000/2024-27, 1583; Orthodox 2023/24) and EXHAUSTIVELY over 1583..9999: every
Easter is a Sunday in [Mar22,Apr25].
|
| |
|
|
|
|
|
| |
Hinnant civil<->days rep (1970-epoch rata die); make validates month/day and
the 1583..9999 domain; of_rata/add_days are total arithmetic. Weekday, compare.
Tested: known weekdays, leap boundaries, rejects; qcheck round-trip / add-inverse
/ weekday-cycle properties over random in-range dates.
|
| |
|
|
|
| |
OCaml 5.2.0 local switch; colitur_kernel library, a colitur executable stub,
and an alcotest+qcheck test runner. AGPL LICENSE, README, generated colitur.opam.
|
| |
|