// Command lectio-ef-dump prints lectio's Extraordinary Form (1962) calendar, // one line per day, for use as colitur's differential oracle. // // Output format matches colitur's `colitur day ` line for line (see // colitur's bin/main.ml, day_line), so the two streams are diffable directly: // // YYYY-MM-DD weekday season week slug rank colour [+other-slug]... // // 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 } // dumpLine renders one LiturgicalDay as a colitur-format line. 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", 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), ) for _, o := range day.Others { fmt.Fprintf(&b, " +%s", o.Slug) } b.WriteByte('\n') return b.String() }