Render octave commemorations in getDayCollects on stacking days
getDayCollects previously dropped kind: 'octave' commemorations entirely, so on days where the temporal office keeps its own standing (the Christmas Octave's own Nativity/Stephen/John/Holy-Innocents stack, e.g. Dec 30) those octaves contributed nothing but a name in the day label. Add an octave branch, gated on temporalCategory !== 'ordinary- feria' -- the same condition resolveOfficeWinner uses -- so an ordinary octave day's already-substituted primary content never gets a redundant repeat.
This commit is contained in:
@@ -462,6 +462,22 @@ function sanctoralCommemorationPart(commemoration: Extract<Commemoration, { kind
|
||||
return { kind: 'preces', text: { text: {}, status: { la: 'missing', en: 'missing' } }, label };
|
||||
}
|
||||
|
||||
/** An octave commemoration's own rendering — the fuller "Commemoratio
|
||||
* Octavæ ..." Ant+V/R+collect bundle (`${id}-octave-commemoration`, e.g.
|
||||
* christmas-day-octave-commemoration.yml), same shape and fallback
|
||||
* pattern as sanctoralCommemorationPart. No per-saint `propers`
|
||||
* indirection needed: an octave commemoration's id already is the base
|
||||
* feast/saint id (`christmas-day`, `st-stephen-protomartyr`, ...),
|
||||
* matching the proper file's own id 1:1. */
|
||||
function octaveCommemorationPart(commemoration: Extract<Commemoration, { kind: 'octave' }>): ResolvedPart {
|
||||
const label = `Commemoration of the Octave of ${commemoration.name}`;
|
||||
const combined = resolveCommon(`${commemoration.id}-octave-commemoration`);
|
||||
if (combined.status.la !== 'missing' || combined.status.en !== 'missing') {
|
||||
return { kind: 'preces', text: combined, label };
|
||||
}
|
||||
return { kind: 'preces', text: { text: {}, status: { la: 'missing', en: 'missing' } }, label };
|
||||
}
|
||||
|
||||
/**
|
||||
* The day's own collect, plus one more per commemoration (calendar/
|
||||
* types.ts's LiturgicalDay.commemorations) — Lauds/Vespers say all of
|
||||
@@ -475,10 +491,22 @@ function sanctoralCommemorationPart(commemoration: Extract<Commemoration, { kind
|
||||
* Amen." for the single-collect case every other hour uses today, and
|
||||
* stripping that back out per-collect to chain them properly would need
|
||||
* text surgery this doesn't attempt — so on a commemorated day, each
|
||||
* collect here renders as its own complete, separate block instead. An
|
||||
* octave commemoration never contributes anything of its own here — once
|
||||
* resolveOfficeWinner is in play, its content is already the primary
|
||||
* collect above, so a separate entry would just be a redundant repeat.
|
||||
* collect here renders as its own complete, separate block instead.
|
||||
*
|
||||
* An octave commemoration only renders its own block here when
|
||||
* `day.temporalCategory !== 'ordinary-feria'` — the same gate
|
||||
* resolveOfficeWinner uses (see its own doc comment). On an *ordinary*
|
||||
* octave day (e.g. an in-between day of St. Lawrence's own octave),
|
||||
* resolveOfficeWinner has already substituted that octave's content as
|
||||
* the primary collect above, so rendering it again here would be a
|
||||
* redundant repeat (or worse, an honestly-"missing" duplicate for the
|
||||
* many octaves without their own `-octave-commemoration.yml` authored).
|
||||
* On a day the temporal identity itself keeps real standing (the
|
||||
* Christmas Octave's own stacking days, e.g. Dec 26-31, where Christmas
|
||||
* + Stephen + John + Holy Innocents are each merely commemorated
|
||||
* alongside the day's own temporal office), resolveOfficeWinner does
|
||||
* *not* touch the primary collect at all, so this is the only place
|
||||
* these four octaves' real "Commemoratio Octavæ ..." content surfaces.
|
||||
*/
|
||||
export function getDayCollects(day: LiturgicalDay): ResolvedPart[] {
|
||||
const parts: ResolvedPart[] = [{ kind: 'prayer', text: getDayCollect(day) }];
|
||||
@@ -487,6 +515,8 @@ export function getDayCollects(day: LiturgicalDay): ResolvedPart[] {
|
||||
parts.push({ kind: 'prayer', text: toResolvedText(getTemporalProper(`${commemoration.id}-collect`)) });
|
||||
} else if (commemoration.kind === 'sanctoral') {
|
||||
parts.push(sanctoralCommemorationPart(commemoration));
|
||||
} else if (commemoration.kind === 'octave' && day.temporalCategory !== 'ordinary-feria') {
|
||||
parts.push(octaveCommemorationPart(commemoration));
|
||||
}
|
||||
}
|
||||
return parts;
|
||||
|
||||
@@ -157,6 +157,34 @@ describe('resolveOrdo("vespers", ...)', () => {
|
||||
expect(anne).toBeDefined();
|
||||
});
|
||||
|
||||
it("renders each of the Christmas Octave's own stacked 'Commemoratio Octavæ' blocks on a day the temporal office itself keeps standing", () => {
|
||||
// 2033-12-30 -- one day past the '2033-12-29' stacking fixture already
|
||||
// used in tests/calendar/octaves.test.ts (St. Thomas of Canterbury's
|
||||
// day, itself outside this app's calendar so the day stays plain
|
||||
// temporal). All four of Christmas/Stephen/John/Holy Innocents' own
|
||||
// octaves are active and none of them wins the day outright (the
|
||||
// temporal day itself, "privileged-feria-minor", keeps the office) --
|
||||
// see hours/resolve-common.ts's getDayCollects, kind === 'octave'
|
||||
// branch, and its own doc comment for why this is the one case an
|
||||
// octave commemoration renders its own Ant+V/R+collect block here.
|
||||
const ordo = resolveOrdo('vespers', '2033-12-30');
|
||||
const octaveParts = ordo.parts.filter(
|
||||
(p): p is Extract<typeof p, { kind: 'preces' }> => p.kind === 'preces' && (p.label?.includes('Octave of') ?? false),
|
||||
);
|
||||
expect(octaveParts.map((p) => p.label).sort()).toEqual(
|
||||
[
|
||||
'Commemoration of the Octave of Christmas',
|
||||
'Commemoration of the Octave of The Holy Innocents, Martyrs',
|
||||
'Commemoration of the Octave of St. John, Apostle and Evangelist',
|
||||
'Commemoration of the Octave of St. Stephen, Protomartyr',
|
||||
].sort(),
|
||||
);
|
||||
for (const part of octaveParts) {
|
||||
expect(part.text.status.la).toBe('verified');
|
||||
expect(part.text.status.en).toBe('verified');
|
||||
}
|
||||
});
|
||||
|
||||
it("renders Advent's seasonal chapter/hymn/versicle instead of the plain weekday default", () => {
|
||||
// 2025-12-02 is a Tuesday in Advent (St. Bibiana, Simplex, merely
|
||||
// commemorated — the day's own winner stays temporal either way).
|
||||
|
||||
Reference in New Issue
Block a user