Centralize antiphon opening-doubling logic across all hours
The same idiom (splitNamedAntiphon + isDoubleOrHigher(...) ? full : incipit) was copy-pasted at 11 call sites across 8 hour files. Add one shared openingAntiphon(antiphon, winner) helper in resolve-common.ts and use it everywhere a psalm/canticle antiphon's opening form is decided. Pure dedup, no behavior change. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F25189JqjXddUhU9hM9nUS
This commit is contained in:
@@ -7,7 +7,7 @@ import { getHymnDoxologyId } from './hymn-doxology';
|
|||||||
import { getOpeningVersicleId } from './opening-versicle';
|
import { getOpeningVersicleId } from './opening-versicle';
|
||||||
import { getMarianAntiphonId, getMarianAntiphonLabel } from './marian-antiphon';
|
import { getMarianAntiphonId, getMarianAntiphonLabel } from './marian-antiphon';
|
||||||
import { isDoubleOrHigher } from './antiphon';
|
import { isDoubleOrHigher } from './antiphon';
|
||||||
import { resolveCommon, appendDoxology, splitNamedAntiphon, resolveResponsory } from './resolve-common';
|
import { resolveCommon, appendDoxology, splitNamedAntiphon, openingAntiphon, resolveResponsory } from './resolve-common';
|
||||||
import complineDefinitionData from '../data/hours/compline.yml';
|
import complineDefinitionData from '../data/hours/compline.yml';
|
||||||
|
|
||||||
const complineDefinition = complineDefinitionData as HourDefinition;
|
const complineDefinition = complineDefinitionData as HourDefinition;
|
||||||
@@ -63,8 +63,9 @@ function resolvePart(part: HourPart, day: LiturgicalDay): ResolvedPart[] {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
case 'nunc-dimittis': {
|
case 'nunc-dimittis': {
|
||||||
const { incipit, full } = splitNamedAntiphon(resolveCommon('nunc-dimittis-antiphon'));
|
const antiphonText = resolveCommon('nunc-dimittis-antiphon');
|
||||||
const opening = isDoubleOrHigher(day.winner) ? full : incipit;
|
const opening = openingAntiphon(antiphonText, day.winner);
|
||||||
|
const { full } = splitNamedAntiphon(antiphonText);
|
||||||
return [
|
return [
|
||||||
{ kind: 'canticle', canticleId: 'nunc-dimittis', text: resolveCommon('nunc-dimittis'), antiphon: opening },
|
{ kind: 'canticle', canticleId: 'nunc-dimittis', text: resolveCommon('nunc-dimittis'), antiphon: opening },
|
||||||
{ kind: 'antiphon', text: full },
|
{ kind: 'antiphon', text: full },
|
||||||
|
|||||||
+6
-6
@@ -14,6 +14,7 @@ import {
|
|||||||
getDayCollects,
|
getDayCollects,
|
||||||
getBenedictusAntiphon,
|
getBenedictusAntiphon,
|
||||||
splitNamedAntiphon,
|
splitNamedAntiphon,
|
||||||
|
openingAntiphon,
|
||||||
resolveOfficeWinner,
|
resolveOfficeWinner,
|
||||||
verifiedText,
|
verifiedText,
|
||||||
seasonalOfficeSuffix,
|
seasonalOfficeSuffix,
|
||||||
@@ -134,10 +135,8 @@ function canticleText(canticleId: string, slice?: [number, number]): ResolvedTex
|
|||||||
* plain weekday default below gets substituted. */
|
* plain weekday default below gets substituted. */
|
||||||
function resolvePsalmody(day: LiturgicalDay): ResolvedPart[] {
|
function resolvePsalmody(day: LiturgicalDay): ResolvedPart[] {
|
||||||
const wd = getPsalmodyOverrideFor(day) ?? laudsAntiphons[day.weekday];
|
const wd = getPsalmodyOverrideFor(day) ?? laudsAntiphons[day.weekday];
|
||||||
const opening = (antiphon: BilingualText) => {
|
const winner = resolveOfficeWinner(day);
|
||||||
const { incipit, full } = splitNamedAntiphon(verifiedText(antiphon));
|
const opening = (antiphon: BilingualText) => openingAntiphon(verifiedText(antiphon), winner);
|
||||||
return isDoubleOrHigher(resolveOfficeWinner(day)) ? full : incipit;
|
|
||||||
};
|
|
||||||
const parts: ResolvedPart[] = [
|
const parts: ResolvedPart[] = [
|
||||||
{
|
{
|
||||||
kind: 'psalm',
|
kind: 'psalm',
|
||||||
@@ -237,8 +236,9 @@ function resolvePart(part: HourPart, day: LiturgicalDay): ResolvedPart[] {
|
|||||||
case 'lauds-office':
|
case 'lauds-office':
|
||||||
return resolveOffice(day);
|
return resolveOffice(day);
|
||||||
case 'benedictus': {
|
case 'benedictus': {
|
||||||
const { incipit, full } = splitNamedAntiphon(getBenedictusAntiphon(day));
|
const antiphonText = getBenedictusAntiphon(day);
|
||||||
const opening = isDoubleOrHigher(resolveOfficeWinner(day)) ? full : incipit;
|
const opening = openingAntiphon(antiphonText, resolveOfficeWinner(day));
|
||||||
|
const { full } = splitNamedAntiphon(antiphonText);
|
||||||
return [
|
return [
|
||||||
{ kind: 'canticle', canticleId: 'benedictus', text: resolveCommon('benedictus'), antiphon: opening },
|
{ kind: 'canticle', canticleId: 'benedictus', text: resolveCommon('benedictus'), antiphon: opening },
|
||||||
{ kind: 'antiphon', text: full },
|
{ kind: 'antiphon', text: full },
|
||||||
|
|||||||
+11
-7
@@ -78,6 +78,7 @@ import {
|
|||||||
seasonalOfficeSuffix,
|
seasonalOfficeSuffix,
|
||||||
verifiedText,
|
verifiedText,
|
||||||
splitNamedAntiphon,
|
splitNamedAntiphon,
|
||||||
|
openingAntiphon,
|
||||||
} from './resolve-common';
|
} from './resolve-common';
|
||||||
import { getBiblePlanReadings } from '../propers/bible-plan';
|
import { getBiblePlanReadings } from '../propers/bible-plan';
|
||||||
import { getNocturnReadings, type NocturnReading } from '../propers/nocturn-readings';
|
import { getNocturnReadings, type NocturnReading } from '../propers/nocturn-readings';
|
||||||
@@ -187,8 +188,9 @@ function invitatoryParts(day: LiturgicalDay): ResolvedPart[] {
|
|||||||
function sundayPsalmNocturn(group: SundayNocturn, day: LiturgicalDay): ResolvedPart[] {
|
function sundayPsalmNocturn(group: SundayNocturn, day: LiturgicalDay): ResolvedPart[] {
|
||||||
const parts: ResolvedPart[] = [];
|
const parts: ResolvedPart[] = [];
|
||||||
for (const g of group.groups ?? []) {
|
for (const g of group.groups ?? []) {
|
||||||
const { incipit, full } = splitNamedAntiphon(verifiedText(g.antiphon));
|
const antiphonText = verifiedText(g.antiphon);
|
||||||
const opening = isDoubleOrHigher(resolveOfficeWinner(day)) ? full : incipit;
|
const opening = openingAntiphon(antiphonText, resolveOfficeWinner(day));
|
||||||
|
const { full } = splitNamedAntiphon(antiphonText);
|
||||||
g.psalms.forEach((n, i) => {
|
g.psalms.forEach((n, i) => {
|
||||||
parts.push(psalmPartWithAntiphon(n, i === 0 ? opening : undefined));
|
parts.push(psalmPartWithAntiphon(n, i === 0 ? opening : undefined));
|
||||||
});
|
});
|
||||||
@@ -201,8 +203,9 @@ function sundayPsalmNocturn(group: SundayNocturn, day: LiturgicalDay): ResolvedP
|
|||||||
/** Nocturn 3's 3 fixed OT canticles under one shared antiphon — see
|
/** Nocturn 3's 3 fixed OT canticles under one shared antiphon — see
|
||||||
* data/hours/matins-sunday-antiphons.yml's own header. */
|
* data/hours/matins-sunday-antiphons.yml's own header. */
|
||||||
function sundayCanticleNocturn(group: SundayNocturn, day: LiturgicalDay): ResolvedPart[] {
|
function sundayCanticleNocturn(group: SundayNocturn, day: LiturgicalDay): ResolvedPart[] {
|
||||||
const { incipit, full } = splitNamedAntiphon(verifiedText(group.antiphon ?? {}));
|
const antiphonText = verifiedText(group.antiphon ?? {});
|
||||||
const opening = isDoubleOrHigher(resolveOfficeWinner(day)) ? full : incipit;
|
const opening = openingAntiphon(antiphonText, resolveOfficeWinner(day));
|
||||||
|
const { full } = splitNamedAntiphon(antiphonText);
|
||||||
const parts: ResolvedPart[] = (group.canticles ?? []).map((c, i) => {
|
const parts: ResolvedPart[] = (group.canticles ?? []).map((c, i) => {
|
||||||
const verses = c.refs.flatMap((ref) => getScriptureVerses(ref.book, ref.chapter, ref.verses));
|
const verses = c.refs.flatMap((ref) => getScriptureVerses(ref.book, ref.chapter, ref.verses));
|
||||||
const text: BilingualText = {
|
const text: BilingualText = {
|
||||||
@@ -285,11 +288,12 @@ function ferialPsalmody(day: LiturgicalDay): ResolvedPart[] {
|
|||||||
* as one combined V./R. block via `versicleText`. */
|
* as one combined V./R. block via `versicleText`. */
|
||||||
function ferialAntiphonedNocturn(day: LiturgicalDay): ResolvedPart[] {
|
function ferialAntiphonedNocturn(day: LiturgicalDay): ResolvedPart[] {
|
||||||
const nocturn = ferialAntiphons[day.weekday as Exclude<Weekday, 'sunday'>];
|
const nocturn = ferialAntiphons[day.weekday as Exclude<Weekday, 'sunday'>];
|
||||||
const isDouble = isDoubleOrHigher(resolveOfficeWinner(day));
|
const winner = resolveOfficeWinner(day);
|
||||||
const parts: ResolvedPart[] = [];
|
const parts: ResolvedPart[] = [];
|
||||||
for (const group of nocturn.groups) {
|
for (const group of nocturn.groups) {
|
||||||
const { incipit, full } = splitNamedAntiphon(verifiedText(group.antiphon));
|
const antiphonText = verifiedText(group.antiphon);
|
||||||
const opening = isDouble ? full : incipit;
|
const opening = openingAntiphon(antiphonText, winner);
|
||||||
|
const { full } = splitNamedAntiphon(antiphonText);
|
||||||
group.psalms.forEach((ref, i) => {
|
group.psalms.forEach((ref, i) => {
|
||||||
const rawVerses = getPsalmVerses(ref.number, ref.verses).map((v): ResolvedVerse => ({ n: v.n, text: v.text, status: v.status }));
|
const rawVerses = getPsalmVerses(ref.number, ref.verses).map((v): ResolvedVerse => ({ n: v.n, text: v.text, status: v.status }));
|
||||||
const { verses, antiphon } = applyFlexaMark(rawVerses, i === 0 ? opening : undefined);
|
const { verses, antiphon } = applyFlexaMark(rawVerses, i === 0 ? opening : undefined);
|
||||||
|
|||||||
+3
-4
@@ -5,11 +5,11 @@ import { getDayLabel } from '../calendar/day-label';
|
|||||||
import { getPsalmsFor } from '../psalter/distribution';
|
import { getPsalmsFor } from '../psalter/distribution';
|
||||||
import { getPsalmVerses } from '../psalter';
|
import { getPsalmVerses } from '../psalter';
|
||||||
import { getOpeningVersicleId } from './opening-versicle';
|
import { getOpeningVersicleId } from './opening-versicle';
|
||||||
import { isDoubleOrHigher, applyFlexaMark } from './antiphon';
|
import { applyFlexaMark } from './antiphon';
|
||||||
import {
|
import {
|
||||||
resolveCommon,
|
resolveCommon,
|
||||||
getDayCollect,
|
getDayCollect,
|
||||||
splitNamedAntiphon,
|
openingAntiphon,
|
||||||
resolveOfficeWinner,
|
resolveOfficeWinner,
|
||||||
resolveMinorHourAntiphon,
|
resolveMinorHourAntiphon,
|
||||||
resolveMinorHourChapter,
|
resolveMinorHourChapter,
|
||||||
@@ -38,8 +38,7 @@ function resolvePart(part: HourPart, day: LiturgicalDay): ResolvedPart[] {
|
|||||||
// psalms, no closing repeat (unlike Prime): confirmed directly
|
// psalms, no closing repeat (unlike Prime): confirmed directly
|
||||||
// against the engine, Capitulum follows the third psalm immediately.
|
// against the engine, Capitulum follows the third psalm immediately.
|
||||||
const psalmRefs = getPsalmsFor('none', day.weekday);
|
const psalmRefs = getPsalmsFor('none', day.weekday);
|
||||||
const { incipit, full } = splitNamedAntiphon(resolveMinorHourAntiphon('none', day, antiphons[day.weekday]));
|
const opening = openingAntiphon(resolveMinorHourAntiphon('none', day, antiphons[day.weekday]), resolveOfficeWinner(day));
|
||||||
const opening = isDoubleOrHigher(resolveOfficeWinner(day)) ? full : incipit;
|
|
||||||
return psalmRefs.map((ref, i) => {
|
return psalmRefs.map((ref, i) => {
|
||||||
const rawVerses = getPsalmVerses(ref.number, ref.verses).map((v) => ({ n: v.n, text: v.text, status: v.status }));
|
const rawVerses = getPsalmVerses(ref.number, ref.verses).map((v) => ({ n: v.n, text: v.text, status: v.status }));
|
||||||
const { verses, antiphon } = applyFlexaMark(rawVerses, i === 0 ? opening : undefined);
|
const { verses, antiphon } = applyFlexaMark(rawVerses, i === 0 ? opening : undefined);
|
||||||
|
|||||||
+3
-2
@@ -14,6 +14,7 @@ import {
|
|||||||
resolveCommon,
|
resolveCommon,
|
||||||
appendDoxology,
|
appendDoxology,
|
||||||
splitNamedAntiphon,
|
splitNamedAntiphon,
|
||||||
|
openingAntiphon,
|
||||||
resolveOfficeWinner,
|
resolveOfficeWinner,
|
||||||
resolveMinorHourAntiphon,
|
resolveMinorHourAntiphon,
|
||||||
isSundayOrFeastOffice,
|
isSundayOrFeastOffice,
|
||||||
@@ -65,11 +66,11 @@ function resolvePart(part: HourPart, date: string, day: LiturgicalDay): Resolved
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
const psalmRefs = getPsalmsFor('prime', day.weekday);
|
const psalmRefs = getPsalmsFor('prime', day.weekday);
|
||||||
const { incipit, full } = splitNamedAntiphon(resolveMinorHourAntiphon('prime', day, antiphons[day.weekday]));
|
const antiphonText = resolveMinorHourAntiphon('prime', day, antiphons[day.weekday]);
|
||||||
// Full text on a Double-or-higher feast, otherwise just the incipit
|
// Full text on a Double-or-higher feast, otherwise just the incipit
|
||||||
// — see hours/antiphon.ts. The full repeat comes later, after the
|
// — see hours/antiphon.ts. The full repeat comes later, after the
|
||||||
// Creed (see 'closing-antiphon'), not tacked onto the last psalm.
|
// Creed (see 'closing-antiphon'), not tacked onto the last psalm.
|
||||||
const opening = isDoubleOrHigher(resolveOfficeWinner(day)) ? full : incipit;
|
const opening = openingAntiphon(antiphonText, resolveOfficeWinner(day));
|
||||||
return psalmRefs.map((ref, i) => {
|
return psalmRefs.map((ref, i) => {
|
||||||
const rawVerses = getPsalmVerses(ref.number, ref.verses).map((v) => ({ n: v.n, text: v.text, status: v.status }));
|
const rawVerses = getPsalmVerses(ref.number, ref.verses).map((v) => ({ n: v.n, text: v.text, status: v.status }));
|
||||||
const { verses, antiphon } = applyFlexaMark(rawVerses, i === 0 ? opening : undefined);
|
const { verses, antiphon } = applyFlexaMark(rawVerses, i === 0 ? opening : undefined);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { getSaintRecord } from '../calendar/feasts';
|
|||||||
import { resolveActiveOctave, activeOctavesFor, octaveGoverningPrivilegedDay, isAtLeast } from '../calendar';
|
import { resolveActiveOctave, activeOctavesFor, octaveGoverningPrivilegedDay, isAtLeast } from '../calendar';
|
||||||
import { getTemporalFeastRecord } from '../calendar/temporal-feasts';
|
import { getTemporalFeastRecord } from '../calendar/temporal-feasts';
|
||||||
import { isInTriduum } from '../calendar/temporal';
|
import { isInTriduum } from '../calendar/temporal';
|
||||||
import { splitAntiphon } from './antiphon';
|
import { splitAntiphon, isDoubleOrHigher } from './antiphon';
|
||||||
import vespersMagnificatAntiphonsData from '../data/hours/vespers-magnificat-antiphons.yml';
|
import vespersMagnificatAntiphonsData from '../data/hours/vespers-magnificat-antiphons.yml';
|
||||||
|
|
||||||
type BilingualText = Partial<Record<string, string>>;
|
type BilingualText = Partial<Record<string, string>>;
|
||||||
@@ -692,6 +692,19 @@ export function splitNamedAntiphon(antiphon: ResolvedText): {
|
|||||||
return { incipit: { text: incipitText, status: incipitStatus }, full: { text: fullText, status: fullStatus } };
|
return { incipit: { text: incipitText, status: incipitStatus }, full: { text: fullText, status: fullStatus } };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** The antiphon actually shown *before* a psalm/canticle: full text on a
|
||||||
|
* Double-rank winner or higher, incipit only below that (see
|
||||||
|
* `isDoubleOrHigher`'s own doc comment for the underlying rule) — the one
|
||||||
|
* idiom every hour's psalmody independently repeated (`splitNamedAntiphon`
|
||||||
|
* + `isDoubleOrHigher(...) ? full : incipit`) before being centralized
|
||||||
|
* here. The closing repeat after the psalm/canticle is always `full`,
|
||||||
|
* unconditionally, at each call site — this helper only decides the
|
||||||
|
* opening. */
|
||||||
|
export function openingAntiphon(antiphon: ResolvedText, winner: DayWinner): ResolvedText {
|
||||||
|
const { incipit, full } = splitNamedAntiphon(antiphon);
|
||||||
|
return isDoubleOrHigher(winner) ? full : incipit;
|
||||||
|
}
|
||||||
|
|
||||||
/** Fixed wording, same as lauds.ts's weekday-canticle Gloria Patri —
|
/** Fixed wording, same as lauds.ts's weekday-canticle Gloria Patri —
|
||||||
* appended after every psalm (hours/index.ts) except during the Sacred
|
* appended after every psalm (hours/index.ts) except during the Sacred
|
||||||
* Triduum. Not "verified" via verifiedText() because it's boilerplate
|
* Triduum. Not "verified" via verifiedText() because it's boilerplate
|
||||||
|
|||||||
+3
-4
@@ -5,11 +5,11 @@ import { getDayLabel } from '../calendar/day-label';
|
|||||||
import { getPsalmsFor } from '../psalter/distribution';
|
import { getPsalmsFor } from '../psalter/distribution';
|
||||||
import { getPsalmVerses } from '../psalter';
|
import { getPsalmVerses } from '../psalter';
|
||||||
import { getOpeningVersicleId } from './opening-versicle';
|
import { getOpeningVersicleId } from './opening-versicle';
|
||||||
import { isDoubleOrHigher, applyFlexaMark } from './antiphon';
|
import { applyFlexaMark } from './antiphon';
|
||||||
import {
|
import {
|
||||||
resolveCommon,
|
resolveCommon,
|
||||||
getDayCollect,
|
getDayCollect,
|
||||||
splitNamedAntiphon,
|
openingAntiphon,
|
||||||
resolveOfficeWinner,
|
resolveOfficeWinner,
|
||||||
resolveMinorHourAntiphon,
|
resolveMinorHourAntiphon,
|
||||||
resolveMinorHourChapter,
|
resolveMinorHourChapter,
|
||||||
@@ -38,8 +38,7 @@ function resolvePart(part: HourPart, day: LiturgicalDay): ResolvedPart[] {
|
|||||||
// psalms, no closing repeat (unlike Prime): confirmed directly
|
// psalms, no closing repeat (unlike Prime): confirmed directly
|
||||||
// against the engine, Capitulum follows the third psalm immediately.
|
// against the engine, Capitulum follows the third psalm immediately.
|
||||||
const psalmRefs = getPsalmsFor('sext', day.weekday);
|
const psalmRefs = getPsalmsFor('sext', day.weekday);
|
||||||
const { incipit, full } = splitNamedAntiphon(resolveMinorHourAntiphon('sext', day, antiphons[day.weekday]));
|
const opening = openingAntiphon(resolveMinorHourAntiphon('sext', day, antiphons[day.weekday]), resolveOfficeWinner(day));
|
||||||
const opening = isDoubleOrHigher(resolveOfficeWinner(day)) ? full : incipit;
|
|
||||||
return psalmRefs.map((ref, i) => {
|
return psalmRefs.map((ref, i) => {
|
||||||
const rawVerses = getPsalmVerses(ref.number, ref.verses).map((v) => ({ n: v.n, text: v.text, status: v.status }));
|
const rawVerses = getPsalmVerses(ref.number, ref.verses).map((v) => ({ n: v.n, text: v.text, status: v.status }));
|
||||||
const { verses, antiphon } = applyFlexaMark(rawVerses, i === 0 ? opening : undefined);
|
const { verses, antiphon } = applyFlexaMark(rawVerses, i === 0 ? opening : undefined);
|
||||||
|
|||||||
+3
-4
@@ -5,11 +5,11 @@ import { getDayLabel } from '../calendar/day-label';
|
|||||||
import { getPsalmsFor } from '../psalter/distribution';
|
import { getPsalmsFor } from '../psalter/distribution';
|
||||||
import { getPsalmVerses } from '../psalter';
|
import { getPsalmVerses } from '../psalter';
|
||||||
import { getOpeningVersicleId } from './opening-versicle';
|
import { getOpeningVersicleId } from './opening-versicle';
|
||||||
import { isDoubleOrHigher, applyFlexaMark } from './antiphon';
|
import { applyFlexaMark } from './antiphon';
|
||||||
import {
|
import {
|
||||||
resolveCommon,
|
resolveCommon,
|
||||||
getDayCollect,
|
getDayCollect,
|
||||||
splitNamedAntiphon,
|
openingAntiphon,
|
||||||
resolveOfficeWinner,
|
resolveOfficeWinner,
|
||||||
resolveMinorHourAntiphon,
|
resolveMinorHourAntiphon,
|
||||||
resolveMinorHourChapter,
|
resolveMinorHourChapter,
|
||||||
@@ -38,8 +38,7 @@ function resolvePart(part: HourPart, day: LiturgicalDay): ResolvedPart[] {
|
|||||||
// psalms, no closing repeat (unlike Prime): confirmed directly
|
// psalms, no closing repeat (unlike Prime): confirmed directly
|
||||||
// against the engine, Capitulum follows the third psalm immediately.
|
// against the engine, Capitulum follows the third psalm immediately.
|
||||||
const psalmRefs = getPsalmsFor('terce', day.weekday);
|
const psalmRefs = getPsalmsFor('terce', day.weekday);
|
||||||
const { incipit, full } = splitNamedAntiphon(resolveMinorHourAntiphon('terce', day, antiphons[day.weekday]));
|
const opening = openingAntiphon(resolveMinorHourAntiphon('terce', day, antiphons[day.weekday]), resolveOfficeWinner(day));
|
||||||
const opening = isDoubleOrHigher(resolveOfficeWinner(day)) ? full : incipit;
|
|
||||||
return psalmRefs.map((ref, i) => {
|
return psalmRefs.map((ref, i) => {
|
||||||
const rawVerses = getPsalmVerses(ref.number, ref.verses).map((v) => ({ n: v.n, text: v.text, status: v.status }));
|
const rawVerses = getPsalmVerses(ref.number, ref.verses).map((v) => ({ n: v.n, text: v.text, status: v.status }));
|
||||||
const { verses, antiphon } = applyFlexaMark(rawVerses, i === 0 ? opening : undefined);
|
const { verses, antiphon } = applyFlexaMark(rawVerses, i === 0 ? opening : undefined);
|
||||||
|
|||||||
@@ -4,12 +4,13 @@ import { resolveEveningDay } from '../calendar/vespers';
|
|||||||
import { getDayLabel } from '../calendar/day-label';
|
import { getDayLabel } from '../calendar/day-label';
|
||||||
import { getPsalmVerses } from '../psalter';
|
import { getPsalmVerses } from '../psalter';
|
||||||
import { getOpeningVersicleId } from './opening-versicle';
|
import { getOpeningVersicleId } from './opening-versicle';
|
||||||
import { isDoubleOrHigher, applyFlexaMark } from './antiphon';
|
import { applyFlexaMark } from './antiphon';
|
||||||
import {
|
import {
|
||||||
resolveCommon,
|
resolveCommon,
|
||||||
getDayCollects,
|
getDayCollects,
|
||||||
getMagnificatAntiphon,
|
getMagnificatAntiphon,
|
||||||
splitNamedAntiphon,
|
splitNamedAntiphon,
|
||||||
|
openingAntiphon,
|
||||||
resolveOfficeWinner,
|
resolveOfficeWinner,
|
||||||
verifiedText,
|
verifiedText,
|
||||||
seasonalOfficeSuffix,
|
seasonalOfficeSuffix,
|
||||||
@@ -47,8 +48,9 @@ function normalizePsalmRef(ref: PsalmRefLike): { number: number; verses?: string
|
|||||||
* in full once, after the last. Mirrors lauds.ts's psalmParts, extended
|
* in full once, after the last. Mirrors lauds.ts's psalmParts, extended
|
||||||
* for verse-range entries (see PsalmRefLike). */
|
* for verse-range entries (see PsalmRefLike). */
|
||||||
function psalmParts(group: VespersGroup, day: LiturgicalDay): ResolvedPart[] {
|
function psalmParts(group: VespersGroup, day: LiturgicalDay): ResolvedPart[] {
|
||||||
const { incipit, full } = splitNamedAntiphon(verifiedText(group.antiphon));
|
const antiphonText = verifiedText(group.antiphon);
|
||||||
const opening = isDoubleOrHigher(resolveOfficeWinner(day)) ? full : incipit;
|
const opening = openingAntiphon(antiphonText, resolveOfficeWinner(day));
|
||||||
|
const { full } = splitNamedAntiphon(antiphonText);
|
||||||
const refs = group.psalms.map(normalizePsalmRef);
|
const refs = group.psalms.map(normalizePsalmRef);
|
||||||
const parts: ResolvedPart[] = refs.map((ref, i) => {
|
const parts: ResolvedPart[] = refs.map((ref, i) => {
|
||||||
const rawVerses = getPsalmVerses(ref.number, ref.verses).map((v) => ({ n: v.n, text: v.text, status: v.status }));
|
const rawVerses = getPsalmVerses(ref.number, ref.verses).map((v) => ({ n: v.n, text: v.text, status: v.status }));
|
||||||
@@ -161,8 +163,9 @@ function resolvePart(part: HourPart, day: LiturgicalDay): ResolvedPart[] {
|
|||||||
case 'vespers-office':
|
case 'vespers-office':
|
||||||
return resolveOffice(day);
|
return resolveOffice(day);
|
||||||
case 'magnificat': {
|
case 'magnificat': {
|
||||||
const { incipit, full } = splitNamedAntiphon(getMagnificatAntiphon(day));
|
const antiphonText = getMagnificatAntiphon(day);
|
||||||
const opening = isDoubleOrHigher(resolveOfficeWinner(day)) ? full : incipit;
|
const opening = openingAntiphon(antiphonText, resolveOfficeWinner(day));
|
||||||
|
const { full } = splitNamedAntiphon(antiphonText);
|
||||||
return [
|
return [
|
||||||
{ kind: 'canticle', canticleId: 'magnificat', text: resolveCommon('magnificat'), antiphon: opening },
|
{ kind: 'canticle', canticleId: 'magnificat', text: resolveCommon('magnificat'), antiphon: opening },
|
||||||
{ kind: 'antiphon', text: full },
|
{ kind: 'antiphon', text: full },
|
||||||
|
|||||||
Reference in New Issue
Block a user