//go:build ignore // genlect generates the EF temporal Sunday lectionary from missalemeum // (Divinum Officium data), keyed by lectio's computed temporal-day slug. // One-time; requires network. Run from the repo root: // go run scripts/genlect.go // Writes internal/caldata/tridentine-lectionary.ini. package main import ( "encoding/json" "fmt" "net/http" "os" "regexp" "sort" "strings" "time" "github.com/lukaszkasprzak/lectio/internal/caldata" "github.com/lukaszkasprzak/lectio/internal/calendar" ) var citeRe = regexp.MustCompile(`\*([^*]+)\*`) func fetchCitations(date string) (epistle, gospel string) { resp, err := http.Get("https://www.missalemeum.com/en/api/v5/proper/" + date) if err != nil { return } defer resp.Body.Close() var data []struct { Sections []struct { ID string `json:"id"` Body [][]string `json:"body"` // [[english, latin]] } `json:"sections"` } if json.NewDecoder(resp.Body).Decode(&data) != nil || len(data) == 0 { return } for _, s := range data[0].Sections { if len(s.Body) == 0 || len(s.Body[0]) == 0 { continue } m := citeRe.FindStringSubmatch(s.Body[0][0]) // english text carries *citation* if m == nil { continue } switch s.ID { case "Lectio": epistle = strings.TrimSpace(m[1]) case "Evangelium": gospel = strings.TrimSpace(m[1]) } } return } func main() { sel := calendar.DefaultSelection() sel.Form = "old" layers := []calendar.Layer{caldata.Tridentine()} lect := map[string][2]string{} // slug -> {epistle, gospel} start := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC) end := time.Date(2028, 12, 31, 0, 0, 0, 0, time.UTC) for d := start; !d.After(end); d = d.AddDate(0, 0, 1) { if d.Weekday() != time.Sunday { continue } day := calendar.Compute(d, sel, layers) if day.Observed.Layer != "temporal" { // a feast won that Sunday -> its own propers continue } slug := day.Observed.Slug if _, ok := lect[slug]; ok { continue // one instance per slug } ep, gos := fetchCitations(d.Format("2006-01-02")) if ep == "" && gos == "" { continue } lect[slug] = [2]string{ep, gos} fmt.Fprintf(os.Stderr, "%s %-34s ep=%-22s go=%s\n", d.Format("2006-01-02"), slug, ep, gos) } slugs := make([]string, 0, len(lect)) for s := range lect { slugs = append(slugs, s) } sort.Strings(slugs) var b strings.Builder b.WriteString("; EF (1962) temporal lectionary, keyed by lectio's computed temporal-day slug.\n") b.WriteString("; Generated from missalemeum (Divinum Officium). Epistle (first) + Gospel citations.\n") for _, s := range slugs { v := lect[s] fmt.Fprintf(&b, "\n[%s]\n", s) if v[0] != "" { fmt.Fprintf(&b, "first = %s\n", v[0]) } if v[1] != "" { fmt.Fprintf(&b, "gospel = %s\n", v[1]) } } if err := os.WriteFile("internal/caldata/tridentine-lectionary.ini", []byte(b.String()), 0o644); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } fmt.Fprintf(os.Stderr, "wrote %d temporal entries\n", len(lect)) }