diff options
| -rw-r--r-- | data/of/lectionary.sexp | 2317 | ||||
| -rw-r--r-- | lib/rites/rite_of/lectionary_of.ml | 107 | ||||
| -rw-r--r-- | lib/rites/rite_of/lectionary_of.mli | 136 | ||||
| -rw-r--r-- | test/dune | 2 | ||||
| -rw-r--r-- | test/test_colitur.ml | 1 | ||||
| -rw-r--r-- | test/test_lectionary_of.ml | 372 | ||||
| -rw-r--r-- | tools/bootstrap_lectionary_of.ml | 827 | ||||
| -rw-r--r-- | tools/dune | 15 |
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 @@ -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 @@ -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 -- |
