diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-26 13:30:09 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-26 13:30:09 +0200 |
| commit | 9b8821f7b914c94f5b2c8eeda05407ee921b3d5a (patch) | |
| tree | 0aca637921a3792b50e46a2830b869d6b7c4d3ac /tools/bootstrap_lectionary_of.ml | |
| parent | 9cc763c169a6ce4ebbdbed506c5eb2dad1f9f3c1 (diff) | |
| download | colitur-9b8821f7b914c94f5b2c8eeda05407ee921b3d5a.tar.gz colitur-9b8821f7b914c94f5b2c8eeda05407ee921b3d5a.zip | |
feat(of-lectionary): disclose the citation-conversion residual in the header
Fix option (c) from the I2 review finding, done alongside the parser
fix itself rather than deferred: tools/bootstrap_lectionary_of.ml now
runs every emitted reference through Colitur_citation.Parse.parse at
generation time and adds a fourth COVERAGE item plus a named listing
to data/of/lectionary.sexp's own header, so the 41-reference residual
(all chapter-crossing hyphen ranges, see the citation-fix commit) is
disclosed in the artifact a reader actually opens, not only in a task
report or test file.
Regenerated against the pinned lectio snapshot (dune exec
tools/bootstrap_lectionary_of.exe -- ../lectio/internal/caldata/
of-lectionary.ini data/of/lectionary.sexp); diffed against the
pre-change file to confirm the change is header-only, zero lines
removed, the sexp payload byte-identical. Re-pins the file's own
SHA-256 in test_lectionary_of.ml accordingly (re-derived with
sha256sum, not transcribed from generator stdout, matching that
test's own stated discipline).
Diffstat (limited to 'tools/bootstrap_lectionary_of.ml')
| -rw-r--r-- | tools/bootstrap_lectionary_of.ml | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/tools/bootstrap_lectionary_of.ml b/tools/bootstrap_lectionary_of.ml index da37bd9..a679b01 100644 --- a/tools/bootstrap_lectionary_of.ml +++ b/tools/bootstrap_lectionary_of.ml @@ -825,6 +825,34 @@ let temporal_day_gap ~lectionary ~year_start = done; (!count, !total, List.rev !misses) +(* Fix wave I2 (final-review.md, 2026-08-25-colitur-of-phases-3-5): every + reference this file emits, run through the SAME parser [colitur readings] + itself uses to convert to Latin sigla ({!Colitur_citation.Sigla.format} + -> {!Colitur_citation.Parse.parse} on a miss). Disclosed here, at + generation time, rather than left for a reader to discover as a silent + "- | -"-shaped surprise or an unconverted English fragment sitting next + to Latin ones -- this is what I2's own review finding asked for as the + minimum acceptable fix if full conversion could not be reached, and it + was not: see test/test_citation_coverage_of.ml for the pinned, exact + residual and book.ml's own citation for why it remains (chapter-crossing + hyphen ranges -- "2:29-3:6" -- a {!Colitur_citation.Parse.t} shape this + parser does not represent, deliberately not built this task; every OTHER + shape this file's data used to expose, including 345 previously- + unregistered book names, is now fixed at the source). *) +let citation_conversion_census lect = + let total = ref 0 and bad = ref [] in + List.iter + (fun (_slug, cits) -> + List.iter + (fun (c : Citation.t) -> + incr total; + match Colitur_citation.Parse.parse c.Citation.reference with + | Ok _ -> () + | Error _ -> if not (List.mem c.Citation.reference !bad) then bad := c.Citation.reference :: !bad) + cits) + (Lectionary.entries lect); + (!total, List.sort compare !bad) + let sha256 path = let ic = Unix.open_process_in (Printf.sprintf "sha256sum %s" (Filename.quote path)) in let line = try input_line ic with End_of_file -> die "sha256sum failed" in @@ -846,6 +874,7 @@ let () = let gap_count, gap_total, gap_misses = temporal_day_gap ~lectionary:lect ~year_start:Rite_of.Temporal_of.year_start in + let cit_total, cit_bad = citation_conversion_census lect in let oc = open_out dst in Printf.fprintf oc "; data/of/lectionary.sexp -- OF (2002) temporal + sanctoral lectionary\n\ @@ -926,15 +955,33 @@ pairs -> %d colitur slugs mapped, %d ini bases genuinely excluded (structurally\ ; ferial (Lectionary_of.readings' own step 2 -> step 3) -- this is\n\ ; OLM norms working as designed for a saint with no proper of\n\ ; their own, not a gap in this data.\n\ + ; (4) Citation-siglum conversion (fix wave I2, 2026-08-26 review): of\n\ + ; %d emitted (First, Gospel) citation fields, %d distinct\n\ + ; references (out of the full %d) do not parse -- every one a\n\ + ; hyphen range that crosses a chapter boundary (\"2:29-3:6\"), a\n\ + ; {!Colitur_citation.Parse.t} shape this parser's [part]/\n\ + ; [verse_range] types do not represent, deliberately not built\n\ + ; this task (see book.ml's own [is_single_chapter] neighbourhood\n\ + ; for what WAS fixed: 345 previously-unregistered book names and\n\ + ; verse sub-letter markers, both closed at the parser/book-table\n\ + ; level, not here). Such a reference still prints, verbatim,\n\ + ; never a crash or a dropped citation -- {!Colitur_citation.Sigla\n\ + ; .format}'s own documented contract on a parse miss. Pinned\n\ + ; exactly, both directions, by test/test_citation_coverage_of.ml.\n\ + ; Named below.\n\ ; Regenerate with:\n\ ; eval $(opam env) && dune exec tools/bootstrap_lectionary_of.exe -- %s %s\n" src (sha256 src) (List.length secs) (List.length resolved) report.mapped (List.length excluded_bases) (List.length report.unmapped) (List.length entries) gap_total gap_count (List.length report.unmapped) (List.length resolved) (Hashtbl.length sanctoral_slugs) report.sanctoral_passthrough - (Hashtbl.length sanctoral_slugs - report.sanctoral_passthrough) src dst; + (Hashtbl.length sanctoral_slugs - report.sanctoral_passthrough) + cit_total (List.length cit_bad) cit_total src dst; Printf.fprintf oc "; Unmapped lectio bases (%d):\n" (List.length report.unmapped); List.iter (fun b -> Printf.fprintf oc "; %s\n" b) report.unmapped; + Printf.fprintf oc "; Citations that do not parse (%d distinct, all chapter-crossing ranges):\n" + (List.length cit_bad); + List.iter (fun r -> Printf.fprintf oc "; %s\n" r) cit_bad; Printf.fprintf oc "; Temporal_of slugs (2004-2051) with no lectionary entry (%d, informational --\n\ ; most are the Christmas-season/late-Advent date-vs-weekday gap named above):\n" (List.length uncovered_temporal); |
