// This code was written by Jeremy and Jason Wall. // Feel free to use, and if you can, include a link back to www.walljm.com // Jason@walljm.com // www.walljm.com // Jeremy@marzhillstudios.com // jeremy.marzhillstudios.com String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ""); }; String.prototype.ltrim = function() { return this.replace(/^\s+/, ""); }; String.prototype.rtrim = function() { return this.replace(/\s+$/, ""); }; function parseReference(ref, r) { var rest = parseBook(ref, r.start, r); rest = parseFirstNum(rest, r.start, r); rest = maybeParseSecondNum(rest, r.start, r); rest = maybeParseRangeSep(rest, r, r); rest = maybeParseBook(rest, r.end, r); rest = maybeParseFirstNumOrVerse(rest, r.end, r); rest = maybeParseSecondNum(rest, r.end, r); return r; } function parseBook(ref, data, errAcc) { ref = ref.toLowerCase().trim(); var fbook = ref.substring(0, ref.search(/\w\s+\d/i)+1); var rest = ref.slice(ref.search(/\w\s+\d/i)+1); if (fbook.search(/\b(genesis|gen|ge|gn)\b/i) != -1) { data.book = 1; data.bookname = "Genesis"; data.longbookname = "Genesis"; data.lastchapter = 50; } if (fbook.search(/\b(exodus|ex|exo|exod|exd)\b/i) != -1) { data.book = 2; data.bookname = "Exodus"; data.longbookname = "Exodus"; data.lastchapter = 40; } if (fbook.search(/\b(leviticus|lev|le|levi|lv)\b/i) != -1) { data.book = 3; data.bookname = "Leviticus"; data.longbookname = "Leviticus"; data.lastchapter = 27; } if (fbook.search(/\b(numbers|num|nu|numb|number)\b/i) != -1) { data.book = 4; data.bookname = "Numbers"; data.longbookname = "Book_of_Numbers"; data.lastchapter = 36; } if (fbook.search(/\b(deuteronomy|deut|de|dt|deu)\b/i) != -1) { data.book = 5; data.bookname = "Deuteronomy"; data.longbookname = "Deuteronomy"; data.lastchapter = 34; } if (fbook.search(/\b(joshua|josh|jos)\b/i) != -1) { data.book = 6; data.bookname = "Joshua"; data.longbookname = "Book_of_Joshua"; data.lastchapter = 24; } if (fbook.search(/\b(judges|jud|ju|jdg|judg)\b/i) != -1) { data.book = 7; data.bookname = "Judges"; data.longbookname = "Book_of_Judges"; data.lastchapter = 21; } if (fbook.search(/\b(ruth|ru)\b/i) != -1) { data.book = 8; data.bookname = "Ruth"; data.longbookname = "Book_of_Ruth"; data.lastchapter = 4; } if (fbook.search(/\b(1|i|1st|first)\s*(samuel|sa|sam|sml)\b/i) != -1) { data.book = 9; data.bookname = "1 Samuel"; data.longbookname = "First_Samuel"; data.lastchapter = 31; } if (fbook.search(/\b(2|ii|2nd|second|sec)\s*(samuel|sa|sam|sml)\b/i) != -1) { data.book = 10; data.bookname = "2 Samuel"; data.longbookname = "Second_Samuel"; data.lastchapter = 24; } if (fbook.search(/\b(1|i|1st|first)\s*(kings|king|kgs|kn|k|ki)\b/i) != -1) { data.book = 11; data.bookname = "1 Kings"; data.longbookname = "First_Kings"; data.lastchapter = 22; } if (fbook.search(/\b(2|ii|2nd|second|sec)\s*(kings|king|kgs|kn|k|ki)\b/i) != -1) { data.book = 12; data.bookname = "2 Kings"; data.longbookname = "Second_Kings"; data.lastchapter = 25; } if (fbook.search(/\b(1|i|1st|first)\s*(chronicles|chron|ch|chr)\b/i) != -1) { data.book = 13; data.bookname = "1 Chronicles"; data.longbookname = "First_Chronicles"; data.lastchapter = 29; } if (fbook.search(/\b(2|ii|2nd|second|sec)\s*(chronicles|chron|ch|chr)\b/i) != -1) { data.book = 14; data.bookname = "2 Chronicles"; data.longbookname = "Second_Chronicles"; data.lastchapter = 36; } if (fbook.search(/\b(ezra|ez|ezr)\b/i) != -1) { data.book = 15; data.bookname = "Ezra"; data.longbookname = "Book_of_Ezra"; data.lastchapter = 10; } if (fbook.search(/\b(nehemiah|neh|ne|nehamiah)\b/i) != -1) { data.book = 16; data.bookname = "Nehemiah"; data.longbookname = "Book_of_Nehemiah"; data.lastchapter = 13; } if (fbook.search(/\b(esther|est|es|esth)\b/i) != -1) { data.book = 17; data.bookname = "Esther"; data.longbookname = "Book_of_Esther"; data.lastchapter = 10; } if (fbook.search(/\b(job|jo|jb)\b/i) != -1) { data.book = 18; data.bookname = "Job"; data.longbookname = "Book_of_Job"; data.lastchapter = 42; } if (fbook.search(/\b(psalms|ps|psa|psalm|psm)\b/i) != -1) { data.book = 19; data.bookname = "Psalm"; data.longbookname = "Psalm"; data.lastchapter = 150; } if (fbook.search(/\b(proverbs|prov|pr|pro|proverb|prv|prvbs)\b/i) != -1) { data.book = 20; data.bookname = "Proverbs"; data.longbookname = "Book_of_Proverbs"; data.lastchapter = 31; } if (fbook.search(/\b(ecclesiastes|eccl|ecc|eccles|ec|ecl|ecclesiaste)\b/i) != -1) { data.book = 21; data.bookname = "Ecclesiastes"; data.longbookname = "Ecclesiastes"; data.lastchapter = 12; } if (fbook.search(/\b(song\sof\ssolomon|song\sof\ssongs|sos|ss|son|so|song|songs)\b/i) != -1) { data.book = 22; data.bookname = "Song of Solomon"; data.longbookname = "Song_of_Solomon"; data.lastchapter = 8; } if (fbook.search(/\b(isaiah|is|is|isah|isai|ia)\b/i) != -1) { data.book = 23; data.bookname = "Isaiah"; data.longbookname = "Book_of_Isaiah"; data.lastchapter = 66; } if (fbook.search(/\b(jerimiah|jeremiah|jer|je|jere)\b/i) != -1) { data.book = 24; data.bookname = "Jeremiah"; data.longbookname = "Book_of_Jeremiah"; data.lastchapter = 52; } if (fbook.search(/\b(lamentations|lam|la|lamentation)\b/i) != -1) { data.book = 25; data.bookname = "Lamentations"; data.longbookname = "Book_of_Lamentations"; data.lastchapter = 5; } if (fbook.search(/\b(ezekiel|eze|ez|ezk|ezek)\b/i) != -1) { data.book = 26; data.bookname = "Ezekiel"; data.longbookname = "Book_of_Ezekiel"; data.lastchapter = 48; } if (fbook.search(/\b(daniel|dan|dn|dl|da)\b/i) != -1) { data.book = 27; data.bookname = "Daniel"; data.longbookname = "Book_of_Daniel"; data.lastchapter = 12; } if (fbook.search(/\b(hosea|hos|ho)\b/i) != -1) { data.book = 28; data.bookname = "Hosea"; data.longbookname = "Book_of_Hosea"; data.lastchapter = 14; } if (fbook.search(/\b(joel|joe|jl)\b/i) != -1) { data.book = 29; data.bookname = "Joel"; data.longbookname = "Book_of_Joel"; data.lastchapter = 3; } if (fbook.search(/\b(amos|am|amo)\b/i) != -1) { data.book = 30; data.bookname = "Amos"; data.longbookname = "Book_of_Amos"; data.lastchapter = 9; } if (fbook.search(/\b(obadiah|oba|ob|obad)\b/i) != -1) { data.book = 31; data.bookname = "Obadiah"; data.longbookname = "Book_of_Obadiah"; data.lastchapter = 1; } if (fbook.search(/\b(jonah|jnh|jon)\b/i) != -1) { data.book = 32; data.bookname = "Jonah"; data.longbookname = "Book_of_Jonah"; data.lastchapter = 4; } if (fbook.search(/\b(micah|mic|mi)\b/i) != -1) { data.book = 33; data.bookname = "Micah"; data.longbookname = "Book_of_Micah"; data.lastchapter = 7; } if (fbook.search(/\b(nahum|nah|na)\b/i) != -1) { data.book = 34; data.bookname = "Nahum"; data.longbookname = "Book_of_Nahum"; data.lastchapter = 3; } if (fbook.search(/\b(habakkuk|hab|ha|habakuk)\b/i) != -1) { data.book = 35; data.bookname = "Habakkuk"; data.longbookname = "Book_of_Habakkuk"; data.lastchapter = 3; } if (fbook.search(/\b(zephaniah|zeph|zep)\b/i) != -1) { data.book = 36; data.bookname = "Zephaniah"; data.longbookname = "Book_of_Zephaniah"; data.lastchapter = 3; } if (fbook.search(/\b(haggia|hag|hg|haggai)\b/i) != -1) { data.book = 37; data.bookname = "Haggai"; data.longbookname = "Book_of_Haggai"; data.lastchapter = 2; } if (fbook.search(/\b(zechariah|zech|zch|zec)\b/i) != -1) { data.book = 38; data.bookname = "Zechariah"; data.longbookname = "Book_of_Zechariah"; data.lastchapter = 14; } if (fbook.search(/\b(malachi|mal)\b/i) != -1) { data.book = 39; data.bookname = "Malachi"; data.longbookname = "Book_of_Malachi"; data.lastchapter = 4; } if (fbook.search(/\b(matthew|mt|matt|mat)\b/i) != -1) { data.book = 40; data.bookname = "Matthew"; data.longbookname = "Gospel_of_Matthew"; data.lastchapter = 28; } if (fbook.search(/\b(mark|mrk|mk|mr)\b/i) != -1) { data.book = 41; data.bookname = "Mark"; data.longbookname = "Gospel_of_Mark"; data.lastchapter = 16; } if (fbook.search(/\b(luke|lu|lke|luk|lk)\b/i) != -1) { data.book = 42; data.bookname = "Luke"; data.longbookname = "Gospel_of_Luke"; data.lastchapter = 24; } if (fbook.search(/\b(john|jn|jhn)\b/i) != -1) { data.book = 43; data.bookname = "John"; data.longbookname = "Gospel_of_John"; data.lastchapter = 21; } if (fbook.search(/\b(acts|ac|act)\b/i) != -1) { data.book = 44; data.bookname = "Acts"; data.longbookname = "Acts_of_the_Apostles"; data.lastchapter = 28; } if (fbook.search(/\b(romans|rom|ro|rm|roman)\b/i) != -1) { data.book = 45; data.bookname = "Romans"; data.longbookname = "Epistle_to_the_Romans"; data.lastchapter = 16; } if (fbook.search(/\b(1|i|1st|first)\s*(corinthian|cor|corinthians|corinth|corin|corth|corint)\b/i) != -1) { data.book = 46; data.bookname = "1 Corinthians"; data.longbookname = "First_Epistle_to_the_Corinthians"; data.lastchapter = 16; } if (fbook.search(/\b(2|ii|2nd|second|sec)\s*(corinthian|cor|corinthians|corinth|corin|corth|corint)\b/i) != -1) { data.book = 47; data.bookname = "2 Corinthians"; data.longbookname = "Second_Epistle_to_the_Corinthians"; data.lastchapter = 13; } if (fbook.search(/\b(galatians|galatian|galations|gal|ga|gala|galation|galat)\b/i) != -1) { data.book = 48; data.bookname = "Galatians"; data.longbookname = "Epistle_to_the_Galatians"; data.lastchapter = 6; } if (fbook.search(/\b(ephesians|eph|ep|ephes|ephe|ephs)\b/i) != -1) { data.book = 49; data.bookname = "Ephesians"; data.longbookname = "Epistle_to_the_Ephesians"; data.lastchapter = 6; } if (fbook.search(/\b(philippians|phi|phil|ph|philip)\b/i) != -1) { data.book = 50; data.bookname = "Philippians"; data.longbookname = "Epistle_to_the_Philippians"; data.lastchapter = 4; } if (fbook.search(/\b(colossians|col|co|colossian|colos|coloss)\b/i) != -1) { data.book = 51; data.bookname = "Colossians"; data.longbookname = "Epistle_to_the_Colossians"; data.lastchapter = 4; } if (fbook.search(/\b(1|i|1st|first)\s*(thessalonians|the|thessa|thessalonian|thes|thess|th)\b/i) != -1) { data.book = 52; data.bookname = "1 Thessalonians"; data.longbookname = "First_Epistle_to_the_Thessalonians"; data.lastchapter = 5; } if (fbook.search(/\b(2|ii|2nd|second|sec)\s*(thessalonians|the|thessa|thessalonian|thes|thess|th)\b/i) != -1) { data.book = 53; data.bookname = "2 Thessalonians"; data.longbookname = "Second_Epistle_to_the_Thessalonians"; data.lastchapter = 3; } if (fbook.search(/\b(1|i|1st|first)\s*(timothy|tim|ti|timoth|tm)\b/i) != -1) { data.book = 54; data.bookname = "1 Timothy"; data.longbookname = "First_Epistle_to_Timothy"; data.lastchapter = 6; } if (fbook.search(/\b(2|ii|2nd|second|sec)\s*(timothy|tim|timoth|tm)\b/i) != -1) { data.book = 55; data.bookname = "2 Timothy"; data.longbookname = "Second_Epistle_to_Timothy"; data.lastchapter = 4; } if (fbook.search(/\b(titus|tit)\b/i) != -1) { data.book = 56; data.bookname = "Titus"; data.longbookname = "Epistle_to_Titus"; data.lastchapter = 3; } if (fbook.search(/\b(philemon|phlmn|phl|phm|phile|philem)\b/i) != -1) { data.book = 57; data.bookname = "Philemon"; data.longbookname = "Epistle_to_Philemon"; data.lastchapter = 1; } if (fbook.search(/\b(hebrews|heb|he|hebrew)\b/i) != -1) { data.book = 58; data.bookname = "Hebrews"; data.longbookname = "Epistle_to_the_Hebrews"; data.lastchapter = 13; } if (fbook.search(/\b(james|jam|ja|jas|jms|jame|jm)\b/i) != -1) { data.book = 59; data.bookname = "James"; data.longbookname = "Epistle_of_James"; data.lastchapter = 5; } if (fbook.search(/\b(1|i|1st|first)\s*(peter|pe|pet|pete|pt|p)\b/i) != -1) { data.book = 60; data.bookname = "1 Peter"; data.longbookname = "First_Epistle_of_Peter"; data.lastchapter = 5; } if (fbook.search(/\b(2|ii|2nd|second|sec)\s*(peter|pe|pet|pete|pt|p)\b/i) != -1) { data.book = 61; data.bookname = "2 Peter"; data.longbookname = "Second_Epistle_of_Peter"; data.lastchapter = 3; } if (fbook.search(/\b(1|i|1st|first)\s*(john|jn|jo)\b/i) != -1) { data.book = 62; data.bookname = "1 John"; data.longbookname = "First_Epistle_of_John"; data.lastchapter = 5; } if (fbook.search(/\b(2|ii|2nd|second|sec)\s*(john|jn|jo)\b/i) != -1) { data.book = 63; data.bookname = "2 John"; data.longbookname = "Second_Epistle_of_John"; data.lastchapter = 1; } if (fbook.search(/\b(3|iii|3rd|third)\s*(john|jn|jo)\b/i) != -1) { data.book = 64; data.bookname = "3 John"; data.longbookname = "Third_Epistle_of_John"; data.lastchapter = 1; } if (fbook.search(/\b(jude|jud|ju)\b/i) != -1) { data.book = 65; data.bookname = "Jude"; data.longbookname = "Epistle_of_Jude"; data.lastchapter = 1; } if (fbook.search(/\b(revelation|rev|re|revelations|rv)\b/i) != -1) { data.book = 66; data.bookname = "Revelation"; data.longbookname = "Book_of_Revelations"; data.lastchapter = 22; } return rest; } function parseFirstNum(ref, r, errAcc) { ref = ref.ltrim(); var found = false; for (var i = 0; i <= ref.length; i++) { var c = ref.charAt(i); // Grab characters until we hit a non digit. if ("0".charAt(0) <= c && c <= "9".charAt(0)) { found = true; r.first = r.first.concat(c); } else { // if the chapter is longer than 3 digits it's an error if (r.first.length > 3) { errAcc.err = "Chapter too long\"" + r.first + "\"."; return ""; } else if (!found) { errAcc.err = "No chapter found" + ref; } return ref.slice(i); } } return ""; } function parseSecondNum(ref, r, errAcc, skipColon) { ref = ref.toLowerCase().ltrim(); if (!skipColon) { if (ref[0] != ":") { return ref; } ref = ref.slice(1); } ref = ref.toLowerCase().ltrim(); if (ref[0] == '*') { r.second = '*'; return ref.slice(1); } for (var i = 0; i <= ref.length; i++) { var c = ref.charAt(i); if ("0".charAt(0) <= c && c <= "9".charAt(0)) { r.second = r.second.concat(c); } else { if (r.second.length > 3) { errAcc.err = "Verse too long \"" + r.second + "\"."; return ""; } return ref.slice(i); } } return ""; } function maybeDo(ref, r, errAcc, f) { ref = ref.toLowerCase().ltrim(); if (ref != "") { return f(ref, r, errAcc); } return ""; } function maybeParseBook(ref, r, errAcc) { return maybeDo(ref, r, errAcc, parseBook); } function maybeParseSecondNum(ref, r, errAcc, skipColon) { return maybeDo(ref, r, errAcc, function (ref, r, errAcc) { return parseSecondNum(ref, r, errAcc, skipColon); }); } function maybeParseFirstNumOrVerse(ref, r, errAcc) { return maybeDo(ref, r, errAcc, function(ref, r, errAcc) { if (typeof r.book != -1) { if (ref.search(/:/) != -1) { ref = parseFirstNum(ref, r, errAcc); } return parseSecondNum(ref, r, errAcc, true); } return ""; }); } function maybeParseRangeSep(ref, r, errAcc) { return maybeDo(ref.ltrim(), r, errAcc, function(ref, r, errAcc) { if (ref[0] == "-") { return ref.slice(1).ltrim(); } return ""; }); } function Reference(ref) { r = { start: { first: '', second: '' }, end: { first: '', second: '' } }; // First collect all our tokens so to speak parseReference(ref.toLowerCase().trim(), r); this.book = r.start.book; this.bookname = r.start.bookname; this.longbookname = r.start.longbookname; this.startchapter = r.start.first; this.endchapter = r.start.first; this.startverse = '1'; // Then start our statemachine. // Determine start verse if (r.start.second != '') { this.startverse = r.start.second; this.endverse = '*'; } // Determine possible end verse if (r.end.second != '') { this.endverse = r.end.second; } // Enforce some general data cleanliness if (r.end.second != '*' && Number(r.end.second) < Number(r.start.second)) { this.endverse = this.startverse; } // Determine end chapter and verse if (r.end.first == '') { if (r.start.second == '' || typeof r.end.book != 'undefined') { this.endchapter = r.end.second || '1'; this.endverse = '*'; } } else { this.endchapter = r.end.first; } } function bookName(booknum) { var book = new Array(); book[0] = ""; book[1] = "Genesis"; book[2] = "Exodus"; book[3] = "Leviticus"; book[4] = "Numbers"; book[5] = "Deuteronomy"; book[6] = "Joshua"; book[7] = "Judges"; book[8] = "Ruth"; book[9] = "1 Samuel"; book[10] = "2 Samuel"; book[11] = "1 Kings"; book[12] = "2 Kings"; book[13] = "1 Chronicles"; book[14] = "2 Chronicles"; book[15] = "Ezra"; book[16] = "Nehemiah"; book[17] = "Esther"; book[18] = "Job"; book[19] = "Psalm"; book[20] = "Proverbs"; book[21] = "Ecclesiastes"; book[22] = "Song of Songs"; book[23] = "Isaiah"; book[24] = "Jeremiah"; book[25] = "Lamentations"; book[26] = "Ezekiel"; book[27] = "Daniel"; book[28] = "Hosea"; book[29] = "Joel"; book[30] = "Amos"; book[31] = "Obadiah"; book[32] = "Jonah"; book[33] = "Micah"; book[34] = "Nahum"; book[35] = "Habakkuk"; book[36] = "Zephaniah"; book[37] = "Haggai"; book[38] = "Zechariah"; book[39] = "Malachi"; book[40] = "Matthew"; book[41] = "Mark"; book[42] = "Luke"; book[43] = "John"; book[44] = "Acts"; book[45] = "Romans"; book[46] = "1 Corinthians"; book[47] = "2 Corinthians"; book[48] = "Galatians"; book[49] = "Ephesians"; book[50] = "Philippians"; book[51] = "Colossians"; book[52] = "1 Thessalonians"; book[53] = "2 Thessalonians"; book[54] = "1 Timothy"; book[55] = "2 Timothy"; book[56] = "Titus"; book[57] = "Philemon"; book[58] = "Hebrews"; book[59] = "James"; book[60] = "1 Peter"; book[61] = "2 Peter"; book[62] = "1 John"; book[63] = "2 John"; book[64] = "3 John"; book[65] = "Jude"; book[66] = "Revelation"; return book[booknum]; } Reference.prototype.toString = function() { var ref = this.bookname.concat(" "). concat(this.startchapter).concat(":"). concat(this.startverse); if (this.startchapter == this.endchapter) { return ref.concat("-").concat(this.endverse); } return ref.concat("-").concat(this.endchapter) .concat(":").concat(this.endverse); };