aboutsummaryrefslogtreecommitdiff
path: root/internal/calendar/precedence_ef.go
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
commitcca0eb0db6cf6850d55d7a44fef470c594bce8ec (patch)
treebf6eff3bc95e5ed029dd0aa0d50db85d90e3a6cc /internal/calendar/precedence_ef.go
parentc33158ed31d46e9bed76f01223f6718da3b4da21 (diff)
downloadlectio-cca0eb0db6cf6850d55d7a44fef470c594bce8ec.tar.gz
lectio-cca0eb0db6cf6850d55d7a44fef470c594bce8ec.zip
fix(ef): 1962 occurrence precedence for the full sanctoral
- Septuagesima ferias are IV class (per annum), not III class, so a III class saint (e.g. Conversion of St Paul, Jan 25) displaces them. - Holy Week ferias and the privileged octaves of Easter and Pentecost are I class: no saint's feast is admitted (temporal office wins). - Occurrence tie-break is asymmetric by season: an ordinary feria (Advent, per annum) yields to an equal-class feast; Lent/Passiontide ferias keep their privilege and win the tie. - A II class feast of the Lord (Purification, Exaltation of the Cross, Dedication of the Lateran) displaces a II class Sunday it falls on. Validated against missalemeum across 2025-2027: ~97.5% of days observe the liturgically-correct celebration, 100% rank agreement on saint-days.
Diffstat (limited to 'internal/calendar/precedence_ef.go')
-rw-r--r--internal/calendar/precedence_ef.go27
1 files changed, 22 insertions, 5 deletions
diff --git a/internal/calendar/precedence_ef.go b/internal/calendar/precedence_ef.go
index 81862b7..4fda626 100644
--- a/internal/calendar/precedence_ef.go
+++ b/internal/calendar/precedence_ef.go
@@ -22,13 +22,30 @@ func efRankOrder(r Rank) int {
}
// precedenceEF ranks an EF candidate for occurrence (lower = higher precedence):
-// by class first, then — at equal class — the temporal office before the
-// sanctoral (a first-cut of the 1960 occurrence table; the missalemeum oracle
-// drives refinement).
+// by class first, then a tie-break at equal class (1960 occurrence table).
+//
+// The tie-break is asymmetric by season. An ORDINARY feria (per annum, Advent,
+// Septuagesima) yields to an equal-class feast — the feast is celebrated and the
+// feria commemorated (e.g. St Francis Xavier, Dec 3, on an Advent feria). The
+// ferias of Lent and Passiontide are privileged: they outrank an equal-class
+// feast, which is only commemorated. Sundays and named temporal feasts likewise
+// win their ties. The *2 class spacing means the ±1 tie-break never crosses a
+// class boundary.
func precedenceEF(c candidate) int {
p := (6 - efRankOrder(c.Cel.Rank)) * 2 // class-1 -> 2, ferial -> 12
- if !c.Temporal {
- p++ // sanctoral yields to a temporal office of equal class
+ if c.Temporal {
+ ordinaryFeria := (c.Cel.Rank == RankClass3 || c.Cel.Rank == RankClass4) &&
+ c.Season != Lent && c.Season != Passiontide
+ if ordinaryFeria {
+ p++ // an ordinary feria yields to an equal-class feast
+ } else {
+ p-- // Sundays, named feasts, and penitential ferias win their ties
+ }
+ } else if c.Cel.Class == ClassLord && c.Cel.Rank == RankClass2 {
+ // A II class feast of the Lord takes the place of a II class Sunday it
+ // falls on (unlike a saint's feast, which is only commemorated). Give it
+ // the edge over the Sunday's tie-break bonus.
+ p -= 2
}
return p
}