UNPKG

@sahabaplus/mushaf-engine

Version:

TypeScript implementation of a Quran Mushaf navigation engine

138 lines (137 loc) 4.85 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.QuranMetadata = exports.SuraInfo = void 0; /** * Information about a Sura in the Quran */ class SuraInfo { constructor(number = 0, totalVerses = 0, lines = 0, linesWithHeader = 0, startPage = 0, endPage = 0) { this.number = number; this.totalVerses = totalVerses; this.lines = lines; this.linesWithHeader = linesWithHeader; this.startPage = startPage; this.endPage = endPage; } } exports.SuraInfo = SuraInfo; /** * Collection of Sura information for quick lookup */ class QuranMetadata { constructor(suras = []) { this.suras = suras; } /** * Create a new QuranMetadata from the Mushaf * * @param mushaf - The Mushaf to extract metadata from * @returns A new QuranMetadata instance */ static fromMushaf(mushaf) { // Create an array with capacity for exactly 114 suras (0-indexed internally) const suras = []; // Maps to track sura statistics (1-indexed for easier reading) let currentSura = 0; const suraVerseCount = Array(115).fill(0); const suraLines = Array(115).fill(0); const suraStartPage = Array(115).fill(0); const suraEndPage = Array(115).fill(0); // Scan through the mushaf to collect information for (const page of mushaf.pages) { for (const verse of page.verses()) { const suraNum = verse.sura; // Track when we enter a new sura if (suraNum !== currentSura) { currentSura = suraNum; suraStartPage[suraNum] = page.number; } // Count verses and lines suraVerseCount[suraNum] += 1; suraLines[suraNum] += verse.lines; // Update end page suraEndPage[suraNum] = page.number; } } // Create SuraInfo for each sura (store in 0-indexed array) for (let suraNum = 1; suraNum <= 114; suraNum++) { // Add header lines for each sura const headerLines = suraNum === 9 ? 1.0 : 2.0; const totalLinesWithHeader = suraLines[suraNum] + headerLines; suras.push(new SuraInfo(suraNum, suraVerseCount[suraNum], suraLines[suraNum], totalLinesWithHeader, suraStartPage[suraNum], suraEndPage[suraNum])); } return new QuranMetadata(suras); } /** * Convert 1-based sura number to 0-based index for internal storage * * @param suraNumber - 1-based sura number * @returns 0-based index for internal storage, or undefined if out of range */ static suraToIndex(suraNumber) { if (suraNumber === 0 || suraNumber > 114) { return undefined; } return suraNumber - 1; } /** * Get information about a specific Sura (using 1-based sura number) * * @param suraNumber - 1-based sura number * @returns Information about the specified Sura, or undefined if not found */ getSuraInfo(suraNumber) { const idx = QuranMetadata.suraToIndex(suraNumber); return idx !== undefined ? this.suras[idx] : undefined; } /** * Find which Sura contains a particular page * * @param pageNumber - Page number to find suras for * @returns Array of sura numbers that contain the specified page, or undefined if none */ findSuraByPage(pageNumber) { const suras = this.suras .filter(info => info.startPage <= pageNumber && info.endPage >= pageNumber) .map(info => info.number); return suras.length > 0 ? suras : undefined; } /** * Get total number of lines for a range of Suras * * @param startSura - Starting sura number (1-based) * @param endSura - Ending sura number (1-based) * @returns Total number of lines for the specified range of suras */ getLinesRange(startSura, endSura) { const start = Math.max(startSura, 1); const end = Math.min(endSura, 114); let totalLines = 0; for (let suraNum = start; suraNum <= end; suraNum++) { const info = this.getSuraInfo(suraNum); if (info) { totalLines += info.linesWithHeader; } } return totalLines; } /** * Get the number of Suras in the Quran * * @returns The total number of suras */ totalSuras() { return this.suras.length; } /** * Get an iterator over all Sura information * * @returns An iterator over all Sura information */ *[Symbol.iterator]() { for (const sura of this.suras) { yield sura; } } } exports.QuranMetadata = QuranMetadata;