diff options
Diffstat (limited to 'lib/rites/rite_ef/lectionary_ef.ml')
| -rw-r--r-- | lib/rites/rite_ef/lectionary_ef.ml | 99 |
1 files changed, 86 insertions, 13 deletions
diff --git a/lib/rites/rite_ef/lectionary_ef.ml b/lib/rites/rite_ef/lectionary_ef.ml index d7b2497..b996412 100644 --- a/lib/rites/rite_ef/lectionary_ef.ml +++ b/lib/rites/rite_ef/lectionary_ef.ml @@ -51,9 +51,9 @@ module Commons = struct | None -> ( (* A formulary with no citations is indistinguishable at the call site from "this saint has no Common" -- [commons_for] would - return [Some []] and [readings] would emit [] either way. That - is exactly the silent hole this project does not allow, so it - is rejected here where it is still nameable. *) + return [Some (common, [])] and [readings] would emit [] either + way. That is exactly the silent hole this project does not + allow, so it is rejected here where it is still nameable. *) match List.find_opt (fun (_, cs) -> cs = []) commons with | Some (s, _) -> Error (Printf.sprintf "commons: common %S has no citations" (Slug.to_string s)) @@ -72,10 +72,19 @@ module Commons = struct (Slug.to_string saint) (Slug.to_string common)) | None -> Ok { commons; assigned }))) + (* Returns the Common's own id ALONGSIDE its citations, not the citations + alone: [readings]' step 4 needs the id to build the day's + {!Colitur_kernel.Mass_formulary.t} ("the Common's own id as its slug"), + and the id is only ever in scope here, at the point [common] is looked + up -- re-deriving it afterwards would mean a second [assoc_opt] search + over [t.assigned] for a value this function already held. *) let find t saint = match List.assoc_opt saint t.assigned with | None -> None - | Some common -> List.assoc_opt common t.commons + | Some common -> ( + match List.assoc_opt common t.commons with + | None -> None + | Some cs -> Some (common, cs)) (* Byte-for-byte the failure discipline of [Lectionary.load] (see its own comments for why each catch-all is placed where it is): every parse and @@ -250,7 +259,8 @@ let is_bvm_saturday_office (observed : Vocab_ef.rank Celebration.t) let readings ~lectionary ~commons ~observed ~temporal ~date ~temporal_at = match observed.Celebration.citations with - | _ :: _ as cs -> cs + | _ :: _ as cs -> + (Some { Mass_formulary.said = Some observed.Celebration.slug; via = Mass_formulary.Proper }, cs) | [] -> ( (* Step 4: a saint who is the day's observed office and has no proper says his assigned Common. The assignment is explicit, never @@ -346,7 +356,8 @@ let readings ~lectionary ~commons ~observed ~temporal ~date ~temporal_at = match if sanctoral_office then commons_for ~commons observed.Celebration.slug else None with - | Some cs -> cs + | Some (common_id, cs) -> + (Some { Mass_formulary.said = Some common_id; via = Mass_formulary.Common }, cs) | None -> ( (* The votive Mass of Our Lady on Saturday (RG 309(a)) runs HERE: after the proper (step 1) and the Common (step 4), which answer @@ -354,13 +365,73 @@ let readings ~lectionary ~commons ~observed ~temporal ~date ~temporal_at = lookup -- which is exactly what used to answer, with the feria's own Mass, on a day whose office is Our Lady's. Placing it later would be dead code; placing it earlier would let it outrank a - real saint's proper. *) + real saint's proper. + + FORMULARY PROVENANCE: [Votive], not [Own_slug] (CORRECTED, fix + round 1, coordinator review -- the first pass tagged this + [Own_slug] for lack of a better constructor and flagged it as a + judgement call; [Mass_formulary.source] has grown a [Votive] + case since, precisely for this branch). RG 431(e) + (docs/research/LT.txt, verbatim): "e) in Missis votivis IV + classis de Angelis, quocumque die, et de B. Maria Virg. quae in + sabbato celebrantur" -- votive Masses of the IV class, of the + Angels on any day, and of the BVM WHICH ARE CELEBRATED ON + SATURDAY: the Missal's own words classify this exact Mass as a + "Missa votiva", not as the day's own office's Mass, corroborated + by RG 309(a) (this branch's own header comment above, "iuxta + temporum diversitatem") naming the FIVE seasonal Masses RG 431(e) + is speaking of. Together: a votive Mass said IN PLACE of the + day's own office's Mass, the office (RG 78, Officium sanctae + Mariae in sabbato) being kept unchanged. + + CORRECTED, fix round 2 (coordinator review): fix round 1's own + comment here claimed the Latin Mass Society Ordo witnesses + [Votive] directly, printing "V Mass of BVM" with "V" read as an + abbreviation for "votive". That was the coordinator's + misreading, not this codebase's, and it was wrong: the Ordo's + "I"-"V" are ROMAN NUMERALS naming WHICH of the Missal's five + seasonal "Missae de sancta Maria in sabbato" (this branch's own + header comment; RG 309(a)'s "iuxta temporum diversitatem") is + said on a given Saturday -- not an abbreviation of anything, and + not a marker of the Mass's class or kind. All five numerals + occur through the Ordo (I x1, II x4, III x3, IV x3, V x8, + counted across the whole document); "V Mass of BVM" merely also + happens to be substring-matched by a naive search for "V Mass of + BVM" inside "IV Mass of BVM", which is what produced the + original false reading. [Votive] itself is UNAFFECTED by this + correction and stays right, on RG 431(e) alone -- only the + Ordo-witness claim is retracted, not softened, removed. A + genuinely useful consequence survives the mistake: because the + Ordo's own numeral names WHICH seasonal Mass is said, a future + comparison against it (Task 6 of this plan) can validate + [bvm_saturday_citations]'s own season-keyed SELECTION, not + merely that some BVM Mass was chosen. + + [said] used to be set HERE to the day's own temporal slug + (reasoning: [is_bvm_saturday_office] only ever fires when + [sanctoral_office] above is false, i.e. the observed + celebration already IS the day's own temporal office, which + deliberately reuses the ordinary ferial slug, [Temporal_ef]'s + own [bvm_saturday_names]). CORRECTED (whole-branch review fix + round): that value is the OFFICE's slug, not the slug whose + Mass is actually said -- the five seasonal Masses RG 309(a) + names have no slug of their own anywhere in the shipped data, + so [said] is [None] here, honestly, rather than silently + naming the wrong thing. See {!Colitur_kernel.Mass_formulary.t}'s + own [said] citation for the full account; the office itself is + not lost, it is still [observed.slug] on the very same + {!Colitur_kernel.Liturgical_day.t} this formulary lives on. *) if is_bvm_saturday_office observed temporal then - bvm_saturday_citations temporal.Temporal.season ~month:(Date.month date) - ~day:(Date.day date) + ( Some { Mass_formulary.said = None; via = Mass_formulary.Votive }, + bvm_saturday_citations temporal.Temporal.season ~month:(Date.month date) + ~day:(Date.day date) ) else match Lectionary.find lectionary temporal.Temporal.office.Celebration.slug with - | Some cs -> cs + | Some cs -> + ( Some + { Mass_formulary.said = Some temporal.Temporal.office.Celebration.slug; + via = Mass_formulary.Own_slug }, + cs ) | None -> ( (* Step 3: a feria with no proper of its own says the preceding Sunday's Mass. WARRANT is the same as step 2's -- lectio's own @@ -404,12 +475,14 @@ let readings ~lectionary ~commons ~observed ~temporal ~date ~temporal_at = season name), so deriving one from the other textually would be a latent bug the moment a season's naming convention differs. *) let offset = days_since_sunday temporal.Temporal.weekday in - if offset = 0 then [] + if offset = 0 then (None, []) else let sunday = Date.add_days date (-offset) in let sunday_temporal = temporal_at sunday in match Lectionary.find lectionary sunday_temporal.Temporal.office.Celebration.slug with - | Some cs -> cs - | None -> []))) + | Some cs -> + let said = sunday_temporal.Temporal.office.Celebration.slug in + (Some { Mass_formulary.said = Some said; via = Mass_formulary.Preceding_sunday }, cs) + | None -> (None, [])))) |
