calendarium-romanum 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/config/locales/cs.yml +37 -1
  3. data/config/locales/en.yml +37 -1
  4. data/config/locales/it.yml +36 -2
  5. data/config/locales/la.yml +35 -1
  6. data/data/README.md +62 -4
  7. data/data/czech-brno-cs.txt +10 -2
  8. data/data/czech-budejovice-cs.txt +10 -2
  9. data/data/czech-cechy-cs.txt +9 -2
  10. data/data/czech-cs.txt +7 -1
  11. data/data/czech-hradec-cs.txt +10 -2
  12. data/data/czech-litomerice-cs.txt +10 -2
  13. data/data/czech-morava-cs.txt +9 -2
  14. data/data/czech-olomouc-cs.txt +10 -2
  15. data/data/czech-ostrava-cs.txt +10 -2
  16. data/data/czech-plzen-cs.txt +10 -2
  17. data/data/czech-praha-cs.txt +10 -2
  18. data/data/universal-en.txt +4 -1
  19. data/data/universal-it.txt +4 -1
  20. data/data/universal-la.txt +4 -1
  21. data/lib/calendarium-romanum.rb +3 -0
  22. data/lib/calendarium-romanum/calendar.rb +13 -6
  23. data/lib/calendarium-romanum/data.rb +1 -1
  24. data/lib/calendarium-romanum/day.rb +0 -3
  25. data/lib/calendarium-romanum/enums.rb +41 -21
  26. data/lib/calendarium-romanum/ordinalizer.rb +37 -0
  27. data/lib/calendarium-romanum/sanctoraleloader.rb +13 -2
  28. data/lib/calendarium-romanum/temporale.rb +145 -232
  29. data/lib/calendarium-romanum/temporale/dates.rb +151 -0
  30. data/lib/calendarium-romanum/temporale/extensions/christ_eternal_priest.rb +25 -0
  31. data/lib/calendarium-romanum/transfers.rb +23 -5
  32. data/lib/calendarium-romanum/version.rb +1 -1
  33. data/spec/calendar_spec.rb +72 -19
  34. data/spec/dates_spec.rb +45 -0
  35. data/spec/rank_spec.rb +2 -2
  36. data/spec/readme_spec.rb +11 -9
  37. data/spec/spec_helper.rb +16 -1
  38. data/spec/temporale_spec.rb +252 -126
  39. metadata +19 -1
@@ -1,5 +1,13 @@
1
- # Czech Republic
2
- # diocese of Plzeň
1
+ ---
2
+ title: kalendář plzeňské diecéze
3
+ description: Calendar for diocese of Plzeň, Czech Republic
4
+ locale: cs
5
+ country: cz
6
+ diocese: Plzeň
7
+ extends:
8
+ - czech-cs.txt
9
+ - czech-cechy-cs.txt
10
+ ---
3
11
 
4
12
  7/14 f2.8 R : Bl. Hroznaty, mučedníka, hlavního patrona diecéze
5
13
 
@@ -1,4 +1,12 @@
1
- # Czech Republic
2
- # archdiocese of Prague
1
+ ---
2
+ title: kalendář pražské arcidiecéze
3
+ description: Calendar for archdiocese of Prague, Czech Republic
4
+ locale: cs
5
+ country: cz
6
+ diocese: Praha
7
+ extends:
8
+ - czech-cs.txt
9
+ - czech-cechy-cs.txt
10
+ ---
3
11
 
4
12
  5/12 f2.8 : Výročí posvěcení katedrály sv. Víta, Václava a Vojtěcha
@@ -1,5 +1,8 @@
1
- # General Roman Calendar in English
1
+ ---
2
+ title: General Roman Calendar
3
+ locale: en
2
4
  # source: https://en.wikipedia.org/wiki/General_Roman_Calendar
5
+ ---
3
6
 
4
7
  = 1
5
8
  2 m : Saints Basil the Great and Gregory Nazianzen, bishops and doctors
@@ -1,4 +1,7 @@
1
- # Calendario Romano Generale
1
+ ---
2
+ title: Calendario Romano Generale
3
+ locale: it
4
+ ---
2
5
 
3
6
  = 1
4
7
  2 m : Santi Basilio Magno e Gregorio Nazianzeno, vescovi e dottori della Chiesa
@@ -1,5 +1,8 @@
1
- # General Roman Calendar in Latin
1
+ ---
2
+ title: Calendarium Romanum Generale
3
+ locale: la
2
4
  # source: http://www.binetti.ru/collectio/liturgia/missale_files/crg.htm
5
+ ---
3
6
 
4
7
  = 1
5
8
  2 m : Ss. Basilii et Gregorii Nazianzeni, episcoporum et Ecclesiae doctorum
@@ -7,6 +7,8 @@ enums
7
7
  data
8
8
  calendar
9
9
  temporale
10
+ temporale/dates
11
+ temporale/extensions/christ_eternal_priest
10
12
  sanctorale
11
13
  sanctoraleloader
12
14
  sanctorale_factory
@@ -14,6 +16,7 @@ transfers
14
16
  day
15
17
  abstract_date
16
18
  util
19
+ ordinalizer
17
20
  }.each do |f|
18
21
  require_relative File.join('calendarium-romanum', f)
19
22
  end
@@ -12,10 +12,11 @@ module CalendariumRomanum
12
12
  # year: Integer
13
13
  # returns a calendar for the liturgical year beginning with
14
14
  # Advent of the specified civil year.
15
- def initialize(year, sanctorale=nil)
15
+ def initialize(year, sanctorale=nil, temporale_class=nil)
16
16
  @year = year
17
- @temporale = Temporale.new(year)
18
17
  @sanctorale = sanctorale || Sanctorale.new
18
+ @temporale_class = temporale_class || Temporale
19
+ @temporale = @temporale_class.new(year)
19
20
  @transferred = Transfers.new(@temporale, @sanctorale)
20
21
  end
21
22
 
@@ -45,8 +46,8 @@ module CalendariumRomanum
45
46
 
46
47
  # creates a Calendar for the liturgical year including given
47
48
  # date
48
- def for_day(date, sanctorale=nil)
49
- return new(Temporale.liturgical_year(date), sanctorale)
49
+ def for_day(date, *constructor_args)
50
+ return new(Temporale.liturgical_year(date), *constructor_args)
50
51
  end
51
52
  end # class << self
52
53
 
@@ -57,13 +58,13 @@ module CalendariumRomanum
57
58
 
58
59
  # returns a Calendar for the subsequent year
59
60
  def succ
60
- c = Calendar.new @year + 1, @sanctorale
61
+ c = Calendar.new @year + 1, @sanctorale, @temporale_class
61
62
  return c
62
63
  end
63
64
 
64
65
  # returns a Calendar for the previous year
65
66
  def pred
66
- c = Calendar.new @year - 1, @sanctorale
67
+ c = Calendar.new @year - 1, @sanctorale, @temporale_class
67
68
  return c
68
69
  end
69
70
 
@@ -124,6 +125,12 @@ module CalendariumRomanum
124
125
  else
125
126
  return st
126
127
  end
128
+ elsif t.rank == Ranks::FERIAL_PRIVILEGED && st.first.rank.memorial?
129
+ st = st.collect do |c|
130
+ Celebration.new(c.title, Ranks::COMMEMORATION, t.colour)
131
+ end
132
+ st.unshift t
133
+ return st
127
134
  end
128
135
  end
129
136
 
@@ -1,5 +1,5 @@
1
1
  module CalendariumRomanum
2
- # allows easy access to the bundled data files
2
+ # allows easy access to bundled data files
3
3
  class Data < Enum
4
4
 
5
5
  class SanctoraleFile
@@ -30,9 +30,6 @@ module CalendariumRomanum
30
30
 
31
31
  # an Array of Celebrations, possibly empty
32
32
  attr_reader :celebrations
33
-
34
- # Celebration of the following day if it has first vespers
35
- attr_reader :vespers
36
33
  end
37
34
 
38
35
  # information on one particular celebration of the liturgical year
@@ -1,15 +1,45 @@
1
1
  module CalendariumRomanum
2
2
 
3
+ class Colour
4
+ def initialize(symbol)
5
+ @symbol = symbol
6
+ end
7
+
8
+ attr_reader :symbol
9
+ alias to_sym symbol
10
+ end
11
+
12
+ class Colours < Enum
13
+ values do
14
+ [
15
+ GREEN = Colour.new(:green),
16
+ VIOLET = Colour.new(:violet),
17
+ WHITE = Colour.new(:white),
18
+ RED = Colour.new(:red)
19
+ ]
20
+ end
21
+ end
22
+
23
+ Colors = Colours
24
+
25
+ class Season
26
+ def initialize(symbol, colour)
27
+ @symbol = symbol
28
+ @colour = colour
29
+ end
30
+
31
+ attr_reader :symbol, :colour
32
+ alias to_sym symbol
33
+ end
34
+
3
35
  class Seasons < Enum
4
36
  values do
5
37
  [
6
- ADVENT = :advent,
7
- CHRISTMAS = :christmas,
8
- LENT = :lent,
9
- EASTER = :easter,
10
- ORDINARY = :ordinary,
11
- # is Triduum Sacrum a special season? For now I count Friday and Saturday
12
- # to the Lent, Sunday to the Easter time
38
+ ADVENT = Season.new(:advent, Colours::VIOLET),
39
+ CHRISTMAS = Season.new(:christmas, Colours::WHITE),
40
+ LENT = Season.new(:lent, Colours::VIOLET),
41
+ EASTER = Season.new(:easter, Colours::WHITE),
42
+ ORDINARY = Season.new(:ordinary, Colours::GREEN)
13
43
  ]
14
44
  end
15
45
  end
@@ -37,21 +67,11 @@ module CalendariumRomanum
37
67
  MEMORIAL_GENERAL = Rank.new(3.10, 'rank.3_10', 'rank.short.memorial'),
38
68
  MEMORIAL_PROPER = Rank.new(3.11, 'rank.3_11', 'rank.short.memorial'),
39
69
  MEMORIAL_OPTIONAL = Rank.new(3.12, 'rank.3_12', 'rank.short.memorial_opt'),
40
- FERIAL = Rank.new(3.13, 'rank.3_13', 'rank.short.ferial')
70
+ FERIAL = Rank.new(3.13, 'rank.3_13', 'rank.short.ferial'),
71
+ # not included as a celebration rank on it's own
72
+ # in the Table of Liturgical Days
73
+ COMMEMORATION = Rank.new(4.0, 'rank.4_0', 'rank.short.commemoration')
41
74
  ]
42
75
  end
43
76
  end
44
-
45
- class Colours < Enum
46
- values do
47
- [
48
- GREEN = :green,
49
- VIOLET = :violet,
50
- WHITE = :white,
51
- RED = :red
52
- ]
53
- end
54
- end
55
-
56
- Colors = Colours
57
77
  end
@@ -0,0 +1,37 @@
1
+ require 'roman-numerals'
2
+
3
+ module CalendariumRomanum
4
+ # Knows how to produce localized ordinals
5
+ class Ordinalizer
6
+ class << self
7
+ def ordinal(number, locale: nil)
8
+ locale ||= I18n.locale
9
+
10
+ case locale
11
+ when :cs
12
+ "#{number}."
13
+ when :en
14
+ english_ordinal(number)
15
+ # when :it # TODO
16
+ when :la, :it
17
+ RomanNumerals.to_roman number
18
+ else
19
+ number
20
+ end
21
+ end
22
+
23
+ def english_ordinal(number)
24
+ case number
25
+ when 1
26
+ '1st'
27
+ when 2
28
+ '2nd'
29
+ when 3
30
+ '3rd'
31
+ else
32
+ "#{number}th"
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -30,9 +30,20 @@ module CalendariumRomanum
30
30
  def load(src, dest=nil)
31
31
  dest ||= Sanctorale.new
32
32
 
33
+ in_front_matter = false
33
34
  month_section = nil
34
- src.each_line.each_with_index do |l, li|
35
- line_num = li + 1
35
+ src.each_line.with_index(1) do |l, line_num|
36
+ # skip YAML front matter
37
+ if line_num == 1 && l.start_with?('---')
38
+ in_front_matter = true
39
+ next
40
+ elsif in_front_matter
41
+ if l.start_with?('---')
42
+ in_front_matter = false
43
+ end
44
+
45
+ next
46
+ end
36
47
 
37
48
  # strip whitespace and comments
38
49
  l.sub!(/#.*/, '')
@@ -7,21 +7,22 @@ module CalendariumRomanum
7
7
 
8
8
  WEEK = 7
9
9
 
10
- SEASON_COLOUR = {
11
- Seasons::ADVENT => Colours::VIOLET,
12
- Seasons::CHRISTMAS => Colours::WHITE,
13
- Seasons::ORDINARY => Colours::GREEN,
14
- Seasons::LENT => Colours::VIOLET,
15
- Seasons::EASTER => Colours::WHITE,
16
- }
17
-
18
10
  # year is Integer - the civil year when the liturgical year begins
19
- def initialize(year=nil)
11
+ def initialize(year)
20
12
  @year = year
21
- prepare_solemnities unless @year.nil?
13
+ prepare_solemnities
22
14
  end
23
15
 
16
+ attr_reader :year
17
+
24
18
  class << self
19
+ # Creates a subclass with specified extension modules included
20
+ def with_extensions(*extensions)
21
+ Class.new(self) do
22
+ extensions.each {|e| include e }
23
+ end
24
+ end
25
+
25
26
  # Determines liturgical year for the given date
26
27
  def liturgical_year(date)
27
28
  year = date.year
@@ -39,197 +40,106 @@ module CalendariumRomanum
39
40
  def for_day(date)
40
41
  return new(liturgical_year(date))
41
42
  end
42
- end
43
-
44
- def start_date(year=nil)
45
- first_advent_sunday(year)
46
- end
47
-
48
- def end_date(year=nil)
49
- year ||= @year
50
- first_advent_sunday(year+1) - 1
51
- end
52
-
53
- def date_range(year=nil)
54
- start_date(year) .. end_date(year)
55
- end
56
43
 
57
- def range_check(date)
58
- # necessary in order to handle Date correctly
59
- date = date.to_date if date.class != Date
60
-
61
- unless date_range.include? date
62
- raise RangeError.new "Date out of range #{date}"
44
+ C = Struct.new(:date_method, :celebration)
45
+ private_constant :C
46
+
47
+ # implementation detail, not to be touched by client code
48
+ def celebrations
49
+ @celebrations ||=
50
+ begin
51
+ [
52
+ c(:nativity, Ranks::PRIMARY),
53
+ c(:holy_family, Ranks::FEAST_LORD_GENERAL),
54
+ c(:mother_of_god, Ranks::SOLEMNITY_GENERAL),
55
+ c(:epiphany, Ranks::PRIMARY),
56
+ c(:baptism_of_lord, Ranks::FEAST_LORD_GENERAL),
57
+ c(:ash_wednesday, Ranks::PRIMARY, Colours::VIOLET),
58
+ c(:good_friday, Ranks::TRIDUUM, Colours::RED),
59
+ c(:holy_saturday, Ranks::TRIDUUM, Colours::VIOLET),
60
+ c(:palm_sunday, Ranks::PRIMARY, Colours::RED),
61
+ c(:easter_sunday, Ranks::TRIDUUM),
62
+ c(:ascension, Ranks::PRIMARY),
63
+ c(:pentecost, Ranks::PRIMARY, Colours::RED),
64
+ c(:holy_trinity, Ranks::SOLEMNITY_GENERAL),
65
+ c(:body_blood, Ranks::SOLEMNITY_GENERAL),
66
+ c(:sacred_heart, Ranks::SOLEMNITY_GENERAL),
67
+ c(:christ_king, Ranks::SOLEMNITY_GENERAL),
68
+
69
+ # Immaculate Heart of Mary is actually (currently the only one)
70
+ # movable *sanctorale* feast, but as it would make little sense
71
+ # to add support for movable sanctorale feasts because of
72
+ # a single one, we cheat a bit and handle it in temporale.
73
+ c(:immaculate_heart, Ranks::MEMORIAL_GENERAL),
74
+ ]
75
+ end
63
76
  end
64
- end
65
-
66
- # converts an AbstractDate to a Date in the given
67
- # liturgical year
68
- def concretize_abstract_date(abstract_date)
69
- d = abstract_date.concretize(@year + 1)
70
- if date_range.include? d
71
- d
72
- else
73
- abstract_date.concretize(@year)
74
- end
75
- end
76
77
 
77
- def weekday_before(weekday, date)
78
- if date.wday == weekday then
79
- return date - WEEK
80
- elsif weekday < date.wday
81
- return date - (date.wday - weekday)
82
- else
83
- return date - (date.wday + WEEK - weekday)
84
- end
85
- end
86
-
87
- def weekday_after(weekday, date)
88
- if date.wday == weekday then
89
- return date + WEEK
90
- elsif weekday > date.wday
91
- return date + (weekday - date.wday)
92
- else
93
- return date + (WEEK - date.wday + weekday)
94
- end
95
- end
96
-
97
- def octave_of(date)
98
- date + WEEK
99
- end
100
-
101
- WEEKDAYS = %w{sunday monday tuesday wednesday thursday friday saturday}
102
- WEEKDAYS.each_with_index do |weekday, weekday_i|
103
- define_method "#{weekday}_before" do |date|
104
- send('weekday_before', weekday_i, date)
105
- end
106
-
107
- define_method "#{weekday}_after" do |date|
108
- send('weekday_after', weekday_i, date)
109
- end
110
- end
111
-
112
- # first_advent_sunday -> advent_sunday(1)
113
- %w{first second third fourth}.each_with_index do |word,i|
114
- define_method "#{word}_advent_sunday" do |year=nil|
115
- send("advent_sunday", i + 1, year)
116
- end
117
- end
78
+ # Hook point for extensions to add new celebrations
79
+ def add_celebration(date_method, celebration)
80
+ if self == Temporale
81
+ raise RuntimeError.new("Don't add celebrations to Temporale itself, subclass it and modify the subclass.")
82
+ end
118
83
 
119
- def advent_sunday(num, year=nil)
120
- advent_sundays_total = 4
121
- unless (1..advent_sundays_total).include? num
122
- raise ArgumentError.new "Invalid Advent Sunday #{num}"
84
+ celebrations << C.new(date_method, celebration)
123
85
  end
124
86
 
125
- year ||= @year
126
- return sunday_before(nativity(year)) - ((advent_sundays_total - num) * WEEK)
127
- end
87
+ private
128
88
 
129
- def nativity(year=nil)
130
- year ||= @year
131
- return Date.new(year, 12, 25)
132
- end
89
+ def c(date_method, rank, colour=Colours::WHITE)
90
+ title = proc { I18n.t("temporale.solemnity.#{date_method}") }
133
91
 
134
- def holy_family(year=nil)
135
- year ||= @year
136
- xmas = nativity(year)
137
- if xmas.sunday?
138
- return Date.new(year, 12, 30)
139
- else
140
- sunday_after(xmas)
92
+ C.new(
93
+ date_method,
94
+ Celebration.new(title, rank, colour)
95
+ )
141
96
  end
142
97
  end
143
98
 
144
- def mother_of_god(year=nil)
145
- octave_of(nativity(year))
99
+ def start_date
100
+ first_advent_sunday
146
101
  end
147
102
 
148
- def epiphany(year=nil)
149
- year ||= @year
150
- return Date.new(year+1, 1, 6)
103
+ def end_date
104
+ Dates.first_advent_sunday(year+1) - 1
151
105
  end
152
106
 
153
- def baptism_of_lord(year=nil)
154
- year ||= @year
155
- return sunday_after epiphany(year)
107
+ def date_range
108
+ start_date .. end_date
156
109
  end
157
110
 
158
- def ash_wednesday(year=nil)
159
- year ||= @year
160
- return easter_sunday(year) - (6 * WEEK + 4)
161
- end
162
-
163
- def easter_sunday(year=nil)
164
- year ||= @year
165
- year += 1
166
-
167
- # algorithm below taken from the 'easter' gem:
168
- # https://github.com/jrobertson/easter
111
+ def range_check(date)
112
+ # necessary in order to handle Date correctly
113
+ date = date.to_date if date.class != Date
169
114
 
170
- golden_number = (year % 19) + 1
171
- if year <= 1752 then
172
- # Julian calendar
173
- dominical_number = (year + (year / 4) + 5) % 7
174
- paschal_full_moon = (3 - (11 * golden_number) - 7) % 30
175
- else
176
- # Gregorian calendar
177
- dominical_number = (year + (year / 4) - (year / 100) + (year / 400)) % 7
178
- solar_correction = (year - 1600) / 100 - (year - 1600) / 400
179
- lunar_correction = (((year - 1400) / 100) * 8) / 25
180
- paschal_full_moon = (3 - 11 * golden_number + solar_correction - lunar_correction) % 30
181
- end
182
- dominical_number += 7 until dominical_number > 0
183
- paschal_full_moon += 30 until paschal_full_moon > 0
184
- paschal_full_moon -= 1 if paschal_full_moon == 29 or (paschal_full_moon == 28 and golden_number > 11)
185
- difference = (4 - paschal_full_moon - dominical_number) % 7
186
- difference += 7 if difference < 0
187
- day_easter = paschal_full_moon + difference + 1
188
- if day_easter < 11 then
189
- # Easter occurs in March.
190
- return Date.new(y=year, m=3, d=day_easter + 21)
191
- else
192
- # Easter occurs in April.
193
- return Date.new(y=year, m=4, d=day_easter - 10)
115
+ unless date_range.include? date
116
+ raise RangeError.new "Date out of range #{date}"
194
117
  end
195
118
  end
196
119
 
197
- def palm_sunday(year=nil)
198
- return easter_sunday(year) - 7
199
- end
200
-
201
- def good_friday(year=nil)
202
- return easter_sunday(year) - 2
203
- end
204
-
205
- def holy_saturday(year=nil)
206
- return easter_sunday(year) - 1
207
- end
208
-
209
- def ascension(year=nil)
210
- return pentecost(year) - 10
211
- end
212
-
213
- def pentecost(year=nil)
214
- year ||= @year
215
- return easter_sunday(year) + 7 * WEEK
216
- end
217
-
218
- def holy_trinity(year=nil)
219
- sunday_after(pentecost(year))
220
- end
221
-
222
- def body_blood(year=nil)
223
- thursday_after(holy_trinity(year))
224
- end
225
-
226
- def sacred_heart(year=nil)
227
- friday_after(sunday_after(body_blood(year)))
228
- end
229
-
230
- def christ_king(year=nil)
231
- year ||= @year
232
- sunday_before(first_advent_sunday(year + 1))
120
+ %i(
121
+ first_advent_sunday
122
+ nativity
123
+ holy_family
124
+ mother_of_god
125
+ epiphany
126
+ baptism_of_lord
127
+ ash_wednesday
128
+ palm_sunday
129
+ good_friday
130
+ holy_saturday
131
+ easter_sunday
132
+ ascension
133
+ pentecost
134
+ holy_trinity
135
+ body_blood
136
+ sacred_heart
137
+ immaculate_heart
138
+ christ_king
139
+ ).each do |feast|
140
+ define_method feast do
141
+ Dates.public_send feast, year
142
+ end
233
143
  end
234
144
 
235
145
  # which liturgical season is it?
@@ -268,14 +178,14 @@ module CalendariumRomanum
268
178
  when Seasons::EASTER
269
179
  easter_sunday
270
180
  else # ordinary time
271
- monday_after(baptism_of_lord)
181
+ Dates.monday_after(baptism_of_lord)
272
182
  end
273
183
  end
274
184
 
275
185
  def season_week(seasonn, date)
276
186
  week1_beginning = season_beginning = season_beginning(seasonn)
277
187
  unless season_beginning.sunday?
278
- week1_beginning = sunday_after(season_beginning)
188
+ week1_beginning = Dates.sunday_after(season_beginning)
279
189
  end
280
190
 
281
191
  week = date_difference(date, week1_beginning) / Temporale::WEEK + 1
@@ -286,7 +196,7 @@ module CalendariumRomanum
286
196
  week += 1
287
197
 
288
198
  if date > pentecost
289
- weeks_after_date = date_difference(first_advent_sunday(@year + 1), date) / 7
199
+ weeks_after_date = date_difference(Dates.first_advent_sunday(@year + 1), date) / 7
290
200
  week = 34 - weeks_after_date
291
201
  week += 1 if date.sunday?
292
202
  end
@@ -310,44 +220,34 @@ module CalendariumRomanum
310
220
  end
311
221
  end
312
222
 
313
- return solemnity(date) || sunday(date) || ferial(date)
223
+ return @solemnities[date] || @feasts[date] || sunday(date) || @memorials[date] || ferial(date)
314
224
  end
315
225
 
316
226
  private
317
227
 
318
- # the celebration determination split in methods:
319
-
320
- def solemnity(date)
321
- if @solemnities.has_key?(date)
322
- return @solemnities[date]
323
- end
324
-
325
- seas = season(date)
326
- case seas
327
- when Seasons::EASTER
328
- if date <= sunday_after(easter_sunday)
329
- return Celebration.new '', Ranks::PRIMARY, SEASON_COLOUR[seas]
330
- end
331
- end
332
-
333
- return nil
334
- end
228
+ # seasons when Sundays have higher rank
229
+ SEASONS_SUNDAY_PRIMARY = [Seasons::ADVENT, Seasons::LENT, Seasons::EASTER].freeze
335
230
 
336
231
  def sunday(date)
337
232
  return nil unless date.sunday?
338
233
 
339
234
  seas = season date
340
235
  rank = Ranks::SUNDAY_UNPRIVILEGED
341
- if [Seasons::ADVENT, Seasons::LENT, Seasons::EASTER].include?(seas)
236
+ if SEASONS_SUNDAY_PRIMARY.include?(seas)
342
237
  rank = Ranks::PRIMARY
343
238
  end
344
239
 
345
- return Celebration.new '', rank, SEASON_COLOUR[seas]
240
+ week = Ordinalizer.ordinal season_week(seas, date)
241
+ title = I18n.t "temporale.#{seas.to_sym}.sunday", week: week
242
+
243
+ return Celebration.new title, rank, seas.colour
346
244
  end
347
245
 
348
246
  def ferial(date)
349
247
  seas = season date
248
+ week = season_week(seas, date)
350
249
  rank = Ranks::FERIAL
250
+ title = nil
351
251
  case seas
352
252
  when Seasons::ADVENT
353
253
  if date >= Date.new(@year, 12, 17)
@@ -356,12 +256,31 @@ module CalendariumRomanum
356
256
  when Seasons::CHRISTMAS
357
257
  if date < mother_of_god
358
258
  rank = Ranks::FERIAL_PRIVILEGED
259
+
260
+ nth = Ordinalizer.ordinal(date.day - nativity.day + 1) # 1-based counting
261
+ title = I18n.t 'temporale.christmas.nativity_octave.ferial', day: nth
262
+ elsif date > epiphany
263
+ title = I18n.t "temporale.christmas.after_epiphany.ferial", weekday: I18n.t("weekday.#{date.wday}")
359
264
  end
360
265
  when Seasons::LENT
361
- rank = Ranks::FERIAL_PRIVILEGED
266
+ if week == 0
267
+ title = I18n.t "temporale.lent.after_ashes.ferial", weekday: I18n.t("weekday.#{date.wday}")
268
+ elsif date > palm_sunday
269
+ rank = Ranks::PRIMARY
270
+ title = I18n.t "temporale.lent.holy_week.ferial", weekday: I18n.t("weekday.#{date.wday}")
271
+ end
272
+ rank = Ranks::FERIAL_PRIVILEGED unless rank > Ranks::FERIAL_PRIVILEGED
273
+ when Seasons::EASTER
274
+ if week == 1
275
+ rank = Ranks::PRIMARY
276
+ title = I18n.t "temporale.easter.octave.ferial", weekday: I18n.t("weekday.#{date.wday}")
277
+ end
362
278
  end
363
279
 
364
- return Celebration.new '', rank, SEASON_COLOUR[seas]
280
+ week_ord = Ordinalizer.ordinal week
281
+ title ||= I18n.t "temporale.#{seas.to_sym}.ferial", week: week_ord, weekday: I18n.t("weekday.#{date.wday}")
282
+
283
+ return Celebration.new title, rank, seas.colour
365
284
  end
366
285
 
367
286
  # helper: difference between two Dates in days
@@ -369,35 +288,29 @@ module CalendariumRomanum
369
288
  return (d1 - d2).numerator
370
289
  end
371
290
 
372
- # prepare dates of temporale solemnities and their octaves
291
+ # prepare dates of temporale solemnities
373
292
  def prepare_solemnities
374
293
  @solemnities = {}
375
-
376
- {
377
- nativity: [Ranks::PRIMARY, nil],
378
- holy_family: [Ranks::FEAST_LORD_GENERAL, nil],
379
- mother_of_god: [Ranks::SOLEMNITY_GENERAL],
380
- epiphany: [Ranks::PRIMARY, nil],
381
- baptism_of_lord: [Ranks::FEAST_LORD_GENERAL, nil],
382
- ash_wednesday: [Ranks::PRIMARY, nil],
383
- good_friday: [Ranks::TRIDUUM, Colours::RED],
384
- holy_saturday: [Ranks::TRIDUUM, nil],
385
- palm_sunday: [Ranks::PRIMARY, Colours::RED],
386
- easter_sunday: [Ranks::TRIDUUM, nil],
387
- ascension: [Ranks::PRIMARY, Colours::WHITE],
388
- pentecost: [Ranks::PRIMARY, Colours::RED],
389
- holy_trinity: [Ranks::SOLEMNITY_GENERAL, Colours::WHITE],
390
- body_blood: [Ranks::SOLEMNITY_GENERAL, Colours::WHITE],
391
- sacred_heart: [Ranks::SOLEMNITY_GENERAL, Colours::WHITE],
392
- christ_king: [Ranks::SOLEMNITY_GENERAL, Colours::WHITE],
393
- }.each_pair do |method_name, data|
394
- date = send(method_name)
395
- rank, colour = data
396
- @solemnities[date] = Celebration.new(
397
- proc { I18n.t("temporale.solemnity.#{method_name}") },
398
- rank,
399
- colour || SEASON_COLOUR[season(date)]
400
- )
294
+ @feasts = {}
295
+ @memorials = {}
296
+
297
+ self.class.celebrations.each do |c|
298
+ if c.date_method.is_a? Proc
299
+ date = instance_eval &c.date_method
300
+ else
301
+ date = public_send(c.date_method)
302
+ end
303
+ celebration = c.celebration
304
+
305
+ add_to =
306
+ if celebration.feast?
307
+ @feasts
308
+ elsif celebration.memorial?
309
+ @memorials
310
+ else
311
+ @solemnities
312
+ end
313
+ add_to[date] = celebration
401
314
  end
402
315
  end
403
316
  end