ec448bc35b
Deploy / deploy (push) Successful in 38s
Ordo is Monastic 1617 as a base, with deliberate Tridentine 1906 additions: the "In manus tuas" short responsory, the Nunc Dimittis with its "Salva nos" antiphon, the fuller Preces (Monastic's own is shorter), and Lent's "Christe, qui lux es et dies" hymn replacement (English translation marked draft, pending a real historical one). Psalms 4, 90, 133 are fixed daily with real verified text, unlike Prime's weekday-rotated psalms. The closing Marian antiphon now picks Alma Redemptoris Mater / Ave Regina Caelorum / Regina Caeli / Salve Regina by real season, using the calendar work from the previous commit — except Ave Regina Caelorum's own window (Candlemas through the day before Maundy Thursday) doesn't align to any single season value, so that one case checks the real date directly instead of going through the by-season table. resolve-common.ts extracts the resolve/status/doxology/antiphon helpers Prime already had into something Compline can share; a few propers files lose their "prime-" prefix now that both hours use them.
52 lines
2.4 KiB
TypeScript
52 lines
2.4 KiB
TypeScript
import type { LiturgicalDay } from '../calendar/types';
|
|
import { easterSunday } from '../calendar/easter';
|
|
import { addDays, toIsoDate } from '../calendar/date-math';
|
|
import { resolveSeasonalPropersId } from './seasonal-propers';
|
|
import bySeasonData from '../data/hours/marian-antiphon-by-season.yml';
|
|
|
|
const bySeason = bySeasonData as { perAnnum: string; bySeason: Record<string, string> };
|
|
|
|
const AVE_REGINA_CAELORUM_ID = 'marian-antiphon-ave-regina-caelorum';
|
|
|
|
/**
|
|
* Ave Regina Caelorum's real window (Candlemas through Wednesday of Holy
|
|
* Week) doesn't line up with any of the mutually-exclusive `season` values
|
|
* the rest of the app uses (it starts mid-Epiphanytide and ends mid-Lent
|
|
* or mid-Passiontide, depending on the year) — see calendar/types.ts's
|
|
* Season doc comment for the general overlapping-windows problem this is
|
|
* one instance of. Rather than force `season` to represent it, this checks
|
|
* the real date directly, bypassing the by-season table for this one case.
|
|
* The Triduum (Maundy Thursday through Holy Saturday) that follows isn't
|
|
* specially handled — it falls through to whatever `season` resolves to
|
|
* there (currently 'passiontide', not a key in marian-antiphon-by-season's
|
|
* bySeason table, so it lands on the perAnnum default), which is a known,
|
|
* separate gap, not something this fix claims to solve.
|
|
*/
|
|
function isCandlemasToHolyWednesday(isoDate: string): boolean {
|
|
const year = Number(isoDate.slice(0, 4));
|
|
const candlemas = `${year}-02-02`;
|
|
const maundyThursday = addDays(toIsoDate(easterSunday(year)), -3);
|
|
return isoDate >= candlemas && isoDate < maundyThursday;
|
|
}
|
|
|
|
/** Resolves the common-propers id for Compline's closing Marian antiphon. */
|
|
export function getMarianAntiphonId(day: LiturgicalDay): string {
|
|
if (isCandlemasToHolyWednesday(day.date)) {
|
|
return AVE_REGINA_CAELORUM_ID;
|
|
}
|
|
return resolveSeasonalPropersId(day.season, day.occurring, bySeason);
|
|
}
|
|
|
|
const LABELS: Record<string, string> = {
|
|
'marian-antiphon-alma-redemptoris-advent': 'Alma Redemptoris Mater',
|
|
'marian-antiphon-alma-redemptoris-nativity': 'Alma Redemptoris Mater',
|
|
'marian-antiphon-ave-regina-caelorum': 'Ave Regina Caelorum',
|
|
'marian-antiphon-regina-caeli': 'Regina Caeli',
|
|
'marian-antiphon-salve-regina': 'Salve Regina',
|
|
};
|
|
|
|
/** The real, singable name of whichever antiphon getMarianAntiphonId picked. */
|
|
export function getMarianAntiphonLabel(id: string): string {
|
|
return LABELS[id] ?? 'Marian Antiphon';
|
|
}
|