calendarium-romanum 0.4.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/.rubocop.yml +47 -0
- data/.travis.yml +22 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +431 -0
- data/Gemfile +25 -0
- data/Gemfile.lock +86 -0
- data/README.md +598 -0
- data/Rakefile +16 -0
- data/bin/calendariumrom +4 -1
- data/calendarium-romanum.gemspec +31 -0
- data/config/locales/cs.yml +5 -0
- data/config/locales/en.yml +21 -14
- data/config/locales/es.yml +94 -0
- data/config/locales/fr.yml +7 -0
- data/config/locales/it.yml +7 -0
- data/config/locales/la.yml +7 -0
- data/data/README.md +70 -24
- data/data/czech-brno-cs.txt +4 -6
- data/data/czech-budejovice-cs.txt +4 -6
- data/data/czech-cechy-cs.txt +4 -5
- data/data/czech-cs.txt +236 -234
- data/data/czech-hradec-cs.txt +3 -5
- data/data/czech-litomerice-cs.txt +5 -7
- data/data/czech-morava-cs.txt +4 -5
- data/data/czech-olomouc-cs.txt +2 -4
- data/data/czech-ostrava-cs.txt +3 -5
- data/data/czech-plzen-cs.txt +3 -5
- data/data/czech-praha-cs.txt +3 -4
- data/data/easter_dates.txt +67 -0
- data/data/universal-1969-la.txt +234 -0
- data/data/universal-en.txt +214 -211
- data/data/universal-es.txt +243 -0
- data/data/universal-fr.txt +214 -210
- data/data/universal-it.txt +214 -211
- data/data/universal-la.txt +214 -210
- data/doc/data_readme.md +2 -0
- data/doc/images/class_diagram.png +0 -0
- data/doc/images/class_diagram.puml +44 -0
- data/doc/yard_readme.rdoc +76 -0
- data/lib/calendarium-romanum.rb +35 -22
- data/lib/calendarium-romanum/abstract_date.rb +15 -0
- data/lib/calendarium-romanum/calendar.rb +207 -42
- data/lib/calendarium-romanum/cli.rb +63 -80
- data/lib/calendarium-romanum/cli/comparator.rb +63 -0
- data/lib/calendarium-romanum/cli/date_parser.rb +30 -0
- data/lib/calendarium-romanum/cli/dumper.rb +68 -0
- data/lib/calendarium-romanum/cli/helper.rb +23 -0
- data/lib/calendarium-romanum/cli/querier.rb +73 -0
- data/lib/calendarium-romanum/cr.rb +16 -0
- data/lib/calendarium-romanum/data.rb +50 -20
- data/lib/calendarium-romanum/day.rb +208 -32
- data/lib/calendarium-romanum/enum.rb +42 -25
- data/lib/calendarium-romanum/enums.rb +124 -44
- data/lib/calendarium-romanum/errors.rb +4 -0
- data/lib/calendarium-romanum/ordinalizer.rb +23 -2
- data/lib/calendarium-romanum/perpetual_calendar.rb +58 -7
- data/lib/calendarium-romanum/rank.rb +43 -12
- data/lib/calendarium-romanum/rank_predicates.rb +43 -0
- data/lib/calendarium-romanum/sanctorale.rb +164 -24
- data/lib/calendarium-romanum/sanctorale_factory.rb +74 -3
- data/lib/calendarium-romanum/sanctorale_loader.rb +180 -0
- data/lib/calendarium-romanum/sanctorale_writer.rb +119 -0
- data/lib/calendarium-romanum/temporale.rb +226 -94
- data/lib/calendarium-romanum/temporale/celebration_factory.rb +107 -0
- data/lib/calendarium-romanum/temporale/dates.rb +84 -16
- data/lib/calendarium-romanum/temporale/easter_table.rb +27 -0
- data/lib/calendarium-romanum/temporale/extensions.rb +15 -0
- data/lib/calendarium-romanum/temporale/extensions/christ_eternal_priest.rb +16 -3
- data/lib/calendarium-romanum/temporale/extensions/dedication_before_all_saints.rb +73 -0
- data/lib/calendarium-romanum/transfers.rb +60 -15
- data/lib/calendarium-romanum/util.rb +22 -3
- data/lib/calendarium-romanum/version.rb +5 -1
- data/liturgical_law/1969_normae_universales.md +568 -0
- data/liturgical_law/1977_decretum_de_celebratione_baptismatis_domini.md +58 -0
- data/liturgical_law/1990_decretum_de_variatione_inducenda.md +67 -0
- data/liturgical_law/1998_notificatio_de_occurrentia.md +57 -0
- data/liturgical_law/2002_normae_universales.md +946 -0
- data/liturgical_law/2006_notification.md +37 -0
- data/liturgical_law/2012_declarationes.md +38 -0
- data/liturgical_law/README.md +74 -0
- metadata +50 -28
- data/lib/calendarium-romanum/sanctoraleloader.rb +0 -115
- data/spec/abstract_date_spec.rb +0 -62
- data/spec/calendar_spec.rb +0 -330
- data/spec/celebration_spec.rb +0 -23
- data/spec/cli_spec.rb +0 -26
- data/spec/colour_spec.rb +0 -17
- data/spec/data_spec.rb +0 -23
- data/spec/date_spec.rb +0 -61
- data/spec/dates_spec.rb +0 -45
- data/spec/day_spec.rb +0 -59
- data/spec/enum_spec.rb +0 -51
- data/spec/i18n_spec.rb +0 -59
- data/spec/ordinalizer_spec.rb +0 -22
- data/spec/perpetual_calendar_spec.rb +0 -91
- data/spec/rank_spec.rb +0 -57
- data/spec/readme_spec.rb +0 -52
- data/spec/sanctorale_factory_spec.rb +0 -42
- data/spec/sanctorale_spec.rb +0 -191
- data/spec/sanctoraleloader_spec.rb +0 -171
- data/spec/season_spec.rb +0 -17
- data/spec/spec_helper.rb +0 -35
- data/spec/temporale_spec.rb +0 -519
data/doc/data_readme.md
ADDED
Binary file
|
@@ -0,0 +1,44 @@
|
|
1
|
+
@startuml
|
2
|
+
object Calendar {
|
3
|
+
year
|
4
|
+
}
|
5
|
+
object PerpetualCalendar
|
6
|
+
|
7
|
+
object Temporale
|
8
|
+
object Sanctorale
|
9
|
+
|
10
|
+
object Day {
|
11
|
+
date
|
12
|
+
season
|
13
|
+
season_week
|
14
|
+
celebrations
|
15
|
+
vespers
|
16
|
+
}
|
17
|
+
object Celebration {
|
18
|
+
title
|
19
|
+
colour
|
20
|
+
rank
|
21
|
+
date
|
22
|
+
cycle
|
23
|
+
symbol
|
24
|
+
}
|
25
|
+
object AbstractDate
|
26
|
+
object Season
|
27
|
+
object Rank
|
28
|
+
object Colour
|
29
|
+
|
30
|
+
Calendar o-- Temporale
|
31
|
+
Calendar o-- Sanctorale
|
32
|
+
|
33
|
+
PerpetualCalendar *-- Calendar
|
34
|
+
|
35
|
+
Calendar ..> Day : produces
|
36
|
+
Temporale ..> Celebration : produces
|
37
|
+
Sanctorale "1" --> "0..*" Celebration
|
38
|
+
|
39
|
+
Day "1" --> "1..*" Celebration
|
40
|
+
Celebration --> Season
|
41
|
+
Celebration --> Rank
|
42
|
+
Celebration --> Colour
|
43
|
+
Celebration --> AbstractDate
|
44
|
+
@enduml
|
@@ -0,0 +1,76 @@
|
|
1
|
+
= calendarium-romanum
|
2
|
+
|
3
|
+
Ruby gem for
|
4
|
+
calendar computations according to the Roman Catholic liturgical
|
5
|
+
calendar as instituted by
|
6
|
+
MP <em>{Mysterii Paschalis}[http://w2.vatican.va/content/paul-vi/en/motu_proprio/documents/hf_p-vi_motu-proprio_19690214_mysterii-paschalis.html]</em> of Paul VI. (AAS 61 (1969), pp. 222-226).
|
7
|
+
The rules are defined in
|
8
|
+
<em>{General Norms for the Liturgical Year and the Calendar}[https://www.ewtn.com/catholicism/library/liturgical-year-2193]</em>.
|
9
|
+
|
10
|
+
== Quickstart
|
11
|
+
|
12
|
+
For usage instructions with copy-pastable code examples see {file:README.md}
|
13
|
+
|
14
|
+
== Object model overview
|
15
|
+
|
16
|
+
rdoc-image:images/class_diagram.png
|
17
|
+
|
18
|
+
<b>{CalendariumRomanum::Calendar Calendar}</b> is the library's main functional unit.
|
19
|
+
It represents calendar for a single liturgical year and allows retrieving calendar data
|
20
|
+
for any of the year's days.
|
21
|
+
Calendar basically consists of
|
22
|
+
a {CalendariumRomanum::Temporale Temporale} and a {CalendariumRomanum::Sanctorale Sanctorale}
|
23
|
+
and it's main task is to combine information from both and for any day of the year produce
|
24
|
+
a fully and correctly populated {CalendariumRomanum::Day Day} instance,
|
25
|
+
containing one or more {CalendariumRomanum::Celebration Celebrations}
|
26
|
+
(see {CalendariumRomanum::Calendar#[] Calendar#[]}).
|
27
|
+
|
28
|
+
(+Calendar+ does not own either +Temporale+ or +Sanctorale+ - it is possible to pass them
|
29
|
+
on initialization and they are treated as read-only. The only exception is method
|
30
|
+
{CalendariumRomanum::Calendar#freeze #freeze}, which freezes all the +Calendar+'s contents,
|
31
|
+
including +Temporale+ and +Sanctorale+.)
|
32
|
+
|
33
|
+
<b>{CalendariumRomanum::PerpetualCalendar PerpetualCalendar}</b> is a higher-level API
|
34
|
+
for retrieving calendar data
|
35
|
+
without bothering about liturgical years. It builds {CalendariumRomanum::Calendar Calendar}
|
36
|
+
instances internally and passes method calls to them.
|
37
|
+
|
38
|
+
<b>{CalendariumRomanum::Day Day}</b> contains complete calendar data of a liturgical day.
|
39
|
+
It owns one or more {CalendariumRomanum::Celebration Celebrations}.
|
40
|
+
If there are multiple it means that any one of them can be chosen and celebrated
|
41
|
+
that day.
|
42
|
+
|
43
|
+
<b>{CalendariumRomanum::Celebration Celebration}</b> represents a celebration
|
44
|
+
(particular solemnity / feast / memorial / Sunday / ferial)
|
45
|
+
and holds it's liturgical properties, encoded mostly by value objects.
|
46
|
+
|
47
|
+
(Unlike +Day+, +Celebration+ instances are not bound to a particular date,
|
48
|
+
they represent "celebration C in general", not "celebration C in year Y".
|
49
|
+
The latter is represented only by a combination of +Celebration+ and +Day+.
|
50
|
+
+Celebration+ instances are immutable and some may be used repeatedly in context of various
|
51
|
+
days and calendars.)
|
52
|
+
|
53
|
+
<b>{CalendariumRomanum::Season Season}</b>,
|
54
|
+
<b>{CalendariumRomanum::Rank Rank}</b>,
|
55
|
+
<b>{CalendariumRomanum::Colour Colour}</b>
|
56
|
+
are value objects representing values
|
57
|
+
of {CalendariumRomanum::Celebration Celebration} properties.
|
58
|
+
Immutable instances representing the standard values are referenced by constants and
|
59
|
+
normally there should be no need to create any more.
|
60
|
+
|
61
|
+
<b>{CalendariumRomanum::Temporale Temporale}</b> represents the temporale cycle of a single liturgical
|
62
|
+
year, computes movable feasts, determines liturgical seasons.
|
63
|
+
For any day of the year it provides a temporale {CalendariumRomanum::Celebration Celebration}.
|
64
|
+
|
65
|
+
<b>{CalendariumRomanum::Sanctorale Sanctorale}</b> represents the sanctorale cycle, i.e. the fixed-date
|
66
|
+
celebrations, mostly feasts of saints. It is not bound to a particular year, hence a single
|
67
|
+
instance can be used by many {CalendariumRomanum::Calendar Calendar} instances representing
|
68
|
+
various liturgical years. For any day it provides zero or more
|
69
|
+
{CalendariumRomanum::Celebration Celebrations}.
|
70
|
+
|
71
|
+
Most particular calendars (calendars of countries, provinces, dioceses, churches, religious
|
72
|
+
institutes) share the same temporale definition and differ in sanctorale contents.
|
73
|
+
Therefore the task of implementing a particular calendar usually consists of populating
|
74
|
+
a {CalendariumRomanum::Sanctorale Sanctorale} instance with the desired data.
|
75
|
+
A convenient way to do so is preparing a {file:data/README.md sanctorale data file}
|
76
|
+
and loading it using {CalendariumRomanum::SanctoraleLoader SanctoraleLoader}.
|
data/lib/calendarium-romanum.rb
CHANGED
@@ -1,23 +1,36 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
day
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
1
|
+
# Module wrapping the gem's classes
|
2
|
+
#
|
3
|
+
# If you hate typing the long module name, see {CR}
|
4
|
+
module CalendariumRomanum
|
5
|
+
end
|
6
|
+
|
7
|
+
%w(
|
8
|
+
version
|
9
|
+
i18n_setup
|
10
|
+
abstract_date
|
11
|
+
rank_predicates
|
12
|
+
rank
|
13
|
+
enum
|
14
|
+
enums
|
15
|
+
errors
|
16
|
+
data
|
17
|
+
day
|
18
|
+
calendar
|
19
|
+
perpetual_calendar
|
20
|
+
temporale/dates
|
21
|
+
temporale/celebration_factory
|
22
|
+
temporale/easter_table
|
23
|
+
temporale/extensions
|
24
|
+
temporale/extensions/christ_eternal_priest
|
25
|
+
temporale/extensions/dedication_before_all_saints
|
26
|
+
temporale
|
27
|
+
sanctorale
|
28
|
+
sanctorale_loader
|
29
|
+
sanctorale_writer
|
30
|
+
sanctorale_factory
|
31
|
+
transfers
|
32
|
+
util
|
33
|
+
ordinalizer
|
34
|
+
).each do |f|
|
35
|
+
require_relative File.join('calendarium-romanum', f)
|
23
36
|
end
|
@@ -4,12 +4,20 @@ module CalendariumRomanum
|
|
4
4
|
class AbstractDate
|
5
5
|
include Comparable
|
6
6
|
|
7
|
+
# @param month [Integer]
|
8
|
+
# @param day [Integer]
|
9
|
+
# @raise [RangeError] on invalid +month+/+day+ value
|
7
10
|
def initialize(month, day)
|
8
11
|
validate! month, day
|
9
12
|
@month = month
|
10
13
|
@day = day
|
11
14
|
end
|
12
15
|
|
16
|
+
# Build a new instance from a +Date+ (or an object with
|
17
|
+
# similar public interface).
|
18
|
+
#
|
19
|
+
# @param date [Date]
|
20
|
+
# @return [AbstractDate]
|
13
21
|
def self.from_date(date)
|
14
22
|
new(date.month, date.day)
|
15
23
|
end
|
@@ -32,10 +40,17 @@ module CalendariumRomanum
|
|
32
40
|
month == other.month && day == other.day
|
33
41
|
end
|
34
42
|
|
43
|
+
# Produce a +Date+ by providing a year to an +AbstractDate+
|
44
|
+
#
|
45
|
+
# @param year [Integer]
|
46
|
+
# @return [Date]
|
35
47
|
def concretize(year)
|
36
48
|
Date.new(year, month, day)
|
37
49
|
end
|
38
50
|
|
51
|
+
# @since 0.8.0
|
52
|
+
alias in_year concretize
|
53
|
+
|
39
54
|
private
|
40
55
|
|
41
56
|
def validate!(month, day)
|
@@ -5,47 +5,76 @@ module CalendariumRomanum
|
|
5
5
|
|
6
6
|
# Provides complete information concerning a liturgical year,
|
7
7
|
# it's days and celebrations occurring on them.
|
8
|
+
#
|
9
|
+
# {Calendar}'s business logic is mostly about correctly combining
|
10
|
+
# information from {Temporale} and {Sanctorale}.
|
8
11
|
class Calendar
|
9
12
|
extend Forwardable
|
10
13
|
|
11
14
|
# Day when the implemented calendar system became effective
|
12
15
|
EFFECTIVE_FROM = Date.new(1970, 1, 1).freeze
|
13
16
|
|
14
|
-
# year
|
15
|
-
# returns a calendar for the liturgical year beginning with
|
17
|
+
# Returns a calendar for the liturgical year beginning with
|
16
18
|
# Advent of the specified civil year.
|
17
|
-
|
19
|
+
#
|
20
|
+
# @overload initialize(year, sanctorale = nil, temporale = nil, vespers: false)
|
21
|
+
# @param year [Integer]
|
22
|
+
# Civil year when the liturgical year begins.
|
23
|
+
# @param sanctorale [Sanctorale, nil]
|
24
|
+
# If not provided, the +Calendar+ will only know celebrations
|
25
|
+
# of the temporale cycle, no feasts of the saints!
|
26
|
+
# @param temporale [Temporale, nil]
|
27
|
+
# If not provided, +Temporale+ for the given year with default
|
28
|
+
# configuration will built.
|
29
|
+
# @param vespers [Boolean] Set to true if you want the +Calendar+ to populate {Day#vespers}
|
30
|
+
#
|
31
|
+
# @overload initialize(temporale, sanctorale=nil, vespers: false)
|
32
|
+
# @param temporale [Temporale]
|
33
|
+
# @param sanctorale [Sanctorale, nil]
|
34
|
+
# If not provided, the +Calendar+ will only know celebrations
|
35
|
+
# of the temporale cycle, no feasts of the saints!
|
36
|
+
# @param vespers [Boolean] Set to true if you want the +Calendar+ to populate {Day#vespers}
|
37
|
+
# @since 0.8.0
|
38
|
+
#
|
39
|
+
# @raise [RangeError]
|
40
|
+
# if +year+ is specified for which the implemented calendar
|
41
|
+
# system wasn't in force
|
42
|
+
def initialize(year, sanctorale = nil, temporale = nil, vespers: false)
|
43
|
+
unless year.is_a? Integer
|
44
|
+
temporale = year
|
45
|
+
year = temporale.year
|
46
|
+
end
|
47
|
+
|
18
48
|
if year < (EFFECTIVE_FROM.year - 1)
|
19
49
|
raise system_not_effective
|
20
50
|
end
|
21
51
|
|
22
52
|
if temporale && temporale.year != year
|
23
|
-
raise ArgumentError.new(
|
53
|
+
raise ArgumentError.new('Temporale year must be the same as year.')
|
24
54
|
end
|
25
55
|
|
26
56
|
@year = year
|
27
57
|
@sanctorale = sanctorale || Sanctorale.new
|
28
58
|
@temporale = temporale || Temporale.new(year)
|
29
|
-
@
|
59
|
+
@populate_vespers = vespers
|
60
|
+
|
61
|
+
@transferred = Transfers.call(@temporale, @sanctorale).freeze
|
30
62
|
end
|
31
63
|
|
32
64
|
class << self
|
65
|
+
# @api private
|
33
66
|
def mk_date(*args)
|
34
67
|
ex = TypeError.new('Date, DateTime or three Integers expected')
|
35
68
|
|
36
|
-
if args.size == 3
|
69
|
+
if args.size == 3
|
37
70
|
args.each do |a|
|
38
|
-
unless a.is_a? Integer
|
39
|
-
raise ex
|
40
|
-
end
|
71
|
+
raise ex unless a.is_a? Integer
|
41
72
|
end
|
42
|
-
return Date.new
|
73
|
+
return Date.new(*args)
|
43
74
|
|
44
|
-
elsif args.size == 1
|
75
|
+
elsif args.size == 1
|
45
76
|
a = args.first
|
46
|
-
unless a.is_a? Date
|
47
|
-
raise ex
|
48
|
-
end
|
77
|
+
raise ex unless a.is_a? Date
|
49
78
|
return a
|
50
79
|
|
51
80
|
else
|
@@ -53,38 +82,103 @@ module CalendariumRomanum
|
|
53
82
|
end
|
54
83
|
end
|
55
84
|
|
56
|
-
#
|
57
|
-
# date
|
85
|
+
# Creates a new instance for the liturgical year which includes
|
86
|
+
# given date
|
87
|
+
#
|
88
|
+
# @param date [Date]
|
89
|
+
# @param constructor_args
|
90
|
+
# arguments that will be passed to {initialize}
|
91
|
+
# @return [Calendar]
|
58
92
|
def for_day(date, *constructor_args)
|
59
|
-
|
93
|
+
new(Temporale.liturgical_year(date), *constructor_args)
|
60
94
|
end
|
61
95
|
end # class << self
|
62
96
|
|
97
|
+
# @!method range_check(date)
|
98
|
+
# @see Temporale#range_check
|
99
|
+
# @param date
|
100
|
+
# @return [void]
|
101
|
+
# @!method season(date)
|
102
|
+
# @see Temporale#season
|
103
|
+
# @param date
|
104
|
+
# @return [Season]
|
63
105
|
def_delegators :@temporale, :range_check, :season
|
106
|
+
|
107
|
+
# @return [Integer]
|
64
108
|
attr_reader :year
|
109
|
+
|
110
|
+
# @return [Temporale]
|
65
111
|
attr_reader :temporale
|
112
|
+
|
113
|
+
# @return [Sanctorale]
|
66
114
|
attr_reader :sanctorale
|
67
115
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
116
|
+
# Solemnities transferred to a date different from the usual one
|
117
|
+
# due to occurrence with a higher-ranking celebration.
|
118
|
+
#
|
119
|
+
# @return [Hash<Date=>Celebration>]
|
120
|
+
# @since 0.8.0
|
121
|
+
attr_reader :transferred
|
72
122
|
|
73
|
-
|
123
|
+
# Do {Day} instances returned by this +Calendar+
|
124
|
+
# have {Day#vespers} populated?
|
125
|
+
# @return [Boolean]
|
126
|
+
# @since 0.6.0
|
127
|
+
def populates_vespers?
|
128
|
+
@populate_vespers
|
74
129
|
end
|
75
130
|
|
76
|
-
#
|
77
|
-
#
|
78
|
-
|
79
|
-
|
80
|
-
|
131
|
+
# Two +Calendar+s are equal if they have equal settings
|
132
|
+
# (which means that to equal input they return equal data)
|
133
|
+
def ==(b)
|
134
|
+
b.class == self.class &&
|
135
|
+
year == b.year &&
|
136
|
+
populates_vespers? == b.populates_vespers? &&
|
137
|
+
temporale == b.temporale &&
|
138
|
+
sanctorale == b.sanctorale
|
139
|
+
end
|
140
|
+
|
141
|
+
# Retrieve liturgical calendar information for the specified day
|
142
|
+
# or range of days.
|
143
|
+
#
|
144
|
+
# @overload [](date)
|
145
|
+
# @param date [Date]
|
146
|
+
# @return [Day]
|
147
|
+
# @overload [](range)
|
148
|
+
# @param range [Range<Date>]
|
149
|
+
# @return [Array<Day>]
|
150
|
+
def [](args)
|
151
|
+
if args.is_a?(Range)
|
152
|
+
args.map {|date| day(date) }
|
153
|
+
else
|
154
|
+
day(args)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# Retrieve liturgical calendar information for the specified day
|
159
|
+
#
|
160
|
+
# @overload day(date, vespers: false)
|
161
|
+
# @param date [Date]
|
162
|
+
# @overload day(year, month, day, vespers: false)
|
163
|
+
# @param year [Integer]
|
164
|
+
# @param month [Integer]
|
165
|
+
# @param day [Integer]
|
166
|
+
# @param vespers [Boolean]
|
167
|
+
# Set to +true+ in order to get {Day} with {Day#vespers}
|
168
|
+
# populated (overrides instance-wide setting {#populates_vespers?}).
|
169
|
+
# @return [Day]
|
170
|
+
# @raise [RangeError]
|
171
|
+
# If a date is specified on which the implemented calendar
|
172
|
+
# system was not yet in force (it became effective during
|
173
|
+
# the liturgical year 1969/1970)
|
174
|
+
def day(*args, vespers: false)
|
81
175
|
if args.size == 2
|
82
176
|
date = Date.new(@year, *args)
|
83
177
|
unless @temporale.date_range.include? date
|
84
178
|
date = Date.new(@year + 1, *args)
|
85
179
|
end
|
86
180
|
else
|
87
|
-
date = self.class.mk_date
|
181
|
+
date = self.class.mk_date(*args)
|
88
182
|
range_check date
|
89
183
|
end
|
90
184
|
|
@@ -92,25 +186,63 @@ module CalendariumRomanum
|
|
92
186
|
raise system_not_effective
|
93
187
|
end
|
94
188
|
|
189
|
+
celebrations = celebrations_for(date)
|
190
|
+
vespers_celebration = nil
|
191
|
+
if @populate_vespers || vespers
|
192
|
+
begin
|
193
|
+
vespers_celebration = first_vespers_on(date, celebrations)
|
194
|
+
rescue RangeError
|
195
|
+
# there is exactly one possible case when
|
196
|
+
# range_check(date) passes and range_check(date + 1) fails:
|
197
|
+
vespers_celebration = Temporale::CelebrationFactory.first_advent_sunday
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
95
201
|
s = @temporale.season(date)
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
202
|
+
Day.new(
|
203
|
+
date: date,
|
204
|
+
season: s,
|
205
|
+
season_week: @temporale.season_week(s, date),
|
206
|
+
celebrations: celebrations,
|
207
|
+
vespers: vespers_celebration
|
208
|
+
)
|
209
|
+
end
|
210
|
+
|
211
|
+
# Iterate over the whole liturgical year, day by day,
|
212
|
+
# for each day yield calendar data.
|
213
|
+
# If called without a block, returns +Enumerator+.
|
214
|
+
#
|
215
|
+
# @yield [Day]
|
216
|
+
# @return [void, Enumerator]
|
217
|
+
# @since 0.6.0
|
218
|
+
def each
|
219
|
+
return to_enum(__method__) unless block_given?
|
220
|
+
|
221
|
+
temporale.date_range
|
222
|
+
.each {|date| yield(day(date)) }
|
102
223
|
end
|
103
224
|
|
104
225
|
# Sunday lectionary cycle
|
226
|
+
#
|
227
|
+
# @return [Symbol]
|
228
|
+
# For possible values see {LECTIONARY_CYCLES}
|
105
229
|
def lectionary
|
106
230
|
LECTIONARY_CYCLES[@year % 3]
|
107
231
|
end
|
108
232
|
|
109
233
|
# Ferial lectionary cycle
|
234
|
+
#
|
235
|
+
# @return [1, 2]
|
110
236
|
def ferial_lectionary
|
111
237
|
@year % 2 + 1
|
112
238
|
end
|
113
239
|
|
240
|
+
# Freezes the instance.
|
241
|
+
#
|
242
|
+
# *WARNING*: {Temporale} and {Sanctorale} instances passed
|
243
|
+
# to the +Calendar+ on initialization will be frozen, too!
|
244
|
+
# This is necessary, because a +Calendar+ would not really be
|
245
|
+
# frozen were it possible to mutate it's key components.
|
114
246
|
def freeze
|
115
247
|
@temporale.freeze
|
116
248
|
@sanctorale.freeze
|
@@ -120,11 +252,18 @@ module CalendariumRomanum
|
|
120
252
|
private
|
121
253
|
|
122
254
|
def celebrations_for(date)
|
123
|
-
tr = @transferred
|
255
|
+
tr = @transferred[date]
|
124
256
|
return [tr] if tr
|
125
257
|
|
126
|
-
t = @temporale
|
127
|
-
st = @sanctorale
|
258
|
+
t = @temporale[date]
|
259
|
+
st = @sanctorale[date]
|
260
|
+
|
261
|
+
if date.saturday? &&
|
262
|
+
@temporale.season(date) == Seasons::ORDINARY &&
|
263
|
+
(st.empty? || st.first.rank == Ranks::MEMORIAL_OPTIONAL) &&
|
264
|
+
t.rank <= Ranks::MEMORIAL_OPTIONAL
|
265
|
+
st = st.dup << Temporale::CelebrationFactory.saturday_memorial_bvm
|
266
|
+
end
|
128
267
|
|
129
268
|
unless st.empty?
|
130
269
|
if st.first.rank > t.rank
|
@@ -134,15 +273,41 @@ module CalendariumRomanum
|
|
134
273
|
return st
|
135
274
|
end
|
136
275
|
elsif t.rank == Ranks::FERIAL_PRIVILEGED && st.first.rank.memorial?
|
137
|
-
|
138
|
-
|
276
|
+
commemorations = st.collect do |c|
|
277
|
+
c.change(rank: Ranks::COMMEMORATION, colour: t.colour)
|
139
278
|
end
|
140
|
-
|
141
|
-
|
279
|
+
return commemorations.unshift t
|
280
|
+
elsif t.symbol == :immaculate_heart &&
|
281
|
+
[Ranks::MEMORIAL_GENERAL, Ranks::MEMORIAL_PROPER].include?(st.first.rank)
|
282
|
+
optional_memorials = ([t] + st).collect do |celebration|
|
283
|
+
celebration.change rank: Ranks::MEMORIAL_OPTIONAL
|
284
|
+
end
|
285
|
+
ferial = temporale.send :ferial, date # ugly and evil
|
286
|
+
return [ferial] + optional_memorials
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
[t]
|
291
|
+
end
|
292
|
+
|
293
|
+
def first_vespers_on(date, celebrations)
|
294
|
+
tomorrow = date + 1
|
295
|
+
tomorrow_celebrations = celebrations_for(tomorrow)
|
296
|
+
|
297
|
+
c = tomorrow_celebrations.first
|
298
|
+
if c.rank >= Ranks::SOLEMNITY_PROPER ||
|
299
|
+
c.rank == Ranks::SUNDAY_UNPRIVILEGED ||
|
300
|
+
(c.rank == Ranks::FEAST_LORD_GENERAL && tomorrow.sunday?)
|
301
|
+
if c.symbol == :ash_wednesday || c.symbol == :good_friday
|
302
|
+
return nil
|
303
|
+
end
|
304
|
+
|
305
|
+
if c.rank > celebrations.first.rank || c.symbol == :easter_sunday
|
306
|
+
return c
|
142
307
|
end
|
143
308
|
end
|
144
309
|
|
145
|
-
|
310
|
+
nil
|
146
311
|
end
|
147
312
|
|
148
313
|
def system_not_effective
|