58958aa847
Deploy / deploy (push) Failing after 21s
Pulls in verified content from Divinum Officium rather than placeholders: 17 psalms (2, 6, 7-19, 118, 129), 365 days of the Martyrology, and the full 121-reading Regula cycle, plus the Athanasian Creed. Ordo corrections driven by review against the real engine output: - Capitulum and Preces now pick a Sunday/feast vs. ferial form (calendar/isSundayOrFeast); ferial Preces said every ferial day by choice. - Chapter responsory, hymn doxology, and the opening versicle's Alleluia/Laus tibi all vary by season via a shared resolver (hours/seasonal-propers.ts). - Real Roman Kalends/Nones/Ides Latin dating (calendar/roman-date.ts, verified against 363/365 real Martyrology headings) plus the historical "bis sextus" Feb 29 handling, and the Martyrology's Luna (moon-day) heading (a ported Golden-Number calculation). - Fixed responsory structure (was missing its initial full repeat), weekday psalm antiphons (opening as incipit-or-full by rank, full repeat after the psalms/Creed as its own part, "*" chant mark kept), scripture citations on the capitulum/lectio brevis, and V./R. markers switched from Unicode symbols to plain text for reliable font rendering. - Dropped Pretiosa and the dead-commemoration psalm (129) for time; trimmed section headings down to the ones that are actually named things (Preces, Chapter Office, etc. no longer relabel connective text). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
79 lines
2.6 KiB
TypeScript
79 lines
2.6 KiB
TypeScript
import type { MartyrologyEntry } from './types';
|
|
import { lunaDay, lunaOrdinalLatin, lunaOrdinalEnglish } from './luna';
|
|
import { romanDateLatin } from '../calendar/roman-date';
|
|
|
|
// One file per calendar day (MM-DD.yml) — only a handful exist so far
|
|
// (content-authoring the full 366-day Roman Martyrology is a separate,
|
|
// later task, same as full psalm-text authoring). Missing days resolve as
|
|
// pending rather than throwing.
|
|
const modules = import.meta.glob<{ default: MartyrologyEntry }>('../data/martyrology/*.yml', {
|
|
eager: true,
|
|
});
|
|
|
|
const entries = new Map<string, MartyrologyEntry>();
|
|
for (const mod of Object.values(modules)) {
|
|
entries.set(mod.default.monthDay, mod.default);
|
|
}
|
|
|
|
const ENGLISH_MONTHS = [
|
|
'January',
|
|
'February',
|
|
'March',
|
|
'April',
|
|
'May',
|
|
'June',
|
|
'July',
|
|
'August',
|
|
'September',
|
|
'October',
|
|
'November',
|
|
'December',
|
|
];
|
|
|
|
function dayFollowing(isoDate: string): { month: number; day: number; year: number; monthDay: string } {
|
|
const date = new Date(`${isoDate}T00:00:00Z`);
|
|
date.setUTCDate(date.getUTCDate() + 1);
|
|
const month = date.getUTCMonth() + 1;
|
|
const day = date.getUTCDate();
|
|
const year = date.getUTCFullYear();
|
|
return { month, day, year, monthDay: `${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}` };
|
|
}
|
|
|
|
/**
|
|
* The Latin heading uses the real Roman Kalends/Nones/Ides date (see
|
|
* calendar/roman-date.ts); English dates are given in plain Gregorian
|
|
* form — there's no traditional English equivalent of the Kalends system.
|
|
*/
|
|
function heading(month: number, day: number, year: number): { la: string; en: string } {
|
|
const luna = lunaDay(month, day, year);
|
|
return {
|
|
la: `${romanDateLatin(month, day, year)} Luna ${lunaOrdinalLatin(luna)}. Anno Dómini ${year}.`,
|
|
en: `${ENGLISH_MONTHS[month - 1]} ${day}, ${year} — the ${lunaOrdinalEnglish(luna)} day of the Moon.`,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Monastic Prime reads *tomorrow's* Martyrology entry (the announcement of
|
|
* the next day's saints), not today's — this computes that offset so callers
|
|
* just pass the ordo's own date.
|
|
*/
|
|
export function getMartyrologyEntryFor(isoDate: string): MartyrologyEntry {
|
|
const { month, day, year, monthDay } = dayFollowing(isoDate);
|
|
const entry = entries.get(monthDay);
|
|
if (!entry) {
|
|
return { monthDay, text: {}, status: { la: 'missing', en: 'missing' } };
|
|
}
|
|
|
|
const head = heading(month, day, year);
|
|
return {
|
|
monthDay,
|
|
text: {
|
|
la: entry.text.la ? `${head.la}\n\n${entry.text.la}` : entry.text.la,
|
|
en: entry.text.en ? `${head.en}\n\n${entry.text.en}` : entry.text.en,
|
|
},
|
|
status: entry.status,
|
|
};
|
|
}
|
|
|
|
export type { MartyrologyEntry } from './types';
|