aboutsummaryrefslogtreecommitdiff
path: root/internal/caldata
diff options
context:
space:
mode:
Diffstat (limited to 'internal/caldata')
-rw-r--r--internal/caldata/caldata_test.go45
-rw-r--r--internal/caldata/readings.go43
2 files changed, 88 insertions, 0 deletions
diff --git a/internal/caldata/caldata_test.go b/internal/caldata/caldata_test.go
index f993a12..2a13d3d 100644
--- a/internal/caldata/caldata_test.go
+++ b/internal/caldata/caldata_test.go
@@ -521,3 +521,48 @@ func TestEFBVMSaturdayReadings(t *testing.T) {
t.Errorf("2026-04-18: gospel = %q, want %q (the Paschaltide formulary)", gospel, "John 19:25-27")
}
}
+
+// TestEFNativityOctaveWeekdayMass pins the Mass of a WEEKDAY within the Octave
+// of the Nativity, and the Sunday it must not swallow.
+//
+// The Missal gives 29-31 December a direct formulary, "Diebus infra octavam
+// Nativitatis Domini, II classis" -- Titus 3:4-7 / Luke 2:15-20 -- and names
+// them in the calendarium ("De V die infra octavam ... II classis"). Treated
+// as ordinary ferias they fell back to the preceding Sunday and served
+// "Dominica infra octavam" (Gal 4:1-7 / Luke 2:33-40), which is a different
+// heading for a different day.
+//
+// The Sunday case is asserted too, because it is the one the wrong citation
+// blurred: when 29-31 December IS a Sunday the day really is "Dominica infra
+// octavam" and keeps that Mass. A fix that applied the weekday formulary by
+// date alone would pass the first half of this test and fail the second.
+func TestEFNativityOctaveWeekdayMass(t *testing.T) {
+ sel := calendar.Selection{Form: "old"}
+ layers := []calendar.Layer{Tridentine()}
+ get := func(date string) (string, string) {
+ day, _ := time.Parse("2006-01-02", date)
+ var first, gospel string
+ for _, r := range Readings(sel, layers, day, calendar.Compute(day, sel, layers)) {
+ switch r.Part {
+ case "first":
+ first = r.Citation
+ case "gospel":
+ gospel = r.Citation
+ }
+ }
+ return first, gospel
+ }
+ // 2026: 29-31 December are Tuesday, Wednesday, Thursday -- weekdays.
+ for _, date := range []string{"2026-12-29", "2026-12-30", "2026-12-31"} {
+ if f, g := get(date); f != "Titus 3:4-7" || g != "Luke 2:15-20" {
+ t.Errorf("%s: got %q / %q, want Titus 3:4-7 / Luke 2:15-20 "+
+ "(Diebus infra octavam Nativitatis Domini)", date, f, g)
+ }
+ }
+ // 2030: 29 December is a SUNDAY, so it is Dominica infra octavam and keeps
+ // the Sunday's own Mass.
+ if f, g := get("2030-12-29"); f != "Gal 4:1-7" || g != "Luke 2:33-40" {
+ t.Errorf("2030-12-29 (a Sunday): got %q / %q, want Gal 4:1-7 / Luke 2:33-40 "+
+ "-- the weekday formulary must not swallow Dominica infra octavam", f, g)
+ }
+}
diff --git a/internal/caldata/readings.go b/internal/caldata/readings.go
index 62ef1fc..44d1bc1 100644
--- a/internal/caldata/readings.go
+++ b/internal/caldata/readings.go
@@ -60,6 +60,9 @@ func Readings(sel calendar.Selection, layers []calendar.Layer, date time.Time, d
if r := efBVMSaturdayReadings(day); len(r) > 0 {
return r
}
+ if r := efNativityOctaveReadings(day); len(r) > 0 {
+ return r
+ }
if r := TemporalReadings("old", day.Observed.Slug); len(r) > 0 {
return r
}
@@ -145,3 +148,43 @@ func efBVMSaturdayReadings(day calendar.LiturgicalDay) []calendar.Reading {
{Part: "gospel", Citation: gospel},
}
}
+
+// efNativityOctaveReadings returns the Mass of a WEEKDAY within the Octave of
+// the Nativity -- 29, 30 and 31 December.
+//
+// The Missal gives those days a direct formulary, "Diebus infra octavam
+// Nativitatis Domini, II classis": Titus 3:4-7 / Luke 2:15-20, and each date's
+// own rubric points at it ("Die 29 decembris ... Missa Puer natus est nobis,
+// ut supra", repeated verbatim on the 30th and 31st). They are named days in
+// the calendarium too -- "De V die infra octavam Nativitatis Domini, II
+// classis" and so on -- not ordinary ferias.
+//
+// lectio treated them as ordinary Christmas ferias, so they fell back to the
+// preceding Sunday and served "Dominica infra octavam Nativitatis Domini"
+// (Gal 4:1-7 / Luke 2:33-40). That is a DIFFERENT heading, for the Sunday
+// specifically. colitur made the identical mistake once, measured it against
+// real years and reverted it; its bootstrap_lectionary.ml records the
+// rejection so it is not re-attempted, with the scan references for both.
+//
+// Only the WEEKDAYS. When 29-31 December falls on a Sunday the day really is
+// "Dominica infra octavam" and keeps the Sunday's Mass, which is the
+// distinction the wrong citation blurred -- so the Sunday is excluded here
+// rather than merely happening not to match.
+func efNativityOctaveReadings(day calendar.LiturgicalDay) []calendar.Reading {
+ if day.Date.Month() != time.December || day.Date.Day() < 29 {
+ return nil
+ }
+ if day.Weekday == time.Sunday {
+ return nil
+ }
+ // The day within the octave, not a feast that outranks it: the observed
+ // office must still be the temporal one. A sanctoral feast keeps its own
+ // readings, as it did before this.
+ if !strings.HasPrefix(day.Observed.Slug, "ef-christmas-") {
+ return nil
+ }
+ return []calendar.Reading{
+ {Part: "first", Citation: "Titus 3:4-7"},
+ {Part: "gospel", Citation: "Luke 2:15-20"},
+ }
+}