summaryrefslogtreecommitdiff
path: root/internal/calendar
Commit message (Collapse)AuthorAgeFilesLines
* naming: localise liturgical day names in any languageLukasz Kasprzak2026-07-282-178/+0
| | | | | | | | | | | | | | | | | | | | | | | | Add internal/naming, which renders temporal day names and celebration display names from the calendar engine's slugs in any language. English is the built-in baseline; a language is data -- an embedded lang/<code>.ini (pl shipped) and/or a user file at <config dir>/names/<code>.ini that overrides it key by key. Names compose from a small vocabulary plus per-language format templates, so word order and grammatical case can differ (e.g. Polish genitive "3. Niedziela Okresu Zwykłego"); any string a language omits falls back to English. - Move day-name generation out of calendar (calendar.HumanizeSlug removed, calendar stays a pure engine) into naming.DayName; the English golden cases carry over verbatim. - naming.CelebrationName unifies the three duplicated resolvers (cli/readings/calfeed): name.<lang> -> English -> Latin -> humanized slug. Saint names stay in the calendar data (name.<lang>), overridable via calendar layers. - config: ui_language now accepts any code (lower-cased, not clamped to en/pl) so names/<code>.ini applies; UI chrome still resolves en/pl and falls back to English. Add NamesDir(); wire naming.SetUserDir (and the previously unwired bible.SetUserCorporaDir) in the TUI and web mains too, so external corpora and name files work across all three binaries.
* fix(EF): resumed Sundays after Pentecost use the Epiphany MassesLukasz Kasprzak2026-07-281-0/+18
| | | | | | | | | | | In early-Easter years there are more than 24 Sundays after Pentecost. Per the 1960 Rubrics the surplus Sundays resume the Sundays after Epiphany that Septuagesima cut short (highest-numbered first) and the last Sunday keeps the 24th (Last) Mass. temporalEF now routes those Sundays to the resumed Epiphany slug for readings while keeping the calendrical time-after-pentecost season; the mis-harvested tail entries (post-Pentecost sundays 24-28) are corrected to the true 24th Mass and the surplus removed. Validated: 88/88 tail/resumed Sunday gospels match missalemeum 2025-2050; EF oracle green.
* fix(EF): fill reading gaps (major feasts, feria-repeat-through-feast, sundays)Lukasz Kasprzak2026-07-281-0/+13
| | | | | | | | | | | | | | | | EF readings had ~1.8% of days with no readings (major feasts falling back to the wrong Sunday, feria-repeats broken when the preceding Sunday was a feast). Now 0 gaps over 9496 days (2025-2050); reading correctness spot-checks match missalemeum except the resumed-Epiphany-Sunday edge (next commit). - calendar.TemporalSlug: the green-season weekday-repeats-the-Sunday rule uses the Sunday's TEMPORAL slug, so a Monday still finds its Sunday Mass when that Sunday was displaced by a feast (e.g. the Purification on Feb 2). - Add the missing EF temporal Masses (from missalemeum): the Nativity Day Mass (Heb 1:1-12 / John 1:1-14), Epiphany (Isa 60:1-6 / Matt 2:1-12), the Octave Day of Christmas (Titus 2:11-15 / Luke 2:21), the 6th Sunday after Epiphany (1 Thess 1:2-10 / Matt 13:31-35), and the last Sunday after Pentecost (Col 1:9-14 / Matt 24:15-35).
* fix(calendar): OF precedence/transfer + readings resolution; EF Pentecost octaveLukasz Kasprzak2026-07-284-3/+62
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fixes found by validating the offline engine per-day vs the LiturgicalCalendar API (OF) and missalemeum (EF) across 2005-2050. OF calendar is now 0 real errors in the forward window (season/cycle already perfect). OF precedence/transfer (calendar): - Ash Wednesday and Holy Week Mon-Wed are band-2 privileged, so a coinciding feast (Chair of St Peter on Ash Wednesday) is suppressed, not observed. - Solemnities transfer out of Holy Week / the Easter octave: the Annunciation defers to the Monday after the 2nd Sunday of Easter; St Joseph is anticipated to the Saturday before Palm Sunday; the Nativity of St John the Baptist moves to Jun 23 when a Lord's solemnity (Sacred Heart / Corpus Christi) falls Jun 24. - Within a precedence band, a solemnity of the Lord/BVM outranks a saint's (dignity tiebreak) rather than losing an alphabetical slug tie. - Perpetua & Felicity corrected optional -> obligatory memorial. OF readings resolution (bible.OFRef + lectionary data): - Verse-accurate Hebrew->Vulgate psalm mapping incl. the split psalms (9/10, 114/115, 116, 147); "+" verse joins and abbreviated ranges ("127-28") normalized; single-chapter books (2/3 John, Jude) get chapter 1. - Cleaned harvest artifacts from of-lectionary.ini (descriptive-suffix gospels, "or Year A" alternates, "*"/"[Vulg.]"/bracket markers, slash abbreviations); Joel/Malachi/Zechariah/Esther book-versification citations fixed to Vulgate. - Split a merged Ps 15:10/11 row in vul.tsv. Result: 0 unresolvable OF readings over 2557 rendered days (cycles A/B/C, varied Easters). EF: the Octave of Pentecost (Whit Monday-Saturday) is red, not white.
* feat: humanize temporal-day display names (OF + EF)Lukasz Kasprzak2026-07-282-0/+178
| | | | | | | | | | Temporal days with no proper name showed a slug-derived string ('triduum fri', 'ordinary 11 tue', 'advent-dec-17'). Add calendar.HumanizeSlug, used by both celebrationName fallbacks (cli + calfeed), turning slugs into proper liturgical names: Good Friday, Ash Wednesday, 'Tuesday of the 11th Week in Ordinary Time', '11th Sunday in Ordinary Time', 'December 17', 'The Most Holy Trinity', and the EF forms ('4th Week after Pentecost', 'Passion Week', 'Ember Wednesday of September'). Adds TestHumanizeSlug.
* feat(of): proper readings for the movable Marian memorialsLukasz Kasprzak2026-07-282-5/+24
| | | | | | | | Mary, Mother of the Church and the Immaculate Heart of Mary are computed in the engine (no fixed-date INI entry), so they fell back to the ferial. Attach their proper Masses inline: Mary MotC = Gen 3:9-15,20 / Ps 87 / John 19:25-34; Immaculate Heart = Isa 61:9-11 / 1 Sam 2 canticle / Luke 2:41-51. Verified they render when observed (Immaculate Heart 2029-06-09). Extends TestOFMovableMemorials.
* feat(of): Christmas-season weekday ferials from catholic-resources.org ↵Lukasz Kasprzak2026-07-281-1/+11
| | | | | | | | | | | | | | | (date-based) Completes the seasonal weekday lectionary. The Christmas-season weekdays sit on the AdventChristmas page in a SHIFTED 6-column layout (Day in c[1], not c[2] like Advent's 7-column) -- the generator now finds the Day column wherever it is. Adds date-based slugs to temporal.go: christmas-dec-<29..31> (octave), christmas-jan-<2..7> (before Epiphany), christmas-after-epiphany-<weekday> (before the Baptism). Fixes the christmas-octave-fri coverage gap and the by-date/by-week collision. 362/362 seasonal ferial-days render across 2026-2029 with 0 gaps. Extends TestOFSeasonalFerials. All of Advent/Lent/Easter/Christmas weekdays now CR-sourced; only the Commons remain (optional -- memorials default to the ferial).
* feat(of): seasonal weekday ferials from catholic-resources.org + date-based ↵Lukasz Kasprzak2026-07-281-0/+5
| | | | | | | | | | | | | | | | | | | | | | late Advent Re-sources the proper weekdays of Advent (weeks 1-3), Lent, and Eastertide from catholic-resources.org (scripts/genlect-of-season-ferials-cr.py; single-cycle, so both -I/-II keys get the same readings). The diff caught real niedziela defects: - Easter weekday first readings contaminated (easter-3-mon had 1 Cor 15 instead of Acts 6:8-15; easter-4-thu had Rev 12 instead of Acts 13:13-25). - The Easter octave weekdays (Easter Mon-Sat) had no readings at all. - Stray psalm-numbering artifacts (147A(146), Ps42(41)) cleared. Late Advent (Dec 17-24) is proper to the DATE, not the Advent week, so temporal.go now keys those days 'advent-dec-<day>' (fixing the same by-date/by-week collision as the OT numbering) and the generator supplies them (Dec 17 = the genealogy Matt 1:1-17; Dec 24 = the Benedictus). 157 seasonal ferial-days render across 2026-2028 with 1 residual gap (christmas-octave-fri). Adds TestOFSeasonalFerials, credits the source, bumps to 0.43.0. Christmas-season weekdays (Dec 29-31, Jan 2-5) remain niedziela-sourced (CR's shifted layout + Epiphany-dependent assignment -- a documented follow-up).
* fix(of): canonical OT ferial week numbering + CR-sourced ferial lectionaryLukasz Kasprzak2026-07-282-2/+26
| | | | | | | | | | | | | | | | | | | | | | The Ordinary Form ferial lectionary had two linked defects, both from harvesting niedziela.pl by date: (1) post-Pentecost Ordinary-Time ferial WEEK NUMBERS were one too high (temporal.go counted back from Christ the King using the weekday itself, not its preceding Sunday, so a ferial took the next week's number), and (2) ~17 ferial keys held a SAINT's readings (stored when a saint displaced the ferial on the queried date, e.g. week 22 smeared with a Marian Prov 8/John 2), plus 16 weekday slots were missing entirely. - temporal.go: number a span-2 ferial from its preceding Sunday. Verified 388/388 ferial-week agreement with calapi across 2026-2028. - scripts/genlect-of-cr.py: regenerate the Ordinary-Time ferial lectionary (first/psalm/gospel, both years, all 34 weeks) from catholic-resources.org (Fr. Felix Just, S.J.), which is keyed by liturgical position (immune to by-date contamination) and complete. Citations only; text still rendered from the public-domain corpora. of-lectionary.ini OT ferials now 408 (was 392). Fixes ~17 contaminated entries + 16 gaps + the week-numbering audit item. Psalms already share modern numbering, so no conversion. Adds TestOFOrdinaryTimeFerialWeek. Credits catholic-resources.org in NOTICE. Bumps to 0.40.0.
* feat: complete OF+EF calendar coverage (movable feasts, vigils, ember days, ↵Lukasz Kasprzak2026-07-284-1/+211
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | transfers) Ordinary Form: - Add the movable Marian memorials that have no fixed date: Mary, Mother of the Church (Monday after Pentecost) and the Immaculate Heart (Saturday after the Sacred Heart), computed in computeOF. - General Norms 60: two coinciding obligatory memorials both become optional and the ferial is observed -- except Mary, Mother of the Church, which keeps precedence per its 2018 decree. Extraordinary Form: - Capture fixed-date vigils in the sanctoral harvest (Christmas, the Nativity of St John the Baptist, Sts Peter & Paul, St Lawrence, the Assumption, All Saints, the Immaculate Conception) -- previously filtered out. - temporalEF: the movable vigils of the Ascension (I class eve) and Pentecost (Whitsun Eve), and the September/Advent Ember days (II class violet ferias). - transferIfImpededEF: the Annunciation transfers past Holy Week/the Easter octave to the Monday after Low Sunday; All Souls moves to Nov 3 when Nov 2 is a Sunday. - genlect harvests proper Masses for the new Ember/vigil days. Adds TestEFCoverage + TestOFMovableMemorials. Bumps to 0.39.0. Verified per-day: OF 0 real errors vs calapi (2026-2028, 100% correct-observed); EF 0 real errors vs missalemeum (2025-2027), residual = deep-tail vigil-occurrence and St Joseph Passiontide-transfer edges (~1-2 days/yr, documented).
* fix(ef): 1962 occurrence precedence for the full sanctoralLukasz Kasprzak2026-07-282-7/+53
| | | | | | | | | | | | | | | - Septuagesima ferias are IV class (per annum), not III class, so a III class saint (e.g. Conversion of St Paul, Jan 25) displaces them. - Holy Week ferias and the privileged octaves of Easter and Pentecost are I class: no saint's feast is admitted (temporal office wins). - Occurrence tie-break is asymmetric by season: an ordinary feria (Advent, per annum) yields to an equal-class feast; Lent/Passiontide ferias keep their privilege and win the tie. - A II class feast of the Lord (Purification, Exaltation of the Cross, Dedication of the Lateran) displaces a II class Sunday it falls on. Validated against missalemeum across 2025-2027: ~97.5% of days observe the liturgically-correct celebration, 100% rank agreement on saint-days.
* feat(of): full sanctoral calendar + weekday/memorial readingsLukasz Kasprzak2026-07-281-1/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Populate the OF General Roman Calendar sanctoral and extend the OF readings to weekdays and sanctoral days. Sanctoral calendar (roman-calendar.ini: 29 -> 202 celebrations): - scripts/gen-sanctoral.go generates it from calapi.inadiutorium.cz (authoritative General Roman Calendar) -- English name/rank/colour from general-en, Latin from general-la, Polish from niedziela DayInfo (obligatory celebrations). Fixed dates the temporal engine already computes are excluded. VALIDATED: my engine's observed rank agrees with calapi on all 86 obligatory sanctoral days of 2026 (0 mismatches). Precedence fix (precedence.go): an optional memorial no longer displaces the weekday as the DEFAULT observed celebration (it sorts below the ferial, shown as an option) -- matching the General Roman Calendar / calapi. Readings (of-lectionary.ini: 254 -> 1018 entries) via genlect-of.go: - Weekday (ferial) 2-year cycle I/II, keyed <ferial-slug>-<WeekdayCycle>, harvested from niedziela over 2020-2025 (multiple years per cycle; retry-on-failure so a glitch year never poisons a key; only TRUE ferials + optional-memorial days, where niedziela shows the ferial). - Obligatory memorials keyed by their OWN slug (niedziela shows their proper, e.g. Barnabas -> Acts 11, or the ferial for memorials without a proper) -- never miskeyed to a ferial position. - caldata.Readings: OF resolves slug+SundayCycle | slug+WeekdayCycle, else a memorial falls back to the day's ferial readings. - Source-glitch normalisation (1J->1 J, PnP->Pnp). books.ini: canonical names "Song of Solomon" and "The Acts" added as their own [en] forms (ToEnglishRef emits the canonical; it must resolve). Fixes ~32 cross-chapter Song-of-Songs/Acts citations. Coverage: 359/365 days of 2026 render (98.4%); 6 residual ferial positions never a true-ferial in 2020-2025. EF sanctoral and OF psalm renumbering still pending.
* feat(ef): complete offline EF readings — proper ferias, deuterocanon, ↵Lukasz Kasprzak2026-07-271-1/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Latin fallback Finish the Extraordinary Form (1962) offline Mass readings so every day of the year resolves in both English and Polish. Temporal engine (temporal_ef.go): - Unique ferial slugs "ef-<season>-<week>-<weekday>" so penitential-season weekdays (Lent, Advent, Passiontide, Easter octave) can key their own proper Masses; green-season ferias have no entry and fall back to the preceding Sunday (the 1962 rule). - Special "ef-lent-after-ashes-<weekday>" case for the days between Ash Wednesday and Lent I, which have their own propers. Lectionary (tridentine-lectionary.ini, 55 -> 143 entries) via genlect.go: - Generator now fetches proper-season weekdays and stores a feria only when its Mass differs from the preceding Sunday's. - cleanCite() normalises two missalemeum data glitches: a stray comma between book and chapter ("4 Kings, 5:1" -> "4 Kings 5:1") and a period-as-separator ("John 20. 19-31" -> "John 20:19-31"), both guarded so legitimate multi-chapter citations are untouched. Citations & corpora: - books.ini: Douay abbreviations in the [en] dialect (Ex, Ezech, Jonas, and 3/4 Kings -> canonical 1/2 Kings), so the EF Lenten epistles resolve while the display keeps modern sigla. - drb.tsv: +205 rows backfilling the deuterocanonical Daniel 13-14 (Susanna, Bel) and Esther 11-16 (Greek additions) from get.bible douayrheims, which the base corpus omitted; scripts/gen-deutero.py documents the fetch. Rendering (liturgy.go): - readingLine() falls back to the Latin Vulgate (complete) when the vernacular corpus lacks a passage, with a clear note. Covers the Polish Wujek deuterocanon gap (no clean public-domain source exists) and any future vernacular gap; faithful to the EF as a Latin rite. Result: 730/730 days resolve for both EN (native) and PL (native + Latin fallback for 3 deuterocanon days). Version 0.32.0 -> 0.33.0.
* feat: EF temporal Sunday lectionary (offline Sunday Mass readings)Lukasz Kasprzak2026-07-271-2/+10
| | | | | | | | | Unique temporal-day slugs (season-sunday-week); scripts/genlect.go generates tridentine-lectionary.ini from missalemeum keyed by slug (55 entries: the Sundays of the whole EF year). caldata.TemporalReadings(form,slug) lookup; --liturgy resolves proper-of-feast else the temporal cycle and renders the text. bible.ParseRef strips abbreviation dots (1 Cor. -> 1 Cor). 52/53 Sundays fully resolve offline.
* test(calendar): EF oracle vs missalemeum 2025-2026 (0 season mismatches)Lukasz Kasprzak2026-07-272-0/+4498
| | | | | | temporalEF validated against Divinum Officium data. Season-mapping handles the Whit octave (Paschaltide), the Christmas vigil (Advent), and the resumed Epiphany Sundays (within Time after Pentecost).
* feat(calendar): Compute branches on Form (computeEF via temporalEF/precedenceEF)Lukasz Kasprzak2026-07-272-3/+65
|
* feat(calendar): precedenceEF (1960 occurrence by class + ↵Lukasz Kasprzak2026-07-272-0/+78
| | | | temporal-before-sanctoral)
* feat(calendar): EF (1962) temporal cycle temporalEF + EF seasonsLukasz Kasprzak2026-07-273-9/+192
| | | | | | 8 EF seasons by date boundary (Septuagesima, Passiontide, Time after Epiphany/ Pentecost + shared); major feasts of the Lord; Christ the King = last Sun of October. ParseRank accepts EF ranks.
* refactor(calendar): Rank int enum -> unified string token (OF unchanged, ↵Lukasz Kasprzak2026-07-272-8/+39
| | | | | | | oracle 0 mismatches) Adds EF rank constants (class-1..4, commemoration); ofRankOrder() for the two ordered comparisons; buildCelebration defaults missing rank to ferial.
* feat(cli): --cal-new scaffold + --cal-check lint for custom calendar layersLukasz Kasprzak2026-07-271-1/+8
| | | | Also: reject out-of-range MM-DD in resolveDate (strict validation for user data).
* fix(ini,calendar): full-line-only comments (preserve ';' in citations); drop ↵Lukasz Kasprzak2026-07-271-0/+3
| | | | superseded ferial from Others
* style: gofmt temporal.goLukasz Kasprzak2026-07-271-1/+1
|
* test(calendar): regression oracle vs calapi 2020-2040 (0 season mismatches)Lukasz Kasprzak2026-07-275-5/+7775
| | | | | | Caught + fixed an Advent-start bug: anchor on Christmas Eve, not Dec 25, so years where Dec 25 is a Sunday don't lose the first week of Advent. Rank-class diffs (324) are informational — the initial sanctoral dataset is partial.
* fix(calendar): Christmas solemnity in temporal; feasts of the Lord band 5; ↵Lukasz Kasprzak2026-07-273-4/+40
| | | | Sunday band before solemnity-rank fallback
* feat(calendar): Compute — build celebrations, apply precedence + transfer, ↵Lukasz Kasprzak2026-07-273-2/+216
| | | | | | cycles Also: deterministic pick tiebreak by slug.
* feat(calendar): Universal Norms precedence bands + pickLukasz Kasprzak2026-07-272-0/+107
|
* feat(calendar): ordered-stack layer merge (override/suppress/add)Lukasz Kasprzak2026-07-272-0/+86
|
* feat(calendar): temporal cycle (seasons, Sundays, movable solemnities)Lukasz Kasprzak2026-07-272-0/+294
|
* feat(calendar): DateSpec resolution (fixed + easter/christmas offsets + ↵Lukasz Kasprzak2026-07-272-0/+76
| | | | sunday-after)
* feat(calendar): core types + Gregorian ComputusLukasz Kasprzak2026-07-274-0/+204