{"id":21485324,"url":"https://github.com/igneus/calendarium-romanum","last_synced_at":"2025-05-01T09:17:20.155Z","repository":{"id":15083291,"uuid":"17809741","full_name":"igneus/calendarium-romanum","owner":"igneus","description":"liturgical calendar library (Roman Catholic, post-Vatican II)","archived":false,"fork":false,"pushed_at":"2025-02-11T20:35:05.000Z","size":1199,"stargazers_count":58,"open_issues_count":21,"forks_count":23,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-05-01T09:17:13.623Z","etag":null,"topics":["calendar","church","liturgy","ruby","ruby-gem"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/igneus.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-03-16T21:32:32.000Z","updated_at":"2025-03-16T00:48:05.000Z","dependencies_parsed_at":"2024-07-16T02:05:45.673Z","dependency_job_id":"52422e83-5dfe-4d62-b1f7-f041ecab51bc","html_url":"https://github.com/igneus/calendarium-romanum","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igneus%2Fcalendarium-romanum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igneus%2Fcalendarium-romanum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igneus%2Fcalendarium-romanum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igneus%2Fcalendarium-romanum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/igneus","download_url":"https://codeload.github.com/igneus/calendarium-romanum/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251850182,"owners_count":21653978,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["calendar","church","liturgy","ruby","ruby-gem"],"created_at":"2024-11-23T13:14:57.465Z","updated_at":"2025-05-01T09:17:20.133Z","avatar_url":"https://github.com/igneus.png","language":"Ruby","funding_links":[],"categories":["Libraries"],"sub_categories":[],"readme":"# calendarium-romanum\n\n![Build Status](https://github.com/igneus/calendarium-romanum/actions/workflows/ci.yml/badge.svg)\n[![Gem Version](https://badge.fury.io/rb/calendarium-romanum.svg)](https://badge.fury.io/rb/calendarium-romanum)\n\nAPI documentation:\n[0.9.0](http://www.rubydoc.info/gems/calendarium-romanum/0.9.0)\n[0.8.0](http://www.rubydoc.info/gems/calendarium-romanum/0.8.0)\n[0.7.1](http://www.rubydoc.info/gems/calendarium-romanum/0.7.1)\n[0.6.0](http://www.rubydoc.info/gems/calendarium-romanum/0.6.0)\n[0.5.0](http://www.rubydoc.info/gems/calendarium-romanum/0.5.0)\n[0.4.0](http://www.rubydoc.info/gems/calendarium-romanum/0.4.0)\n[0.3.0](http://www.rubydoc.info/gems/calendarium-romanum/0.3.0)\n[0.2.0](http://www.rubydoc.info/gems/calendarium-romanum/0.2.0)\n\nRuby gem for\ncalendar computations according to the Roman Catholic liturgical calendar as instituted by\n[MP Mysterii Paschalis](http://w2.vatican.va/content/paul-vi/en/motu_proprio/documents/hf_p-vi_motu-proprio_19690214_mysterii-paschalis.html)\nof Paul VI. (AAS 61 (1969), pp. 222-226),\ndefined in *General Norms for the Liturgical Year and the Calendar*\n([English translation][gnlyc])\nand subsequent [documents of liturgical legislation][liturgical_law].\n\n`calendarium-romanum` aspires to become the most complete and most accurate\nFOSS implementation of this calendar system\n(see [list of implementations available][awesomecc]).\n\n## Features\n\n`calendarium-romanum` is now a **feature-complete** implementation of the abovementioned calendar\nsystem, capable of generating a complete and (at least mostly) correct Roman Catholic liturgical\ncalendar for any year according to the most recent calendar rules and data\n(i.e. today's state of the calendar is used also for years in the past - for historically accurate\ncomputations see a [related project][crhistorical]).\n\nIt is **continuously kept up-to-date** with latest developments of the liturgical\nlegislation and newly introduced feasts.\n\n**Accuracy** is highly valued. Therefore just a very limited set of calendar data\nis bundled in the library, but with a guarantee that a theologian continuously takes care\nof them being up-to-date and correct. Users of the library will usually want to prepare\nand maintain their own data files representing their local calendars.\n(For ready-to-use calendar data without guarantees of correctness\nsee a [related repository][data-contrib].)\n\nThe project's scope is strictly limited to computing **liturgical calendar in a narrow sense.**\nIt doesn't provide functionality specific for individual liturgical books, unless it is\ndealt with in general liturgical norms regarding the calendar.\n(Liturgical colours being an exception from this rule, as it is very common to include\nthem in all kinds of liturgical calendars.)\nBut the library is designed with machine-readability in mind, so that additional layers\nof functionality, implementing book-specific calculations, can be built upon it.\n\nStrings are **localized** (using the [i18n][i18n] Ruby gem). Translations to six languages\n(Latin, English, Spanish, French, Italian, Czech)\nare provided. The built-in translations can be both replaced and/or supplemented\nwith translations to additional languages without having to modify the gem's code.\n\n## Credits\n\nincludes computation of the Easter date from the\n[easter](https://github.com/jrobertson/easter) gem\nby James Robertson.\n\nSee also changelog for list of contributions and their authors.\n\n## License\n\ndual licensed: freely choose between GNU/LGPL 3 and MIT\n\n## Project status\n\nThe library is currently considered feature-complete for release 1.0.0\nand it's public API mostly stabilized.\nDevelopment focuses on reaching higher degree of certainty regarding\ncorrectness by means of making the test suite more comprehensive and rigorous.\n\n## Backward compatibility\n\nThe gem's public interface has now been mostly stabilized, but until v1.0.0 release\nthere is still no guaranteed backward compatibility between minor versions.\n\nWhen using the gem in your projects, it is recommended to lock\nthe dependency to a particular minor version.\n\nIn your app's Gemfile\n\n```\ngem 'calendarium-romanum', '~\u003e0.9.0'\n```\n\nor in gemspec of your gem\n\n```\nspec.add_dependency 'calendarium-romanum', '~\u003e0.9.0'\n```\n\n## Usage\n\nAll the examples below expect that you first required the gem:\n\n```ruby\nrequire 'calendarium-romanum'\n```\n\n### 1. Typical usage\n\nThe easiest way to obtain calendar entry of any liturgical day:\n\n```ruby\nI18n.locale = :en # set locale\n\n# build calendar\npcal = CalendariumRomanum::PerpetualCalendar.new(\n  sanctorale: CalendariumRomanum::Data::GENERAL_ROMAN_ENGLISH.load\n)\n\n# query\nday = pcal[Date.new(2000, 1, 1)]\n```\n\nFor explanation see the detailed steps below.\n\n### 2. What liturgical day is it today?\n\n`PerpetualCalendar` used in the example above is a high-level API.\nIn order to understand what's happening under the hood, we will\nnow take a lower-level approach and work on the level of a simple\n`Calendar`.\nEach `Calendar` instance describes a particular *liturgical year*.\nWe may not know which liturgical year our day of interest\nbelongs to, but fortunately there is \"alternative constructor\"\n`Calendar.for_day()` to rescue:\n\n```ruby\ndate = Date.new(2016, 8, 19)\ncalendar = CalendariumRomanum::Calendar.for_day(date)\nday = calendar[date]\n\nday.season # =\u003e #\u003cCalendariumRomanum::Season:0x00000001d4cfa0 @symbol=:ordinary, @colour=#\u003cCalendariumRomanum::Colour:0x00000001d4d928 @symbol=:green, @i18n_key=\"colour.green\"\u003e, @i18n_key=\"temporale.season.ordinary\"\u003e\nday.season.equal? CalendariumRomanum::Seasons::ORDINARY # =\u003e true\n\nday.celebrations\n# =\u003e [#\u003cCalendariumRomanum::Celebration:0x00000001c69cc8 @title=\"Friday, 20th week in Ordinary Time\", @rank=#\u003cCalendariumRomanum::Rank:0x00000001d4c708 @priority=3.13, @desc=\"rank.3_13\", @short_desc=\"rank.short.ferial\"\u003e, @colour=#\u003cCalendariumRomanum::Colour:0x00000001d4d928 @symbol=:green, @i18n_key=\"colour.green\"\u003e, @symbol=nil\u003e]\nc = day.celebrations.first\nc.title # =\u003e \"Friday, 20th week in Ordinary Time\"\nc.rank # =\u003e #\u003cCalendariumRomanum::Rank:0x00000001d4c708 @priority=3.13, @desc=\"rank.3_13\", @short_desc=\"rank.short.ferial\"\u003e\nc.rank.equal? CalendariumRomanum::Ranks::FERIAL # =\u003e true\nc.rank \u003c CalendariumRomanum::Ranks::MEMORIAL_PROPER # =\u003e true\nc.colour\n# =\u003e #\u003cCalendariumRomanum::Colour:0x00000001d4d928 @symbol=:green, @i18n_key=\"colour.green\"\u003e\n```\n\n`Calendar#[]` returns a single `Day`, describing a liturgical day.\nEach day belongs to some `#season`; every day, we can choose from\none or more `#celebrations` to celebrate.\n(The only case with multiple choices is combination of a ferial\nwith one or more optional memorials; higher-ranking celebrations\nare always exclusive.)\n\nEach `Celebration` is described by a `#title`, `#rank` and `#colour`.\n\n### 3. But does it take feasts of saints in account?\n\nActually, no. Not yet. We need to load some calendar data first:\n\n```ruby\nCR = CalendariumRomanum\nloader = CR::SanctoraleLoader.new\nsanctorale = loader.load_from_file 'data/universal-en.txt' # insert path to your data file\ndate = Date.new(2016, 8, 19)\ncalendar = CR::Calendar.for_day(date, sanctorale)\nday = calendar[date]\nday.celebrations # =\u003e [#\u003cCalendariumRomanum::Celebration:0x000000027d9590 @title=\"Friday, 20th week in Ordinary Time\", @rank=#\u003cCalendariumRomanum::Rank:0x000000029e1108 @priority=3.13, ... \u003e, @colour=#\u003cCalendariumRomanum::Colour:0x000000029e1f68 @symbol=:green\u003e\u003e, #\u003cCalendariumRomanum::Celebration:0x000000029c96c0 @title=\"Saint John Eudes, priest\", @rank=#\u003cCalendariumRomanum::Rank:0x000000029e1180 @priority=3.12, ... \u003e, @colour=#\u003cCalendariumRomanum::Colour:0x000000029e1f18 @symbol=:white\u003e\u003e]\n```\n\nUnless a sanctorale is loaded, `Calendar` only counts with\ntemporale feasts, Sundays and ferials.\n\nNote how we saved some typing by defining new constant `CR`\nreferencing the `CalendariumRomanum` module.\nIn fact you can save even more typing by replacing\n`require 'calendarium-romanum'`\nby\n`require 'calendarium-romanum/cr'`\nwhich loads the gem *and* defines the `CR` shortcut for you.\nFollowing examples expect the `CR` constant to be defined\nand reference the `CalendariumRomanum` module.\n\nAnother possible way of saving some typing (if you don't care about\npossible name clashes or polluting current namespace)\nis including `CalendariumRomanum` module in the current module.\nThen `CalendariumRomanum` classes can be referenced unqualified:\n\n```ruby\ninclude CalendariumRomanum\n\nloader = SanctoraleLoader.new\n# etc.\n```\n\n### 4. Isn't there an easier way to get sanctorale data?\n\nYes! There are a few data files bundled in the gem.\nYou can explore them by iterating over `CalendariumRomanum::Data.all`.\nThose of general interest are additionally identified by their proper\nconstants, e.g. `CalendariumRomanum::Data::GENERAL_ROMAN_ENGLISH`.\nBundled data files can be loaded by a handy shortcut method `#load`:\n\n```ruby\nsanctorale = CR::Data::GENERAL_ROMAN_ENGLISH.load # easy loading\ndate = Date.new(2016, 8, 19)\ncalendar = CR::Calendar.for_day(date, sanctorale)\nday = calendar[date]\n```\n\n### 5. I don't want to care about (liturgical) years\n\nEach Calendar instance is bound to a particular *liturgical* year.\nCalling `Calendar#[]` with a date out of the year's range\nresults in a `RangeError`:\n\n```ruby\ncalendar = CR::Calendar.new(2000)\nbegin\n  day = calendar[Date.new(2000, 1, 1)]\nrescue RangeError\n  STDERR.puts 'ouch' # will happen\nend\n```\n\nThe example demonstrates the well known fact,\nthat the **civil and liturgical year don't match:**\n1st January 2000\ndoes not belong to the liturgical year 2000-2001\n(which will begin on the first Sunday of Advent,\ni.e. on 3rd December 2000), but to the year 1999-2000.\nFor the sake of simplicity, `calendarium-romanum` denotes\nliturgical years by the starting year only, so you create\na `Calendar` for liturgical year 1999-2000 by calling\n`Calendar.new(1999)`.\n\nWe have already seen `Calendar.for_day()`, which takes care\nof finding the liturgical year a particular date belongs to\nand creating a `Calendar` for this year.\nBut maybe you want to query a calendar without caring about liturgical\nyears altogether, possibly picking days across multiple years.\nThe best tool for such use cases is `PerpetualCalendar`.\n\n```ruby\npcal = CR::PerpetualCalendar.new\n\n# get days\nd1 = pcal[Date.new(2000, 1, 1)]\nd2 = pcal[Date.new(2100, 1, 1)]\nd3 = pcal[Date.new(1970, 1, 1)]\n\n# get Calendar instances if you need them\ncalendar = pcal.calendar_for_year(1987)\n```\n\nJust like `Calendar` with the default settings (no sanctorale data\netc.) is usually of little use, so is a `PerpetualCalendar`\ncreating such `Calendar`s. Of course it is possible to specify\nconfiguration which is then applied on the `Calendar`s\nbeing created:\n\n```ruby\npcal = CR::PerpetualCalendar.new(\n  # Sanctorale instance\n  sanctorale: CR::Data::GENERAL_ROMAN_ENGLISH.load,\n  # options that will be passed to Temporale.new\n  temporale_options: {\n    transfer_to_sunday: [:epiphany],\n    extensions: [CR::Temporale::Extensions::ChristEternalPriest]\n  }\n)\nd = pcal[Date.new(2000, 1, 1)]\n\n# It is also possible to supply Temporale factory instead of options:\npcal = CR::PerpetualCalendar.new(\n  # Proc returning a Temporale instance for the specified year\n  temporale_factory: lambda do |year|\n    CR::Temporale.new(year, transfer_to_sunday: [:ascension])\n  end\n)\npcal[Date.new(2000, 1, 1)]\n```\n\n**Memory management note:**\nInternally, `PerpetualCalendar` builds `Calendar` instances as needed\nand by default caches them *perpetually.* This is OK in most cases,\nbut it can lead to memory exhaustion if you traverse an excessive\namount of liturgical years. In such cases you can supply\nyour own cache (a `Hash` or anything with hash-like interface)\nand implement some kind of cache size limiting.\n\n```ruby\nmy_cache = {}\npcal = CR::PerpetualCalendar.new(cache: my_cache)\n```\n\n## Sanctorale Data\n\n### Use prepared data or create your own\n\nThe gem expects data files following a custom format -\nsee README in the [data][data] directory for it's description.\nThe same directory contains a bunch of example data files.\n(All of them are also bundled in the gem and accessible via\n`CalendariumRomanum::Data`, as described above.)\n\n`universal-en.txt` and `universal-la.txt` are data of the General\nRoman Calendar in English and Latin.\n\nThe `czech-*.txt` files, when layered properly, can be used to assemble\nproper calendar of any diocese in the Czech Republic.\n\n### Implement custom loading strategy\n\nIn case you already have sanctorale data in another format,\nit might be better suited for you to implement your own loading\nroutine instead of transforming them to our custom format.\n`SanctoraleLoader` is the class to look into for inspiration.\n\nThe important bit is that for each celebration you\nbuild a `Celebration` instance and push it in a `Sanctorale`\ninstance by a call to `Sanctorale#add`, which receives a month,\na day (as integers) and a `Celebration`:\n\n```ruby\nsanctorale = CR::Sanctorale.new\ncelebration = CR::Celebration.new('Saint John Eudes, priest', CR::Ranks::MEMORIAL_OPTIONAL, CR::Colours::WHITE)\nsanctorale.add 8, 19, celebration\n\ndate = Date.new(2016, 8, 19)\ncalendar = CR::Calendar.for_day(date, sanctorale)\n\nday = calendar[date]\nday.celebrations # =\u003e [#\u003cCalendariumRomanum::Celebration:0x000000010deea8 @title=\"\", @rank=#\u003cstruct CalendariumRomanum::Rank priority=3.13, desc=\"Unprivileged ferials\", short_desc=\"ferial\"\u003e, @colour=:green\u003e, #\u003cCalendariumRomanum::Celebration:0x000000010fec08 @title=\"Saint John Eudes, priest\", @rank=#\u003cstruct CalendariumRomanum::Rank priority=3.12, desc=\"Optional memorials\", short_desc=\"optional memorial\"\u003e, @colour=:white\u003e]\n```\n\n### Proper calendar of a church\n\nOne common case of preparing custom sanctorale data is\nimplementing proper calendar of a church\n(cf. *General Norms for the Liturgical Year and the Calendar* par. 52 c).\nProper calendar of a church is built by adding to the calendar\nof the diocese (or religious institute) the church'es proper celebration,\nwhich are usually just two solemnities: anniversary of dedication\nand titular solemnity.\n\nLet's say you have calendar of your diocese in sanctorale data file\n`my-diocese.txt`.\nYou could copy the file to a new location and add the two proper solemnities,\nbut your programmer better self won't allow you to do that.\nWhat options are left? You can create a new sanctorale file\nwith the two proper celebrations and then load it over the calendar\nof the diocese, as explained in [data][data].\nOr, if you need the calendar just for that single little script\nand don't care about creating data files, you can build the two\nproper solemnities in code:\n\n```ruby\n# here you would load your 'diocese.txt' instead\ndiocese = CR::SanctoraleLoader.new.load_from_file 'data/universal-en.txt'\n\ndedication = CR::Celebration.new('Anniversary of Dedication of the Parish Church', CR::Ranks::SOLEMNITY_PROPER, CR::Colours::WHITE)\ntitular = CR::Celebration.new('Saint Nicholas, Bishop, Titular Solemnity of the Parish Church', CR::Ranks::SOLEMNITY_PROPER, CR::Colours::WHITE)\n\n# solution 1 - directly modify the loaded Sanctorale\n\ndiocese.replace(10, 25, [dedication])\ndiocese.replace(12, 6, [titular])\n\n# solution 2 - create a new Sanctorale with just the two solemnities,\n# then create a third instance merging contents of the two without modifying them\n\nproper_solemnities = CR::Sanctorale.new\nproper_solemnities.replace(10, 25, [dedication])\nproper_solemnities.replace(12, 6, [titular])\n\ncomplete_proper_calendar = CR::SanctoraleFactory.create_layered(diocese, proper_solemnities)\n```\n\n## I18n, or, how to fix names of temporale feasts\n\nOne drawback of the current implementation is that names\nof *temporale* feasts are totally independent of *sanctorale* feast\nnames. They are hardcoded in the gem, as [i18n][]\n[translation strings][translations].\n\nWhen you load *sanctorale* data in your favourite language,\nthe `Calendar` will by default still produce *temporale*\nfeasts with names in English.\nThis can be fixed by changing locale to match your *sanctorale*\ndata.\n\n`I18n.locale = :la # or :en, :fr, :it, :cs`\n\nThe gem ships with English, Latin, Italian, Spanish, French and Czech translation.\nContributed translations to other languages are most welcome.\n\n## Transfer of solemnities to a Sunday\n\nAs specified in\n[General Norms for the Liturgical Year and the Calendar][gnlyc] 7,\nthe solemnities of Epiphany, Ascension and Corpus Christi\ncan be transferred to a Sunday.\n`Temporale` by default preserves the regular dates of these\nsolemnities, but it has an option to enable the transfer:\n\n```ruby\n# transfer all three to Sunday\ntemporale = CR::Temporale.new(2016, transfer_to_sunday: [:epiphany, :ascension, :corpus_christi])\n```\n\nUsually you don't want to work with `Temporale` alone, but with\na `Calendar`. In order to create a `Calendar` with non-default\n`Temporale` settings, it is necessary to provide a `Temporale`\nas third argument to the constructor.\n\n```ruby\nyear = 2000\nsanctorale = CR::Data::GENERAL_ROMAN_ENGLISH.load\ntemporale = CR::Temporale.new(year, transfer_to_sunday: [:epiphany])\n\ncalendar = CR::Calendar.new(year, sanctorale, temporale)\n```\n\n## Custom movable feasts\n\nSome local calendars may include proper movable feasts.\nIn Czech Republic this has recently been the case with the newly\nintroduced feast of *Christ the Priest* (celebrated on Thursday\nafter Pentecost). Support for this feast, celebrated in several other\ndioceses and religious institutes, is included in the gem\nas `Temporale` extension.\n\nIn order to build a complete Czech `Calendar` with proper sanctorale\nfeasts and the additional temporale feast of *Christ the Priest*,\nit is necessary, apart of loading the sanctorale data,\nto provide a `Temporale` instance with the extension applied:\n\n```ruby\nyear = 2016\nsanctorale = CR::Data::CZECH.load\ntemporale =\n  CR::Temporale.new(\n    year,\n    # the important bit: apply the Temporale extension\n    extensions: [CR::Temporale::Extensions::ChristEternalPriest]\n  )\n\ncalendar = CR::Calendar.new(year, sanctorale, temporale)\n```\n\nThe feast of *Christ the Priest*, by it's nature, extends the cycle of\n*Feasts of the Lord in the Ordinary Time* and thus clearly belongs\nto the *temporale.* Even if your proper movable feast\nis by it's nature a *sanctorale* feast, just having a movable\ndate, the only way to handle it using this gem is to write\na *temporale* extension. There is no support for movable feasts\nin the `Sanctorale` class. Even the single movable sanctorale\nfeast of the General Roman Calendar,\nthe memorial of *Immaculate Heart of Mary,* is, by a little cheat,\ncurrently implemented in the `Temporale`.\n\nAny object defining method `each_celebration`, which yields\npairs of \"date computer\" and `Celebration`, can be used as\ntemporale extension. Unless you have a good reason to do otherwise,\na class or module defining `each_celebration` as class/module method\nis a convenient choice.\n\n```ruby\nmodule MyExtension\n  # yields celebrations defined by the extension\n  def self.each_celebration\n    yield(\n      :my_feast_date, # name of a method computing date of the feast\n      CR::Celebration.new(\n        'My Feast', # feast title\n        CR::Ranks::FEAST_PROPER, # rank\n        CR::Colours::WHITE # colour\n      )\n    )\n\n    yield(\n      # Proc can be used for date computation instead of a method\n      # referenced by name\n      lambda {|year| CR::Temporale::Dates.easter_sunday(year) + 9 },\n      CR::Celebration.new(\n        # It is possible to use a Proc as feast title if you want it\n        # to be determined at runtime - e.g. because you want to\n        # have the feast title translated and follow changes of `I18n.locale`\n        proc { I18n.t('my_feasts.another_feast') },\n        CR::Ranks::MEMORIAL_PROPER,\n        CR::Colours::WHITE\n      )\n    )\n  end\n\n  # computes date of the feast;\n  # the year passed as argument is year when the liturgical\n  # year in question _began_\n  def self.my_feast_date(year)\n    # the day before Christ the King\n    CR::Temporale::Dates.christ_king(year) - 1\n  end\nend\n\ntemporale = CR::Temporale.new(2016, extensions: [MyExtension])\n\n# the feast is there!\ntemporale[Date.new(2017, 11, 25)] # =\u003e #\u003cCalendariumRomanum::Celebration:0x0000000246fd78 @title=\"My Feast\", @rank=#\u003cCalendariumRomanum::Rank:0x000000019c27e0 @priority=2.8, ... \u003e, @colour=#\u003cCalendariumRomanum::Colour:0x000000019c31e0 @symbol=:white\u003e\u003e\n```\n\n## Internationalization internals\n\nIt was already mentioned earlier in this document that\nfor internationalization of temporale feast names and\nother \"built-in strings\"\n`calendarium-romanum` relies upon the `i18n` gem.\nSome internal details may be worth a mention:\n\nOn `require 'calendarium-romanum'`, paths of a few translation\nfiles bundled in the gem are added to `I18n.config.load_path`.\nWhile otherwise we avoid polluting or modifying the environment\noutside the gem's own scope, in this case we exceptionally\nmodify global configuration in order to make the internationalization\neasily and conveniently work.\nIf your application requires `calendarium-romanum` to handle\nlanguages not bundled in the gem, or if you don't like the default\ntranslations, just prepare a [translation file][translations],\nput it anywhere in your project's tree\nand add it's path to `I18n.config.load_path`.\nIf, on the other hand, even the officially supported languages\ndon't work for you, check if paths to the gem's translation files\nare present in `I18n.config.load_path` and possibly search your\napplication (and it's other dependencies) for code which kicked\nthem out.\n\n## Example code\n\nFor applications using calendarium-romanum see the Dependency Graph on Github.\n\nThere is also a growing collection of [gists][gists] with smaller examples,\nusually finding answers for calendrical questions.\n\n## Executable\n\nThis gem provides an executable, `calendariumrom`.\nIt's handful of subcommands can be used to query liturgical calendar\nfrom the command line and to check validity of sanctorale data files.\n\n### 1. Query liturgical calendar from the command line\n\n- `calendariumrom query` prints calendar entries for today or a specified day, month or year.\n  See `calendariumrom help query` for available options and arguments.\n- `calendariumrom calendars` lists data files bundled in `calendarium-romanum`.\n\nTip: `calendariumrom query` is a rather bare-bones calendar querying\ntool. Check out the [`calrom`][calrom] gem for a more feature-rich\nliturgical calendar for your command line.\n\n### 2. Check sanctorale data files\n\n- `calendariumrom cmp FILE1 FILE2` loads two data files and prints any differences between them\n  (excepting differences in celebration titles)\n- `calendariumrom errors FILE1, ...` attempts loading a data file (or several of them),\n  reports eventual errors\n\n### 3. Help\n\n- `calendariumrom` lists available subcommands\n- `calendariumrom help [COMMAND]` outputs a short help for all available subcommands\n- `calendariumrom version` prints installed version of the gem\n\n## For Developers\n\nGet the sources and install development depencencies:\n\n1. `git clone git@github.com:igneus/calendarium-romanum.git`\n2. `cd calendarium-romanum`\n3. `bundle install` or `bundle install --path vendor/bundle`\n\n### Run from CLI\n\n`bundle exec ruby -Ilib bin/calendariumrom`\n\n### Run Tests\n\n- `bundle exec rake spec` to execute the complete test suite\n- `bundle exec rake spec_fast` to run tests, skipping those known to be slow (for fast TDD cycles)\n- `bundle exec rake spec_all_locales` to run the test suite for each of the supported locales\n  (to make sure that the gem works equally well with all supported locales\n  and tests depending on the current locale are explicit about it)\n- `bundle exec appraisal rake spec` to test compatibility with different versions of dependencies\n- `bash spec/build/gem_build_test.sh` to test that a valid working Ruby gem can be built from the sources\n\n[awesomecc]: https://github.com/calendarium-romanum/awesome-church-calendar\n[gnlyc]: https://www.ewtn.com/catholicism/library/liturgical-year-2193\n[i18n]: https://github.com/svenfuchs/i18n\n[translations]: /config/locales\n[liturgical_law]: /liturgical_law\n[data]: /data\n[module-included]: http://ruby-doc.org/core-2.2.2/Module.html#method-i-included\n[calrom]: https://github.com/calendarium-romanum/calrom\n[crhistorical]: https://github.com/calendarium-romanum/historical\n[data-contrib]: https://github.com/calendarium-romanum/data-contrib\n[i18n]: https://github.com/ruby-i18n/i18n\n[gists]: https://gist.github.com/search?q=calendarium-romanum\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Figneus%2Fcalendarium-romanum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Figneus%2Fcalendarium-romanum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Figneus%2Fcalendarium-romanum/lists"}