aboutsummaryrefslogtreecommitdiff
path: root/cmd/lectio-ef-dump/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/lectio-ef-dump/main.go')
-rw-r--r--cmd/lectio-ef-dump/main.go106
1 files changed, 106 insertions, 0 deletions
diff --git a/cmd/lectio-ef-dump/main.go b/cmd/lectio-ef-dump/main.go
new file mode 100644
index 0000000..08ff547
--- /dev/null
+++ b/cmd/lectio-ef-dump/main.go
@@ -0,0 +1,106 @@
+// 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 <year>` 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 <from-year> <to-year>
+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 <from-year> <to-year>")
+ 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()
+}