aboutsummaryrefslogtreecommitdiff
path: root/internal/calendar/precedence.go
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-07-27 12:19:17 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-07-27 12:19:17 +0200
commit4c08e94dbcce8dc7757afba3001abe509bd2b6a8 (patch)
treee6d7025c3f96b5a50a0a3565d110fc5013afe16a /internal/calendar/precedence.go
parent9839ea9f2257d843c08497f07e9a5d23dc47e0fb (diff)
downloadlectio-4c08e94dbcce8dc7757afba3001abe509bd2b6a8.tar.gz
lectio-4c08e94dbcce8dc7757afba3001abe509bd2b6a8.zip
feat(calendar): Universal Norms precedence bands + pick
Diffstat (limited to 'internal/calendar/precedence.go')
-rw-r--r--internal/calendar/precedence.go71
1 files changed, 71 insertions, 0 deletions
diff --git a/internal/calendar/precedence.go b/internal/calendar/precedence.go
new file mode 100644
index 0000000..b013b77
--- /dev/null
+++ b/internal/calendar/precedence.go
@@ -0,0 +1,71 @@
+package calendar
+
+import "sort"
+
+// candidate is one celebration competing for a given day: the temporal day, or
+// a sanctoral celebration landing on it. The flags come from the temporal
+// builder (Task 4) or are empty for sanctoral entries.
+type candidate struct {
+ Cel Celebration
+ Temporal bool
+ Privileged bool // band 1-2 temporal day
+ PrivFeria bool // band 9 privileged feria
+ Sunday bool // Ordinary/Christmas Sunday (band 6)
+ Season Season
+}
+
+// precedence maps a candidate to its band in the Table of Liturgical Days
+// (Universal Norms, 1969) — lower = higher precedence. "Proper" celebrations
+// (a non-universal, non-temporal layer) sit one band below their General
+// Calendar counterpart.
+func precedence(c candidate) int {
+ proper := c.Cel.Layer != "" && c.Cel.Layer != "universal" && c.Cel.Layer != "temporal"
+ if c.Temporal {
+ switch {
+ case c.Season == Triduum:
+ return 1
+ case c.Privileged:
+ return 2
+ case c.Cel.Rank == RankSolemnity: // Trinity, Corpus Christi, Sacred Heart, Christ the King
+ return 3
+ case c.Cel.Rank == RankFeast: // feasts of the Lord (Baptism, Holy Family)
+ return 5
+ case c.Sunday:
+ return 6
+ case c.PrivFeria:
+ return 9
+ default:
+ return 13
+ }
+ }
+ switch c.Cel.Rank {
+ case RankSolemnity:
+ if proper {
+ return 4
+ }
+ return 3
+ case RankFeast:
+ if proper {
+ return 8
+ }
+ return 7
+ case RankMemorial:
+ if proper {
+ return 11
+ }
+ return 10
+ case RankOptional:
+ return 12
+ default:
+ return 13
+ }
+}
+
+// pick returns the highest-precedence candidate as observed and the rest as
+// others (commemorations / optional memorials), stably ordered by precedence.
+func pick(cands []candidate) (candidate, []candidate) {
+ sorted := make([]candidate, len(cands))
+ copy(sorted, cands)
+ sort.SliceStable(sorted, func(i, j int) bool { return precedence(sorted[i]) < precedence(sorted[j]) })
+ return sorted[0], sorted[1:]
+}