calendarium-romanum 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/calendariumrom +2 -61
- data/config/locales/cs.yml +40 -0
- data/config/locales/en.yml +4 -1
- data/config/locales/it.yml +40 -0
- data/config/locales/la.yml +40 -0
- data/data/README.md +87 -0
- data/data/czech-brno-cs.txt +7 -0
- data/data/czech-budejovice-cs.txt +8 -0
- data/data/czech-cechy-cs.txt +8 -0
- data/data/czech-cs.txt +259 -0
- data/data/czech-hradec-cs.txt +6 -0
- data/data/czech-litomerice-cs.txt +8 -0
- data/data/czech-morava-cs.txt +7 -0
- data/data/czech-olomouc-cs.txt +4 -0
- data/data/czech-ostrava-cs.txt +6 -0
- data/data/czech-plzen-cs.txt +6 -0
- data/data/czech-praha-cs.txt +4 -0
- data/data/universal-en.txt +237 -0
- data/data/universal-it.txt +236 -0
- data/data/universal-la.txt +236 -0
- data/lib/calendarium-romanum.rb +2 -0
- data/lib/calendarium-romanum/calendar.rb +4 -1
- data/lib/calendarium-romanum/cli.rb +100 -0
- data/lib/calendarium-romanum/data.rb +41 -0
- data/lib/calendarium-romanum/day.rb +7 -1
- data/lib/calendarium-romanum/enum.rb +33 -0
- data/lib/calendarium-romanum/enums.rb +43 -35
- data/lib/calendarium-romanum/rank.rb +16 -12
- data/lib/calendarium-romanum/sanctorale.rb +9 -0
- data/lib/calendarium-romanum/sanctoraleloader.rb +8 -8
- data/lib/calendarium-romanum/temporale.rb +24 -9
- data/lib/calendarium-romanum/version.rb +1 -1
- data/spec/calendar_spec.rb +89 -7
- data/spec/cli_spec.rb +26 -0
- data/spec/data_spec.rb +16 -8
- data/spec/date_spec.rb +52 -1
- data/spec/enum_spec.rb +51 -0
- data/spec/i18n_spec.rb +59 -0
- data/spec/readme_spec.rb +50 -0
- data/spec/sanctorale_spec.rb +24 -1
- data/spec/sanctoraleloader_spec.rb +30 -1
- data/spec/temporale_spec.rb +24 -0
- metadata +28 -2
@@ -1,48 +1,56 @@
|
|
1
1
|
module CalendariumRomanum
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
class Seasons < Enum
|
4
|
+
values do
|
5
|
+
[
|
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
|
13
|
+
]
|
14
|
+
end
|
11
15
|
end
|
12
16
|
|
13
17
|
LECTIONARY_CYCLES = [:A, :B, :C]
|
14
18
|
|
15
19
|
# ranks of celebrations
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
20
|
+
class Ranks < Enum
|
21
|
+
values(index_by: :priority) do
|
22
|
+
# Values are at the same time references to sections
|
23
|
+
# of the Table of Liturgical Days.
|
24
|
+
# The lower value, the higher rank.
|
25
|
+
[
|
26
|
+
TRIDUUM = Rank.new(1.1, 'rank.1_1'),
|
27
|
+
PRIMARY = Rank.new(1.2, 'rank.1_2'), # description may not be exact
|
28
|
+
SOLEMNITY_GENERAL = Rank.new(1.3, 'rank.1_3', 'rank.short.solemnity'), # description may not be exact
|
29
|
+
SOLEMNITY_PROPER = Rank.new(1.4, 'rank.1_4', 'rank.short.solemnity'),
|
30
|
+
|
31
|
+
FEAST_LORD_GENERAL = Rank.new(2.5, 'rank.2_5', 'rank.short.feast'),
|
32
|
+
SUNDAY_UNPRIVILEGED = Rank.new(2.6, 'rank.2_6', 'rank.short.sunday'),
|
33
|
+
FEAST_GENERAL = Rank.new(2.7, 'rank.2_7', 'rank.short.feast'),
|
34
|
+
FEAST_PROPER = Rank.new(2.8, 'rank.2_8', 'rank.short.feast'),
|
35
|
+
FERIAL_PRIVILEGED = Rank.new(2.9, 'rank.2_9', 'rank.short.ferial'),
|
36
|
+
|
37
|
+
MEMORIAL_GENERAL = Rank.new(3.10, 'rank.3_10', 'rank.short.memorial'),
|
38
|
+
MEMORIAL_PROPER = Rank.new(3.11, 'rank.3_11', 'rank.short.memorial'),
|
39
|
+
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')
|
41
|
+
]
|
38
42
|
end
|
39
43
|
end
|
40
44
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
45
|
+
class Colours < Enum
|
46
|
+
values do
|
47
|
+
[
|
48
|
+
GREEN = :green,
|
49
|
+
VIOLET = :violet,
|
50
|
+
WHITE = :white,
|
51
|
+
RED = :red
|
52
|
+
]
|
53
|
+
end
|
46
54
|
end
|
47
55
|
|
48
56
|
Colors = Colours
|
@@ -1,24 +1,28 @@
|
|
1
1
|
module CalendariumRomanum
|
2
|
-
class Rank
|
2
|
+
class Rank
|
3
3
|
include Comparable
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
@@instances[self.priority] = self
|
5
|
+
def initialize(priority=nil, desc=nil, short_desc=nil)
|
6
|
+
@priority = priority
|
7
|
+
@desc = desc
|
8
|
+
@short_desc = short_desc
|
11
9
|
end
|
12
10
|
|
13
|
-
|
14
|
-
|
11
|
+
attr_reader :priority
|
12
|
+
alias_method :to_f, :priority
|
13
|
+
|
14
|
+
def desc
|
15
|
+
@desc && I18n.t(@desc)
|
15
16
|
end
|
16
17
|
|
17
|
-
alias_method :to_f, :priority
|
18
18
|
alias_method :to_s, :desc
|
19
19
|
|
20
|
-
def
|
21
|
-
|
20
|
+
def short_desc
|
21
|
+
@short_desc && I18n.t(@short_desc)
|
22
|
+
end
|
23
|
+
|
24
|
+
def <=>(b)
|
25
|
+
b.priority <=> self.priority
|
22
26
|
end
|
23
27
|
|
24
28
|
def solemnity?
|
@@ -21,6 +21,15 @@ module CalendariumRomanum
|
|
21
21
|
@solemnities[date] = celebration
|
22
22
|
end
|
23
23
|
|
24
|
+
unless @days[date].empty?
|
25
|
+
present = @days[date][0]
|
26
|
+
if present.rank != Ranks::MEMORIAL_OPTIONAL
|
27
|
+
raise ArgumentError.new("On #{date} there is already a #{present.rank}. No more celebrations can be added.")
|
28
|
+
elsif celebration.rank != Ranks::MEMORIAL_OPTIONAL
|
29
|
+
raise ArgumentError.new("Celebration of rank #{celebration.rank} cannot be grouped, but there is already another celebration on #{date}")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
24
33
|
@days[date] << celebration
|
25
34
|
end
|
26
35
|
|
@@ -19,10 +19,10 @@ module CalendariumRomanum
|
|
19
19
|
}
|
20
20
|
COLOUR_CODES = {
|
21
21
|
nil => Colours::WHITE,
|
22
|
-
'
|
23
|
-
'
|
24
|
-
'
|
25
|
-
'
|
22
|
+
'w' => Colours::WHITE,
|
23
|
+
'v' => Colours::VIOLET,
|
24
|
+
'g' => Colours::GREEN,
|
25
|
+
'r' => Colours::RED
|
26
26
|
}
|
27
27
|
|
28
28
|
# dest should be a Sanctorale,
|
@@ -50,7 +50,7 @@ module CalendariumRomanum
|
|
50
50
|
end
|
51
51
|
|
52
52
|
# celebration record
|
53
|
-
m = l.match /^((\d+)\/)?(\d+)\s*(([mfs])(\d\.\d
|
53
|
+
m = l.match /^((\d+)\/)?(\d+)\s*(([mfs])?(\d\.\d{1,2})?)?\s*([WVRG])?\s*:(.*)$/i
|
54
54
|
if m.nil?
|
55
55
|
raise error("Syntax error, line skipped '#{l}'", line_num)
|
56
56
|
next
|
@@ -61,7 +61,7 @@ module CalendariumRomanum
|
|
61
61
|
day = day.to_i
|
62
62
|
month = month.to_i
|
63
63
|
|
64
|
-
rank = RANK_CODES[rank_char]
|
64
|
+
rank = RANK_CODES[rank_char && rank_char.downcase]
|
65
65
|
if rank.nil?
|
66
66
|
raise error("Invalid celebration rank code #{rank_char}", line_num)
|
67
67
|
end
|
@@ -72,7 +72,7 @@ module CalendariumRomanum
|
|
72
72
|
|
73
73
|
if rank_by_num.nil?
|
74
74
|
raise error("Invalid celebration rank code #{rank_num}", line_num)
|
75
|
-
elsif rank.priority.to_i != rank_by_num.priority.to_i
|
75
|
+
elsif rank_char && (rank.priority.to_i != rank_by_num.priority.to_i)
|
76
76
|
raise error("Invalid combination of rank letter #{rank_char.inspect} and number #{rank_num}.", line_num)
|
77
77
|
end
|
78
78
|
|
@@ -82,7 +82,7 @@ module CalendariumRomanum
|
|
82
82
|
dest.add month, day, Celebration.new(
|
83
83
|
title.strip,
|
84
84
|
rank,
|
85
|
-
COLOUR_CODES[colour]
|
85
|
+
COLOUR_CODES[colour && colour.downcase]
|
86
86
|
)
|
87
87
|
end
|
88
88
|
|
@@ -55,6 +55,9 @@ module CalendariumRomanum
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def range_check(date)
|
58
|
+
# necessary in order to handle Date correctly
|
59
|
+
date = date.to_date if date.class != Date
|
60
|
+
|
58
61
|
unless date_range.include? date
|
59
62
|
raise RangeError.new "Date out of range #{date}"
|
60
63
|
end
|
@@ -191,12 +194,20 @@ module CalendariumRomanum
|
|
191
194
|
end
|
192
195
|
end
|
193
196
|
|
197
|
+
def palm_sunday(year=nil)
|
198
|
+
return easter_sunday(year) - 7
|
199
|
+
end
|
200
|
+
|
194
201
|
def good_friday(year=nil)
|
195
|
-
return
|
202
|
+
return easter_sunday(year) - 2
|
196
203
|
end
|
197
204
|
|
198
205
|
def holy_saturday(year=nil)
|
199
|
-
return
|
206
|
+
return easter_sunday(year) - 1
|
207
|
+
end
|
208
|
+
|
209
|
+
def ascension(year=nil)
|
210
|
+
return pentecost(year) - 10
|
200
211
|
end
|
201
212
|
|
202
213
|
def pentecost(year=nil)
|
@@ -275,8 +286,9 @@ module CalendariumRomanum
|
|
275
286
|
week += 1
|
276
287
|
|
277
288
|
if date > pentecost
|
278
|
-
|
279
|
-
week
|
289
|
+
weeks_after_date = date_difference(first_advent_sunday(@year + 1), date) / 7
|
290
|
+
week = 34 - weeks_after_date
|
291
|
+
week += 1 if date.sunday?
|
280
292
|
end
|
281
293
|
end
|
282
294
|
|
@@ -362,15 +374,18 @@ module CalendariumRomanum
|
|
362
374
|
@solemnities = {}
|
363
375
|
|
364
376
|
{
|
365
|
-
nativity: [
|
377
|
+
nativity: [Ranks::PRIMARY, nil],
|
366
378
|
holy_family: [Ranks::FEAST_LORD_GENERAL, nil],
|
367
379
|
mother_of_god: [Ranks::SOLEMNITY_GENERAL],
|
368
|
-
epiphany: [
|
380
|
+
epiphany: [Ranks::PRIMARY, nil],
|
369
381
|
baptism_of_lord: [Ranks::FEAST_LORD_GENERAL, nil],
|
382
|
+
ash_wednesday: [Ranks::PRIMARY, nil],
|
370
383
|
good_friday: [Ranks::TRIDUUM, Colours::RED],
|
371
384
|
holy_saturday: [Ranks::TRIDUUM, nil],
|
385
|
+
palm_sunday: [Ranks::PRIMARY, Colours::RED],
|
372
386
|
easter_sunday: [Ranks::TRIDUUM, nil],
|
373
|
-
|
387
|
+
ascension: [Ranks::PRIMARY, Colours::WHITE],
|
388
|
+
pentecost: [Ranks::PRIMARY, Colours::RED],
|
374
389
|
holy_trinity: [Ranks::SOLEMNITY_GENERAL, Colours::WHITE],
|
375
390
|
body_blood: [Ranks::SOLEMNITY_GENERAL, Colours::WHITE],
|
376
391
|
sacred_heart: [Ranks::SOLEMNITY_GENERAL, Colours::WHITE],
|
@@ -379,8 +394,8 @@ module CalendariumRomanum
|
|
379
394
|
date = send(method_name)
|
380
395
|
rank, colour = data
|
381
396
|
@solemnities[date] = Celebration.new(
|
382
|
-
I18n.t("temporale.solemnity.#{method_name}"),
|
383
|
-
rank
|
397
|
+
proc { I18n.t("temporale.solemnity.#{method_name}") },
|
398
|
+
rank,
|
384
399
|
colour || SEASON_COLOUR[season(date)]
|
385
400
|
)
|
386
401
|
end
|
data/spec/calendar_spec.rb
CHANGED
@@ -43,12 +43,42 @@ describe CR::Calendar do
|
|
43
43
|
end
|
44
44
|
|
45
45
|
describe '#day' do
|
46
|
-
|
47
|
-
|
48
|
-
|
46
|
+
describe 'received arguments' do
|
47
|
+
describe 'Date' do
|
48
|
+
it 'returns a Day' do
|
49
|
+
@c.day(Date.new(2013, 12, 10)).should be_a CR::Day
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe 'DateTime' do
|
54
|
+
it 'returns a Day' do
|
55
|
+
@c.day(DateTime.new(2013, 12, 10, 12, 10, 0)).should be_a CR::Day
|
56
|
+
end
|
57
|
+
end
|
49
58
|
|
50
|
-
|
51
|
-
|
59
|
+
describe 'three Integers' do
|
60
|
+
it 'returns a Day' do
|
61
|
+
@c.day(2013, 12, 10).should be_a CR::Day
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe 'two integers' do
|
66
|
+
describe 'autumn' do
|
67
|
+
it 'supplies year' do
|
68
|
+
day = @c.day(12, 10)
|
69
|
+
expect(day).to be_a CR::Day
|
70
|
+
expect(day.date).to eq Date.new(2013, 12, 10)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe 'spring' do
|
75
|
+
it 'supplies year' do
|
76
|
+
day = @c.day(4, 10)
|
77
|
+
expect(day).to be_a CR::Day
|
78
|
+
expect(day.date).to eq Date.new(2014, 4, 10)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
52
82
|
end
|
53
83
|
|
54
84
|
it 'throws RangeError if given date not included in the year' do
|
@@ -97,8 +127,60 @@ describe CR::Calendar do
|
|
97
127
|
expect(@c.day(2014, 1, 13).season_week).to eq 1
|
98
128
|
end
|
99
129
|
|
100
|
-
|
101
|
-
|
130
|
+
describe 'after Pentecost' do
|
131
|
+
it '2014' do
|
132
|
+
c = described_class.new(2013)
|
133
|
+
expect(c.day(2014, 6, 9).season_week).to eq 10
|
134
|
+
end
|
135
|
+
|
136
|
+
it '2015' do
|
137
|
+
c = described_class.new(2014)
|
138
|
+
expect(c.day(2015, 5, 25).season_week).to eq 8
|
139
|
+
end
|
140
|
+
|
141
|
+
it '2016' do
|
142
|
+
c = described_class.new(2015)
|
143
|
+
expect(c.day(2016, 5, 16).season_week).to eq 7
|
144
|
+
end
|
145
|
+
|
146
|
+
it '2017' do
|
147
|
+
c = described_class.new(2016)
|
148
|
+
expect(c.day(2017, 6, 5).season_week).to eq 9
|
149
|
+
end
|
150
|
+
|
151
|
+
describe 'works correctly for the whole week' do
|
152
|
+
describe 'first' do
|
153
|
+
Date.new(2014, 6, 9).upto(Date.new(2014, 6, 14)) do |date|
|
154
|
+
it date do
|
155
|
+
expect(@c.day(date).season_week).to eq 10
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe 'second' do
|
161
|
+
Date.new(2014, 6, 15).upto(Date.new(2014, 6, 21)) do |date|
|
162
|
+
it date do
|
163
|
+
expect(@c.day(date).season_week).to eq 11
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe 'second last' do
|
169
|
+
Date.new(2014, 11, 16).upto(Date.new(2014, 11, 22)) do |date|
|
170
|
+
it date do
|
171
|
+
expect(@c.day(date).season_week).to eq 33
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe 'last' do
|
177
|
+
Date.new(2014, 11, 23).upto(Date.new(2014, 11, 29)) do |date|
|
178
|
+
it date do
|
179
|
+
expect(@c.day(date).season_week).to eq 34
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
102
184
|
end
|
103
185
|
end
|
104
186
|
end
|
data/spec/cli_spec.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'calendarium-romanum/cli'
|
3
|
+
|
4
|
+
describe CalendariumRomanum::CLI do
|
5
|
+
let(:path_universal_la) { File.expand_path('../../data/universal-la.txt', __FILE__) }
|
6
|
+
let(:path_universal_en) { File.expand_path('../../data/universal-en.txt', __FILE__) }
|
7
|
+
describe 'subcommands' do
|
8
|
+
describe 'errors' do
|
9
|
+
it 'raises no exception' do
|
10
|
+
described_class.start(['errors', path_universal_la])
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'fails on a non-existent file' do
|
14
|
+
expect do
|
15
|
+
described_class.start(['errors', 'does-not-exist.txt'])
|
16
|
+
end.to raise_exception Errno::ENOENT
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'cmp' do
|
21
|
+
it 'raises no exception' do
|
22
|
+
described_class.start(['cmp', path_universal_la, path_universal_en])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/spec/data_spec.rb
CHANGED
@@ -1,15 +1,23 @@
|
|
1
1
|
require_relative 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
4
|
-
|
3
|
+
describe CalendariumRomanum::Data do
|
4
|
+
describe 'all available data files are included' do
|
5
|
+
data_path = File.expand_path '../data', File.dirname(__FILE__)
|
6
|
+
glob = File.join(data_path, '*.txt')
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
+
Dir[glob].each do |file|
|
9
|
+
it file do
|
10
|
+
in_data = described_class.all.find {|f| f.path == file }
|
11
|
+
expect(in_data).not_to be nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
8
15
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
16
|
+
describe 'all can be loaded' do
|
17
|
+
described_class.each do |data|
|
18
|
+
it data.siglum do
|
19
|
+
expect { data.load }.not_to raise_exception
|
20
|
+
end
|
13
21
|
end
|
14
22
|
end
|
15
23
|
end
|