UNPKG

@sahabaplus/mushaf-engine

Version:

TypeScript implementation of a Quran Mushaf navigation engine

176 lines (175 loc) 6.34 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.VersesNavigator = void 0; const direction_1 = require("./direction"); /** * A class responsible for navigating through verses in the Mushaf */ class VersesNavigator { /** * Create a new VersesNavigator * * @param mushaf - The Mushaf to navigate through * @param metadata - Metadata about the Quran */ constructor(mushaf, metadata) { this.mushaf = mushaf; this.quranMetadata = metadata; this.currentPageIdx = 0; this.currentVerseIdx = 0; } /** * Reset the navigator to a specific verse position * * @param suraNumber - Sura number (1-114) * @param verseNumber - Verse number within the sura * @returns The current verse after reset, or undefined if not found */ resetPosition(suraNumber, verseNumber) { const versePos = this.findVerse(suraNumber, verseNumber); if (versePos) { const [_, page, idx] = versePos; this.currentPageIdx = page - 1; this.currentVerseIdx = idx; return this.currentVerse(); } return undefined; } /** * Get the current verse * * @returns The current verse */ currentVerse() { const currentPageVerses = this.mushaf.pages[this.currentPageIdx].verses(); return currentPageVerses[this.currentVerseIdx]; } /** * Move to the next verse based on direction * * @param direction - Direction to navigate * @returns The next verse, or undefined if not found */ nextVerse(direction) { switch (direction) { case direction_1.Direction.Downwards: return this.nextVerseDownward(); case direction_1.Direction.Upwards: return this.nextVerseUpward(); } } /** * Move to the next verse in downward direction * * @returns The next verse, or undefined if not found */ nextVerseDownward() { const mushaf = this.mushaf.pages; // Try to move to the next verse on the current page this.currentVerseIdx += 1; // If we've reached the end of current page, move to next page if (this.currentVerseIdx >= mushaf[this.currentPageIdx].verses().length) { this.currentPageIdx += 1; this.currentVerseIdx = 0; // Check if we've reached the end of the mushaf if (this.currentPageIdx >= mushaf.length) { // Select last verse of quran this.currentPageIdx = mushaf.length - 1; this.currentVerseIdx = mushaf[this.currentPageIdx].verses().length - 1; } } return this.currentVerse(); } /** * Move to the previous sura * * @param currentSura - Current sura number * @returns The first verse of the previous sura, or undefined if not found */ movePreSura(currentSura) { const preSura = this.quranMetadata.getSuraInfo(currentSura - 1); if (!preSura) return undefined; const firstPageIdx = preSura.startPage - 1; const firstPage = this.mushaf.pages[firstPageIdx]; // Find first verse index for (let idx = 0; idx < firstPage.verses().length; idx++) { const verse = firstPage.verses()[idx]; if (verse.sura === preSura.number) { this.currentPageIdx = firstPageIdx; this.currentVerseIdx = idx; return verse; } } throw new Error("Unreachable code: Should have found a verse"); } /** * Move to the next verse in upward direction * * @returns The next verse, or undefined if not found */ nextVerseUpward() { const pages = this.mushaf.pages; const currentVerse = this.currentVerse(); // Reference current verse let currentVerseIdx = this.currentVerseIdx + 1; let currentPageIdx = this.currentPageIdx; // Check if the next verse index is valid + in same sura if (currentVerseIdx >= pages[currentPageIdx].verses().length) { // Move to previous sura currentPageIdx += 1; currentVerseIdx = 0; } if (currentPageIdx >= pages.length || pages[currentPageIdx].verses()[currentVerseIdx].sura !== currentVerse.sura) { return this.movePreSura(currentVerse.sura); } // Move next normally this.currentVerseIdx = currentVerseIdx; this.currentPageIdx = currentPageIdx; return this.currentVerse(); } /** * Find a verse in the mushaf and return its location (Verse, page, index_of_verse) * * @param suraNumber - Sura number (1-114) * @param verseNumber - Verse number within the sura * @returns The verse and its location, or undefined if not found */ findVerse(suraNumber, verseNumber) { const sura = this.quranMetadata.getSuraInfo(suraNumber); if (sura) { const pages = this.mushaf.pages; for (let i = sura.startPage; i <= sura.endPage; i++) { const page = pages[i - 1]; for (let j = 0; j < page.verses().length; j++) { const verse = page.verses()[j]; if (verse.sura === suraNumber && verse.number === verseNumber) { return [verse, page.number, j]; } } } } return undefined; } /** * Calculate the lines taken by a verse including any sura headers * * @param verse - The verse to calculate lines for * @returns The total number of lines taken by the verse */ calculateVerseLines(verse) { let totalLines = verse.lines; // Add lines for sura headers if this is the first verse of a sura if (verse.number === 1) { // All suras except At-Tawbah (9) have bismillah if (verse.sura !== 9) { totalLines += 2.0; // Sura title + bismillah } else { totalLines += 1.0; // Only sura title for At-Tawbah } } return totalLines; } } exports.VersesNavigator = VersesNavigator;