All checks were successful
CI / update (push) Successful in 1m34s
- Extract Bible lookup logic into shared src/lib/server/bible.ts module - Add build script to pre-generate all 20 mystery verse lookups as static data, eliminating runtime API calls on rosary page load - Update Prayer.svelte to pass showLatin/urlLang as snippet parameters; all 14 prayer components now conditionally render only visible language elements instead of hiding via CSS - Extract 4 inline mystery selector SVGs into MysteryIcon.svelte component - Remove unused CSS selectors from angelus page
89 lines
2.1 KiB
TypeScript
89 lines
2.1 KiB
TypeScript
import { readFileSync } from 'fs';
|
|
import { resolve } from 'path';
|
|
|
|
export interface BibleVerse {
|
|
bookName: string;
|
|
abbreviation: string;
|
|
bookNumber: number;
|
|
chapter: number;
|
|
verseNumber: number;
|
|
text: string;
|
|
}
|
|
|
|
let cachedVerses: BibleVerse[] | null = null;
|
|
|
|
export function loadVersesFromFile(tsvPath?: string): BibleVerse[] {
|
|
if (cachedVerses) return cachedVerses;
|
|
|
|
const filePath = tsvPath ?? resolve('static/allioli.tsv');
|
|
const content = readFileSync(filePath, 'utf-8');
|
|
const lines = content.trim().split('\n');
|
|
|
|
cachedVerses = lines.map((line) => {
|
|
const [bookName, abbreviation, bookNumber, chapter, verseNumber, text] = line.split('\t');
|
|
return {
|
|
bookName,
|
|
abbreviation,
|
|
bookNumber: parseInt(bookNumber),
|
|
chapter: parseInt(chapter),
|
|
verseNumber: parseInt(verseNumber),
|
|
text
|
|
};
|
|
});
|
|
|
|
return cachedVerses;
|
|
}
|
|
|
|
function parseReference(reference: string) {
|
|
const match = reference.match(
|
|
/^([A-Za-zäöüÄÖÜß]+)\s*(\d+)[\s,:]+(\d+)(?:[-:](\d+))?$/
|
|
);
|
|
if (!match) return null;
|
|
|
|
const [, bookRef, chapterStr, startVerseStr, endVerseStr] = match;
|
|
|
|
return {
|
|
bookRef,
|
|
isFullName: bookRef.length > 5,
|
|
chapter: parseInt(chapterStr),
|
|
startVerse: parseInt(startVerseStr),
|
|
endVerse: endVerseStr ? parseInt(endVerseStr) : parseInt(startVerseStr)
|
|
};
|
|
}
|
|
|
|
export function getVersesByReference(
|
|
verses: BibleVerse[],
|
|
reference: string
|
|
): BibleVerse[] {
|
|
const parsed = parseReference(reference);
|
|
if (!parsed) return [];
|
|
|
|
return verses.filter((v) => {
|
|
const bookMatches = parsed.isFullName
|
|
? v.bookName === parsed.bookRef
|
|
: v.abbreviation === parsed.bookRef;
|
|
|
|
return (
|
|
bookMatches &&
|
|
v.chapter === parsed.chapter &&
|
|
v.verseNumber >= parsed.startVerse &&
|
|
v.verseNumber <= parsed.endVerse
|
|
);
|
|
});
|
|
}
|
|
|
|
export function lookupReference(reference: string, tsvPath?: string) {
|
|
const verses = loadVersesFromFile(tsvPath);
|
|
const matched = getVersesByReference(verses, reference);
|
|
|
|
if (matched.length === 0) return null;
|
|
|
|
const first = matched[0];
|
|
return {
|
|
reference,
|
|
book: first.bookName,
|
|
chapter: first.chapter,
|
|
verses: matched.map((v) => ({ verse: v.verseNumber, text: v.text }))
|
|
};
|
|
}
|