summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-07-28 07:51:05 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-07-28 07:51:05 +0200
commit1f694889f767dedd84f60d8e0cbccf201c2d123f (patch)
tree0b8e85a1cf9dbce5f75a6ded538146ca8f1f389b
parentcca0eb0db6cf6850d55d7a44fef470c594bce8ec (diff)
downloadlectio-1f694889f767dedd84f60d8e0cbccf201c2d123f.tar.gz
lectio-1f694889f767dedd84f60d8e0cbccf201c2d123f.zip
feat(ef): full 1962 universal sanctoral (16 -> 317 celebrations)
Generate internal/caldata/tridentine-calendar.ini from missalemeum's per-date proper API (Divinum Officium 1962 data) via scripts/gen-sanctoral-ef.go: each fixed date's observed saint with rank, colour, English name and proper Epistle/Gospel citations, plus sancti commemorations. Multiple reference years are tried per date so a saint occulted by a Sunday in one year is still captured observed in another; saints never observed are ranked commemoration. Feasts of the Lord are marked class=lord. Latin names hand-curated (missalemeum has none). Adds TestTridentineLoads, credits missalemeum in NOTICE, bumps to 0.38.0.
-rw-r--r--NOTICE9
-rw-r--r--internal/caldata/caldata_test.go41
-rw-r--r--internal/caldata/tridentine-calendar.ini2336
-rw-r--r--internal/config/config.go2
-rwxr-xr-xscripts/build-oracle-ef.sh4
-rw-r--r--scripts/gen-sanctoral-ef.go402
6 files changed, 2712 insertions, 82 deletions
diff --git a/NOTICE b/NOTICE
index 4240624..f2c47c1 100644
--- a/NOTICE
+++ b/NOTICE
@@ -13,9 +13,12 @@ romcal — Copyright (c) romcal contributors — MIT License.
Extraordinary Form (1962) calendar data
---------------------------------------
-The 1962 calendar data in internal/caldata/tridentine-calendar.ini was
-bootstrapped with reference to Divinum Officium (https://divinumofficium.com)
-and the Missal1962 / tridentine_calendar projects, and is lectio's own.
+The 1962 universal sanctoral in internal/caldata/tridentine-calendar.ini was
+generated (scripts/gen-sanctoral-ef.go) from missalemeum.com's per-date proper
+API, which is built on Divinum Officium (https://divinumofficium.com) 1962 data
+-- English names, rank, colour, and the proper Epistle/Gospel CITATIONS (not the
+reading text). Latin names are lectio's own hand-curation. The data as committed
+is lectio's, may be freely hand-edited, and carries no upstream licence.
Lectionary data (reading citations)
-----------------------------------
diff --git a/internal/caldata/caldata_test.go b/internal/caldata/caldata_test.go
index 12aed8c..5ffa57e 100644
--- a/internal/caldata/caldata_test.go
+++ b/internal/caldata/caldata_test.go
@@ -29,3 +29,44 @@ func TestUniversalLoads(t *testing.T) {
}
}
}
+
+func TestTridentineLoads(t *testing.T) {
+ l := Tridentine()
+ if l.ID != "tridentine" {
+ t.Fatalf("layer id = %q", l.ID)
+ }
+ // The full 1962 sanctoral is populated (generated from missalemeum), not the
+ // 16-entry bootstrap.
+ if len(l.Cels) < 250 {
+ t.Fatalf("EF sanctoral has only %d entries; expected the full calendar", len(l.Cels))
+ }
+ // Landmark feasts must be present with the right rank/class: Sts Peter & Paul
+ // (I class, 06-29), the Purification/Presentation (a II class feast of the
+ // Lord, 02-02, which must displace a Sunday), the Immaculate Conception
+ // (I class, 12-08).
+ want := map[string]struct{ date, rank, class string }{
+ "sts-peter-paul": {"06-29", "class-1", ""},
+ "purification-of-the-blessed-virgin-mary": {"02-02", "class-2", "lord"},
+ "immaculate-conception-of-the-blessed-virgin-mary": {"12-08", "class-1", ""},
+ }
+ for slug, w := range want {
+ rc, ok := l.Cels[slug]
+ if !ok {
+ t.Errorf("missing landmark feast %q", slug)
+ continue
+ }
+ if rc.Fields["date"] != w.date || rc.Fields["rank"] != w.rank {
+ t.Errorf("%s: date/rank = %q/%q, want %q/%q", slug, rc.Fields["date"], rc.Fields["rank"], w.date, w.rank)
+ }
+ if w.class != "" && rc.Fields["class"] != w.class {
+ t.Errorf("%s: class = %q, want %q", slug, rc.Fields["class"], w.class)
+ }
+ }
+ // every entry must build into a typed Celebration whose rank parsed.
+ for slug, rc := range l.Cels {
+ c := calendar.BuildCelebrationForTest(slug, rc)
+ if c.Rank == calendar.RankFerial && rc.Fields["rank"] != "" {
+ t.Errorf("%s: rank did not parse (%q)", slug, rc.Fields["rank"])
+ }
+ }
+}
diff --git a/internal/caldata/tridentine-calendar.ini b/internal/caldata/tridentine-calendar.ini
index 30951bb..aaa9841 100644
--- a/internal/caldata/tridentine-calendar.ini
+++ b/internal/caldata/tridentine-calendar.ini
@@ -2,141 +2,2325 @@
; The temporal cycle (seasons, Sundays, Easter/Christmas/Epiphany, Ascension,
; Pentecost, Trinity, Corpus Christi, Sacred Heart, Christ the King) is computed
; by internal/calendar (temporalEF) and is NOT listed here.
-; Ranks use the 1960 Code of Rubrics: class-1..class-4 + commemoration.
-; INITIAL coverage; ranks/membership refined against the missalemeum oracle.
-; Bootstrapped with reference to Divinum Officium / Missal1962 — see NOTICE.
+; Ranks use the 1960 Code of Rubrics: class-1..class-4.
+; Generated by scripts/gen-sanctoral-ef.go from missalemeum (Divinum Officium 1962
+; data). Latin names are hand-curated where present. See NOTICE.
[layer]
id = tridentine
name = General Roman Calendar of 1962
type = universal
-; --- I class ---
+[telesphorus-pope-and-martyr]
+date = 01-05
+rank = commemoration
+colour = red
+name.en = St. Telesphorus Pope and Martyr
-[immaculate-conception]
-reading.first = Prov 8:22-35
-reading.gospel = Luke 1:26-28
-date = 12-08
-rank = class-1
+[hyginus-pope-and-martyr]
+date = 01-11
+rank = commemoration
+colour = red
+name.en = St. Hyginus Pope and Martyr
+
+[commemoration-of-the-baptism-of-the-lord]
+date = 01-13
+rank = class-2
colour = white
-name.en = The Immaculate Conception of the Blessed Virgin Mary
-name.la = In Conceptione Immaculata Beatae Mariae Virginis
+name.en = Commemoration of the Baptism of the Lord
+reading.first = Isa 60:1-6
+reading.gospel = John 1:29-34
-[st-joseph]
-reading.first = Sir 45:1-6
-reading.gospel = Matt 1:18-21
+[felicis]
+date = 01-14
+rank = commemoration
+colour = red
+name.en = S. Felicis
+
+[hilary]
+date = 01-14
+rank = class-3
+colour = white
+name.en = St. Hilary
+reading.first = 2 Tim 4:1-8
+reading.gospel = Matt 5:13-19
+
+[maur-abbot]
+date = 01-15
+rank = commemoration
+colour = white
+name.en = St. Maur, Abbot
+
+[paul-the-first-hermit]
+date = 01-15
+rank = class-3
+colour = white
+name.en = St. Paul, the First Hermit
+reading.first = Phil 3:7-12
+reading.gospel = Matt 11:25-30
+
+[marcellus-i]
+date = 01-16
+rank = class-3
+colour = red
+name.en = St. Marcellus I
+reading.first = 1 Pet 5:1-4; 5:10-11.
+reading.gospel = Matt 16:13-19
+
+[anthony]
+date = 01-17
+rank = class-3
+colour = white
+name.en = St. Anthony
+reading.first = Ecclus 45:1-6
+reading.gospel = Luke 12:35-40
+
+[prisca]
+date = 01-18
+rank = commemoration
+colour = white
+name.en = St. Prisca
+
+[canute-martyr]
+date = 01-19
+rank = commemoration
+colour = red
+name.en = St. Canute, Martyr
+
+[sts-marius-martha-audifax-abachum]
+date = 01-19
+rank = commemoration
+colour = red
+name.en = Sts. Marius, Martha, Audifax & Abachum
+
+[sts-fabian-sebastian]
+date = 01-20
+rank = class-3
+colour = red
+name.en = Sts. Fabian & Sebastian
+reading.first = Heb 11:33-39
+reading.gospel = Luke 6:17-23
+
+[agnes]
+date = 01-21
+rank = class-3
+colour = red
+name.en = St. Agnes
+reading.first = Sir 51:1-8; 51:12
+reading.gospel = Matt 25:1-13.
+
+[sts-vincent-anastasius]
+date = 01-22
+rank = class-3
+colour = red
+name.en = Sts. Vincent & Anastasius
+reading.first = Wis 3:1-8
+reading.gospel = Luke 21:9-19
+
+[emerentiana]
+date = 01-23
+rank = commemoration
+colour = red
+name.en = St. Emerentiana
+
+[raymond-of-pe-afort]
+date = 01-23
+rank = class-3
+colour = white
+name.en = St. Raymond of Peñafort
+reading.first = Sir 31:8-11
+reading.gospel = Luke 12:35-40
+
+[timothy]
+date = 01-24
+rank = class-3
+colour = red
+name.en = St. Timothy
+reading.first = 1 Tim. 6:11-16
+reading.gospel = Luke 14:26-33.
+
+[conversion-of-st-paul]
+date = 01-25
+rank = class-3
+colour = white
+name.en = Conversion of St. Paul
+reading.first = Acts 9:1-22
+reading.gospel = Matt 19:27-29.
+
+[peter]
+date = 01-25
+rank = commemoration
+colour = white
+name.en = St. Peter
+
+[polycarp]
+date = 01-26
+rank = class-3
+colour = red
+name.en = St. Polycarp
+reading.first = 1 John 3:10-16
+reading.gospel = Matt 10:26-32.
+
+[john-chrysostom]
+date = 01-27
+rank = class-3
+colour = white
+name.en = St. John Chrysostom
+reading.first = 2 Tim 4:1-8
+reading.gospel = Matt 5:13-19
+
+[peter-nolasco]
+date = 01-28
+rank = class-3
+colour = white
+name.en = St. Peter Nolasco
+reading.first = 1 Cor. 4:9-14
+reading.gospel = Luke 12:32-34
+
+[francis-de-sales]
+date = 01-29
+rank = class-3
+colour = white
+name.en = St. Francis de Sales
+reading.first = 2 Tim 4:1-8
+reading.gospel = Matt 5:13-19
+
+[martina]
+date = 01-30
+rank = class-3
+colour = red
+name.en = St. Martina
+reading.first = Sir 51:1-8; 51:12
+reading.gospel = Matt 25:1-13.
+
+[john-bosco]
+date = 01-31
+rank = class-3
+colour = white
+name.en = St. John Bosco
+reading.first = Phil 4:4-9
+reading.gospel = Matt 18:1-5
+
+[ignatius-of-antioch]
+date = 02-01
+rank = class-3
+colour = red
+name.en = St. Ignatius of Antioch
+reading.first = Rom 8:35-39
+reading.gospel = John 12:24-26
+
+[purification-of-the-blessed-virgin-mary]
+date = 02-02
+rank = class-2
+colour = white
+class = lord
+name.en = Purification of the Blessed Virgin Mary
+reading.first = Mal 3:1-4
+reading.gospel = Luke 2:22-32
+
+[blaise]
+date = 02-03
+rank = commemoration
+colour = red
+name.en = St. Blaise
+
+[andrew-corsini]
+date = 02-04
+rank = class-3
+colour = white
+name.en = St. Andrew Corsini
+reading.first = Sir 44:16-27; 45:3-20
+reading.gospel = Matt 25:14-23
+
+[agatha]
+date = 02-05
+rank = class-3
+colour = red
+name.en = St. Agatha
+reading.first = 1 Cor. 1:26-31
+reading.gospel = Matt 19:3-12.
+
+[dorothy]
+date = 02-06
+rank = commemoration
+colour = red
+name.en = St. Dorothy
+
+[titus]
+date = 02-06
+rank = class-3
+colour = white
+name.en = St. Titus
+reading.first = Sir 44:16-27; 45:3-20
+reading.gospel = Luke 10:1-9
+
+[romuald]
+date = 02-07
+rank = class-3
+colour = white
+name.en = St. Romuald
+reading.first = Ecclus 45:1-6
+reading.gospel = Matt 19:27-29.
+
+[john-of-matha]
+date = 02-08
+rank = class-3
+colour = white
+name.en = St. John of Matha
+reading.first = Sir 31:8-11
+reading.gospel = Luke 12:35-40
+
+[appollonia]
+date = 02-09
+rank = commemoration
+colour = red
+name.en = St. Appollonia
+
+[cyril-of-alexandria]
+date = 02-09
+rank = class-3
+colour = white
+name.en = St. Cyril of Alexandria
+reading.first = 2 Tim 4:1-8
+reading.gospel = Matt 5:13-19
+
+[scholastica]
+date = 02-10
+rank = class-3
+colour = white
+name.en = St. Scholastica
+reading.first = 2 Cor 10:17-18; 11:1-2
+reading.gospel = Matt 25:1-13.
+
+[our-lady-of-lourdes]
+date = 02-11
+rank = class-3
+colour = white
+name.en = Our Lady of Lourdes
+reading.first = Apoc 11:19; 12:1, 10
+reading.gospel = Luke 1:26-31.
+
+[seven-holy-servite-founders]
+date = 02-12
+rank = class-3
+colour = white
+name.en = Seven Holy Servite Founders
+reading.first = Ecclus 44:1-15
+reading.gospel = Matt 19:27-29.
+
+[valentine]
+date = 02-14
+rank = commemoration
+colour = red
+name.en = St. Valentine
+
+[sts-faustinus-jovita]
+date = 02-15
+rank = commemoration
+colour = red
+name.en = Sts. Faustinus & Jovita
+
+[simeon]
+date = 02-18
+rank = commemoration
+colour = red
+name.en = St. Simeon
+
+[chair-of-st-peter]
+date = 02-22
+rank = class-2
+colour = white
+name.en = Chair of St. Peter
+reading.first = 1 Pet 1:1-7
+reading.gospel = Matt 16:13-19
+
+[paul]
+date = 02-22
+rank = commemoration
+colour = red
+name.en = St. Paul
+
+[peter-damien]
+date = 02-23
+rank = class-3
+colour = white
+name.en = St. Peter Damien
+reading.first = 2 Tim 4:1-8
+reading.gospel = Matt 5:13-19
+
+[matthias]
+date = 02-24
+rank = class-2
+colour = red
+name.en = St. Matthias
+reading.first = Acts 1:15-26
+reading.gospel = Matt 11:25-30
+
+[gabriel-of-our-lady-of-sorrows]
+date = 02-27
+rank = class-3
+colour = white
+name.en = St. Gabriel of Our Lady of Sorrows
+reading.first = 1 John 2:14-17
+reading.gospel = Mark 10:13-21
+
+[casimir]
+date = 03-04
+rank = class-3
+colour = white
+name.en = St. Casimir
+reading.first = Sir 31:8-11
+reading.gospel = Luke 12:35-40
+
+[lucius]
+date = 03-04
+rank = commemoration
+colour = red
+name.en = St. Lucius
+
+[sts-felicitas-perpetua]
+date = 03-06
+rank = commemoration
+colour = red
+name.en = Sts. Felicitas & Perpetua
+
+[thomas-aquinas]
+date = 03-07
+rank = commemoration
+colour = white
+name.en = St. Thomas Aquinas
+
+[john-of-god]
+date = 03-08
+rank = commemoration
+colour = white
+name.en = St. John of God
+
+[frances-rome]
+date = 03-09
+rank = commemoration
+colour = white
+name.en = St. Frances Rome
+
+[forty-holy-martyrs-of-sebaste]
+date = 03-10
+rank = commemoration
+colour = red
+name.en = Forty Holy Martyrs of Sebaste
+
+[gregory-the-great]
+date = 03-12
+rank = commemoration
+colour = white
+name.en = St. Gregory the Great
+
+[patrick]
+date = 03-17
+rank = commemoration
+colour = white
+name.en = St. Patrick
+
+[cyril-of-jerusalem]
+date = 03-18
+rank = commemoration
+colour = white
+name.en = St. Cyril of Jerusalem
+
+[joseph-spouse-of-the-bl-virgin-mary]
date = 03-19
rank = class-1
colour = white
-name.en = Saint Joseph, Spouse of the Blessed Virgin Mary
-name.la = Sancti Joseph Sponsi Beatae Mariae Virginis
+name.en = St. Joseph, Spouse of the Bl. Virgin Mary
+reading.first = Ecclus 45:1-6
+reading.gospel = Matt 1:18-21
+
+[benedict]
+date = 03-21
+rank = commemoration
+colour = white
+name.en = St. Benedict
+
+[gabriel-the-archangel]
+date = 03-24
+rank = commemoration
+colour = white
+name.en = St. Gabriel the Archangel
-[annunciation]
+[annunciation-of-the-blessed-virgin-mary]
+date = 03-25
+rank = class-1
+colour = white
+name.en = Annunciation of the Blessed Virgin Mary
reading.first = Isa 7:10-15
reading.gospel = Luke 1:26-38
-date = 03-25
+
+[john-damascene]
+date = 03-27
+rank = commemoration
+colour = white
+name.en = St. John Damascene
+
+[john-of-capistrano]
+date = 03-28
+rank = commemoration
+colour = white
+name.en = St. John of Capistrano
+
+[francis-of-paola]
+date = 04-02
+rank = commemoration
+colour = white
+name.en = St. Francis of Paola
+
+[isidore-of-seville]
+date = 04-04
+rank = commemoration
+colour = white
+name.en = St. Isidore of Seville
+
+[vincent-ferrer]
+date = 04-05
+rank = commemoration
+colour = white
+name.en = St. Vincent Ferrer
+
+[leo-the-great]
+date = 04-11
+rank = class-3
+colour = white
+name.en = St. Leo the Great
+reading.first = 1 Pet 5:1-4; 5:10-11.
+reading.gospel = Matt 16:13-19
+
+[hermenegild]
+date = 04-13
+rank = class-3
+colour = red
+name.en = St. Hermenegild
+reading.first = Wis 10:10-14
+reading.gospel = Luke 14:26-33.
+
+[justin]
+date = 04-14
+rank = class-3
+colour = red
+name.en = St. Justin
+reading.first = 1 Cor 1:18-25; 1:30;
+reading.gospel = Luke 12:2-8
+
+[sts-tiburtius-valerian-et-maximus-martyrs]
+date = 04-14
+rank = commemoration
+colour = red
+name.en = Sts. Tiburtius, Valerian et Maximus, Martyrs
+
+[anicetus]
+date = 04-17
+rank = commemoration
+colour = red
+name.en = St. Anicetus
+
+[anselm]
+date = 04-21
+rank = class-3
+colour = white
+name.en = St. Anselm
+reading.first = 2 Tim 4:1-8
+reading.gospel = Matt 5:13-19
+
+[sts-soter-caius]
+date = 04-22
+rank = class-3
+colour = red
+name.en = Sts. Soter & Caius
+reading.first = 1 Pet 5:1-4; 5:10-11.
+reading.gospel = Matt 16:13-19
+
+[george]
+date = 04-23
+rank = commemoration
+colour = red
+name.en = St. George
+
+[fidelis-of-sigmaringen]
+date = 04-24
+rank = class-3
+colour = red
+name.en = St. Fidelis of Sigmaringen
+reading.first = Wis 5:1-5
+reading.gospel = John 15:1-7
+
+[mark]
+date = 04-25
+rank = class-2
+colour = red
+name.en = St. Mark
+reading.first = Ezek 1:10-14
+reading.gospel = Luke 10:1-9
+
+[sts-cletus-marcellinus]
+date = 04-26
+rank = class-3
+colour = red
+name.en = Sts. Cletus & Marcellinus
+reading.first = 1 Pet 5:1-4; 5:10-11.
+reading.gospel = Matt 16:13-19
+
+[peter-canisius]
+date = 04-27
+rank = class-3
+colour = white
+name.en = St. Peter Canisius
+reading.first = 2 Tim 4:1-8
+reading.gospel = Matt 5:13-19
+
+[paul-of-the-cross]
+date = 04-28
+rank = class-3
+colour = white
+name.en = St. Paul of the Cross
+reading.first = 1 Cor 1:17-25.
+reading.gospel = Luke 10:1-9
+
+[peter-of-verona]
+date = 04-29
+rank = class-3
+colour = red
+name.en = St. Peter of Verona
+reading.first = 2 Tim. 2:8-10; 3:10-12.
+reading.gospel = Matt 10:34-42
+
+[catherine-of-siena]
+date = 04-30
+rank = class-3
+colour = white
+name.en = St. Catherine of Siena
+reading.first = 2 Cor 10:17-18; 11:1-2
+reading.gospel = Matt 25:1-13.
+
+[joseph-the-workman]
+date = 05-01
rank = class-1
colour = white
-name.en = The Annunciation of the Blessed Virgin Mary
-name.la = In Annuntiatione Beatae Mariae Virginis
+name.en = St. Joseph the Workman
+reading.first = Col. 3:14-15, 17, 23-24
+reading.gospel = Matt 13:54-58
-[nativity-john-baptist]
-reading.first = Isa 49:1-3,5-7
-reading.gospel = Luke 1:57-68
+[athanasius]
+date = 05-02
+rank = class-3
+colour = white
+name.en = St. Athanasius
+reading.first = 2 Cor. 4:5-14
+reading.gospel = Matt 10:23-28
+
+[sts-alexander-companions]
+date = 05-03
+rank = commemoration
+colour = red
+name.en = Sts. Alexander & Companions
+
+[monica]
+date = 05-04
+rank = class-3
+colour = white
+name.en = St. Monica
+reading.first = 1 Tim. 5:3-10.
+reading.gospel = Luke 7:11-16
+
+[pius-v]
+date = 05-05
+rank = class-3
+colour = white
+name.en = St. Pius V
+reading.first = 1 Pet 5:1-4; 5:10-11.
+reading.gospel = Matt 16:13-19
+
+[stanislaus]
+date = 05-07
+rank = class-3
+colour = red
+name.en = St. Stanislaus
+reading.first = Wis 5:1-5
+reading.gospel = John 15:1-7
+
+[gregory-of-nazianzen]
+date = 05-09
+rank = class-3
+colour = white
+name.en = St. Gregory of Nazianzen
+reading.first = Ecclus 39:6-14
+reading.gospel = Matt 5:13-19
+
+[antoninus]
+date = 05-10
+rank = class-3
+colour = white
+name.en = St. Antoninus
+reading.first = Sir 44:16-27; 45:3-20
+reading.gospel = Matt 25:14-23
+
+[gordiano-and-epimacho]
+date = 05-10
+rank = commemoration
+colour = red
+name.en = St. Gordiano and Epimacho
+
+[sts-philip-james]
+date = 05-11
+rank = class-2
+colour = red
+name.en = Sts. Philip & James
+reading.first = Wis. 5:1-5
+reading.gospel = John 14:1-13
+
+[sts-nereus-achilleus-domitilla-pancras]
+date = 05-12
+rank = class-3
+colour = red
+name.en = Sts. Nereus, Achilleus, Domitilla, & Pancras
+reading.first = Wis. 5:1-5
+reading.gospel = John 4:46-53
+
+[robert-bellarmine]
+date = 05-13
+rank = class-3
+colour = white
+name.en = St. Robert Bellarmine
+reading.first = Wis 7:7-14.
+reading.gospel = Matt 5:13-19
+
+[john-baptist-de-la-salle]
+date = 05-15
+rank = class-3
+colour = white
+name.en = St. John Baptist de la Salle
+reading.first = Sir 31:8-11
+reading.gospel = Matt 18:1-5
+
+[ubaldus]
+date = 05-16
+rank = commemoration
+colour = white
+name.en = St. Ubaldus
+
+[paschal-baylon]
+date = 05-17
+rank = class-3
+colour = white
+name.en = St. Paschal Baylon
+reading.first = Sir 31:8-11
+reading.gospel = Luke 12:35-40
+
+[venantius]
+date = 05-18
+rank = class-3
+colour = red
+name.en = St. Venantius
+reading.first = Wis 5:1-5
+reading.gospel = John 15:1-7
+
+[peter-celestine]
+date = 05-19
+rank = class-3
+colour = white
+name.en = St. Peter Celestine
+reading.first = 1 Pet 5:1-4; 5:10-11.
+reading.gospel = Matt 16:13-19
+
+[pudentiana-virginis]
+date = 05-19
+rank = commemoration
+colour = white
+name.en = St. Pudentiana Virginis
+
+[bernardine-of-siena]
+date = 05-20
+rank = class-3
+colour = white
+name.en = St. Bernardine of Siena
+reading.first = Sir 31:8-11
+reading.gospel = Matt 19:27-29.
+
+[gregory-vii]
+date = 05-25
+rank = class-3
+colour = white
+name.en = St. Gregory VII
+reading.first = 1 Pet 5:1-4; 5:10-11.
+reading.gospel = Matt 16:13-19
+
+[urban-pope-and-martyr]
+date = 05-25
+rank = commemoration
+colour = red
+name.en = St. Urban, Pope and Martyr
+
+[eleutherius]
+date = 05-26
+rank = commemoration
+colour = red
+name.en = S. Eleutherius
+
+[philip-neri]
+date = 05-26
+rank = class-3
+colour = white
+name.en = St. Philip Neri
+reading.first = Wis 7:7-14.
+reading.gospel = Luke 12:35-40
+
+[bede-the-venerable]
+date = 05-27
+rank = class-3
+colour = white
+name.en = St. Bede the Venerable
+reading.first = 2 Tim 4:1-8
+reading.gospel = Matt 5:13-19
+
+[john-i]
+date = 05-27
+rank = commemoration
+colour = red
+name.en = St. John I
+
+[augustine-of-canterbury]
+date = 05-28
+rank = class-3
+colour = white
+name.en = St. Augustine of Canterbury
+reading.first = 1 Thess 2:2-9
+reading.gospel = Luke 10:1-9
+
+[mary-magdalene-de-pazzi]
+date = 05-29
+rank = class-3
+colour = white
+name.en = St. Mary Magdalene de Pazzi
+reading.first = 2 Cor 10:17-18; 11:1-2
+reading.gospel = Matt 25:1-13.
+
+[felix-i]
+date = 05-30
+rank = commemoration
+colour = red
+name.en = St. Felix I
+
+[petronilla]
+date = 05-31
+rank = commemoration
+colour = white
+name.en = St. Petronilla
+
+[queenship-of-the-blessed-virgin-mary]
+date = 05-31
+rank = class-2
+colour = white
+name.en = Queenship of the Blessed Virgin Mary
+reading.first = Eccli 24:5; 14:7; 14:9-11; 24:30-31
+reading.gospel = Luke 1:26-33
+
+[angela-merici]
+date = 06-01
+rank = class-3
+colour = white
+name.en = St. Angela Merici
+reading.first = 2 Cor 10:17-18; 11:1-2
+reading.gospel = Matt 25:1-13.
+
+[sts-marcellinus-peter-erasmus]
+date = 06-02
+rank = commemoration
+colour = red
+name.en = Sts. Marcellinus, Peter, & Erasmus
+
+[francis-caracciolo]
+date = 06-04
+rank = class-3
+colour = white
+name.en = St. Francis Caracciolo
+reading.first = Wis. 4:7-14.
+reading.gospel = Luke 12:35-40
+
+[boniface]
+date = 06-05
+rank = class-3
+colour = red
+name.en = St. Boniface
+reading.first = Ecclus 44:1-15
+reading.gospel = Matt 5:1-12
+
+[norbert]
+date = 06-06
+rank = class-3
+colour = white
+name.en = St. Norbert
+reading.first = Sir 44:16-27; 45:3-20
+reading.gospel = Matt 25:14-23
+
+[sts-primus-felicianus]
+date = 06-09
+rank = commemoration
+colour = red
+name.en = Sts. Primus & Felicianus
+
+[margaret-of-scotland]
+date = 06-10
+rank = class-3
+colour = white
+name.en = St. Margaret of Scotland
+reading.first = Prov 31:10-31
+reading.gospel = Matt 13:44-52.
+
+[barnabas]
+date = 06-11
+rank = class-3
+colour = red
+name.en = St. Barnabas
+reading.first = Acts 11:21-26; 13:1-3
+reading.gospel = Matt 10:16-22
+
+[basilidus]
+date = 06-12
+rank = commemoration
+colour = red
+name.en = St. Basilidus
+
+[john-of-san-fecundo]
+date = 06-12
+rank = class-3
+colour = red
+name.en = St. John of San Fecundo
+reading.first = Sir 31:8-11
+reading.gospel = Luke 12:35-40
+
+[anthony-of-padua]
+date = 06-13
+rank = class-3
+colour = white
+name.en = St. Anthony of Padua
+reading.first = 2 Tim 4:1-8
+reading.gospel = Matt 5:13-19
+
+[basil-the-great]
+date = 06-14
+rank = class-3
+colour = white
+name.en = St. Basil the Great
+reading.first = 2 Tim 4:1-8
+reading.gospel = Luke 14:26-35
+
+[vitus]
+date = 06-15
+rank = commemoration
+colour = white
+name.en = St. Vitus
+
+[gregory-barbarigo]
+date = 06-17
+rank = class-3
+colour = white
+name.en = St. Gregory Barbarigo
+reading.first = Sir 44:16-27; 45:3-20
+reading.gospel = Matt 25:14-23
+
+[ephrem-of-syria]
+date = 06-18
+rank = class-3
+colour = red
+name.en = St. Ephrem of Syria
+reading.first = 2 Tim 4:1-8
+reading.gospel = Matt 5:13-19
+
+[marcus-and-marcellianus]
+date = 06-18
+rank = commemoration
+colour = red
+name.en = Ss. Marcus and Marcellianus
+
+[julia-of-falconieri]
+date = 06-19
+rank = class-3
+colour = red
+name.en = St. Julia of Falconieri
+reading.first = 2 Cor 10:17-18; 11:1-2
+reading.gospel = Matt 25:1-13.
+
+[sts-gervasius-and-protasius]
+date = 06-19
+rank = commemoration
+colour = red
+name.en = Sts. Gervasius and Protasius
+
+[silverius]
+date = 06-20
+rank = commemoration
+colour = red
+name.en = St. Silverius
+
+[aloysius-gongzaga]
+date = 06-21
+rank = class-3
+colour = white
+name.en = St. Aloysius Gongzaga
+reading.first = Sir 31:8-11
+reading.gospel = Matt 22:29-40
+
+[paulinus-of-nola]
+date = 06-22
+rank = class-3
+colour = white
+name.en = St. Paulinus of Nola
+reading.first = 2 Cor. 8:9-15
+reading.gospel = Luke 12:32-34
+
+[nativity-of-st-john-the-baptist]
date = 06-24
rank = class-1
colour = white
-name.en = The Nativity of Saint John the Baptist
+name.en = Nativity of St. John the Baptist
+reading.first = Isa 49:1-3, 5-7.
+reading.gospel = Luke 1:57-68
-[peter-and-paul]
-reading.first = Acts 12:1-11
-reading.gospel = Matt 16:13-19
+[william]
+date = 06-25
+rank = class-3
+colour = white
+name.en = St. William
+reading.first = Ecclus 45:1-6
+reading.gospel = Matt 19:27-29.
+
+[sts-john-paul]
+date = 06-26
+rank = class-3
+colour = red
+name.en = Sts. John & Paul
+reading.first = Eccli 44:10-15
+reading.gospel = Luke 12:1-8
+
+[sts-peter-paul]
date = 06-29
rank = class-1
colour = red
-name.en = Saints Peter and Paul, Apostles
+name.en = Sts. Peter & Paul
+reading.first = Acts 12:1-11
+reading.gospel = Matt 16:13-19
-[assumption]
-reading.first = Judith 13:22-25; 15:10
-reading.gospel = Luke 1:41-50
-date = 08-15
+[in-commemoratione-sancti-pauli-apostoli]
+date = 06-30
+rank = class-3
+colour = red
+name.en = In Commemoratione Sancti Pauli Apostoli
+reading.first = Gal 1:11-20
+reading.gospel = Matt 10:16-22
+
+[precious-blood-of-our-lord-jesus-christ]
+date = 07-01
rank = class-1
+colour = red
+class = lord
+name.en = The Precious Blood of Our Lord Jesus Christ
+reading.first = Heb 9:11-15.
+reading.gospel = John 19:30-35
+
+[processus-and-martinian]
+date = 07-02
+rank = commemoration
+colour = red
+name.en = SS. Processus and Martinian
+
+[visitation-of-the-blessed-virgin-mary]
+date = 07-02
+rank = class-2
colour = white
-name.en = The Assumption of the Blessed Virgin Mary
-name.la = In Assumptione Beatae Mariae Virginis
+name.en = Visitation of the Blessed Virgin Mary
+reading.first = Song 2:8-14
+reading.gospel = Luke 1:39-47
-[st-michael]
-reading.first = Rev 1:1-5
-reading.gospel = Matt 18:1-10
-date = 09-29
-rank = class-1
+[irenaeus]
+date = 07-03
+rank = class-3
+colour = red
+name.en = St. Irenaeus
+reading.first = 2 Tim. 3:14-17; 4:1-5
+reading.gospel = Matt 10:28-33
+
+[anthony-mary-zaccariah]
+date = 07-05
+rank = class-3
colour = white
-name.en = The Dedication of Saint Michael the Archangel
+name.en = St. Anthony Mary Zaccariah
+reading.first = 1 Tim. 4:8-16
+reading.gospel = Mark 10:15-21
-[all-saints]
-reading.first = Rev 7:2-12
-reading.gospel = Matt 5:1-12
-date = 11-01
-rank = class-1
+[sts-cyril-methodius]
+date = 07-07
+rank = class-3
colour = white
-name.en = All Saints
+name.en = Sts. Cyril & Methodius
+reading.first = Heb 7:23-27
+reading.gospel = Luke 10:1-9
-; --- II class ---
+[elizabeth-of-portugal]
+date = 07-08
+rank = class-3
+colour = white
+name.en = St. Elizabeth of Portugal
+reading.first = Prov 31:10-31
+reading.gospel = Matt 13:44-52.
-[purification]
-reading.first = Mal 3:1-4
-reading.gospel = Luke 2:22-32
-date = 02-02
+[seven-holy-brothers-and-sts-rufina-secunda]
+date = 07-10
+rank = class-3
+colour = red
+name.en = Seven Holy Brothers and Sts. Rufina & Secunda
+reading.first = Prov 31:10-31
+reading.gospel = Matt 12:46-50
+
+[pius-i]
+date = 07-11
+rank = commemoration
+colour = red
+name.en = St. Pius I
+
+[john-gualbert]
+date = 07-12
+rank = class-3
+colour = red
+name.en = St. John Gualbert
+reading.first = Ecclus 45:1-6
+reading.gospel = Matt 5:43-48
+
+[naboris-et-felicis]
+date = 07-12
+rank = commemoration
+colour = red
+name.en = Ss. Naboris et Felicis
+
+[bonaventure]
+date = 07-14
+rank = class-3
+colour = white
+name.en = St. Bonaventure
+reading.first = 2 Tim 4:1-8
+reading.gospel = Matt 5:13-19
+
+[henry-the-emperor]
+date = 07-15
+rank = class-3
+colour = white
+name.en = St. Henry the Emperor
+reading.first = Sir 31:8-11
+reading.gospel = Luke 12:35-40
+
+[our-lady-of-mt-carmel]
+date = 07-16
+rank = commemoration
+colour = white
+name.en = Our Lady of Mt. Carmel
+
+[alexis]
+date = 07-17
+rank = commemoration
+colour = white
+name.en = St. Alexis
+
+[camillus-de-lellis]
+date = 07-18
+rank = class-3
+colour = red
+name.en = Camillus de Lellis
+reading.first = 1 John 3:13-18.
+reading.gospel = John 15:12-16
+
+[symphorosa-and-sons]
+date = 07-18
+rank = commemoration
+colour = red
+name.en = Ss. Symphorosa and sons
+
+[vincent-de-paul]
+date = 07-19
+rank = class-3
+colour = white
+name.en = St. Vincent de Paul
+reading.first = 1 Cor. 4:9-14
+reading.gospel = Luke 10:1-9
+
+[jerome-emiliani]
+date = 07-20
+rank = class-3
+colour = red
+name.en = St. Jerome Emiliani
+reading.first = Isa 58:7-11
+reading.gospel = Matt 19:13-21
+
+[margaret]
+date = 07-20
+rank = commemoration
+colour = white
+name.en = St. Margaret
+
+[laurence-of-brindisi]
+date = 07-21
+rank = class-3
+colour = white
+name.en = St. Laurence of Brindisi
+reading.first = 2 Tim 4:1-8
+reading.gospel = Matt 5:13-19
+
+[praxedis-virginis]
+date = 07-21
+rank = commemoration
+colour = white
+name.en = St. Praxedis Virginis
+
+[mary-magdalene]
+date = 07-22
+rank = class-3
+colour = white
+name.en = St. Mary Magdalene
+reading.first = Song 3:2-5; 8:6-7
+reading.gospel = Luke 7:36-50
+
+[apollinaris]
+date = 07-23
+rank = class-3
+colour = white
+name.en = St. Apollinaris
+reading.first = 1 Pet. 5:1-11
+reading.gospel = Luke 22:24-30
+
+[liborii]
+date = 07-23
+rank = commemoration
+colour = red
+name.en = S. Liborii
+
+[christina]
+date = 07-24
+rank = commemoration
+colour = red
+name.en = St. Christina
+
+[christopher]
+date = 07-25
+rank = commemoration
+colour = red
+name.en = St. Christopher
+
+[james-the-greater]
+date = 07-25
+rank = class-2
+colour = red
+name.en = St. James the Greater
+reading.first = 1 Cor. 4:9-15
+reading.gospel = Matt 20:20-23
+
+[anne-mother-of-the-blessed-virgin]
+date = 07-26
rank = class-2
colour = white
-name.en = The Purification of the Blessed Virgin Mary
+name.en = St. Anne, Mother of the Blessed Virgin
+reading.first = Prov 31:10-31
+reading.gospel = Matt 13:44-52.
-[st-lawrence]
-reading.first = 2 Cor 9:6-10
-reading.gospel = John 12:24-26
+[pantaleon]
+date = 07-27
+rank = commemoration
+colour = red
+name.en = St. Pantaleon
+
+[sts-nazarius-celsus-st-victor-i-st-innocent-i]
+date = 07-28
+rank = class-3
+colour = red
+name.en = Sts. Nazarius & Celsus, St. Victor I & St. Innocent I
+reading.first = Wis 10:17-20
+reading.gospel = Luke 21:9-19
+
+[felicis-simplicii-faustini-et-beatricis]
+date = 07-29
+rank = commemoration
+colour = red
+name.en = Ss. Felicis, Simplicii, Faustini et Beatricis
+
+[martha]
+date = 07-29
+rank = class-3
+colour = red
+name.en = St. Martha
+reading.first = 2 Cor 10:17-18; 11:1-2
+reading.gospel = Luke 10:38-42
+
+[sts-abdon-sennen]
+date = 07-30
+rank = commemoration
+colour = red
+name.en = Sts. Abdon & Sennen
+
+[ignatius-loyola]
+date = 07-31
+rank = class-3
+colour = white
+name.en = St. Ignatius Loyola
+reading.first = 2 Tim. 2:8-10; 3:10-12.
+reading.gospel = Luke 10:1-9
+
+[holy-machabees]
+date = 08-01
+rank = commemoration
+colour = red
+name.en = Holy Machabees
+
+[alphonsus-liguori]
+date = 08-02
+rank = class-3
+colour = red
+name.en = St. Alphonsus Liguori
+reading.first = 2 Tim. 2:1-7
+reading.gospel = Luke 10:1-9
+
+[stephen-i-pope-and-martyr]
+date = 08-02
+rank = commemoration
+colour = red
+name.en = St. Stephen I, Pope and Martyr
+
+[dominic]
+date = 08-04
+rank = class-3
+colour = white
+name.en = St. Dominic
+reading.first = 2 Tim. 4:1-8
+reading.gospel = Luke 12:35-40
+
+[dedication-of-the-basilica-of-st-mary-major]
+date = 08-05
+rank = class-3
+colour = white
+name.en = Dedication of the Basilica of St. Mary Major
+reading.first = Ecclus 24:14-16
+reading.gospel = Luke 11:27-28
+
+[pope-sixtus-ii-felicissimus-and-agapitus-martyrs]
+date = 08-06
+rank = commemoration
+colour = red
+name.en = Pope Sixtus II, Felicissimus and Agapitus, Martyrs
+
+[transfiguration-of-our-lord]
+date = 08-06
+rank = class-2
+colour = white
+class = lord
+name.en = Transfiguration of Our Lord
+reading.first = 2 Pet. 1:16-19
+reading.gospel = Matt 17:1-9
+
+[cajetan]
+date = 08-07
+rank = class-3
+colour = white
+name.en = St. Cajetan
+reading.first = Sir 31:8-11
+reading.gospel = Matt 6:24-33
+
+[donatus]
+date = 08-07
+rank = commemoration
+colour = red
+name.en = St. Donatus
+
+[cyriacus-largus-and-smaragdus-martyrs]
+date = 08-08
+rank = commemoration
+colour = red
+name.en = Ss. Cyriacus, Largus and Smaragdus, Martyrs
+
+[john-mary-vianney]
+date = 08-08
+rank = class-3
+colour = white
+name.en = St. John Mary Vianney
+reading.first = Sir 31:8-11
+reading.gospel = Luke 12:35-40
+
+[romanus]
+date = 08-09
+rank = commemoration
+colour = red
+name.en = St. Romanus
+
+[lawrence]
date = 08-10
rank = class-2
colour = red
-name.en = Saint Lawrence, Martyr
+name.en = St. Lawrence
+reading.first = 2 Cor. 9:6-10
+reading.gospel = John 12:24-26
-[nativity-bvm]
-reading.first = Prov 8:22-35
+[sts-tiburtius-susanna]
+date = 08-11
+rank = commemoration
+colour = red
+name.en = Sts. Tiburtius & Susanna
+
+[clare]
+date = 08-12
+rank = class-3
+colour = white
+name.en = St. Clare
+reading.first = 2 Cor 10:17-18; 11:1-2
+reading.gospel = Matt 25:1-13.
+
+[sts-hippolytus-cassian]
+date = 08-13
+rank = commemoration
+colour = red
+name.en = Sts. Hippolytus & Cassian
+
+[assumption-of-the-blessed-virgin-mary]
+date = 08-15
+rank = class-1
+colour = white
+name.en = Assumption of the Blessed Virgin Mary
+reading.first = Judith 13:22-25; 13:15; 13:10
+reading.gospel = Luke 1:41-50
+
+[joachim-father-of-the-blessed-virgin]
+date = 08-16
+rank = class-2
+colour = white
+name.en = St. Joachim, Father of the Blessed Virgin
+reading.first = Sir 31:8-11
reading.gospel = Matt 1:1-16
+
+[hyacinth]
+date = 08-17
+rank = class-3
+colour = white
+name.en = St. Hyacinth
+reading.first = Sir 31:8-11
+reading.gospel = Luke 12:35-40
+
+[agapitus]
+date = 08-18
+rank = commemoration
+colour = white
+name.en = St. Agapitus
+
+[john-eudes]
+date = 08-19
+rank = class-3
+colour = white
+name.en = St. John Eudes
+reading.first = Sir 31:8-11
+reading.gospel = Luke 12:35-40
+
+[bernard-of-clairvaux]
+date = 08-20
+rank = class-3
+colour = white
+name.en = St. Bernard of Clairvaux
+reading.first = Ecclus 39:6-14
+reading.gospel = Matt 5:13-19
+
+[jane-frances-de-chantal]
+date = 08-21
+rank = class-3
+colour = white
+name.en = St. Jane Frances de Chantal
+reading.first = Prov 31:10-31
+reading.gospel = Matt 13:44-52.
+
+[immaculate-heart-of-mary]
+date = 08-22
+rank = class-2
+colour = white
+name.en = Immaculate Heart of Mary
+reading.first = Sir 24:23-31
+reading.gospel = John 19:25-27
+
+[sts-timothy-hippolytus-and-symphorianus-martyrs]
+date = 08-22
+rank = commemoration
+colour = red
+name.en = Sts. Timothy, Hippolytus and Symphorianus, Martyrs
+
+[philip-benizi]
+date = 08-23
+rank = class-3
+colour = white
+name.en = St. Philip Benizi
+reading.first = 1 Cor. 4:9-14
+reading.gospel = Luke 12:32-34
+
+[bartholomew]
+date = 08-24
+rank = class-2
+colour = red
+name.en = St. Bartholomew
+reading.first = 1 Cor. 12:27-31
+reading.gospel = Luke 6:12-19
+
+[louis-ix]
+date = 08-25
+rank = class-3
+colour = white
+name.en = St. Louis IX
+reading.first = Wis 10:10-14
+reading.gospel = Luke 19:12-26
+
+[zephyrinus]
+date = 08-26
+rank = commemoration
+colour = red
+name.en = St. Zephyrinus
+
+[joseph-calasance]
+date = 08-27
+rank = class-3
+colour = white
+name.en = St. Joseph Calasance
+reading.first = Wis 10:10-14
+reading.gospel = Matt 18:1-5
+
+[augustine]
+date = 08-28
+rank = class-3
+colour = red
+name.en = St. Augustine
+reading.first = 2 Tim 4:1-8
+reading.gospel = Matt 5:13-19
+
+[hermes]
+date = 08-28
+rank = commemoration
+colour = red
+name.en = St. Hermes
+
+[beheading-of-st-john-the-baptist]
+date = 08-29
+rank = class-3
+colour = red
+name.en = Beheading of St. John the Baptist
+reading.first = Jer 1:17-19
+reading.gospel = Mark 6:17-29
+
+[sabina]
+date = 08-29
+rank = commemoration
+colour = red
+name.en = St. Sabina
+
+[rose-of-lima]
+date = 08-30
+rank = class-3
+colour = red
+name.en = St. Rose of Lima
+reading.first = 2 Cor 10:17-18; 11:1-2
+reading.gospel = Matt 25:1-13.
+
+[sts-felix-and-adauctus]
+date = 08-30
+rank = commemoration
+colour = red
+name.en = Sts. Felix and Adauctus
+
+[raymond-nonnatus]
+date = 08-31
+rank = class-3
+colour = white
+name.en = St. Raymond Nonnatus
+reading.first = Sir 31:8-11
+reading.gospel = Luke 12:35-40
+
+[giles]
+date = 09-01
+rank = commemoration
+colour = white
+name.en = St. Giles
+
+[twelve-holy-brothers-martyrs]
+date = 09-01
+rank = commemoration
+colour = red
+name.en = Twelve Holy Brothers, Martyrs
+
+[stephen-of-hungary]
+date = 09-02
+rank = class-3
+colour = white
+name.en = St. Stephen of Hungary
+reading.first = Sir 31:8-11
+reading.gospel = Luke 19:12-26
+
+[pius-x]
+date = 09-03
+rank = class-3
+colour = white
+name.en = St. Pius X
+reading.first = 1 Thess. 2:2-8
+reading.gospel = John 21:15-17
+
+[lawrence-justinian]
+date = 09-05
+rank = class-3
+colour = white
+name.en = St. Lawrence Justinian
+reading.first = Sir 44:16-27; 45:3-20
+reading.gospel = Matt 25:14-23
+
+[hadriani]
+date = 09-08
+rank = commemoration
+colour = red
+name.en = S. Hadriani
+
+[nativity-of-the-blessed-virgin-mary]
date = 09-08
rank = class-2
colour = white
-name.en = The Nativity of the Blessed Virgin Mary
+name.en = Nativity of the Blessed Virgin Mary
+reading.first = Prov 8:22-35
+reading.gospel = Matt 1:1-16
+
+[gorgonius]
+date = 09-09
+rank = commemoration
+colour = red
+name.en = St. Gorgonius
+
+[nicholas-of-tolentino]
+date = 09-10
+rank = class-3
+colour = white
+name.en = St. Nicholas of Tolentino
+reading.first = 1 Cor. 4:9-14
+reading.gospel = Luke 12:32-34
+
+[sts-protus-hyacinth]
+date = 09-11
+rank = commemoration
+colour = red
+name.en = Sts. Protus & Hyacinth
+
+[most-holy-name-of-mary]
+date = 09-12
+rank = class-3
+colour = white
+class = lord
+name.en = Most Holy Name of Mary
+reading.first = Sir 24:23-31
+reading.gospel = Luke 1:26-38
-[exaltation-of-the-cross]
+[exaltation-of-the-holy-cross]
+date = 09-14
+rank = class-2
+colour = red
+class = lord
+name.en = Exaltation of the Holy Cross
reading.first = Phil 2:5-11
reading.gospel = John 12:31-36
-date = 09-14
+
+[nicomedes]
+date = 09-15
+rank = commemoration
+colour = red
+name.en = S. Nicomedes
+
+[seven-sorrows-of-the-blessed-virgin-mary]
+date = 09-15
rank = class-2
+colour = white
+name.en = Seven Sorrows of the Blessed Virgin Mary
+reading.first = Judith 13:22; 13:25
+reading.gospel = John 19:25-27
+
+[sts-cornelius-cyprian]
+date = 09-16
+rank = class-3
colour = red
-name.en = The Exaltation of the Holy Cross
+name.en = Sts. Cornelius & Cyprian
+reading.first = Wis 3:1-8
+reading.gospel = Luke 21:9-19
-[st-andrew]
-reading.first = Rom 10:10-18
-reading.gospel = Matt 4:18-22
-date = 11-30
+[sts-euphemia-lucy-and-geminianus]
+date = 09-16
+rank = commemoration
+colour = red
+name.en = Sts. Euphemia, Lucy and Geminianus
+
+[stigmata-of-st-francis]
+date = 09-17
+rank = commemoration
+colour = white
+name.en = Stigmata of St. Francis
+
+[joseph-of-cupertino]
+date = 09-18
+rank = class-3
+colour = white
+name.en = St. Joseph of Cupertino
+reading.first = 1 Cor 13:1-8
+reading.gospel = Matt 22:1-14
+
+[januarius-companions]
+date = 09-19
+rank = class-3
+colour = red
+name.en = St. Januarius & Companions
+reading.first = Heb 10:32-38
+reading.gospel = Matt 24:3-13
+
+[sts-eustace-companions]
+date = 09-20
+rank = commemoration
+colour = red
+name.en = Sts. Eustace & Companions
+
+[matthew]
+date = 09-21
rank = class-2
colour = red
-name.en = Saint Andrew, Apostle
+name.en = St. Matthew
+reading.first = Ezek 1:10-14
+reading.gospel = Matt 9:9-13
-; --- III class ---
+[maurice-and-companions-martyrs]
+date = 09-22
+rank = commemoration
+colour = red
+name.en = St. Maurice and Companions, Martyrs
-[conversion-of-paul]
-reading.first = Acts 9:1-22
-reading.gospel = Matt 19:27-29
-date = 01-25
+[thomas-of-villanova]
+date = 09-22
+rank = class-3
+colour = white
+name.en = St. Thomas of Villanova
+reading.first = Sir 44:16-27; 45:3-20
+reading.gospel = Matt 25:14-23
+
+[linus]
+date = 09-23
rank = class-3
+colour = red
+name.en = St. Linus
+reading.first = 1 Pet 5:1-4; 5:10-11.
+reading.gospel = Matt 16:13-19
+
+[thecla]
+date = 09-23
+rank = commemoration
+colour = red
+name.en = St. Thecla
+
+[our-lady-of-ransom]
+date = 09-24
+rank = commemoration
colour = white
-name.en = The Conversion of Saint Paul the Apostle
+name.en = Our Lady of Ransom
+
+[sts-cyprian-justina]
+date = 09-26
+rank = commemoration
+colour = red
+name.en = Sts. Cyprian & Justina
+
+[sts-cosmas-damian]
+date = 09-27
+rank = class-3
+colour = red
+name.en = Sts. Cosmas & Damian
+reading.first = Wis 5:16-20
+reading.gospel = Luke 6:17-23
-[st-lucy]
+[wenceslaus]
+date = 09-28
+rank = class-3
+colour = red
+name.en = St. Wenceslaus
+reading.first = Wis 10:10-14
+reading.gospel = Matt 10:34-42
+
+[dedication-of-st-michael-the-archangel]
+date = 09-29
+rank = class-1
+colour = white
+name.en = Dedication of St. Michael the Archangel
+reading.first = Rev 1:1-5
+reading.gospel = Matt 18:1-10
+
+[jerome]
+date = 09-30
+rank = class-3
+colour = white
+name.en = St. Jerome
+reading.first = 2 Tim 4:1-8
+reading.gospel = Matt 5:13-19
+
+[remigius]
+date = 10-01
+rank = commemoration
+colour = white
+name.en = St. Remigius
+
+[holy-guardian-angels]
+date = 10-02
+rank = class-3
+colour = white
+name.en = Holy Guardian Angels
+reading.first = Exod 23:20-23
+reading.gospel = Matt 18:1-10
+
+[theresa-of-the-infant-jesus]
+date = 10-03
+rank = class-3
+colour = white
+name.en = St. Theresa of the Infant Jesus
+reading.first = Isa 66:12-14
+reading.gospel = Matt 18:1-4
+
+[francis-of-assisi]
+date = 10-04
+rank = class-3
+colour = white
+name.en = St. Francis of Assisi
+reading.first = Gal 6:14-18
+reading.gospel = Matt 11:25-30
+
+[placid-companions]
+date = 10-05
+rank = commemoration
+colour = red
+name.en = St. Placid & Companions
+
+[bruno]
+date = 10-06
+rank = class-3
+colour = white
+name.en = St. Bruno
+reading.first = Sir 31:8-11
+reading.gospel = Luke 12:35-40
+
+[mark-i]
+date = 10-07
+rank = commemoration
+colour = red
+name.en = St. Mark I
+
+[our-lady-of-the-rosary]
+date = 10-07
+rank = class-2
+colour = white
+name.en = Our Lady of the Rosary
+reading.first = Prov 8:22-24, 32-35.
+reading.gospel = Luke 1:26-38
+
+[bridget-of-sweden]
+date = 10-08
+rank = class-3
+colour = white
+name.en = St. Bridget of Sweden
+reading.first = 1 Tim. 5:3-10.
+reading.gospel = Matt 13:44-52.
+
+[sergio-baccho-marcello-and-apulejo-martyrs]
+date = 10-08
+rank = commemoration
+colour = red
+name.en = Ss. Sergio, Baccho, Marcello and Apulejo Martyrs
+
+[dionysius-and-companions]
+date = 10-09
+rank = commemoration
+colour = red
+name.en = St. Dionysius and companions
+
+[john-leonardi]
+date = 10-09
+rank = class-3
+colour = white
+name.en = St. John Leonardi
+reading.first = 2 Cor 4:1-6; 4:15-18
+reading.gospel = Luke 10:1-9
+
+[francis-borgia]
+date = 10-10
+rank = class-3
+colour = white
+name.en = St. Francis Borgia
+reading.first = Ecclus 45:1-6
+reading.gospel = Matt 19:27-29.
+
+[maternity-of-the-blessed-virgin-mary]
+date = 10-11
+rank = class-2
+colour = white
+name.en = Maternity of the Blessed Virgin Mary
+reading.first = Sir 24:23-31
+reading.gospel = Luke 2:43-51
+
+[edward]
+date = 10-13
+rank = class-3
+colour = white
+name.en = St. Edward
+reading.first = Sir 31:8-11
+reading.gospel = Luke 12:35-40
+
+[callistus-i]
+date = 10-14
+rank = class-3
+colour = red
+name.en = St. Callistus I
+reading.first = 1 Pet 5:1-4; 5:10-11.
+reading.gospel = Matt 16:13-19
+
+[teresa-of-avila]
+date = 10-15
+rank = class-3
+colour = white
+name.en = St. Teresa of Avila
+reading.first = 2 Cor 10:17-18; 11:1-2
+reading.gospel = Matt 25:1-13.
+
+[hedwig]
+date = 10-16
+rank = class-3
+colour = white
+name.en = St. Hedwig
+reading.first = Prov 31:10-31
+reading.gospel = Matt 13:44-52.
+
+[margaret-mary-alacoque]
+date = 10-17
+rank = class-3
+colour = white
+name.en = St. Margaret Mary Alacoque
+reading.first = Eph 3:8-9, 14-19
+reading.gospel = Matt 11:25-30
+
+[luke-the-evangelist]
+date = 10-18
+rank = class-2
+colour = red
+name.en = St. Luke the Evangelist
+reading.first = 2 Cor. 8:16-24
+reading.gospel = Luke 10:1-9
+
+[peter-of-alcantara]
+date = 10-19
+rank = class-3
+colour = white
+name.en = St. Peter of Alcantara
+reading.first = Phil 3:7-12
+reading.gospel = Luke 12:32-34
+
+[john-cantius]
+date = 10-20
+rank = class-3
+colour = white
+name.en = St. John Cantius
+reading.first = James 2:12-17
+reading.gospel = Luke 12:35-40
+
+[hilarion]
+date = 10-21
+rank = commemoration
+colour = white
+name.en = St. Hilarion
+
+[ursula-and-companions]
+date = 10-21
+rank = commemoration
+colour = red
+name.en = St. Ursula and Companions
+
+[anthony-mary-claret]
+date = 10-23
+rank = class-3
+colour = white
+name.en = St. Anthony Mary Claret
+reading.first = Heb 7:23-27
+reading.gospel = Matt 24:42-47
+
+[raphael-the-archangel]
+date = 10-24
+rank = class-3
+colour = white
+name.en = St. Raphael the Archangel
+reading.first = Tob 12:7-15
+reading.gospel = John 5:1-4
+
+[sts-chrysanthus-daria]
+date = 10-25
+rank = commemoration
+colour = red
+name.en = Sts. Chrysanthus & Daria
+
+[sts-simon-jude]
+date = 10-28
+rank = class-2
+colour = red
+name.en = Sts. Simon & Jude
+reading.first = Eph. 4:7-13.
+reading.gospel = John 15:17-25
+
+[all-saints]
+date = 11-01
+rank = class-1
+colour = white
+name.en = All Saints
+reading.first = Apoc 7:2-12
+reading.gospel = Matt 5:1-12
+
+[commemoration-of-all-souls]
+date = 11-02
+rank = class-1
+colour = black
+name.en = Commemoration of All Souls
+reading.first = 1 Cor. 15:51-57
+reading.gospel = John 5:25-29
+
+[charles-borromeo]
+date = 11-04
+rank = class-3
+colour = white
+name.en = St. Charles Borromeo
+reading.first = Sir 44:16-27; 45:3-20
+reading.gospel = Matt 25:14-23
+
+[sts-vitalis-and-agricola-martyrs]
+date = 11-04
+rank = commemoration
+colour = red
+name.en = Sts. Vitalis and Agricola, Martyrs
+
+[four-holy-crowned-martyrs]
+date = 11-08
+rank = commemoration
+colour = red
+name.en = Four Holy Crowned Martyrs
+
+[dedication-of-the-archbasilica-of-our-holy-savior]
+date = 11-09
+rank = class-2
+colour = white
+class = lord
+name.en = Dedication of the Archbasilica of Our Holy Savior
+reading.first = Rev 21:2-5
+reading.gospel = Luke 19:1-10
+
+[andrew-avellino]
+date = 11-10
+rank = class-3
+colour = white
+name.en = St. Andrew Avellino
+reading.first = Sir 31:8-11
+reading.gospel = Luke 12:35-40
+
+[sts-tryphonis-respicii-et-nymphae]
+date = 11-10
+rank = commemoration
+colour = red
+name.en = Sts. Tryphonis, Respicii, et Nymphae
+
+[martin-of-tours]
+date = 11-11
+rank = class-3
+colour = white
+name.en = St. Martin of Tours
+reading.first = Sir 44:16-27; 45:3-20
+reading.gospel = Luke 11:33-36
+
+[menna]
+date = 11-11
+rank = commemoration
+colour = red
+name.en = St. Menna
+
+[martin-i]
+date = 11-12
+rank = class-3
+colour = red
+name.en = St. Martin I
+reading.first = 1 Pet 5:1-4; 5:10-11.
+reading.gospel = Matt 16:13-19
+
+[didacus]
+date = 11-13
+rank = commemoration
+colour = white
+name.en = St. Didacus
+
+[josaphat]
+date = 11-14
+rank = class-3
+colour = white
+name.en = St. Josaphat
+reading.first = Heb 5:1-6
+reading.gospel = John 10:11-16
+
+[albert-the-great]
+date = 11-15
+rank = class-3
+colour = white
+name.en = St. Albert the Great
+reading.first = 2 Tim 4:1-8
+reading.gospel = Matt 5:13-19
+
+[gertrude-the-great]
+date = 11-16
+rank = class-3
+colour = white
+name.en = St. Gertrude the Great
reading.first = 2 Cor 10:17-18; 11:1-2
-reading.gospel = Matt 13:44-52
+reading.gospel = Matt 25:1-13.
+
+[gregory-the-wonderworker]
+date = 11-17
+rank = class-3
+colour = white
+name.en = St. Gregory the Wonderworker
+reading.first = Sir 44:16-27; 45:3-20
+reading.gospel = Mark 11:22-24
+
+[dedication-of-the-basilicas-of-sts-peter-paul]
+date = 11-18
+rank = class-3
+colour = white
+name.en = Dedication of the Basilicas of Sts. Peter & Paul
+reading.first = Rev 21:2-5
+reading.gospel = Luke 19:1-10
+
+[elizabeth-of-hungary]
+date = 11-19
+rank = class-3
+colour = white
+name.en = St. Elizabeth of Hungary
+reading.first = Prov 31:10-31
+reading.gospel = Matt 13:44-52.
+
+[pontian]
+date = 11-19
+rank = commemoration
+colour = red
+name.en = St. Pontian
+
+[felix-of-valois]
+date = 11-20
+rank = class-3
+colour = white
+name.en = St. Felix of Valois
+reading.first = 1 Cor. 4:9-14
+reading.gospel = Luke 12:32-34
+
+[presentation-of-the-blessed-virgin-mary]
+date = 11-21
+rank = class-3
+colour = white
+name.en = Presentation of the Blessed Virgin Mary
+reading.first = Ecclus 24:14-16
+reading.gospel = Luke 11:27-28
+
+[cecilia]
+date = 11-22
+rank = class-3
+colour = red
+name.en = St. Cecilia
+reading.first = Sir 51:13-17.
+reading.gospel = Matt 25:1-13.
+
+[clement-i]
+date = 11-23
+rank = class-3
+colour = red
+name.en = St. Clement I
+reading.first = Phil 3:17-21; 4:1-3
+reading.gospel = Matt 16:13-19
+
+[felicity]
+date = 11-23
+rank = commemoration
+colour = red
+name.en = St. Felicity
+
+[chrysogonus]
+date = 11-24
+rank = commemoration
+colour = red
+name.en = St. Chrysogonus
+
+[john-of-the-cross]
+date = 11-24
+rank = class-3
+colour = white
+name.en = St. John of the Cross
+reading.first = 2 Tim 4:1-8
+reading.gospel = Matt 5:13-19
+
+[catherine-of-alexandria]
+date = 11-25
+rank = class-3
+colour = red
+name.en = St. Catherine of Alexandria
+reading.first = Sir 51:1-8; 51:12
+reading.gospel = Matt 25:1-13.
+
+[peter-of-alexandria]
+date = 11-26
+rank = commemoration
+colour = red
+name.en = St. Peter of Alexandria
+
+[sylvester]
+date = 11-26
+rank = class-3
+colour = white
+name.en = St. Sylvester
+reading.first = Ecclus 45:1-6
+reading.gospel = Matt 19:27-29.
+
+[saturninus]
+date = 11-29
+rank = commemoration
+colour = red
+name.en = St. Saturninus
+
+[andrew]
+date = 11-30
+rank = class-2
+colour = red
+name.en = St. Andrew
+reading.first = Rom 10:10-18
+reading.gospel = Matt 4:18-22
+
+[vivian]
+date = 12-02
+rank = class-3
+colour = red
+name.en = St. Vivian
+reading.first = Sir 51:13-17.
+reading.gospel = Matt 13:44-52.
+
+[francis-xavier]
+date = 12-03
+rank = class-3
+colour = white
+name.en = St. Francis Xavier
+reading.first = Rom 10:10-18
+reading.gospel = Mark 16:15-18
+
+[peter-chrysologus]
+date = 12-04
+rank = class-3
+colour = white
+name.en = St. Peter Chrysologus
+reading.first = 2 Tim 4:1-8
+reading.gospel = Matt 5:13-19
+
+[sabbas]
+date = 12-05
+rank = commemoration
+colour = white
+name.en = St. Sabbas
+
+[nicholas]
+date = 12-06
+rank = class-3
+colour = white
+name.en = St. Nicholas
+reading.first = Heb 13:7-17
+reading.gospel = Matt 25:14-23
+
+[ambrose]
+date = 12-07
+rank = class-3
+colour = white
+name.en = St. Ambrose
+reading.first = 2 Tim 4:1-8
+reading.gospel = Matt 5:13-19
+
+[immaculate-conception-of-the-blessed-virgin-mary]
+date = 12-08
+rank = class-1
+colour = white
+name.en = Immaculate Conception of the Blessed Virgin Mary
+reading.first = Prov 8:22-35
+reading.gospel = Luke 1:26-28
+
+[melchiades]
+date = 12-10
+rank = commemoration
+colour = red
+name.en = St. Melchiades
+
+[damasus-i]
+date = 12-11
+rank = class-3
+colour = white
+name.en = St. Damasus I
+reading.first = 1 Pet 5:1-4; 5:10-11.
+reading.gospel = Matt 16:13-19
+
+[lucy]
date = 12-13
rank = class-3
colour = red
-name.en = Saint Lucy, Virgin and Martyr
+name.en = St. Lucy
+reading.first = 2 Cor 10:17-18; 11:1-2
+reading.gospel = Matt 13:44-52.
+
+[eusebius]
+date = 12-16
+rank = class-3
+colour = red
+name.en = St. Eusebius
+reading.first = 2 Cor. 1:3-7
+reading.gospel = Matt 16:24-27.
+
+[thomas]
+date = 12-21
+rank = class-2
+colour = red
+name.en = St. Thomas
+reading.first = Eph 2:19-22
+reading.gospel = John 20:24-29
+
+[stephen]
+date = 12-26
+rank = class-2
+colour = red
+name.en = St. Stephen
+reading.first = Acts 6:8-10; 7:54-59
+reading.gospel = Matt 23:34-39
+
+[john-the-evangelist]
+date = 12-27
+rank = class-2
+colour = white
+name.en = St. John the Evangelist
+reading.first = Ecclus 15:1-6
+reading.gospel = John 21:19-24
+
+[holy-innocents]
+date = 12-28
+rank = class-2
+colour = red
+name.en = Holy Innocents
+reading.first = Apoc 14:1-5
+reading.gospel = Matt 2:13-18
+
+[thomas-becket]
+date = 12-29
+rank = commemoration
+colour = red
+name.en = St. Thomas Becket
+
+[silvester]
+date = 12-31
+rank = commemoration
+colour = white
+name.en = St. Silvester
diff --git a/internal/config/config.go b/internal/config/config.go
index aadf160..d4de9c4 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -63,7 +63,7 @@ const configHeader = `# lectio configuration (INI). Full-line comments only (# o
// Version is lectio's release version, shared by every binary's
// -v/--version output (lectio, lectio-ui, lectio-web).
-const Version = "0.37.0"
+const Version = "0.38.0"
// validVersions are the five scripture versions lectio understands.
var validVersions = map[string]bool{
diff --git a/scripts/build-oracle-ef.sh b/scripts/build-oracle-ef.sh
index 71174ae..2864551 100755
--- a/scripts/build-oracle-ef.sh
+++ b/scripts/build-oracle-ef.sh
@@ -26,9 +26,9 @@ done > "$work/dates"
fetch() {
local d="$1"
local j
- j=$(curl -sf "https://www.missalemeum.com/en/api/v5/proper/$d" || true)
+ j=$(curl -sf --max-time 25 "https://www.missalemeum.com/en/api/v5/proper/$d" || true)
printf '%s' "$j" | jq -c --arg d "$d" \
- '{($d): (.[0].info | {tempora:(.tempora // ""), title:.title, rank:.rank, colour:(.colors|join(""))})}' \
+ '{($d): (.[0].info | {id:(.id // ""), tempora:(.tempora // ""), title:.title, rank:.rank, colour:(.colors|join(""))})}' \
2>/dev/null || true
}
export -f fetch
diff --git a/scripts/gen-sanctoral-ef.go b/scripts/gen-sanctoral-ef.go
new file mode 100644
index 0000000..f40fe34
--- /dev/null
+++ b/scripts/gen-sanctoral-ef.go
@@ -0,0 +1,402 @@
+//go:build ignore
+
+// gen-sanctoral-ef generates the EF (Extraordinary Form, 1962) universal
+// sanctoral (internal/caldata/tridentine-calendar.ini) from missalemeum's
+// per-date proper API (built on Divinum Officium's 1962 data — the same oracle
+// lectio's trad view and the EF regression test use).
+//
+// For each fixed calendar date it takes the sanctoral office missalemeum
+// observes (info.id "sancti:MM-DD:RANK:COLOUR"), with its proper Epistle
+// (Lectio) and Gospel (Evangelium) citations, plus any sancti co-celebrations
+// listed as commemorations. Several reference years are tried per date so a
+// saint whose date is a Sunday (or under a higher feast) in one year is still
+// captured, observed with its own readings, from another. Existing Latin names
+// in the file are preserved (missalemeum has no Latin titles).
+//
+// One-time; requires network. Run from the repo root:
+//
+// go run scripts/gen-sanctoral-ef.go
+//
+// Writes internal/caldata/tridentine-calendar.ini.
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "os"
+ "regexp"
+ "sort"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/lukaszkasprzak/lectio/internal/caldata"
+ "github.com/lukaszkasprzak/lectio/internal/calendar"
+)
+
+const ua = "Mozilla/5.0 (lectio EF sanctoral generator)"
+
+// client with a hard timeout: missalemeum occasionally stalls a connection
+// under concurrent load, and a timeout-less client would hang a worker forever.
+var client = &http.Client{Timeout: 25 * time.Second}
+
+// reference years: tried in order per date until the saint is observed (not
+// occulted by a Sunday or higher feast). Six years guarantee every fixed date
+// falls on a weekday in at least one of them.
+var years = []int{2025, 2026, 2027, 2028, 2029, 2024}
+
+// tempFeastSkip: fixed-date Lord's feasts that missalemeum files under sancti:
+// but the EF temporal engine (temporalEF) already computes — excluded so they
+// are not duplicated in the sanctoral layer.
+var tempFeastSkip = map[string]bool{"01-01": true, "01-06": true, "12-25": true}
+
+var (
+ citeRe = regexp.MustCompile(`\*([^*]+)\*`)
+ bookCommaRe = regexp.MustCompile(`^([^:]*?),\s+(\d+:)`)
+ chapDotRe = regexp.MustCompile(`(\d+)\.\s+(\d)`)
+ slugStripRe = regexp.MustCompile(`[^a-z0-9]+`)
+)
+
+// cleanCite fixes the two missalemeum citation glitches (verbatim from
+// scripts/genlect.go): a stray comma after the book, and a European
+// "chapter. verse" separator.
+func cleanCite(s string) string {
+ s = bookCommaRe.ReplaceAllString(strings.TrimSpace(s), "$1 $2")
+ if !strings.Contains(s, ":") {
+ s = chapDotRe.ReplaceAllString(s, "$1:$2")
+ }
+ return s
+}
+
+func slugify(title string) string {
+ s := strings.ToLower(title)
+ s = strings.NewReplacer(
+ "ł", "l", "æ", "ae", "œ", "oe", "é", "e", "è", "e", "ô", "o", "ç", "c",
+ "ï", "i", "ë", "e", "ü", "u", "ö", "o", "á", "a", "à", "a",
+ ).Replace(s)
+ s = slugStripRe.ReplaceAllString(s, "-")
+ s = strings.Trim(s, "-")
+ for _, p := range []string{"the-", "ss-", "st-", "s-"} {
+ s = strings.TrimPrefix(s, p)
+ }
+ return s
+}
+
+var colourWord = map[byte]string{
+ 'w': "white", 'r': "red", 'g': "green",
+ 'v': "violet", 'b': "black", 'p': "rose",
+}
+
+func colourOf(joined string) string {
+ if joined == "" {
+ return "white"
+ }
+ if c, ok := colourWord[joined[0]]; ok {
+ return c
+ }
+ return "white"
+}
+
+var rankWord = map[int]calendar.Rank{
+ 1: calendar.RankClass1, 2: calendar.RankClass2,
+ 3: calendar.RankClass3, 4: calendar.RankClass4,
+}
+
+func rankOf(n int) calendar.Rank {
+ if r, ok := rankWord[n]; ok {
+ return r
+ }
+ return calendar.RankClass4
+}
+
+// classOf marks the feasts of the Lord (class lord). A II class feast of the
+// Lord takes the place of a Sunday of the same class (1960 occurrence rules) —
+// e.g. the Purification (Presentation, Feb 2), the Exaltation of the Holy Cross
+// (Sep 14), the Dedication of the Lateran (Nov 9). Saint/BVM feasts of the same
+// class are only commemorated on a Sunday, so they need no marker.
+func classOf(en string) string {
+ l := strings.ToLower(en)
+ switch {
+ case strings.Contains(l, "holy cross"), // Exaltation / Finding of the Holy Cross
+ strings.Contains(l, "transfiguration"),
+ strings.Contains(l, "purification"), // the Presentation of the Lord
+ strings.Contains(l, "precious blood"),
+ strings.Contains(l, "holy name"),
+ strings.Contains(l, "dedication of the archbasilica"),
+ strings.Contains(l, "of our holy savior"),
+ strings.Contains(l, "of our lord jesus"),
+ strings.HasSuffix(l, "of our lord"):
+ return "lord"
+ }
+ return ""
+}
+
+// isSaintTitle rejects the temporal commemorations that share the sancti:
+// namespace (octave days, vigils) so only genuine saints/feasts are harvested.
+func isSaintTitle(t string) bool {
+ l := strings.ToLower(t)
+ for _, bad := range []string{"octave", "vigil", "feria", "ember", "rogation", "sunday", "within the"} {
+ if strings.Contains(l, bad) {
+ return false
+ }
+ }
+ return true
+}
+
+type mmInfo struct {
+ ID string `json:"id"`
+ Title string `json:"title"`
+ Rank int `json:"rank"`
+ Colors []string `json:"colors"`
+ Commemorations []struct {
+ ID string `json:"id"`
+ Title string `json:"title"`
+ } `json:"commemorations"`
+}
+
+type mmDay struct {
+ Info mmInfo `json:"info"`
+ Sections []struct {
+ ID string `json:"id"`
+ Body [][]string `json:"body"`
+ } `json:"sections"`
+}
+
+func fetchOnce(date string) (*mmDay, error) {
+ req, _ := http.NewRequest("GET", "https://www.missalemeum.com/en/api/v5/proper/"+date, nil)
+ req.Header.Set("User-Agent", ua)
+ resp, err := client.Do(req)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode != 200 {
+ return nil, fmt.Errorf("status %d", resp.StatusCode)
+ }
+ var data []mmDay
+ if err := json.NewDecoder(resp.Body).Decode(&data); err != nil || len(data) == 0 {
+ return nil, fmt.Errorf("decode/empty")
+ }
+ return &data[0], nil
+}
+
+// fetch retries transient failures (timeouts, 5xx) a few times before giving up.
+func fetch(date string) (*mmDay, error) {
+ var err error
+ for attempt := 0; attempt < 4; attempt++ {
+ var d *mmDay
+ if d, err = fetchOnce(date); err == nil {
+ return d, nil
+ }
+ }
+ return nil, err
+}
+
+type entry struct {
+ slug, date, colour, class, en, la, first, gospel string
+ rank calendar.Rank
+ observed bool // has readings / reliable rank
+}
+
+// idParts splits "sancti:MM-DD[sfx]:RANK:COLOUR" into rank word and colour word.
+func idParts(id string) (calendar.Rank, string) {
+ p := strings.Split(id, ":")
+ if len(p) < 4 {
+ return calendar.RankClass4, "white"
+ }
+ n, _ := strconv.Atoi(p[2])
+ return rankOf(n), colourOf(p[3])
+}
+
+func readingsFrom(d *mmDay) (first, gospel string) {
+ for _, s := range d.Sections {
+ if len(s.Body) == 0 || len(s.Body[0]) == 0 {
+ continue
+ }
+ m := citeRe.FindStringSubmatch(s.Body[0][0])
+ if m == nil {
+ continue
+ }
+ switch s.ID {
+ case "Lectio":
+ first = cleanCite(m[1])
+ case "Evangelium":
+ gospel = cleanCite(m[1])
+ }
+ }
+ return
+}
+
+// harvestDate returns the observed sanctoral office for a fixed MM-DD (nil if
+// the date is always a feria/temporal) plus any sancti commemorations seen.
+func harvestDate(mmdd string) (*entry, []entry) {
+ var comms []entry
+ seenComm := map[string]bool{}
+ for _, y := range years {
+ date := fmt.Sprintf("%04d-%s", y, mmdd)
+ if _, err := time.Parse("2006-01-02", date); err != nil {
+ continue // e.g. 02-29 in a common year
+ }
+ d, err := fetch(date)
+ if err != nil {
+ continue
+ }
+ for _, c := range d.Info.Commemorations {
+ if !strings.HasPrefix(c.ID, "sancti:") || !isSaintTitle(c.Title) {
+ continue
+ }
+ slug := slugify(c.Title)
+ if slug == "" || seenComm[slug] {
+ continue
+ }
+ seenComm[slug] = true
+ _, col := idParts(c.ID)
+ // A saint never OBSERVED in any harvest year — only ever commemorated —
+ // is a commemoration in the 1962 universal calendar: it does NOT have
+ // its own Mass and yields to the ferial office (which is celebrated with
+ // the saint commemorated). Rank it RankCommemoration, not the id's class
+ // (missalemeum reuses class-3/4 for these), so a genuine IV class feast
+ // still outranks the feria while a commemoration does not. If the same
+ // slug is observed in another year, that observed entry supersedes this.
+ comms = append(comms, entry{slug: slug, date: mmdd, colour: col, en: c.Title, rank: calendar.RankCommemoration})
+ }
+ if strings.HasPrefix(d.Info.ID, "sancti:") && isSaintTitle(d.Info.Title) {
+ // A few Lord's feasts live in missalemeum's sancti namespace but the
+ // EF temporal engine already computes them (Nativity, Circumcision,
+ // Epiphany); exclude them so they aren't duplicated in the sanctoral.
+ // NOTE: don't skip merely because the temporal is class-1/2 in THIS
+ // year — a real saint (e.g. Sts Peter & Paul) falling on a Sunday must
+ // still be captured; another harvest year observes it on a weekday.
+ if tempFeastSkip[mmdd] || strings.Contains(strings.ToLower(d.Info.Title), "christ the king") {
+ // Christ the King is movable (last Sunday of October) and computed
+ // by the temporal engine; missalemeum files it under sancti, so it
+ // would otherwise leak into the sanctoral at a spurious fixed date.
+ return nil, comms
+ }
+ first, gospel := readingsFrom(d)
+ col := colourOf(strings.Join(d.Info.Colors, ""))
+ return &entry{
+ slug: slugify(d.Info.Title), date: mmdd, colour: col, class: classOf(d.Info.Title),
+ en: d.Info.Title, first: first, gospel: gospel,
+ rank: rankOf(d.Info.Rank), observed: true,
+ }, comms
+ }
+ }
+ return nil, comms
+}
+
+func main() {
+ // Existing Latin names to preserve (missalemeum has no Latin titles).
+ la := map[string]string{}
+ for slug, rc := range caldata.Tridentine().Cels {
+ if v := rc.Fields["name.la"]; v != "" {
+ la[slug] = v
+ }
+ }
+
+ // All fixed calendar dates (from a leap year so 02-29 is included).
+ var dates []string
+ for d := time.Date(2028, 1, 1, 0, 0, 0, 0, time.UTC); d.Year() == 2028; d = d.AddDate(0, 0, 1) {
+ dates = append(dates, d.Format("01-02"))
+ }
+
+ type res struct {
+ obs *entry
+ comms []entry
+ }
+ results := make([]res, len(dates))
+ var wg sync.WaitGroup
+ sem := make(chan struct{}, 6)
+ for i, mmdd := range dates {
+ wg.Add(1)
+ go func(i int, mmdd string) {
+ defer wg.Done()
+ sem <- struct{}{}
+ defer func() { <-sem }()
+ obs, comms := harvestDate(mmdd)
+ results[i] = res{obs, comms}
+ fmt.Fprintf(os.Stderr, ".")
+ }(i, mmdd)
+ }
+ wg.Wait()
+ fmt.Fprintln(os.Stderr)
+
+ entries := map[string]entry{}
+ add := func(e entry) {
+ if cur, ok := entries[e.slug]; ok {
+ if cur.observed && !e.observed {
+ return // don't let a commemoration downgrade an observed office
+ }
+ if cur.observed && e.observed {
+ return // first observed year wins
+ }
+ }
+ entries[e.slug] = e
+ }
+ for _, r := range results {
+ if r.obs != nil {
+ add(*r.obs)
+ }
+ }
+ for _, r := range results { // commemorations after, so observed offices win
+ for _, c := range r.comms {
+ if _, ok := entries[c.slug]; !ok {
+ add(c)
+ }
+ }
+ }
+
+ es := make([]entry, 0, len(entries))
+ for _, e := range entries {
+ if l := la[e.slug]; l != "" {
+ e.la = l
+ }
+ es = append(es, e)
+ }
+ sort.Slice(es, func(i, j int) bool {
+ if es[i].date != es[j].date {
+ return es[i].date < es[j].date
+ }
+ return es[i].slug < es[j].slug
+ })
+
+ var b strings.Builder
+ b.WriteString("; General Roman Calendar of 1962 (Extraordinary Form) — universal sanctoral.\n")
+ b.WriteString("; The temporal cycle (seasons, Sundays, Easter/Christmas/Epiphany, Ascension,\n")
+ b.WriteString("; Pentecost, Trinity, Corpus Christi, Sacred Heart, Christ the King) is computed\n")
+ b.WriteString("; by internal/calendar (temporalEF) and is NOT listed here.\n")
+ b.WriteString("; Ranks use the 1960 Code of Rubrics: class-1..class-4.\n")
+ b.WriteString("; Generated by scripts/gen-sanctoral-ef.go from missalemeum (Divinum Officium 1962\n")
+ b.WriteString("; data). Latin names are hand-curated where present. See NOTICE.\n\n")
+ b.WriteString("[layer]\nid = tridentine\nname = General Roman Calendar of 1962\ntype = universal\n")
+ for _, e := range es {
+ fmt.Fprintf(&b, "\n[%s]\ndate = %s\nrank = %s\ncolour = %s\n", e.slug, e.date, e.rank, e.colour)
+ if e.class != "" {
+ fmt.Fprintf(&b, "class = %s\n", e.class)
+ }
+ fmt.Fprintf(&b, "name.en = %s\n", e.en)
+ if e.la != "" {
+ fmt.Fprintf(&b, "name.la = %s\n", e.la)
+ }
+ if e.first != "" {
+ fmt.Fprintf(&b, "reading.first = %s\n", e.first)
+ }
+ if e.gospel != "" {
+ fmt.Fprintf(&b, "reading.gospel = %s\n", e.gospel)
+ }
+ }
+ if err := os.WriteFile("internal/caldata/tridentine-calendar.ini", []byte(b.String()), 0o644); err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+ nObs := 0
+ for _, e := range es {
+ if e.observed {
+ nObs++
+ }
+ }
+ fmt.Fprintf(os.Stderr, "wrote %d EF sanctoral celebrations (%d observed w/ readings, %d commemoration-only)\n",
+ len(es), nObs, len(es)-nObs)
+}