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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 2f2a47dec05e4ed520cbe19a3057f8b2a2846659
4
- data.tar.gz: 26d20de0bb41c7054a20c22c0b5cbcd44e57e130
2
+ SHA256:
3
+ metadata.gz: c2e561032a6b91d68a87839856d8ce94b794187a539ac544fc907cfd2568add7
4
+ data.tar.gz: 8c9ab4bbdc83cc0c9884dbb4fb9f658c578e83956ce63da45b8698f59c55124f
5
5
  SHA512:
6
- metadata.gz: 1a8246694c98d8525a693b2afc72170205c715a59b79877c8e5b805846dc394e69be9b71bce65a5b50b56d22916f84610932140483ca1ed50577fcb5c708f1bc
7
- data.tar.gz: 48f9f4df5a0d75f8eed66520c48b27173f10eb16dd17a7b0f685435d2e6f117dbd97af15cda3b4406ea3290839da81244895fc68cdb57b8fb78abfe29d4c729b
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
@@ -1,5 +1,15 @@
1
- sudo: false
2
1
  language: ruby
2
+
3
+ dist: focal
4
+
5
+ # oldest supported and newest MRI
3
6
  rvm:
4
- - 2.3.1
5
- before_install: gem install bundler -v 1.13.6
7
+ - 2.5.0
8
+ - 3.0.0
9
+
10
+ install: bundle install --jobs=3
11
+
12
+ script: bundle exec rake
13
+
14
+ git:
15
+ depth: 3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,102 @@
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
+
55
+ ## [0.3.0] 2020-06-21
56
+
57
+ ### Added
58
+
59
+ - date range selection: options `--today`, `--tomorrow`, `--yesterday`
60
+ - specifying the `--calendar=` option multiple times layers the calendars
61
+ - file path can be provided as argument to the `--calendar=` option
62
+ - option `--locale=` to specify language of localized calendar strings
63
+ - language of the (last loaded) sanctorale data is by default used for localized strings
64
+ - output is by default not colorized when not printing to a terminal
65
+ - configuration files
66
+ - `/etc/calromrc`
67
+ - `$HOME/.calromrc`
68
+ - specified by the `--config=` option
69
+ - machine-readable output formats `--format=csv`, `--format=json`
70
+ - option `--calendars` to list bundled calendars
71
+
72
+ ### Fixed
73
+
74
+ - crash on option parsing errors other than invalid option
75
+
76
+ ## [0.2.0] 2020-06-16
77
+
78
+ ### Added
79
+
80
+ - cal-like view (is now default for month, year and date range listing)
81
+ - support more cal-like ways of specifying date range
82
+ - month argument `calrom MONTH YEAR` (as an alternative to month option `cal -m MONTH YEAR`)
83
+ - month option with p/f flag `calrom -m 5p` / `calrom -m 5f` as a shortcut to specify a month of the previous/following year
84
+ - option to print the whole current year `calrom -y`
85
+ - support arbitrary date range specified as two ISO dates
86
+ - input is validated, errors handled and reported
87
+ - cal-like option to print (only) the date of Easter
88
+ - cal-like debugging options `-d` and `-H`
89
+ - option `--[no-]color` to enable/disable ANSI colours (enabled by default)
90
+
91
+ ### Changed
92
+
93
+ - list view: contains weekday names; month names instead of month numbers
94
+
95
+ ### Fixed
96
+
97
+ - unhandled edge-case in `Calrom::Month` when dealing with the end of a year
98
+ - liturgical colour violet
99
+
3
100
  ## [0.1.0] 2019-10-05
4
101
 
5
102
  ### Added
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # calrom
2
2
 
3
+ ![Build Status](https://github.com/calendarium-romanum/calrom/actions/workflows/ci.yml/badge.svg)
4
+ [![Gem Version](https://badge.fury.io/rb/calrom.svg)](https://badge.fury.io/rb/calrom)
5
+
3
6
  Command line utility providing access to the Roman Catholic
4
7
  liturgical calendar (post-Vatican II).
5
8
 
@@ -9,22 +12,190 @@ Built on top of the [calendarium-romanum][caro] Ruby gem.
9
12
 
10
13
  calrom is a Ruby gem:
11
14
 
12
- `gem install calrom`
15
+ `$ gem install calrom`
16
+
17
+ ## Usage
18
+
19
+ ### Specifying date range
20
+
21
+ Print liturgical calendar for the current month (default):
22
+
23
+ `$ calrom`
24
+
25
+ ... for a specified month of the current year:
26
+
27
+ `$ calrom -m 9`
28
+
29
+ ... for a specified month of another year:
30
+
31
+ `$ calrom -m 1 2028` or `$ calrom 1 2028`
32
+
33
+ ... for a whole year:
34
+
35
+ `$ calrom 2017`
36
+
37
+ ... for the current year:
38
+
39
+ `$ calrom -y`
40
+
41
+ ... for a specified date:
42
+
43
+ `$ calrom 2028-01-15`
44
+
45
+ ... for an arbitrary date range:
46
+
47
+ `$ calrom 2028-01-15 2028-03-07`
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
+
78
+ ### Selecting calendar
79
+
80
+ There are a few calendars bundled in calrom (actually in the calendarium-romanum gem)
81
+ and ready to use. List them:
82
+
83
+ `$ calrom --calendars`
84
+
85
+ Each entry of the listing contains an ID of the calendar, it's name and language code.
86
+ Use calendar ID to request General Roman Calendar in Latin:
87
+
88
+ `$ calrom --calendar=universal-la`
89
+
90
+ You can prepare [your own calendar data][carodata] and load them:
91
+
92
+ `$ calrom --calendar=path/to/my_calendar.txt`
93
+
94
+ If you specify more than one calendar, they are loaded "layered" one over another
95
+ (from left to right), which comes in handy when extending a general calendar
96
+ with just a few additional and/or differing celebrations, e.g. solemnities (titular, dedication)
97
+ of the local church:
98
+
99
+ `$ calrom --calendar=universal-la --calendar=path/to/our_local_celebrations.txt`
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
+
112
+ ### Data presentation settings
113
+
114
+ Print detailed listing:
115
+
116
+ `$ calrom -l`
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
+
123
+ Disable colours:
124
+
125
+ `$ calrom --no-color`
126
+
127
+ Machine-readable output formats:
128
+
129
+ `$ calrom --format=json` - prints JSON array containing one object per day.
130
+ The object contents mimick output of the [Church Calendar API v0][calapidoc].
131
+
132
+ `$ calrom --format=csv` - prints a CSV, one celebration per line
133
+ (i.e. there is one or more lines for each liturgical day).
134
+
135
+ ### Configuration files
136
+
137
+ `calrom` looks for configuration files `/etc/calromrc` and `~/.calromrc`.
138
+ They are processed in this order and both are used if available.
139
+ Their syntax is that of shell options and arguments (with the sole exception that newline
140
+ is not considered end of shell input, but generic whitespace), supported are all options and arguments
141
+ accepted by the command.
142
+
143
+ If a custom configuration file location is specified on the command line,
144
+ `$ calrom --config=path/to/my/custom/config`, the standard system-wide and user-specific configuration
145
+ files are *not* loaded. Empty config path `$ calrom --config=` makes calrom ignore all configuration
146
+ files and use the built-in default configuration.
147
+
148
+ Example configuration file, loading the proper calendar of the archdiocese of Prague
149
+ and disabling colours:
150
+
151
+ ```bash
152
+ # shell-like comments can be used in configuration files
153
+
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)
159
+
160
+ --no-color # disable colours
161
+ ```
162
+
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.
175
+
176
+ ## Running tests
177
+
178
+ Clone the repository, `$ bundle install` to install dependencies, then:
179
+
180
+ `$ rake cucumber` - run specs describing the command line interface
181
+
182
+ `$ rake spec` - run specs describing internal implementation details
183
+
184
+ `$ rake` - run all groups of specs one after another
13
185
 
14
186
  ## Project roadmap
15
187
 
16
- * [ ] detailed listing of a day/month/year/range of dates
17
- * [ ] month/year overview - options and output mostly mimicking the
188
+ * [x] detailed listing of a day/month/year/range of dates
189
+ * [x] month/year overview - options and output mostly mimicking
18
190
  the BSD Unix [`cal`][cal] utility,
19
191
  but with liturgical colours and celebration ranks
20
- * [ ] condensed format (but with detailed information) suitable for awesome/i3 toolbars etc.
21
- * [ ] machine-readable detailed listing
192
+ * [x] condensed format (but with detailed information) suitable for awesome/i3 toolbars etc.
193
+ * [x] machine-readable detailed listing
22
194
  * [ ] year summary: lectionary cycles, movable feasts
23
- * [ ] configuration file to set default options
24
- * [ ] specify calendar data path (with support for layering several calendars)
195
+ * [x] configuration file to set default options
196
+ * [x] specify calendar data path (with support for layering several calendars)
25
197
  * [ ] option to auto-select one of optional celebrations - with multiple supported strategies (prefer ferial, take first non-ferial, configured whitelist, blacklist)
26
198
  * [ ] integrate online data sources
27
- * [ ] interactive browsing
28
199
 
29
200
  ## Backward compatibility
30
201
 
@@ -51,7 +222,7 @@ command line interface
51
222
 
52
223
  * [(BSD version of) `cal`][cal] should be mimicked where reasonable
53
224
  * the [Command-Line Options][taoup] chapter from E. S. Raymond's
54
- "The Art of Unix Programming" should be consulted in the rest
225
+ *The Art of Unix Programming* should be consulted in the rest
55
226
  of cases
56
227
 
57
228
  ## License
@@ -59,6 +230,10 @@ command line interface
59
230
  GNU/GPL 3.0 or later
60
231
 
61
232
  [caro]: https://github.com/igneus/calendarium-romanum
233
+ [carodata]: https://github.com/igneus/calendarium-romanum/tree/master/data
234
+ [calapidoc]: http://calapi.inadiutorium.cz/api-doc
62
235
  [semver]: https://semver.org/
63
236
  [cal]: https://www.freebsd.org/cgi/man.cgi?query=cal
64
237
  [taoup]: http://www.catb.org/esr/writings/taoup/html/ch10s05.html
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/Rakefile CHANGED
@@ -1,6 +1,10 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
+ require "cucumber/rake/task"
3
4
 
4
5
  RSpec::Core::RakeTask.new(:spec)
5
6
 
6
- task :default => :spec
7
+ Cucumber::Rake::Task.new
8
+
9
+ desc 'runs all tests'
10
+ task :default => [:spec, :cucumber]
data/calrom.gemspec CHANGED
@@ -20,10 +20,11 @@ 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.6.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'
26
+ spec.add_dependency 'pattern-match', '~> 1.0'
25
27
 
26
- spec.add_development_dependency 'bundler', '~> 1.13'
27
28
  spec.add_development_dependency 'rake', '~> 10.0'
28
29
  spec.add_development_dependency 'rspec', '~> 3.0'
29
30
  spec.add_development_dependency 'cucumber', '~> 1.3'
data/lib/calrom/cli.rb CHANGED
@@ -1,16 +1,75 @@
1
1
  module Calrom
2
2
  class CLI
3
3
  def self.call(argv)
4
- config = OptionParser.call argv
5
- calendar = config.calendar
4
+ begin
5
+ config_files = OptionParser.call(argv).configs
6
6
 
7
- enumerator = Enumerator.new do |yielder|
8
- config.date_range.each do |date|
9
- yielder.yield calendar[date]
10
- end
7
+ config = EnvironmentReader.call
8
+ config = OptionParser.call(
9
+ rc_options(config_files.empty? ? nil : config_files) +
10
+ argv,
11
+ config
12
+ )
13
+
14
+ calendar = config.calendar
15
+ rescue OptionParser::Error, InputError => e
16
+ STDERR.puts e.message
17
+ exit 1
11
18
  end
12
19
 
13
- config.formatter.call enumerator, config.date_range
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
31
+
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
43
+ end
44
+
45
+ private
46
+
47
+ # options loaded from configuration files
48
+ def self.rc_options(paths = nil)
49
+ return [] if paths == ['']
50
+
51
+ paths ||=
52
+ ['/etc/calromrc', '~/.calromrc']
53
+ .collect {|f| File.expand_path f }
54
+ .select {|f| File.file? f }
55
+
56
+ paths.collect do |f|
57
+ begin
58
+ content = File.read(f)
59
+ rescue Errno::ENOENT
60
+ raise InputError.new("Configuration file \"#{f}\" not found")
61
+ end
62
+
63
+ options = RcParser.call content
64
+
65
+ begin
66
+ OptionParser.call(options)
67
+ rescue OptionParser::Error => e
68
+ raise InputError.new("Error loading '#{f}': #{e.message}")
69
+ end
70
+
71
+ options
72
+ end.flatten
14
73
  end
15
74
  end
16
75
  end
data/lib/calrom/config.rb CHANGED
@@ -1,18 +1,150 @@
1
1
  module Calrom
2
2
  class Config
3
+ DEFAULT_DATA = CR::Data::GENERAL_ROMAN_ENGLISH
4
+ DEFAULT_LOCALE = :en
5
+
3
6
  def initialize
4
7
  self.today = Date.today
5
- self.date_range = CR::Util::Month.new(today.year, today.month)
8
+ self.date_range = Month.new(today.year, today.month)
9
+ self.sanctorale = []
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 = []
6
17
  end
7
18
 
8
- attr_accessor :today, :date_range
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
9
42
 
10
43
  def calendar
11
- CR::PerpetualCalendar.new(sanctorale: CR::Data::GENERAL_ROMAN_ENGLISH.load)
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
+ )
60
+ end
61
+
62
+ def build_sanctorale
63
+ if @sanctorale.empty?
64
+ return DEFAULT_DATA.load
65
+ end
66
+
67
+ data = @sanctorale.collect do |s|
68
+ expanded = File.expand_path s
69
+
70
+ if s == '-'
71
+ CR::SanctoraleLoader.new.load_from_string STDIN.read
72
+ else
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
89
+ end
90
+ end
91
+
92
+ CR::SanctoraleFactory.create_layered(*data)
93
+ end
94
+
95
+ def temporale_options
96
+ {transfer_to_sunday: transfer_to_sunday, extensions: temporale_extensions}
97
+ end
98
+
99
+ def locale
100
+ @locale || locale_in_file_metadata || DEFAULT_LOCALE
101
+ end
102
+
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
113
+ end
114
+
115
+ klass.new build_highlighter(highlighter), today
116
+ end
117
+
118
+ def build_highlighter(colourful)
119
+ if (self.colours == false || (self.colours.nil? && !STDOUT.isatty))
120
+ return Highlighter::No.new
121
+ end
122
+
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
138
+ end
139
+
140
+ private
141
+
142
+ def locale_in_file_metadata
143
+ is_remote_calendar? ? nil : build_sanctorale.metadata['locale']&.to_sym
12
144
  end
13
145
 
14
- def formatter
15
- Formatter::List.new Highlighter::List.new, today
146
+ def is_remote_calendar?
147
+ !!@sanctorale.find {|s| s =~ /^https?:\/\// }
16
148
  end
17
149
  end
18
150
  end