1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
// Package calendar computes the Ordinary Form liturgical day for any Gregorian
// date, offline and from first principles. It imports only the standard library.
package calendar
import "time"
// Rank is a form-specific rank token. Ordinary Form uses the values below;
// the Extraordinary Form uses its own (class-1..class-4, commemoration, ferial).
// Each form's precedence interprets its own vocabulary.
type Rank string
const (
// Ordinary Form ranks.
RankFerial Rank = "ferial" // ordinary weekday
RankOptional Rank = "optional" // optional memorial
RankMemorial Rank = "memorial" // obligatory memorial
RankFeast Rank = "feast" //
RankSolemnity Rank = "solemnity" //
// Extraordinary Form ranks (1960 Code of Rubrics): I-IV class + commemoration.
RankClass1 Rank = "class-1"
RankClass2 Rank = "class-2"
RankClass3 Rank = "class-3"
RankClass4 Rank = "class-4"
RankCommemoration Rank = "commemoration"
)
// ofRankOrder orders the Ordinary Form ranks for the few `<` comparisons in the
// OF path (ferial lowest, solemnity highest). Unknown/empty → 0 (ferial-level).
func ofRankOrder(r Rank) int {
switch r {
case RankSolemnity:
return 4
case RankFeast:
return 3
case RankMemorial:
return 2
case RankOptional:
return 1
default:
return 0
}
}
type Class int
const (
ClassNone Class = iota // temporal / ferial
ClassSaint // a saint
ClassBVM // the Blessed Virgin Mary
ClassLord // the Lord
)
type Colour string
const (
White Colour = "white"
Red Colour = "red"
Green Colour = "green"
Violet Colour = "violet"
Rose Colour = "rose"
Black Colour = "black"
)
type Season string
const (
Advent Season = "advent"
Christmas Season = "christmas"
Lent Season = "lent"
Triduum Season = "triduum"
Easter_ Season = "easter" // trailing underscore: Easter is the func name
Ordinary Season = "ordinary"
)
type Reading struct{ Part, Citation string }
type Mass struct {
Variant string // "" = the day Mass; e.g. "vigil"
Readings []Reading
}
// DateSpec is a celebration's raw date expression, resolved by resolveDate:
// "MM-DD" (fixed) | "easter±N" | "christmas±N" | "sunday-after MM-DD".
type DateSpec string
// RawCelebration is a celebration's fields exactly as parsed from a layer,
// before typing/merging. Fields are raw INI values keyed by INI key
// (e.g. "rank", "name.pl"); Variants holds "[slug/variant]" sub-sections.
type RawCelebration struct {
Fields map[string]string
Variants map[string]map[string]string
}
// Celebration is the typed, built form used in results.
type Celebration struct {
Slug string
Name map[string]string // lang -> name
Rank Rank
Class Class
Colour Colour
Date DateSpec
Masses []Mass
Layer string // provenance
}
// Layer is one calendar layer (the embedded universal base, or later an
// override file). Cels is keyed by slug; insertion order is not significant.
type Layer struct {
ID, Name, Type string
Cels map[string]RawCelebration
}
// Selection carries the config choices that steer computation.
type Selection struct {
Form string // "new" (OF). "old" reserved.
Epiphany string // "fixed" | "sunday"
Ascension string // "thursday" | "sunday"
CorpusChristi string // "thursday" | "sunday"
}
// DefaultSelection is the Universal Roman Calendar default.
func DefaultSelection() Selection {
return Selection{Form: "new", Epiphany: "fixed", Ascension: "thursday", CorpusChristi: "thursday"}
}
type LiturgicalDay struct {
Date time.Time
Season Season
Week int
Weekday time.Weekday
Observed Celebration
Others []Celebration
Colour Colour
ObservedBand int // Table-of-Liturgical-Days band of the observed celebration (1=highest)
SundayCycle string // "A" | "B" | "C"
WeekdayCycle string // "I" | "II"
}
// ParseRank validates a rank token (OF or EF vocabulary), falling back to
// RankFerial for anything unknown.
func ParseRank(s string) Rank {
switch Rank(s) {
case RankSolemnity, RankFeast, RankMemorial, RankOptional, RankFerial,
RankClass1, RankClass2, RankClass3, RankClass4, RankCommemoration:
return Rank(s)
default:
return RankFerial
}
}
func ParseClass(s string) Class {
switch s {
case "lord":
return ClassLord
case "bvm":
return ClassBVM
case "saint":
return ClassSaint
default:
return ClassNone
}
}
func ParseColour(s string) Colour {
switch Colour(s) {
case White, Red, Green, Violet, Rose, Black:
return Colour(s)
default:
return ""
}
}
|