1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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()
}
|