summaryrefslogtreecommitdiff
path: root/lib/rites/rite_ef/lectionary_ef.ml
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rites/rite_ef/lectionary_ef.ml')
-rw-r--r--lib/rites/rite_ef/lectionary_ef.ml58
1 files changed, 45 insertions, 13 deletions
diff --git a/lib/rites/rite_ef/lectionary_ef.ml b/lib/rites/rite_ef/lectionary_ef.ml
index d7b2497..4325bed 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 = 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 = 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,32 @@ 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, a genuine judgement call: {!Mass_formulary.source}
+ has no fifth constructor for "the RG 309(a) seasonal votive Mass",
+ so this is tagged [Own_slug] -- [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 (the office
+ deliberately reuses the ordinary ferial slug, [Temporal_ef]'s own
+ [bvm_saturday_names]), so [said] is genuinely "the day's own
+ slug" -- [Own_slug]'s own documented meaning
+ (mass_formulary.mli's [said] comment) -- even though the
+ citations themselves come from [bvm_saturday_citations]'s
+ season table rather than a [Lectionary.find] hit. Flagged in the
+ task report as an interpretation, not a specified answer. *)
if is_bvm_saturday_office observed temporal then
- bvm_saturday_citations temporal.Temporal.season ~month:(Date.month date)
- ~day:(Date.day date)
+ let said = temporal.Temporal.office.Celebration.slug in
+ ( Some { Mass_formulary.said; via = Mass_formulary.Own_slug },
+ 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 = 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 +434,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; via = Mass_formulary.Preceding_sunday }, cs)
+ | None -> (None, []))))