quran-meta
Version:
Library with meta data and functionality related to Holy Quran
106 lines (104 loc) • 4.34 kB
JavaScript
const require_validation = require('./validation.cjs');
const require_typeGuards = require('./typeGuards.cjs');
//#region src/ayahStringSplitter.ts
/**
* Splits a string representation of Quran reference into surah and ayah components
* @param str - The string to parse, expected format: "surah:ayah" or "surah:ayahStart-ayahEnd"
* @param isStrict - If true, enforces strict format checking. Defaults to true. If false, allows for additional characters in the string
* @returns A tuple containing surah number and either a single ayah number or a range [start, end]
* @throws {@link Error} If the string format is invalid
* @throws {@link Error} If surah number is invalid
* @throws {@link Error} If ayah number(s) are invalid
* @throws {@link sError} If ayah range is invalid (start should be less than end)
* @example
* ```ts
* ayahStringSplitter("2:255") // returns [2, 255]
* ayahStringSplitter("1:1-7") // returns [1, [1, 7]]
* ```
*/
function ayahStringSplitter(str, isStrict = true) {
const result = isStrict ? string2NumberSplitterStrict(str) : string2NumberSplitter(str);
if (!result) throw new Error("Invalid string format: " + str);
const { surahOrAyah: surahX, ayah, ayahTo } = result;
if (!require_typeGuards.isValidSurah(surahX)) throw new Error("Invalid ayah number: " + str);
const surah = surahX;
let ayahs;
if (ayahTo) {
require_validation.checkValidAyahId(ayah);
require_validation.checkValidAyahId(ayahTo);
if (ayah > ayahTo) throw new Error("Invalid ayah range: " + str);
ayahs = [ayah, ayahTo];
} else {
if (!require_typeGuards.isValidAyahNo(ayah)) throw new Error("Error in data " + str);
require_validation.checkValidSurahAyah(surah, ayah);
ayahs = ayah;
}
return [surah, ayahs];
}
/**
* Splits a string containing surah and ayah numbers into their numeric components.
*
* @param str - Input string containing numbers separated by non-digits (e.g., "2:255" or "2 255" or "2-255")
* @returns An object containing the parsed numbers, or null if parsing fails
* - ayah: The ayah number if present
* - ayahTo: The ending ayah number if a range is specified
* - surahOrAyah: The surah number
* @example
* stringNumberSplitter("2:255") // returns { ayah: 255, ayahTo: 0, surahOrAyah: 2 }
* stringNumberSplitter("2:255-260") // returns { ayah: 255, ayahTo: 260, surahOrAyah: 2 }
* stringNumberSplitter("invalid") // returns null
*/
function string2NumberSplitter(str) {
const sr = /(?<surah>\d{1,3})\D*(?<ayah>\d{0,3})\D*(?<ayahTo>\d{0,3})/.exec(str);
if (sr?.groups && +sr.groups.surah > 0) {
const { ayah, ayahTo, surah } = sr.groups;
return {
surahOrAyah: +surah,
ayah: +ayah,
ayahTo: +ayahTo
};
}
return null;
}
/**
* Splits a string in the format "surah:ayah" or "surah:ayah-ayah" into its numeric components.
*
* @param str - The input string to parse in the format "surah:ayah" or "surah:ayah-ayah"
* @returns An object containing the parsed numbers:
* - surahOrAyah: The surah number
* - ayah: The first or only ayah number
* - ayahTo: The ending ayah number (if range specified)
* @throws {@link Error} When the input string format is invalid or contains non-numeric values
*
* @example
* string2NumberSplitterStrict("2:255") // returns { surahOrAyah: 2, ayah: 255, ayahTo: NaN }
* string2NumberSplitterStrict("2:255-260") // returns { surahOrAyah: 2, ayah: 255, ayahTo: 260 }
*/
function string2NumberSplitterStrict(str) {
let [surahStr, ayahsStr] = str.trim().split(":");
surahStr = surahStr.trim();
const surahX = parseInt(surahStr.trim(), 10);
if (isNaN(surahX)) throw new Error("Error in surah format " + str);
ayahsStr = ayahsStr.trim();
if (!ayahsStr) throw new Error("Error in data " + str);
let ayahs;
if (ayahsStr.includes("-")) ayahs = ayahsStr.split("-").map((a) => {
const ayahX = parseInt(a, 10);
if (isNaN(ayahX)) throw new Error("Error in surah format " + str);
return ayahX;
});
else {
const ayahX = parseInt(ayahsStr, 10);
if (isNaN(ayahX)) throw new Error("Error in surah format " + str);
ayahs = [ayahX, NaN];
}
return {
surahOrAyah: +surahX,
ayah: +ayahs[0],
ayahTo: +ayahs[1]
};
}
//#endregion
exports.ayahStringSplitter = ayahStringSplitter;
exports.string2NumberSplitter = string2NumberSplitter;
exports.string2NumberSplitterStrict = string2NumberSplitterStrict;