calrom 0.3.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 +4 -4
- data/.github/workflows/ci.yml +24 -0
- data/.travis.yml +2 -2
- data/CHANGELOG.md +52 -0
- data/README.md +69 -14
- data/calrom.gemspec +2 -1
- data/lib/calrom/cli.rb +27 -5
- data/lib/calrom/config.rb +101 -28
- data/lib/calrom/date_range.rb +26 -13
- data/lib/calrom/environment_reader.rb +36 -0
- data/lib/calrom/filtering_calendar.rb +71 -0
- data/lib/calrom/formatter/calendars.rb +15 -8
- data/lib/calrom/formatter/condensed.rb +51 -0
- data/lib/calrom/formatter/csv.rb +2 -3
- data/lib/calrom/formatter/easter.rb +1 -1
- data/lib/calrom/formatter/formatter.rb +12 -1
- data/lib/calrom/formatter/json.rb +3 -3
- data/lib/calrom/formatter/list.rb +6 -8
- data/lib/calrom/formatter/overview.rb +15 -10
- data/lib/calrom/highlighter/selective.rb +34 -0
- data/lib/calrom/option_parser.rb +65 -12
- 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 +10 -0
- metadata +25 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c2e561032a6b91d68a87839856d8ce94b794187a539ac544fc907cfd2568add7
|
4
|
+
data.tar.gz: 8c9ab4bbdc83cc0c9884dbb4fb9f658c578e83956ce63da45b8698f59c55124f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e49e7f177d74b28c08ad6bd6ea25c4579857a6ca16ec68483b8fa4e1ad62807754f7010aad598ee156f728e94fd203042ae31f669f187b6ca52f3abcc0a2eec3
|
7
|
+
data.tar.gz: 2d416f813d7e688b1e855dcb28f27ba47002118c7de8d526ef8b86cd9571edd1bde6fdd9c0eb4c40a23bae75ab17fa66df43a7628b8f3d5ac5d29fd0be7b8bf7
|
@@ -0,0 +1,24 @@
|
|
1
|
+
name: CI
|
2
|
+
on: [push, pull_request]
|
3
|
+
jobs:
|
4
|
+
specs:
|
5
|
+
runs-on: ubuntu-latest
|
6
|
+
strategy:
|
7
|
+
matrix:
|
8
|
+
# oldest supported and newest MRI
|
9
|
+
# TODO: versions known to have worked back in Travis days; update needed
|
10
|
+
ruby-version:
|
11
|
+
- 2.5.0
|
12
|
+
- 3.0.0
|
13
|
+
|
14
|
+
steps:
|
15
|
+
- name: Check out code
|
16
|
+
uses: actions/checkout@v3
|
17
|
+
- name: Set up Ruby ${{ matrix.ruby-version }}
|
18
|
+
uses: ruby/setup-ruby@v1
|
19
|
+
with:
|
20
|
+
ruby-version: ${{ matrix.ruby-version }}
|
21
|
+
- name: Install dependencies
|
22
|
+
run: bundle install --jobs=3
|
23
|
+
- name: Run tests
|
24
|
+
run: bundle exec rake
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,57 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [0.4.0] 2022-06-27
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- date range selection: cal-like option `-3` to select the current month together
|
8
|
+
with the preceding and following one (contributed by Fabio Soares @fabiosoaresv)
|
9
|
+
- if exactly one sanctorale data file is specified and its YAML front matter
|
10
|
+
references a parent calendar (key `extends`), the file is loaded with its complete
|
11
|
+
graph of parents
|
12
|
+
- option `--[no-]load-parents` to explicitly enable/disable loading of parent calendars
|
13
|
+
- basic support for remote calendars: the `--calendar=` option now accepts
|
14
|
+
also a calendar API URL like
|
15
|
+
`--calendar=http://calapi.inadiutorium.cz/api/v0/en/calendars/general-la`,
|
16
|
+
the referenced API is expected to be compatible with
|
17
|
+
[Liturgical Calendar API](http://calapi.inadiutorium.cz/) v0
|
18
|
+
- calendar listing (`--calendars`) marks default calendar as such
|
19
|
+
- calendar listing lists each calendar's parents
|
20
|
+
- option `--verbose`
|
21
|
+
- condensed view (`--format=condensed`), intended for use cases like printing current day
|
22
|
+
in a window manager toolbar and the like
|
23
|
+
- option `--to-sunday=` to configure which temporale solemnities should be transferred to Sunday
|
24
|
+
(e.g. `--to-sunday=epiphany`)
|
25
|
+
- option `--temporale-extension=` to activate temporale extension
|
26
|
+
(supported values are [temporale extension](https://github.com/igneus/calendarium-romanum/tree/master/lib/calendarium-romanum/temporale/extensions)
|
27
|
+
class names, e.g. `--temporale-extension=ChristEternalPriest`)
|
28
|
+
- any class in the `Calrom::Formatter` module is considered formatter and its
|
29
|
+
lowercased name can be used as value for the `--format=` option - custom formatters
|
30
|
+
can be added by defining new classes in the namespace
|
31
|
+
- options `--day-filter=` and `--celebration-filter=` for filtering days and celebrations
|
32
|
+
by a Ruby expression
|
33
|
+
- environment variable `CALROM_CURRENT_DATE` can be used to override current date
|
34
|
+
(intended mainly for testing)
|
35
|
+
|
36
|
+
### Changed
|
37
|
+
|
38
|
+
- automated locale selection based on sanctorale data file relies solely on the `locale` key
|
39
|
+
of the file's YAML front matter (previously it relied on a file naming convention)
|
40
|
+
- option `--calendar=` expands tilde in path (if it isn't expanded by shell,
|
41
|
+
as is the case e.g. in configuration files)
|
42
|
+
- when displaying just a single day, highlighting of the current day is disabled by default
|
43
|
+
(i.e. if the day being displayed is current day, it won't be highlighted as such)
|
44
|
+
- list view (`--list`): rank is not printed for ferials and Sundays
|
45
|
+
- overview view always arranges the displayed months in multiple columns, just like `cal`
|
46
|
+
(previously date ranges spanning less than three months were printed in a single column)
|
47
|
+
- date range specification: support for dates with year higher than 9999 (e.g. `10000-01-01`)
|
48
|
+
|
49
|
+
### Fixed
|
50
|
+
|
51
|
+
- crash on invalid value of `--locale`
|
52
|
+
- list view: when printing a date range between the same months of different years
|
53
|
+
(e.g. 2000-01-xx .. 2001-01-xx), year was not printed in month headings
|
54
|
+
|
3
55
|
## [0.3.0] 2020-06-21
|
4
56
|
|
5
57
|
### Added
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# calrom
|
2
2
|
|
3
|
-
|
3
|
+

|
4
4
|
[](https://badge.fury.io/rb/calrom)
|
5
5
|
|
6
6
|
Command line utility providing access to the Roman Catholic
|
@@ -46,6 +46,35 @@ Print liturgical calendar for the current month (default):
|
|
46
46
|
|
47
47
|
`$ calrom 2028-01-15 2028-03-07`
|
48
48
|
|
49
|
+
### Day and celebration filtering
|
50
|
+
|
51
|
+
In addition to specifying date range, filtering is a way to further refine
|
52
|
+
the selection of data to be displayed. Options `--day-filter=` and `--celebration-filter=`
|
53
|
+
both accept a snippet of Ruby code, which is then `eval`ed in context of each
|
54
|
+
`CalendariumRomanum::Day` / `CalendariumRomanum::Celebration` within the selected date range
|
55
|
+
and only days/celebrations for which the expression evaluates truthy are displayed.
|
56
|
+
|
57
|
+
Display only Saturdays:
|
58
|
+
|
59
|
+
`$ calrom --day-filter='date.saturday?'`
|
60
|
+
|
61
|
+
Display all Mondays with a celebration of a rank higher than memorial:
|
62
|
+
|
63
|
+
`$ calrom --day-filter='date.monday?' --day-filter='celebrations[0].rank > MEMORIAL_GENERAL'`
|
64
|
+
|
65
|
+
(As you can see, `calendarium-romanum` constants like ranks or seasons are available
|
66
|
+
as top-level constants. Noone likes extensive writing in the terminal.)
|
67
|
+
|
68
|
+
Display only ferials:
|
69
|
+
|
70
|
+
`$ calrom --celebration-filter='ferial?'`
|
71
|
+
|
72
|
+
Display only celebrations in green:
|
73
|
+
|
74
|
+
`$ calrom --celebration-filter='colour == GREEN'`
|
75
|
+
|
76
|
+
The options can be combined and used repeatedly to narrow the selection down as needed.
|
77
|
+
|
49
78
|
### Selecting calendar
|
50
79
|
|
51
80
|
There are a few calendars bundled in calrom (actually in the calendarium-romanum gem)
|
@@ -69,12 +98,28 @@ of the local church:
|
|
69
98
|
|
70
99
|
`$ calrom --calendar=universal-la --calendar=path/to/our_local_celebrations.txt`
|
71
100
|
|
101
|
+
Please note that specifying more than one calendar disables automatic loading of
|
102
|
+
parent calendars. If any of the listed calendars extends a parent calendar,
|
103
|
+
the parent either has to be explicitly listed using the `--calendar` option in order to be loaded,
|
104
|
+
or automatic parent loading has to be explicitly enabled using the `--load-parents` option.
|
105
|
+
|
106
|
+
Limited support for remote calendars is provided. Calendar URL from the
|
107
|
+
[Liturgical Calendar API](http://calapi.inadiutorium.cz/) or a compatible calendar API
|
108
|
+
is accepted as a value of `--calendar=`:
|
109
|
+
|
110
|
+
`$ calrom --calendar=http://calapi.inadiutorium.cz/api/v0/en/calendars/general-la`
|
111
|
+
|
72
112
|
### Data presentation settings
|
73
113
|
|
74
114
|
Print detailed listing:
|
75
115
|
|
76
116
|
`$ calrom -l`
|
77
117
|
|
118
|
+
Print current day in a condensed format (intended mainly for use cases like
|
119
|
+
window manager toolbars):
|
120
|
+
|
121
|
+
`$ calrom --format=condensed --today`
|
122
|
+
|
78
123
|
Disable colours:
|
79
124
|
|
80
125
|
`$ calrom --no-color`
|
@@ -94,13 +139,11 @@ They are processed in this order and both are used if available.
|
|
94
139
|
Their syntax is that of shell options and arguments (with the sole exception that newline
|
95
140
|
is not considered end of shell input, but generic whitespace), supported are all options and arguments
|
96
141
|
accepted by the command.
|
97
|
-
It usually makes sense to use configuration files only for the most fundamental settings
|
98
|
-
you will never change, like selecting calendar (if you know you will always check this single one)
|
99
|
-
or disabling colours (if you hate colourful output).
|
100
142
|
|
101
143
|
If a custom configuration file location is specified on the command line,
|
102
144
|
`$ calrom --config=path/to/my/custom/config`, the standard system-wide and user-specific configuration
|
103
|
-
files are *not* loaded.
|
145
|
+
files are *not* loaded. Empty config path `$ calrom --config=` makes calrom ignore all configuration
|
146
|
+
files and use the built-in default configuration.
|
104
147
|
|
105
148
|
Example configuration file, loading the proper calendar of the archdiocese of Prague
|
106
149
|
and disabling colours:
|
@@ -108,15 +151,27 @@ and disabling colours:
|
|
108
151
|
```bash
|
109
152
|
# shell-like comments can be used in configuration files
|
110
153
|
|
111
|
-
--calendar=czech-cs
|
112
|
-
--calendar
|
113
|
-
|
114
|
-
--
|
154
|
+
--calendar=czech-praha-cs # calendar of the archdiocese of Prague
|
155
|
+
--calendar=~/calendar_data/local_church.txt # path to a custom calendar file with proper celebrations of the parish where I live (titular feast of the church, dedication)
|
156
|
+
|
157
|
+
--load-parents # load also parent calendars specified by the calendar file(s)
|
158
|
+
# (default if just one calendar file is specified, but we specified two)
|
115
159
|
|
116
160
|
--no-color # disable colours
|
117
161
|
```
|
118
162
|
|
119
|
-
(Configuration file format is inspired by [.rspec][dotrspec].
|
163
|
+
(Configuration file format is inspired by [.rspec][dotrspec], [.yardopts][dotyardopts]
|
164
|
+
and others.)
|
165
|
+
|
166
|
+
Most options work in such a way that if several conflicting options are provided,
|
167
|
+
the last one wins. You can thus e.g. set your favourite display format (e.g. `--list`)
|
168
|
+
or date range (e.g. `-3`) in the configuration file and override it, if necessary,
|
169
|
+
by providing some other option from the same group on the command line.
|
170
|
+
An exception from this rule is the `--calendar=` option, repeated occurrences of which
|
171
|
+
do not cancel each other, but are all composed together in the given order to build a calendar
|
172
|
+
by layering.
|
173
|
+
Also repeated occurrences of the `--day-filter=` and `--celebration-filter=` options
|
174
|
+
don't cancel each other, but all specified filtering expressions are applied.
|
120
175
|
|
121
176
|
## Running tests
|
122
177
|
|
@@ -131,17 +186,16 @@ Clone the repository, `$ bundle install` to install dependencies, then:
|
|
131
186
|
## Project roadmap
|
132
187
|
|
133
188
|
* [x] detailed listing of a day/month/year/range of dates
|
134
|
-
* [
|
189
|
+
* [x] month/year overview - options and output mostly mimicking
|
135
190
|
the BSD Unix [`cal`][cal] utility,
|
136
191
|
but with liturgical colours and celebration ranks
|
137
|
-
* [
|
192
|
+
* [x] condensed format (but with detailed information) suitable for awesome/i3 toolbars etc.
|
138
193
|
* [x] machine-readable detailed listing
|
139
194
|
* [ ] year summary: lectionary cycles, movable feasts
|
140
195
|
* [x] configuration file to set default options
|
141
196
|
* [x] specify calendar data path (with support for layering several calendars)
|
142
197
|
* [ ] option to auto-select one of optional celebrations - with multiple supported strategies (prefer ferial, take first non-ferial, configured whitelist, blacklist)
|
143
198
|
* [ ] integrate online data sources
|
144
|
-
* [ ] interactive browsing
|
145
199
|
|
146
200
|
## Backward compatibility
|
147
201
|
|
@@ -168,7 +222,7 @@ command line interface
|
|
168
222
|
|
169
223
|
* [(BSD version of) `cal`][cal] should be mimicked where reasonable
|
170
224
|
* the [Command-Line Options][taoup] chapter from E. S. Raymond's
|
171
|
-
|
225
|
+
*The Art of Unix Programming* should be consulted in the rest
|
172
226
|
of cases
|
173
227
|
|
174
228
|
## License
|
@@ -182,3 +236,4 @@ GNU/GPL 3.0 or later
|
|
182
236
|
[cal]: https://www.freebsd.org/cgi/man.cgi?query=cal
|
183
237
|
[taoup]: http://www.catb.org/esr/writings/taoup/html/ch10s05.html
|
184
238
|
[dotrspec]: https://relishapp.com/rspec/rspec-core/v/2-0/docs/configuration/read-command-line-configuration-options-from-files
|
239
|
+
[dotyardopts]: https://rubydoc.info/gems/yard/file/docs/GettingStarted.md#yardopts-options-file
|
data/calrom.gemspec
CHANGED
@@ -20,7 +20,8 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ['lib']
|
22
22
|
|
23
|
-
spec.add_dependency 'calendarium-romanum', '~> 0.
|
23
|
+
spec.add_dependency 'calendarium-romanum', '~> 0.9.0'
|
24
|
+
spec.add_dependency 'calendarium-romanum-remote', '~> 0.3.0'
|
24
25
|
spec.add_dependency 'colorize', '~> 0.8'
|
25
26
|
spec.add_dependency 'pattern-match', '~> 1.0'
|
26
27
|
|
data/lib/calrom/cli.rb
CHANGED
@@ -4,20 +4,42 @@ module Calrom
|
|
4
4
|
begin
|
5
5
|
config_files = OptionParser.call(argv).configs
|
6
6
|
|
7
|
+
config = EnvironmentReader.call
|
7
8
|
config = OptionParser.call(
|
8
9
|
rc_options(config_files.empty? ? nil : config_files) +
|
9
|
-
argv
|
10
|
+
argv,
|
11
|
+
config
|
10
12
|
)
|
11
13
|
|
12
14
|
calendar = config.calendar
|
13
|
-
rescue
|
15
|
+
rescue OptionParser::Error, InputError => e
|
14
16
|
STDERR.puts e.message
|
15
17
|
exit 1
|
16
18
|
end
|
17
19
|
|
18
|
-
|
20
|
+
begin
|
21
|
+
I18n.locale = config.locale
|
22
|
+
rescue I18n::InvalidLocale
|
23
|
+
locales_help = I18n.available_locales.join(', ')
|
24
|
+
STDERR.puts "Locale '#{config.locale}' unsupported (available locales: #{locales_help})"
|
25
|
+
exit 1
|
26
|
+
end
|
27
|
+
|
28
|
+
unless config.verbose
|
29
|
+
HTTPI.log = false
|
30
|
+
end
|
19
31
|
|
20
|
-
|
32
|
+
begin
|
33
|
+
config.build_formatter.call calendar, config.date_range
|
34
|
+
rescue CR::Remote::UnexpectedResponseError => e
|
35
|
+
STDERR.puts "Remote calendar query failed: #{e.message}"
|
36
|
+
exit 1
|
37
|
+
rescue InputError => e
|
38
|
+
STDERR.puts e.message
|
39
|
+
exit 1
|
40
|
+
rescue Errno::EPIPE
|
41
|
+
# broken pipe - simply stop execution, exit successfully
|
42
|
+
end
|
21
43
|
end
|
22
44
|
|
23
45
|
private
|
@@ -42,7 +64,7 @@ module Calrom
|
|
42
64
|
|
43
65
|
begin
|
44
66
|
OptionParser.call(options)
|
45
|
-
rescue
|
67
|
+
rescue OptionParser::Error => e
|
46
68
|
raise InputError.new("Error loading '#{f}': #{e.message}")
|
47
69
|
end
|
48
70
|
|
data/lib/calrom/config.rb
CHANGED
@@ -8,12 +8,55 @@ module Calrom
|
|
8
8
|
self.date_range = Month.new(today.year, today.month)
|
9
9
|
self.sanctorale = []
|
10
10
|
self.configs = []
|
11
|
+
self.verbose = false
|
12
|
+
self.highlight = Set.new(%i(colour rank today))
|
13
|
+
self.transfer_to_sunday = []
|
14
|
+
self.temporale_extensions = []
|
15
|
+
self.filter_days = []
|
16
|
+
self.filter_celebrations = []
|
11
17
|
end
|
12
18
|
|
13
|
-
|
19
|
+
ATTRIBUTES = [
|
20
|
+
:today,
|
21
|
+
:date_range,
|
22
|
+
:formatter,
|
23
|
+
:colours,
|
24
|
+
:sanctorale,
|
25
|
+
:transfer_to_sunday,
|
26
|
+
:temporale_extensions,
|
27
|
+
:locale,
|
28
|
+
:configs,
|
29
|
+
:load_parents,
|
30
|
+
:highlight,
|
31
|
+
:verbose,
|
32
|
+
:filter_days,
|
33
|
+
:filter_celebrations,
|
34
|
+
]
|
35
|
+
|
36
|
+
attr_accessor *ATTRIBUTES
|
37
|
+
|
38
|
+
def ==(b)
|
39
|
+
self.class == b.class &&
|
40
|
+
ATTRIBUTES.all? {|prop| public_send(prop) == b.public_send(prop) }
|
41
|
+
end
|
14
42
|
|
15
43
|
def calendar
|
16
|
-
|
44
|
+
calendar =
|
45
|
+
if is_remote_calendar?
|
46
|
+
if @sanctorale.size > 1
|
47
|
+
raise InputError.new '--calendar option provided multiple times, but at least one of the calendars is remote. Remote calendars cannot be layered.'
|
48
|
+
end
|
49
|
+
|
50
|
+
CR::Remote::Calendar.new date_range.first.year, @sanctorale.last
|
51
|
+
else
|
52
|
+
CR::PerpetualCalendar.new(sanctorale: build_sanctorale, temporale_options: temporale_options, vespers: true)
|
53
|
+
end
|
54
|
+
|
55
|
+
FilteringCalendar.new(
|
56
|
+
calendar,
|
57
|
+
filter_days,
|
58
|
+
filter_celebrations,
|
59
|
+
)
|
17
60
|
end
|
18
61
|
|
19
62
|
def build_sanctorale
|
@@ -22,56 +65,86 @@ module Calrom
|
|
22
65
|
end
|
23
66
|
|
24
67
|
data = @sanctorale.collect do |s|
|
68
|
+
expanded = File.expand_path s
|
69
|
+
|
25
70
|
if s == '-'
|
26
71
|
CR::SanctoraleLoader.new.load_from_string STDIN.read
|
27
|
-
elsif File.file? s
|
28
|
-
CR::SanctoraleLoader.new.load_from_file s
|
29
|
-
elsif CR::Data[s]
|
30
|
-
CR::Data[s].load
|
31
72
|
else
|
32
|
-
|
33
|
-
|
34
|
-
|
73
|
+
data_file =
|
74
|
+
if File.file? expanded
|
75
|
+
SanctoraleFile.new expanded
|
76
|
+
elsif CR::Data[s]
|
77
|
+
CR::Data[s]
|
78
|
+
else
|
79
|
+
raise InputError.new "\"#{s}\" is neither a file, nor a valid identifier of a bundled calendar. " +
|
80
|
+
"Valid identifiers are: " +
|
81
|
+
CR::Data.each.collect(&:siglum).inspect
|
82
|
+
end
|
83
|
+
|
84
|
+
if load_parents?
|
85
|
+
data_file.load_with_parents
|
86
|
+
else
|
87
|
+
data_file.load
|
88
|
+
end
|
35
89
|
end
|
36
90
|
end
|
37
91
|
|
38
92
|
CR::SanctoraleFactory.create_layered(*data)
|
39
93
|
end
|
40
94
|
|
95
|
+
def temporale_options
|
96
|
+
{transfer_to_sunday: transfer_to_sunday, extensions: temporale_extensions}
|
97
|
+
end
|
98
|
+
|
41
99
|
def locale
|
42
|
-
@locale ||
|
100
|
+
@locale || locale_in_file_metadata || DEFAULT_LOCALE
|
43
101
|
end
|
44
102
|
|
45
|
-
def
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
Formatter::Json.new
|
56
|
-
else
|
57
|
-
Formatter::Overview.new highlighter(Highlighter::Overview), today
|
103
|
+
def build_formatter
|
104
|
+
highlighter = Highlighter::List
|
105
|
+
klass = @formatter && Formatter.const_get(@formatter.capitalize)
|
106
|
+
|
107
|
+
if @formatter.nil?
|
108
|
+
klass = date_range.is_a?(Day) ? Formatter::List : Formatter::Overview
|
109
|
+
end
|
110
|
+
|
111
|
+
if [Formatter::Calendars, Formatter::Overview].include? klass
|
112
|
+
highlighter = Highlighter::Overview
|
58
113
|
end
|
114
|
+
|
115
|
+
klass.new build_highlighter(highlighter), today
|
59
116
|
end
|
60
117
|
|
61
|
-
def
|
118
|
+
def build_highlighter(colourful)
|
62
119
|
if (self.colours == false || (self.colours.nil? && !STDOUT.isatty))
|
63
120
|
return Highlighter::No.new
|
64
121
|
end
|
65
122
|
|
66
|
-
colourful.new
|
123
|
+
Highlighter::Selective.new highlight, colourful.new
|
124
|
+
end
|
125
|
+
|
126
|
+
# Should calendars be loaded including parent files they reference?
|
127
|
+
def load_parents?
|
128
|
+
load_parents == true ||
|
129
|
+
(load_parents.nil? && @sanctorale.size == 1)
|
130
|
+
end
|
131
|
+
|
132
|
+
def highlight
|
133
|
+
if date_range.is_a? Day
|
134
|
+
@highlight - [:today]
|
135
|
+
else
|
136
|
+
@highlight
|
137
|
+
end
|
67
138
|
end
|
68
139
|
|
69
140
|
private
|
70
141
|
|
71
|
-
def
|
72
|
-
|
142
|
+
def locale_in_file_metadata
|
143
|
+
is_remote_calendar? ? nil : build_sanctorale.metadata['locale']&.to_sym
|
144
|
+
end
|
73
145
|
|
74
|
-
|
146
|
+
def is_remote_calendar?
|
147
|
+
!!@sanctorale.find {|s| s =~ /^https?:\/\// }
|
75
148
|
end
|
76
149
|
end
|
77
150
|
end
|
data/lib/calrom/date_range.rb
CHANGED
@@ -13,7 +13,6 @@ module Calrom
|
|
13
13
|
.each_with_index do |m,i|
|
14
14
|
if i == 0 && first.day > 1
|
15
15
|
# first month, incomplete
|
16
|
-
end_of_month = first.next_month - first.day + 1
|
17
16
|
yield self.class.new(first, m.last)
|
18
17
|
elsif m.first.year == last.year && m.first.month == last.month && last != m.last
|
19
18
|
# last month, incomplete
|
@@ -23,6 +22,11 @@ module Calrom
|
|
23
22
|
end
|
24
23
|
end
|
25
24
|
end
|
25
|
+
|
26
|
+
def spans_multiple_months?
|
27
|
+
first.month != last.month ||
|
28
|
+
first.year != last.year
|
29
|
+
end
|
26
30
|
end
|
27
31
|
|
28
32
|
class Year < DateRange
|
@@ -41,11 +45,30 @@ module Calrom
|
|
41
45
|
end
|
42
46
|
end
|
43
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
|
64
|
+
end
|
65
|
+
|
44
66
|
class Month < DateRange
|
45
67
|
def initialize(year, month)
|
46
68
|
@year = year
|
47
69
|
@month = month
|
48
|
-
|
70
|
+
|
71
|
+
super Date.new(year, month, 1), Date.new(year, month, -1)
|
49
72
|
end
|
50
73
|
|
51
74
|
def to_s
|
@@ -59,7 +82,7 @@ module Calrom
|
|
59
82
|
end
|
60
83
|
|
61
84
|
def succ
|
62
|
-
n =
|
85
|
+
n = Date.new(@year, @month, 1).next_month
|
63
86
|
self.class.new(n.year, n.month)
|
64
87
|
end
|
65
88
|
|
@@ -76,16 +99,6 @@ module Calrom
|
|
76
99
|
protected
|
77
100
|
|
78
101
|
attr_reader :year, :month
|
79
|
-
|
80
|
-
private
|
81
|
-
|
82
|
-
def next_month_beginning
|
83
|
-
if @month == 12
|
84
|
-
Date.new(@year + 1, 1, 1)
|
85
|
-
else
|
86
|
-
Date.new(@year, @month + 1, 1)
|
87
|
-
end
|
88
|
-
end
|
89
102
|
end
|
90
103
|
|
91
104
|
class Day < DateRange
|
@@ -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
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
|
3
1
|
module Calrom
|
4
2
|
module Formatter
|
5
3
|
# Prints list of available bundled calendars
|
@@ -7,16 +5,25 @@ module Calrom
|
|
7
5
|
def call(calendar, date_range)
|
8
6
|
last_locale = nil
|
9
7
|
CR::Data.each do |d|
|
10
|
-
|
8
|
+
sanctorale = d.load_with_parents
|
9
|
+
meta = sanctorale.metadata
|
11
10
|
puts if last_locale && last_locale != meta['locale']
|
12
|
-
|
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}" }
|
13
24
|
last_locale = meta['locale']
|
14
25
|
end
|
15
26
|
end
|
16
|
-
|
17
|
-
def load_front_matter(data_file)
|
18
|
-
YAML.load File.read data_file.path
|
19
|
-
end
|
20
27
|
end
|
21
28
|
end
|
22
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
|
data/lib/calrom/formatter/csv.rb
CHANGED
@@ -2,13 +2,12 @@ require 'csv'
|
|
2
2
|
|
3
3
|
module Calrom
|
4
4
|
module Formatter
|
5
|
-
class Csv
|
5
|
+
class Csv < Formatter
|
6
6
|
def call(calendar, date_range)
|
7
7
|
CSV do |out|
|
8
8
|
out << %w(date title symbol rank rank_num colour season)
|
9
9
|
|
10
|
-
date_range
|
11
|
-
day = calendar[date]
|
10
|
+
calendar.each_day_in_range(date_range) do |day|
|
12
11
|
day.celebrations.each do |c|
|
13
12
|
out << [
|
14
13
|
day.date,
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Calrom
|
2
2
|
module Formatter
|
3
3
|
# Prints (only) date of Easter for the specified year.
|
4
|
-
class Easter
|
4
|
+
class Easter < Formatter
|
5
5
|
def call(calendar, date_range)
|
6
6
|
unless date_range.is_a?(Year) || date_range.is_a?(Month)
|
7
7
|
raise 'unexpected date range, expected a year'
|
@@ -1,15 +1,26 @@
|
|
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
12
|
def call(calendar, date_range)
|
12
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
|
23
|
+
end
|
13
24
|
end
|
14
25
|
end
|
15
26
|
end
|
@@ -3,14 +3,14 @@ require 'json'
|
|
3
3
|
module Calrom
|
4
4
|
module Formatter
|
5
5
|
# JSON format mimicking Church Calendar API v0 (https://github.com/igneus/church-calendar-api)
|
6
|
-
class Json
|
6
|
+
class Json < Formatter
|
7
7
|
def call(calendar, date_range)
|
8
8
|
# We build the outer JSON Array manually in order to be able to print
|
9
9
|
# vast amounts of calendar data without risking RAM exhaustion.
|
10
10
|
print "["
|
11
11
|
|
12
|
-
date_range.each_with_index do |
|
13
|
-
|
12
|
+
calendar.each_day_in_range(date_range).each_with_index do |day,i|
|
13
|
+
date = day.date
|
14
14
|
hash = {
|
15
15
|
date: date,
|
16
16
|
season: day.season.symbol,
|
@@ -2,22 +2,20 @@ module Calrom
|
|
2
2
|
module Formatter
|
3
3
|
class List < Formatter
|
4
4
|
def call(calendar, date_range)
|
5
|
-
print_months = 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
|
-
date_range
|
13
|
-
liturgical_day = calendar[date]
|
14
|
-
|
12
|
+
calendar.each_day_in_range(date_range) do |liturgical_day|
|
15
13
|
if print_months && liturgical_day.date.month != current_month
|
16
|
-
current_month
|
17
|
-
|
18
|
-
puts
|
14
|
+
puts unless current_month == nil
|
19
15
|
puts liturgical_day.date.strftime('%B') #current_month
|
20
16
|
puts
|
17
|
+
|
18
|
+
current_month = liturgical_day.date.month
|
21
19
|
end
|
22
20
|
|
23
21
|
day liturgical_day
|
@@ -42,7 +40,7 @@ module Calrom
|
|
42
40
|
s += highlighter.colour(colour.name[0].upcase, colour) +
|
43
41
|
' ' +
|
44
42
|
highlighter.rank(celebration.title, rank) +
|
45
|
-
(rank.short_desc.nil? ? '' : ', ' + rank.short_desc)
|
43
|
+
((rank.short_desc.nil? || rank.sunday? || rank.ferial?) ? '' : ', ' + rank.short_desc)
|
46
44
|
|
47
45
|
if liturgical_day.date == today
|
48
46
|
s = highlighter.today s
|
@@ -4,10 +4,10 @@ require 'stringio'
|
|
4
4
|
module Calrom
|
5
5
|
module Formatter
|
6
6
|
class Overview < Formatter
|
7
|
-
def call(calendar, date_range
|
8
|
-
colnum =
|
7
|
+
def call(calendar, date_range)
|
8
|
+
colnum = 3 # TODO: expose configuration
|
9
9
|
if date_range.is_a? Year
|
10
|
-
|
10
|
+
puts center_on(weekdays.size * colnum + 2 * (colnum - 1), date_range.to_s)
|
11
11
|
end
|
12
12
|
|
13
13
|
date_range.each_month.each_slice(colnum) do |months|
|
@@ -16,7 +16,7 @@ module Calrom
|
|
16
16
|
print_month io, calendar, month, date_range.is_a?(Year)
|
17
17
|
end
|
18
18
|
end
|
19
|
-
print_columns columns, io
|
19
|
+
print_columns columns, @io
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -29,14 +29,19 @@ module Calrom
|
|
29
29
|
io.puts weekdays
|
30
30
|
|
31
31
|
io.print ' ' * month.first.wday
|
32
|
-
month
|
33
|
-
|
32
|
+
calendar.each_day_in_range(month, include_skipped: true) do |liturgical_day|
|
33
|
+
date = liturgical_day.date
|
34
34
|
|
35
|
-
|
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
|
36
44
|
|
37
|
-
datestr = date.day.to_s.rjust(2)
|
38
|
-
datestr = highlighter.colour(datestr, celebration.colour)
|
39
|
-
datestr = highlighter.rank(datestr, celebration.rank)
|
40
45
|
if date == today
|
41
46
|
datestr = highlighter.today datestr
|
42
47
|
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
|
data/lib/calrom/option_parser.rb
CHANGED
@@ -6,20 +6,28 @@ module Calrom
|
|
6
6
|
class OptionParser
|
7
7
|
using PatternMatch
|
8
8
|
|
9
|
+
# Raised when the options being parsed are invalid.
|
10
|
+
#
|
11
|
+
# Exceptions raised by the option parsing library are translated to this exception,
|
12
|
+
# thus hiding implementation details (the option parsing library's exception types)
|
13
|
+
# from the outer world.
|
14
|
+
class Error < RuntimeError; end
|
15
|
+
|
9
16
|
class CustomizedOptionParser < ::OptionParser
|
10
17
|
def separator(string)
|
11
18
|
super "\n" + string
|
12
19
|
end
|
13
20
|
end
|
14
21
|
|
15
|
-
def self.call(
|
16
|
-
self.new.call(
|
22
|
+
def self.call(*args)
|
23
|
+
self.new.call(*args)
|
17
24
|
end
|
18
25
|
|
19
|
-
def call(argv)
|
20
|
-
config
|
26
|
+
def call(argv, config = nil)
|
27
|
+
config ||= Config.new
|
21
28
|
|
22
29
|
today = config.today
|
30
|
+
|
23
31
|
year = today.year
|
24
32
|
month = today.month
|
25
33
|
day = nil
|
@@ -42,6 +50,7 @@ module Calrom
|
|
42
50
|
calrom 2000 - whole year 2000
|
43
51
|
calrom -y 2000 - also whole year 2000
|
44
52
|
calrom -y - whole current year
|
53
|
+
calrom -3 - display the previous, current and next month surrounding today
|
45
54
|
|
46
55
|
Specifying date range (not cal-compatible):
|
47
56
|
|
@@ -70,23 +79,28 @@ module Calrom
|
|
70
79
|
end
|
71
80
|
end
|
72
81
|
|
82
|
+
# cal
|
83
|
+
opts.on('-3', 'display the previous, current and next month surrounding today') do |value|
|
84
|
+
range_type = :three_months
|
85
|
+
end
|
86
|
+
|
73
87
|
# cal
|
74
88
|
opts.on('-y', '--year', 'display specified (or current) year') do |value|
|
75
89
|
range_type = :year
|
76
90
|
end
|
77
91
|
|
78
92
|
opts.on('--yesterday', 'display previous day') do |value|
|
79
|
-
day =
|
93
|
+
day = today - 1
|
80
94
|
range_type = :day
|
81
95
|
end
|
82
96
|
|
83
97
|
opts.on('--today', 'display current day') do |value|
|
84
|
-
day =
|
98
|
+
day = today
|
85
99
|
range_type = :day
|
86
100
|
end
|
87
101
|
|
88
102
|
opts.on('--tomorrow', 'display following day') do |value|
|
89
|
-
day =
|
103
|
+
day = today + 1
|
90
104
|
range_type = :day
|
91
105
|
end
|
92
106
|
|
@@ -96,8 +110,21 @@ module Calrom
|
|
96
110
|
config.sanctorale << value
|
97
111
|
end
|
98
112
|
|
99
|
-
|
100
|
-
|
113
|
+
opts.on('--[no-]load-parents', 'explicitly enable/disable parent calendar loading') do |value|
|
114
|
+
config.load_parents = value
|
115
|
+
end
|
116
|
+
|
117
|
+
transferable = CR::Temporale::SUNDAY_TRANSFERABLE_SOLEMNITIES
|
118
|
+
opts.on('--to-sunday=SOLEMNITY', transferable, 'transfer solemnity to Sunday' + supported_values(transferable)) do |value|
|
119
|
+
config.transfer_to_sunday << value.to_sym
|
120
|
+
end
|
121
|
+
|
122
|
+
extensions = CR::Temporale::Extensions.all.collect {|cls| cls.name.split('::').last.to_sym }
|
123
|
+
opts.on('--temporale-extension=EXTENSION', extensions, 'use temporale extension' + supported_values(extensions)) do |value|
|
124
|
+
config.temporale_extensions << CR::Temporale::Extensions.const_get(value)
|
125
|
+
end
|
126
|
+
|
127
|
+
opts.on('--locale=LOCALE', 'override language in which temporale celebration titles are rendered' + supported_values(I18n.available_locales)) do |value|
|
101
128
|
config.locale = value.to_sym
|
102
129
|
end
|
103
130
|
|
@@ -107,12 +134,23 @@ module Calrom
|
|
107
134
|
config.formatter = :list
|
108
135
|
end
|
109
136
|
|
110
|
-
supported_formats =
|
137
|
+
supported_formats =
|
138
|
+
Calrom::Formatter.constants
|
139
|
+
.collect(&:downcase)
|
140
|
+
.delete_if {|i| i == :formatter }
|
111
141
|
formats_help = supported_formats.join(', ')
|
112
142
|
opts.on('--format=FORMAT', supported_formats, "specify output format (supported: #{formats_help})") do |value|
|
113
143
|
config.formatter = value
|
114
144
|
end
|
115
145
|
|
146
|
+
opts.on('--day-filter=EXPR', 'display only days for which the expression (Ruby snippet executed in context of each CalendariumRomanum::Day instance) evaluates as truthy') do |expr|
|
147
|
+
config.filter_days << expr
|
148
|
+
end
|
149
|
+
|
150
|
+
opts.on('--celebration-filter=EXPR', 'display only celebrations for which the expression (Ruby snippet executed in context of each CalendariumRomanum::Celebration instance) evaluates as truthy') do |expr|
|
151
|
+
config.filter_celebrations << expr
|
152
|
+
end
|
153
|
+
|
116
154
|
# cal
|
117
155
|
opts.on('-e', '--easter', 'display date of Easter (only)') do
|
118
156
|
config.formatter = :easter
|
@@ -126,6 +164,10 @@ module Calrom
|
|
126
164
|
config.colours = value
|
127
165
|
end
|
128
166
|
|
167
|
+
opts.on('-v', '--verbose', 'enable verbose output') do
|
168
|
+
config.verbose = true
|
169
|
+
end
|
170
|
+
|
129
171
|
opts.separator 'Debugging options'
|
130
172
|
|
131
173
|
# cal
|
@@ -142,6 +184,7 @@ module Calrom
|
|
142
184
|
|
143
185
|
opts.on('-V', '--version', 'display calrom version') do
|
144
186
|
puts 'calrom v' + Calrom::VERSION
|
187
|
+
puts 'using calendarium-romanum v' + CR::VERSION
|
145
188
|
exit
|
146
189
|
end
|
147
190
|
|
@@ -153,9 +196,13 @@ module Calrom
|
|
153
196
|
end
|
154
197
|
end
|
155
198
|
|
156
|
-
|
199
|
+
begin
|
200
|
+
arguments = opt_parser.parse argv
|
201
|
+
rescue ::OptionParser::ParseError => e
|
202
|
+
raise Error.new(e.message)
|
203
|
+
end
|
157
204
|
|
158
|
-
iso_date_regexp = /^(\d{4}-\d{2}-\d{2})$/
|
205
|
+
iso_date_regexp = /^(\d{4,}-\d{2}-\d{2})$/
|
159
206
|
match(arguments) do
|
160
207
|
with(_[iso_date_regexp.(date)]) do
|
161
208
|
range_type = :day
|
@@ -233,6 +280,8 @@ module Calrom
|
|
233
280
|
Day.new(day)
|
234
281
|
when :free
|
235
282
|
DateRange.new(day, another_day)
|
283
|
+
when :three_months
|
284
|
+
ThreeMonths.new(year, month)
|
236
285
|
else
|
237
286
|
Month.new(year, month)
|
238
287
|
end
|
@@ -244,5 +293,9 @@ module Calrom
|
|
244
293
|
|
245
294
|
range
|
246
295
|
end
|
296
|
+
|
297
|
+
def supported_values(values)
|
298
|
+
" (supported: #{values.join(', ')})"
|
299
|
+
end
|
247
300
|
end
|
248
301
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Calrom
|
2
|
+
module Refinement
|
3
|
+
module CalendariumRomanum
|
4
|
+
# Refinement used when evaluating the Day/Celebration filter expressions.
|
5
|
+
# Allows the user (at least in simple cases) to write just `TRIDUUM` both
|
6
|
+
# as a season and as a rank.
|
7
|
+
module TriduumNameClashWorkaround
|
8
|
+
refine CR::Season do
|
9
|
+
alias_method :old_equal, :==
|
10
|
+
|
11
|
+
def ==(other)
|
12
|
+
if other.is_a?(CR::Rank) && self == CR::Seasons::TRIDUUM
|
13
|
+
return CR::Ranks::TRIDUUM == other
|
14
|
+
end
|
15
|
+
|
16
|
+
old_equal other
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
refine CR::Rank do
|
21
|
+
alias_method :old_equal, :==
|
22
|
+
|
23
|
+
def ==(other)
|
24
|
+
if other.is_a?(CR::Season) && self == CR::Ranks::TRIDUUM
|
25
|
+
return CR::Seasons::TRIDUUM == other
|
26
|
+
end
|
27
|
+
|
28
|
+
old_equal other
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Calrom
|
2
|
+
# Wraps arbitrary sanctorale files and allows handling and loading them exactly
|
3
|
+
# the same way as bundled sanctorale files.
|
4
|
+
#
|
5
|
+
# Erm, yes, according to calendarium-romanum documentation the parent class is actually
|
6
|
+
# not intended for use like this. But we take the risk of breakage by future
|
7
|
+
# calendarium-romanum releases ;)
|
8
|
+
class SanctoraleFile < CR::Data::SanctoraleFile
|
9
|
+
def initialize(path)
|
10
|
+
@siglum = nil
|
11
|
+
@path = path
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/calrom/version.rb
CHANGED
data/lib/calrom.rb
CHANGED
@@ -1,20 +1,29 @@
|
|
1
1
|
require 'calendarium-romanum'
|
2
|
+
require 'calendarium-romanum/remote'
|
2
3
|
require 'colorized_string'
|
3
4
|
|
5
|
+
# make useful calendarium-romanum constants available as top-level constants
|
6
|
+
include CalendariumRomanum::Constants
|
7
|
+
|
4
8
|
module Calrom
|
5
9
|
CR = CalendariumRomanum
|
6
10
|
end
|
7
11
|
|
8
12
|
require 'calrom/version'
|
13
|
+
require 'calrom/refinement/calendarium-romanum/triduum_nameclash_workaround'
|
9
14
|
require 'calrom/cli'
|
10
15
|
require 'calrom/option_parser'
|
16
|
+
require 'calrom/environment_reader'
|
11
17
|
require 'calrom/config'
|
12
18
|
require 'calrom/date_range'
|
13
19
|
require 'calrom/rc_parser'
|
14
20
|
require 'calrom/exceptions'
|
21
|
+
require 'calrom/sanctorale_file'
|
22
|
+
require 'calrom/filtering_calendar'
|
15
23
|
require 'calrom/formatter/formatter'
|
16
24
|
require 'calrom/formatter/list'
|
17
25
|
require 'calrom/formatter/overview'
|
26
|
+
require 'calrom/formatter/condensed'
|
18
27
|
require 'calrom/formatter/csv'
|
19
28
|
require 'calrom/formatter/json'
|
20
29
|
require 'calrom/formatter/easter'
|
@@ -22,3 +31,4 @@ require 'calrom/formatter/calendars'
|
|
22
31
|
require 'calrom/highlighter/no'
|
23
32
|
require 'calrom/highlighter/list'
|
24
33
|
require 'calrom/highlighter/overview'
|
34
|
+
require 'calrom/highlighter/selective'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: calrom
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jakub Pavlík
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-06-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: calendarium-romanum
|
@@ -16,14 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.9.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.9.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: calendarium-romanum-remote
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.3.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.3.0
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: colorize
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -116,6 +130,7 @@ executables:
|
|
116
130
|
extensions: []
|
117
131
|
extra_rdoc_files: []
|
118
132
|
files:
|
133
|
+
- ".github/workflows/ci.yml"
|
119
134
|
- ".gitignore"
|
120
135
|
- ".rspec"
|
121
136
|
- ".travis.yml"
|
@@ -132,8 +147,11 @@ files:
|
|
132
147
|
- lib/calrom/cli.rb
|
133
148
|
- lib/calrom/config.rb
|
134
149
|
- lib/calrom/date_range.rb
|
150
|
+
- lib/calrom/environment_reader.rb
|
135
151
|
- lib/calrom/exceptions.rb
|
152
|
+
- lib/calrom/filtering_calendar.rb
|
136
153
|
- lib/calrom/formatter/calendars.rb
|
154
|
+
- lib/calrom/formatter/condensed.rb
|
137
155
|
- lib/calrom/formatter/csv.rb
|
138
156
|
- lib/calrom/formatter/easter.rb
|
139
157
|
- lib/calrom/formatter/formatter.rb
|
@@ -143,8 +161,11 @@ files:
|
|
143
161
|
- lib/calrom/highlighter/list.rb
|
144
162
|
- lib/calrom/highlighter/no.rb
|
145
163
|
- lib/calrom/highlighter/overview.rb
|
164
|
+
- lib/calrom/highlighter/selective.rb
|
146
165
|
- lib/calrom/option_parser.rb
|
147
166
|
- lib/calrom/rc_parser.rb
|
167
|
+
- lib/calrom/refinement/calendarium-romanum/triduum_nameclash_workaround.rb
|
168
|
+
- lib/calrom/sanctorale_file.rb
|
148
169
|
- lib/calrom/version.rb
|
149
170
|
homepage: https://github.com/calendarium-romanum/calrom
|
150
171
|
licenses:
|