summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/of/lectionary.sexp2317
-rw-r--r--lib/rites/rite_of/lectionary_of.ml107
-rw-r--r--lib/rites/rite_of/lectionary_of.mli136
-rw-r--r--test/dune2
-rw-r--r--test/test_colitur.ml1
-rw-r--r--test/test_lectionary_of.ml372
-rw-r--r--tools/bootstrap_lectionary_of.ml827
-rw-r--r--tools/dune15
8 files changed, 3777 insertions, 0 deletions
diff --git a/data/of/lectionary.sexp b/data/of/lectionary.sexp
new file mode 100644
index 0000000..4f43f12
--- /dev/null
+++ b/data/of/lectionary.sexp
@@ -0,0 +1,2317 @@
+; data/of/lectionary.sexp -- OF (2002) temporal + sanctoral lectionary
+; (Epistle + Gospel citations, never scripture text), bootstrapped from
+; lectio.
+;
+; LINEAGE, stated loudly because it constrains what this file can show
+; (design spec 2026-08-24-colitur-of-rite-module-design.md sec4.4/sec5):
+; this is a POLISH VERNACULAR pastoral lectionary (niedziela.pl,
+; harvested 2020-2025 by lectio's own scripts/genlect-of.go), NOT the
+; Latin OLM (Ordo Lectionum Missae) 1981 itself, and its citations are
+; ENGLISH-CANONICAL, not OLM's Vulgate numbering. It CANNOT show any
+; divergence between niedziela.pl's own pastoral choices and OLM's own
+; text -- three such divergences are already confirmed against the real
+; OLM page images (design spec sec4.4): Holy Family Year A's second-
+; reading short form, Trinity Sunday's Dan 3:56, and the Baptism of the
+; Lord's Mc 9:6 vs "Mark 9:7". Nor can it show OLM's short/long-form
+; reading alternatives, which niedziela.pl does not distinguish. This is
+; ALSO a SEPARATE lineage from lectio's own OF CALENDAR data
+; (data/of/calendar-2002.sexp, roman-calendar.ini, upstream
+; calapi.inadiutorium.cz) -- lectio is two unrelated upstreams glued
+; together by one downstream project, not one witness, and neither is
+; the typical edition.
+;
+; Generator: tools/bootstrap_lectionary_of.ml -- do not hand-edit;
+; re-run against the same lectio snapshot (its SHA-256 is pinned below;
+; a MISSING source file is fatal, checked before any read is attempted --
+; see this generator's own [parse_ini]) and commit the diff instead.
+; Every emitted key is asserted, at generation time, to be a slug
+; Rite_of.Temporal_of actually computes OR a slug the real merged
+; sanctoral layer (data/of/calendar-2002.sexp + all 13 decree overlays)
+; actually carries -- see [assert_reachable].
+;
+; Source: ../lectio/internal/caldata/of-lectionary.ini
+; SHA-256: f0b527aef58b93e6ccdfbeafe52b340ed2a9d7d72805bf5083e3da04b080123c
+; 988 ini sections (988 expected) -> 438 resolved (base, cycle-shape) pairs -> 419 colitur slugs mapped, 19 ini bases deliberately excluded (date-
+; keyed duplicates/late-Advent, no colitur date-keyed lookup exists --
+; see [excluded_bases]), 0 ini bases genuinely unmapped (no pattern, no
+; override, no matching sanctoral slug) -> 754 emitted lectionary entries.
+;
+; COVERAGE, BOTH DIRECTIONS (Step 1 of this task's own brief):
+; (1) Temporal-day gap: of the 365 days of civil year 2026, 1 produce a
+; Rite_of.Temporal_of slug with NO entry in this file (tried flat,
+; then both the Sunday- and weekday-cycle letter suffixes -- the
+; same order Lectionary_of.readings itself tries). Those are days
+; with no readings via the temporal-slug path (a sanctoral proper
+; on the same civil day, where one exists, is Lectionary_of's own
+; separate first chance). Named set below.
+; (2) Unmapped lectio keys: 0 ini base names (of 988 sections, 438
+; distinct bases) map to no colitur slug at all -- data being
+; silently dropped if unreported. Named below.
+; Regenerate with:
+; eval $(opam env) && dune exec tools/bootstrap_lectionary_of.exe -- ../lectio/internal/caldata/of-lectionary.ini data/of/lectionary.sexp
+; Unmapped lectio bases (0):
+; Temporal_of slugs (2004-2051) with no lectionary entry (1, informational --
+; most are the Christmas-season/late-Advent date-vs-weekday gap named above):
+; of-nativity
+((all-saints
+ (((part First) (reference "Revelation 7:2-4,9-14"))
+ ((part Gospel) (reference "Mat 5:1-12"))))
+ (all-souls
+ (((part First) (reference "Job 19:1,23-27"))
+ ((part Gospel) (reference "Luke 23:44-46,50,52-53"))))
+ (andrew-the-apostle
+ (((part First) (reference "Isaiah 49:1-6"))
+ ((part Gospel) (reference "Mat 4:18-22"))))
+ (annunciation-of-the-lord
+ (((part First) (reference "Isaiah 7:10-14;8:10"))
+ ((part Gospel) (reference "Luke 1:26-38"))))
+ (assumption-of-the-blessed-virgin-mary
+ (((part First) (reference "1 Chronicles 15:3-4,15-16;16:1-2"))
+ ((part Gospel) (reference "Luke 11:27-28"))))
+ (bartholomew-the-apostle
+ (((part First) (reference "Revelation 21:9-14"))
+ ((part Gospel) (reference "John 1:45-51"))))
+ (birth-of-saint-john-the-baptist
+ (((part First) (reference "Jeremiah 1:4-10"))
+ ((part Gospel) (reference "Luke 1:5-17"))))
+ (birth-of-the-blessed-virgin-mary
+ (((part First) (reference "Micah 5:1-4"))
+ ((part Gospel) (reference "Mat 1:18-23"))))
+ (chair-of-saint-peter-apostle
+ (((part First) (reference "1 Peter 5:1-4"))
+ ((part Gospel) (reference "Mat 16:13-19"))))
+ (dedication-of-the-lateran-basilica
+ (((part First) (reference "Ezekiel 47:1-2,8-9,12"))
+ ((part Gospel) (reference "John 2:13-22"))))
+ (holy-innocents-martyrs
+ (((part First) (reference "1 John 1:5-2:2"))
+ ((part Gospel) (reference "Mat 2:13-18"))))
+ (immaculate-conception-of-the-blessed-virgin-mary
+ (((part First) (reference "Genesis 3:9-15,20"))
+ ((part Gospel) (reference "Luke 1:26-38"))))
+ (james-apostle
+ (((part First) (reference "2 Corinthians 4:7-15"))
+ ((part Gospel) (reference "Mat 20:20-28"))))
+ (john-the-apostle-and-evangelist
+ (((part First) (reference "1 John 1:1-4"))
+ ((part Gospel) (reference "John 20:2-8"))))
+ (joseph-husband-of-the-blessed-virgin-mary
+ (((part First) (reference "2 Samuel 7:4-5,12-14,16"))
+ ((part Gospel) (reference "Luke 2:41-51"))))
+ (lawrence-deacon-and-martyr
+ (((part First) (reference "2 Corinthians 9:6-10"))
+ ((part Gospel) (reference "John 12:24-26"))))
+ (luke-the-evangelist
+ (((part First) (reference "2 Timothy 4:10-17"))
+ ((part Gospel) (reference "Luke 10:1-9"))))
+ (mark-the-evangelist
+ (((part First) (reference "1 Peter 5:5-14"))
+ ((part Gospel) (reference "Mark 16:15-20"))))
+ (mary-magdalene
+ (((part First) (reference "Song of Solomon 8:6-7"))
+ ((part Gospel) (reference "John 20:1,11-18"))))
+ (matthew-the-evangelist-apostle-evangelist
+ (((part First) (reference "Ephesians 4:1-7,11-13"))
+ ((part Gospel) (reference "Mat 9:9-13"))))
+ (matthias-the-apostle
+ (((part First) (reference "Acts 1:15-17,20-26"))
+ ((part Gospel) (reference "John 15:9-17"))))
+ (of-advent-1-friday
+ (((part First) (reference "Isaiah 29:17-24"))
+ ((part Gospel) (reference "Matthew 9:27-31"))))
+ (of-advent-1-monday
+ (((part First) (reference "Isaiah 2:1-5"))
+ ((part Gospel) (reference "Matthew 8:5-11"))))
+ (of-advent-1-saturday
+ (((part First) (reference "Isaiah 30:19-21,23-26"))
+ ((part Gospel) (reference "Matthew 9:35-10:1,5a,6-8"))))
+ (of-advent-1-thursday
+ (((part First) (reference "Isaiah 26:1-6"))
+ ((part Gospel) (reference "Matthew 7:21,24-27"))))
+ (of-advent-1-tuesday
+ (((part First) (reference "Isaiah 11:1-10"))
+ ((part Gospel) (reference "Luke 10:21-24"))))
+ (of-advent-1-wednesday
+ (((part First) (reference "Isaiah 25:6-10a"))
+ ((part Gospel) (reference "Matthew 15:29-37"))))
+ (of-advent-2-friday
+ (((part First) (reference "Isaiah 48:17-19"))
+ ((part Gospel) (reference "Matthew 11:16-19"))))
+ (of-advent-2-monday
+ (((part First) (reference "Isaiah 35:1-10"))
+ ((part Gospel) (reference "Luke 5:17-26"))))
+ (of-advent-2-saturday
+ (((part First) (reference "Sirach 48:1-4,9-11"))
+ ((part Gospel) (reference "Matthew 17:9a,10-135"))))
+ (of-advent-2-thursday
+ (((part First) (reference "Isaiah 41:13-20"))
+ ((part Gospel) (reference "Matthew 11:11-15"))))
+ (of-advent-2-tuesday
+ (((part First) (reference "Isaiah 40:1-11"))
+ ((part Gospel) (reference "Matthew 18:12-14"))))
+ (of-advent-2-wednesday
+ (((part First) (reference "Isaiah 40:25-31"))
+ ((part Gospel) (reference "Matthew 11:28-30"))))
+ (of-advent-3-friday
+ (((part First) (reference "Isaiah 56:1-3a,6-8"))
+ ((part Gospel) (reference "John 5:33-36"))))
+ (of-advent-3-monday
+ (((part First) (reference "Numbers 24:2-7,15-17a"))
+ ((part Gospel) (reference "Matthew 21:23-27"))))
+ (of-advent-3-saturday-i
+ (((part First) (reference "1 Samuel 1:24-28"))
+ ((part Gospel) (reference "Luke 1:46-56"))))
+ (of-advent-3-saturday-ii
+ (((part First) (reference "Song of Solomon 2:8-14"))
+ ((part Gospel) (reference "Luke 1:39-45"))))
+ (of-advent-3-thursday
+ (((part First) (reference "Isaiah 54:1-10"))
+ ((part Gospel) (reference "Luke 7:24-30"))))
+ (of-advent-3-tuesday
+ (((part First) (reference "Zephaniah 3:1-2,9-13"))
+ ((part Gospel) (reference "Matthew 21:28-32"))))
+ (of-advent-3-wednesday
+ (((part First) (reference "Isaiah 45:6c-8,18,21c-25"))
+ ((part Gospel) (reference "Luke 7:18b-23"))))
+ (of-advent-4-friday-i
+ (((part First) (reference "Malachi 3:1-4;4:5-6"))
+ ((part Gospel) (reference "Luke 1:57-66"))))
+ (of-advent-4-friday-ii
+ (((part First) (reference "2 Samuel 7:1-5,8-12,14,16"))
+ ((part Gospel) (reference "Luke 1:67-79"))))
+ (of-advent-4-monday-i
+ (((part First) (reference "2 Samuel 7:1-5,8-12,14,16"))
+ ((part Gospel) (reference "Luke 1:67-79"))))
+ (of-advent-4-monday-ii
+ (((part First) (reference "Malachi 3:1-4;4:5-6"))
+ ((part Gospel) (reference "Luke 1:57-66"))))
+ (of-advent-4-thursday-i
+ (((part First) (reference "2 Samuel 7:1-5,8-12,14,16"))
+ ((part Gospel) (reference "Luke 1:67-79"))))
+ (of-advent-4-thursday-ii
+ (((part First) (reference "Malachi 3:1-4;4:5-6"))
+ ((part Gospel) (reference "Luke 1:57-66"))))
+ (of-advent-4-tuesday-i
+ (((part First) (reference "1 Samuel 1:24-28"))
+ ((part Gospel) (reference "Luke 1:46-56"))))
+ (of-advent-4-tuesday-ii
+ (((part First) (reference "2 Samuel 7:1-5,8-12,14,16"))
+ ((part Gospel) (reference "Luke 1:67-79"))))
+ (of-advent-4-wednesday-i
+ (((part First) (reference "Malachi 3:1-4;4:5-6"))
+ ((part Gospel) (reference "Luke 1:57-66"))))
+ (of-advent-4-wednesday-ii
+ (((part First) (reference "1 Samuel 1:24-28"))
+ ((part Gospel) (reference "Luke 1:46-56"))))
+ (of-advent-sunday-1-a
+ (((part First) (reference "Isaiah 2:1-5"))
+ ((part Gospel) (reference "Matthew 24:37-44"))))
+ (of-advent-sunday-1-b
+ (((part First) (reference "Isaiah 63:16b-17,19b;64:2-7"))
+ ((part Gospel) (reference "Mark 13:33-37"))))
+ (of-advent-sunday-1-c
+ (((part First) (reference "Jeremiah 33:14-16"))
+ ((part Gospel) (reference "Luke 21:25-28,34-36"))))
+ (of-advent-sunday-2-a
+ (((part First) (reference "Isaiah 11:1-10"))
+ ((part Gospel) (reference "Matthew 3:1-12"))))
+ (of-advent-sunday-2-b
+ (((part First) (reference "Isaiah 40:1-5,9-11"))
+ ((part Gospel) (reference "Mark 1:1-8"))))
+ (of-advent-sunday-2-c
+ (((part First) (reference "Baruch 5:1-9"))
+ ((part Gospel) (reference "Luke 3:1-6"))))
+ (of-advent-sunday-3-a
+ (((part First) (reference "Isaiah 35:1-6a,10"))
+ ((part Gospel) (reference "Matthew 11:2-11"))))
+ (of-advent-sunday-3-b
+ (((part First) (reference "Isaiah 61:1-2a,10-11"))
+ ((part Gospel) (reference "John 1:6-8,19-28"))))
+ (of-advent-sunday-3-c
+ (((part First) (reference "Zephaniah 3:14-18a"))
+ ((part Gospel) (reference "Luke 3:10-18"))))
+ (of-advent-sunday-4-a
+ (((part First) (reference "Isaiah 7:10-14"))
+ ((part Gospel) (reference "Matthew 1:18-24"))))
+ (of-advent-sunday-4-b
+ (((part First) (reference "2 Samuel 7:1-5,8b-12,14a,16"))
+ ((part Gospel) (reference "Luke 1:26-38"))))
+ (of-advent-sunday-4-c
+ (((part First) (reference "Micah 5:1-4a"))
+ ((part Gospel) (reference "Luke 1:39-45"))))
+ (of-ascension-a
+ (((part First) (reference "The Acts 1:1-11"))
+ ((part Gospel) (reference "Matthew 28:16-20"))))
+ (of-ascension-b
+ (((part First) (reference "The Acts 1:1-11"))
+ ((part Gospel) (reference "Mark 16:15-20"))))
+ (of-ascension-c
+ (((part First) (reference "The Acts 1:1-11"))
+ ((part Gospel) (reference "Luke 24:46-53"))))
+ (of-ash-wednesday
+ (((part First) (reference "Joel 2:12-18"))
+ ((part Gospel) (reference "Matthew 6:1-6,16-18"))))
+ (of-baptism-of-the-lord-a
+ (((part First) (reference "Isaiah 42:1-4,6-7"))
+ ((part Gospel) (reference "Matthew 3:13-17"))))
+ (of-baptism-of-the-lord-b
+ (((part First) (reference "Isaiah 55:1-11"))
+ ((part Gospel) (reference "Mark 1:7-11"))))
+ (of-baptism-of-the-lord-c
+ (((part First) (reference "Isaiah 40:1-5,9-11"))
+ ((part Gospel) (reference "Luke 3:15-16,21-22"))))
+ (of-christ-the-king-a
+ (((part First) (reference "Ezekiel 34:11-12,15-17"))
+ ((part Gospel) (reference "Matthew 25:31-46"))))
+ (of-christ-the-king-b
+ (((part First) (reference "Daniel 7:13-14"))
+ ((part Gospel) (reference "John 18:33b-37"))))
+ (of-christ-the-king-c
+ (((part First) (reference "2 Samuel 5:1-3"))
+ ((part Gospel) (reference "Luke 23:35-43"))))
+ (of-christmas-0-friday-ii
+ (((part First) (reference "1 John 2:18-21"))
+ ((part Gospel) (reference "John 1:1-5,9-14"))))
+ (of-christmas-0-monday-i
+ (((part First) (reference "1 John 2:18-21"))
+ ((part Gospel) (reference "John 1:1-5,9-14"))))
+ (of-christmas-0-monday-ii
+ (((part First) (reference "1 John 2:12-17"))
+ ((part Gospel) (reference "Luke 2:36-40"))))
+ (of-christmas-0-saturday-i
+ (((part First) (reference "1 John 2:3-11"))
+ ((part Gospel) (reference "Luke 2:22-35"))))
+ (of-christmas-0-saturday-ii
+ (((part First) (reference "1 John 2:12-17"))
+ ((part Gospel) (reference "Luke 2:36-40"))))
+ (of-christmas-0-thursday-i
+ (((part First) (reference "1 John 2:18-21"))
+ ((part Gospel) (reference "John 1:1-5,9-14"))))
+ (of-christmas-0-thursday-ii
+ (((part First) (reference "1 John 2:12-17"))
+ ((part Gospel) (reference "Luke 2:36-40"))))
+ (of-christmas-0-tuesday-i
+ (((part First) (reference "1 John 2:3-11"))
+ ((part Gospel) (reference "Luke 2:22-35"))))
+ (of-christmas-0-tuesday-ii
+ (((part First) (reference "1 John 2:18-21"))
+ ((part Gospel) (reference "John 1:1-5,9-14"))))
+ (of-christmas-0-wednesday-i
+ (((part First) (reference "1 John 2:12-17"))
+ ((part Gospel) (reference "Luke 2:36-40"))))
+ (of-christmas-0-wednesday-ii
+ (((part First) (reference "1 John 2:3-11"))
+ ((part Gospel) (reference "Luke 2:22-35"))))
+ (of-christmas-1-friday-i
+ (((part First) (reference "1 John 3:7-10"))
+ ((part Gospel) (reference "John 1:35-42"))))
+ (of-christmas-1-friday-ii
+ (((part First) (reference "1 John 3:11-21"))
+ ((part Gospel) (reference "John 1:43-51"))))
+ (of-christmas-1-monday-i
+ (((part First) (reference "1 John 3:22-4:6"))
+ ((part Gospel) (reference "Mat 4:12-17,23-25"))))
+ (of-christmas-1-monday-ii
+ (((part First) (reference "1 John 2:29-3:6"))
+ ((part Gospel) (reference "John 1:29-34"))))
+ (of-christmas-1-saturday-i
+ (((part First) (reference "1 John 3:11-21"))
+ ((part Gospel) (reference "John 1:43-51"))))
+ (of-christmas-1-saturday-ii
+ (((part First) (reference "1 John 3:7-10"))
+ ((part Gospel) (reference "John 1:35-42"))))
+ (of-christmas-1-thursday-i
+ (((part First) (reference "1 John 2:29-3:6"))
+ ((part Gospel) (reference "John 1:29-34"))))
+ (of-christmas-1-thursday-ii
+ (((part First) (reference "1 John 3:7-10"))
+ ((part Gospel) (reference "John 1:35-42"))))
+ (of-christmas-1-tuesday-i
+ (((part First) (reference "1 John 4:7-10"))
+ ((part Gospel) (reference "Mark 6:34-44"))))
+ (of-christmas-1-tuesday-ii
+ (((part First) (reference "1 John 3:22-4:6"))
+ ((part Gospel) (reference "Mat 4:12-17,23-25"))))
+ (of-christmas-1-wednesday-i
+ (((part First) (reference "1 John 4:11-18"))
+ ((part Gospel) (reference "Mark 6:45-52"))))
+ (of-christmas-1-wednesday-ii
+ (((part First) (reference "1 John 2:29-3:6"))
+ ((part Gospel) (reference "John 1:29-34"))))
+ (of-christmas-2-friday
+ (((part First) (reference "1 John 5:5-13"))
+ ((part Gospel) (reference "Luke 5:12-16"))))
+ (of-christmas-2-monday
+ (((part First) (reference "1 John 3:22-4:6"))
+ ((part Gospel) (reference "Matthew 4:12-17,23-25"))))
+ (of-christmas-2-saturday
+ (((part First) (reference "1 John 5:14-21"))
+ ((part Gospel) (reference "John 3:22-30"))))
+ (of-christmas-2-thursday
+ (((part First) (reference "1 John 4:19-5:4"))
+ ((part Gospel) (reference "Luke 4:14-22a"))))
+ (of-christmas-2-tuesday
+ (((part First) (reference "1 John 4:7-10"))
+ ((part Gospel) (reference "Mark 6:34-44"))))
+ (of-christmas-2-wednesday
+ (((part First) (reference "1 John 4:11-18"))
+ ((part Gospel) (reference "Mark 6:45-52"))))
+ (of-christmas-sunday-2
+ (((part First) (reference "Sirach 24:1-4,12-16"))
+ ((part Gospel) (reference "John 1:1-18"))))
+ (of-corpus-christi-a
+ (((part First) (reference "Deuteronomy 8:2-3,14b-16a"))
+ ((part Gospel) (reference "John 6:51-58"))))
+ (of-corpus-christi-b
+ (((part First) (reference "Exodus 24:3-8"))
+ ((part Gospel) (reference "Mark 14:12-16,22-26"))))
+ (of-corpus-christi-c
+ (((part First) (reference "Genesis 14:18-20"))
+ ((part Gospel) (reference "Luke 9:11b-17"))))
+ (of-easter-2-friday
+ (((part First) (reference "The Acts 5:34-42"))
+ ((part Gospel) (reference "John 6:1-15"))))
+ (of-easter-2-monday
+ (((part First) (reference "The Acts 4:23-31"))
+ ((part Gospel) (reference "John 3:1-8"))))
+ (of-easter-2-saturday
+ (((part First) (reference "The Acts 6:1-7"))
+ ((part Gospel) (reference "John 6:16-21"))))
+ (of-easter-2-thursday
+ (((part First) (reference "The Acts 5:27-33"))
+ ((part Gospel) (reference "John 3:31-36"))))
+ (of-easter-2-tuesday
+ (((part First) (reference "The Acts 4:32-37"))
+ ((part Gospel) (reference "John 3:7b-15"))))
+ (of-easter-2-wednesday
+ (((part First) (reference "The Acts 5:17-26"))
+ ((part Gospel) (reference "John 3:16-21"))))
+ (of-easter-3-friday
+ (((part First) (reference "The Acts 9:1-20"))
+ ((part Gospel) (reference "John 6:52-59"))))
+ (of-easter-3-monday
+ (((part First) (reference "The Acts 6:8-15"))
+ ((part Gospel) (reference "John 6:22-29"))))
+ (of-easter-3-saturday
+ (((part First) (reference "The Acts 9:31-42"))
+ ((part Gospel) (reference "John 6:60-69"))))
+ (of-easter-3-thursday
+ (((part First) (reference "The Acts 8:26-40"))
+ ((part Gospel) (reference "John 6:44-51"))))
+ (of-easter-3-tuesday
+ (((part First) (reference "The Acts 7:51-8:1a"))
+ ((part Gospel) (reference "John 6:30-35"))))
+ (of-easter-3-wednesday
+ (((part First) (reference "The Acts 8:1b-8"))
+ ((part Gospel) (reference "John 6:35-40"))))
+ (of-easter-4-friday
+ (((part First) (reference "The Acts 13:26-33"))
+ ((part Gospel) (reference "John 14:1-6"))))
+ (of-easter-4-monday
+ (((part First) (reference "The Acts 11:1-18"))
+ ((part Gospel) (reference "John 10:1-10"))))
+ (of-easter-4-saturday
+ (((part First) (reference "The Acts 13:44-52"))
+ ((part Gospel) (reference "John 14:7-14"))))
+ (of-easter-4-thursday
+ (((part First) (reference "The Acts 13:13-25"))
+ ((part Gospel) (reference "John 13:16-20"))))
+ (of-easter-4-tuesday
+ (((part First) (reference "The Acts 11:19-26"))
+ ((part Gospel) (reference "John 10:22-30"))))
+ (of-easter-4-wednesday
+ (((part First) (reference "The Acts 12:24-13:5a"))
+ ((part Gospel) (reference "John 12:44-50"))))
+ (of-easter-5-friday
+ (((part First) (reference "The Acts 15:22-31"))
+ ((part Gospel) (reference "John 15:12-17"))))
+ (of-easter-5-monday
+ (((part First) (reference "The Acts 14:5-18"))
+ ((part Gospel) (reference "John 14:21-26"))))
+ (of-easter-5-saturday
+ (((part First) (reference "The Acts 16:1-10"))
+ ((part Gospel) (reference "John 15:18-21"))))
+ (of-easter-5-thursday
+ (((part First) (reference "The Acts 15:7-21"))
+ ((part Gospel) (reference "John 15:9-11"))))
+ (of-easter-5-tuesday
+ (((part First) (reference "The Acts 14:19-28"))
+ ((part Gospel) (reference "John 14:27-31a"))))
+ (of-easter-5-wednesday
+ (((part First) (reference "The Acts 15:1-6"))
+ ((part Gospel) (reference "John 15:1-8"))))
+ (of-easter-6-friday
+ (((part First) (reference "The Acts 18:9-18"))
+ ((part Gospel) (reference "John 16:20-23"))))
+ (of-easter-6-monday
+ (((part First) (reference "The Acts 16:11-15"))
+ ((part Gospel) (reference "John 15:26-16:4a"))))
+ (of-easter-6-saturday
+ (((part First) (reference "The Acts 18:23-28"))
+ ((part Gospel) (reference "John 16:23b-28"))))
+ (of-easter-6-tuesday
+ (((part First) (reference "The Acts 16:22-34"))
+ ((part Gospel) (reference "John 16:5-11"))))
+ (of-easter-6-wednesday
+ (((part First) (reference "The Acts 17:15,22-18:1"))
+ ((part Gospel) (reference "John 16:12-15"))))
+ (of-easter-7-friday
+ (((part First) (reference "The Acts 25:13b-21"))
+ ((part Gospel) (reference "John 21:15-19"))))
+ (of-easter-7-monday
+ (((part First) (reference "The Acts 19:1-8"))
+ ((part Gospel) (reference "John 16:29-33"))))
+ (of-easter-7-saturday
+ (((part First) (reference "The Acts 28:16-20,30-31"))
+ ((part Gospel) (reference "John 21:20-25"))))
+ (of-easter-7-thursday
+ (((part First) (reference "The Acts 22:30;23:6-11"))
+ ((part Gospel) (reference "John 17:20-26"))))
+ (of-easter-7-tuesday
+ (((part First) (reference "The Acts 20:17-27"))
+ ((part Gospel) (reference "John 17:1-11a"))))
+ (of-easter-7-wednesday
+ (((part First) (reference "The Acts 20:28-38"))
+ ((part Gospel) (reference "John 17:11b-19"))))
+ (of-easter-octave-day-2
+ (((part First) (reference "Acts 2:14,22-32"))
+ ((part Gospel) (reference "Mat 28:8-15"))))
+ (of-easter-octave-day-3
+ (((part First) (reference "Acts 2:36-41"))
+ ((part Gospel) (reference "John 20:11-18"))))
+ (of-easter-octave-day-4
+ (((part First) (reference "Acts 3:1-10"))
+ ((part Gospel) (reference "Luke 24:13-35"))))
+ (of-easter-octave-day-5
+ (((part First) (reference "Acts 3:11-26"))
+ ((part Gospel) (reference "Luke 24:35-48"))))
+ (of-easter-octave-day-6
+ (((part First) (reference "Acts 4:1-12"))
+ ((part Gospel) (reference "John 21:1-14"))))
+ (of-easter-octave-day-7
+ (((part First) (reference "Acts 4:13-21"))
+ ((part Gospel) (reference "Mark 16:9-15"))))
+ (of-easter-sunday
+ (((part First) (reference "The Acts 10:34a,37-43"))
+ ((part Gospel) (reference "John 20:1-9"))))
+ (of-easter-sunday-2-a
+ (((part First) (reference "The Acts 2:42-47"))
+ ((part Gospel) (reference "John 20:19-31"))))
+ (of-easter-sunday-2-b
+ (((part First) (reference "The Acts 4:32-35"))
+ ((part Gospel) (reference "John 20:19-31"))))
+ (of-easter-sunday-2-c
+ (((part First) (reference "The Acts 5:12-16"))
+ ((part Gospel) (reference "John 20:19-31"))))
+ (of-easter-sunday-3-a
+ (((part First) (reference "The Acts 2:14,22-33"))
+ ((part Gospel) (reference "Luke 24:13-35"))))
+ (of-easter-sunday-3-b
+ (((part First) (reference "The Acts 3:13-15,17-19"))
+ ((part Gospel) (reference "Luke 24:35-48"))))
+ (of-easter-sunday-3-c
+ (((part First) (reference "The Acts 5:27-32,40b-41"))
+ ((part Gospel) (reference "John 21:1-19"))))
+ (of-easter-sunday-4-a
+ (((part First) (reference "The Acts 2:14a,36-41"))
+ ((part Gospel) (reference "John 10:1-10"))))
+ (of-easter-sunday-4-b
+ (((part First) (reference "The Acts 4:8-12"))
+ ((part Gospel) (reference "John 10:11-18"))))
+ (of-easter-sunday-4-c
+ (((part First) (reference "The Acts 13:14,43-52"))
+ ((part Gospel) (reference "John 10:27-30"))))
+ (of-easter-sunday-5-a
+ (((part First) (reference "The Acts 6:1-7"))
+ ((part Gospel) (reference "John 14:1-12"))))
+ (of-easter-sunday-5-b
+ (((part First) (reference "The Acts 9:26-31"))
+ ((part Gospel) (reference "John 15:1-8"))))
+ (of-easter-sunday-5-c
+ (((part First) (reference "The Acts 14:21-27"))
+ ((part Gospel) (reference "John 13:31-33a,34-35"))))
+ (of-easter-sunday-6-a
+ (((part First) (reference "The Acts 8:5-8,14-17"))
+ ((part Gospel) (reference "John 14:15-21"))))
+ (of-easter-sunday-6-b
+ (((part First) (reference "The Acts 10:25-26,34-35,44-48"))
+ ((part Gospel) (reference "John 15:9-17"))))
+ (of-easter-sunday-6-c
+ (((part First) (reference "The Acts 15:1-2,22-29"))
+ ((part Gospel) (reference "John 14:23-29"))))
+ (of-easter-sunday-7-a
+ (((part First) (reference "The Acts 1:12-14"))
+ ((part Gospel) (reference "John 17:1-11a"))))
+ (of-easter-sunday-7-b
+ (((part First) (reference "The Acts 1:15-17,20a,20c-26"))
+ ((part Gospel) (reference "John 17:11b-19"))))
+ (of-easter-sunday-7-c
+ (((part First) (reference "The Acts 7:55-60"))
+ ((part Gospel) (reference "John 17:20-26"))))
+ (of-epiphany
+ (((part First) (reference "Isaiah 60:1-6"))
+ ((part Gospel) (reference "Matthew 2:1-12"))))
+ (of-holy-family-a
+ (((part First) (reference "Sirach 3:3-7,14-17a"))
+ ((part Gospel) (reference "Matthew 2:13-15,19-23"))))
+ (of-holy-family-b
+ (((part First) (reference "Genesis 15:1-6;21:1-3"))
+ ((part Gospel) (reference "Luke 2:22-40"))))
+ (of-holy-family-c
+ (((part First) (reference "1 Samuel 1:20-22,24-28"))
+ ((part Gospel) (reference "Luke 2:41-52"))))
+ (of-lent-1-friday
+ (((part First) (reference "Ezekiel 18:21-28"))
+ ((part Gospel) (reference "Matthew 5:20-26"))))
+ (of-lent-1-monday
+ (((part First) (reference "Leviticus 19:1-2,11-18"))
+ ((part Gospel) (reference "Matthew 25:31-46"))))
+ (of-lent-1-saturday
+ (((part First) (reference "Deuteronomy 26:16-19"))
+ ((part Gospel) (reference "Matthew 5:43-48"))))
+ (of-lent-1-thursday
+ (((part First) (reference "Esther 14:1-13"))
+ ((part Gospel) (reference "Matthew 7:7-12"))))
+ (of-lent-1-tuesday
+ (((part First) (reference "Isaiah 55:10-11"))
+ ((part Gospel) (reference "Matthew 6:7-15"))))
+ (of-lent-1-wednesday
+ (((part First) (reference "Jonah 3:1-10"))
+ ((part Gospel) (reference "Luke 11:29-32"))))
+ (of-lent-2-friday
+ (((part First) (reference "Genesis 37:3-4,12-13a,17b-28a"))
+ ((part Gospel) (reference "Matthew 21:33-43,45-46"))))
+ (of-lent-2-monday
+ (((part First) (reference "Daniel 9:4b-10"))
+ ((part Gospel) (reference "Luke 6:36-38"))))
+ (of-lent-2-saturday
+ (((part First) (reference "Micah 7:14-15,18-20"))
+ ((part Gospel) (reference "Luke 15:1-3,11-32"))))
+ (of-lent-2-thursday
+ (((part First) (reference "Jeremiah 17:5-10"))
+ ((part Gospel) (reference "Luke 16:19-31"))))
+ (of-lent-2-tuesday
+ (((part First) (reference "Isaiah 1:10,16-20"))
+ ((part Gospel) (reference "Matthew 23:1-12"))))
+ (of-lent-2-wednesday
+ (((part First) (reference "Jeremiah 18:18-20"))
+ ((part Gospel) (reference "Matthew 20:17-28"))))
+ (of-lent-3-friday
+ (((part First) (reference "Hosea 14:2-10"))
+ ((part Gospel) (reference "Mark 12:28b-34"))))
+ (of-lent-3-monday
+ (((part First) (reference "2 Kings 5:1-15a"))
+ ((part Gospel) (reference "Luke 4:24-30"))))
+ (of-lent-3-saturday
+ (((part First) (reference "Hosea 6:1-6"))
+ ((part Gospel) (reference "Luke 18:9-14"))))
+ (of-lent-3-thursday
+ (((part First) (reference "Jeremiah 7:23-28"))
+ ((part Gospel) (reference "Luke 11:14-23"))))
+ (of-lent-3-tuesday
+ (((part First) (reference "Daniel 3:25,34-43"))
+ ((part Gospel) (reference "Matthew 18:21-35"))))
+ (of-lent-3-wednesday
+ (((part First) (reference "Deuteronomy 4:1,5-9"))
+ ((part Gospel) (reference "Matthew 5:17-19"))))
+ (of-lent-4-friday
+ (((part First) (reference "Wisdom 2:1a,12-22"))
+ ((part Gospel) (reference "John 7:1-2,10,25-30"))))
+ (of-lent-4-monday
+ (((part First) (reference "Isaiah 65:17-21"))
+ ((part Gospel) (reference "John 4:43-54"))))
+ (of-lent-4-saturday
+ (((part First) (reference "Jeremiah 11:18-20"))
+ ((part Gospel) (reference "John 7:40-53"))))
+ (of-lent-4-thursday
+ (((part First) (reference "Exodus 32:7-14"))
+ ((part Gospel) (reference "John 5:31-47"))))
+ (of-lent-4-tuesday
+ (((part First) (reference "Ezekiel 47:1-9,12"))
+ ((part Gospel) (reference "John 5:1-3a,5-16"))))
+ (of-lent-4-wednesday
+ (((part First) (reference "Isaiah 49:8-15"))
+ ((part Gospel) (reference "John 5:17-30"))))
+ (of-lent-5-friday
+ (((part First) (reference "Jeremiah 20:10-13"))
+ ((part Gospel) (reference "John 10:31-42"))))
+ (of-lent-5-monday
+ (((part First) (reference "Daniel 13:1-9,15-17,19-30,33-62"))
+ ((part Gospel) (reference "John 8:1-11"))))
+ (of-lent-5-saturday
+ (((part First) (reference "Ezekiel 37:21-28"))
+ ((part Gospel) (reference "John 11:45-56"))))
+ (of-lent-5-thursday
+ (((part First) (reference "Genesis 17:3-9"))
+ ((part Gospel) (reference "John 8:51-59"))))
+ (of-lent-5-tuesday
+ (((part First) (reference "Numbers 21:4-9"))
+ ((part Gospel) (reference "John 8:21-30"))))
+ (of-lent-5-wednesday
+ (((part First) (reference "Daniel 3:14-20,91-92,95"))
+ ((part Gospel) (reference "John 8:31-42"))))
+ (of-lent-6-friday
+ (((part First) (reference "Isaiah 52:13-53:12"))
+ ((part Gospel) (reference "John 18:1-19:42"))))
+ (of-lent-6-monday
+ (((part First) (reference "Isaiah 42:1-7"))
+ ((part Gospel) (reference "John 12:1-11"))))
+ (of-lent-6-saturday
+ (((part First) (reference "Genesis 1:1-2:2"))
+ ((part Gospel) (reference "Mat 28:1-10"))))
+ (of-lent-6-thursday
+ (((part First) (reference "Isaiah 61:1-3,6,8-9"))
+ ((part Gospel) (reference "Luke 4:16-21"))))
+ (of-lent-6-tuesday
+ (((part First) (reference "Isaiah 49:1-6"))
+ ((part Gospel) (reference "John 13:21-33,36-38"))))
+ (of-lent-6-wednesday
+ (((part First) (reference "Isaiah 50:4-9"))
+ ((part Gospel) (reference "Mat 26:14-25"))))
+ (of-lent-after-ashes-friday
+ (((part First) (reference "Isaiah 58:1-9a"))
+ ((part Gospel) (reference "Matthew 9:14-15"))))
+ (of-lent-after-ashes-saturday
+ (((part First) (reference "Isaiah 58:9b-14"))
+ ((part Gospel) (reference "Luke 5:27-32"))))
+ (of-lent-after-ashes-thursday
+ (((part First) (reference "Deuteronomy 30:15-20"))
+ ((part Gospel) (reference "Luke 9:22-25"))))
+ (of-lent-sunday-1-a
+ (((part First) (reference "Genesis 2:7-9;3:1-7"))
+ ((part Gospel) (reference "Matthew 4:1-11"))))
+ (of-lent-sunday-1-b
+ (((part First) (reference "Genesis 9:8-15"))
+ ((part Gospel) (reference "Mark 1:12-15"))))
+ (of-lent-sunday-1-c
+ (((part First) (reference "Deuteronomy 26:4-10"))
+ ((part Gospel) (reference "Luke 4:1-13"))))
+ (of-lent-sunday-2-a
+ (((part First) (reference "Genesis 12:1-4a"))
+ ((part Gospel) (reference "Matthew 17:1-9"))))
+ (of-lent-sunday-2-b
+ (((part First) (reference "Genesis 22:1-2,9a,10-13,15-18"))
+ ((part Gospel) (reference "Mark 9:2-10"))))
+ (of-lent-sunday-2-c
+ (((part First) (reference "Genesis 15:5-12,17-18"))
+ ((part Gospel) (reference "Luke 9:28b-36"))))
+ (of-lent-sunday-3-a
+ (((part First) (reference "Exodus 17:3-7"))
+ ((part Gospel) (reference "John 4:5-42"))))
+ (of-lent-sunday-3-b
+ (((part First) (reference "Exodus 20:1-17"))
+ ((part Gospel) (reference "John 2:13-25"))))
+ (of-lent-sunday-3-c
+ (((part First) (reference "Exodus 3:1-8a,13-15"))
+ ((part Gospel) (reference "Luke 13:1-9"))))
+ (of-lent-sunday-4-a
+ (((part First) (reference "1 Samuel 16:1b,6-7,10-13a"))
+ ((part Gospel) (reference "John 9:1-41"))))
+ (of-lent-sunday-4-b
+ (((part First) (reference "2 Chronicles 36:14-16,19-23"))
+ ((part Gospel) (reference "John 3:14-21"))))
+ (of-lent-sunday-4-c
+ (((part First) (reference "Joshua 5:9a,10-12"))
+ ((part Gospel) (reference "Luke 15:1-3,11-32"))))
+ (of-lent-sunday-5-a
+ (((part First) (reference "Ezekiel 37:12-14"))
+ ((part Gospel) (reference "John 11:1-45"))))
+ (of-lent-sunday-5-b
+ (((part First) (reference "Jeremiah 31:31-34"))
+ ((part Gospel) (reference "John 12:20-33"))))
+ (of-lent-sunday-5-c
+ (((part First) (reference "Isaiah 43:16-21"))
+ ((part Gospel) (reference "John 8:1-11"))))
+ (of-mary-mother-of-god
+ (((part First) (reference "Numbers 6:22-27"))
+ ((part Gospel) (reference "Luke 2:16-21"))))
+ (of-nativity-vigil
+ (((part First) (reference "Isaiah 62:1-5"))
+ ((part Gospel) (reference "Mat 1:18-25"))))
+ (of-ordinary-time-1-friday-i
+ (((part First) (reference "Hebrews 4:1-5,11"))
+ ((part Gospel) (reference "Mark 2:1-12"))))
+ (of-ordinary-time-1-friday-ii
+ (((part First) (reference "1 Samuel 8:4-7,10-22a"))
+ ((part Gospel) (reference "Mark 2:1-12"))))
+ (of-ordinary-time-1-monday-i
+ (((part First) (reference "Hebrews 1:1-6"))
+ ((part Gospel) (reference "Mark 1:14-20"))))
+ (of-ordinary-time-1-monday-ii
+ (((part First) (reference "1 Samuel 1:1-8"))
+ ((part Gospel) (reference "Mark 1:14-22"))))
+ (of-ordinary-time-1-saturday-i
+ (((part First) (reference "Hebrews 4:12-16"))
+ ((part Gospel) (reference "Mark 2:13-17"))))
+ (of-ordinary-time-1-saturday-ii
+ (((part First) (reference "1 Samuel 9:1-4,17-19;10:1"))
+ ((part Gospel) (reference "Mark 2:13-17"))))
+ (of-ordinary-time-1-thursday-i
+ (((part First) (reference "Hebrews 3:7-14"))
+ ((part Gospel) (reference "Mark 1:40-45"))))
+ (of-ordinary-time-1-thursday-ii
+ (((part First) (reference "1 Samuel 4:1-11"))
+ ((part Gospel) (reference "Mark 1:40-45"))))
+ (of-ordinary-time-1-tuesday-i
+ (((part First) (reference "Hebrews 2:5-12"))
+ ((part Gospel) (reference "Mark 1:21-28"))))
+ (of-ordinary-time-1-tuesday-ii
+ (((part First) (reference "1 Samuel 1:9-22"))
+ ((part Gospel) (reference "Mark 1:21-28"))))
+ (of-ordinary-time-1-wednesday-i
+ (((part First) (reference "Hebrews 2:14-18"))
+ ((part Gospel) (reference "Mark 1:29-39"))))
+ (of-ordinary-time-1-wednesday-ii
+ (((part First) (reference "1 Samuel 3:1-10,19-22"))
+ ((part Gospel) (reference "Mark 1:29-39"))))
+ (of-ordinary-time-10-friday-i
+ (((part First) (reference "2 Corinthians 4:7-15"))
+ ((part Gospel) (reference "Matthew 5:27-32"))))
+ (of-ordinary-time-10-friday-ii
+ (((part First) (reference "1 Kings 19:9a,11-16"))
+ ((part Gospel) (reference "Matthew 5:27-32"))))
+ (of-ordinary-time-10-monday-i
+ (((part First) (reference "2 Corinthians 1:1-7"))
+ ((part Gospel) (reference "Matthew 5:1-12"))))
+ (of-ordinary-time-10-monday-ii
+ (((part First) (reference "1 Kings 17:1-6"))
+ ((part Gospel) (reference "Matthew 5:1-12"))))
+ (of-ordinary-time-10-saturday-i
+ (((part First) (reference "2 Corinthians 5:14-21"))
+ ((part Gospel) (reference "Matthew 5:33-37"))))
+ (of-ordinary-time-10-saturday-ii
+ (((part First) (reference "1 Kings 19:19-21"))
+ ((part Gospel) (reference "Matthew 5:33-37"))))
+ (of-ordinary-time-10-thursday-i
+ (((part First) (reference "2 Corinthians 3:15-4:1,3-6"))
+ ((part Gospel) (reference "Matthew 5:20-26"))))
+ (of-ordinary-time-10-thursday-ii
+ (((part First) (reference "1 Kings 18:41-46"))
+ ((part Gospel) (reference "Matthew 5:20-26"))))
+ (of-ordinary-time-10-tuesday-i
+ (((part First) (reference "2 Corinthians 1:18-22"))
+ ((part Gospel) (reference "Matthew 5:13-16"))))
+ (of-ordinary-time-10-tuesday-ii
+ (((part First) (reference "1 Kings 17:7-16"))
+ ((part Gospel) (reference "Matthew 5:13-16"))))
+ (of-ordinary-time-10-wednesday-i
+ (((part First) (reference "2 Corinthians 3:4-11"))
+ ((part Gospel) (reference "Matthew 5:17-19"))))
+ (of-ordinary-time-10-wednesday-ii
+ (((part First) (reference "1 Kings 18:20-39"))
+ ((part Gospel) (reference "Matthew 5:17-19"))))
+ (of-ordinary-time-11-friday-i
+ (((part First) (reference "2 Corinthians 11:18,21-30"))
+ ((part Gospel) (reference "Matthew 6:19-23"))))
+ (of-ordinary-time-11-friday-ii
+ (((part First) (reference "2 Kings 11:1-4,9-18,20"))
+ ((part Gospel) (reference "Matthew 6:19-23"))))
+ (of-ordinary-time-11-monday-i
+ (((part First) (reference "2 Corinthians 6:1-10"))
+ ((part Gospel) (reference "Matthew 5:38-42"))))
+ (of-ordinary-time-11-monday-ii
+ (((part First) (reference "1 Kings 21:1-16"))
+ ((part Gospel) (reference "Matthew 5:38-42"))))
+ (of-ordinary-time-11-saturday-i
+ (((part First) (reference "2 Corinthians 12:1-10"))
+ ((part Gospel) (reference "Matthew 6:24-34"))))
+ (of-ordinary-time-11-saturday-ii
+ (((part First) (reference "2 Chronicles 24:17-25"))
+ ((part Gospel) (reference "Matthew 6:24-34"))))
+ (of-ordinary-time-11-thursday-i
+ (((part First) (reference "2 Corinthians 11:1-11"))
+ ((part Gospel) (reference "Matthew 6:7-15"))))
+ (of-ordinary-time-11-thursday-ii
+ (((part First) (reference "Sirach 48:1-14"))
+ ((part Gospel) (reference "Matthew 6:7-15"))))
+ (of-ordinary-time-11-tuesday-i
+ (((part First) (reference "2 Corinthians 8:1-9"))
+ ((part Gospel) (reference "Matthew 5:43-48"))))
+ (of-ordinary-time-11-tuesday-ii
+ (((part First) (reference "1 Kings 21:17-29"))
+ ((part Gospel) (reference "Matthew 5:43-48"))))
+ (of-ordinary-time-11-wednesday-i
+ (((part First) (reference "2 Corinthians 9:6-11"))
+ ((part Gospel) (reference "Matthew 6:1-6,16-18"))))
+ (of-ordinary-time-11-wednesday-ii
+ (((part First) (reference "2 Kings 2:1,6-14"))
+ ((part Gospel) (reference "Matthew 6:1-6,16-18"))))
+ (of-ordinary-time-12-friday-i
+ (((part First) (reference "Genesis 17:1,9-10,15-22"))
+ ((part Gospel) (reference "Matthew 8:1-4"))))
+ (of-ordinary-time-12-friday-ii
+ (((part First) (reference "2 Kings 25:1-12"))
+ ((part Gospel) (reference "Matthew 8:1-4"))))
+ (of-ordinary-time-12-monday-i
+ (((part First) (reference "Genesis 12:1-9"))
+ ((part Gospel) (reference "Matthew 7:1-5"))))
+ (of-ordinary-time-12-monday-ii
+ (((part First) (reference "2 Kings 17:5-8,13-15a,18"))
+ ((part Gospel) (reference "Matthew 7:1-5"))))
+ (of-ordinary-time-12-saturday-i
+ (((part First) (reference "Genesis 18:1-15"))
+ ((part Gospel) (reference "Matthew 8:5-17"))))
+ (of-ordinary-time-12-saturday-ii
+ (((part First) (reference "Lamentations 2:2,10-14,18-19"))
+ ((part Gospel) (reference "Matthew 8:5-17"))))
+ (of-ordinary-time-12-thursday-i
+ (((part First) (reference "Genesis 16:1-12,15-16"))
+ ((part Gospel) (reference "Matthew 7:21-29"))))
+ (of-ordinary-time-12-thursday-ii
+ (((part First) (reference "2 Kings 24:8-17"))
+ ((part Gospel) (reference "Matthew 7:21-29"))))
+ (of-ordinary-time-12-tuesday-i
+ (((part First) (reference "Genesis 13:2,5-18"))
+ ((part Gospel) (reference "Matthew 7:6,12-14"))))
+ (of-ordinary-time-12-tuesday-ii
+ (((part First) (reference "2 Kings 19:9b-11,14-21,31-35a,36"))
+ ((part Gospel) (reference "Matthew 7:6,12-14"))))
+ (of-ordinary-time-12-wednesday-i
+ (((part First) (reference "Genesis 15:1-12,17-18"))
+ ((part Gospel) (reference "Matthew 7:15-20"))))
+ (of-ordinary-time-12-wednesday-ii
+ (((part First) (reference "2 Kings 22:8-13;23:1-3"))
+ ((part Gospel) (reference "Matthew 7:15-22"))))
+ (of-ordinary-time-13-friday-i
+ (((part First) (reference "Genesis 23:1-4,19;24:1-8,62-67"))
+ ((part Gospel) (reference "Matthew 9:9-13"))))
+ (of-ordinary-time-13-friday-ii
+ (((part First) (reference "Amos 8:4-6,9-12"))
+ ((part Gospel) (reference "Matthew 9:9-13"))))
+ (of-ordinary-time-13-monday-i
+ (((part First) (reference "Genesis 18:16-33"))
+ ((part Gospel) (reference "Matthew 8:18-22"))))
+ (of-ordinary-time-13-monday-ii
+ (((part First) (reference "Amos 2:6-10,13-16"))
+ ((part Gospel) (reference "Matthew 8:18-22"))))
+ (of-ordinary-time-13-saturday-i
+ (((part First) (reference "Genesis 27:1-5,15-29"))
+ ((part Gospel) (reference "Matthew 9:14-17"))))
+ (of-ordinary-time-13-saturday-ii
+ (((part First) (reference "Amos 9:11-15"))
+ ((part Gospel) (reference "Matthew 9:14-17"))))
+ (of-ordinary-time-13-thursday-i
+ (((part First) (reference "Genesis 22:1b-19"))
+ ((part Gospel) (reference "Matthew 9:1-8"))))
+ (of-ordinary-time-13-thursday-ii
+ (((part First) (reference "Amos 7:10-17"))
+ ((part Gospel) (reference "Matthew 9:1-8"))))
+ (of-ordinary-time-13-tuesday-i
+ (((part First) (reference "Genesis 19:15-29"))
+ ((part Gospel) (reference "Matthew 8:23-27"))))
+ (of-ordinary-time-13-tuesday-ii
+ (((part First) (reference "Amos 3:1-8;4:11-12"))
+ ((part Gospel) (reference "Matthew 8:23-27"))))
+ (of-ordinary-time-13-wednesday-i
+ (((part First) (reference "Genesis 21:5,8-20a"))
+ ((part Gospel) (reference "Matthew 8:28-34"))))
+ (of-ordinary-time-13-wednesday-ii
+ (((part First) (reference "Amos 5:14-15,21-24"))
+ ((part Gospel) (reference "Matthew 8:28-34"))))
+ (of-ordinary-time-14-friday-i
+ (((part First) (reference "Genesis 46:1-7,28-30"))
+ ((part Gospel) (reference "Matthew 10:16-23"))))
+ (of-ordinary-time-14-friday-ii
+ (((part First) (reference "Hosea 14:2-10"))
+ ((part Gospel) (reference "Matthew 10:16-23"))))
+ (of-ordinary-time-14-monday-i
+ (((part First) (reference "Genesis 28:10-22a"))
+ ((part Gospel) (reference "Matthew 9:18-26"))))
+ (of-ordinary-time-14-monday-ii
+ (((part First) (reference "Hosea 2:16,17c-18,21-22"))
+ ((part Gospel) (reference "Matthew 9:18-26"))))
+ (of-ordinary-time-14-saturday-i
+ (((part First) (reference "Genesis 49:29-32;50:15-26a"))
+ ((part Gospel) (reference "Matthew 10:24-33"))))
+ (of-ordinary-time-14-saturday-ii
+ (((part First) (reference "Isaiah 6:1-8"))
+ ((part Gospel) (reference "Matthew 10:24-33"))))
+ (of-ordinary-time-14-thursday-i
+ (((part First) (reference "Genesis 44:18-21,23b-29;45:1-5"))
+ ((part Gospel) (reference "Matthew 10:7-15"))))
+ (of-ordinary-time-14-thursday-ii
+ (((part First) (reference "Hosea 11:1-4,8e-9"))
+ ((part Gospel) (reference "Matthew 10:7-15"))))
+ (of-ordinary-time-14-tuesday-i
+ (((part First) (reference "Genesis 32:23-33"))
+ ((part Gospel) (reference "Matthew 9:32-38"))))
+ (of-ordinary-time-14-tuesday-ii
+ (((part First) (reference "Hosea 8:4-7,11-13"))
+ ((part Gospel) (reference "Matthew 9:32-38"))))
+ (of-ordinary-time-14-wednesday-i
+ (((part First) (reference "Genesis 41:55-57;42:5-7a,17-24a"))
+ ((part Gospel) (reference "Matthew 10:1-7"))))
+ (of-ordinary-time-14-wednesday-ii
+ (((part First) (reference "Hosea 10:1-3,7-8,12"))
+ ((part Gospel) (reference "Matthew 10:1-7"))))
+ (of-ordinary-time-15-friday-i
+ (((part First) (reference "Exodus 11:10-12:14"))
+ ((part Gospel) (reference "Matthew 12:1-8"))))
+ (of-ordinary-time-15-friday-ii
+ (((part First) (reference "Isaiah 38:1-6,21-22,7-8"))
+ ((part Gospel) (reference "Matthew 12:1-8"))))
+ (of-ordinary-time-15-monday-i
+ (((part First) (reference "Exodus 1:8-14,22"))
+ ((part Gospel) (reference "Matthew 10:34-11:1"))))
+ (of-ordinary-time-15-monday-ii
+ (((part First) (reference "Isaiah 1:10-17"))
+ ((part Gospel) (reference "Matthew 10:34-11:1"))))
+ (of-ordinary-time-15-saturday-i
+ (((part First) (reference "Exodus 12:37-42"))
+ ((part Gospel) (reference "Matthew 12:14-21"))))
+ (of-ordinary-time-15-saturday-ii
+ (((part First) (reference "Micah 2:1-5"))
+ ((part Gospel) (reference "Matthew 12:14-21"))))
+ (of-ordinary-time-15-thursday-i
+ (((part First) (reference "Exodus 3:13-20"))
+ ((part Gospel) (reference "Matthew 11:28-30"))))
+ (of-ordinary-time-15-thursday-ii
+ (((part First) (reference "Isaiah 26:7-9,12,16-19"))
+ ((part Gospel) (reference "Matthew 11:28-30"))))
+ (of-ordinary-time-15-tuesday-i
+ (((part First) (reference "Exodus 2:1-15a"))
+ ((part Gospel) (reference "Matthew 11:20-24"))))
+ (of-ordinary-time-15-tuesday-ii
+ (((part First) (reference "Isaiah 7:1-9"))
+ ((part Gospel) (reference "Matthew 11:20-24"))))
+ (of-ordinary-time-15-wednesday-i
+ (((part First) (reference "Exodus 3:1-6,9-12"))
+ ((part Gospel) (reference "Matthew 11:25-27"))))
+ (of-ordinary-time-15-wednesday-ii
+ (((part First) (reference "Isaiah 10:5-7,13b-16"))
+ ((part Gospel) (reference "Matthew 11:25-27"))))
+ (of-ordinary-time-16-friday-i
+ (((part First) (reference "Exodus 20:1-17"))
+ ((part Gospel) (reference "Matthew 13:18-23"))))
+ (of-ordinary-time-16-friday-ii
+ (((part First) (reference "Jeremiah 3:14-17"))
+ ((part Gospel) (reference "Matthew 13:18-23"))))
+ (of-ordinary-time-16-monday-i
+ (((part First) (reference "Exodus 14:5-18"))
+ ((part Gospel) (reference "Matthew 12:38-42"))))
+ (of-ordinary-time-16-monday-ii
+ (((part First) (reference "Micah 6:1-4,6-8"))
+ ((part Gospel) (reference "Matthew 12:38-42"))))
+ (of-ordinary-time-16-saturday-i
+ (((part First) (reference "Exodus 24:3-8"))
+ ((part Gospel) (reference "Matthew 13:24-30"))))
+ (of-ordinary-time-16-saturday-ii
+ (((part First) (reference "Jeremiah 7:1-11"))
+ ((part Gospel) (reference "Matthew 13:24-30"))))
+ (of-ordinary-time-16-thursday-i
+ (((part First) (reference "Exodus 19:1-2,9-11,16-20b"))
+ ((part Gospel) (reference "Matthew 13:10-17"))))
+ (of-ordinary-time-16-thursday-ii
+ (((part First) (reference "Jeremiah 2:1-3,7-8,12-13"))
+ ((part Gospel) (reference "Matthew 13:10-17"))))
+ (of-ordinary-time-16-tuesday-i
+ (((part First) (reference "Exodus 14:21-15:1"))
+ ((part Gospel) (reference "Matthew 12:46-50"))))
+ (of-ordinary-time-16-tuesday-ii
+ (((part First) (reference "Micah 7:14-15,18-22"))
+ ((part Gospel) (reference "Matthew 12:46-50"))))
+ (of-ordinary-time-16-wednesday-i
+ (((part First) (reference "Exodus 16:1-5,9-15"))
+ ((part Gospel) (reference "Matthew 13:1-9"))))
+ (of-ordinary-time-16-wednesday-ii
+ (((part First) (reference "Jeremiah 1:1,4-10"))
+ ((part Gospel) (reference "Matthew 13:1-9"))))
+ (of-ordinary-time-17-friday-i
+ (((part First) (reference "Leviticus 23:1,4-11,15-16,27,34b-37"))
+ ((part Gospel) (reference "Matthew 13:54-58"))))
+ (of-ordinary-time-17-friday-ii
+ (((part First) (reference "Jeremiah 26:1-9"))
+ ((part Gospel) (reference "Matthew 13:54-58"))))
+ (of-ordinary-time-17-monday-i
+ (((part First) (reference "Exodus 32:15-24,30-34"))
+ ((part Gospel) (reference "Matthew 13:31-35"))))
+ (of-ordinary-time-17-monday-ii
+ (((part First) (reference "Jeremiah 13:1-11"))
+ ((part Gospel) (reference "Matthew 13:31-35"))))
+ (of-ordinary-time-17-saturday-i
+ (((part First) (reference "Leviticus 25:1,8-17"))
+ ((part Gospel) (reference "Matthew 14:1-12"))))
+ (of-ordinary-time-17-saturday-ii
+ (((part First) (reference "Jeremiah 26:11-16,24"))
+ ((part Gospel) (reference "Matthew 14:1-12"))))
+ (of-ordinary-time-17-thursday-i
+ (((part First) (reference "Exodus 40:16-21,34-38"))
+ ((part Gospel) (reference "Matthew 13:47-53"))))
+ (of-ordinary-time-17-thursday-ii
+ (((part First) (reference "Jeremiah 18:1-6"))
+ ((part Gospel) (reference "Matthew 13:47-53"))))
+ (of-ordinary-time-17-tuesday-i
+ (((part First) (reference "Exodus 33:7-11;34:5b-9,28"))
+ ((part Gospel) (reference "Matthew 13:36-43"))))
+ (of-ordinary-time-17-tuesday-ii
+ (((part First) (reference "Jeremiah 14:17-22"))
+ ((part Gospel) (reference "Matthew 13:36-43"))))
+ (of-ordinary-time-17-wednesday-i
+ (((part First) (reference "Exodus 34:29-35"))
+ ((part Gospel) (reference "Matthew 13:44-46"))))
+ (of-ordinary-time-17-wednesday-ii
+ (((part First) (reference "Jeremiah 15:10,16-21"))
+ ((part Gospel) (reference "Matthew 13:44-46"))))
+ (of-ordinary-time-18-friday-i
+ (((part First) (reference "Deuteronomy 4:32-40"))
+ ((part Gospel) (reference "Matthew 16:24-28"))))
+ (of-ordinary-time-18-friday-ii
+ (((part First) (reference "Nahum 2:1,3;3:1-3,6-7"))
+ ((part Gospel) (reference "Matthew 16:24-28"))))
+ (of-ordinary-time-18-monday-i
+ (((part First) (reference "Numbers 11:4b-15"))
+ ((part Gospel) (reference "Matthew 14:13-21"))))
+ (of-ordinary-time-18-monday-ii
+ (((part First) (reference "Jeremiah 28:1-17"))
+ ((part Gospel) (reference "Matthew 14:13-21"))))
+ (of-ordinary-time-18-saturday-i
+ (((part First) (reference "Deuteronomy 6:4-13"))
+ ((part Gospel) (reference "Matthew 17:14-20"))))
+ (of-ordinary-time-18-saturday-ii
+ (((part First) (reference "Habakkuk 1:12-2:4"))
+ ((part Gospel) (reference "Matthew 17:14-22"))))
+ (of-ordinary-time-18-thursday-i
+ (((part First) (reference "Numbers 20:1-13"))
+ ((part Gospel) (reference "Matthew 16:13-23"))))
+ (of-ordinary-time-18-thursday-ii
+ (((part First) (reference "Jeremiah 31:31-34"))
+ ((part Gospel) (reference "Matthew 16:13-23"))))
+ (of-ordinary-time-18-tuesday-i
+ (((part First) (reference "Numbers 12:1-13"))
+ ((part Gospel) (reference "Matthew 14:22-36"))))
+ (of-ordinary-time-18-tuesday-ii
+ (((part First) (reference "Jeremiah 30:1-2,12-15,18-22"))
+ ((part Gospel) (reference "Matthew 14:22-36"))))
+ (of-ordinary-time-18-wednesday-i
+ (((part First) (reference "Numbers 13:1-2,25-14:1,26a-29a,34-35"))
+ ((part Gospel) (reference "Matthew 15:21-28"))))
+ (of-ordinary-time-18-wednesday-ii
+ (((part First) (reference "Jeremiah 31:1-7"))
+ ((part Gospel) (reference "Matthew 15:21-28"))))
+ (of-ordinary-time-19-friday-i
+ (((part First) (reference "Joshua 24:1-13"))
+ ((part Gospel) (reference "Matthew 19:3-12"))))
+ (of-ordinary-time-19-friday-ii
+ (((part First) (reference "Ezekiel 16:1-15,60,63"))
+ ((part Gospel) (reference "Matthew 19:3-12"))))
+ (of-ordinary-time-19-monday-i
+ (((part First) (reference "Deuteronomy 10:12-22"))
+ ((part Gospel) (reference "Matthew 17:22-27"))))
+ (of-ordinary-time-19-monday-ii
+ (((part First) (reference "Ezekiel 1:2-5,24-28c"))
+ ((part Gospel) (reference "Matthew 17:22-27"))))
+ (of-ordinary-time-19-saturday-i
+ (((part First) (reference "Joshua 24:14-29"))
+ ((part Gospel) (reference "Matthew 19:13-15"))))
+ (of-ordinary-time-19-saturday-ii
+ (((part First) (reference "Ezekiel 18:1-10,13b,30-32"))
+ ((part Gospel) (reference "Matthew 19:13-15"))))
+ (of-ordinary-time-19-thursday-i
+ (((part First) (reference "Joshua 3:7-10a,11,13-17"))
+ ((part Gospel) (reference "Matthew 18:21-19:1"))))
+ (of-ordinary-time-19-thursday-ii
+ (((part First) (reference "Ezekiel 12:1-12"))
+ ((part Gospel) (reference "Matthew 18:21-19:1"))))
+ (of-ordinary-time-19-tuesday-i
+ (((part First) (reference "Deuteronomy 31:1-8"))
+ ((part Gospel) (reference "Matthew 18:1-5,10,12-14"))))
+ (of-ordinary-time-19-tuesday-ii
+ (((part First) (reference "Ezekiel 2:8-3:4"))
+ ((part Gospel) (reference "Matthew 18:1-5,10,12-14"))))
+ (of-ordinary-time-19-wednesday-i
+ (((part First) (reference "Deuteronomy 34:1-12"))
+ ((part Gospel) (reference "Matthew 18:15-20"))))
+ (of-ordinary-time-19-wednesday-ii
+ (((part First) (reference "Ezekiel 9:1-7;10:18-22"))
+ ((part Gospel) (reference "Matthew 18:15-22"))))
+ (of-ordinary-time-2-friday-i
+ (((part First) (reference "Hebrews 8:6-13"))
+ ((part Gospel) (reference "Mark 3:13-19"))))
+ (of-ordinary-time-2-friday-ii
+ (((part First) (reference "1 Samuel 24:3-21"))
+ ((part Gospel) (reference "Mark 3:13-19"))))
+ (of-ordinary-time-2-monday-i
+ (((part First) (reference "Hebrews 5:1-10"))
+ ((part Gospel) (reference "Mark 2:18-22"))))
+ (of-ordinary-time-2-monday-ii
+ (((part First) (reference "1 Samuel 15:16-23"))
+ ((part Gospel) (reference "Mark 2:18-22"))))
+ (of-ordinary-time-2-saturday-i
+ (((part First) (reference "Hebrews 9:2-3,11-14"))
+ ((part Gospel) (reference "Mark 3:20-21"))))
+ (of-ordinary-time-2-saturday-ii
+ (((part First) (reference "2 Samuel 1:1-4,11-12,19,23-27"))
+ ((part Gospel) (reference "Mark 3:20-21"))))
+ (of-ordinary-time-2-thursday-i
+ (((part First) (reference "Hebrews 7:25-8:6"))
+ ((part Gospel) (reference "Mark 3:7-12"))))
+ (of-ordinary-time-2-thursday-ii
+ (((part First) (reference "1 Samuel 18:6-9;19:1-7"))
+ ((part Gospel) (reference "Mark 3:7-12"))))
+ (of-ordinary-time-2-tuesday-i
+ (((part First) (reference "Hebrews 6:10-20"))
+ ((part Gospel) (reference "Mark 2:23-28"))))
+ (of-ordinary-time-2-tuesday-ii
+ (((part First) (reference "1 Samuel 16:1-13"))
+ ((part Gospel) (reference "Mark 2:23-28"))))
+ (of-ordinary-time-2-wednesday-i
+ (((part First) (reference "Hebrews 7:1-3,15-17"))
+ ((part Gospel) (reference "Mark 3:1-6"))))
+ (of-ordinary-time-2-wednesday-ii
+ (((part First) (reference "1 Samuel 17:32-33,37,40-51"))
+ ((part Gospel) (reference "Mark 3:1-6"))))
+ (of-ordinary-time-20-friday-i
+ (((part First) (reference "Ruth 1:1,3-6,14b-16,22"))
+ ((part Gospel) (reference "Matthew 22:34-40"))))
+ (of-ordinary-time-20-friday-ii
+ (((part First) (reference "Ezekiel 37:1-14"))
+ ((part Gospel) (reference "Matthew 22:34-40"))))
+ (of-ordinary-time-20-monday-i
+ (((part First) (reference "Judges 2:11-19"))
+ ((part Gospel) (reference "Matthew 19:16-22"))))
+ (of-ordinary-time-20-monday-ii
+ (((part First) (reference "Ezekiel 24:15-23"))
+ ((part Gospel) (reference "Matthew 19:16-22"))))
+ (of-ordinary-time-20-saturday-i
+ (((part First) (reference "Ruth 2:1-3,8-11;4:13-17"))
+ ((part Gospel) (reference "Matthew 23:1-12"))))
+ (of-ordinary-time-20-saturday-ii
+ (((part First) (reference "Ezekiel 43:1-7ab"))
+ ((part Gospel) (reference "Matthew 23:1-12"))))
+ (of-ordinary-time-20-thursday-i
+ (((part First) (reference "Judges 11:29-39a"))
+ ((part Gospel) (reference "Matthew 22:1-14"))))
+ (of-ordinary-time-20-thursday-ii
+ (((part First) (reference "Ezekiel 36:23-28"))
+ ((part Gospel) (reference "Matthew 22:1-14"))))
+ (of-ordinary-time-20-tuesday-i
+ (((part First) (reference "Judges 6:11-24a"))
+ ((part Gospel) (reference "Matthew 19:23-30"))))
+ (of-ordinary-time-20-tuesday-ii
+ (((part First) (reference "Ezekiel 28:1-10"))
+ ((part Gospel) (reference "Matthew 19:23-30"))))
+ (of-ordinary-time-20-wednesday-i
+ (((part First) (reference "Judges 9:6-15"))
+ ((part Gospel) (reference "Matthew 20:1-16"))))
+ (of-ordinary-time-20-wednesday-ii
+ (((part First) (reference "Ezekiel 34:1-11"))
+ ((part Gospel) (reference "Matthew 20:1-16"))))
+ (of-ordinary-time-21-friday-i
+ (((part First) (reference "1 Thessalonians 4:1-8"))
+ ((part Gospel) (reference "Matthew 25:1-13"))))
+ (of-ordinary-time-21-friday-ii
+ (((part First) (reference "1 Corinthians 1:17-25"))
+ ((part Gospel) (reference "Matthew 25:1-13"))))
+ (of-ordinary-time-21-monday-i
+ (((part First) (reference "1 Thessalonians 1:1-5,8b-10"))
+ ((part Gospel) (reference "Matthew 23:13-22"))))
+ (of-ordinary-time-21-monday-ii
+ (((part First) (reference "2 Thessalonians 1:1-5,11-12"))
+ ((part Gospel) (reference "Matthew 23:13-22"))))
+ (of-ordinary-time-21-saturday-i
+ (((part First) (reference "1 Thessalonians 4:9-11"))
+ ((part Gospel) (reference "Matthew 25:14-30"))))
+ (of-ordinary-time-21-saturday-ii
+ (((part First) (reference "1 Corinthians 1:26-31"))
+ ((part Gospel) (reference "Matthew 25:14-30"))))
+ (of-ordinary-time-21-thursday-i
+ (((part First) (reference "1 Thessalonians 3:7-13"))
+ ((part Gospel) (reference "Matthew 24:42-51"))))
+ (of-ordinary-time-21-thursday-ii
+ (((part First) (reference "1 Corinthians 1:1-9"))
+ ((part Gospel) (reference "Matthew 24:42-51"))))
+ (of-ordinary-time-21-tuesday-i
+ (((part First) (reference "1 Thessalonians 2:1-8"))
+ ((part Gospel) (reference "Matthew 23:23-26"))))
+ (of-ordinary-time-21-tuesday-ii
+ (((part First) (reference "2 Thessalonians 2:1-3a,14-17"))
+ ((part Gospel) (reference "Matthew 23:23-26"))))
+ (of-ordinary-time-21-wednesday-i
+ (((part First) (reference "1 Thessalonians 2:9-13"))
+ ((part Gospel) (reference "Matthew 23:27-32"))))
+ (of-ordinary-time-21-wednesday-ii
+ (((part First) (reference "2 Thessalonians 3:6-10,16-18"))
+ ((part Gospel) (reference "Matthew 23:27-32"))))
+ (of-ordinary-time-22-friday-i
+ (((part First) (reference "Colossians 1:15-20"))
+ ((part Gospel) (reference "Luke 5:33-39"))))
+ (of-ordinary-time-22-friday-ii
+ (((part First) (reference "1 Corinthians 4:1-5"))
+ ((part Gospel) (reference "Luke 5:33-39"))))
+ (of-ordinary-time-22-monday-i
+ (((part First) (reference "1 Thessalonians 4:13-18"))
+ ((part Gospel) (reference "Luke 4:16-30"))))
+ (of-ordinary-time-22-monday-ii
+ (((part First) (reference "1 Corinthians 2:1-5"))
+ ((part Gospel) (reference "Luke 4:16-30"))))
+ (of-ordinary-time-22-saturday-i
+ (((part First) (reference "Colossians 1:21-23"))
+ ((part Gospel) (reference "Luke 6:1-5"))))
+ (of-ordinary-time-22-saturday-ii
+ (((part First) (reference "1 Corinthians 4:6b-15"))
+ ((part Gospel) (reference "Luke 6:1-5"))))
+ (of-ordinary-time-22-thursday-i
+ (((part First) (reference "Colossians 1:9-14"))
+ ((part Gospel) (reference "Luke 5:1-11"))))
+ (of-ordinary-time-22-thursday-ii
+ (((part First) (reference "1 Corinthians 3:18-23"))
+ ((part Gospel) (reference "Luke 5:1-11"))))
+ (of-ordinary-time-22-tuesday-i
+ (((part First) (reference "1 Thessalonians 5:1-6,9-11"))
+ ((part Gospel) (reference "Luke 4:31-37"))))
+ (of-ordinary-time-22-tuesday-ii
+ (((part First) (reference "1 Corinthians 2:10b-16"))
+ ((part Gospel) (reference "Luke 4:31-37"))))
+ (of-ordinary-time-22-wednesday-i
+ (((part First) (reference "Colossians 1:1-8"))
+ ((part Gospel) (reference "Luke 4:38-44"))))
+ (of-ordinary-time-22-wednesday-ii
+ (((part First) (reference "1 Corinthians 3:1-9"))
+ ((part Gospel) (reference "Luke 4:38-44"))))
+ (of-ordinary-time-23-friday-i
+ (((part First) (reference "1 Timothy 1:1-2,12-14"))
+ ((part Gospel) (reference "Luke 6:39-42"))))
+ (of-ordinary-time-23-friday-ii
+ (((part First) (reference "1 Corinthians 9:16-19,22b-27"))
+ ((part Gospel) (reference "Luke 6:39-42"))))
+ (of-ordinary-time-23-monday-i
+ (((part First) (reference "Colossians 1:24-2:3"))
+ ((part Gospel) (reference "Luke 6:6-11"))))
+ (of-ordinary-time-23-monday-ii
+ (((part First) (reference "1 Corinthians 5:1-8"))
+ ((part Gospel) (reference "Luke 6:6-11"))))
+ (of-ordinary-time-23-saturday-i
+ (((part First) (reference "1 Timothy 1:15-17"))
+ ((part Gospel) (reference "Luke 6:43-49"))))
+ (of-ordinary-time-23-saturday-ii
+ (((part First) (reference "1 Corinthians 10:14-22"))
+ ((part Gospel) (reference "Luke 6:43-49"))))
+ (of-ordinary-time-23-thursday-i
+ (((part First) (reference "Colossians 3:12-17"))
+ ((part Gospel) (reference "Luke 6:27-38"))))
+ (of-ordinary-time-23-thursday-ii
+ (((part First) (reference "1 Corinthians 8:1b-7,11-13"))
+ ((part Gospel) (reference "Luke 6:27-38"))))
+ (of-ordinary-time-23-tuesday-i
+ (((part First) (reference "Colossians 2:6-15"))
+ ((part Gospel) (reference "Luke 6:12-19"))))
+ (of-ordinary-time-23-tuesday-ii
+ (((part First) (reference "1 Corinthians 6:1-11"))
+ ((part Gospel) (reference "Luke 6:12-19"))))
+ (of-ordinary-time-23-wednesday-i
+ (((part First) (reference "Colossians 3:1-11"))
+ ((part Gospel) (reference "Luke 6:20-26"))))
+ (of-ordinary-time-23-wednesday-ii
+ (((part First) (reference "1 Corinthians 7:25-31"))
+ ((part Gospel) (reference "Luke 6:20-26"))))
+ (of-ordinary-time-24-friday-i
+ (((part First) (reference "1 Timothy 6:2c-12"))
+ ((part Gospel) (reference "Luke 8:1-3"))))
+ (of-ordinary-time-24-friday-ii
+ (((part First) (reference "1 Corinthians 15:12-22"))
+ ((part Gospel) (reference "Luke 8:1-3"))))
+ (of-ordinary-time-24-monday-i
+ (((part First) (reference "1 Timothy 2:1-8"))
+ ((part Gospel) (reference "Luke 7:1-10"))))
+ (of-ordinary-time-24-monday-ii
+ (((part First) (reference "1 Corinthians 11:17-26,33"))
+ ((part Gospel) (reference "Luke 7:1-10"))))
+ (of-ordinary-time-24-saturday-i
+ (((part First) (reference "1 Timothy 6:13-16"))
+ ((part Gospel) (reference "Luke 8:4-15"))))
+ (of-ordinary-time-24-saturday-ii
+ (((part First) (reference "1 Corinthians 15:35-37,42-49"))
+ ((part Gospel) (reference "Luke 8:4-15"))))
+ (of-ordinary-time-24-thursday-i
+ (((part First) (reference "1 Timothy 4:12-16"))
+ ((part Gospel) (reference "Luke 7:36-50"))))
+ (of-ordinary-time-24-thursday-ii
+ (((part First) (reference "1 Corinthians 15:1-11"))
+ ((part Gospel) (reference "Luke 7:36-50"))))
+ (of-ordinary-time-24-tuesday-i
+ (((part First) (reference "1 Timothy 3:1-13"))
+ ((part Gospel) (reference "Luke 7:11-17"))))
+ (of-ordinary-time-24-tuesday-ii
+ (((part First) (reference "1 Corinthians 12:12-14,27-31a"))
+ ((part Gospel) (reference "Luke 7:11-17"))))
+ (of-ordinary-time-24-wednesday-i
+ (((part First) (reference "1 Timothy 3:14-16"))
+ ((part Gospel) (reference "Luke 7:31-35"))))
+ (of-ordinary-time-24-wednesday-ii
+ (((part First) (reference "1 Corinthians 12:31-13:13"))
+ ((part Gospel) (reference "Luke 7:31-35"))))
+ (of-ordinary-time-25-friday-i
+ (((part First) (reference "Haggai 2:1-9"))
+ ((part Gospel) (reference "Luke 9:18-22"))))
+ (of-ordinary-time-25-friday-ii
+ (((part First) (reference "Ecclesiastes 3:1-11"))
+ ((part Gospel) (reference "Luke 9:18-22"))))
+ (of-ordinary-time-25-monday-i
+ (((part First) (reference "Ezra 1:1-6"))
+ ((part Gospel) (reference "Luke 8:16-18"))))
+ (of-ordinary-time-25-monday-ii
+ (((part First) (reference "Proverbs 3:27-34"))
+ ((part Gospel) (reference "Luke 8:16-18"))))
+ (of-ordinary-time-25-saturday-i
+ (((part First) (reference "Zechariah 2:1-5,10-11"))
+ ((part Gospel) (reference "Luke 9:43b-45"))))
+ (of-ordinary-time-25-saturday-ii
+ (((part First) (reference "Ecclesiastes 11:9-12:8"))
+ ((part Gospel) (reference "Luke 9:43b-45"))))
+ (of-ordinary-time-25-thursday-i
+ (((part First) (reference "Haggai 1:1-8"))
+ ((part Gospel) (reference "Luke 9:7-9"))))
+ (of-ordinary-time-25-thursday-ii
+ (((part First) (reference "Ecclesiastes 1:2-11"))
+ ((part Gospel) (reference "Luke 9:7-9"))))
+ (of-ordinary-time-25-tuesday-i
+ (((part First) (reference "Ezra 6:7-8,12b,14-20"))
+ ((part Gospel) (reference "Luke 8:19-21"))))
+ (of-ordinary-time-25-tuesday-ii
+ (((part First) (reference "Proverbs 21:1-6,10-13"))
+ ((part Gospel) (reference "Luke 8:19-21"))))
+ (of-ordinary-time-25-wednesday-i
+ (((part First) (reference "Ezra 9:5-9"))
+ ((part Gospel) (reference "Luke 9:1-6"))))
+ (of-ordinary-time-25-wednesday-ii
+ (((part First) (reference "Proverbs 30:5-9"))
+ ((part Gospel) (reference "Luke 9:1-6"))))
+ (of-ordinary-time-26-friday-i
+ (((part First) (reference "Baruch 1:15-22"))
+ ((part Gospel) (reference "Luke 10:13-16"))))
+ (of-ordinary-time-26-friday-ii
+ (((part First) (reference "Job 38:1,12-21;40:3-5"))
+ ((part Gospel) (reference "Luke 10:13-16"))))
+ (of-ordinary-time-26-monday-i
+ (((part First) (reference "Zechariah 8:1-8"))
+ ((part Gospel) (reference "Luke 9:46-50"))))
+ (of-ordinary-time-26-monday-ii
+ (((part First) (reference "Job 1:6-22"))
+ ((part Gospel) (reference "Luke 9:46-50"))))
+ (of-ordinary-time-26-saturday-i
+ (((part First) (reference "Baruch 4:5-12,27-29"))
+ ((part Gospel) (reference "Luke 10:17-24"))))
+ (of-ordinary-time-26-saturday-ii
+ (((part First) (reference "Job 42:1-3,5-6,12-17"))
+ ((part Gospel) (reference "Luke 10:17-24"))))
+ (of-ordinary-time-26-thursday-i
+ (((part First) (reference "Nehemiah 8:1-4a,5-6,7b-12"))
+ ((part Gospel) (reference "Luke 10:1-12"))))
+ (of-ordinary-time-26-thursday-ii
+ (((part First) (reference "Job 19:21-27"))
+ ((part Gospel) (reference "Luke 10:1-12"))))
+ (of-ordinary-time-26-tuesday-i
+ (((part First) (reference "Zechariah 8:20-23"))
+ ((part Gospel) (reference "Luke 9:51-56"))))
+ (of-ordinary-time-26-tuesday-ii
+ (((part First) (reference "Job 3:1-3,11-17,20-23"))
+ ((part Gospel) (reference "Luke 9:51-56"))))
+ (of-ordinary-time-26-wednesday-i
+ (((part First) (reference "Nehemiah 2:1-8"))
+ ((part Gospel) (reference "Luke 9:57-62"))))
+ (of-ordinary-time-26-wednesday-ii
+ (((part First) (reference "Job 9:1-12,14-16"))
+ ((part Gospel) (reference "Luke 9:57-62"))))
+ (of-ordinary-time-27-friday-i
+ (((part First) (reference "Joel 1:13-15;2:1-2"))
+ ((part Gospel) (reference "Luke 11:15-26"))))
+ (of-ordinary-time-27-friday-ii
+ (((part First) (reference "Galatians 3:7-14"))
+ ((part Gospel) (reference "Luke 11:15-26"))))
+ (of-ordinary-time-27-monday-i
+ (((part First) (reference "Jonah 1:1-2:2,11"))
+ ((part Gospel) (reference "Luke 10:25-37"))))
+ (of-ordinary-time-27-monday-ii
+ (((part First) (reference "Galatians 1:6-12"))
+ ((part Gospel) (reference "Luke 10:25-37"))))
+ (of-ordinary-time-27-saturday-i
+ (((part First) (reference "Joel 3:12-21"))
+ ((part Gospel) (reference "Luke 11:27-28"))))
+ (of-ordinary-time-27-saturday-ii
+ (((part First) (reference "Galatians 3:22-29"))
+ ((part Gospel) (reference "Luke 11:27-28"))))
+ (of-ordinary-time-27-thursday-i
+ (((part First) (reference "Malachi 3:13-18;4:1-2"))
+ ((part Gospel) (reference "Luke 11:5-13"))))
+ (of-ordinary-time-27-thursday-ii
+ (((part First) (reference "Galatians 3:1-5"))
+ ((part Gospel) (reference "Luke 11:5-13"))))
+ (of-ordinary-time-27-tuesday-i
+ (((part First) (reference "Jonah 3:1-10"))
+ ((part Gospel) (reference "Luke 10:38-42"))))
+ (of-ordinary-time-27-tuesday-ii
+ (((part First) (reference "Galatians 1:13-24"))
+ ((part Gospel) (reference "Luke 10:38-42"))))
+ (of-ordinary-time-27-wednesday-i
+ (((part First) (reference "Jonah 4:1-11"))
+ ((part Gospel) (reference "Luke 11:1-4"))))
+ (of-ordinary-time-27-wednesday-ii
+ (((part First) (reference "Galatians 2:1-2,7-14"))
+ ((part Gospel) (reference "Luke 11:1-4"))))
+ (of-ordinary-time-28-friday-i
+ (((part First) (reference "Romans 4:1-8"))
+ ((part Gospel) (reference "Luke 12:1-7"))))
+ (of-ordinary-time-28-friday-ii
+ (((part First) (reference "Ephesians 1:11-14"))
+ ((part Gospel) (reference "Luke 12:1-7"))))
+ (of-ordinary-time-28-monday-i
+ (((part First) (reference "Romans 1:1-7"))
+ ((part Gospel) (reference "Luke 11:29-32"))))
+ (of-ordinary-time-28-monday-ii
+ (((part First) (reference "Galatians 4:22-24,26-27,31-5:1"))
+ ((part Gospel) (reference "Luke 11:29-32"))))
+ (of-ordinary-time-28-saturday-i
+ (((part First) (reference "Romans 4:13,16-18"))
+ ((part Gospel) (reference "Luke 12:8-12"))))
+ (of-ordinary-time-28-saturday-ii
+ (((part First) (reference "Ephesians 1:15-23"))
+ ((part Gospel) (reference "Luke 12:8-12"))))
+ (of-ordinary-time-28-thursday-i
+ (((part First) (reference "Romans 3:21-30"))
+ ((part Gospel) (reference "Luke 11:47-54"))))
+ (of-ordinary-time-28-thursday-ii
+ (((part First) (reference "Ephesians 1:1-10"))
+ ((part Gospel) (reference "Luke 11:47-54"))))
+ (of-ordinary-time-28-tuesday-i
+ (((part First) (reference "Romans 1:16-25"))
+ ((part Gospel) (reference "Luke 11:37-41"))))
+ (of-ordinary-time-28-tuesday-ii
+ (((part First) (reference "Galatians 5:1-6"))
+ ((part Gospel) (reference "Luke 11:37-41"))))
+ (of-ordinary-time-28-wednesday-i
+ (((part First) (reference "Romans 2:1-11"))
+ ((part Gospel) (reference "Luke 11:42-46"))))
+ (of-ordinary-time-28-wednesday-ii
+ (((part First) (reference "Galatians 5:18-25"))
+ ((part Gospel) (reference "Luke 11:42-46"))))
+ (of-ordinary-time-29-friday-i
+ (((part First) (reference "Romans 7:18-25a"))
+ ((part Gospel) (reference "Luke 12:54-59"))))
+ (of-ordinary-time-29-friday-ii
+ (((part First) (reference "Ephesians 4:1-6"))
+ ((part Gospel) (reference "Luke 12:54-59"))))
+ (of-ordinary-time-29-monday-i
+ (((part First) (reference "Romans 4:20-25"))
+ ((part Gospel) (reference "Luke 12:13-21"))))
+ (of-ordinary-time-29-monday-ii
+ (((part First) (reference "Ephesians 2:1-10"))
+ ((part Gospel) (reference "Luke 12:13-21"))))
+ (of-ordinary-time-29-saturday-i
+ (((part First) (reference "Romans 8:1-11"))
+ ((part Gospel) (reference "Luke 13:1-9"))))
+ (of-ordinary-time-29-saturday-ii
+ (((part First) (reference "Ephesians 4:7-16"))
+ ((part Gospel) (reference "Luke 13:1-9"))))
+ (of-ordinary-time-29-thursday-i
+ (((part First) (reference "Romans 6:19-23"))
+ ((part Gospel) (reference "Luke 12:49-53"))))
+ (of-ordinary-time-29-thursday-ii
+ (((part First) (reference "Ephesians 3:14-21"))
+ ((part Gospel) (reference "Luke 12:49-53"))))
+ (of-ordinary-time-29-tuesday-i
+ (((part First) (reference "Romans 5:12,15b,17-19,20b-21"))
+ ((part Gospel) (reference "Luke 12:35-38"))))
+ (of-ordinary-time-29-tuesday-ii
+ (((part First) (reference "Ephesians 2:12-22"))
+ ((part Gospel) (reference "Luke 12:35-38"))))
+ (of-ordinary-time-29-wednesday-i
+ (((part First) (reference "Romans 6:12-18"))
+ ((part Gospel) (reference "Luke 12:39-48"))))
+ (of-ordinary-time-29-wednesday-ii
+ (((part First) (reference "Ephesians 3:2-12"))
+ ((part Gospel) (reference "Luke 12:39-48"))))
+ (of-ordinary-time-3-friday-i
+ (((part First) (reference "Hebrews 10:32-39"))
+ ((part Gospel) (reference "Mark 4:26-34"))))
+ (of-ordinary-time-3-friday-ii
+ (((part First) (reference "2 Samuel 11:1-4a,5-10a,13-17"))
+ ((part Gospel) (reference "Mark 4:26-34"))))
+ (of-ordinary-time-3-monday-i
+ (((part First) (reference "Hebrews 9:15,24-28"))
+ ((part Gospel) (reference "Mark 3:22-30"))))
+ (of-ordinary-time-3-monday-ii
+ (((part First) (reference "2 Samuel 5:1-7,10"))
+ ((part Gospel) (reference "Mark 3:22-30"))))
+ (of-ordinary-time-3-saturday-i
+ (((part First) (reference "Hebrews 11:1-2,8-19"))
+ ((part Gospel) (reference "Mark 4:35-41"))))
+ (of-ordinary-time-3-saturday-ii
+ (((part First) (reference "2 Samuel 12:1-7a,10-17"))
+ ((part Gospel) (reference "Mark 4:35-41"))))
+ (of-ordinary-time-3-thursday-i
+ (((part First) (reference "Hebrews 10:19-25"))
+ ((part Gospel) (reference "Mark 4:21-25"))))
+ (of-ordinary-time-3-thursday-ii
+ (((part First) (reference "2 Samuel 7:18-19,24-29"))
+ ((part Gospel) (reference "Mark 4:21-25"))))
+ (of-ordinary-time-3-tuesday-i
+ (((part First) (reference "Hebrews 10:1-10"))
+ ((part Gospel) (reference "Mark 3:31-35"))))
+ (of-ordinary-time-3-tuesday-ii
+ (((part First) (reference "2 Samuel 6:12b-15,17-19"))
+ ((part Gospel) (reference "Mark 3:31-35"))))
+ (of-ordinary-time-3-wednesday-i
+ (((part First) (reference "Hebrews 10:11-18"))
+ ((part Gospel) (reference "Mark 4:1-20"))))
+ (of-ordinary-time-3-wednesday-ii
+ (((part First) (reference "2 Samuel 7:4-17"))
+ ((part Gospel) (reference "Mark 4:1-22"))))
+ (of-ordinary-time-30-friday-i
+ (((part First) (reference "Romans 9:1-5"))
+ ((part Gospel) (reference "Luke 14:1-6"))))
+ (of-ordinary-time-30-friday-ii
+ (((part First) (reference "Philippians 1:1-11"))
+ ((part Gospel) (reference "Luke 14:1-6"))))
+ (of-ordinary-time-30-monday-i
+ (((part First) (reference "Romans 8:12-17"))
+ ((part Gospel) (reference "Luke 13:10-17"))))
+ (of-ordinary-time-30-monday-ii
+ (((part First) (reference "Ephesians 4:32-5:8"))
+ ((part Gospel) (reference "Luke 13:10-17"))))
+ (of-ordinary-time-30-saturday-i
+ (((part First) (reference "Romans 11:1-2a,11-12,25-29"))
+ ((part Gospel) (reference "Luke 14:1,7-11"))))
+ (of-ordinary-time-30-saturday-ii
+ (((part First) (reference "Philippians 1:18b-26"))
+ ((part Gospel) (reference "Luke 14:1,7-11"))))
+ (of-ordinary-time-30-thursday-i
+ (((part First) (reference "Romans 8:31b-39"))
+ ((part Gospel) (reference "Luke 13:31-35"))))
+ (of-ordinary-time-30-thursday-ii
+ (((part First) (reference "Ephesians 6:10-22"))
+ ((part Gospel) (reference "Luke 13:31-35"))))
+ (of-ordinary-time-30-tuesday-i
+ (((part First) (reference "Romans 8:18-25"))
+ ((part Gospel) (reference "Luke 13:18-21"))))
+ (of-ordinary-time-30-tuesday-ii
+ (((part First) (reference "Ephesians 5:21-33"))
+ ((part Gospel) (reference "Luke 13:18-21"))))
+ (of-ordinary-time-30-wednesday-i
+ (((part First) (reference "Romans 8:26-30"))
+ ((part Gospel) (reference "Luke 13:22-30"))))
+ (of-ordinary-time-30-wednesday-ii
+ (((part First) (reference "Ephesians 6:1-9"))
+ ((part Gospel) (reference "Luke 13:22-30"))))
+ (of-ordinary-time-31-friday-i
+ (((part First) (reference "Romans 15:14-21"))
+ ((part Gospel) (reference "Luke 16:1-8"))))
+ (of-ordinary-time-31-friday-ii
+ (((part First) (reference "Philippians 3:17-4:1"))
+ ((part Gospel) (reference "Luke 16:1-8"))))
+ (of-ordinary-time-31-monday-i
+ (((part First) (reference "Romans 11:29-36"))
+ ((part Gospel) (reference "Luke 14:12-14"))))
+ (of-ordinary-time-31-monday-ii
+ (((part First) (reference "Philippians 2:1-4"))
+ ((part Gospel) (reference "Luke 14:12-14"))))
+ (of-ordinary-time-31-saturday-i
+ (((part First) (reference "Romans 16:3-9,16,22-27"))
+ ((part Gospel) (reference "Luke 16:9-15"))))
+ (of-ordinary-time-31-saturday-ii
+ (((part First) (reference "Philippians 4:10-19"))
+ ((part Gospel) (reference "Luke 16:9-15"))))
+ (of-ordinary-time-31-thursday-i
+ (((part First) (reference "Romans 14:7-12"))
+ ((part Gospel) (reference "Luke 15:1-10"))))
+ (of-ordinary-time-31-thursday-ii
+ (((part First) (reference "Philippians 3:3-8a"))
+ ((part Gospel) (reference "Luke 15:1-10"))))
+ (of-ordinary-time-31-tuesday-i
+ (((part First) (reference "Romans 12:5-16ab"))
+ ((part Gospel) (reference "Luke 14:15-24"))))
+ (of-ordinary-time-31-tuesday-ii
+ (((part First) (reference "Philippians 2:5-11"))
+ ((part Gospel) (reference "Luke 14:15-24"))))
+ (of-ordinary-time-31-wednesday-i
+ (((part First) (reference "Romans 13:8-10"))
+ ((part Gospel) (reference "Luke 14:25-33"))))
+ (of-ordinary-time-31-wednesday-ii
+ (((part First) (reference "Philippians 2:12-18"))
+ ((part Gospel) (reference "Luke 14:25-33"))))
+ (of-ordinary-time-32-friday-i
+ (((part First) (reference "Wisdom 13:1-9"))
+ ((part Gospel) (reference "Luke 17:26-37"))))
+ (of-ordinary-time-32-friday-ii
+ (((part First) (reference "2 John 4-9"))
+ ((part Gospel) (reference "Luke 17:26-37"))))
+ (of-ordinary-time-32-monday-i
+ (((part First) (reference "Wisdom 1:1-7"))
+ ((part Gospel) (reference "Luke 17:1-6"))))
+ (of-ordinary-time-32-monday-ii
+ (((part First) (reference "Titus 1:1-9"))
+ ((part Gospel) (reference "Luke 17:1-6"))))
+ (of-ordinary-time-32-saturday-i
+ (((part First) (reference "Wisdom 18:14-16;19:6-9"))
+ ((part Gospel) (reference "Luke 18:1-8"))))
+ (of-ordinary-time-32-saturday-ii
+ (((part First) (reference "3 John 5-8"))
+ ((part Gospel) (reference "Luke 18:1-8"))))
+ (of-ordinary-time-32-thursday-i
+ (((part First) (reference "Wisdom 7:22b-8:1"))
+ ((part Gospel) (reference "Luke 17:20-25"))))
+ (of-ordinary-time-32-thursday-ii
+ (((part First) (reference "Philemon 7-22"))
+ ((part Gospel) (reference "Luke 17:20-25"))))
+ (of-ordinary-time-32-tuesday-i
+ (((part First) (reference "Wisdom 2:23-3:9"))
+ ((part Gospel) (reference "Luke 17:7-10"))))
+ (of-ordinary-time-32-tuesday-ii
+ (((part First) (reference "Titus 2:1-8,11-14"))
+ ((part Gospel) (reference "Luke 17:7-10"))))
+ (of-ordinary-time-32-wednesday-i
+ (((part First) (reference "Wisdom 6:1-11"))
+ ((part Gospel) (reference "Luke 17:11-19"))))
+ (of-ordinary-time-32-wednesday-ii
+ (((part First) (reference "Titus 3:1-7"))
+ ((part Gospel) (reference "Luke 17:11-19"))))
+ (of-ordinary-time-33-friday-i
+ (((part First) (reference "1 Maccabees 4:36-37,52-59"))
+ ((part Gospel) (reference "Luke 19:45-48"))))
+ (of-ordinary-time-33-friday-ii
+ (((part First) (reference "Revelation 10:8-11"))
+ ((part Gospel) (reference "Luke 19:45-48"))))
+ (of-ordinary-time-33-monday-i
+ (((part First) (reference "1 Maccabees 1:10-15,41-43,54-57,62-63"))
+ ((part Gospel) (reference "Luke 18:35-43"))))
+ (of-ordinary-time-33-monday-ii
+ (((part First) (reference "Revelation 1:1-4;2:1-5"))
+ ((part Gospel) (reference "Luke 18:35-43"))))
+ (of-ordinary-time-33-saturday-i
+ (((part First) (reference "1 Maccabees 6:1-13"))
+ ((part Gospel) (reference "Luke 20:27-40"))))
+ (of-ordinary-time-33-saturday-ii
+ (((part First) (reference "Revelation 11:4-12"))
+ ((part Gospel) (reference "Luke 20:27-40"))))
+ (of-ordinary-time-33-thursday-i
+ (((part First) (reference "1 Maccabees 2:15-29"))
+ ((part Gospel) (reference "Luke 19:41-44"))))
+ (of-ordinary-time-33-thursday-ii
+ (((part First) (reference "Revelation 5:1-10"))
+ ((part Gospel) (reference "Luke 19:41-44"))))
+ (of-ordinary-time-33-tuesday-i
+ (((part First) (reference "2 Maccabees 6:18-31"))
+ ((part Gospel) (reference "Luke 19:1-10"))))
+ (of-ordinary-time-33-tuesday-ii
+ (((part First) (reference "Revelation 3:1-6,14-22"))
+ ((part Gospel) (reference "Luke 19:1-10"))))
+ (of-ordinary-time-33-wednesday-i
+ (((part First) (reference "2 Maccabees 7:1,20-31"))
+ ((part Gospel) (reference "Luke 19:11-28"))))
+ (of-ordinary-time-33-wednesday-ii
+ (((part First) (reference "Revelation 4:1-11"))
+ ((part Gospel) (reference "Luke 19:11-28"))))
+ (of-ordinary-time-34-friday-i
+ (((part First) (reference "Daniel 7:2-14"))
+ ((part Gospel) (reference "Luke 21:29-33"))))
+ (of-ordinary-time-34-friday-ii
+ (((part First) (reference "Revelation 20:1-4,11-21:2"))
+ ((part Gospel) (reference "Luke 21:29-33"))))
+ (of-ordinary-time-34-monday-i
+ (((part First) (reference "Daniel 1:1-6,8-20"))
+ ((part Gospel) (reference "Luke 21:1-4"))))
+ (of-ordinary-time-34-monday-ii
+ (((part First) (reference "Revelation 14:1-3,4b-5"))
+ ((part Gospel) (reference "Luke 21:1-4"))))
+ (of-ordinary-time-34-saturday-i
+ (((part First) (reference "Daniel 7:15-27"))
+ ((part Gospel) (reference "Luke 21:34-36"))))
+ (of-ordinary-time-34-saturday-ii
+ (((part First) (reference "Revelation 22:1-7"))
+ ((part Gospel) (reference "Luke 21:34-36"))))
+ (of-ordinary-time-34-thursday-i
+ (((part First) (reference "Daniel 6:12-28"))
+ ((part Gospel) (reference "Luke 21:20-28"))))
+ (of-ordinary-time-34-thursday-ii
+ (((part First) (reference "Revelation 18:1-2,21-23;19:1-3,9a"))
+ ((part Gospel) (reference "Luke 21:20-28"))))
+ (of-ordinary-time-34-tuesday-i
+ (((part First) (reference "Daniel 2:31-45"))
+ ((part Gospel) (reference "Luke 21:5-11"))))
+ (of-ordinary-time-34-tuesday-ii
+ (((part First) (reference "Revelation 14:14-19"))
+ ((part Gospel) (reference "Luke 21:5-11"))))
+ (of-ordinary-time-34-wednesday-i
+ (((part First) (reference "Daniel 5:1-6,13-14,16-17,23-28"))
+ ((part Gospel) (reference "Luke 21:12-19"))))
+ (of-ordinary-time-34-wednesday-ii
+ (((part First) (reference "Revelation 15:1-4"))
+ ((part Gospel) (reference "Luke 21:12-19"))))
+ (of-ordinary-time-4-friday-i
+ (((part First) (reference "Hebrews 13:1-8"))
+ ((part Gospel) (reference "Mark 6:14-29"))))
+ (of-ordinary-time-4-friday-ii
+ (((part First) (reference "Sirach 47:2-11"))
+ ((part Gospel) (reference "Mark 6:14-29"))))
+ (of-ordinary-time-4-monday-i
+ (((part First) (reference "Hebrews 11:32-40"))
+ ((part Gospel) (reference "Mark 5:1-20"))))
+ (of-ordinary-time-4-monday-ii
+ (((part First) (reference "2 Samuel 15:13-14,30;16:5-13"))
+ ((part Gospel) (reference "Mark 5:1-22"))))
+ (of-ordinary-time-4-saturday-i
+ (((part First) (reference "Hebrews 13:15-17,20-21"))
+ ((part Gospel) (reference "Mark 6:30-34"))))
+ (of-ordinary-time-4-saturday-ii
+ (((part First) (reference "1 Kings 3:4-13"))
+ ((part Gospel) (reference "Mark 6:30-34"))))
+ (of-ordinary-time-4-thursday-i
+ (((part First) (reference "Hebrews 12:18-19,21-24"))
+ ((part Gospel) (reference "Mark 6:7-13"))))
+ (of-ordinary-time-4-thursday-ii
+ (((part First) (reference "1 Kings 2:1-4,10-12"))
+ ((part Gospel) (reference "Mark 6:7-13"))))
+ (of-ordinary-time-4-tuesday-i
+ (((part First) (reference "Hebrews 12:1-4"))
+ ((part Gospel) (reference "Mark 5:21-43"))))
+ (of-ordinary-time-4-tuesday-ii
+ (((part First) (reference "2 Samuel 18:9-10,14b,24-25a,30-19:3"))
+ ((part Gospel) (reference "Mark 5:21-43"))))
+ (of-ordinary-time-4-wednesday-i
+ (((part First) (reference "Hebrews 12:4-7,11-15"))
+ ((part Gospel) (reference "Mark 6:1-6"))))
+ (of-ordinary-time-4-wednesday-ii
+ (((part First) (reference "2 Samuel 24:2,9-17"))
+ ((part Gospel) (reference "Mark 6:1-6"))))
+ (of-ordinary-time-5-friday-i
+ (((part First) (reference "Genesis 3:1-8"))
+ ((part Gospel) (reference "Mark 7:31-37"))))
+ (of-ordinary-time-5-friday-ii
+ (((part First) (reference "1 Kings 11:29-32;12:19"))
+ ((part Gospel) (reference "Mark 7:31-37"))))
+ (of-ordinary-time-5-monday-i
+ (((part First) (reference "Genesis 1:1-19"))
+ ((part Gospel) (reference "Mark 6:53-56"))))
+ (of-ordinary-time-5-monday-ii
+ (((part First) (reference "1 Kings 8:1-7,9-13"))
+ ((part Gospel) (reference "Mark 6:53-56"))))
+ (of-ordinary-time-5-saturday-i
+ (((part First) (reference "Genesis 3:9-24"))
+ ((part Gospel) (reference "Mark 8:1-10"))))
+ (of-ordinary-time-5-saturday-ii
+ (((part First) (reference "1 Kings 12:26-32;13:33-34"))
+ ((part Gospel) (reference "Mark 8:1-10"))))
+ (of-ordinary-time-5-thursday-i
+ (((part First) (reference "Genesis 2:18-25"))
+ ((part Gospel) (reference "Mark 7:24-30"))))
+ (of-ordinary-time-5-thursday-ii
+ (((part First) (reference "1 Kings 11:4-13"))
+ ((part Gospel) (reference "Mark 7:24-30"))))
+ (of-ordinary-time-5-tuesday-i
+ (((part First) (reference "Genesis 1:20-2:4a"))
+ ((part Gospel) (reference "Mark 7:1-13"))))
+ (of-ordinary-time-5-tuesday-ii
+ (((part First) (reference "1 Kings 8:22-23,27-30"))
+ ((part Gospel) (reference "Mark 7:1-13"))))
+ (of-ordinary-time-5-wednesday-i
+ (((part First) (reference "Genesis 2:4b-9,15-17"))
+ ((part Gospel) (reference "Mark 7:14-23"))))
+ (of-ordinary-time-5-wednesday-ii
+ (((part First) (reference "1 Kings 10:1-10"))
+ ((part Gospel) (reference "Mark 7:14-23"))))
+ (of-ordinary-time-6-friday-i
+ (((part First) (reference "Genesis 11:1-9"))
+ ((part Gospel) (reference "Mark 8:34-9:1"))))
+ (of-ordinary-time-6-friday-ii
+ (((part First) (reference "James 2:14-24,26"))
+ ((part Gospel) (reference "Mark 8:34-9:1"))))
+ (of-ordinary-time-6-monday-i
+ (((part First) (reference "Genesis 4:1-15,25"))
+ ((part Gospel) (reference "Mark 8:11-13"))))
+ (of-ordinary-time-6-monday-ii
+ (((part First) (reference "James 1:1-11"))
+ ((part Gospel) (reference "Mark 8:11-13"))))
+ (of-ordinary-time-6-saturday-i
+ (((part First) (reference "Hebrews 11:1-7"))
+ ((part Gospel) (reference "Mark 9:2-13"))))
+ (of-ordinary-time-6-saturday-ii
+ (((part First) (reference "James 3:1-10"))
+ ((part Gospel) (reference "Mark 9:2-13"))))
+ (of-ordinary-time-6-thursday-i
+ (((part First) (reference "Genesis 9:1-13"))
+ ((part Gospel) (reference "Mark 8:27-33"))))
+ (of-ordinary-time-6-thursday-ii
+ (((part First) (reference "James 2:1-9"))
+ ((part Gospel) (reference "Mark 8:27-33"))))
+ (of-ordinary-time-6-tuesday-i
+ (((part First) (reference "Genesis 6:5-8;7:1-5,10"))
+ ((part Gospel) (reference "Mark 8:14-21"))))
+ (of-ordinary-time-6-tuesday-ii
+ (((part First) (reference "James 1:12-18"))
+ ((part Gospel) (reference "Mark 8:14-21"))))
+ (of-ordinary-time-6-wednesday-i
+ (((part First) (reference "Genesis 8:6-13,20-22"))
+ ((part Gospel) (reference "Mark 8:22-26"))))
+ (of-ordinary-time-6-wednesday-ii
+ (((part First) (reference "James 1:19-27"))
+ ((part Gospel) (reference "Mark 8:22-26"))))
+ (of-ordinary-time-7-friday-i
+ (((part First) (reference "Sirach 6:5-17"))
+ ((part Gospel) (reference "Mark 10:1-12"))))
+ (of-ordinary-time-7-friday-ii
+ (((part First) (reference "James 5:9-12"))
+ ((part Gospel) (reference "Mark 10:1-12"))))
+ (of-ordinary-time-7-monday-i
+ (((part First) (reference "Sirach 1:1-10"))
+ ((part Gospel) (reference "Mark 9:14-29"))))
+ (of-ordinary-time-7-monday-ii
+ (((part First) (reference "James 3:13-18"))
+ ((part Gospel) (reference "Mark 9:14-29"))))
+ (of-ordinary-time-7-saturday-i
+ (((part First) (reference "Sirach 17:1-15"))
+ ((part Gospel) (reference "Mark 10:13-16"))))
+ (of-ordinary-time-7-saturday-ii
+ (((part First) (reference "James 5:13-22"))
+ ((part Gospel) (reference "Mark 10:13-16"))))
+ (of-ordinary-time-7-thursday-i
+ (((part First) (reference "Sirach 5:1-8"))
+ ((part Gospel) (reference "Mark 9:41-50"))))
+ (of-ordinary-time-7-thursday-ii
+ (((part First) (reference "James 5:1-6"))
+ ((part Gospel) (reference "Mark 9:41-50"))))
+ (of-ordinary-time-7-tuesday-i
+ (((part First) (reference "Sirach 2:1-11"))
+ ((part Gospel) (reference "Mark 9:30-37"))))
+ (of-ordinary-time-7-tuesday-ii
+ (((part First) (reference "James 4:1-10"))
+ ((part Gospel) (reference "Mark 9:30-37"))))
+ (of-ordinary-time-7-wednesday-i
+ (((part First) (reference "Sirach 4:11-19"))
+ ((part Gospel) (reference "Mark 9:38-40"))))
+ (of-ordinary-time-7-wednesday-ii
+ (((part First) (reference "James 4:13-17"))
+ ((part Gospel) (reference "Mark 9:38-40"))))
+ (of-ordinary-time-8-friday-i
+ (((part First) (reference "Sirach 44:1,9-13"))
+ ((part Gospel) (reference "Mark 11:11-26"))))
+ (of-ordinary-time-8-friday-ii
+ (((part First) (reference "1 Peter 4:7-13"))
+ ((part Gospel) (reference "Mark 11:11-26"))))
+ (of-ordinary-time-8-monday-i
+ (((part First) (reference "Sirach 17:20-24"))
+ ((part Gospel) (reference "Mark 10:17-27"))))
+ (of-ordinary-time-8-monday-ii
+ (((part First) (reference "1 Peter 1:3-9"))
+ ((part Gospel) (reference "Mark 10:17-27"))))
+ (of-ordinary-time-8-saturday-i
+ (((part First) (reference "Sirach 51:12cd-20"))
+ ((part Gospel) (reference "Mark 11:27-33"))))
+ (of-ordinary-time-8-saturday-ii
+ (((part First) (reference "Jude 17,20b-25"))
+ ((part Gospel) (reference "Mark 11:27-33"))))
+ (of-ordinary-time-8-thursday-i
+ (((part First) (reference "Sirach 42:15-25"))
+ ((part Gospel) (reference "Mark 10:46-52"))))
+ (of-ordinary-time-8-thursday-ii
+ (((part First) (reference "1 Peter 2:2-5,9-12"))
+ ((part Gospel) (reference "Mark 10:46-52"))))
+ (of-ordinary-time-8-tuesday-i
+ (((part First) (reference "Sirach 35:1-12"))
+ ((part Gospel) (reference "Mark 10:28-31"))))
+ (of-ordinary-time-8-tuesday-ii
+ (((part First) (reference "1 Peter 1:10-16"))
+ ((part Gospel) (reference "Mark 10:28-31"))))
+ (of-ordinary-time-8-wednesday-i
+ (((part First) (reference "Sirach 36:1,4-5a,10-17"))
+ ((part Gospel) (reference "Mark 10:32-45"))))
+ (of-ordinary-time-8-wednesday-ii
+ (((part First) (reference "1 Peter 1:18-25"))
+ ((part Gospel) (reference "Mark 10:32-45"))))
+ (of-ordinary-time-9-friday-i
+ (((part First) (reference "Tobit 11:5-17"))
+ ((part Gospel) (reference "Mark 12:35-37"))))
+ (of-ordinary-time-9-friday-ii
+ (((part First) (reference "2 Timothy 3:10-17"))
+ ((part Gospel) (reference "Mark 12:35-37"))))
+ (of-ordinary-time-9-monday-i
+ (((part First) (reference "Tobit 1:3;2:1a-8"))
+ ((part Gospel) (reference "Mark 12:1-12"))))
+ (of-ordinary-time-9-monday-ii
+ (((part First) (reference "2 Peter 1:2-7"))
+ ((part Gospel) (reference "Mark 12:1-12"))))
+ (of-ordinary-time-9-saturday-i
+ (((part First) (reference "Tobit 12:1,5-15,20"))
+ ((part Gospel) (reference "Mark 12:38-44"))))
+ (of-ordinary-time-9-saturday-ii
+ (((part First) (reference "2 Timothy 4:1-8"))
+ ((part Gospel) (reference "Mark 12:38-44"))))
+ (of-ordinary-time-9-thursday-i
+ (((part First) (reference "Tobit 6:10-11;7:1bcde,9-17;8:4-9a"))
+ ((part Gospel) (reference "Mark 12:28b-34"))))
+ (of-ordinary-time-9-thursday-ii
+ (((part First) (reference "2 Timothy 2:8-15"))
+ ((part Gospel) (reference "Mark 12:28b-34"))))
+ (of-ordinary-time-9-tuesday-i
+ (((part First) (reference "Tobit 2:9-14"))
+ ((part Gospel) (reference "Mark 12:13-17"))))
+ (of-ordinary-time-9-tuesday-ii
+ (((part First) (reference "2 Peter 3:12-15a,17-18"))
+ ((part Gospel) (reference "Mark 12:13-17"))))
+ (of-ordinary-time-9-wednesday-i
+ (((part First) (reference "Tobit 3:1-11a,16-17a"))
+ ((part Gospel) (reference "Mark 12:18-27"))))
+ (of-ordinary-time-9-wednesday-ii
+ (((part First) (reference "2 Timothy 1:1-3,6-12"))
+ ((part Gospel) (reference "Mark 12:18-27"))))
+ (of-ordinary-time-sunday-10-a
+ (((part First) (reference "Hosea 6:3-6"))
+ ((part Gospel) (reference "Matthew 9:9-13"))))
+ (of-ordinary-time-sunday-10-b
+ (((part First) (reference "Genesis 3:9-15"))
+ ((part Gospel) (reference "Mark 3:20-35"))))
+ (of-ordinary-time-sunday-10-c
+ (((part First) (reference "1 Kings 17:17-24"))
+ ((part Gospel) (reference "Luke 7:11-17"))))
+ (of-ordinary-time-sunday-11-a
+ (((part First) (reference "Exodus 19:2-6a"))
+ ((part Gospel) (reference "Matthew 9:36-10:8"))))
+ (of-ordinary-time-sunday-11-b
+ (((part First) (reference "Ezekiel 17:22-24"))
+ ((part Gospel) (reference "Mark 4:26-34"))))
+ (of-ordinary-time-sunday-11-c
+ (((part First) (reference "2 Samuel 12:7-10,13"))
+ ((part Gospel) (reference "Luke 7:36-8:3"))))
+ (of-ordinary-time-sunday-12-a
+ (((part First) (reference "Jeremiah 20:10-13"))
+ ((part Gospel) (reference "Matthew 10:26-33"))))
+ (of-ordinary-time-sunday-12-b
+ (((part First) (reference "Job 38:1,8-11"))
+ ((part Gospel) (reference "Mark 4:35-41"))))
+ (of-ordinary-time-sunday-12-c
+ (((part First) (reference "Zechariah 12:10-11;13:1"))
+ ((part Gospel) (reference "Luke 9:18-24"))))
+ (of-ordinary-time-sunday-13-a
+ (((part First) (reference "2 Kings 4:8-11,14-16a"))
+ ((part Gospel) (reference "Matthew 10:37-42"))))
+ (of-ordinary-time-sunday-13-b
+ (((part First) (reference "Wisdom 1:13-15;2:23-24"))
+ ((part Gospel) (reference "Mark 5:21-43"))))
+ (of-ordinary-time-sunday-13-c
+ (((part First) (reference "1 Kings 19:16b,19-21"))
+ ((part Gospel) (reference "Luke 9:51-62"))))
+ (of-ordinary-time-sunday-14-a
+ (((part First) (reference "Zechariah 9:9-10"))
+ ((part Gospel) (reference "Matthew 11:25-30"))))
+ (of-ordinary-time-sunday-14-b
+ (((part First) (reference "Ezekiel 2:2-5"))
+ ((part Gospel) (reference "Mark 6:1-6"))))
+ (of-ordinary-time-sunday-14-c
+ (((part First) (reference "Isaiah 66:10-14c"))
+ ((part Gospel) (reference "Luke 10:1-12,17-20"))))
+ (of-ordinary-time-sunday-15-a
+ (((part First) (reference "Isaiah 55:10-11"))
+ ((part Gospel) (reference "Matthew 13:1-23"))))
+ (of-ordinary-time-sunday-15-b
+ (((part First) (reference "Amos 7:12-15"))
+ ((part Gospel) (reference "Mark 6:7-13"))))
+ (of-ordinary-time-sunday-15-c
+ (((part First) (reference "Deuteronomy 30:10-14"))
+ ((part Gospel) (reference "Luke 10:25-37"))))
+ (of-ordinary-time-sunday-16-a
+ (((part First) (reference "Wisdom 12:13,16-19"))
+ ((part Gospel) (reference "Matthew 13:24-43"))))
+ (of-ordinary-time-sunday-16-b
+ (((part First) (reference "Jeremiah 23:1-6"))
+ ((part Gospel) (reference "Mark 6:30-34"))))
+ (of-ordinary-time-sunday-16-c
+ (((part First) (reference "Genesis 18:1-10a"))
+ ((part Gospel) (reference "Luke 10:38-42"))))
+ (of-ordinary-time-sunday-17-a
+ (((part First) (reference "1 Kings 3:5,7-12"))
+ ((part Gospel) (reference "Matthew 13:44-52"))))
+ (of-ordinary-time-sunday-17-b
+ (((part First) (reference "2 Kings 4:42-44"))
+ ((part Gospel) (reference "John 6:1-15"))))
+ (of-ordinary-time-sunday-17-c
+ (((part First) (reference "Genesis 18:20-32"))
+ ((part Gospel) (reference "Luke 11:1-13"))))
+ (of-ordinary-time-sunday-18-a
+ (((part First) (reference "Isaiah 55:1-3"))
+ ((part Gospel) (reference "Matthew 14:13-21"))))
+ (of-ordinary-time-sunday-18-b
+ (((part First) (reference "Exodus 16:2-4,12-15"))
+ ((part Gospel) (reference "John 6:24-35"))))
+ (of-ordinary-time-sunday-18-c
+ (((part First) (reference "Ecclesiastes 1:2;2:21-23"))
+ ((part Gospel) (reference "Luke 12:13-21"))))
+ (of-ordinary-time-sunday-19-a
+ (((part First) (reference "1 Kings 19:9a,11-13a"))
+ ((part Gospel) (reference "Matthew 14:22-33"))))
+ (of-ordinary-time-sunday-19-b
+ (((part First) (reference "1 Kings 19:4-8"))
+ ((part Gospel) (reference "John 6:41-51"))))
+ (of-ordinary-time-sunday-19-c
+ (((part First) (reference "Wisdom 18:6-9"))
+ ((part Gospel) (reference "Luke 12:32-48"))))
+ (of-ordinary-time-sunday-2-a
+ (((part First) (reference "Isaiah 49:3,5-6"))
+ ((part Gospel) (reference "John 1:29-34"))))
+ (of-ordinary-time-sunday-2-b
+ (((part First) (reference "1 Samuel 3:3b-10,19"))
+ ((part Gospel) (reference "John 1:35-42"))))
+ (of-ordinary-time-sunday-2-c
+ (((part First) (reference "Isaiah 62:1-5"))
+ ((part Gospel) (reference "John 2:1-11"))))
+ (of-ordinary-time-sunday-20-a
+ (((part First) (reference "Isaiah 56:1,6-7"))
+ ((part Gospel) (reference "Matthew 15:21-28"))))
+ (of-ordinary-time-sunday-20-b
+ (((part First) (reference "Proverbs 9:1-6"))
+ ((part Gospel) (reference "John 6:51-58"))))
+ (of-ordinary-time-sunday-20-c
+ (((part First) (reference "Jeremiah 38:4-6,8-10"))
+ ((part Gospel) (reference "Luke 12:49-53"))))
+ (of-ordinary-time-sunday-21-a
+ (((part First) (reference "Isaiah 22:19-23"))
+ ((part Gospel) (reference "Matthew 16:13-20"))))
+ (of-ordinary-time-sunday-21-b
+ (((part First) (reference "Joshua 24:1-2a,15-17,18b"))
+ ((part Gospel) (reference "John 6:60-69"))))
+ (of-ordinary-time-sunday-21-c
+ (((part First) (reference "Isaiah 66:18-21"))
+ ((part Gospel) (reference "Luke 13:22-30"))))
+ (of-ordinary-time-sunday-22-a
+ (((part First) (reference "Jeremiah 20:7-9"))
+ ((part Gospel) (reference "Matthew 16:21-27"))))
+ (of-ordinary-time-sunday-22-b
+ (((part First) (reference "Deuteronomy 4:1-2,6-8"))
+ ((part Gospel) (reference "Mark 7:1-8,14-15,21-23"))))
+ (of-ordinary-time-sunday-22-c
+ (((part First) (reference "Sirach 3:17-18,20,28-29"))
+ ((part Gospel) (reference "Luke 14:1,7-14"))))
+ (of-ordinary-time-sunday-23-a
+ (((part First) (reference "Ezekiel 33:7-9"))
+ ((part Gospel) (reference "Matthew 18:15-20"))))
+ (of-ordinary-time-sunday-23-b
+ (((part First) (reference "Isaiah 35:4-7a"))
+ ((part Gospel) (reference "Mark 7:31-37"))))
+ (of-ordinary-time-sunday-23-c
+ (((part First) (reference "Wisdom 9:13-18b"))
+ ((part Gospel) (reference "Luke 14:25-33"))))
+ (of-ordinary-time-sunday-24-a
+ (((part First) (reference "Sirach 27:30-28:7"))
+ ((part Gospel) (reference "Matthew 18:21-35"))))
+ (of-ordinary-time-sunday-24-b
+ (((part First) (reference "Isaiah 50:4-9a"))
+ ((part Gospel) (reference "Mark 8:27-35"))))
+ (of-ordinary-time-sunday-24-c
+ (((part First) (reference "Exodus 32:7-11,13-14"))
+ ((part Gospel) (reference "Luke 15:1-32"))))
+ (of-ordinary-time-sunday-25-a
+ (((part First) (reference "Isaiah 55:6-9"))
+ ((part Gospel) (reference "Matthew 20:1-16a"))))
+ (of-ordinary-time-sunday-25-b
+ (((part First) (reference "Wisdom 2:12,17-20"))
+ ((part Gospel) (reference "Mark 9:30-37"))))
+ (of-ordinary-time-sunday-25-c
+ (((part First) (reference "Amos 8:4-7"))
+ ((part Gospel) (reference "Luke 16:1-13"))))
+ (of-ordinary-time-sunday-26-a
+ (((part First) (reference "Ezekiel 18:25-28"))
+ ((part Gospel) (reference "Matthew 21:28-32"))))
+ (of-ordinary-time-sunday-26-b
+ (((part First) (reference "Numbers 11:25-29"))
+ ((part Gospel) (reference "Mark 9:38-43,45,47-48"))))
+ (of-ordinary-time-sunday-26-c
+ (((part First) (reference "Amos 6:1a,4-7"))
+ ((part Gospel) (reference "Luke 16:19-31"))))
+ (of-ordinary-time-sunday-27-a
+ (((part First) (reference "Isaiah 5:1-7"))
+ ((part Gospel) (reference "Matthew 21:33-43"))))
+ (of-ordinary-time-sunday-27-b
+ (((part First) (reference "Genesis 2:18-24"))
+ ((part Gospel) (reference "Mark 10:2-16"))))
+ (of-ordinary-time-sunday-27-c
+ (((part First) (reference "Habakkuk 1:2-3;2:2-4"))
+ ((part Gospel) (reference "Luke 17:5-10"))))
+ (of-ordinary-time-sunday-28-a
+ (((part First) (reference "Isaiah 25:6-10a"))
+ ((part Gospel) (reference "Matthew 22:1-14"))))
+ (of-ordinary-time-sunday-28-b
+ (((part First) (reference "Wisdom 7:7-11"))
+ ((part Gospel) (reference "Mark 10:17-30"))))
+ (of-ordinary-time-sunday-28-c
+ (((part First) (reference "2 Kings 5:14-17"))
+ ((part Gospel) (reference "Luke 17:11-19"))))
+ (of-ordinary-time-sunday-29-a
+ (((part First) (reference "Isaiah 45:1,4-6"))
+ ((part Gospel) (reference "Matthew 22:15-21"))))
+ (of-ordinary-time-sunday-29-b
+ (((part First) (reference "Isaiah 53:10-11"))
+ ((part Gospel) (reference "Mark 10:35-45"))))
+ (of-ordinary-time-sunday-29-c
+ (((part First) (reference "Exodus 17:8-13"))
+ ((part Gospel) (reference "Luke 18:1-8"))))
+ (of-ordinary-time-sunday-3-a
+ (((part First) (reference "Isaiah 8:23b-9:3"))
+ ((part Gospel) (reference "Matthew 4:12-23"))))
+ (of-ordinary-time-sunday-3-b
+ (((part First) (reference "Jonah 3:1-5,10"))
+ ((part Gospel) (reference "Mark 1:14-20"))))
+ (of-ordinary-time-sunday-3-c
+ (((part First) (reference "Nehemiah 8:2-4a,5-6,8-10"))
+ ((part Gospel) (reference "Luke 1:1-4;4:14-21"))))
+ (of-ordinary-time-sunday-30-a
+ (((part First) (reference "Exodus 22:20-26"))
+ ((part Gospel) (reference "Matthew 22:34-40"))))
+ (of-ordinary-time-sunday-30-b
+ (((part First) (reference "Jeremiah 31:7-9"))
+ ((part Gospel) (reference "Mark 10:46-52"))))
+ (of-ordinary-time-sunday-30-c
+ (((part First) (reference "Sirach 35:12-14,16-18"))
+ ((part Gospel) (reference "Luke 18:9-14"))))
+ (of-ordinary-time-sunday-31-a
+ (((part First) (reference "Malachi 1:14b-2:2b,8-10"))
+ ((part Gospel) (reference "Matthew 23:1-12"))))
+ (of-ordinary-time-sunday-31-b
+ (((part First) (reference "Deuteronomy 6:2-6"))
+ ((part Gospel) (reference "Mark 12:28b-34"))))
+ (of-ordinary-time-sunday-31-c
+ (((part First) (reference "Wisdom 11:22-12:2"))
+ ((part Gospel) (reference "Luke 19:1-10"))))
+ (of-ordinary-time-sunday-32-a
+ (((part First) (reference "Wisdom 6:12-16"))
+ ((part Gospel) (reference "Matthew 25:1-13"))))
+ (of-ordinary-time-sunday-32-b
+ (((part First) (reference "1 Kings 17:10-16"))
+ ((part Gospel) (reference "Mark 12:38-44"))))
+ (of-ordinary-time-sunday-32-c
+ (((part First) (reference "2 Maccabees 7:1-2,9-14"))
+ ((part Gospel) (reference "Luke 20:27-38"))))
+ (of-ordinary-time-sunday-33-a
+ (((part First) (reference "Proverbs 31:10-13,19-20,30-31"))
+ ((part Gospel) (reference "Matthew 25:14-30"))))
+ (of-ordinary-time-sunday-33-b
+ (((part First) (reference "Daniel 12:1-3"))
+ ((part Gospel) (reference "Mark 13:24-32"))))
+ (of-ordinary-time-sunday-33-c
+ (((part First) (reference "Malachi 4:1-2"))
+ ((part Gospel) (reference "Luke 21:5-19"))))
+ (of-ordinary-time-sunday-4-a
+ (((part First) (reference "Zephaniah 2:3;3:12-13"))
+ ((part Gospel) (reference "Matthew 5:1-12a"))))
+ (of-ordinary-time-sunday-4-b
+ (((part First) (reference "Deuteronomy 18:15-20"))
+ ((part Gospel) (reference "Mark 1:21-28"))))
+ (of-ordinary-time-sunday-4-c
+ (((part First) (reference "Jeremiah 1:4-5,17-19"))
+ ((part Gospel) (reference "Luke 4:21-30"))))
+ (of-ordinary-time-sunday-5-a
+ (((part First) (reference "Isaiah 58:7-10"))
+ ((part Gospel) (reference "Matthew 5:13-16"))))
+ (of-ordinary-time-sunday-5-b
+ (((part First) (reference "Job 7:1-4,6-7"))
+ ((part Gospel) (reference "Mark 1:29-39"))))
+ (of-ordinary-time-sunday-5-c
+ (((part First) (reference "Isaiah 6:1-2a,3-8"))
+ ((part Gospel) (reference "Luke 5:1-11"))))
+ (of-ordinary-time-sunday-6-a
+ (((part First) (reference "Sirach 15:16-21"))
+ ((part Gospel) (reference "Matthew 5:17-37"))))
+ (of-ordinary-time-sunday-6-b
+ (((part First) (reference "Leviticus 13:1-2,44-46"))
+ ((part Gospel) (reference "Mark 1:40-45"))))
+ (of-ordinary-time-sunday-6-c
+ (((part First) (reference "Jeremiah 17:5-8"))
+ ((part Gospel) (reference "Luke 6:17,20-26"))))
+ (of-ordinary-time-sunday-7-a
+ (((part First) (reference "Leviticus 19:1-2,17-18"))
+ ((part Gospel) (reference "Matthew 5:38-48"))))
+ (of-ordinary-time-sunday-7-b
+ (((part First) (reference "Isaiah 43:18-19,21-22,24b-25"))
+ ((part Gospel) (reference "Mark 2:1-12"))))
+ (of-ordinary-time-sunday-7-c
+ (((part First) (reference "1 Samuel 26:2,7-9,12-13,22-23"))
+ ((part Gospel) (reference "Luke 6:27-38"))))
+ (of-ordinary-time-sunday-8-a
+ (((part First) (reference "Isaiah 49:14-15"))
+ ((part Gospel) (reference "Matthew 6:24-34"))))
+ (of-ordinary-time-sunday-8-b
+ (((part First) (reference "Hosea 2:16b,17b,21-22"))
+ ((part Gospel) (reference "Mark 2:18-22"))))
+ (of-ordinary-time-sunday-8-c
+ (((part First) (reference "Sirach 27:5-8"))
+ ((part Gospel) (reference "Luke 6:39-45"))))
+ (of-ordinary-time-sunday-9-a
+ (((part First) (reference "Deuteronomy 11:18,26-28,32"))
+ ((part Gospel) (reference "Matthew 7:21-27"))))
+ (of-ordinary-time-sunday-9-b
+ (((part First) (reference "Deuteronomy 5:12-15"))
+ ((part Gospel) (reference "Mark 2:23-3:6"))))
+ (of-ordinary-time-sunday-9-c
+ (((part First) (reference "1 Kings 8:41-43"))
+ ((part Gospel) (reference "Luke 7:1-10"))))
+ (of-palm-sunday-a
+ (((part First) (reference "Isaiah 50:4-7"))
+ ((part Gospel) (reference "Mat 27:11-54"))))
+ (of-palm-sunday-b
+ (((part First) (reference "Isaiah 50:4-7"))
+ ((part Gospel) (reference "Mark 15:1-39"))))
+ (of-palm-sunday-c
+ (((part First) (reference "Isaiah 50:4-7"))
+ ((part Gospel) (reference "Luke 23:1-49"))))
+ (of-pentecost-a
+ (((part First) (reference "The Acts 2:1-11"))
+ ((part Gospel) (reference "John 20:19-23"))))
+ (of-pentecost-b
+ (((part First) (reference "The Acts 2:1-11"))
+ ((part Gospel) (reference "John 15:26-27;16:12-15"))))
+ (of-pentecost-c
+ (((part First) (reference "The Acts 2:1-11"))
+ ((part Gospel) (reference "John 14:15-16,23b-26"))))
+ (of-trinity-a
+ (((part First) (reference "Exodus 34:4b-6,8-9"))
+ ((part Gospel) (reference "John 3:16-18"))))
+ (of-trinity-b
+ (((part First) (reference "Deuteronomy 4:32-34,39-40"))
+ ((part Gospel) (reference "Matthew 28:16-20"))))
+ (of-trinity-c
+ (((part First) (reference "Proverbs 8:22-31"))
+ ((part Gospel) (reference "John 16:12-15"))))
+ (presentation-of-the-lord
+ (((part First) (reference "Malachi 3:1-4"))
+ ((part Gospel) (reference "Luke 2:22-32"))))
+ (sacred-heart-of-jesus-a
+ (((part First) (reference "Deuteronomy 7:6-11"))
+ ((part Gospel) (reference "Matthew 11:25-30"))))
+ (sacred-heart-of-jesus-b
+ (((part First) (reference "Hosea 11:1,3-4,8c-9"))
+ ((part Gospel) (reference "John 19:31-37"))))
+ (sacred-heart-of-jesus-c
+ (((part First) (reference "Ezekiel 34:11-16"))
+ ((part Gospel) (reference "Luke 15:3-7"))))
+ (saints-michael-gabriel-and-raphael-archangels
+ (((part First) (reference "Daniel 7:9-10,13-14"))
+ ((part Gospel) (reference "John 1:47-51"))))
+ (saints-peter-and-paul-apostles
+ (((part First) (reference "Acts 3:1-10"))
+ ((part Gospel) (reference "John 21:15-19"))))
+ (saints-philip-and-james-apostles
+ (((part First) (reference "Revelation 11:19;12,1-6,10ab"))
+ ((part Gospel) (reference "John 19:25-27"))))
+ (simon-and-saint-jude-apostles
+ (((part First) (reference "Ephesians 2:19-22"))
+ ((part Gospel) (reference "Luke 6:12-19"))))
+ (stephen-the-first-martyr
+ (((part First) (reference "Acts 6:8-10;7:54-60"))
+ ((part Gospel) (reference "Mat 10:17-22"))))
+ (the-conversion-of-saint-paul-apostle
+ (((part First) (reference "Acts 22:3-16"))
+ ((part Gospel) (reference "Mark 16:15-18"))))
+ (thomas-the-apostle
+ (((part First) (reference "Ephesians 2:19-22"))
+ ((part Gospel) (reference "John 20:24-29"))))
+ (transfiguration-of-the-lord-a
+ (((part First) (reference "Daniel 7:9-10,13-14"))
+ ((part Gospel) (reference "Mat 17:1-9"))))
+ (transfiguration-of-the-lord-b
+ (((part First) (reference "Daniel 7:9-10,13-14"))
+ ((part Gospel) (reference "Mark 9:2-10"))))
+ (transfiguration-of-the-lord-c
+ (((part First) (reference "Daniel 7:9-10,13-14"))
+ ((part Gospel) (reference "Luke 9:28-36"))))
+ (triumph-of-the-holy-cross
+ (((part First) (reference "Numbers 21:4-9"))
+ ((part Gospel) (reference "John 3:13-17"))))
+ (visitation-of-the-blessed-virgin-mary
+ (((part First) (reference "Zephaniah 3:14-17"))
+ ((part Gospel) (reference "Luke 1:39-56")))))
diff --git a/lib/rites/rite_of/lectionary_of.ml b/lib/rites/rite_of/lectionary_of.ml
new file mode 100644
index 0000000..1664fad
--- /dev/null
+++ b/lib/rites/rite_of/lectionary_of.ml
@@ -0,0 +1,107 @@
+(* See lectionary_of.mli for the full citations and design argument. *)
+open Colitur_kernel
+
+type sunday_cycle = Year_a | Year_b | Year_c
+type weekday_cycle = Year_i | Year_ii
+
+let sunday_cycle_letter = function Year_a -> "a" | Year_b -> "b" | Year_c -> "c"
+let weekday_cycle_letter = function Year_i -> "i" | Year_ii -> "ii"
+
+(* The civil year in which the liturgical year CONTAINING [date] opened --
+ i.e. the year y such that [year_start y <= date < year_start (y + 1)].
+ This is the one piece of arithmetic both cycle rules share, and it is
+ exactly the "get the boundary right" the task brief names: a date in,
+ say, early December belongs to the liturgical year that opened THAT
+ same Advent only once Advent has actually started that year (compared
+ by real date, not by month) -- a month-based shortcut ("December always
+ means the new liturgical year") is wrong in the (real, if rare) case of
+ a December date still ahead of that year's own Advent I. *)
+let liturgical_year_open_year ~year_start date =
+ let y = Date.year date in
+ if Date.compare date (year_start y) >= 0 then y else y - 1
+
+(* OLM n.66 + footnote 102 (mli's own citation): the LABEL year is the one
+ most of the liturgical year falls in, i.e. one more than the year
+ Advent opened in ("a prima hebdomada Adventus, quae cadit in anno
+ civili praecedente" -- the first week of Advent falls in the PRECEDING
+ civil year relative to the label). Divisible by 3 -> C, then A, then B,
+ worked example 1980=C/1981=A/1982=B/1983=C verified against the real
+ page image. *)
+let sunday_cycle ~year_start date =
+ let label = liturgical_year_open_year ~year_start date + 1 in
+ match label mod 3 with 0 -> Year_c | 1 -> Year_a | _ -> Year_b
+
+(* OLM n.69 point 4 (mli's own citation): "Annus primus adhibetur annis
+ imparibus, annus secundus vero annis paribus" -- Year I in odd label
+ years, Year II in even. Same label-year computation as [sunday_cycle]
+ above, for the identical reason: this is a two-year cycle, not a
+ three-year one, but the label-year definition itself does not depend on
+ which modulus governs it. *)
+let weekday_cycle ~year_start date =
+ let label = liturgical_year_open_year ~year_start date + 1 in
+ if label mod 2 = 1 then Year_i else Year_ii
+
+(* Tries [base] flat, then [base]-<sunday letter>, then [base]-<weekday
+ letter>, in that order. Safe unconditionally: tools/
+ bootstrap_lectionary_of.ml emits a given base under AT MOST ONE of
+ these three forms (a flat entry when the two/three cycle years were
+ byte-identical, a cycle-lettered family otherwise -- never both), so at
+ most one of the three lookups below can ever hit, and trying the two
+ irrelevant forms for a family of the other kind or a flat family is
+ simply two wasted, harmless misses. This is what lets [readings] below
+ stay ignorant of which of the two cycle systems (or neither) a given
+ slug's own family actually uses. *)
+let lookup_any lectionary ~year_start base date =
+ match Lectionary.find lectionary base with
+ | Some cs -> Some cs
+ | None -> (
+ let with_suffix suffix = Slug.of_string_exn (Slug.to_string base ^ "-" ^ suffix) in
+ match Lectionary.find lectionary (with_suffix (sunday_cycle_letter (sunday_cycle ~year_start date))) with
+ | Some cs -> Some cs
+ | None -> Lectionary.find lectionary (with_suffix (weekday_cycle_letter (weekday_cycle ~year_start date))))
+
+let readings ~lectionary ~year_start ~(observed : Vocab_of.rank Celebration.t)
+ ~(temporal : (Vocab_of.season, Vocab_of.rank) Temporal.t) ~date ~temporal_at:_ =
+ match observed.Celebration.citations with
+ | _ :: _ as cs ->
+ (Some { Mass_formulary.said = Some observed.Celebration.slug; via = Mass_formulary.Proper }, cs)
+ | [] -> (
+ (* Step 2: a sanctoral entity actually won the day -- i.e. the
+ observed celebration is not itself the day's own temporal office.
+ Same guard shape as Rite_ef.Lectionary_ef.readings' own step 4
+ (see that module's implementation comment for the full argument
+ for why this comparison, not a [subject]/[status] test, is the
+ right one): comparing SLUGS is exact whenever the temporal and
+ sanctoral streams cannot collide, which holds here for the
+ identical reason it holds for EF -- every Temporal_of slug this
+ module ever constructs carries the "of-" prefix (temporal_of.ml's
+ own [temporal], every branch), and 0 of the 222 shipped
+ data/of/calendar-2002.sexp + amendments sanctoral slugs do. *)
+ let sanctoral_office =
+ not (Slug.equal observed.Celebration.slug temporal.Temporal.office.Celebration.slug)
+ in
+ match
+ if sanctoral_office then lookup_any lectionary ~year_start observed.Celebration.slug date else None
+ with
+ | Some cs ->
+ (* Mass_formulary.Proper, not .Common -- see lectionary_of.mli's
+ own doc comment on this branch for the full argument. In
+ short: EF's [Common] constructor names a SPECIFIC mechanism
+ (several saints sharing one formulary via an explicit
+ assignment table, data/ef/commons.sexp) that OF's own data has
+ no counterpart for -- every sanctoral slug this step resolves
+ carries its OWN dedicated lectio entry, not a shared one, so
+ relabelling it [Common] would claim a mechanism that is not
+ actually present. [Proper] is the honest fit: "the observed
+ celebration's own proper Mass", true regardless of whether the
+ citations are embedded on Celebration.t (step 1) or held
+ externally in [lectionary] (this step) -- a storage detail
+ Mass_formulary.source was never built to carry. *)
+ (Some { Mass_formulary.said = Some observed.Celebration.slug; via = Mass_formulary.Proper }, cs)
+ | None -> (
+ match lookup_any lectionary ~year_start temporal.Temporal.office.Celebration.slug date with
+ | Some cs ->
+ ( Some { Mass_formulary.said = Some temporal.Temporal.office.Celebration.slug;
+ via = Mass_formulary.Own_slug },
+ cs )
+ | None -> (None, [])))
diff --git a/lib/rites/rite_of/lectionary_of.mli b/lib/rites/rite_of/lectionary_of.mli
new file mode 100644
index 0000000..0c4d1d6
--- /dev/null
+++ b/lib/rites/rite_of/lectionary_of.mli
@@ -0,0 +1,136 @@
+(** The OF reading-cycle arithmetic and the temporal + sanctoral lectionary
+ resolution chain (Task 4, 2026-08-25-colitur-of-phases-3-5).
+
+ Two halves with a different character, per the task's own brief:
+
+ - {b The cycle rules are CODE}, computed from the civil year, cited to
+ the OLM (Ordo Lectionum Missae) 1981 Praenotanda -- see {!sunday_cycle}
+ and {!weekday_cycle} below for the citations, each verified against the
+ real page image (docs/research/of/olm-1981.pdf pp.32-33/"XXXII-XXXIII"),
+ not the unreliable OCR text layer (design spec 2026-08-24-colitur-of-
+ rite-module-design.md sec4.4's own caveat).
+ - {b The data is bootstrapped from lectio} (binding decision 3), a
+ POLISH VERNACULAR pastoral lectionary (niedziela.pl), not the Latin
+ OLM itself -- see tools/bootstrap_lectionary_of.ml's own top-of-file
+ comment and data/of/lectionary.sexp's own provenance header for the
+ full lineage statement and what it cannot show. *)
+
+open Colitur_kernel
+
+(** OLM 1981 Praenotanda n.66 (page-image verified, p.32/"XXXII"): "cyclus
+ trium annorum proponitur" -- the three-year Sunday/solemnity cycle.
+ Footnote 102, same page, gives the determining rule with a worked
+ example: "Per litteram C designatur annus cuius numerus in tres partes
+ aequales dividi potest... Sic annus 1980 est annus C, annus vero
+ sequens, scilicet annus 1981, est annus A, annus vero 1982 est annus B,
+ et annus 1983 est iterum annus C" -- the year divisible by three is
+ Year C, the next Year A, the next Year B. The SAME footnote also gives
+ the Gospel-per-year identity quoted on {!sunday_cycle}'s own doc
+ comment below (A = Matthew, B = Mark, C = Luke), and states explicitly
+ that each cycle's own "year" runs "iuxta dispositionem anni liturgici,
+ nempe a prima hebdomada Adventus, quae cadit in anno civili
+ praecedente" -- according to the liturgical year, namely from the first
+ week of Advent, WHICH FALLS IN THE PRECEDING CIVIL YEAR. This is the
+ task brief's own "the cycle turns at Advent I, not 1 January": Advent
+ 1980 (civil year 1980) already opens the 1981-labelled liturgical year
+ (Year A), even though most of civil year 1980 was still Year C. *)
+type sunday_cycle = Year_a | Year_b | Year_c
+
+(** OLM 1981 Praenotanda n.69 (page-image verified, p.33/"XXXIII"), the
+ "c) De ordinatione lectionum pro feriis" subsection's own point 4:
+ "Pro feriis vero triginta quattuor hebdomadarum <<per annum>> lectiones
+ evangelicae unico disponuntur cyclo, qui singulis annis resumitur.
+ Prior vero lectio, in duplici cyclo ordinatur, alternis annis legenda.
+ Annus primus adhibetur annis imparibus, annus secundus vero annis
+ paribus" -- for the ferias of the thirty-four weeks of Ordinary Time,
+ the GOSPEL is arranged in a single cycle repeated every year; the FIRST
+ reading alone alternates over two years. Year I is used in odd years,
+ Year II in even years. The SAME point 4, its own preceding points 2-3,
+ state the two-year alternation is confined to Ordinary Time: Lent has
+ its own single seasonal cycle (point 2) and "Pro feriis Adventus,
+ temporis Nativitatis et paschalis cyclus eodem modo annualis est:
+ lectiones ideo non mutantur" -- for the ferias of Advent, Christmastide
+ and Paschaltide the cycle is likewise annual: the readings DO NOT
+ CHANGE (point 3). {!Lectionary.t} does not need to encode that
+ distinction itself: a non-alternating family's own two cycle-letter
+ keys were collapsed to one flat entry at bootstrap time (see
+ tools/bootstrap_lectionary_of.ml's own [collapse_weekday]), so trying
+ both letters here is always safe -- the flat entry is found first
+ either way. *)
+type weekday_cycle = Year_i | Year_ii
+
+val sunday_cycle_letter : sunday_cycle -> string
+val weekday_cycle_letter : weekday_cycle -> string
+
+(** [sunday_cycle ~year_start date]: which of the three-year cycle's own
+ labelled years [date] falls in, per {!sunday_cycle}'s own citation.
+ A = Matthew, B = Mark, C = Luke -- OLM n.66's own footnote 102, same
+ passage: "primus cycli annus dicitur et est annus legendi Matthaeum,
+ ceteri vero, secundus nempe et tertius, respective annus legendi
+ Marcum et annus legendi Lucam". [year_start] is the rite's own
+ Advent-anchor function ({!Temporal_of.year_start}), supplied by the
+ caller rather than hard-coded, the same seam {!Rite_ef.Lectionary_ef
+ .readings}'s own [~lectionary]/[~commons] already use for rite data --
+ this module reads no filesystem and knows no OF-specific season
+ vocabulary of its own beyond what [year_start] and {!Colitur_kernel
+ .Temporal.t} already carry. *)
+val sunday_cycle : year_start:(int -> Date.t) -> Date.t -> sunday_cycle
+
+(** [weekday_cycle ~year_start date]: which of the two-year cycle's own
+ labelled years [date] falls in, per {!weekday_cycle}'s own citation. *)
+val weekday_cycle : year_start:(int -> Date.t) -> Date.t -> weekday_cycle
+
+(** The Mass's Epistle and Gospel citations for this day, and (when the
+ shipped data can name one) which formulary they came from -- the OF
+ counterpart of {!Rite_ef.Lectionary_ef.readings}, deliberately simpler:
+ OF has no Commons indirection table (spec's own scope for this task),
+ so the chain is three steps, not four:
+
+ - {b Step 1} -- the observed celebration's own embedded citations, if
+ any. {!Colitur_kernel.Mass_formulary.Proper}. Defensive: every
+ shipped data/of/calendar-2002.sexp entry carries [citations ()]
+ today (Task 1), so this step is currently dead on shipped data, kept
+ for the same forward-compatibility reason EF's own step 1 stays
+ first even where most callers reach it rarely.
+ - {b Step 2} -- when the observed celebration is NOT itself the day's
+ own temporal office (a real sanctoral entity won occurrence), its
+ own slug looked up directly in [lectionary] (tried flat, then both
+ cycle-letter suffixes via {!sunday_cycle}/{!weekday_cycle} -- a
+ sanctoral entry may be tagged either way in the shipped data, see
+ tools/bootstrap_lectionary_of.ml's own header, so both are tried
+ rather than assumed). Tagged {!Colitur_kernel.Mass_formulary.Proper}
+ too, not {!Colitur_kernel.Mass_formulary.Common}: OF has no shared-
+ formulary indirection the way EF's Commons do (this task's own
+ scope), so a looked-up sanctoral citation is still, substantively,
+ "the observed celebration's own proper" -- only ITS STORAGE differs
+ from step 1's (external file vs an embedded field), which
+ {!Colitur_kernel.Mass_formulary.source} was never designed to
+ distinguish (its own doc names what DECIDED the Mass, not where the
+ bytes happen to live). {!Colitur_kernel.Mass_formulary.source} is a
+ closed kernel type outside this task's own scope to extend; see
+ lectionary_of.ml's own implementation comment on this branch for the
+ full argument. [said] the observed slug.
+ - {b Step 3} -- the day's own temporal slug, same three-way lookup.
+ {!Colitur_kernel.Mass_formulary.Own_slug}, [said] that slug.
+ - A day matching neither gets [(None, [])] -- see data/of/lectionary
+ .sexp's own provenance header for exactly which days that is, both
+ directions, measured, not guessed.
+
+ NO preceding-Sunday fallback (EF's own step 3): unlike EF's RG 299,
+ the OF's own two-year FERIAL cycle assigns every Ordinary Time weekday
+ its own reading by design (OLM n.69 point 4, {!weekday_cycle}'s own
+ citation) -- there is no OF norm this task found instructing a ferial
+ with no proper of its own to repeat the preceding Sunday's Mass, so no
+ such step is built. [temporal_at] is therefore accepted, unused, to
+ satisfy {!Colitur_kernel.Rite.t}'s own [readings] field shape (the same
+ contract {!Rite_ef.Lectionary_ef.readings} satisfies) -- kept rather
+ than dropped so a future task that DOES find such a rule has the
+ callback already in place. *)
+val readings :
+ lectionary:Lectionary.t ->
+ year_start:(int -> Date.t) ->
+ observed:Vocab_of.rank Celebration.t ->
+ temporal:(Vocab_of.season, Vocab_of.rank) Temporal.t ->
+ date:Date.t ->
+ temporal_at:(Date.t -> (Vocab_of.season, Vocab_of.rank) Temporal.t) ->
+ Mass_formulary.t option * Citation.t list
diff --git a/test/dune b/test/dune
index c5bfe07..50bdee2 100644
--- a/test/dune
+++ b/test/dune
@@ -29,6 +29,8 @@
../data/of/expected-divergences-litcal.sexp
../data/ef/lectionary.sexp
../data/ef/commons.sexp
+ ../data/of/lectionary.sexp
+ ../tools/bootstrap_lectionary_of.exe
../data/ef/examples/diocesan-example.sexp
fixtures/lectio-ef-2005-2050.txt
fixtures/missalemeum-ef-2026-2027.txt
diff --git a/test/test_colitur.ml b/test/test_colitur.ml
index 3e16566..30e649e 100644
--- a/test/test_colitur.ml
+++ b/test/test_colitur.ml
@@ -27,6 +27,7 @@ let () =
Test_golden.suite;
("lectionary", Test_lectionary.suite);
("lectionary-ef", Test_lectionary_ef.suite);
+ ("lectionary-of", Test_lectionary_of.suite);
Test_escape.suite;
Test_template.suite;
Test_template.render_suite;
diff --git a/test/test_lectionary_of.ml b/test/test_lectionary_of.ml
new file mode 100644
index 0000000..6fb48a0
--- /dev/null
+++ b/test/test_lectionary_of.ml
@@ -0,0 +1,372 @@
+(* Task 4 (2026-08-25-colitur-of-phases-3-5): the reading-cycle arithmetic
+ and the temporal + sanctoral lectionary resolution chain,
+ Rite_of.Lectionary_of.
+
+ No Rite_of.context exists yet (Task 5's own deliverable), so the
+ coverage test below builds its own APPROXIMATE day resolver directly
+ against Layer.on_date + Temporal_of.temporal, rather than through
+ Calendar.day/Colitur_kernel.Validate -- it does not run RG-style
+ occurrence/precedence resolution (Precedence_of.rules is Task 5's own
+ wiring point too), so on a date where more than one sanctoral entry
+ would occur it simply takes the layer's own canonically-sorted first
+ match. This is not a claim that the FULL calendar resolves this way; it
+ is the minimum needed to exercise Lectionary_of.readings' own
+ observed-vs-temporal branch honestly, over real (not synthetic) data. *)
+
+module L = Colitur_kernel.Layer
+module O = Colitur_kernel.Overlay
+module Cel = Colitur_kernel.Celebration
+module D = Colitur_kernel.Date
+module Slug = Colitur_kernel.Slug
+module Mass_formulary = Colitur_kernel.Mass_formulary
+module Lectionary = Colitur_kernel.Lectionary
+module Computus = Colitur_kernel.Computus
+module V = Rite_of.Vocab_of
+module T = Rite_of.Temporal_of
+module Lect_of = Rite_of.Lectionary_of
+
+let d y m dd = match D.make ~year:y ~month:m ~day:dd with Ok t -> t | Error e -> Alcotest.failf "%s" e
+let iso = D.to_iso8601
+
+(* ---- fixtures -------------------------------------------------------- *)
+
+let lectionary_path = "../data/of/lectionary.sexp"
+let calendar_path = "../data/of/calendar-2002.sexp"
+let amendments_dir = "../data/of/amendments/"
+
+let amendment_files =
+ [ "001-padre-pio.sexp"; "002-juan-diego-cuauhtlatoatzin.sexp"; "003-our-lady-of-guadalupe.sexp";
+ "004-john-xxiii-john-paul-ii.sexp"; "005-mary-magdalene-rank.sexp";
+ "006-mary-mother-of-the-church.sexp"; "007-paul-vi.sexp"; "008-our-lady-of-loreto.sexp";
+ "009-faustina-kowalska.sexp"; "010-narek-avila-hildegard.sexp"; "011-martha-mary-lazarus.sexp";
+ "012-teresa-of-calcutta.sexp"; "013-john-henry-newman.sexp" ]
+
+let real_lectionary () =
+ match Lectionary.load lectionary_path with
+ | Ok l -> l
+ | Error e -> Alcotest.failf "%s: failed to load: %s" lectionary_path e
+
+let real_sanctoral_layer () =
+ let base =
+ match L.load V.rank_of_sexp calendar_path with
+ | Ok l -> l
+ | Error e -> Alcotest.failf "%s: failed to load: %s" calendar_path e
+ in
+ let overlays =
+ List.map
+ (fun name ->
+ let path = amendments_dir ^ name in
+ match O.load V.rank_of_sexp path with
+ | Ok o -> o
+ | Error e -> Alcotest.failf "%s: failed to load: %s" path e)
+ amendment_files
+ in
+ let merged, diagnostics = O.merge base overlays in
+ Alcotest.(check (list string)) "the committed OF overlays apply cleanly, no diagnostics" []
+ (List.map O.diagnostic_to_string diagnostics);
+ merged
+
+(* Approximate "observed" celebration for [date]: the sanctoral layer's own
+ (canonically-sorted) first match if any, else the day's own temporal
+ office -- see this file's own top-of-file comment for why this is a
+ deliberately simplified stand-in for real occurrence resolution. *)
+let observed_on index date temporal =
+ match L.on_date index date with
+ | e :: _ -> e.L.cel
+ | [] -> temporal.Colitur_kernel.Temporal.office
+
+let readings_on lectionary index date =
+ let temporal = T.temporal date in
+ let observed = observed_on index date temporal in
+ Lect_of.readings ~lectionary ~year_start:T.year_start ~observed ~temporal ~date ~temporal_at:T.temporal
+
+(* ---- cycle arithmetic (OLM 1981 Praenotanda n.66/n.69 -- see
+ lectionary_of.mli's own citations, page-image verified) ---- *)
+
+let sunday_letter c = Lect_of.sunday_cycle_letter c
+let weekday_letter c = Lect_of.weekday_cycle_letter c
+
+(* Every case here is derivable from OLM n.66's own footnote 102, whose
+ worked example ("annus 1980 est annus C, annus vero sequens, scilicet
+ annus 1981, est annus A, annus vero 1982 est annus B, et annus 1983 est
+ iterum annus C") is reproduced directly by testing dates EITHER SIDE of
+ Advent 1980/1981/1982 -- the task brief's own "straddle Advent I inside
+ a single civil year" requirement, exercised three times over, against
+ the primary source's own numbers, not invented ones. *)
+let test_sunday_cycle_table () =
+ let cases =
+ [ (* Just before Advent 1980 (still the liturgical year opened Advent
+ 1979, labelled 1980 -- OLM's own "1980 est annus C"), and Advent
+ 1980 itself (opens the year labelled 1981 -- "1981, est annus A"):
+ both civil dates fall in the SAME civil year, 1980, on either side
+ of that year's own Advent I -- the boundary the brief names. *)
+ (D.add_days (T.advent_start 1980) (-1), "c", "before Advent 1980 (civil year 1980, label 1980)");
+ (T.advent_start 1980, "a", "Advent Sunday 1980 itself (civil year 1980, label 1981)");
+ (D.add_days (T.advent_start 1980) 3, "a", "a few days into Advent 1980 (still label 1981)");
+ (* Advent 1981 -> 1982 (A -> B). *)
+ (D.add_days (T.advent_start 1981) (-1), "a", "before Advent 1981 (label 1981)");
+ (T.advent_start 1981, "b", "Advent Sunday 1981 (label 1982)");
+ (* Advent 1982 -> 1983 (B -> C). *)
+ (D.add_days (T.advent_start 1982) (-1), "b", "before Advent 1982 (label 1982)");
+ (T.advent_start 1982, "c", "Advent Sunday 1982 (label 1983)");
+ (* A live-relevant pair: Advent 2025 (opens the "2026" liturgical
+ year, this task's own civil year) is label 2026, 2026 mod 3 = 1
+ -> A; the civil days immediately before it are still label 2025,
+ 2025 mod 3 = 0 -> C. *)
+ (D.add_days (T.advent_start 2025) (-1), "c", "before Advent 2025 (label 2025)");
+ (T.advent_start 2025, "a", "Advent Sunday 2025 (label 2026)")
+ ]
+ in
+ List.iter
+ (fun (date, expected, label) ->
+ Alcotest.(check string) (label ^ " (" ^ iso date ^ ")") expected
+ (sunday_letter (Lect_of.sunday_cycle ~year_start:T.year_start date)))
+ cases
+
+(* OLM n.69 point 4: Year I odd label years, Year II even. Reuses the SAME
+ Advent-1980/1981/1982 boundaries as the Sunday-cycle table above (label
+ 1980 even -> II, 1981 odd -> I, 1982 even -> II, 1983 odd -> I),
+ straddling Advent I within a single civil year exactly as the Sunday
+ table does. *)
+let test_weekday_cycle_table () =
+ let cases =
+ [ (D.add_days (T.advent_start 1980) (-1), "ii", "before Advent 1980 (label 1980, even)");
+ (T.advent_start 1980, "i", "Advent Sunday 1980 (label 1981, odd)");
+ (D.add_days (T.advent_start 1981) (-1), "i", "before Advent 1981 (label 1981, odd)");
+ (T.advent_start 1981, "ii", "Advent Sunday 1981 (label 1982, even)");
+ (D.add_days (T.advent_start 1982) (-1), "ii", "before Advent 1982 (label 1982, even)");
+ (T.advent_start 1982, "i", "Advent Sunday 1982 (label 1983, odd)");
+ (D.add_days (T.advent_start 2025) (-1), "i", "before Advent 2025 (label 2025, odd)");
+ (T.advent_start 2025, "ii", "Advent Sunday 2025 (label 2026, even)")
+ ]
+ in
+ List.iter
+ (fun (date, expected, label) ->
+ Alcotest.(check string) (label ^ " (" ^ iso date ^ ")") expected
+ (weekday_letter (Lect_of.weekday_cycle ~year_start:T.year_start date)))
+ cases
+
+(* The two cycles are independent computations, not two views of the same
+ number -- Advent 1981 (label 1982) is Sunday-cycle B but weekday-cycle
+ II, a label that is even for one modulus and not reducible to the
+ other. *)
+let test_cycles_are_independent () =
+ let date = T.advent_start 1981 in
+ Alcotest.(check string) "Sunday cycle B" "b" (sunday_letter (Lect_of.sunday_cycle ~year_start:T.year_start date));
+ Alcotest.(check string) "weekday cycle II" "ii"
+ (weekday_letter (Lect_of.weekday_cycle ~year_start:T.year_start date))
+
+(* ---- SHA-256 pins ----------------------------------------------------- *)
+
+let sha256_of_file path =
+ let tmp = Filename.temp_file "colitur_lectionary_of_sha256" ".txt" in
+ let cmd = Printf.sprintf "sha256sum %s > %s" (Filename.quote path) (Filename.quote tmp) in
+ (match Sys.command cmd with
+ | 0 -> ()
+ | n -> Alcotest.failf "sha256sum exited %d" n);
+ let ic = open_in tmp in
+ let line = input_line ic in
+ close_in ic;
+ Sys.remove tmp;
+ match String.split_on_char ' ' line with
+ | hash :: _ -> hash
+ | [] -> Alcotest.fail "sha256sum produced no output"
+
+(* Pinned 2026-08-26 against the shipped file itself, independently
+ re-derived (`sha256sum data/of/lectionary.sexp`), the same "derive the
+ new value, don't transcribe it from generator stdout" discipline
+ test_calendar_of_data.ml's own [test_sha256] already follows. *)
+let test_sha256_pinned () =
+ Alcotest.(check string) "data/of/lectionary.sexp SHA-256"
+ "e7fd109bc30baf8a5531a614995e986959214424c80f4d444fa2b772538decde" (sha256_of_file lectionary_path)
+
+(* lectio's OWN of-lectionary.ini SHA-256, pinned inside data/of/
+ lectionary.sexp's own provenance header (tools/bootstrap_lectionary_of
+ .ml's own emitted "; SHA-256: ..." line for the SOURCE, not the file
+ pinned above) -- checked here as a plain substring of the shipped file,
+ not by re-reading the sibling lectio repository (which need not be
+ present wherever this test runs; the point of pinning it in the header
+ is that this repo alone is then enough to know which snapshot produced
+ it). *)
+let test_source_sha256_pinned_in_header () =
+ let ic = open_in lectionary_path in
+ let n = in_channel_length ic in
+ let content = really_input_string ic n in
+ close_in ic;
+ let needle = "SHA-256: f0b527aef58b93e6ccdfbeafe52b340ed2a9d7d72805bf5083e3da04b080123c" in
+ let contains haystack needle =
+ let hl = String.length haystack and nl = String.length needle in
+ let rec go i = i + nl <= hl && (String.sub haystack i nl = needle || go (i + 1)) in
+ go 0
+ in
+ Alcotest.(check bool) "lectio's of-lectionary.ini SHA-256 is pinned in the provenance header" true
+ (contains content needle)
+
+(* A missing lectio snapshot must fail LOUDLY -- Task 1's own extractor
+ shipped exactly this bug (parse_lectio_ini swallowing FileNotFoundError,
+ silently producing a DIFFERENT file with a different SHA-256 and zero
+ `en` names) and needed a review round to fix; this task's own brief
+ names it explicitly as a trap not to repeat. Exercised here as a real
+ subprocess run, not merely by reading the generator's source: invokes
+ the built tools/bootstrap_lectionary_of.exe against a path that does
+ not exist and asserts BOTH a non-zero exit AND that no output file was
+ written (a generator that failed loudly but left a partial/stale
+ destination file behind would be only half fixed). *)
+let test_missing_source_fails_loudly () =
+ let exe = "../tools/bootstrap_lectionary_of.exe" in
+ let bogus_src = Filename.temp_file "colitur_lectionary_of_missing" ".ini" in
+ Sys.remove bogus_src;
+ (* guaranteed not to exist, still a plausible-looking path *)
+ let dst = Filename.temp_file "colitur_lectionary_of_dst" ".sexp" in
+ Sys.remove dst;
+ let log = Filename.temp_file "colitur_lectionary_of_stderr" ".txt" in
+ let cmd =
+ Printf.sprintf "%s %s %s >%s 2>&1" (Filename.quote exe) (Filename.quote bogus_src) (Filename.quote dst)
+ (Filename.quote log)
+ in
+ let status = Sys.command cmd in
+ let ic = open_in log in
+ let n = in_channel_length ic in
+ let stderr_text = really_input_string ic n in
+ close_in ic;
+ Sys.remove log;
+ Alcotest.(check bool) "non-zero exit on a missing source file" true (status <> 0);
+ Alcotest.(check bool) "no output file written" false (Sys.file_exists dst);
+ Alcotest.(check bool) "error message names the missing path and explains why this matters" true
+ (let contains haystack needle =
+ let hl = String.length haystack and nl = String.length needle in
+ let rec go i = i + nl <= hl && (String.sub haystack i nl = needle || go (i + 1)) in
+ go 0
+ in
+ contains stderr_text "no such file" && contains stderr_text bogus_src)
+
+(* ---- basic load ------------------------------------------------------- *)
+
+let test_load () =
+ let l = real_lectionary () in
+ Alcotest.(check int) "754 entries" 754 (List.length (Lectionary.entries l))
+
+(* ---- coverage: a full sample civil year, both directions, PINNED ------ *)
+
+(* Civil year 2026 -- the same year this task's data file's own coverage
+ report uses. Iterates every day, resolving readings the same
+ approximate way [readings_on] does (see this file's own top-of-file
+ comment), and asserts BOTH the total resolved count AND the exact,
+ named set of unresolved dates -- never a silent zero (task brief's own
+ Step 4 requirement). *)
+let all_days_of_2026 =
+ let days_in_month = [| 31; 28; 31; 30; 31; 30; 31; 31; 30; 31; 30; 31 |] in
+ List.concat
+ (List.init 12 (fun mi ->
+ let m = mi + 1 in
+ List.init days_in_month.(mi) (fun di -> d 2026 m (di + 1))))
+
+let test_coverage_2026 () =
+ let lectionary = real_lectionary () in
+ let layer = real_sanctoral_layer () in
+ let index = L.index layer ~easter:Computus.gregorian_easter ~years:[ 2025; 2026 ] in
+ let unresolved =
+ List.filter_map
+ (fun date ->
+ match readings_on lectionary index date with
+ | None, [] -> Some (iso date)
+ | Some _, (_ :: _) -> None
+ | (Some _, []) | (None, _ :: _) ->
+ Alcotest.failf "%s: Mass_formulary.t and citations disagree on whether readings resolved"
+ (iso date))
+ all_days_of_2026
+ in
+ Alcotest.(check int) "365 days in 2026" 365 (List.length all_days_of_2026);
+ (* The ONE genuine gap this task's own bootstrap found and named: lectio's
+ 988 keys never include a Christmas DAY Mass (only the Vigil) -- see
+ data/of/lectionary.sexp's own provenance header and
+ tools/bootstrap_lectionary_of.ml's own [named_overrides] comment on
+ "christmas". Pinned as a NAMED set, not a bare count: a silent zero
+ here is exactly the failure mode the task brief warns against. *)
+ Alcotest.(check (list string)) "the unresolved-day set is exactly {25 December}" [ "2026-12-25" ] unresolved;
+ Alcotest.(check int) "364 of 365 days resolve readings" 364 (365 - List.length unresolved)
+
+(* Same measurement, restated as "how many days resolve" rather than "how
+ many don't" -- redundant with the count above by construction, kept
+ because Step 4's own brief asks for a pinned resolved-count assertion
+ specifically, not only its complement. *)
+let test_pinned_resolved_count () =
+ let lectionary = real_lectionary () in
+ let layer = real_sanctoral_layer () in
+ let index = L.index layer ~easter:Computus.gregorian_easter ~years:[ 2025; 2026 ] in
+ let resolved =
+ List.length
+ (List.filter
+ (fun date -> match readings_on lectionary index date with Some _, _ :: _ -> true | _ -> false)
+ all_days_of_2026)
+ in
+ Alcotest.(check int) "364 days resolve readings in 2026" 364 resolved
+
+(* ---- resolution chain: unit-level spot checks -------------------------- *)
+
+(* Step 3: an ordinary Ordinary Time weekday with no sanctoral entry
+ resolves via its own temporal slug, cycle-selected. 16 June 2026 is a
+ Tuesday of Ordinary Time, in the SECOND (post-Pentecost) block, with no
+ calendar-2002.sexp/amendments entry (checked against the real merged
+ layer, not assumed, and clear of the three nearby movable solemnities
+ -- Corpus Christi 4 June, Sacred Heart 12 June, Immaculate Heart 13
+ June). The expected slug is read off Temporal_of.temporal itself, not
+ hand-computed: the second block's own week arithmetic (temporal_of.ml's
+ own [ordinary_time_week]) is counted BACKWARDS from Christ the King, not
+ forwards from the Baptism -- re-deriving that by hand here would just
+ duplicate the one calculation this test exists to exercise, not check
+ it independently. *)
+let test_step3_temporal_ferial () =
+ let lectionary = real_lectionary () in
+ let layer = real_sanctoral_layer () in
+ let index = L.index layer ~easter:Computus.gregorian_easter ~years:[ 2025; 2026 ] in
+ let date = d 2026 6 16 in
+ Alcotest.(check bool) "16 June 2026: no sanctoral entry" true (L.on_date index date = []);
+ let expected_slug = (T.temporal date).Colitur_kernel.Temporal.office.Cel.slug in
+ match readings_on lectionary index date with
+ | Some fm, (_ :: _ as cs) ->
+ Alcotest.(check bool) "tagged Own_slug" true (fm.Mass_formulary.via = Mass_formulary.Own_slug);
+ Alcotest.(check (option string)) "said the temporal slug" (Some (Slug.to_string expected_slug))
+ (Option.map Slug.to_string fm.Mass_formulary.said);
+ Alcotest.(check int) "two citations (First + Gospel)" 2 (List.length cs)
+ | _ -> Alcotest.fail "16 June 2026 should resolve readings via step 3"
+
+(* Step 2: a sanctoral saint who won the day resolves via his own slug, not
+ the temporal ferial's. 30 November 2026 is a Monday of Advent week 1
+ (which would otherwise be "of-advent-1-monday") but is also St Andrew
+ the Apostle's own fixed date. *)
+let test_step2_sanctoral_wins () =
+ let lectionary = real_lectionary () in
+ let layer = real_sanctoral_layer () in
+ let index = L.index layer ~easter:Computus.gregorian_easter ~years:[ 2025; 2026 ] in
+ let date = d 2026 11 30 in
+ (match L.on_date index date with
+ | [ e ] -> Alcotest.(check string) "St Andrew's own entry" "andrew-the-apostle" (Slug.to_string e.L.cel.Cel.slug)
+ | es -> Alcotest.failf "expected exactly one sanctoral entry on 30 Nov 2026, got %d" (List.length es));
+ match readings_on lectionary index date with
+ | Some fm, (_ :: _ as cs) ->
+ Alcotest.(check bool) "tagged Proper" true (fm.Mass_formulary.via = Mass_formulary.Proper);
+ Alcotest.(check (option string)) "said Andrew's own slug" (Some "andrew-the-apostle")
+ (Option.map Slug.to_string fm.Mass_formulary.said);
+ (* "of-advent-1-monday" is FLAT, not cycle-lettered (OLM n.69 point 3:
+ Advent's own ferias do not change year to year -- confirmed by
+ this generator's own collapse, tools/bootstrap_lectionary_of.ml's
+ [collapse_weekday]), so there is exactly one temporal citation
+ set to compare against, not two. *)
+ Alcotest.(check bool) "NOT the temporal ferial's Advent citations" true
+ (cs <> Option.get (Lectionary.find lectionary (Slug.of_string_exn "of-advent-1-monday")))
+ | _ -> Alcotest.fail "30 November 2026 should resolve readings via step 2"
+
+let suite =
+ [ Alcotest.test_case "Sunday cycle table (OLM n.66, straddles Advent I)" `Quick test_sunday_cycle_table;
+ Alcotest.test_case "weekday cycle table (OLM n.69.4, straddles Advent I)" `Quick test_weekday_cycle_table;
+ Alcotest.test_case "the two cycles are independent" `Quick test_cycles_are_independent;
+ Alcotest.test_case "data/of/lectionary.sexp SHA-256 pinned" `Quick test_sha256_pinned;
+ Alcotest.test_case "lectio source SHA-256 pinned in the header" `Quick test_source_sha256_pinned_in_header;
+ Alcotest.test_case "a missing lectio source fails loudly, not silently" `Quick test_missing_source_fails_loudly;
+ Alcotest.test_case "loads, 754 entries" `Quick test_load;
+ Alcotest.test_case "2026 coverage: exactly {25 December} unresolved" `Quick test_coverage_2026;
+ Alcotest.test_case "2026 coverage: 364 days resolve" `Quick test_pinned_resolved_count;
+ Alcotest.test_case "step 3: temporal ferial fallback" `Quick test_step3_temporal_ferial;
+ Alcotest.test_case "step 2: sanctoral proper wins over the ferial" `Quick test_step2_sanctoral_wins
+ ]
diff --git a/tools/bootstrap_lectionary_of.ml b/tools/bootstrap_lectionary_of.ml
new file mode 100644
index 0000000..f521bb1
--- /dev/null
+++ b/tools/bootstrap_lectionary_of.ml
@@ -0,0 +1,827 @@
+(* Bootstraps data/of/lectionary.sexp from lectio's of-lectionary.ini
+ (Task 4, 2026-08-25-colitur-of-phases-3-5). Lives in tools/, OCaml, not
+ Python -- deliberately: this task's own brief named
+ tools/extract_of_lectionary.py, but tools/bootstrap_lectionary.ml
+ already IS the established shape for exactly this job (EF's own
+ lectionary bootstrap), including a real, load-bearing safety net --
+ [assert_reachable] below sweeps Rite_of.Temporal_of.temporal AND the
+ real merged sanctoral layer directly, so a mapping-table typo cannot
+ ship a dead key silently. Reimplementing that check in Python would mean
+ duplicating colitur's own date arithmetic in a second language, exactly
+ the drift risk this generator exists to avoid. Named to match the
+ OF-specific sibling convention (temporal_of.ml, precedence_of.ml), not
+ bootstrap_lectionary.ml's own bare name, since a second rite needs a
+ second, distinguishable generator.
+
+ THE LINEAGE, stated once, here, because every downstream comment and the
+ emitted file's own header both lean on it: lectio's of-lectionary.ini
+ says of itself (its own top-of-file comment) that it is "Generated from
+ niedziela.pl by scripts/genlect-of.go (harvest 2020-2025)". niedziela.pl
+ is a POLISH VERNACULAR pastoral lectionary aid, not the Latin OLM
+ (Ordo Lectionum Missae) 1981 itself, and its own citations are, per the
+ design spec (2026-08-24-colitur-of-rite-module-design.md sec4.4),
+ ENGLISH-CANONICAL (English book names/verse numbering), not the OLM's
+ Vulgate-numbered Latin. THIS IS A SEPARATE LINEAGE from lectio's OF
+ CALENDAR (data/of/calendar-2002.sexp, roman-calendar.ini, upstream
+ calapi.inadiutorium.cz) -- lectio is not one OF witness but two,
+ unrelated upstreams glued together by one downstream project, and
+ neither is the typical edition. What this data CANNOT show: any
+ divergence between niedziela.pl's own pastoral choices and the Latin
+ OLM's own text (verse-range short/long forms, alternative readings,
+ Vulgate-vs-Nova-Vulgata numbering -- the design spec's own sec4.4 records
+ three real, confirmed such divergences against the actual OLM page
+ images: Holy Family Year A's second-reading short form, Trinity Sunday's
+ Dan 3:56, and the Baptism of the Lord's Mc 9:6 vs "Mark 9:7"); nor can it
+ show anything about the OLM's SHORT-FORM/LONG-FORM alternatives, which
+ niedziela.pl does not distinguish. This generator does not attempt to
+ correct any of that -- it transcribes the vernacular data faithfully,
+ states the lineage loudly, and lets a future task with the actual OLM
+ page images (docs/research/of/olm-1981.pdf) do primary-source
+ verification the way tools/bootstrap_lectionary.ml's own Holy Week
+ entries did for EF. *)
+open Colitur_kernel
+
+let default_source = "../lectio/internal/caldata/of-lectionary.ini"
+let default_dest = "data/of/lectionary.sexp"
+
+let die fmt =
+ Printf.ksprintf
+ (fun s -> prerr_endline ("bootstrap_lectionary_of: " ^ s); exit 1)
+ fmt
+
+(* ---- INI parsing --------------------------------------------------- *)
+
+type section = { name : string; fields : (string * string) list }
+
+(* Fails loudly, not silently, when the source file is absent -- Task 1's
+ own review found exactly this bug in the calendar extractor
+ (parse_lectio_ini swallowing FileNotFoundError, producing a DIFFERENT
+ file with a different SHA-256 and no warning): checked BEFORE any read
+ is attempted, and the [open_in] itself is also guarded as defence in
+ depth, mirroring tools/bootstrap_lectionary.ml's own [parse_ini]. *)
+let parse_ini path =
+ if not (Sys.file_exists path) then
+ die "%s: no such file (a missing lectio snapshot must fail loudly, not \
+ silently regenerate with a different SHA-256 and no warning -- Task 1's \
+ own review round found exactly this bug)"
+ path;
+ let ic = try open_in path with Sys_error e -> die "%s" e in
+ let sections = ref [] and cur = ref None and malformed = ref [] and lineno = ref 0 in
+ let flush () =
+ match !cur with
+ | Some (n, fs) -> sections := { name = n; fields = List.rev fs } :: !sections
+ | None -> ()
+ in
+ (try
+ while true do
+ incr lineno;
+ let raw = input_line ic in
+ let line = String.trim raw in
+ if line = "" || line.[0] = ';' || line.[0] = '#' then ()
+ else if line.[0] = '[' then begin
+ flush ();
+ cur := Some (String.sub line 1 (String.length line - 2), [])
+ end
+ else
+ let known_key k = List.mem k [ "first"; "psalm"; "second"; "gospel" ] in
+ match String.index_opt line '=' with
+ | Some i when known_key (String.trim (String.sub line 0 i)) ->
+ let k = String.trim (String.sub line 0 i) in
+ let v = String.trim (String.sub line (i + 1) (String.length line - i - 1)) in
+ cur :=
+ (match !cur with
+ | Some (n, fs) -> Some (n, (k, v) :: fs)
+ | None -> die "%s:%d: field %S before any section" path !lineno k)
+ | Some _ | None ->
+ (* Known, single, understood anomaly (see the assertion below):
+ line 1276 of the shipped snapshot, inside [holy-family-A],
+ reads bare "=Sir3:2-6,12-14-Gk" -- an EMPTY key, not "no
+ '=' sign" (an earlier version of this parser tested for the
+ latter and missed this line entirely, since [String.
+ index_opt] DOES find the '=' at position 0; a key must now
+ be one of the four known field names, checked explicitly).
+ This is the Polish lectionary's own Septuagint/Greek-
+ numbering variant for Sirach 3 (design spec sec5's own
+ "Polish is independent on one point": Syr 3,2-6.12-14
+ against the OLM/CEI/USA table's shared Nova Vulgata
+ 3,3-7.14-17a), evidently emitted by niedziela.pl's own
+ scraper as a stray annotation rather than a proper
+ "first_alt = ..." field. Recorded, not silently dropped:
+ every such line is collected and the count is asserted
+ below, so a NEW malformed line in a future lectio snapshot
+ still fails loudly rather than being quietly absorbed by
+ this same tolerance. *)
+ malformed := (!lineno, line) :: !malformed
+ done
+ with End_of_file -> ());
+ flush ();
+ close_in ic;
+ (match List.rev !malformed with
+ | [ (1276, "=Sir3:2-6,12-14-Gk") ] -> ()
+ | [] -> die "%s: expected exactly one known malformed line (1276, the Sirach \
+ Septuagint-numbering annotation) but found none -- either the \
+ snapshot changed or this tolerance is now dead code; re-check \
+ by hand before touching this assertion" path
+ | other ->
+ List.iter (fun (n, l) -> Printf.eprintf " line %d: %S\n" n l) other;
+ die "%s: %d unparseable line(s) found, not the one previously-known \
+ anomaly (see above) -- investigate before shipping; a new \
+ malformed line must be understood, not silently swallowed"
+ path (List.length other));
+ List.rev !sections
+
+(* ---- Citation extraction -- First + Gospel only --------------------- *)
+
+(* Psalm and Second are deliberately dropped, even though lectio's ini
+ carries [psalm] (every entry) and [second] (Sundays/solemnities):
+ Colitur_kernel.Validate's own ["citations"] check (kernel, off limits to
+ this task) hard-asserts every day's citation-part list is EXACTLY
+ [[First; Gospel]] -- the identical scope boundary
+ tools/bootstrap_lectionary.ml's own [convert] already holds for EF
+ ("Nothing here encodes... the chants (Psalm, Second, Tract, Alleluia,
+ Sequence) are deliberately unbuilt"). Carrying Psalm/Second through here
+ would not add capability today (nothing reads them) and would set up a
+ guaranteed collision with that kernel check the moment a future task
+ wires Validate over OF data. *)
+let cite sec =
+ let get k = match List.assoc_opt k sec.fields with None | Some "" -> None | Some v -> Some v in
+ match (get "first", get "gospel") with
+ | Some first, Some gospel ->
+ Some [ { Citation.part = Citation.First; reference = first };
+ { Citation.part = Citation.Gospel; reference = gospel } ]
+ | _ -> None
+
+(* ---- Cycle-family grouping ------------------------------------------ *)
+
+(* Every one of the 988 sections carries a cycle suffix: -A/-B/-C (Sunday
+ cycle, 102 bases x 3 = 306) or -I/-II (weekday cycle, 341 bases x up to
+ 2 = up to 682; two bases are short one cycle -- see
+ [collapse_weekday] below). Measured exhaustively before writing this
+ generator: no section carries any OTHER suffix, and no base name
+ appears in both groups. *)
+let strip_suffix ~suffix s =
+ let ls = String.length s and lsuf = String.length suffix in
+ if ls > lsuf && String.sub s (ls - lsuf) lsuf = suffix then
+ Some (String.sub s 0 (ls - lsuf))
+ else None
+
+let base_and_letter name =
+ match strip_suffix ~suffix:"-A" name with
+ | Some b -> Some (b, `A)
+ | None -> (
+ match strip_suffix ~suffix:"-B" name with
+ | Some b -> Some (b, `B)
+ | None -> (
+ match strip_suffix ~suffix:"-C" name with
+ | Some b -> Some (b, `C)
+ | None -> (
+ match strip_suffix ~suffix:"-II" name with
+ | Some b -> Some (b, `II)
+ | None -> (
+ match strip_suffix ~suffix:"-I" name with
+ | Some b -> Some (b, `I)
+ | None -> None))))
+
+type resolved =
+ | Flat of Citation.t list (* cycle-independent: one citation set for every year *)
+ | Sunday_cycle of (Citation.t list * Citation.t list * Citation.t list) (* A, B, C *)
+ | Weekday_cycle of (Citation.t list option * Citation.t list option) (* I, II -- either may be absent *)
+
+(* Sunday-cycle collapse: mechanical, not curated per-saint. Measured
+ across all 102 bases before this generator existed: 43 are byte-
+ identical across A/B/C (routine -- a fixed-date saint's own Mass simply
+ does not vary by year, e.g. andrew-the-apostle); 57 are genuinely
+ distinct on all three letters (real OLM n.66 three-year-cycle content --
+ every numbered Sunday, plus the handful of movable/fixed solemnities of
+ the Lord whose OWN Gospel varies by year: Holy Family, Baptism of the
+ Lord, Ascension, Corpus Christi, Christ the King, Trinity, Sacred Heart,
+ Transfiguration); and EXACTLY 2 have a clean 2-of-3 majority with the
+ third an unrelated passage from a DIFFERENT day entirely --
+ annunciation-of-the-lord (B is Monday of Holy Week's own Mass,
+ Isa 42:1-7/John 12:1-11 -- a scraping-year artifact: the Annunciation
+ was genuinely impeded and transferred that harvest year, so
+ niedziela.pl's site had Holy Week's Mass on 25 March instead) and
+ immaculate-conception-of-the-blessed-virgin-mary (A is Isa 35:1-10/
+ Luke 5:17-26, an ordinary Lenten-feria Gospel, the same shape). Both
+ solemnities are, in real practice, NOT cycle-dependent at all (single
+ Mass every year) -- corroborated externally by the "2 of 3 agree, none
+ of the 57 genuine cases exhibit that shape" measurement itself, not
+ merely asserted -- so majority-collapse is applied, and the discarded
+ outlier is logged. No other base in the whole 102-base population has
+ this 2-of-3 shape; the rule is general, not hand-targeted at these two
+ names. *)
+let collapse_sunday base va vb vc =
+ if va = vb && vb = vc then Flat va
+ else if va = vb then begin
+ Printf.eprintf
+ "bootstrap_lectionary_of: %s: cycle C disagreed with A/B (scraping-year \
+ artifact, majority kept): %s\n"
+ base (match vc with [ f; _ ] -> f.Citation.reference | _ -> "?");
+ Flat va
+ end
+ else if va = vc then begin
+ Printf.eprintf
+ "bootstrap_lectionary_of: %s: cycle B disagreed with A/C (scraping-year \
+ artifact, majority kept): %s\n"
+ base (match vb with [ f; _ ] -> f.Citation.reference | _ -> "?");
+ Flat va
+ end
+ else if vb = vc then begin
+ Printf.eprintf
+ "bootstrap_lectionary_of: %s: cycle A disagreed with B/C (scraping-year \
+ artifact, majority kept): %s\n"
+ base (match va with [ f; _ ] -> f.Citation.reference | _ -> "?");
+ Flat vb
+ end
+ else Sunday_cycle (va, vb, vc)
+
+(* Weekday-cycle collapse: same mechanical byte-identity test. OLM 1981
+ Praenotanda n.69 points 2-3 (page-image verified,
+ docs/research/of/olm-1981.pdf p.33/"XXXIII") state that Lent has its own
+ fixed seasonal cycle and Advent/Christmastide/Paschaltide ferias "do not
+ change" year to year -- exactly the byte-identical shape measured for
+ those families (advent-1/2/3, advent-dec-17..24, lent-after-ashes-*,
+ holy-week-*, easter-octave-*: 119 of 341 bases). Point 4 confines the
+ REAL two-year alternation to Ordinary Time's 34 weeks, and even there
+ only the FIRST reading alternates -- the Gospel is one single,
+ year-independent cycle (n.69 point 4: "lectiones evangelicae unico
+ disponuntur cyclo... Prior vero lectio, in duplici cyclo ordinatur") --
+ which is exactly why 198 of the 221 non-identical bases still share a
+ common Gospel with only the First Reading differing: real content, kept
+ as two entries because the FULL pair genuinely differs, not a scraping
+ artifact (unlike the two Sunday-cycle cases above, no base in this group
+ showed a "majority of one, unrelated outlier" shape). *)
+let collapse_weekday base v1 v2 =
+ match (v1, v2) with
+ | Some a, Some b when a = b -> Flat a
+ | Some _, Some _ -> Weekday_cycle (v1, v2)
+ | Some _, None | None, Some _ ->
+ Printf.eprintf
+ "bootstrap_lectionary_of: %s: only one weekday-cycle year present in \
+ lectio's own snapshot (a real gap in niedziela.pl's 2020-2025 harvest, \
+ not a parsing defect) -- transcribed as-is\n"
+ base;
+ Weekday_cycle (v1, v2)
+ | None, None -> die "%s: cycle collapse called with no data" base
+
+let resolve_sections secs =
+ let tbl = Hashtbl.create 1024 in
+ List.iter
+ (fun sec ->
+ match base_and_letter sec.name with
+ | None -> die "%s: no recognised cycle suffix (-A/-B/-C/-I/-II)" sec.name
+ | Some (base, letter) -> (
+ match cite sec with
+ | None -> die "%s: no first/gospel field" sec.name
+ | Some cs ->
+ let cur = try Hashtbl.find tbl base with Not_found -> (None, None, None, None, None) in
+ let a, b, c, i, ii = cur in
+ let updated =
+ match letter with
+ | `A -> (Some cs, b, c, i, ii)
+ | `B -> (a, Some cs, c, i, ii)
+ | `C -> (a, b, Some cs, i, ii)
+ | `I -> (a, b, c, Some cs, ii)
+ | `II -> (a, b, c, i, Some cs)
+ in
+ Hashtbl.replace tbl base updated))
+ secs;
+ Hashtbl.fold
+ (fun base (a, b, c, i, ii) acc ->
+ match (a, b, c, i, ii) with
+ | Some va, Some vb, Some vc, None, None -> (base, collapse_sunday base va vb vc) :: acc
+ | None, None, None, i, ii when i <> None || ii <> None ->
+ (base, collapse_weekday base i ii) :: acc
+ | Some va, Some vb, Some vc, i, ii when i <> None || ii <> None ->
+ (* A real, measured duplicate in lectio's own source, confined
+ (checked below by this generator's own exhaustive Hashtbl.fold)
+ to the six Easter Octave weekdays: each carries BOTH an
+ -A/-B/-C section AND an -I/-II one, evidently written by two
+ different passes of niedziela.pl's own generation pipeline.
+ Content-verified identical in substance (Acts 2:14,22-32/33,
+ Ps 16, Matt 28:8-15 -- "Acts"/"The Acts" and "Mat"/"Matthew"
+ spelling differ, the citation does not), and each of the two
+ representations is ALSO internally self-consistent
+ (A=B=C, I=II) on its own -- so this is redundancy, not a real
+ conflict. The -A/-B/-C reading is kept (it is what this
+ generator's own [named_overrides] table for these six bases
+ already targets); the -I/-II reading is discarded, logged
+ here rather than silently dropped. *)
+ Printf.eprintf
+ "bootstrap_lectionary_of: %s: BOTH Sunday- and weekday-cycle data present \
+ (a genuine lectio duplicate, not a defect -- see the comment on this branch); \
+ keeping the Sunday-cycle (A/B/C) reading, discarding the weekday-cycle (I/II) one\n"
+ base;
+ (base, collapse_sunday base va vb vc) :: acc
+ | _ ->
+ die "%s: mixed or incomplete cycle data (a=%b b=%b c=%b i=%b ii=%b)" base (a <> None)
+ (b <> None) (c <> None) (i <> None) (ii <> None))
+ tbl []
+
+(* ---- colitur slug mapping -------------------------------------------- *)
+
+let weekday_pairs =
+ (* (colitur full word, lectio abbreviation) *)
+ [ ("monday", "mon"); ("tuesday", "tue"); ("wednesday", "wed"); ("thursday", "thu");
+ ("friday", "fri"); ("saturday", "sat") ]
+
+let split_dash s = String.split_on_char '-' s
+
+(* (colitur season word, lectio season word, max week number) -- ferial
+ families. Min week is always 1. Week 6 of Lent (Holy Week) and week 1 of
+ Easter (the Octave) are deliberately excluded from this generic table --
+ both have their own named families, handled in [special_overrides]. *)
+let ferial_families =
+ [ ("advent", "advent", 4); ("lent", "lent", 5); ("easter", "easter", 7);
+ ("ordinary-time", "ordinary", 34) ]
+
+(* Easter's own numbered Sunday family runs 3..7 in lectio (2 is the
+ separately-named "easter-octave-sun", see [named_overrides]) but the
+ upper bound here is deliberately still a loose "any n >= 1" check (see
+ [pattern_match]'s own guard) -- lectio simply never emits an
+ "easter-sunday-1"/"-2" base for this family to collide with. *)
+let sunday_families =
+ [ ("advent", "advent", 4); ("lent", "lent", 5); ("easter", "easter", 7);
+ ("ordinary-time", "ordinary", 33) ]
+
+(* A base that pattern-matches a numbered ferial or Sunday family. Returns
+ the colitur slug directly. *)
+let pattern_match base =
+ match split_dash base with
+ | [ w; "sunday"; n ] -> (
+ match (List.find_opt (fun (_, lw, _) -> lw = w) sunday_families, int_of_string_opt n) with
+ | Some (cw, _, max_n), Some ni when ni >= 1 && ni <= max_n ->
+ Some (Printf.sprintf "of-%s-sunday-%d" cw ni)
+ | _ -> None)
+ | [ w; n; wd ] -> (
+ match
+ ( List.find_opt (fun (_, lw, _) -> lw = w) ferial_families,
+ int_of_string_opt n,
+ List.find_opt (fun (_, la) -> la = wd) weekday_pairs )
+ with
+ | Some (cw, _, max_n), Some ni, Some (full_wd, _) when ni >= 1 && ni <= max_n ->
+ Some (Printf.sprintf "of-%s-%d-%s" cw ni full_wd)
+ | _ -> None)
+ | _ -> None
+
+(* Named-day and irregular-family renames -- everything [pattern_match]
+ above cannot reach because colitur's own slug uses a DIFFERENT word, a
+ DIFFERENT numbering scheme, or (the Christmas-season families) the SAME
+ weekday-keyed scheme lectio happens to expose under a differently-named
+ family. Each entry cites the content verification that justified it,
+ not merely the name resemblance -- three of these (christmas,
+ christmas-sunday-sun, easter-octave-sun) would have been WRONG if
+ matched by name alone; see the comment on each. *)
+let named_overrides =
+ [ (* Content-verified against the real reading (Isa 62:1-5/Matt 1:18-25,
+ the genealogy/annunciation-to-Joseph narrative): this is the VIGIL
+ Mass, not "Christmas Day" despite the bare name -- the real Christmas
+ DAY Mass (Isa 52:7-10/John 1:1-14) is ABSENT from lectio's own 988
+ keys entirely, a genuine, notable gap (see the generator's own
+ coverage report). *)
+ ("christmas", [ "of-nativity-vigil" ]);
+ (* Content-verified (Sirach 24 Wisdom-personified / Eph 1 / John 1:1-18):
+ this is the SECOND SUNDAY AFTER THE NATIVITY (Normae n.36), not a
+ generic "the Sunday of Christmas" despite the bare name -- Holy
+ Family (a DIFFERENT Sunday, Normae n.35(a)) has its own "holy-family"
+ base, mapped just below. *)
+ ("christmas-sunday-sun", [ "of-christmas-sunday-2" ]);
+ ("mary-mother-of-god-octave-of-christmas", [ "of-mary-mother-of-god" ]);
+ (* Content-verified (Joel 2:12-18/Matt 6:1-6,16-18, THE Ash Wednesday
+ Mass): lectio groups Ash Wednesday itself into this weekday-cycle
+ family rather than giving it a bare "ash-wednesday" key. Its own
+ three siblings (Thursday/Friday/Saturday right after Ash
+ Wednesday) are plain ferias, matched by the SAME family, needing
+ only the word rename ("lent-after-ashes" -> "of-lent-after-ashes")
+ [pattern_match] cannot supply on its own (it is not a numbered
+ week). *)
+ ("lent-after-ashes-wed", [ "of-ash-wednesday" ]);
+ ("lent-after-ashes-thu", [ "of-lent-after-ashes-thursday" ]);
+ ("lent-after-ashes-fri", [ "of-lent-after-ashes-friday" ]);
+ ("lent-after-ashes-sat", [ "of-lent-after-ashes-saturday" ]);
+ ("trinity-sunday", [ "of-trinity" ]);
+ (* Content-verified (John 20:19-31, the Divine Mercy Gospel): the
+ Sunday CLOSING the Easter Octave, colitur's own generic
+ week-2-of-Easter Sunday slug, not a second distinct office. *)
+ ("easter-octave-sun", [ "of-easter-sunday-2" ]);
+ (* The remaining single- or compound-word NAMED temporal days
+ (Temporal_of.named/[temporal]'s own Sunday branches): colitur's own
+ slug is simply "of-" prepended to lectio's own bare name, verified
+ against temporal_of.ml directly rather than assumed -- these are
+ NOT reachable by pass-through (pass-through checks the SANCTORAL
+ layer only, and none of these is sanctoral data). *)
+ ("epiphany", [ "of-epiphany" ]);
+ ("palm-sunday", [ "of-palm-sunday" ]);
+ ("easter-sunday", [ "of-easter-sunday" ]);
+ ("ascension", [ "of-ascension" ]);
+ ("pentecost", [ "of-pentecost" ]);
+ ("baptism-of-the-lord", [ "of-baptism-of-the-lord" ]);
+ ("christ-the-king", [ "of-christ-the-king" ]);
+ ("corpus-christi", [ "of-corpus-christi" ]);
+ ("holy-family", [ "of-holy-family" ]);
+ (* Sacred Heart is SANCTORAL data (calendar-2002.sexp, Easter_offset 68
+ -- F-HEARTS finding, this plan's Task 1), not a Temporal_of slug, and
+ its colitur slug carries "-of-jesus" that lectio's bare "sacred-heart"
+ does not. *)
+ ("sacred-heart", [ "sacred-heart-of-jesus" ]);
+ (* Holy Week Monday-Wednesday and the Triduum: colitur's own
+ Temporal_of deliberately does NOT name these days (Lent's own
+ generic week-6 ferial slug covers them, see temporal_of.ml's own
+ [season] function -- Lent runs "through Holy Saturday inclusive").
+ lectio names them by a WEEKDAY family lectio itself calls
+ "holy-week"/"triduum" rather than "lent-6". *)
+ ("holy-week-mon", [ "of-lent-6-monday" ]);
+ ("holy-week-tue", [ "of-lent-6-tuesday" ]);
+ ("holy-week-wed", [ "of-lent-6-wednesday" ]);
+ ("triduum-thu", [ "of-lent-6-thursday" ]);
+ ("triduum-fri", [ "of-lent-6-friday" ]);
+ ("triduum-sat", [ "of-lent-6-saturday" ]);
+ (* Easter Octave weekdays: colitur names these directly
+ (of-easter-octave-day-N, Monday=2..Saturday=7 -- temporal_of.ml's
+ own [named], "Easter Sunday (above) plus these six"). *)
+ ("easter-octave-mon", [ "of-easter-octave-day-2" ]);
+ ("easter-octave-tue", [ "of-easter-octave-day-3" ]);
+ ("easter-octave-wed", [ "of-easter-octave-day-4" ]);
+ ("easter-octave-thu", [ "of-easter-octave-day-5" ]);
+ ("easter-octave-fri", [ "of-easter-octave-day-6" ]);
+ ("easter-octave-sat", [ "of-easter-octave-day-7" ]);
+ (* The three Christmas-season ferial stretches
+ (Temporal_of.christmas_feria_slug's own three "of-christmas-{0,1,2}-
+ <weekday>" stretches, 26-31 Dec / 2-5 Jan / 7 Jan..pre-Baptism) are
+ WEEKDAY-keyed on colitur's side. lectio exposes THREE separate
+ weekday-keyed families that line up with them one-for-one, under
+ names that do not textually resemble colitur's own -- matched here
+ by CONTENT/POSITION, not by name:
+ - "christmas-octave-<wd>" (1 John/John 1, the Octave itself, 26-31
+ Dec) -> stretch 0.
+ - "christmas-<wd>" bare, no "-octave-"/"-dec-"/"-jan-" (1 John
+ 2-3/John 1:29-51, the semi-continuous reading BETWEEN the Octave
+ and Epiphany, 2-5 Jan) -> stretch 1.
+ - "christmas-after-epiphany-<wd>" (7 Jan..Baptism) -> stretch 2.
+ lectio ALSO carries "christmas-dec-29/30/31" and "christmas-jan-
+ 2..7", a DATE-keyed duplicate of the same stretches -- deliberately
+ UNUSED (see [excluded_bases] below): colitur's own slugs are
+ weekday-keyed, not date-keyed, so a fixed civil date such as
+ "29 December" is not any single colitur slug -- it is a DIFFERENT
+ weekday (hence a different of-christmas-0-<weekday>) in different
+ years, and Lectionary.t has no per-date lookup at all. *)
+ ("christmas-octave-mon", [ "of-christmas-0-monday" ]);
+ ("christmas-octave-tue", [ "of-christmas-0-tuesday" ]);
+ ("christmas-octave-wed", [ "of-christmas-0-wednesday" ]);
+ ("christmas-octave-thu", [ "of-christmas-0-thursday" ]);
+ ("christmas-octave-fri", [ "of-christmas-0-friday" ]);
+ ("christmas-octave-sat", [ "of-christmas-0-saturday" ]);
+ ("christmas-mon", [ "of-christmas-1-monday" ]);
+ ("christmas-tue", [ "of-christmas-1-tuesday" ]);
+ ("christmas-wed", [ "of-christmas-1-wednesday" ]);
+ ("christmas-thu", [ "of-christmas-1-thursday" ]);
+ ("christmas-fri", [ "of-christmas-1-friday" ]);
+ ("christmas-sat", [ "of-christmas-1-saturday" ]);
+ ("christmas-after-epiphany-mon", [ "of-christmas-2-monday" ]);
+ ("christmas-after-epiphany-tue", [ "of-christmas-2-tuesday" ]);
+ ("christmas-after-epiphany-wed", [ "of-christmas-2-wednesday" ]);
+ ("christmas-after-epiphany-thu", [ "of-christmas-2-thursday" ]);
+ ("christmas-after-epiphany-fri", [ "of-christmas-2-friday" ]);
+ ("christmas-after-epiphany-sat", [ "of-christmas-2-saturday" ])
+ ]
+
+(* Deliberately unmapped, with the reason named -- see [named_overrides]'s
+ own comment on the Christmas-season families for the date-vs-weekday
+ mismatch these two groups share:
+
+ - "advent-dec-17".."advent-dec-24": the O-Antiphon days. colitur's own
+ Temporal_of has no per-date slug for late Advent at all (Temporal_ef's
+ EF counterpart doesn't either); these ferias fall through to the
+ ordinary week-numbered "of-advent-{3,4}-<weekday>" slug, and WHICH
+ weekday-string a given December date is varies year to year, so no
+ static base-name mapping is possible. A future task wanting these
+ eight dates covered needs a genuinely date-keyed lookup path in
+ Lectionary_of.readings, not a slug rename here.
+ - "christmas-dec-29/30/31", "christmas-jan-2/3/4/5/6/7": the date-keyed
+ duplicates of the weekday-keyed families already mapped above. Same
+ reasoning, same remedy if ever closed.
+ - "easter-6-thu": Thursday of Easter week 6 is STRUCTURALLY, always,
+ the Ascension (Easter+39 is always a Thursday) -- Temporal_of's own
+ [named] intercepts it before the generic ferial branch ever runs, so
+ "of-easter-6-thursday" is not a slug Temporal_of can ever produce.
+ - "advent-4-sat": the Saturday of Advent week 4 is STRUCTURALLY, always,
+ either 24 December (intercepted by [named]'s own Nativity Vigil
+ branch on every non-Sunday year) or does not exist as a ferial at all
+ (when 24 December is itself the Fourth Sunday of Advent, week 4 has
+ no ferial days whatsoever) -- "of-advent-4-saturday" is not a slug
+ Temporal_of can ever produce either.
+ Both confirmed, not assumed: [assert_reachable]'s own reachability
+ sweep flagged each as a genuine dead key this generator's own pattern
+ rule produced (after fixing the suffix-stripping bug that function's
+ own comment describes, which had masked them under 580 false
+ positives on this generator's first run). *)
+let excluded_bases =
+ [ "advent-dec-17"; "advent-dec-18"; "advent-dec-19"; "advent-dec-20"; "advent-dec-21";
+ "advent-dec-22"; "advent-dec-23"; "advent-dec-24";
+ "christmas-dec-29"; "christmas-dec-30"; "christmas-dec-31";
+ "christmas-jan-2"; "christmas-jan-3"; "christmas-jan-4"; "christmas-jan-5"; "christmas-jan-6";
+ "christmas-jan-7"; "easter-6-thu"; "advent-4-sat" ]
+
+type mapping_report = { mapped : int; excluded : int; unmapped : string list }
+
+(* Resolves every (base, resolved-citations) pair into zero or more
+ (colitur-slug, resolved-citations) pairs, and separately tracks what
+ could not be resolved -- the second half of Step 1's own "measure the
+ gap in both directions" requirement. A sanctoral PASS-THROUGH (lectio's
+ own base name used verbatim as colitur's slug) is verified against the
+ real merged sanctoral layer at generation time, not assumed: an
+ unverified guess would be exactly the silent-drop failure mode this
+ whole task exists to avoid. *)
+let map_bases resolved ~sanctoral_slugs =
+ let unmapped = ref [] in
+ let excluded = ref 0 in
+ let out =
+ List.filter_map
+ (fun (base, r) ->
+ if List.mem base excluded_bases then begin
+ incr excluded;
+ None
+ end
+ else
+ match pattern_match base with
+ | Some slug -> Some (slug, r)
+ | None -> (
+ match List.assoc_opt base named_overrides with
+ | Some [ slug ] -> Some (slug, r)
+ | Some _ -> die "%s: named_overrides entry must name exactly one slug" base
+ | None ->
+ if Hashtbl.mem sanctoral_slugs base then Some (base, r)
+ else begin
+ unmapped := base :: !unmapped;
+ None
+ end))
+ resolved
+ in
+ (out, { mapped = List.length out; excluded = !excluded; unmapped = List.sort compare !unmapped })
+
+(* ---- Emit one Lectionary.t entry per (slug, resolved) pair ---------- *)
+
+let sunday_letter = function `A -> "a" | `B -> "b" | `C -> "c"
+let weekday_letter = function `I -> "i" | `II -> "ii"
+
+let slug_or_die name = match Slug.of_string name with Ok s -> s | Error e -> die "%s" e
+
+let entries_of (slug, r) =
+ match r with
+ | Flat cs -> [ (slug_or_die slug, cs) ]
+ | Sunday_cycle (a, b, c) ->
+ [ (slug_or_die (slug ^ "-" ^ sunday_letter `A), a);
+ (slug_or_die (slug ^ "-" ^ sunday_letter `B), b);
+ (slug_or_die (slug ^ "-" ^ sunday_letter `C), c) ]
+ | Weekday_cycle (i, ii) ->
+ List.filter_map
+ (fun (letter, v) -> Option.map (fun cs -> (slug_or_die (slug ^ "-" ^ weekday_letter letter), cs)) v)
+ [ (`I, i); (`II, ii) ]
+
+(* ---- Real-code reachability, both temporal and sanctoral ------------ *)
+
+(* Same discipline as tools/bootstrap_lectionary.ml's own
+ [reachable_temporal_slugs]/[assert_reachable]: this sweeps
+ Rite_of.Temporal_of.temporal directly over a real civil-day range, so an
+ emitted key naming no real office is a DEAD KEY, caught here rather than
+ shipped silently. 2004-2051 matches the EF generator's own range and
+ for the same reason -- wide enough to enumerate every distinct slug
+ FAMILY (season/week/weekday recur every year; only which year exhibits a
+ given alignment changes), not a claim about the kernel's full
+ 1583-9999 domain, which is this bootstrap tool's business only insofar
+ as [Temporal_of.temporal] itself is already total over it. *)
+let reachable_temporal_slugs () =
+ let tbl = Hashtbl.create 512 in
+ let mk y m d = match Date.make ~year:y ~month:m ~day:d with Ok t -> t | Error e -> die "%s" e in
+ for y = 2004 to 2051 do
+ let d = ref (mk y 1 1) in
+ let stop = mk y 12 31 in
+ while Date.compare !d stop <= 0 do
+ let t = Rite_of.Temporal_of.temporal !d in
+ Hashtbl.replace tbl (Slug.to_string t.Temporal.office.Celebration.slug) true;
+ d := Date.add_days !d 1
+ done
+ done;
+ tbl
+
+(* The merged sanctoral layer -- calendar-2002.sexp plus all 13 decree
+ overlays, the SAME base + amendment set Tasks 1/2 shipped, loaded here
+ read-only, purely to know which slugs are real. A missing/malformed
+ calendar or amendment file is fatal (die), not silently treated as "zero
+ sanctoral slugs", which would make [map_bases]' own pass-through
+ validation vacuously reject every saint. *)
+let amendment_files =
+ [ "001-padre-pio.sexp"; "002-juan-diego-cuauhtlatoatzin.sexp"; "003-our-lady-of-guadalupe.sexp";
+ "004-john-xxiii-john-paul-ii.sexp"; "005-mary-magdalene-rank.sexp";
+ "006-mary-mother-of-the-church.sexp"; "007-paul-vi.sexp"; "008-our-lady-of-loreto.sexp";
+ "009-faustina-kowalska.sexp"; "010-narek-avila-hildegard.sexp"; "011-martha-mary-lazarus.sexp";
+ "012-teresa-of-calcutta.sexp"; "013-john-henry-newman.sexp" ]
+
+let reachable_sanctoral_slugs () =
+ let base_path = "data/of/calendar-2002.sexp" in
+ let amendments_dir = "data/of/amendments/" in
+ let base =
+ match Layer.load Rite_of.Vocab_of.rank_of_sexp base_path with
+ | Ok l -> l
+ | Error e -> die "%s: %s" base_path e
+ in
+ let overlays =
+ List.map
+ (fun name ->
+ let path = amendments_dir ^ name in
+ match Overlay.load Rite_of.Vocab_of.rank_of_sexp path with
+ | Ok o -> o
+ | Error e -> die "%s: %s" path e)
+ amendment_files
+ in
+ let merged, diagnostics = Overlay.merge base overlays in
+ (match diagnostics with
+ | [] -> ()
+ | ds ->
+ die "data/of/amendments: %d diagnostic(s) applying to the base calendar -- \
+ fix the amendment files before bootstrapping the lectionary from them: %s"
+ (List.length ds)
+ (String.concat "; " (List.map Overlay.diagnostic_to_string ds)));
+ let tbl = Hashtbl.create 256 in
+ List.iter (fun (e : _ Layer.entry) -> Hashtbl.replace tbl (Slug.to_string e.Layer.cel.Celebration.slug) true)
+ merged.Layer.entries;
+ tbl
+
+(* [base_and_letter] strips the RAW ini suffixes (-A/-B/-C/-I/-II,
+ uppercase, as lectio itself spells them). The final EMITTED slugs use
+ {!entries_of}'s own lowercase letters (-a/-b/-c/-i/-ii, valid
+ {!Slug.t} characters -- Slug.ml's own [valid_char] rejects uppercase
+ outright), so a distinct stripper is needed here; reusing
+ [base_and_letter] silently matched nothing (a real bug this generator's
+ own first run caught: every emitted key showed up as "dead", 580 of
+ them, because "-a" never matches an uppercase "-A" test). *)
+let strip_emitted_suffix s =
+ List.fold_left
+ (fun acc suf -> match acc with Some _ -> acc | None -> strip_suffix ~suffix:suf s)
+ None [ "-a"; "-b"; "-c"; "-ii"; "-i" ]
+ |> Option.value ~default:s
+
+let assert_reachable entries ~temporal_slugs ~sanctoral_slugs =
+ let base_of s = strip_emitted_suffix (Slug.to_string s) in
+ let dead =
+ List.filter
+ (fun (s, _) ->
+ let b = base_of s in
+ not (Hashtbl.mem temporal_slugs b || Hashtbl.mem sanctoral_slugs b))
+ entries
+ in
+ (match dead with
+ | [] -> ()
+ | _ ->
+ List.iter
+ (fun (s, _) ->
+ Printf.eprintf
+ "bootstrap_lectionary_of: DEAD KEY -- %S is not a real Temporal_of slug (2004-2051) \
+ nor a real sanctoral slug\n"
+ (Slug.to_string s))
+ dead;
+ die "%d emitted key(s) are unreachable (see above)" (List.length dead));
+ let emitted_temporal = Hashtbl.create 512 in
+ List.iter
+ (fun (s, _) ->
+ let b = base_of s in
+ if Hashtbl.mem temporal_slugs b then Hashtbl.replace emitted_temporal b true)
+ entries;
+ let uncovered =
+ Hashtbl.fold (fun s _ acc -> if Hashtbl.mem emitted_temporal s then acc else s :: acc) temporal_slugs []
+ |> List.sort compare
+ in
+ uncovered
+
+(* ---- Coverage measurement, both directions --------------------------- *)
+
+(* Number 1 (temporal-day coverage): over every day of civil year 2026, how
+ many days does Rite_of.Temporal_of.temporal produce a slug this
+ generator never emits an entry for (tried flat, then both cycle-letter
+ suffixes -- exactly the lookup order Lectionary_of.readings itself
+ uses). Those are days with no readings via the temporal-slug path
+ (a sanctoral proper on the same day, if any, is a separate, second
+ chance -- see the generator's own summary printout for that count too). *)
+let temporal_day_gap ~lectionary ~year_start =
+ let mk m d = match Date.make ~year:2026 ~month:m ~day:d with Ok t -> t | Error e -> die "%s" e in
+ let count = ref 0 and total = ref 0 and misses = ref [] in
+ for m = 1 to 12 do
+ let days_in_month = match m with
+ | 1 | 3 | 5 | 7 | 8 | 10 | 12 -> 31 | 4 | 6 | 9 | 11 -> 30 | 2 -> 28 | _ -> assert false
+ in
+ for d = 1 to days_in_month do
+ incr total;
+ let date = mk m d in
+ let t = Rite_of.Temporal_of.temporal date in
+ let base = Slug.to_string t.Temporal.office.Celebration.slug in
+ let found =
+ Lectionary.mem lectionary (slug_or_die base)
+ || Lectionary.mem lectionary
+ (slug_or_die
+ (base ^ "-"
+ ^ Rite_of.Lectionary_of.sunday_cycle_letter (Rite_of.Lectionary_of.sunday_cycle ~year_start date)))
+ || Lectionary.mem lectionary
+ (slug_or_die
+ (base ^ "-"
+ ^ Rite_of.Lectionary_of.weekday_cycle_letter
+ (Rite_of.Lectionary_of.weekday_cycle ~year_start date)))
+ in
+ if not found then begin
+ incr count;
+ misses := (Date.to_iso8601 date, base) :: !misses
+ end
+ done
+ done;
+ (!count, !total, List.rev !misses)
+
+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
+ ignore (Unix.close_process_in ic);
+ List.hd (String.split_on_char ' ' line)
+
+let () =
+ let src = if Array.length Sys.argv > 1 then Sys.argv.(1) else default_source in
+ let dst = if Array.length Sys.argv > 2 then Sys.argv.(2) else default_dest in
+ let secs = parse_ini src in
+ let resolved = resolve_sections secs in
+ let sanctoral_slugs = reachable_sanctoral_slugs () in
+ let mapped, report = map_bases resolved ~sanctoral_slugs in
+ let entries = List.concat_map entries_of mapped in
+ let temporal_slugs = reachable_temporal_slugs () in
+ let uncovered_temporal = assert_reachable entries ~temporal_slugs ~sanctoral_slugs in
+ let lect = match Lectionary.of_entries entries with Ok l -> l | Error e -> die "%s" e in
+ let gap_count, gap_total, gap_misses =
+ temporal_day_gap ~lectionary:lect ~year_start:Rite_of.Temporal_of.year_start
+ in
+ let oc = open_out dst in
+ Printf.fprintf oc
+ "; data/of/lectionary.sexp -- OF (2002) temporal + sanctoral lectionary\n\
+ ; (Epistle + Gospel citations, never scripture text), bootstrapped from\n\
+ ; lectio.\n\
+ ;\n\
+ ; LINEAGE, stated loudly because it constrains what this file can show\n\
+ ; (design spec 2026-08-24-colitur-of-rite-module-design.md sec4.4/sec5):\n\
+ ; this is a POLISH VERNACULAR pastoral lectionary (niedziela.pl,\n\
+ ; harvested 2020-2025 by lectio's own scripts/genlect-of.go), NOT the\n\
+ ; Latin OLM (Ordo Lectionum Missae) 1981 itself, and its citations are\n\
+ ; ENGLISH-CANONICAL, not OLM's Vulgate numbering. It CANNOT show any\n\
+ ; divergence between niedziela.pl's own pastoral choices and OLM's own\n\
+ ; text -- three such divergences are already confirmed against the real\n\
+ ; OLM page images (design spec sec4.4): Holy Family Year A's second-\n\
+ ; reading short form, Trinity Sunday's Dan 3:56, and the Baptism of the\n\
+ ; Lord's Mc 9:6 vs \"Mark 9:7\". Nor can it show OLM's short/long-form\n\
+ ; reading alternatives, which niedziela.pl does not distinguish. This is\n\
+ ; ALSO a SEPARATE lineage from lectio's own OF CALENDAR data\n\
+ ; (data/of/calendar-2002.sexp, roman-calendar.ini, upstream\n\
+ ; calapi.inadiutorium.cz) -- lectio is two unrelated upstreams glued\n\
+ ; together by one downstream project, not one witness, and neither is\n\
+ ; the typical edition.\n\
+ ;\n\
+ ; Generator: tools/bootstrap_lectionary_of.ml -- do not hand-edit;\n\
+ ; re-run against the same lectio snapshot (its SHA-256 is pinned below;\n\
+ ; a MISSING source file is fatal, checked before any read is attempted --\n\
+ ; see this generator's own [parse_ini]) and commit the diff instead.\n\
+ ; Every emitted key is asserted, at generation time, to be a slug\n\
+ ; Rite_of.Temporal_of actually computes OR a slug the real merged\n\
+ ; sanctoral layer (data/of/calendar-2002.sexp + all 13 decree overlays)\n\
+ ; actually carries -- see [assert_reachable].\n\
+ ;\n\
+ ; Source: %s\n\
+ ; SHA-256: %s\n\
+ ; %d ini sections (988 expected) -> %d resolved (base, cycle-shape) \
+pairs -> %d colitur slugs mapped, %d ini bases deliberately excluded (date-\n\
+ ; keyed duplicates/late-Advent, no colitur date-keyed lookup exists --\n\
+ ; see [excluded_bases]), %d ini bases genuinely unmapped (no pattern, no\n\
+ ; override, no matching sanctoral slug) -> %d emitted lectionary entries.\n\
+ ;\n\
+ ; COVERAGE, BOTH DIRECTIONS (Step 1 of this task's own brief):\n\
+ ; (1) Temporal-day gap: of the %d days of civil year 2026, %d produce a\n\
+ ; Rite_of.Temporal_of slug with NO entry in this file (tried flat,\n\
+ ; then both the Sunday- and weekday-cycle letter suffixes -- the\n\
+ ; same order Lectionary_of.readings itself tries). Those are days\n\
+ ; with no readings via the temporal-slug path (a sanctoral proper\n\
+ ; on the same civil day, where one exists, is Lectionary_of's own\n\
+ ; separate first chance). Named set below.\n\
+ ; (2) Unmapped lectio keys: %d ini base names (of 988 sections, %d\n\
+ ; distinct bases) map to no colitur slug at all -- data being\n\
+ ; silently dropped if unreported. 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) 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 "; 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);
+ List.iter (fun s -> Printf.fprintf oc "; %s\n" s) uncovered_temporal;
+ Sexplib.Sexp.output_hum oc (Lectionary.sexp_of_t lect);
+ output_char oc '\n';
+ close_out oc;
+ Printf.printf "bootstrap_lectionary_of: %d entries -> %s\n" (List.length entries) dst;
+ Printf.printf "bootstrap_lectionary_of: coverage gap 1 (temporal days, 2026): %d/%d\n" gap_count gap_total;
+ Printf.printf "bootstrap_lectionary_of: coverage gap 2 (unmapped lectio bases): %d\n"
+ (List.length report.unmapped);
+ ignore gap_misses
diff --git a/tools/dune b/tools/dune
index 9a4dea5..40e9836 100644
--- a/tools/dune
+++ b/tools/dune
@@ -23,6 +23,21 @@
(name bootstrap_lectionary)
(libraries colitur_kernel rite_ef unix sexplib))
+; Task 4 (2026-08-25-colitur-of-phases-3-5): converts lectio's
+; of-lectionary.ini into data/of/lectionary.sexp. Run via `dune exec
+; tools/bootstrap_lectionary_of.exe -- <source.ini> <dest.sexp>`. Same
+; `unix`-for-`sha256sum` usage as bootstrap_lectionary.ml above; `rite_of`
+; for the identical "code, not data" reason bootstrap_lectionary.ml links
+; `rite_ef` -- [assert_reachable] sweeps Rite_of.Temporal_of.temporal AND
+; the real merged sanctoral layer directly, so a mapping-table typo cannot
+; ship a dead key silently. Runs from the repo root (its own [reachable_
+; sanctoral_slugs] reads data/of/calendar-2002.sexp and data/of/amendments/
+; by a repo-root-relative path, unlike bootstrap_lectionary.ml's own
+; source/dest arguments, which are caller-supplied).
+(executable
+ (name bootstrap_lectionary_of)
+ (libraries colitur_kernel rite_of unix sexplib))
+
; Task 6 (2026-08-21-colitur-celebrant-rubrics-phase1): turns pdftotext's
; -layout dump of the Latin Mass Society Ordo into test/fixtures/
; lms-ordo-2024-2025.sexp. Run via `dune exec tools/extract_lms_ordo.exe --