// 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): // // YYYY-MM-DD weekday season week slug rank colour name_en name_pl [+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 // "_" so the line stays whitespace-delimited; "-" where the name is empty // (a bare feria with no proper name). Added after a regeneration of // internal/caldata/tridentine-calendar.ini once deleted all 322 Polish // names (name.pl 322 -> 0) with nothing in this repository's test suite OR // this dumper noticing: the season/rank/colour columns this tool already // printed were all still correct, since name is a wholly separate field // naming.CelebrationName reads independently. This dumper is what the // task's own before/after diff verification is run against, so it needed // to be structurally capable of seeing a name regression, not just told to // look harder next time. // // 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 // comparator's job, not this dumper's; translating here would hide real // divergences behind an already-reconciled view. // // The trailing "+other-slug" tokens are lectio's Others: the sanctoral // candidates that lost the day's precedence contest. lectio has no RG 111 // commemoration-admission logic, so this is the set of losing candidates, not // the set of admitted commemorations -- the two are different things. See the // task report for detail; the comparator does not diff this column. // // Usage: lectio-ef-dump package main import ( "bufio" "fmt" "io" "os" "strconv" "strings" "time" "github.com/lukaszkasprzak/lectio/internal/caldata" "github.com/lukaszkasprzak/lectio/internal/calendar" ) func main() { os.Exit(run(os.Args[1:], os.Stdout, os.Stderr)) } // run is lectio-ef-dump's testable entry point: parse args, compute, and // write. Returns a process exit code (0 ok, 1 runtime error, 2 usage error). func run(args []string, stdout, stderr io.Writer) int { if len(args) != 2 { fmt.Fprintln(stderr, "usage: lectio-ef-dump ") return 2 } from, errFrom := strconv.Atoi(args[0]) to, errTo := strconv.Atoi(args[1]) if errFrom != nil || errTo != nil { fmt.Fprintln(stderr, "lectio-ef-dump: from-year and to-year must be integers") return 2 } if from > to { fmt.Fprintf(stderr, "lectio-ef-dump: from-year %d is after to-year %d\n", from, to) return 2 } sel := calendar.DefaultSelection() sel.Form = "old" layers := []calendar.Layer{caldata.Tridentine()} w := bufio.NewWriter(stdout) for y := from; y <= to; y++ { start := time.Date(y, time.January, 1, 0, 0, 0, 0, time.UTC) 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 { fmt.Fprintf(stderr, "lectio-ef-dump: %v\n", err) return 1 } } } if err := w.Flush(); err != nil { fmt.Fprintf(stderr, "lectio-ef-dump: %v\n", err) return 1 } 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 { if s == "" { return "-" } return strings.ReplaceAll(s, " ", "_") } // 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 { 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", day.Date.Format("2006-01-02"), strings.ToLower(day.Weekday.String()), string(day.Season), week, day.Observed.Slug, string(day.Observed.Rank), string(day.Colour), dumpName(day.Observed.Name["en"]), dumpName(day.Observed.Name["pl"]), ) for _, o := range day.Others { fmt.Fprintf(&b, " +%s", o.Slug) } b.WriteByte('\n') return b.String() }