calendarium-romanum 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/bin/calendariumrom +3 -0
- data/config/locales/es.yml +90 -0
- data/data/README.md +43 -1
- 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 +237 -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/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 -212
- data/lib/calendarium-romanum.rb +6 -0
- data/lib/calendarium-romanum/abstract_date.rb +12 -0
- data/lib/calendarium-romanum/calendar.rb +93 -13
- data/lib/calendarium-romanum/cli.rb +11 -4
- data/lib/calendarium-romanum/cr.rb +16 -0
- data/lib/calendarium-romanum/data.rb +34 -7
- data/lib/calendarium-romanum/day.rb +132 -14
- data/lib/calendarium-romanum/enum.rb +22 -1
- data/lib/calendarium-romanum/enums.rb +80 -28
- data/lib/calendarium-romanum/errors.rb +1 -1
- data/lib/calendarium-romanum/ordinalizer.rb +10 -1
- data/lib/calendarium-romanum/perpetual_calendar.rb +43 -5
- data/lib/calendarium-romanum/rank.rb +23 -0
- data/lib/calendarium-romanum/sanctorale.rb +119 -20
- data/lib/calendarium-romanum/sanctorale_factory.rb +74 -3
- data/lib/calendarium-romanum/sanctorale_loader.rb +60 -19
- data/lib/calendarium-romanum/temporale.rb +110 -9
- data/lib/calendarium-romanum/temporale/celebration_factory.rb +45 -2
- data/lib/calendarium-romanum/temporale/dates.rb +65 -1
- data/lib/calendarium-romanum/temporale/extensions/christ_eternal_priest.rb +14 -2
- data/lib/calendarium-romanum/transfers.rb +20 -1
- data/lib/calendarium-romanum/util.rb +15 -3
- data/lib/calendarium-romanum/version.rb +3 -2
- data/spec/calendar_spec.rb +48 -4
- data/spec/celebration_factory_spec.rb +4 -0
- data/spec/celebration_spec.rb +9 -0
- data/spec/cli_spec.rb +7 -0
- data/spec/data_spec.rb +23 -0
- data/spec/day_spec.rb +26 -0
- data/spec/i18n_spec.rb +10 -0
- data/spec/sanctorale_factory_spec.rb +113 -9
- data/spec/sanctorale_loader_spec.rb +49 -24
- data/spec/sanctorale_spec.rb +72 -9
- data/spec/temporale_spec.rb +52 -53
- data/spec/year_spec.rb +25 -0
- metadata +7 -3
@@ -1,11 +1,17 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
|
3
3
|
module CalendariumRomanum
|
4
|
-
#
|
4
|
+
# Each subclass encapsulates a finite set of value objects.
|
5
|
+
#
|
6
|
+
# @abstract
|
5
7
|
class Enum
|
6
8
|
class << self
|
7
9
|
extend Forwardable
|
8
10
|
|
11
|
+
# @api private
|
12
|
+
# @param index_by
|
13
|
+
# specifies which value objects' property contains
|
14
|
+
# unique internal identifier for use with {.[]}
|
9
15
|
def values(index_by: nil)
|
10
16
|
defined?(@indexed) && raise(RuntimeError.new('initialized repeatedly'))
|
11
17
|
|
@@ -22,9 +28,24 @@ module CalendariumRomanum
|
|
22
28
|
@indexed.freeze
|
23
29
|
end
|
24
30
|
|
31
|
+
# Returns all contained value objects
|
32
|
+
#
|
33
|
+
# @return [Array]
|
25
34
|
attr_reader :all
|
26
35
|
|
36
|
+
# Enumerates contained value objects
|
37
|
+
#
|
38
|
+
# @!method each
|
39
|
+
# @yield value object
|
40
|
+
# @return [void]
|
27
41
|
def_delegators :@all, :each
|
42
|
+
|
43
|
+
# Allows accessing contained value objects by their
|
44
|
+
# internal unique identifiers
|
45
|
+
#
|
46
|
+
# @!method [](identifier)
|
47
|
+
# @param identifier
|
48
|
+
# @return value object or nil
|
28
49
|
def_delegators :@indexed, :[]
|
29
50
|
end
|
30
51
|
end
|
@@ -1,17 +1,28 @@
|
|
1
1
|
module CalendariumRomanum
|
2
|
+
# Methods shared by most value objects defined by the gem
|
2
3
|
module ValueObjectInterface
|
4
|
+
# Machine-readable internal representation of the value
|
5
|
+
#
|
6
|
+
# @return [Symbol]
|
3
7
|
attr_reader :symbol
|
4
8
|
alias to_sym symbol
|
5
9
|
|
10
|
+
# Internationalized, human-readable name
|
11
|
+
#
|
12
|
+
# @return [String]
|
6
13
|
def name
|
7
14
|
I18n.t @i18n_key
|
8
15
|
end
|
9
16
|
|
17
|
+
# String representation of the contents for debugging purposes
|
18
|
+
#
|
19
|
+
# @return [String]
|
10
20
|
def to_s
|
11
21
|
"#<#{self.class.name} #{symbol}>"
|
12
22
|
end
|
13
23
|
end
|
14
24
|
|
25
|
+
# Represents a liturgical colour
|
15
26
|
class Colour
|
16
27
|
include ValueObjectInterface
|
17
28
|
|
@@ -21,70 +32,111 @@ module CalendariumRomanum
|
|
21
32
|
end
|
22
33
|
end
|
23
34
|
|
35
|
+
# Standard set of liturgical colours
|
24
36
|
class Colours < Enum
|
37
|
+
GREEN = Colour.new(:green)
|
38
|
+
VIOLET = Colour.new(:violet)
|
39
|
+
WHITE = Colour.new(:white)
|
40
|
+
RED = Colour.new(:red)
|
41
|
+
|
25
42
|
values(index_by: :symbol) do
|
26
43
|
[
|
27
|
-
GREEN
|
28
|
-
VIOLET
|
29
|
-
WHITE
|
30
|
-
RED
|
44
|
+
GREEN,
|
45
|
+
VIOLET,
|
46
|
+
WHITE,
|
47
|
+
RED
|
31
48
|
]
|
32
49
|
end
|
33
50
|
end
|
34
51
|
|
52
|
+
# Convenience alias (American English spelling)
|
35
53
|
Colors = Colours
|
36
54
|
|
55
|
+
# Liturgical season
|
37
56
|
class Season
|
38
57
|
include ValueObjectInterface
|
39
58
|
|
59
|
+
# @param symbol [Symbol] internal identifier
|
60
|
+
# @param colour [Colour]
|
61
|
+
# liturgical colour of the season's Sundays and ferials
|
40
62
|
def initialize(symbol, colour)
|
41
63
|
@symbol = symbol
|
42
64
|
@colour = colour
|
43
65
|
@i18n_key = "temporale.season.#{@symbol}"
|
44
66
|
end
|
45
67
|
|
68
|
+
# Liturgical colour of the season's Sundays and ferials
|
69
|
+
#
|
70
|
+
# @return [Colour]
|
46
71
|
attr_reader :colour
|
47
72
|
end
|
48
73
|
|
74
|
+
# Standard set of liturgical seasons
|
49
75
|
class Seasons < Enum
|
76
|
+
ADVENT = Season.new(:advent, Colours::VIOLET)
|
77
|
+
CHRISTMAS = Season.new(:christmas, Colours::WHITE)
|
78
|
+
LENT = Season.new(:lent, Colours::VIOLET)
|
79
|
+
EASTER = Season.new(:easter, Colours::WHITE)
|
80
|
+
ORDINARY = Season.new(:ordinary, Colours::GREEN)
|
81
|
+
|
50
82
|
values(index_by: :symbol) do
|
51
83
|
[
|
52
|
-
ADVENT
|
53
|
-
CHRISTMAS
|
54
|
-
LENT
|
55
|
-
EASTER
|
56
|
-
ORDINARY
|
84
|
+
ADVENT,
|
85
|
+
CHRISTMAS,
|
86
|
+
LENT,
|
87
|
+
EASTER,
|
88
|
+
ORDINARY,
|
57
89
|
]
|
58
90
|
end
|
59
91
|
end
|
60
92
|
|
93
|
+
# Sunday lectionary cycles.
|
94
|
+
# Values returned by {Calendar#lectionary}
|
61
95
|
LECTIONARY_CYCLES = [:A, :B, :C].freeze
|
62
96
|
|
63
|
-
# ranks of
|
97
|
+
# Celebration ranks as specified in the Table of Liturgical Days
|
64
98
|
class Ranks < Enum
|
99
|
+
TRIDUUM = Rank.new(1.1, 'rank.1_1')
|
100
|
+
PRIMARY = Rank.new(1.2, 'rank.1_2') # description may not be exact
|
101
|
+
SOLEMNITY_GENERAL = Rank.new(1.3, 'rank.1_3', 'rank.short.solemnity') # description may not be exact
|
102
|
+
SOLEMNITY_PROPER = Rank.new(1.4, 'rank.1_4', 'rank.short.solemnity')
|
103
|
+
|
104
|
+
FEAST_LORD_GENERAL = Rank.new(2.5, 'rank.2_5', 'rank.short.feast')
|
105
|
+
SUNDAY_UNPRIVILEGED = Rank.new(2.6, 'rank.2_6', 'rank.short.sunday')
|
106
|
+
FEAST_GENERAL = Rank.new(2.7, 'rank.2_7', 'rank.short.feast')
|
107
|
+
FEAST_PROPER = Rank.new(2.8, 'rank.2_8', 'rank.short.feast')
|
108
|
+
FERIAL_PRIVILEGED = Rank.new(2.9, 'rank.2_9', 'rank.short.ferial')
|
109
|
+
|
110
|
+
MEMORIAL_GENERAL = Rank.new(3.10, 'rank.3_10', 'rank.short.memorial')
|
111
|
+
MEMORIAL_PROPER = Rank.new(3.11, 'rank.3_11', 'rank.short.memorial')
|
112
|
+
MEMORIAL_OPTIONAL = Rank.new(3.12, 'rank.3_12', 'rank.short.memorial_opt')
|
113
|
+
FERIAL = Rank.new(3.13, 'rank.3_13', 'rank.short.ferial')
|
114
|
+
# Not included as a celebration rank on it's own
|
115
|
+
# in the Table of Liturgical Days
|
116
|
+
COMMEMORATION = Rank.new(4.0, 'rank.4_0', 'rank.short.commemoration')
|
117
|
+
|
65
118
|
values(index_by: :priority) do
|
66
119
|
# Values are at the same time references to sections
|
67
120
|
# of the Table of Liturgical Days.
|
68
121
|
# The lower value, the higher rank.
|
69
122
|
[
|
70
|
-
TRIDUUM
|
71
|
-
PRIMARY
|
72
|
-
SOLEMNITY_GENERAL
|
73
|
-
SOLEMNITY_PROPER
|
74
|
-
|
75
|
-
FEAST_LORD_GENERAL
|
76
|
-
SUNDAY_UNPRIVILEGED
|
77
|
-
FEAST_GENERAL
|
78
|
-
FEAST_PROPER
|
79
|
-
FERIAL_PRIVILEGED
|
80
|
-
|
81
|
-
MEMORIAL_GENERAL
|
82
|
-
MEMORIAL_PROPER
|
83
|
-
MEMORIAL_OPTIONAL
|
84
|
-
FERIAL
|
85
|
-
|
86
|
-
|
87
|
-
COMMEMORATION = Rank.new(4.0, 'rank.4_0', 'rank.short.commemoration')
|
123
|
+
TRIDUUM,
|
124
|
+
PRIMARY,
|
125
|
+
SOLEMNITY_GENERAL,
|
126
|
+
SOLEMNITY_PROPER,
|
127
|
+
|
128
|
+
FEAST_LORD_GENERAL,
|
129
|
+
SUNDAY_UNPRIVILEGED,
|
130
|
+
FEAST_GENERAL,
|
131
|
+
FEAST_PROPER,
|
132
|
+
FERIAL_PRIVILEGED,
|
133
|
+
|
134
|
+
MEMORIAL_GENERAL,
|
135
|
+
MEMORIAL_PROPER,
|
136
|
+
MEMORIAL_OPTIONAL,
|
137
|
+
FERIAL,
|
138
|
+
|
139
|
+
COMMEMORATION,
|
88
140
|
]
|
89
141
|
end
|
90
142
|
end
|
@@ -1,9 +1,18 @@
|
|
1
1
|
require 'roman-numerals'
|
2
2
|
|
3
3
|
module CalendariumRomanum
|
4
|
-
# Knows how to produce localized ordinals
|
4
|
+
# Knows how to produce localized ordinals.
|
5
|
+
#
|
6
|
+
# Used by {Temporale} for building names of Sundays and ferials.
|
5
7
|
class Ordinalizer
|
6
8
|
class << self
|
9
|
+
# @param number [Fixnum] number to build ordinal for
|
10
|
+
# @param locale [Symbol,nil]
|
11
|
+
# locale; +I18n.locale+ (i.e. the `i18n` gem's current locale)
|
12
|
+
# is used if not provided
|
13
|
+
# @return [String, Fixnum]
|
14
|
+
# ordinal, or unchanged +number+ if +Ordinalizer+ cannot
|
15
|
+
# build ordinals for the given locale
|
7
16
|
def ordinal(number, locale: nil)
|
8
17
|
locale ||= I18n.locale
|
9
18
|
|
@@ -1,7 +1,34 @@
|
|
1
1
|
module CalendariumRomanum
|
2
|
-
#
|
3
|
-
#
|
2
|
+
# Has mostly the same public interface as {Calendar},
|
3
|
+
# but represents a "perpetual" calendar, not a calendar
|
4
|
+
# for a single year, thus allowing the client code
|
5
|
+
# to query for liturgical data of any day, without bothering
|
6
|
+
# about boundaries of liturgical years.
|
7
|
+
#
|
8
|
+
# Internally builds {Calendar} instances as needed
|
9
|
+
# and delegates method calls to them.
|
10
|
+
#
|
11
|
+
# @since 0.4.0
|
4
12
|
class PerpetualCalendar
|
13
|
+
# @param sanctorale [Sanctorale, nil]
|
14
|
+
# @param temporale_factory [Proc, nil]
|
15
|
+
# +Proc+ receiving a single parameter - year - and returning
|
16
|
+
# a {Temporale} instance.
|
17
|
+
# @param temporale_options [Hash, nil]
|
18
|
+
# +Hash+ of arguments for {Temporale#initialize}.
|
19
|
+
# +temporale_factory+ and +temporale_options+ are mutually
|
20
|
+
# exclusive - pass either (or none) of them, never both.
|
21
|
+
# @param cache [Hash]
|
22
|
+
# object to be used as internal cache of {Calendar} instances -
|
23
|
+
# anything exposing +#[]=+ and +#[]+ and "behaving mostly like
|
24
|
+
# a +Hash+" will work.
|
25
|
+
# There's no need to pass it unless you want to have control
|
26
|
+
# over the cache. That may be sometimes useful
|
27
|
+
# in order to prevent a long-lived
|
28
|
+
# +PerpetualCalendar+ instance flooding the memory
|
29
|
+
# by huge amount of cached {Calendar} instances.
|
30
|
+
# (By default, once a {Calendar} for a certain year is built,
|
31
|
+
# it is cached for the +PerpetualCalendar+ instances' lifetime.)
|
5
32
|
def initialize(sanctorale: nil, temporale_factory: nil, temporale_options: nil, cache: {})
|
6
33
|
if temporale_factory && temporale_options
|
7
34
|
raise ArgumentError.new('Specify either temporale_factory or temporale_options, not both')
|
@@ -13,11 +40,15 @@ module CalendariumRomanum
|
|
13
40
|
@cache = cache
|
14
41
|
end
|
15
42
|
|
16
|
-
#
|
43
|
+
# @return [Day]
|
44
|
+
# @see Calendar#day
|
17
45
|
def day(*args)
|
18
46
|
calendar_for(*args).day(*args)
|
19
47
|
end
|
20
48
|
|
49
|
+
# @return [Day, Array<Day>]
|
50
|
+
# @see Calendar#[]
|
51
|
+
# @since 0.6.0
|
21
52
|
def [](arg)
|
22
53
|
if arg.is_a? Range
|
23
54
|
return arg.collect do |date|
|
@@ -28,15 +59,22 @@ module CalendariumRomanum
|
|
28
59
|
day(arg)
|
29
60
|
end
|
30
61
|
|
31
|
-
#
|
62
|
+
# Returns a {Calendar} instance for the liturgical year containing
|
32
63
|
# the specified day
|
64
|
+
#
|
65
|
+
# Parameters like {Calendar#day}
|
66
|
+
#
|
67
|
+
# @return [Calendar]
|
33
68
|
def calendar_for(*args)
|
34
69
|
date = Calendar.mk_date(*args)
|
35
70
|
year = Temporale.liturgical_year date
|
36
71
|
calendar_instance year
|
37
72
|
end
|
38
73
|
|
39
|
-
#
|
74
|
+
# Returns a Calendar instance for the specified liturgical year
|
75
|
+
#
|
76
|
+
# @param year [Fixnum]
|
77
|
+
# @return [Calendar]
|
40
78
|
def calendar_for_year(year)
|
41
79
|
calendar_instance year
|
42
80
|
end
|
@@ -1,20 +1,33 @@
|
|
1
1
|
module CalendariumRomanum
|
2
|
+
# Celebration rank
|
2
3
|
class Rank
|
3
4
|
include Comparable
|
4
5
|
|
6
|
+
# @param priority [Float, nil] number in the Table of Liturgical Days
|
7
|
+
# @param desc [String, nil]
|
8
|
+
# full description (translation string identifier)
|
9
|
+
# @param short_desc [String, nil]
|
10
|
+
# short rank name (translation string identifier)
|
5
11
|
def initialize(priority = nil, desc = nil, short_desc = nil)
|
6
12
|
@priority = priority
|
7
13
|
@desc = desc
|
8
14
|
@short_desc = short_desc
|
9
15
|
end
|
10
16
|
|
17
|
+
# @return [Float, nil]
|
11
18
|
attr_reader :priority
|
12
19
|
alias to_f priority
|
13
20
|
|
21
|
+
# Full description - internationalized human-readable string.
|
22
|
+
#
|
23
|
+
# @return [String, nil]
|
14
24
|
def desc
|
15
25
|
@desc && I18n.t(@desc)
|
16
26
|
end
|
17
27
|
|
28
|
+
# String representation mostly for debugging purposes.
|
29
|
+
#
|
30
|
+
# @return [String]
|
18
31
|
def to_s
|
19
32
|
# 'desc' instead of '@desc' is intentional -
|
20
33
|
# for a good reason we don't present contents of an instance
|
@@ -22,6 +35,9 @@ module CalendariumRomanum
|
|
22
35
|
"#<#{self.class.name} @priority=#{priority} desc=#{desc.inspect}>"
|
23
36
|
end
|
24
37
|
|
38
|
+
# Short name - internationalized human-readable string.
|
39
|
+
#
|
40
|
+
# @return [String, nil]
|
25
41
|
def short_desc
|
26
42
|
@short_desc && I18n.t(@short_desc)
|
27
43
|
end
|
@@ -30,22 +46,29 @@ module CalendariumRomanum
|
|
30
46
|
other.priority <=> priority
|
31
47
|
end
|
32
48
|
|
49
|
+
# @return [Boolean]
|
33
50
|
def solemnity?
|
34
51
|
priority.to_i == 1
|
35
52
|
end
|
36
53
|
|
54
|
+
# @return [Boolean]
|
55
|
+
# @since 0.6.0
|
37
56
|
def sunday?
|
38
57
|
self == Ranks::SUNDAY_UNPRIVILEGED
|
39
58
|
end
|
40
59
|
|
60
|
+
# @return [Boolean]
|
41
61
|
def feast?
|
42
62
|
priority.to_i == 2
|
43
63
|
end
|
44
64
|
|
65
|
+
# @return [Boolean]
|
45
66
|
def memorial?
|
46
67
|
priority.to_i == 3 && priority <= 3.12
|
47
68
|
end
|
48
69
|
|
70
|
+
# @return [Boolean]
|
71
|
+
# @since 0.6.0
|
49
72
|
def ferial?
|
50
73
|
self == Ranks::FERIAL ||
|
51
74
|
self == Ranks::FERIAL_PRIVILEGED
|
@@ -1,27 +1,60 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
1
3
|
module CalendariumRomanum
|
2
4
|
|
3
|
-
#
|
5
|
+
# One of the two main {Calendar} components.
|
6
|
+
# Contains celebrations with fixed date, mostly feasts of saints.
|
7
|
+
#
|
8
|
+
# Basically a mapping {AbstractDate} => Array<{Celebration}>
|
9
|
+
# additionally enforcing some constraints:
|
10
|
+
#
|
11
|
+
# - for a given {AbstractDate} there may be multiple {Celebration}s,
|
12
|
+
# but only if all of them are in the rank of an optional
|
13
|
+
# memorial
|
14
|
+
# - {Celebration#symbol} must be unique in the whole set of
|
15
|
+
# contained celebrations
|
4
16
|
class Sanctorale
|
5
17
|
|
6
18
|
def initialize
|
7
19
|
@days = {}
|
8
|
-
|
9
20
|
@solemnities = {}
|
21
|
+
@symbols = Set.new
|
22
|
+
@metadata = nil
|
10
23
|
end
|
11
24
|
|
25
|
+
# Content subset - only {Celebration}s in the rank(s) of solemnity.
|
26
|
+
#
|
27
|
+
# @return [Hash<AbstractDate=>Celebration>]
|
12
28
|
attr_reader :solemnities
|
13
29
|
|
30
|
+
# Sanctorale metadata.
|
31
|
+
#
|
32
|
+
# Data files may contain YAML front matter.
|
33
|
+
# If provided, it's loaded by {SanctoraleLoader} and
|
34
|
+
# stored in this property.
|
35
|
+
# All data files bundled in the gem (see {Data}) have YAML
|
36
|
+
# front matter which is a Hash with a few standardized keys.
|
37
|
+
# While YAML also supports top-level content of other types,
|
38
|
+
# sanctorale data authors should stick to the convention
|
39
|
+
# of using Hash as the top-level data structure of their
|
40
|
+
# front matters.
|
41
|
+
#
|
42
|
+
# @return [Hash, nil]
|
43
|
+
# @since 0.7.0
|
44
|
+
attr_accessor :metadata
|
45
|
+
|
46
|
+
# Adds a new {Celebration}
|
47
|
+
#
|
48
|
+
# @param month [Fixnum]
|
49
|
+
# @param day [Fixnum]
|
50
|
+
# @param celebration [Celebration]
|
51
|
+
# @return [void]
|
52
|
+
# @raise [ArgumentError]
|
53
|
+
# when performing the operation would break the object's invariant
|
14
54
|
def add(month, day, celebration)
|
15
55
|
date = AbstractDate.new(month, day)
|
16
|
-
unless @days.has_key? date
|
17
|
-
@days[date] = []
|
18
|
-
end
|
19
56
|
|
20
|
-
|
21
|
-
@solemnities[date] = celebration
|
22
|
-
end
|
23
|
-
|
24
|
-
unless @days[date].empty?
|
57
|
+
unless @days[date].nil? || @days[date].empty?
|
25
58
|
present = @days[date][0]
|
26
59
|
if present.rank != Ranks::MEMORIAL_OPTIONAL
|
27
60
|
raise ArgumentError.new("On #{date} there is already a #{present.rank}. No more celebrations can be added.")
|
@@ -30,13 +63,51 @@ module CalendariumRomanum
|
|
30
63
|
end
|
31
64
|
end
|
32
65
|
|
66
|
+
unless celebration.symbol.nil?
|
67
|
+
if @symbols.include? celebration.symbol
|
68
|
+
raise ArgumentError.new("Attempted to add Celebration with duplicate symbol #{celebration.symbol.inspect}")
|
69
|
+
end
|
70
|
+
|
71
|
+
@symbols << celebration.symbol
|
72
|
+
end
|
73
|
+
|
74
|
+
unless @days.has_key? date
|
75
|
+
@days[date] = []
|
76
|
+
end
|
77
|
+
|
78
|
+
if celebration.solemnity?
|
79
|
+
@solemnities[date] = celebration
|
80
|
+
end
|
81
|
+
|
33
82
|
@days[date] << celebration
|
34
83
|
end
|
35
84
|
|
36
|
-
#
|
85
|
+
# Replaces content of the given day by given {Celebration}s
|
86
|
+
#
|
87
|
+
# @param month [Fixnum]
|
88
|
+
# @param day [Fixnum]
|
89
|
+
# @param celebrations [Array<Celebration>]
|
90
|
+
# @return [void]
|
91
|
+
# @raise [ArgumentError]
|
92
|
+
# when performing the operation would break the object's invariant
|
37
93
|
def replace(month, day, celebrations)
|
38
94
|
date = AbstractDate.new(month, day)
|
39
95
|
|
96
|
+
symbols_without_day = @symbols
|
97
|
+
unless @days[date].nil?
|
98
|
+
old_symbols = @days[date].collect(&:symbol).compact
|
99
|
+
symbols_without_day = @symbols - old_symbols
|
100
|
+
end
|
101
|
+
|
102
|
+
new_symbols = celebrations.collect(&:symbol).compact
|
103
|
+
duplicate = symbols_without_day.intersection new_symbols
|
104
|
+
unless duplicate.empty?
|
105
|
+
raise ArgumentError.new("Attempted to add Celebrations with duplicate symbols #{duplicate.to_a.inspect}")
|
106
|
+
end
|
107
|
+
|
108
|
+
@symbols = symbols_without_day
|
109
|
+
@symbols.merge new_symbols
|
110
|
+
|
40
111
|
if celebrations.first.solemnity?
|
41
112
|
@solemnities[date] = celebrations.first
|
42
113
|
elsif @solemnities.has_key? date
|
@@ -46,22 +117,38 @@ module CalendariumRomanum
|
|
46
117
|
@days[date] = celebrations.dup
|
47
118
|
end
|
48
119
|
|
49
|
-
#
|
50
|
-
|
51
|
-
|
120
|
+
# Updates the receiver with {Celebration}s from another instance.
|
121
|
+
#
|
122
|
+
# For each date contained in +other+ the content of +self+
|
123
|
+
# is _replaced_ by that of +other+.
|
124
|
+
#
|
125
|
+
# @param other [Sanctorale]
|
126
|
+
# @return [void]
|
127
|
+
# @raise (see #replace)
|
128
|
+
def update(other)
|
129
|
+
other.each_day do |date, celebrations|
|
52
130
|
replace date.month, date.day, celebrations
|
53
131
|
end
|
54
132
|
end
|
55
133
|
|
134
|
+
# Retrieves {Celebration}s for the given date
|
135
|
+
#
|
136
|
+
# @param date [AbstractDate, Date]
|
137
|
+
# @return [Array<Celebration>] (may be empty)
|
138
|
+
# @since 0.6.0
|
56
139
|
def [](date)
|
57
140
|
adate = date.is_a?(AbstractDate) ? date : AbstractDate.from_date(date)
|
58
141
|
@days[adate] || []
|
59
142
|
end
|
60
143
|
|
61
|
-
#
|
62
|
-
# scheduled for the given day
|
144
|
+
# Retrieves {Celebration}s for the given date
|
63
145
|
#
|
64
|
-
#
|
146
|
+
# @overload get(date)
|
147
|
+
# @param date[AbstractDate, Date]
|
148
|
+
# @overload get(month, day)
|
149
|
+
# @param month [Fixnum]
|
150
|
+
# @param day [Fixnum]
|
151
|
+
# @return (see #[])
|
65
152
|
def get(*args)
|
66
153
|
if args.size == 1 && args[0].is_a?(Date)
|
67
154
|
month = args[0].month
|
@@ -74,23 +161,33 @@ module CalendariumRomanum
|
|
74
161
|
self[date]
|
75
162
|
end
|
76
163
|
|
77
|
-
#
|
78
|
-
#
|
164
|
+
# Enumerates dates for which any {Celebration}s are available
|
165
|
+
#
|
166
|
+
# @yield [AbstractDate, Array<Celebration>] the array is never empty
|
167
|
+
# @return [void, Enumerator] if called without a block, returns +Enumerator+
|
79
168
|
def each_day
|
169
|
+
return to_enum(__method__) unless block_given?
|
170
|
+
|
80
171
|
@days.each_pair do |date, celebrations|
|
81
172
|
yield date, celebrations
|
82
173
|
end
|
83
174
|
end
|
84
175
|
|
85
|
-
#
|
176
|
+
# Returns count of _days_ with {Celebration}s filled
|
177
|
+
#
|
178
|
+
# @return [Fixnum]
|
86
179
|
def size
|
87
180
|
@days.size
|
88
181
|
end
|
89
182
|
|
183
|
+
# It is empty if it doesn't contain any {Celebration}
|
184
|
+
#
|
185
|
+
# @return [Boolean]
|
90
186
|
def empty?
|
91
187
|
@days.empty?
|
92
188
|
end
|
93
189
|
|
190
|
+
# Freezes the instance
|
94
191
|
def freeze
|
95
192
|
@days.freeze
|
96
193
|
@days.values.each(&:freeze)
|
@@ -98,6 +195,8 @@ module CalendariumRomanum
|
|
98
195
|
super
|
99
196
|
end
|
100
197
|
|
198
|
+
# @return [Boolean]
|
199
|
+
# @since 0.6.0
|
101
200
|
def ==(b)
|
102
201
|
self.class == b.class &&
|
103
202
|
days == b.days
|