calendarium-romanum 0.5.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +5 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +50 -0
  5. data/.travis.yml +23 -0
  6. data/.yardopts +3 -0
  7. data/Appraisals +67 -0
  8. data/CHANGELOG.md +488 -0
  9. data/Gemfile +26 -0
  10. data/Gemfile.lock +95 -0
  11. data/README.md +601 -0
  12. data/Rakefile +27 -0
  13. data/bin/calendariumrom +3 -0
  14. data/calendarium-romanum.gemspec +31 -0
  15. data/config/locales/cs.yml +4 -0
  16. data/config/locales/en.yml +20 -14
  17. data/config/locales/es.yml +94 -0
  18. data/config/locales/fr.yml +6 -0
  19. data/config/locales/it.yml +6 -0
  20. data/config/locales/la.yml +6 -0
  21. data/config/locales/pt.yml +94 -0
  22. data/data/README.md +70 -24
  23. data/data/czech-brno-cs.txt +4 -6
  24. data/data/czech-budejovice-cs.txt +4 -6
  25. data/data/czech-cechy-cs.txt +4 -5
  26. data/data/czech-cs.txt +239 -235
  27. data/data/czech-hradec-cs.txt +3 -5
  28. data/data/czech-litomerice-cs.txt +5 -7
  29. data/data/czech-morava-cs.txt +4 -5
  30. data/data/czech-olomouc-cs.txt +2 -4
  31. data/data/czech-ostrava-cs.txt +3 -5
  32. data/data/czech-plzen-cs.txt +3 -5
  33. data/data/czech-praha-cs.txt +3 -4
  34. data/data/easter_dates.txt +67 -0
  35. data/data/universal-1969-la.txt +234 -0
  36. data/data/universal-en.txt +217 -211
  37. data/data/universal-es.txt +246 -0
  38. data/data/universal-fr.txt +217 -210
  39. data/data/universal-it.txt +217 -211
  40. data/data/universal-la.txt +217 -212
  41. data/data/universal-pt.txt +248 -0
  42. data/doc/data_readme.md +2 -0
  43. data/doc/images/class_diagram.png +0 -0
  44. data/doc/images/class_diagram.puml +44 -0
  45. data/doc/yard_readme.rdoc +76 -0
  46. data/lib/calendarium-romanum.rb +16 -2
  47. data/lib/calendarium-romanum/abstract_date.rb +15 -0
  48. data/lib/calendarium-romanum/calendar.rb +150 -33
  49. data/lib/calendarium-romanum/cli.rb +80 -100
  50. data/lib/calendarium-romanum/cli/comparator.rb +83 -0
  51. data/lib/calendarium-romanum/cli/date_parser.rb +30 -0
  52. data/lib/calendarium-romanum/cli/dumper.rb +68 -0
  53. data/lib/calendarium-romanum/cli/helper.rb +23 -0
  54. data/lib/calendarium-romanum/cli/querier.rb +73 -0
  55. data/lib/calendarium-romanum/cr.rb +16 -0
  56. data/lib/calendarium-romanum/data.rb +40 -8
  57. data/lib/calendarium-romanum/day.rb +187 -32
  58. data/lib/calendarium-romanum/enum.rb +41 -24
  59. data/lib/calendarium-romanum/enums.rb +127 -43
  60. data/lib/calendarium-romanum/errors.rb +1 -1
  61. data/lib/calendarium-romanum/ordinalizer.rb +10 -1
  62. data/lib/calendarium-romanum/perpetual_calendar.rb +58 -7
  63. data/lib/calendarium-romanum/rank.rb +39 -8
  64. data/lib/calendarium-romanum/rank_predicates.rb +43 -0
  65. data/lib/calendarium-romanum/sanctorale.rb +213 -23
  66. data/lib/calendarium-romanum/sanctorale_factory.rb +74 -3
  67. data/lib/calendarium-romanum/sanctorale_loader.rb +180 -0
  68. data/lib/calendarium-romanum/sanctorale_writer.rb +124 -0
  69. data/lib/calendarium-romanum/temporale.rb +222 -42
  70. data/lib/calendarium-romanum/temporale/celebration_factory.rb +68 -9
  71. data/lib/calendarium-romanum/temporale/date_helper.rb +85 -0
  72. data/lib/calendarium-romanum/temporale/dates.rb +52 -59
  73. data/lib/calendarium-romanum/temporale/easter_table.rb +27 -0
  74. data/lib/calendarium-romanum/temporale/extensions.rb +15 -0
  75. data/lib/calendarium-romanum/temporale/extensions/christ_eternal_priest.rb +16 -3
  76. data/lib/calendarium-romanum/temporale/extensions/dedication_before_all_saints.rb +73 -0
  77. data/lib/calendarium-romanum/transfers.rb +84 -24
  78. data/lib/calendarium-romanum/util.rb +21 -23
  79. data/lib/calendarium-romanum/version.rb +3 -2
  80. data/liturgical_law/1969_normae_universales.md +568 -0
  81. data/liturgical_law/1977_decretum_de_celebratione_baptismatis_domini.md +58 -0
  82. data/liturgical_law/1990_decretum_de_variatione_inducenda.md +67 -0
  83. data/liturgical_law/1998_notificatio_de_occurrentia.md +57 -0
  84. data/liturgical_law/2002_normae_universales.md +946 -0
  85. data/liturgical_law/2006_notification.md +37 -0
  86. data/liturgical_law/2012_declarationes.md +38 -0
  87. data/liturgical_law/2020_dubia_de_calendario_2022.md +100 -0
  88. data/liturgical_law/README.md +74 -0
  89. metadata +61 -38
  90. data/lib/calendarium-romanum/sanctoraleloader.rb +0 -122
  91. data/spec/abstract_date_spec.rb +0 -62
  92. data/spec/calendar_spec.rb +0 -559
  93. data/spec/celebration_factory_spec.rb +0 -16
  94. data/spec/celebration_spec.rb +0 -43
  95. data/spec/cli_spec.rb +0 -155
  96. data/spec/colour_spec.rb +0 -17
  97. data/spec/data_spec.rb +0 -23
  98. data/spec/date_parser_spec.rb +0 -68
  99. data/spec/date_spec.rb +0 -61
  100. data/spec/dates_spec.rb +0 -45
  101. data/spec/day_spec.rb +0 -108
  102. data/spec/enum_spec.rb +0 -51
  103. data/spec/i18n_spec.rb +0 -58
  104. data/spec/ordinalizer_spec.rb +0 -36
  105. data/spec/perpetual_calendar_spec.rb +0 -91
  106. data/spec/rank_spec.rb +0 -57
  107. data/spec/readme_spec.rb +0 -56
  108. data/spec/sanctorale_factory_spec.rb +0 -42
  109. data/spec/sanctorale_spec.rb +0 -191
  110. data/spec/sanctoraleloader_spec.rb +0 -176
  111. data/spec/season_spec.rb +0 -17
  112. data/spec/spec_helper.rb +0 -46
  113. data/spec/temporale_spec.rb +0 -572
@@ -1,31 +1,48 @@
1
1
  require 'forwardable'
2
2
 
3
3
  module CalendariumRomanum
4
- # Utility class for definition of enumerated "types"
5
- class Enum
6
- class << self
7
- extend Forwardable
8
-
9
- def values(index_by: nil)
10
- defined?(@indexed) && raise(RuntimeError.new('initialized repeatedly'))
11
-
12
- @indexed = {}
13
- @all = yield.freeze
14
-
15
- @all.each_with_index do |val, i|
16
- val.freeze
17
-
18
- key = index_by ? val.public_send(index_by) : i
19
- @indexed[key] = val
20
- end
21
-
22
- @indexed.freeze
4
+ # Each Enum encapsulates a finite set of value objects.
5
+ #
6
+ # @api private
7
+ module Enum
8
+ extend Forwardable
9
+
10
+ # @api private
11
+ # @param index_by
12
+ # specifies which value objects' property contains
13
+ # unique internal identifier for use with {.[]}
14
+ def values(index_by: nil)
15
+ defined?(@indexed) && raise(RuntimeError.new('initialized repeatedly'))
16
+
17
+ @all = yield.freeze
18
+ @all.each &:freeze
19
+
20
+ @indexed = {}
21
+ @all.each_with_index do |val, i|
22
+ key = index_by ? val.public_send(index_by) : i
23
+ @indexed[key] = val
23
24
  end
24
-
25
- attr_reader :all
26
-
27
- def_delegators :@all, :each
28
- def_delegators :@indexed, :[]
25
+ @indexed.freeze
29
26
  end
27
+
28
+ # Returns all contained value objects
29
+ #
30
+ # @return [Array]
31
+ attr_reader :all
32
+
33
+ # Enumerates contained value objects
34
+ #
35
+ # @!method each
36
+ # @yield value object
37
+ # @return [void]
38
+ def_delegators :@all, :each
39
+
40
+ # Allows accessing contained value objects by their
41
+ # internal unique identifiers
42
+ #
43
+ # @!method [](identifier)
44
+ # @param identifier
45
+ # @return value object or nil
46
+ def_delegators :@indexed, :[]
30
47
  end
31
48
  end
@@ -1,87 +1,171 @@
1
1
  module CalendariumRomanum
2
+ # Methods shared by most value objects defined by the gem
3
+ module ValueObjectInterface
4
+ # Machine-readable internal representation of the value
5
+ #
6
+ # @return [Symbol]
7
+ attr_reader :symbol
8
+ alias to_sym symbol
9
+
10
+ # Internationalized, human-readable name
11
+ #
12
+ # @return [String]
13
+ def name
14
+ I18n.t @i18n_key
15
+ end
16
+
17
+ # String representation of the contents for debugging purposes
18
+ #
19
+ # @return [String]
20
+ def to_s
21
+ "#<#{self.class.name} #{symbol}>"
22
+ end
23
+ end
2
24
 
25
+ # Represents a liturgical colour
3
26
  class Colour
27
+ include ValueObjectInterface
28
+
4
29
  def initialize(symbol)
5
30
  @symbol = symbol
6
31
  @i18n_key = "colour.#{@symbol}"
7
32
  end
33
+ end
8
34
 
9
- attr_reader :symbol
10
- alias to_sym symbol
35
+ # Standard set of liturgical colours
36
+ module Colours
37
+ extend Enum
11
38
 
12
- def name
13
- I18n.t @i18n_key
14
- end
15
- end
39
+ GREEN = Colour.new(:green)
40
+ VIOLET = Colour.new(:violet)
41
+ WHITE = Colour.new(:white)
42
+ RED = Colour.new(:red)
16
43
 
17
- class Colours < Enum
18
44
  values(index_by: :symbol) do
19
45
  [
20
- GREEN = Colour.new(:green),
21
- VIOLET = Colour.new(:violet),
22
- WHITE = Colour.new(:white),
23
- RED = Colour.new(:red)
46
+ GREEN,
47
+ VIOLET,
48
+ WHITE,
49
+ RED
24
50
  ]
25
51
  end
26
52
  end
27
53
 
54
+ # Convenience alias (American English spelling)
28
55
  Colors = Colours
29
56
 
57
+ # Liturgical season
30
58
  class Season
59
+ include ValueObjectInterface
60
+
61
+ # @param symbol [Symbol] internal identifier
62
+ # @param colour [Colour]
63
+ # liturgical colour of the season's Sundays and ferials
31
64
  def initialize(symbol, colour)
32
65
  @symbol = symbol
33
66
  @colour = colour
34
67
  @i18n_key = "temporale.season.#{@symbol}"
35
68
  end
36
69
 
37
- attr_reader :symbol, :colour
38
- alias to_sym symbol
39
-
40
- def name
41
- I18n.t @i18n_key
42
- end
70
+ # Liturgical colour of the season's Sundays and ferials
71
+ #
72
+ # May be +nil+ if there is no single colour.
73
+ #
74
+ # @return [Colour, nil]
75
+ attr_reader :colour
43
76
  end
44
77
 
45
- class Seasons < Enum
78
+ # Standard set of liturgical seasons
79
+ module Seasons
80
+ extend Enum
81
+
82
+ ADVENT = Season.new(:advent, Colours::VIOLET)
83
+ CHRISTMAS = Season.new(:christmas, Colours::WHITE)
84
+ LENT = Season.new(:lent, Colours::VIOLET)
85
+ TRIDUUM = Season.new(:triduum, nil)
86
+ EASTER = Season.new(:easter, Colours::WHITE)
87
+ ORDINARY = Season.new(:ordinary, Colours::GREEN)
88
+
46
89
  values(index_by: :symbol) do
47
90
  [
48
- ADVENT = Season.new(:advent, Colours::VIOLET),
49
- CHRISTMAS = Season.new(:christmas, Colours::WHITE),
50
- LENT = Season.new(:lent, Colours::VIOLET),
51
- EASTER = Season.new(:easter, Colours::WHITE),
52
- ORDINARY = Season.new(:ordinary, Colours::GREEN)
91
+ ADVENT,
92
+ CHRISTMAS,
93
+ LENT,
94
+ TRIDUUM,
95
+ EASTER,
96
+ ORDINARY,
53
97
  ]
54
98
  end
55
99
  end
56
100
 
101
+ # Sunday lectionary cycles.
102
+ # Values returned by {Calendar#lectionary}
57
103
  LECTIONARY_CYCLES = [:A, :B, :C].freeze
58
104
 
59
- # ranks of celebrations
60
- class Ranks < Enum
105
+ # Celebration ranks as specified in the Table of Liturgical Days
106
+ module Ranks
107
+ extend Enum
108
+
109
+ TRIDUUM = Rank.new(1.1, 'rank.1_1')
110
+ PRIMARY = Rank.new(1.2, 'rank.1_2') # description may not be exact
111
+ SOLEMNITY_GENERAL = Rank.new(1.3, 'rank.1_3', 'rank.short.solemnity') # description may not be exact
112
+ SOLEMNITY_PROPER = Rank.new(1.4, 'rank.1_4', 'rank.short.solemnity')
113
+
114
+ FEAST_LORD_GENERAL = Rank.new(2.5, 'rank.2_5', 'rank.short.feast')
115
+ SUNDAY_UNPRIVILEGED = Rank.new(2.6, 'rank.2_6', 'rank.short.sunday')
116
+ FEAST_GENERAL = Rank.new(2.7, 'rank.2_7', 'rank.short.feast')
117
+ FEAST_PROPER = Rank.new(2.8, 'rank.2_8', 'rank.short.feast')
118
+ FERIAL_PRIVILEGED = Rank.new(2.9, 'rank.2_9', 'rank.short.ferial')
119
+
120
+ MEMORIAL_GENERAL = Rank.new(3.10, 'rank.3_10', 'rank.short.memorial')
121
+ MEMORIAL_PROPER = Rank.new(3.11, 'rank.3_11', 'rank.short.memorial')
122
+ MEMORIAL_OPTIONAL = Rank.new(3.12, 'rank.3_12', 'rank.short.memorial_opt')
123
+ FERIAL = Rank.new(3.13, 'rank.3_13', 'rank.short.ferial')
124
+ # Not included as a celebration rank on it's own
125
+ # in the Table of Liturgical Days
126
+ COMMEMORATION = Rank.new(4.0, 'rank.4_0', 'rank.short.commemoration')
127
+
61
128
  values(index_by: :priority) do
62
129
  # Values are at the same time references to sections
63
130
  # of the Table of Liturgical Days.
64
131
  # The lower value, the higher rank.
65
132
  [
66
- TRIDUUM = Rank.new(1.1, 'rank.1_1'),
67
- PRIMARY = Rank.new(1.2, 'rank.1_2'), # description may not be exact
68
- SOLEMNITY_GENERAL = Rank.new(1.3, 'rank.1_3', 'rank.short.solemnity'), # description may not be exact
69
- SOLEMNITY_PROPER = Rank.new(1.4, 'rank.1_4', 'rank.short.solemnity'),
70
-
71
- FEAST_LORD_GENERAL = Rank.new(2.5, 'rank.2_5', 'rank.short.feast'),
72
- SUNDAY_UNPRIVILEGED = Rank.new(2.6, 'rank.2_6', 'rank.short.sunday'),
73
- FEAST_GENERAL = Rank.new(2.7, 'rank.2_7', 'rank.short.feast'),
74
- FEAST_PROPER = Rank.new(2.8, 'rank.2_8', 'rank.short.feast'),
75
- FERIAL_PRIVILEGED = Rank.new(2.9, 'rank.2_9', 'rank.short.ferial'),
76
-
77
- MEMORIAL_GENERAL = Rank.new(3.10, 'rank.3_10', 'rank.short.memorial'),
78
- MEMORIAL_PROPER = Rank.new(3.11, 'rank.3_11', 'rank.short.memorial'),
79
- MEMORIAL_OPTIONAL = Rank.new(3.12, 'rank.3_12', 'rank.short.memorial_opt'),
80
- FERIAL = Rank.new(3.13, 'rank.3_13', 'rank.short.ferial'),
81
- # not included as a celebration rank on it's own
82
- # in the Table of Liturgical Days
83
- COMMEMORATION = Rank.new(4.0, 'rank.4_0', 'rank.short.commemoration')
133
+ TRIDUUM,
134
+ PRIMARY,
135
+ SOLEMNITY_GENERAL,
136
+ SOLEMNITY_PROPER,
137
+
138
+ FEAST_LORD_GENERAL,
139
+ SUNDAY_UNPRIVILEGED,
140
+ FEAST_GENERAL,
141
+ FEAST_PROPER,
142
+ FERIAL_PRIVILEGED,
143
+
144
+ MEMORIAL_GENERAL,
145
+ MEMORIAL_PROPER,
146
+ MEMORIAL_OPTIONAL,
147
+ FERIAL,
148
+
149
+ COMMEMORATION,
84
150
  ]
85
151
  end
86
152
  end
153
+
154
+ # Convenience module containing all the colour, season and rank constants
155
+ # for easy including
156
+ #
157
+ # Caveat: there is both a {Season} and a {Rank} with the identifier +TRIDUUM+.
158
+ # Due to this name clash, only the {Rank} is easily accessible
159
+ # using the {Constants} module.
160
+ #
161
+ # @example
162
+ # include CalendariumRomanum::Constants
163
+ # RED # now all the constants are available in the current module
164
+ #
165
+ # @since 0.8.0
166
+ module Constants
167
+ include Colours
168
+ include Seasons
169
+ include Ranks
170
+ end
87
171
  end
@@ -1,4 +1,4 @@
1
1
  module CalendariumRomanum
2
- # attempt to load invalid calendar data
2
+ # Thrown by {SanctoraleLoader} on attempt to load invalid data
3
3
  class InvalidDataError < RuntimeError; end
4
4
  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 [Integer] 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, Integer]
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,32 +1,83 @@
1
1
  module CalendariumRomanum
2
- # When you want to query a calendar without caring about
3
- # civil and liturgical years and Calendar instances
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
5
- def initialize(sanctorale: nil, temporale_factory: nil, temporale_options: nil, cache: {})
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 vespers [Boolean]
22
+ # See argument of the same name to {Calendar#initialize}
23
+ # @param cache [Hash]
24
+ # object to be used as internal cache of {Calendar} instances -
25
+ # anything exposing +#[]=+ and +#[]+ and "behaving mostly like
26
+ # a +Hash+" will work.
27
+ # There's no need to pass it unless you want to have control
28
+ # over the cache. That may be sometimes useful
29
+ # in order to prevent a long-lived
30
+ # +PerpetualCalendar+ instance flooding the memory
31
+ # by huge amount of cached {Calendar} instances.
32
+ # (By default, once a {Calendar} for a certain year is built,
33
+ # it is cached for the +PerpetualCalendar+ instances' lifetime.)
34
+ def initialize(sanctorale: nil, temporale_factory: nil, temporale_options: nil, vespers: false, cache: {})
6
35
  if temporale_factory && temporale_options
7
36
  raise ArgumentError.new('Specify either temporale_factory or temporale_options, not both')
8
37
  end
9
38
 
10
39
  @sanctorale = sanctorale
11
40
  @temporale_factory = temporale_factory || build_temporale_factory(temporale_options)
41
+ @vespers = vespers
12
42
 
13
43
  @cache = cache
14
44
  end
15
45
 
16
- # returns a resolved Day
46
+ # @return [Day]
47
+ # @see Calendar#day
17
48
  def day(*args)
18
49
  calendar_for(*args).day(*args)
19
50
  end
20
51
 
21
- # returns a Calendar instance for the liturgical year containing
52
+ # @return [Day, Array<Day>]
53
+ # @see Calendar#[]
54
+ # @since 0.6.0
55
+ def [](arg)
56
+ if arg.is_a? Range
57
+ return arg.collect do |date|
58
+ calendar_for(date).day(date)
59
+ end
60
+ end
61
+
62
+ day(arg)
63
+ end
64
+
65
+ # Returns a {Calendar} instance for the liturgical year containing
22
66
  # the specified day
67
+ #
68
+ # Parameters like {Calendar#day}
69
+ #
70
+ # @return [Calendar]
23
71
  def calendar_for(*args)
24
72
  date = Calendar.mk_date(*args)
25
73
  year = Temporale.liturgical_year date
26
74
  calendar_instance year
27
75
  end
28
76
 
29
- # returns a Calendar instance for the specified liturgical year
77
+ # Returns a Calendar instance for the specified liturgical year
78
+ #
79
+ # @param year [Integer]
80
+ # @return [Calendar]
30
81
  def calendar_for_year(year)
31
82
  calendar_instance year
32
83
  end
@@ -42,7 +93,7 @@ module CalendariumRomanum
42
93
  if @cache.has_key? year
43
94
  @cache[year]
44
95
  else
45
- @cache[year] = Calendar.new(year, @sanctorale, @temporale_factory.call(year))
96
+ @cache[year] = Calendar.new(year, @sanctorale, @temporale_factory.call(year), vespers: @vespers)
46
97
  end
47
98
  end
48
99
  end
@@ -1,22 +1,44 @@
1
1
  module CalendariumRomanum
2
+ # Celebration rank
2
3
  class Rank
4
+ include RankPredicates
3
5
  include Comparable
4
6
 
7
+ # @param priority [Float, nil] number in the Table of Liturgical Days
8
+ # @param desc [String, nil]
9
+ # full description (translation string identifier)
10
+ # @param short_desc [String, nil]
11
+ # short rank name (translation string identifier)
5
12
  def initialize(priority = nil, desc = nil, short_desc = nil)
6
13
  @priority = priority
7
14
  @desc = desc
8
15
  @short_desc = short_desc
9
16
  end
10
17
 
18
+ # @return [Float, nil]
11
19
  attr_reader :priority
12
20
  alias to_f priority
13
21
 
22
+ # Full description - internationalized human-readable string.
23
+ #
24
+ # @return [String, nil]
14
25
  def desc
15
26
  @desc && I18n.t(@desc)
16
27
  end
17
28
 
18
- alias to_s desc
29
+ # String representation mostly for debugging purposes.
30
+ #
31
+ # @return [String]
32
+ def to_s
33
+ # 'desc' instead of '@desc' is intentional -
34
+ # for a good reason we don't present contents of an instance
35
+ # variable but result of an instance method
36
+ "#<#{self.class.name} @priority=#{priority} desc=#{desc.inspect}>"
37
+ end
19
38
 
39
+ # Short name - internationalized human-readable string.
40
+ #
41
+ # @return [String, nil]
20
42
  def short_desc
21
43
  @short_desc && I18n.t(@short_desc)
22
44
  end
@@ -25,16 +47,25 @@ module CalendariumRomanum
25
47
  other.priority <=> priority
26
48
  end
27
49
 
28
- def solemnity?
29
- priority.to_i == 1
30
- end
50
+ # Returns the next higher rank.
51
+ #
52
+ # Allows constructing ranges of ranks.
53
+ #
54
+ # @return [Rank]
55
+ # @since 0.8.0
56
+ def succ
57
+ all = CR::Ranks.all
58
+ index = all.index(self)
59
+ raise StopIteration.new if index == 0
31
60
 
32
- def feast?
33
- priority.to_i == 2
61
+ all[index - 1]
34
62
  end
35
63
 
36
- def memorial?
37
- priority.to_i == 3 && priority <= 3.12
64
+ private
65
+
66
+ # Required by the {RankPredicates} mixin
67
+ def rank
68
+ self
38
69
  end
39
70
  end
40
71
  end