UNPKG

referenceparser

Version:

Parse a verse reference string to match for a book, chapter and verse

81 lines (80 loc) 4.31 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const generousBookNames_1 = __importDefault(require("./data/generousBookNames")); class ReferenceParser { constructor({ defaults = { book: null, chapter: null, verse: null } } = {}) { this._matchBook = (urlBook) => { const normedWordBreaks = urlBook.replace(/[_-]/g, " "); // This allows strings like IIKings => 2Kings (based on capital K, requires uppercase i) const capitalsToDetermineInitialIAsNumber = /^[IV]{1,3}[A-HJ-Z][a-z]+/.test(urlBook) ? normedWordBreaks .replace(/^VI/, "6") .replace(/^V/, "5") .replace(/^IV/, "4") .replace(/^IIII/, "4") // In case someone doesn't understand roman numerals .replace(/^III/, "3") .replace(/^II/, "2") .replace(/^I/, "1") : normedWordBreaks; // if there is an initial i/ii with a space, it's a number... const numberified = capitalsToDetermineInitialIAsNumber .replace(/^vi\b/i, "6") .replace(/^v\b/i, "5") .replace(/^iv\b/i, "4") .replace(/^iii\b/i, "3") .replace(/^ii\b/i, "2") .replace(/^i\b/i, "1"); // first see if we can map directly const possibleKey = numberified.replace(/[-_\ ]/g, "").toLowerCase(); const possibleMatches1 = generousBookNames_1.default.filter(b => b.forms.indexOf(possibleKey) > -1); if (possibleMatches1.length > 0) { // It's possible that there is more than one match here, // If that happens, we just return the first one. // Do a better job of not having conflicting forms... return possibleMatches1[0].name; } const possibleMatches2 = generousBookNames_1.default.filter(b => b.forms.filter(f => f.startsWith(possibleKey)).length > 0); if (possibleMatches2.length > 0) { // It's possible that there is more than one match here, // If that happens, we just return the first one. // Do a better job of not having conflicting forms... return possibleMatches2[0].name; } // we're going to insert one wildcard and move it backward through and then add another... // const possibleMatches3 = generousBookNames // .filter(b => // b.forms.filter(f => f.startsWith(possibleKey)).length > 0 // ) // if (possibleMatches3.length > 0) { // // It's possible that there is more than one match here, // // If that happens, we just return the first one. // // Do a better job of not having conflicting forms... // return possibleMatches3[0].name // } const urlArray = possibleKey.split(""); const regex = new RegExp("^" + urlArray.join(".*"), "i"); const possibleMatches4 = generousBookNames_1.default.filter(b => b.forms.filter(f => regex.test(f)).length > 0); if (possibleMatches4.length > 0) { // It's possible that there is more than one match here, // If that happens, we just return the first one. // Do a better job of not having conflicting forms... return possibleMatches4[0].name; } return false; }; let { book, chapter, verse } = defaults; this.defaults = { book, chapter, verse }; } parse(referenceString) { const matches = referenceString.match(/((?:(?:\d)[^a-zA-Z\d\s:]*)?[a-zA-Z-_\s\.]+)([^a-zA-Z\d:]*(\d+)(\D*(\d+))?)?/); return matches ? { book: this._matchBook(matches[1]) || this.defaults.book, chapter: matches[3] ? +matches[3] : this.defaults.chapter, verse: matches[5] ? +matches[5] : this.defaults.verse } : false; } } exports.default = ReferenceParser;