Prime: real content (psalms, Martyrology, Regula) and ordo corrections
Deploy / deploy (push) Failing after 21s
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>
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
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';
|
||||
Reference in New Issue
Block a user