summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-07-27 23:27:07 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-07-27 23:27:07 +0200
commit4a35093c4358be17da6f0f374197caed743bda26 (patch)
treed0b4298cae6738632437923a64fda0463efbe658
parent5d765444f315ee512c5ceb9bcf83730be8112b60 (diff)
downloadlectio-4a35093c4358be17da6f0f374197caed743bda26.tar.gz
lectio-4a35093c4358be17da6f0f374197caed743bda26.zip
feat(caldata): OF Sunday/solemnity readings by slug+cycle (seed table)
-rw-r--r--internal/caldata/caldata.go10
-rw-r--r--internal/caldata/of-lectionary.ini15
-rw-r--r--internal/caldata/of_test.go38
-rw-r--r--internal/caldata/readings.go7
4 files changed, 67 insertions, 3 deletions
diff --git a/internal/caldata/caldata.go b/internal/caldata/caldata.go
index 92f9327..9c17035 100644
--- a/internal/caldata/caldata.go
+++ b/internal/caldata/caldata.go
@@ -25,6 +25,12 @@ var tridentineLectionary []byte
// efTempReadings maps an EF temporal-day slug to its readings (parsed once).
var efTempReadings = parseLectionary(tridentineLectionary)
+//go:embed of-lectionary.ini
+var ofLectionary []byte
+
+// ofTempReadings maps an OF <slug>-<cycle> key to its readings (parsed once).
+var ofTempReadings = parseLectionary(ofLectionary)
+
func parseLectionary(data []byte) map[string][]calendar.Reading {
l, err := ParseLayer(data)
if err != nil {
@@ -44,12 +50,12 @@ func parseLectionary(data []byte) map[string][]calendar.Reading {
}
// TemporalReadings returns the temporal-cycle readings for a computed day slug,
-// or nil. Only the EF ("old") temporal lectionary exists so far.
+// or nil. EF ("old") looks up efTempReadings; OF looks up ofTempReadings.
func TemporalReadings(form, slug string) []calendar.Reading {
if form == "old" {
return efTempReadings[slug]
}
- return nil
+ return ofTempReadings[slug]
}
// Universal parses the embedded Ordinary Form universal calendar. It panics on a
diff --git a/internal/caldata/of-lectionary.ini b/internal/caldata/of-lectionary.ini
new file mode 100644
index 0000000..b9f4772
--- /dev/null
+++ b/internal/caldata/of-lectionary.ini
@@ -0,0 +1,15 @@
+; OF (Ordinary Form) Sunday & solemnity lectionary, keyed by
+; <computed-temporal-slug>-<SundayCycle>. Citations English-canonical.
+; SEED — replaced by scripts/genlect-of.go (niedziela, 2025-2027).
+
+[easter-sunday-A]
+first = Acts 10:34,37-43
+psalm = Ps 118:1-2,16-17,22-23
+second = Col 3:1-4
+gospel = John 20:1-9
+
+[christ-the-king-A]
+first = Ezek 34:11-12,15-17
+psalm = Ps 23:1-2,2-3,5-6
+second = 1 Cor 15:20-26,28
+gospel = Matt 25:31-46
diff --git a/internal/caldata/of_test.go b/internal/caldata/of_test.go
new file mode 100644
index 0000000..7bc2ce1
--- /dev/null
+++ b/internal/caldata/of_test.go
@@ -0,0 +1,38 @@
+package caldata
+
+import (
+ "testing"
+ "time"
+
+ "github.com/lukaszkasprzak/lectio/internal/calendar"
+)
+
+func TestOFReadingsByCycle(t *testing.T) {
+ // A synthetic OF day keyed christ-the-king-A must resolve to Matt 25.
+ day := calendar.LiturgicalDay{
+ Observed: calendar.Celebration{Slug: "christ-the-king", Layer: "temporal"},
+ SundayCycle: "A",
+ Weekday: time.Sunday,
+ }
+ sel := calendar.Selection{Form: "new"}
+ rs := Readings(sel, nil, time.Date(2026, 11, 22, 0, 0, 0, 0, time.UTC), day)
+ var gospel string
+ for _, r := range rs {
+ if r.Part == "gospel" {
+ gospel = r.Citation
+ }
+ }
+ if gospel == "" || gospel[:4] != "Matt" {
+ t.Fatalf("christ-the-king-A gospel = %q, want Matt…", gospel)
+ }
+}
+
+func TestOFWeekdayEmpty(t *testing.T) {
+ day := calendar.LiturgicalDay{
+ Observed: calendar.Celebration{Slug: "ordinary-weekday", Layer: "temporal"},
+ Weekday: time.Wednesday, // no SundayCycle key -> deferred phase -> empty
+ }
+ if rs := Readings(calendar.Selection{Form: "new"}, nil, time.Now().UTC(), day); len(rs) != 0 {
+ t.Fatalf("weekday should be empty, got %v", rs)
+ }
+}
diff --git a/internal/caldata/readings.go b/internal/caldata/readings.go
index a11235d..2810026 100644
--- a/internal/caldata/readings.go
+++ b/internal/caldata/readings.go
@@ -19,7 +19,12 @@ func Readings(sel calendar.Selection, layers []calendar.Layer, date time.Time, d
if len(rs) > 0 {
return rs
}
- if r := TemporalReadings(sel.Form, day.Observed.Slug); len(r) > 0 {
+ // temporal table: EF by slug, OF by slug+cycle.
+ key := day.Observed.Slug
+ if sel.Form != "old" && day.SundayCycle != "" {
+ key = day.Observed.Slug + "-" + day.SundayCycle
+ }
+ if r := TemporalReadings(sel.Form, key); len(r) > 0 {
return r
}
if sel.Form == "old" && day.Observed.Layer == "temporal" && date.Weekday() != time.Sunday {