UNPKG

@sahabaplus/mushaf-engine

Version:

TypeScript implementation of a Quran Mushaf navigation engine

172 lines (171 loc) 7.36 kB
import { SuraInfo } from "../mushaf/quranMetadata"; import { Direction } from "../navigation/direction"; import { NavigationResult } from "../navigation/navigationResult"; import { NavigationSettings } from "../navigation/navigationSettings"; import { VersePosition } from "../navigation/versePosition"; import { Verse } from "../mushaf"; import { VerseLocation } from "./verseLocation"; /** * Navigation parameters */ export interface NavigateParams { /** Number of lines to navigate (can be fractional) */ lines: number; /** Starting verse position */ from: VersePosition; /** Direction to navigate (Forward or Backward) */ direction: Direction; /** Settings for the Mushaf Engine */ settings: NavigationSettings; } /** * Interface for navigation within a Quran Mushaf * * This interface defines the core navigation functionality for traversing * through the Quran. It allows for moving through the text by a specified * number of lines in either direction from a given verse. */ export interface IMushafEngine { /** * Navigate from a verse by a specified number of lines in the given direction * * This method enables precise navigation through the Quran by moving a * specified number of lines forward or backward from a starting verse. * * @param params - Navigation parameters * @returns Navigation result containing the verse at the destination after navigation */ navigate(params: NavigateParams): NavigationResult; /** * Get metadata about a specific Sura * * @param suraNumber - Sura number (1-114) * @returns Information about the specified Sura, or undefined if not found */ getSuraInfo(suraNumber: number): SuraInfo | undefined; /** * Calculate the direct distance in lines between start and end verses * * This calculates the simple A→B distance without accounting for cycles. * When bounded navigation produces cycles, callers can use the `cycleDistance` * field from `NavigationResult` to compute total distance: * * ```text * total_distance ≈ (cycles_completed - 1) * cycle_distance + direct_distance * ``` * * where `direct_distance` is obtained from this method. * * @param start - Start verse position * @param end - End verse position * @param direction - Direction of navigation * @param settings - Navigation settings * @returns Direct distance in lines between the two verses * @throws Error if the verses are unreachable */ calculateLines(start: VersePosition, end: VersePosition, direction: Direction, settings: NavigationSettings): number; /** * Find the next verse from a given verse in the specified direction. * Respects navigation bounds and iteration limits. * * @param from - Verse position to start from * @param direction - Direction to navigate * @param settings - Navigation settings * @returns The next verse or undefined if at the end */ nextVerse(from: VersePosition, direction: Direction, settings: NavigationSettings): Verse | undefined; /** * Find the previous verse from a given verse in the specified direction. * Respects navigation bounds and iteration limits. * * @param from - Verse position to start from * @param direction - Direction to navigate * @param settings - Navigation settings * @returns The previous verse or undefined if at the start */ previousVerse(from: VersePosition, direction: Direction, settings: NavigationSettings): Verse | undefined; /** * Check if a verse position is out of the current navigation bounds * * Uses the same rules as navigation: the verse must exist in the mushaf, * then is checked against upper/lower bounds and excluding mode. In inclusive * mode, verses on the upper/lower sura edges are interpreted using `direction`, * consistent with the navigator. * * @param verse - Verse position to check * @param direction - Navigation direction (bounds checks at upper/lower sura edges are direction-aware) * @param settings - Navigation settings (bounds and excluding mode) * @returns true if the verse is outside the current bounds */ isOutOfBounds(verse: VersePosition, direction: Direction, settings: NavigationSettings): boolean; /** * Get the effective start of the navigation range for the given direction and settings * * @param direction - Navigation direction * @param settings - Navigation settings * @returns The verse position where the range starts */ getStartBound(direction: Direction, settings: NavigationSettings): VersePosition; /** * Get the effective end of the navigation range for the given direction and settings * * @param direction - Navigation direction * @param settings - Navigation settings * @returns The verse position where the range ends */ getEndBound(direction: Direction, settings: NavigationSettings): VersePosition; /** * Resolve a (sura, verse) position to the full Verse object in the mushaf * * @param position - Verse position to look up * @returns The verse with lines etc., or undefined if not in the mushaf */ findVerse(position: VersePosition): Verse | undefined; /** * Find a verse in the mushaf and return its location (verse, page, index on page) * * @param position - Verse position to find * @returns Location details, or undefined if not found */ findVerseLocation(position: VersePosition): VerseLocation | undefined; /** * Resolve a (sura, verse) pair directly to a Verse object. * * Thin convenience wrapper around `findVerse` to avoid manually constructing * `VersePosition` for simple lookups. * * @param sura - Sura number * @param verse - Verse number within the sura * @returns The verse with lines etc., or undefined if not in the mushaf */ resolvePosition(sura: number, verse: number): Verse | undefined; /** * Calculate the lines taken by a verse including any sura headers * * Uses the same rules as the internal navigator so that callers get * consistent layout calculations. * * @param verse - The verse to calculate lines for * @param settings - Navigation settings (used for `ignoreSuraHeader`) * @returns The total number of lines taken by the verse */ calculateVerseLines(verse: Verse, settings: NavigationSettings): number; /** * Check if navigation direction is wrong for given start and end positions * * This mirrors the internal `VersesNavigator.isWrongDirection` helper so that * callers can reuse the same ordering rules used by the engine itself. * * @param start - Start verse position (by object or coordinates) * @param end - End verse position (by object or coordinates) * @param direction - Direction of navigation * @returns true if the direction is invalid for the given verse order */ isWrongDirection(start: VersePosition | { sura: number; verse: number; }, end: VersePosition | { sura: number; verse: number; }, direction: Direction): boolean; }