From 3ad70f087f30075e6414d85195a5ca037e14f627 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Sat, 15 Aug 2026 02:07:29 +0200 Subject: lectio-ef-dump: emit the Epistle and Gospel citations colitur's differential compares reading citations from this release onward, and needs them per day rather than per lectionary key -- this engine resolves a feria to the preceding Sunday's Mass itself, which is exactly the behaviour the differential has to check. --- cmd/lectio-ef-dump/main.go | 72 +++++++++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 20 deletions(-) (limited to 'cmd/lectio-ef-dump') diff --git a/cmd/lectio-ef-dump/main.go b/cmd/lectio-ef-dump/main.go index e7d014a..73c3ea9 100644 --- a/cmd/lectio-ef-dump/main.go +++ b/cmd/lectio-ef-dump/main.go @@ -1,12 +1,11 @@ // Command lectio-ef-dump prints lectio's Extraordinary Form (1962) calendar, // one line per day, for use as colitur's differential oracle. // -// Output format is colitur's `colitur day ` line, PLUS two display-name -// columns colitur's own line does not carry (so a straight `diff` against -// colitur's output must ignore trailing fields, not compare them line for -// line): +// Output format is colitur's `colitur day ` line, PLUS four columns +// colitur's own line does not carry (so a straight `diff` against colitur's +// output must ignore trailing fields, not compare them line for line): // -// YYYY-MM-DD weekday season week slug rank colour name_en name_pl [+other-slug]... +// YYYY-MM-DD weekday season week slug rank colour name_en name_pl first gospel [+other-slug]... // // name_en and name_pl are the observed celebration's own display name in // English and Polish (Celebration.Name["en"]/["pl"]), spaces replaced with @@ -21,6 +20,20 @@ // to be structurally capable of seeing a name regression, not just told to // look harder next time. // +// first and gospel are the Epistle/Lesson and Gospel citations RESOLVED for +// the day (Reading.Part "first"/"gospel"), not a raw lectionary-table lookup +// keyed by slug: they come from caldata.Readings, the same function the CLI +// and calfeed use, which applies the day's own inline propers first and +// falls back to the 1962 rule that a green-season weekday with no proper +// Mass repeats the PRECEDING SUNDAY's Mass (via calendar.TemporalSlug, which +// still finds that Sunday's temporal identity even when a feast displaced it +// as the observed celebration). That fallback is exactly why this column is +// worth comparing: colitur implements the same rubric independently, so this +// checks two implementations against each other rather than one against +// silence. Spaces become "_" (dumpField, shared with name_en/name_pl); "-" +// where the day has no such reading (e.g. no epistle/gospel citation at +// all, or the Mass proper does not carry that part). +// // Every column carries lectio's OWN vocabulary (season names, slugs, rank and // colour spellings) -- this dumper does not translate lectio's values into // colitur's. The mapping between the two vocabularies is the differential @@ -81,7 +94,8 @@ func run(args []string, stdout, stderr io.Writer) int { end := time.Date(y, time.December, 31, 0, 0, 0, 0, time.UTC) for d := start; !d.After(end); d = d.AddDate(0, 0, 1) { day := calendar.Compute(d, sel, layers) - if _, err := w.WriteString(dumpLine(day)); err != nil { + rs := caldata.Readings(sel, layers, d, day) + if _, err := w.WriteString(dumpLine(day, rs)); err != nil { fmt.Fprintf(stderr, "lectio-ef-dump: %v\n", err) return 1 } @@ -94,30 +108,46 @@ func run(args []string, stdout, stderr io.Writer) int { return 0 } -// dumpName renders a display-name field: spaces become "_" so the line stays -// whitespace-delimited (names routinely contain spaces, e.g. "St. Thomas -// Becket", "Wniebowzięcie N. M. P."); "-" for an empty name, matching the -// week column's own convention for "absent". -func dumpName(s string) string { +// dumpField renders a whitespace-delimited field: spaces become "_" (values +// routinely contain spaces, e.g. the name "St. Thomas Becket" or the citation +// "Rom 13:11-14"); "-" for an empty value, matching the week column's own +// convention for "absent". Shared by the name_en/name_pl columns and the +// first/gospel reading-citation columns. +func dumpField(s string) string { if s == "" { return "-" } return strings.ReplaceAll(s, " ", "_") } +// citationFor returns the citation of the first reading of the given Part +// ("first" or "gospel") among rs, or "" if rs carries none. +func citationFor(rs []calendar.Reading, part string) string { + for _, r := range rs { + if r.Part == part { + return r.Citation + } + } + return "" +} + // dumpLine renders one LiturgicalDay as a colitur-format line, plus the -// name_en/name_pl columns colitur's own line does not carry (see this -// package's doc comment). Week is lectio's own int (0 where no season week -// applies, e.g. named I class feasts and per annum green-season ferias); -// printed as "-" there so the field count stays fixed, matching colitur's -// own convention for an absent week. -func dumpLine(day calendar.LiturgicalDay) string { +// name_en/name_pl/first/gospel columns colitur's own line does not carry +// (see this package's doc comment). rs is the day's RESOLVED readings +// (caldata.Readings' result), not day.Observed.Masses directly: for a +// green-season weekday that repeats the preceding Sunday's Mass, +// day.Observed carries the temporal celebration's own (proper-less) Masses, +// and only caldata.Readings applies that fallback. Week is lectio's own int +// (0 where no season week applies, e.g. named I class feasts and per annum +// green-season ferias); printed as "-" there so the field count stays fixed, +// matching colitur's own convention for an absent week. +func dumpLine(day calendar.LiturgicalDay, rs []calendar.Reading) string { week := "-" if day.Week != 0 { week = strconv.Itoa(day.Week) } var b strings.Builder - fmt.Fprintf(&b, "%s %s %s %s %s %s %s %s %s", + fmt.Fprintf(&b, "%s %s %s %s %s %s %s %s %s %s %s", day.Date.Format("2006-01-02"), strings.ToLower(day.Weekday.String()), string(day.Season), @@ -125,8 +155,10 @@ func dumpLine(day calendar.LiturgicalDay) string { day.Observed.Slug, string(day.Observed.Rank), string(day.Colour), - dumpName(day.Observed.Name["en"]), - dumpName(day.Observed.Name["pl"]), + dumpField(day.Observed.Name["en"]), + dumpField(day.Observed.Name["pl"]), + dumpField(citationFor(rs, "first")), + dumpField(citationFor(rs, "gospel")), ) for _, o := range day.Others { fmt.Fprintf(&b, " +%s", o.Slug) -- cgit v1.3