diff options
Diffstat (limited to 'scripts/gen-sanctoral-ef.go')
| -rw-r--r-- | scripts/gen-sanctoral-ef.go | 107 |
1 files changed, 102 insertions, 5 deletions
diff --git a/scripts/gen-sanctoral-ef.go b/scripts/gen-sanctoral-ef.go index 34bd184..ba4d9ce 100644 --- a/scripts/gen-sanctoral-ef.go +++ b/scripts/gen-sanctoral-ef.go @@ -11,10 +11,12 @@ // [vigil-of-st-lawrence] colour red -> violet // [vigil-of-the-assumption] colour white -> violet // -// missalemeum does not carry them, so RUNNING THIS GENERATOR WILL SILENTLY -// REVERT ALL FOUR. Re-apply them before committing regenerated output, or -// teach this program to. The ini file's own header repeats this list and the -// rubrics behind it, so neither place can rot without the other showing it. +// missalemeum does not carry them. This generator RE-APPLIES all four on every +// run, from the missalOverrides table below, and fails rather than warns if +// one names a slug this run did not harvest -- so a rename upstream stops the +// build instead of quietly dropping a correction. Change the table, not the +// generated file. internal/caldata's TestTridentineMissalOverrides pins the +// same four values from the other side, so neither can rot alone. // // gen-sanctoral-ef generates the EF (Extraordinary Form, 1962) universal // sanctoral (internal/caldata/tridentine-calendar.ini) from missalemeum's @@ -292,6 +294,80 @@ func fetch(date string) (*mmDay, error) { return nil, err } +// missalOverride is a field where the 1962 MISSALE ROMANUM ITSELF decides +// against missalemeum, and the Missal wins. Applied after harvesting, just +// before the file is written. +// +// Why an explicit table rather than "preserve whatever the existing file had" +// -- which is how otherNames below works, and would have been less code. +// Preserving from the file cannot tell a deliberate correction from simple +// staleness: if missalemeum ever fixes one of these, a preserve-from-file rule +// would keep overriding it forever and nobody would notice. Naming each +// override with its authority says what we mean, and makes an obsolete one +// findable by re-reading four lines rather than by diffing a calendar. +// +// Each was found by the sibling project colitur, which validates this data +// against the Missal and its Rubricae Generales rather than against another +// calendar program. See its docs/research/rules-register.md sections 6.24 and +// 6.25 for the full account, and internal/calendar/oracle_ef_test.go for the +// allow-list entries these four require, six days of its 730-day window. +type missalOverride struct { + slug string + field string // "rank" or "colour" + want string + why string +} + +var missalOverrides = []missalOverride{ + {"ubaldus", "rank", "class-3", + `Missal calendarium: "S. Ubaldi Ep. et Conf., III classis" (16 May), no ` + + `commemoration rubric, and a Mass entry of its own in the Proprium ` + + `taking its readings from a Common -- which a bare commemoration never has`}, + {"didacus", "rank", "class-3", + `Missal calendarium: "S. Didaci Conf., III classis" (13 Nov), same shape ` + + `as ubaldus above`}, + {"vigil-of-st-lawrence", "colour", "violet", + `RG 128: violet for vigils of II and III class outside Paschaltide. ` + + `9 August is a III-class vigil outside Paschaltide`}, + {"vigil-of-the-assumption", "colour", "violet", + `RG 128, same rule; 14 August is a II-class vigil outside Paschaltide. ` + + `The rule's sole exception is the Ascension's vigil, INSIDE Paschaltide, ` + + `which is white and is deliberately not listed here`}, +} + +// applyMissalOverrides rewrites the harvested entries in place and reports +// what it did. It FAILS rather than warns when an override names a slug that +// is not present: a rename upstream would otherwise drop a correction +// silently, which is the exact failure this table exists to prevent. +func applyMissalOverrides(entries map[string]entry) error { + for _, o := range missalOverrides { + e, ok := entries[o.slug] + if !ok { + return fmt.Errorf("missal override names [%s], which this run did not "+ + "harvest -- has the slug changed upstream? Fix the override or the "+ + "generator; do NOT delete it silently. Reason on record: %s", o.slug, o.why) + } + var had string + switch o.field { + case "rank": + had, e.rank = string(e.rank), calendar.Rank(o.want) + case "colour": + had, e.colour = e.colour, o.want + default: + return fmt.Errorf("missal override for [%s]: unknown field %q", o.slug, o.field) + } + entries[o.slug] = e + if had == o.want { + fmt.Fprintf(os.Stderr, "\nmissal override [%s] %s: already %s upstream -- "+ + "missalemeum may have fixed this; consider retiring the override\n", + o.slug, o.field, o.want) + } else { + fmt.Fprintf(os.Stderr, "\nmissal override [%s] %s: %s -> %s\n", o.slug, o.field, had, o.want) + } + } + return nil +} + type entry struct { slug, date, colour, class, en, first, gospel string rank calendar.Rank @@ -742,6 +818,16 @@ func main() { } } + // The Missal overrides missalemeum on four fields -- see missalOverrides + // above for each one's authority. Applied HERE, after every harvest and + // collision fix-up has settled and before anything is written, so that the + // value the Missal requires is the last word rather than something a later + // pass could overwrite. + if err := applyMissalOverrides(entries); err != nil { + fmt.Fprintf(os.Stderr, "\n%v\n", err) + os.Exit(1) + } + es := make([]entry, 0, len(entries)) for _, e := range entries { e.otherNames = preservedNames[e.slug] @@ -763,7 +849,18 @@ func main() { b.WriteString("; Generated by scripts/gen-sanctoral-ef.go from missalemeum (Divinum Officium 1962\n") b.WriteString("; data). name.en is always regenerated fresh from missalemeum; every other\n") b.WriteString("; name.<lang> (missalemeum supplies English only) is preserved verbatim from\n") - b.WriteString("; whatever this file already carried before regeneration. See NOTICE.\n\n") + b.WriteString("; whatever this file already carried before regeneration. See NOTICE.\n") + b.WriteString(";\n") + b.WriteString("; FOUR FIELDS ARE NOT FROM missalemeum. They are corrections against the 1962\n") + b.WriteString("; Missale Romanum itself, which missalemeum does not carry, re-applied on every\n") + b.WriteString("; run by this generator's own missalOverrides table (see its comment for the\n") + b.WriteString("; authority behind each). Regenerating this file is therefore SAFE and will\n") + b.WriteString("; not revert them; editing them here by hand is not, because the next run\n") + b.WriteString("; puts them back. Change the table instead.\n") + for _, o := range missalOverrides { + fmt.Fprintf(&b, "; [%s] %s = %s\n", o.slug, o.field, o.want) + } + b.WriteString("\n") b.WriteString("[layer]\nid = tridentine\nname = General Roman Calendar of 1962\ntype = universal\n") for _, e := range es { fmt.Fprintf(&b, "\n[%s]\ndate = %s\nrank = %s\ncolour = %s\n", e.slug, e.date, e.rank, e.colour) |
