diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-26 13:30:02 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-26 13:30:02 +0200 |
| commit | 9cc763c169a6ce4ebbdbed506c5eb2dad1f9f3c1 (patch) | |
| tree | b38d6e418c7de49766478a47f5654086157e66e0 /test/test_citation.ml | |
| parent | 1a3046e2a3793fe52ec518818b19a6f15aadbb75 (diff) | |
| download | colitur-9cc763c169a6ce4ebbdbed506c5eb2dad1f9f3c1.tar.gz colitur-9cc763c169a6ce4ebbdbed506c5eb2dad1f9f3c1.zip | |
fix(citation): recognise English-canonical OF books, verse sub-letters
35% of OF citation fields (259/730 on colitur readings --rite of 2026)
printed unconverted -- 1 John renders on 2 January but not 3 January.
Two independent causes, both in the citation/siglum path, neither in
the OF data itself:
1. Book.table only ever surveyed the three EF citation-bearing files,
so 345 references citing a book no EF file happens to use (Job,
Ruth, Judges, 1/2 Samuel, 1/2 Chronicles, 1/2 Maccabees, Baruch,
Ecclesiastes, Habakkuk, Haggai, Nahum, Zechariah, Zephaniah,
Deuteronomy, Amos, Micah, Lamentations, Ezra, Joshua, 2/3 John,
Jude, Philemon, plus "Isaiah"/"Jeremiah"/"Ezekiel"/"Malachi"/"Mat"/
"The Acts"/"Tobit"/"Song of Solomon" spelling variants of books EF
already knows) failed as "unknown book". Added as a new, separate
of_lectionary_table rather than folded into the EF-surveyed table:
none of these 25 new books is attested in the EF's own scans, and
lang/la.ini's own header refuses to fabricate an uncited Latin
title, so they are resolvable (parse + render, falling back to
their own English spelling) but deliberately excluded from Book.all
-- test_lang_coverage.ml's la.ini-completeness promise is preserved
exactly for the ids it already covered, not silently weakened.
2. Parse's grammar could not read a verse number carrying a lectionary
sub-verse letter ("11a", "1bcde") at all -- the dominant remaining
failure shape once (1) was fixed. verse_range now carries a
verse_num { n; suffix } on each boundary, PRESERVED through
rendering rather than dropped (dropping would silently lose real
precision the source text carries). Chapter numbers are untouched
(nothing in the data ever attaches a letter to one).
A third, subtler bug surfaced by (1): registering "jude"/"philemon"/
"2 John"/"3 John" exposed Parse's existing "leading comma-number is a
chapter" heuristic misreading a single-chapter book's bare verse list
("Jude 17,20b-25") as chapter 17 -- a wrong PARSE, worse than the
previous safe "unknown book" failure. Book.is_single_chapter now tells
Parse to skip that heuristic for the four one-chapter books and default
to chapter 1.
Residual, honestly enumerated rather than forced to zero: 41 distinct
references (of 1540) are hyphenated ranges crossing a chapter boundary
("2:29-3:6") -- a Parse.t shape verse_range/part do not represent, a
type restructuring deliberately not attempted this task. Pinned exactly
by the new test_citation_coverage_of.ml, both directions (a new failure
or one of these 41 starting to convert both go red), and disclosed in
data/of/lectionary.sexp's own regenerated provenance header (tools/
bootstrap_lectionary_of.ml now runs the same parser at generation time
and names the count and the set).
Verified EF-unaffected: git diff v1.0.0..HEAD -- lib/kernel/
lib/rites/rite_ef/ data/ef/ is empty, and `colitur day`/`readings`
output for 2027 is byte-identical against the pre-fix binary.
Diffstat (limited to 'test/test_citation.ml')
| -rw-r--r-- | test/test_citation.ml | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/test/test_citation.ml b/test/test_citation.ml index dae4610..3cbc8c6 100644 --- a/test/test_citation.ml +++ b/test/test_citation.ml @@ -267,10 +267,11 @@ module P = Colitur_citation.Parse (* Render a parse back to a debug string so a test can assert shape compactly: "book|chapter:v-v,v-v|chapter:v". *) let show (t : P.t) = + let num (v : P.verse_num) = string_of_int v.P.n ^ v.P.suffix in let range (r : P.verse_range) = match r.P.last with - | None -> string_of_int r.P.first - | Some l -> Printf.sprintf "%d-%d" r.P.first l + | None -> num r.P.first + | Some l -> Printf.sprintf "%s-%s" (num r.P.first) (num l) in let part (p : P.part) = Printf.sprintf "%d:%s" p.P.chapter @@ -396,7 +397,9 @@ let test_subst_unknown_placeholder_alone () = the assertion isolates exactly the numeral and nothing else. *) let roman_of n = let luke = match B.of_token "Luke" with Some id -> id | None -> assert false in - let t : P.t = { P.book = luke; parts = [ { P.chapter = n; verses = [ { P.first = 1; last = None } ] } ] } in + let t : P.t = + { P.book = luke; parts = [ { P.chapter = n; verses = [ { P.first = { P.n = 1; suffix = "" }; last = None } ] } ] } + in let style = R.style_of_fields [ ("book_sep", ""); ("chapter_verse", "{chapter_roman}") ] in R.render style ~names:(fun _ _ -> "") t |
