Files
vu/src/psalter/index.ts
T
will 58958aa847
Deploy / deploy (push) Failing after 21s
Prime: real content (psalms, Martyrology, Regula) and ordo corrections
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>
2026-08-09 20:03:53 -04:00

47 lines
1.5 KiB
TypeScript

import type { Psalm } from './types';
// @rollup/plugin-yaml parses each .yml into a plain object at build time —
// no YAML parser shipped to the client.
const modules = import.meta.glob<{ default: Psalm }>('../data/psalms/*.yml', {
eager: true,
});
const psalms = new Map<number, Psalm>();
for (const mod of Object.values(modules)) {
psalms.set(mod.default.number, mod.default);
}
/**
* Content-authoring the full psalter (verified Latin+English for every
* psalm) is a separate, ongoing task — an unauthored psalm resolves as a
* single pending "verse" rather than throwing, so an ordo can still render
* around it.
*/
export function getPsalm(number: number): Psalm {
return (
psalms.get(number) ?? {
number,
verses: [{ n: 1, text: {}, status: { la: 'missing', en: 'missing' } }],
}
);
}
/**
* @param verseRange e.g. "2-19" — Vulgate verse numbers, inclusive. Whole
* psalm (Monday's Ps 1/2/6, say) when omitted; a slice of a longer psalm
* (the Monastic Prime distribution splits Pss 9, 17, and 118 across days)
* when given.
*/
export function getPsalmVerses(number: number, verseRange?: string): Psalm['verses'] {
const psalm = getPsalm(number);
if (!verseRange) {
return psalm.verses;
}
const [startStr, endStr] = verseRange.split('-');
const start = Number(startStr);
const end = endStr ? Number(endStr) : start;
return psalm.verses.filter((v) => v.n >= start && v.n <= end);
}
export type { Psalm, PsalmVerse, LanguageCode, TranslationStatus } from './types';