diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-07-27 12:19:17 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-07-27 12:19:17 +0200 |
| commit | 4c08e94dbcce8dc7757afba3001abe509bd2b6a8 (patch) | |
| tree | e6d7025c3f96b5a50a0a3565d110fc5013afe16a /internal/calendar/precedence.go | |
| parent | 9839ea9f2257d843c08497f07e9a5d23dc47e0fb (diff) | |
| download | lectio-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.go | 71 |
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:] +} |
