calrom 0.1.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +24 -0
- data/.travis.yml +13 -3
- data/CHANGELOG.md +97 -0
- data/README.md +184 -9
- data/Rakefile +5 -1
- data/calrom.gemspec +3 -2
- data/lib/calrom/cli.rb +66 -7
- data/lib/calrom/config.rb +137 -5
- data/lib/calrom/date_range.rb +85 -2
- data/lib/calrom/environment_reader.rb +36 -0
- data/lib/calrom/exceptions.rb +4 -0
- data/lib/calrom/filtering_calendar.rb +71 -0
- data/lib/calrom/formatter/calendars.rb +29 -0
- data/lib/calrom/formatter/condensed.rb +51 -0
- data/lib/calrom/formatter/csv.rb +27 -0
- data/lib/calrom/formatter/easter.rb +16 -0
- data/lib/calrom/formatter/formatter.rb +13 -2
- data/lib/calrom/formatter/json.rb +38 -0
- data/lib/calrom/formatter/list.rb +11 -10
- data/lib/calrom/formatter/overview.rb +104 -0
- data/lib/calrom/highlighter/list.rb +6 -1
- data/lib/calrom/highlighter/no.rb +17 -0
- data/lib/calrom/highlighter/overview.rb +15 -0
- data/lib/calrom/highlighter/selective.rb +34 -0
- data/lib/calrom/option_parser.rb +268 -18
- data/lib/calrom/rc_parser.rb +10 -0
- data/lib/calrom/refinement/calendarium-romanum/triduum_nameclash_workaround.rb +34 -0
- data/lib/calrom/sanctorale_file.rb +14 -0
- data/lib/calrom/version.rb +1 -1
- data/lib/calrom.rb +19 -0
- metadata +39 -9
data/lib/calrom/date_range.rb
CHANGED
@@ -1,5 +1,32 @@
|
|
1
1
|
module Calrom
|
2
2
|
class DateRange < Range
|
3
|
+
def each_month
|
4
|
+
return to_enum(:each_month) unless block_given?
|
5
|
+
|
6
|
+
if first.year == last.year && first.month == last.month
|
7
|
+
# a single month or it's part
|
8
|
+
yield self
|
9
|
+
return
|
10
|
+
end
|
11
|
+
|
12
|
+
(Month.new(first.year, first.month) .. Month.new(last.year, last.month))
|
13
|
+
.each_with_index do |m,i|
|
14
|
+
if i == 0 && first.day > 1
|
15
|
+
# first month, incomplete
|
16
|
+
yield self.class.new(first, m.last)
|
17
|
+
elsif m.first.year == last.year && m.first.month == last.month && last != m.last
|
18
|
+
# last month, incomplete
|
19
|
+
yield self.class.new(m.first, last)
|
20
|
+
else
|
21
|
+
yield m
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def spans_multiple_months?
|
27
|
+
first.month != last.month ||
|
28
|
+
first.year != last.year
|
29
|
+
end
|
3
30
|
end
|
4
31
|
|
5
32
|
class Year < DateRange
|
@@ -10,16 +37,68 @@ module Calrom
|
|
10
37
|
def to_s
|
11
38
|
first.year.to_s
|
12
39
|
end
|
40
|
+
|
41
|
+
def each_month
|
42
|
+
return to_enum(:each_month) unless block_given?
|
43
|
+
|
44
|
+
1.upto(12) {|month| yield Month.new(first.year, month) }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class ThreeMonths < DateRange
|
49
|
+
def initialize(year, month)
|
50
|
+
super first_day_of_last_month(year, month), last_day_of_next_month(year, month)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def first_day_of_last_month(year, month)
|
56
|
+
Date.new(year, month, 1).prev_month
|
57
|
+
end
|
58
|
+
|
59
|
+
def last_day_of_next_month(year, month)
|
60
|
+
n = Date.new(year, month).next_month
|
61
|
+
|
62
|
+
Date.new(n.year, n.month, -1)
|
63
|
+
end
|
13
64
|
end
|
14
65
|
|
15
66
|
class Month < DateRange
|
16
67
|
def initialize(year, month)
|
17
|
-
|
68
|
+
@year = year
|
69
|
+
@month = month
|
70
|
+
|
71
|
+
super Date.new(year, month, 1), Date.new(year, month, -1)
|
18
72
|
end
|
19
73
|
|
20
74
|
def to_s
|
21
|
-
|
75
|
+
first.strftime '%B %Y'
|
76
|
+
end
|
77
|
+
|
78
|
+
def each_month
|
79
|
+
return to_enum(:each_month) unless block_given?
|
80
|
+
|
81
|
+
yield self
|
82
|
+
end
|
83
|
+
|
84
|
+
def succ
|
85
|
+
n = Date.new(@year, @month, 1).next_month
|
86
|
+
self.class.new(n.year, n.month)
|
22
87
|
end
|
88
|
+
|
89
|
+
def <=>(other)
|
90
|
+
years_cmp = year <=> other.year
|
91
|
+
|
92
|
+
if years_cmp != 0
|
93
|
+
years_cmp
|
94
|
+
else
|
95
|
+
month <=> other.month
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
protected
|
100
|
+
|
101
|
+
attr_reader :year, :month
|
23
102
|
end
|
24
103
|
|
25
104
|
class Day < DateRange
|
@@ -30,5 +109,9 @@ module Calrom
|
|
30
109
|
def to_s
|
31
110
|
first.to_s
|
32
111
|
end
|
112
|
+
|
113
|
+
def each_month
|
114
|
+
yield self
|
115
|
+
end
|
33
116
|
end
|
34
117
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Calrom
|
2
|
+
# Reads configuration from environment variables
|
3
|
+
class EnvironmentReader
|
4
|
+
def self.call(config = nil)
|
5
|
+
new(config || Config.new).call
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(config)
|
9
|
+
@config = config
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
today
|
14
|
+
|
15
|
+
@config
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def today
|
21
|
+
with_envvar 'CALROM_CURRENT_DATE' do |value, name|
|
22
|
+
begin
|
23
|
+
@config.today = Date.parse value
|
24
|
+
rescue ArgumentError
|
25
|
+
raise InputError.new "value of environment variable #{name} is not a valid date"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def with_envvar(name)
|
31
|
+
value = ENV[name]
|
32
|
+
|
33
|
+
yield value, name if value
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
|
3
|
+
module Calrom
|
4
|
+
# decorates /(Perpetual)?Calendar/, returns data filtered
|
5
|
+
class FilteringCalendar < SimpleDelegator
|
6
|
+
using Refinement::CalendariumRomanum::TriduumNameClashWorkaround
|
7
|
+
|
8
|
+
def initialize(calendar, days_filter_expressions=[], celebrations_filter_expressions=[])
|
9
|
+
super(calendar)
|
10
|
+
|
11
|
+
@days_filter = proc do |day|
|
12
|
+
days_filter_expressions.all? do |expr|
|
13
|
+
eval_filtering_expression(day, expr)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
@celebrations_filter = proc do |celebration|
|
18
|
+
celebrations_filter_expressions.all? do |expr|
|
19
|
+
eval_filtering_expression(celebration, expr)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def [](arg)
|
25
|
+
raw = super(arg)
|
26
|
+
|
27
|
+
unless @days_filter.(raw)
|
28
|
+
return FilteredDay.build_skipped raw
|
29
|
+
end
|
30
|
+
|
31
|
+
FilteredDay.new raw, raw.celebrations.select(&@celebrations_filter)
|
32
|
+
end
|
33
|
+
|
34
|
+
def each_day_in_range(range, include_skipped: false)
|
35
|
+
return to_enum(__method__, range, include_skipped: include_skipped) unless block_given?
|
36
|
+
|
37
|
+
range.each do |date|
|
38
|
+
day = self[date]
|
39
|
+
yield day if (include_skipped || !day.skipped?)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def eval_filtering_expression(object, expression)
|
46
|
+
object.instance_eval expression
|
47
|
+
rescue StandardError, SyntaxError => exception
|
48
|
+
raise InputError.new "Filter expression '#{expression}' raised #{exception.class}: #{exception.message}"
|
49
|
+
end
|
50
|
+
|
51
|
+
class FilteredDay < SimpleDelegator
|
52
|
+
def initialize(day, filtered_celebrations)
|
53
|
+
super(day)
|
54
|
+
|
55
|
+
@filtered_celebrations = filtered_celebrations
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.build_skipped(day)
|
59
|
+
new day, []
|
60
|
+
end
|
61
|
+
|
62
|
+
def celebrations
|
63
|
+
@filtered_celebrations
|
64
|
+
end
|
65
|
+
|
66
|
+
def skipped?
|
67
|
+
celebrations.empty?
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Calrom
|
2
|
+
module Formatter
|
3
|
+
# Prints list of available bundled calendars
|
4
|
+
class Calendars < Formatter
|
5
|
+
def call(calendar, date_range)
|
6
|
+
last_locale = nil
|
7
|
+
CR::Data.each do |d|
|
8
|
+
sanctorale = d.load_with_parents
|
9
|
+
meta = sanctorale.metadata
|
10
|
+
puts if last_locale && last_locale != meta['locale']
|
11
|
+
default = d == Config::DEFAULT_DATA ? ' [default]' : ''
|
12
|
+
puts "%-20s: %s [%s]%s" % [d.siglum, meta['title'], meta['locale'], default]
|
13
|
+
|
14
|
+
next unless meta['components']
|
15
|
+
|
16
|
+
parents =
|
17
|
+
meta['components']
|
18
|
+
.collect {|c| c['extends'] }
|
19
|
+
.compact
|
20
|
+
.map {|e| e.is_a?(Array) ? e : [e] } # 'extends' is String or Array
|
21
|
+
.flatten
|
22
|
+
.map {|p| p.sub(/\.\w{3,4}$/, '') } # file name to "siglum"
|
23
|
+
parents.each {|p| puts " < #{p}" }
|
24
|
+
last_locale = meta['locale']
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Calrom
|
2
|
+
module Formatter
|
3
|
+
class Condensed < Formatter
|
4
|
+
def call(calendar, date_range)
|
5
|
+
calendar.each_day_in_range(date_range) {|d| day d }
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def day(liturgical_day)
|
11
|
+
c = liturgical_day.celebrations.first
|
12
|
+
|
13
|
+
colour = highlighter.colour(c.colour.name[0].upcase, c.colour)
|
14
|
+
rank = highlighter.rank(rank(c.rank), c.rank)
|
15
|
+
title = short_title c
|
16
|
+
more = additional_celebrations(liturgical_day) + vespers(liturgical_day)
|
17
|
+
|
18
|
+
puts "#{title} #{rank}#{colour}#{more}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def rank(rank)
|
22
|
+
if rank.solemnity?
|
23
|
+
'*'
|
24
|
+
elsif rank.feast?
|
25
|
+
'+'
|
26
|
+
else
|
27
|
+
''
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def short_title(celebration)
|
32
|
+
if celebration.cycle == :sanctorale
|
33
|
+
# naive attempt to strip feast titles
|
34
|
+
celebration.title.sub /,[^,]*$/, ''
|
35
|
+
else
|
36
|
+
celebration.title
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def additional_celebrations(day)
|
41
|
+
size = day.celebrations.size
|
42
|
+
|
43
|
+
size > 1 ? " +#{size-1}" : ''
|
44
|
+
end
|
45
|
+
|
46
|
+
def vespers(day)
|
47
|
+
day.vespers_from_following? ? '>' : ''
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'csv'
|
2
|
+
|
3
|
+
module Calrom
|
4
|
+
module Formatter
|
5
|
+
class Csv < Formatter
|
6
|
+
def call(calendar, date_range)
|
7
|
+
CSV do |out|
|
8
|
+
out << %w(date title symbol rank rank_num colour season)
|
9
|
+
|
10
|
+
calendar.each_day_in_range(date_range) do |day|
|
11
|
+
day.celebrations.each do |c|
|
12
|
+
out << [
|
13
|
+
day.date,
|
14
|
+
c.title,
|
15
|
+
c.symbol,
|
16
|
+
c.rank.short_desc,
|
17
|
+
c.rank.priority,
|
18
|
+
c.colour.symbol,
|
19
|
+
day.season.symbol
|
20
|
+
]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Calrom
|
2
|
+
module Formatter
|
3
|
+
# Prints (only) date of Easter for the specified year.
|
4
|
+
class Easter < Formatter
|
5
|
+
def call(calendar, date_range)
|
6
|
+
unless date_range.is_a?(Year) || date_range.is_a?(Month)
|
7
|
+
raise 'unexpected date range, expected a year'
|
8
|
+
end
|
9
|
+
|
10
|
+
puts CR::Temporale::Dates
|
11
|
+
.easter_sunday(date_range.first.year - 1)
|
12
|
+
.strftime('%D')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,14 +1,25 @@
|
|
1
1
|
module Calrom
|
2
2
|
module Formatter
|
3
3
|
class Formatter
|
4
|
-
def initialize(highlighter, today)
|
4
|
+
def initialize(highlighter, today, io = STDOUT)
|
5
5
|
@highlighter = highlighter
|
6
6
|
@today = today
|
7
|
+
@io = io
|
7
8
|
end
|
8
9
|
|
9
10
|
attr_reader :highlighter, :today
|
10
11
|
|
11
|
-
def call(
|
12
|
+
def call(calendar, date_range)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def puts(s = '')
|
18
|
+
@io.puts s
|
19
|
+
end
|
20
|
+
|
21
|
+
def print(s)
|
22
|
+
@io.print s
|
12
23
|
end
|
13
24
|
end
|
14
25
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Calrom
|
4
|
+
module Formatter
|
5
|
+
# JSON format mimicking Church Calendar API v0 (https://github.com/igneus/church-calendar-api)
|
6
|
+
class Json < Formatter
|
7
|
+
def call(calendar, date_range)
|
8
|
+
# We build the outer JSON Array manually in order to be able to print
|
9
|
+
# vast amounts of calendar data without risking RAM exhaustion.
|
10
|
+
print "["
|
11
|
+
|
12
|
+
calendar.each_day_in_range(date_range).each_with_index do |day,i|
|
13
|
+
date = day.date
|
14
|
+
hash = {
|
15
|
+
date: date,
|
16
|
+
season: day.season.symbol,
|
17
|
+
season_week: day.season_week,
|
18
|
+
celebrations: day.celebrations.collect do |c|
|
19
|
+
{
|
20
|
+
title: c.title,
|
21
|
+
symbol: c.symbol,
|
22
|
+
colour: c.colour.symbol,
|
23
|
+
rank: c.rank.short_desc,
|
24
|
+
rank_num: c.rank.priority
|
25
|
+
}
|
26
|
+
end,
|
27
|
+
weekday: date.strftime('%A'),
|
28
|
+
}
|
29
|
+
|
30
|
+
puts "," if i > 0
|
31
|
+
print JSON.generate hash
|
32
|
+
end
|
33
|
+
|
34
|
+
puts "]"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -1,21 +1,21 @@
|
|
1
1
|
module Calrom
|
2
2
|
module Formatter
|
3
3
|
class List < Formatter
|
4
|
-
def call(
|
5
|
-
print_months = date_range.
|
4
|
+
def call(calendar, date_range)
|
5
|
+
print_months = date_range.spans_multiple_months?
|
6
6
|
|
7
7
|
puts date_range.to_s
|
8
8
|
puts
|
9
9
|
|
10
10
|
current_month = nil
|
11
11
|
|
12
|
-
|
12
|
+
calendar.each_day_in_range(date_range) do |liturgical_day|
|
13
13
|
if print_months && liturgical_day.date.month != current_month
|
14
|
-
current_month
|
15
|
-
|
16
|
-
puts
|
17
|
-
puts current_month
|
14
|
+
puts unless current_month == nil
|
15
|
+
puts liturgical_day.date.strftime('%B') #current_month
|
18
16
|
puts
|
17
|
+
|
18
|
+
current_month = liturgical_day.date.month
|
19
19
|
end
|
20
20
|
|
21
21
|
day liturgical_day
|
@@ -28,9 +28,10 @@ module Calrom
|
|
28
28
|
liturgical_day.celebrations.each_with_index do |celebration, i|
|
29
29
|
s =
|
30
30
|
if i > 0
|
31
|
-
' ' *
|
31
|
+
' ' * 6
|
32
32
|
else
|
33
|
-
liturgical_day.date.
|
33
|
+
liturgical_day.date.strftime('%a') +
|
34
|
+
liturgical_day.date.day.to_s.rjust(3)
|
34
35
|
end
|
35
36
|
s += ' '
|
36
37
|
|
@@ -39,7 +40,7 @@ module Calrom
|
|
39
40
|
s += highlighter.colour(colour.name[0].upcase, colour) +
|
40
41
|
' ' +
|
41
42
|
highlighter.rank(celebration.title, rank) +
|
42
|
-
(rank.short_desc.nil? ? '' : ', ' + rank.short_desc)
|
43
|
+
((rank.short_desc.nil? || rank.sunday? || rank.ferial?) ? '' : ', ' + rank.short_desc)
|
43
44
|
|
44
45
|
if liturgical_day.date == today
|
45
46
|
s = highlighter.today s
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'set'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
module Calrom
|
5
|
+
module Formatter
|
6
|
+
class Overview < Formatter
|
7
|
+
def call(calendar, date_range)
|
8
|
+
colnum = 3 # TODO: expose configuration
|
9
|
+
if date_range.is_a? Year
|
10
|
+
puts center_on(weekdays.size * colnum + 2 * (colnum - 1), date_range.to_s)
|
11
|
+
end
|
12
|
+
|
13
|
+
date_range.each_month.each_slice(colnum) do |months|
|
14
|
+
columns = months.collect do |month|
|
15
|
+
StringIO.new.tap do |io|
|
16
|
+
print_month io, calendar, month, date_range.is_a?(Year)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
print_columns columns, @io
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def print_month(io, calendar, month, year_in_heading)
|
26
|
+
heading = month.first.strftime(year_in_heading ? '%B' : '%B %Y')
|
27
|
+
io.puts center_on weekdays.size, heading
|
28
|
+
|
29
|
+
io.puts weekdays
|
30
|
+
|
31
|
+
io.print ' ' * month.first.wday
|
32
|
+
calendar.each_day_in_range(month, include_skipped: true) do |liturgical_day|
|
33
|
+
date = liturgical_day.date
|
34
|
+
|
35
|
+
if liturgical_day.skipped?
|
36
|
+
datestr = ' '
|
37
|
+
else
|
38
|
+
celebration = liturgical_day.celebrations.first
|
39
|
+
|
40
|
+
datestr = date.day.to_s.rjust(2)
|
41
|
+
datestr = highlighter.colour(datestr, celebration.colour)
|
42
|
+
datestr = highlighter.rank(datestr, celebration.rank)
|
43
|
+
end
|
44
|
+
|
45
|
+
if date == today
|
46
|
+
datestr = highlighter.today datestr
|
47
|
+
end
|
48
|
+
io.print datestr
|
49
|
+
if date.wday == 6
|
50
|
+
io.puts
|
51
|
+
else
|
52
|
+
io.print ' '
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# localizable 2-character weekday shortcuts
|
58
|
+
def weekdays
|
59
|
+
@weekdays ||=
|
60
|
+
begin
|
61
|
+
sunday = Date.new 1987, 10, 25
|
62
|
+
sunday
|
63
|
+
.upto(sunday + 6)
|
64
|
+
.collect {|d| d.strftime('%a')[0..1] }
|
65
|
+
.join(' ')
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# centers given string on a given line length
|
70
|
+
def center_on(line_length, content)
|
71
|
+
(' ' * (line_length / 2 - content.size / 2)) +
|
72
|
+
content
|
73
|
+
end
|
74
|
+
|
75
|
+
def print_columns(columns, io)
|
76
|
+
line_enumerators = columns.collect {|c| c.string.each_line }
|
77
|
+
not_yet_exhausted = Set.new line_enumerators
|
78
|
+
column_width = weekdays.size
|
79
|
+
|
80
|
+
loop do
|
81
|
+
break if not_yet_exhausted.empty?
|
82
|
+
|
83
|
+
line_enumerators.each do |l|
|
84
|
+
begin
|
85
|
+
line = l.next.chop
|
86
|
+
io.print line
|
87
|
+
io.print ' ' * (column_width - colour_aware_size(line))
|
88
|
+
rescue StopIteration
|
89
|
+
io.print ' ' * column_width
|
90
|
+
not_yet_exhausted.delete l
|
91
|
+
end
|
92
|
+
io.print ' '
|
93
|
+
end
|
94
|
+
io.puts
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# String length ignoring colour codes
|
99
|
+
def colour_aware_size(str)
|
100
|
+
ColorizedString.new(str).uncolorize.size
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -1,8 +1,13 @@
|
|
1
1
|
module Calrom
|
2
2
|
module Highlighter
|
3
3
|
class List
|
4
|
+
COLOUR_OVERRIDE = {
|
5
|
+
# 'colorize' does not know colour :violet
|
6
|
+
CR::Colours::VIOLET => :magenta,
|
7
|
+
}
|
8
|
+
|
4
9
|
def colour(text, colour)
|
5
|
-
ColorizedString.new(text).colorize(colour.symbol)
|
10
|
+
ColorizedString.new(text).colorize(COLOUR_OVERRIDE[colour] || colour.symbol)
|
6
11
|
end
|
7
12
|
|
8
13
|
def rank(text, rank)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Calrom
|
2
|
+
module Highlighter
|
3
|
+
class Overview < List
|
4
|
+
def rank(text, rank)
|
5
|
+
if rank.solemnity?
|
6
|
+
ColorizedString.new(text).colorize(mode: :bold)
|
7
|
+
elsif rank.feast?
|
8
|
+
ColorizedString.new(text).colorize(mode: :underline)
|
9
|
+
else
|
10
|
+
text
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Calrom
|
2
|
+
module Highlighter
|
3
|
+
class Selective
|
4
|
+
def initialize(selected, highlighter)
|
5
|
+
@selected = selected
|
6
|
+
@highlighter = highlighter
|
7
|
+
end
|
8
|
+
|
9
|
+
def colour(text, colour)
|
10
|
+
if @selected.include? __method__
|
11
|
+
@highlighter.public_send __method__, text, colour
|
12
|
+
else
|
13
|
+
text
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def rank(text, rank)
|
18
|
+
if @selected.include? __method__
|
19
|
+
@highlighter.public_send __method__, text, rank
|
20
|
+
else
|
21
|
+
text
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def today(text)
|
26
|
+
if @selected.include? __method__
|
27
|
+
@highlighter.public_send __method__, text
|
28
|
+
else
|
29
|
+
text
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|