├── .gitmodules ├── webpack.config.js ├── webpack.config.production.js ├── scripts ├── sword.js ├── filterMgr.js ├── idbPluginWrapper.js ├── rawCom.js ├── worker.js ├── moduleMgr.js ├── filters │ ├── plain.js │ ├── thml.js │ └── osis.js ├── tools.js ├── verseKey.js ├── main.js ├── zText.js ├── module.js ├── versificationMgr.js ├── dataMgr.js └── installMgr.js ├── index.html ├── package.json ├── README.md └── data ├── german.json ├── kjv.json ├── vulg.json ├── mt.json ├── leningrad.json └── nrsv.json /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "libs/bcv"] 2 | path = libs/bcv 3 | url = git@github.com:openbibleinfo/Bible-Passage-Reference-Parser.git -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var webpack = require("webpack"); 2 | module.exports = { 3 | entry: "./scripts/main.js", 4 | output: { 5 | path: "./dist/js", 6 | filename: "sword.js" 7 | }, 8 | module: { 9 | loaders: [ 10 | { test: /\.json$/, loader: 'json'}, 11 | { test: "/en_bcv_parser.min.js/", loader: "exports?bcv_parser"} 12 | ], 13 | } 14 | }; -------------------------------------------------------------------------------- /webpack.config.production.js: -------------------------------------------------------------------------------- 1 | var webpack = require("webpack"); 2 | module.exports = { 3 | entry: "./scripts/sword.js", 4 | output: { 5 | path: "./dist/js", 6 | filename: "sword.min.js" 7 | }, 8 | module: { 9 | loaders: [ 10 | { test: /\.json$/, loader: 'json'}, 11 | { test: "/en_bcv_parser.min.js/", loader: "exports?bcv_parser"} 12 | ], 13 | }, 14 | plugins: [ 15 | new webpack.optimize.UglifyJsPlugin({minimize: true}) 16 | ] 17 | }; -------------------------------------------------------------------------------- /scripts/sword.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var installMgr = require("./installMgr"); 4 | var dataMgr = require("./dataMgr"); 5 | var moduleMgr = require("./moduleMgr"); 6 | var versificationMgr = require("./versificationMgr"); 7 | var verseKey = require("./verseKey"); 8 | 9 | //var sword = window.sword || {}; 10 | 11 | var sword = { 12 | installMgr: installMgr, 13 | dataMgr: dataMgr, 14 | moduleMgr: moduleMgr, 15 | verseKey: verseKey, 16 | versificationMgr: versificationMgr 17 | }; 18 | 19 | //BAD, but will be replaced in future, when BibleZ NG got a new frontend 20 | // window.sword = sword; 21 | 22 | module.exports = sword; -------------------------------------------------------------------------------- /scripts/filterMgr.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var osis = require("./filters/osis"); 3 | var plain = require("./filters/plain"); 4 | var thml = require("./filters/thml"); 5 | 6 | function processText(inRaw, inSource, inDirection, inOptions) { 7 | //console.log(inRaw, inSource, inDirection, inOptions); 8 | if(inSource && inSource.toLowerCase() === "osis") 9 | return osis.processText(inRaw, inDirection, inOptions); 10 | if(inSource && inSource.toLowerCase() === "thml") 11 | return thml.processText(inRaw, inDirection, inOptions); 12 | else 13 | return plain.processText(inRaw, inDirection, inOptions); 14 | } 15 | 16 | var filterMgr = { 17 | processText: processText 18 | }; 19 | 20 | module.exports = filterMgr; 21 | -------------------------------------------------------------------------------- /scripts/idbPluginWrapper.js: -------------------------------------------------------------------------------- 1 | var IDB = require("idb-wrapper"); 2 | 3 | var isInitialized = false, 4 | db = null; 5 | 6 | function getDB (inCallback) { 7 | if (isInitialized) { 8 | inCallback(null, db); 9 | } else { 10 | db = new IDB({ 11 | storeName: "swordjs", 12 | dbVersion: 4, 13 | autoIncrement: true, 14 | indexes: [ 15 | {name: "modules", keyPath: "moduleKey", unique: true} 16 | ], 17 | onStoreReady: function() { 18 | isInitialized = true; 19 | if(inCallback) inCallback(null, db); 20 | }, 21 | onError: function(inError) { 22 | isInitialized = false; 23 | if(inCallback) inCallback(inError); 24 | }, 25 | }); 26 | } 27 | } 28 | 29 | function getIDBWrapper () { 30 | return IDB; 31 | } 32 | 33 | var idbPluginWrapper = { 34 | getDB: getDB, 35 | getIDBWrapper: getIDBWrapper 36 | }; 37 | 38 | module.exports = idbPluginWrapper; -------------------------------------------------------------------------------- /scripts/rawCom.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var async = require("async"); 4 | 5 | var textReader = new FileReader(); 6 | 7 | function getRawEntry(inBlob, inPos, inVList, inEcoding, inIntro, inCallback) { 8 | console.log("inPos, inVList, inEcoding, inIntro", inPos, inVList, inEcoding, inIntro); 9 | 10 | var startPos = inPos.startPos, 11 | length = startPos + inPos.length, 12 | blob = inBlob.slice(startPos, length), 13 | rawText = [], 14 | z = 0; 15 | 16 | async.whilst( 17 | function () {return z < inVList.length;}, 18 | function (cb) { 19 | if (!inEcoding) 20 | textReader.readAsText(blob, "CP1252"); 21 | else 22 | textReader.readAsText(blob, inEcoding); 23 | 24 | textReader.onload = function(e) { 25 | if (e.target.result !== "") { 26 | rawText.push({text: e.target.result, osisRef: inVList[z].osisRef, verseData: inVList[z]}); 27 | z++; 28 | } 29 | cb(); 30 | }; 31 | }, 32 | function (inError) { 33 | //console.log(rawText); 34 | inCallback(inError, rawText); 35 | } 36 | ); 37 | } 38 | 39 | var rawCom = { 40 | getRawEntry: getRawEntry 41 | }; 42 | 43 | module.exports = rawCom; -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | swordJS Project 6 | 19 | 20 | 21 |

swordJS Project

22 |
Import your Module (*.zip):
23 | 24 | 25 |
26 |
27 |
28 | 29 | 30 |
31 |
32 | 33 |

34 |

35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /scripts/worker.js: -------------------------------------------------------------------------------- 1 | define(["has", "config"], function (has, config) { 2 | var cb = {}; 3 | var path = ""; 4 | if (has("build")) { 5 | path = config.workerPath + "/swordWorker.min.js"; 6 | } else { 7 | path = "swordWorker.min.js"; 8 | } 9 | var worker = new Worker(path); 10 | 11 | worker.addEventListener('message', function(e) { 12 | var cmd = e.data.cmd, 13 | result = e.data.result; 14 | if(cmd && cb[cmd]) { 15 | cb[cmd](null, result); 16 | delete cb[cmd]; 17 | } else { 18 | console.log(e.data); 19 | } 20 | 21 | return true; 22 | }, false); 23 | 24 | worker.addEventListener('error', function(e) { 25 | console.log('ERROR: ', e); 26 | return true; 27 | }, false); 28 | 29 | function getRawEntry(inBlob, bcvPos, vList, inEncoding, inIntro, inCallback) { 30 | cb["getRawEntry"] = inCallback; 31 | worker.postMessage({"cmd": "getRawEntry", "blob": inBlob, "bcvPos": bcvPos, "vList": vList, "encoding": inEncoding, "intro": inIntro}); 32 | } 33 | 34 | function processText(inRaw, inSource, inDirection, inOptions, inCallback) { 35 | cb["processText"] = inCallback; 36 | worker.postMessage({"cmd": "processText", "raw": inRaw, "source": inSource, "direction": inDirection, "options": inOptions}); 37 | } 38 | 39 | return { 40 | getRawEntry: getRawEntry, 41 | processText: processText 42 | }; 43 | }); -------------------------------------------------------------------------------- /scripts/moduleMgr.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dataMgr = require("./dataMgr"); 4 | var Module = require("./module"); 5 | 6 | 7 | function getModules(inCallback) { 8 | var modules = []; 9 | dataMgr.getModules(function (inError, inModules) { 10 | if(!inError) { 11 | inModules.forEach(function (mod) { 12 | modules.push(new Module(mod.moduleKey, mod.id, { 13 | id: mod.id, 14 | Versification: mod.Versification, 15 | Encoding: mod.Encoding, 16 | Direction: mod.Direction, 17 | SourceType: mod.SourceType, 18 | bcvPosID: mod.bcvPosID, 19 | description: mod.Description, 20 | language: mod.Lang, 21 | ot: mod.ot, 22 | nt: mod.nt, 23 | moduleKey: mod.moduleKey, 24 | modDrv: mod.ModDrv, 25 | conf: mod 26 | })); 27 | }); 28 | inCallback(null, modules); 29 | } else 30 | inCallback(inError); 31 | }); 32 | } 33 | 34 | function getModule(inId, inCallback) { 35 | dataMgr.get(inId, function (inError, inMod) { 36 | if(!inError) inCallback(null, new Module(inMod.moduleKey, inId, inMod)); 37 | else inCallback(null); 38 | }); 39 | } 40 | 41 | var moduleMgr = { 42 | getModule: getModule, 43 | getModules: getModules 44 | }; 45 | 46 | module.exports = moduleMgr; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "swordjs", 3 | "version": "0.1.8", 4 | "description": "swordjs - access modules from crosswire.org/sword in JS", 5 | "main": "scripts/sword.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/zefanja/swordjs" 9 | }, 10 | "scripts": { 11 | "start": "webpack-dev-server --hot --progress --colors", 12 | "build": "webpack --progress --colors --config webpack.config.production.js" 13 | }, 14 | "keywords": [ 15 | "gulp", 16 | "swordjs", 17 | "browserify" 18 | ], 19 | "author": "zefanja", 20 | "license": "GPLv3", 21 | "bugs": { 22 | "url": "https://github.com/zefanja/swordjs/issues" 23 | }, 24 | "homepage": "https://github.com/zefanja/swordjs", 25 | "dependencies": { 26 | "object-assign": "~2.0.0", 27 | "jszip": "~2.4.0", 28 | "async": "~0.9.0", 29 | "idb-wrapper": "~1.4.1", 30 | "pako": "~0.2.5", 31 | "sax": "~0.6.1" 32 | }, 33 | "devDependencies": { 34 | "browser-sync": "^1.6.2", 35 | "browserify": "^6.2.0", 36 | "del": "^0.1.3", 37 | "exports-loader": "^0.6.2", 38 | "gulp": "^3.8.9", 39 | "gulp-autoprefixer": "1.0.1", 40 | "gulp-changed": "^1.0.0", 41 | "gulp-concat": "~2.4.2", 42 | "gulp-csso": "^0.2.9", 43 | "gulp-notify": "^2.0.0", 44 | "gulp-uglify": "^1.0.1", 45 | "json-loader": "^0.5.1", 46 | "superagent": "^0.20.0", 47 | "vinyl-buffer": "^1.0.0", 48 | "vinyl-source-stream": "^1.0.0", 49 | "watchify": "^2.1.0", 50 | "webpack": "^1.7.3", 51 | "webpack-dev-server": "^1.14.1" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /scripts/filters/plain.js: -------------------------------------------------------------------------------- 1 | //* SWFilter Options 2 | var swFilterOptions = { 3 | oneVersePerLine: false, 4 | array: false 5 | }; 6 | 7 | function processText(inRaw, inDirection, inOptions) { 8 | var renderedText = "", 9 | outText = "", 10 | verseArray = []; 11 | 12 | if (!inOptions || inOptions === {}) { 13 | inOptions = swFilterOptions; 14 | } else { 15 | inOptions.oneVersePerLine = (inOptions.oneVersePerLine) ? inOptions.oneVersePerLine : swFilterOptions.oneVersePerLine; 16 | inOptions.array = (inOptions.array) ? inOptions.array : swFilterOptions.array; 17 | } 18 | 19 | for (var i=0; i " + inRaw[i].verse + " " : " " + inRaw[i].verse + " "; 21 | outText += (inDirection !== "RtoL") ? inRaw[i].text : "" + inRaw[i].text + ""; 22 | if (!inOptions.array) 23 | renderedText += (inOptions.oneVersePerLine) ? "
" + outText + "
" : "" + outText + ""; 24 | else 25 | verseArray.push({text: (inOptions.oneVersePerLine) ? "
" + outText + "
" : "" + outText + "", osisRef: inRaw[i].osisRef}); 26 | outText = ""; 27 | } 28 | 29 | if(inDirection === "RtoL") 30 | renderedText = "
" + renderedText + "
"; 31 | 32 | if(!inOptions.array) 33 | return {text: renderedText}; 34 | else 35 | return {verses: verseArray, rtol: (inDirection === "RtoL") ? true : false}; 36 | } 37 | 38 | var plain = { 39 | processText: processText 40 | }; 41 | 42 | module.exports = plain; -------------------------------------------------------------------------------- /scripts/filters/thml.js: -------------------------------------------------------------------------------- 1 | //* SWFilter Options 2 | var swFilterOptions = { 3 | oneVersePerLine: false, 4 | array: false 5 | }; 6 | 7 | function processText(inRaw, inDirection, inOptions) { 8 | var renderedText = "", 9 | outText = "", 10 | verseArray = []; 11 | 12 | if (!inOptions || inOptions === {}) { 13 | inOptions = swFilterOptions; 14 | } else { 15 | inOptions.oneVersePerLine = (inOptions.oneVersePerLine) ? inOptions.oneVersePerLine : swFilterOptions.oneVersePerLine; 16 | inOptions.array = (inOptions.array) ? inOptions.array : swFilterOptions.array; 17 | } 18 | 19 | for (var i=0; i " + inRaw[i].verse + " " : " " + inRaw[i].verse + " "; 21 | inRaw[i].text = inRaw[i].text.replace(/\n\n/g, "

"); 22 | outText += (inDirection !== "RtoL") ? inRaw[i].text : "" + inRaw[i].text + ""; 23 | if (!inOptions.array) 24 | renderedText += (inOptions.oneVersePerLine) ? "
" + outText + "
" : "" + outText + ""; 25 | else 26 | verseArray.push({text: (inOptions.oneVersePerLine) ? "
" + outText + "
" : "" + outText + "", osisRef: inRaw[i].osisRef}); 27 | outText = ""; 28 | } 29 | 30 | if(inDirection === "RtoL") 31 | renderedText = "
" + renderedText + "
"; 32 | 33 | if(!inOptions.array) 34 | return {text: renderedText}; 35 | else 36 | return {verses: verseArray, rtol: (inDirection === "RtoL") ? true : false}; 37 | } 38 | 39 | var thml = { 40 | processText: processText 41 | }; 42 | 43 | module.exports = thml; -------------------------------------------------------------------------------- /scripts/tools.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | //Read a modules conf file a return it as Object 4 | function readConf(inConfString) { 5 | var lines = inConfString.split(/[\r\n]+/g), 6 | configData = {}, 7 | splittedLine = null; 8 | 9 | configData["GlobalOptionFilter"] = []; 10 | configData["Feature"] = []; 11 | 12 | lines.forEach(function(line, index) { 13 | splittedLine = line.split(/=(.+)/); 14 | if (splittedLine[0] !== "") 15 | if (splittedLine[0].search(/\[.*\]/) !== -1) 16 | configData["moduleKey"] = splittedLine[0].replace("[", "").replace("]", ""); 17 | else 18 | if (splittedLine[0] === "GlobalOptionFilter") 19 | configData[splittedLine[0]].push(splittedLine[1]); 20 | else if (splittedLine[0] === "Feature") 21 | configData[splittedLine[0]].push(splittedLine[1]); 22 | else if (splittedLine[0] === "Versification") 23 | configData[splittedLine[0]] = splittedLine[1].toLowerCase(); 24 | else 25 | configData[splittedLine[0]] = splittedLine[1]; 26 | }); 27 | 28 | return configData; 29 | } 30 | 31 | function dynamicSort(property) { 32 | return function (obj1,obj2) { 33 | return obj1[property] > obj2[property] ? 1 34 | : obj1[property] < obj2[property] ? -1 : 0; 35 | }; 36 | } 37 | 38 | function dynamicSortMultiple() { 39 | /* 40 | * save the arguments object as it will be overwritten 41 | * note that arguments object is an array-like object 42 | * consisting of the names of the properties to sort by 43 | */ 44 | var props = arguments; 45 | return function (obj1, obj2) { 46 | var i = 0, result = 0, numberOfProperties = props.length; 47 | /* try getting a different result from 0 (equal) 48 | * as long as we have extra properties to compare 49 | */ 50 | while(result === 0 && i < numberOfProperties) { 51 | result = dynamicSort(props[i])(obj1, obj2); 52 | i++; 53 | } 54 | return result; 55 | }; 56 | } 57 | 58 | function cleanArray(actual){ 59 | var newArray = []; 60 | for(var i = 0; i 1) { 75 | --key.chapter; 76 | } else { 77 | key.chapter = (key.bookNum === 0) ? 1 : maxChapter; 78 | key.bookNum = (key.bookNum > 0) ? --key.bookNum : 0; 79 | key.book = versificationMgr.getBook(key.bookNum, inV11n).abbrev; 80 | } 81 | key.osisRef = key.book+"."+key.chapter; 82 | 83 | return key; 84 | } 85 | 86 | var verseKey = { 87 | parse: parseVkey, 88 | parseVerseList: parseVerseList, 89 | next: next, 90 | previous: previous 91 | }; 92 | 93 | module.exports = verseKey; -------------------------------------------------------------------------------- /scripts/main.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var sword = require("./sword"); 4 | 5 | function handleModuleSelect(evt) { 6 | sword.installMgr.installModule(evt.target.files[0], function (inError, inId) { 7 | if(!inError) 8 | console.log("Installed"); 9 | /*sword.moduleMgr.getModule(inId, function (inError, inModule) { 10 | console.log(inModule); 11 | document.getElementById("out").innerHTML = "Installed Module: " + inModule.modKey; 12 | });*/ 13 | else 14 | console.log("ERROR Installing Module", inError); 15 | }); 16 | } 17 | 18 | function clearDatabase (evt) { 19 | sword.dataMgr.clearDatabase(); 20 | } 21 | 22 | function removeModule(evt) { 23 | sword.installMgr.removeModule("SBLGNT", function (inError) { 24 | console.log(inError); 25 | if(!inError) 26 | console.log("Removed Module"); 27 | }); 28 | } 29 | 30 | function getText() { 31 | //console.log(document.getElementById("passageInput").value); 32 | sword.moduleMgr.getModules(function (inError, inModules) { 33 | if(inModules.length !== 0) { 34 | console.log(inModules); 35 | inModules[0].renderText(document.getElementById("passageInput").value, { 36 | footnotes: false, 37 | crossReferences: true, 38 | oneVersePerLine: true, 39 | headings: true, 40 | wordsOfChristInRed: true, 41 | intro: true, 42 | array: false 43 | }, function (inError, inResult) { 44 | console.log(inError, inResult); 45 | document.getElementById("out").innerHTML = inResult.text; 46 | if(inResult.footnotes) 47 | for (var key in inResult.footnotes) { 48 | document.getElementById("notes").innerHTML += inResult.footnotes[key][0].note + "

"; 49 | } 50 | }); 51 | } else { 52 | document.getElementById("out").innerHTML = "No modules installed"; 53 | } 54 | }); 55 | } 56 | 57 | function next() { 58 | console.log(sword.verseKey.next(document.getElementById("passageInput").value)); 59 | document.getElementById("out").innerHTML = sword.verseKey.next(document.getElementById("passageInput").value); 60 | } 61 | 62 | function prev() { 63 | console.log(sword.verseKey.previous(document.getElementById("passageInput").value)); 64 | document.getElementById("out").innerHTML = sword.verseKey.previous(document.getElementById("passageInput").value); 65 | } 66 | 67 | function worker () { 68 | sword.installMgr.getRepositories("http://biblez.de/swordjs/getMasterlist.php", function (inError, inResult) { 69 | console.log(inError, inResult); 70 | sword.installMgr.getRemoteModules(inResult[2], "http://biblez.de/swordjs/getRemoteModules.php", function (inError, inModules) { 71 | console.log(inError, inModules); 72 | }) 73 | }); 74 | } 75 | 76 | document.getElementById("files").addEventListener('change', handleModuleSelect, false); 77 | document.getElementById("btnClear").addEventListener('click', clearDatabase, false); 78 | document.getElementById("btnRemove").addEventListener('click', removeModule, false); 79 | document.getElementById("btnPassage").addEventListener('click', getText, false); 80 | document.getElementById("btnNext").addEventListener('click', next, false); 81 | document.getElementById("btnPrev").addEventListener('click', prev, false); 82 | document.getElementById("btnWorker").addEventListener('click', worker, false); -------------------------------------------------------------------------------- /scripts/zText.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var async = require("async"); 4 | var pako = require("pako"); 5 | 6 | var zlibReader = new FileReader(), 7 | textReader = new FileReader(); 8 | 9 | 10 | function getRawEntry(inBlob, inPos, inVList, inEcoding, inIntro, inCallback) { 11 | //console.log("inPos, inVList, inEcoding, inIntro", inPos, inVList, inEcoding, inIntro) 12 | if (!inPos[inVList[0].chapter-1]) { 13 | inCallback({message: "Wrong passage. The requested chapter is not available in this module."}); 14 | } else { 15 | var bookStartPos = inPos[inVList[0].chapter-1].bookStartPos, 16 | startPos = inPos[inVList[0].chapter-1].startPos, 17 | length = inPos[inVList[0].chapter-1].length, 18 | chapterStartPos = bookStartPos + startPos, 19 | chapterEndPos = chapterStartPos + length, 20 | blob = inBlob.slice(bookStartPos, chapterEndPos); 21 | 22 | //Return Intro (=Book.Chapter.0) only, if vList.length > 1 or verseNumber === 1 23 | if(inVList.length === 1 && inVList[0].verse !== 1) { 24 | inIntro = false; 25 | } 26 | 27 | zlibReader.readAsArrayBuffer(blob); 28 | zlibReader.onload = function (evt) { 29 | var inflator = new pako.Inflate(); 30 | var view = new Uint8Array(evt.target.result); 31 | 32 | inflator.push(view, true); 33 | if (inflator.err) { 34 | inCallback(inflator.err); 35 | throw new Error(inflator.err); 36 | } 37 | 38 | //console.log(inflator.result); 39 | var infBlob = new Blob([inflator.result]); 40 | 41 | //Read raw text entry 42 | var rawText = [], 43 | verseStart = 0, 44 | verseEnd = 0, 45 | z = 0, 46 | gotIntro = false; 47 | async.whilst( 48 | function () {return z < inVList.length;}, 49 | function (cb) { 50 | if(inIntro && !gotIntro) { 51 | verseStart = (inVList[z].chapter === 1) ? 0 : inPos[inVList[z].chapter-2].startPos + inPos[inVList[z].chapter-2].length; 52 | verseEnd = startPos; 53 | } else { 54 | verseStart = startPos + inPos[inVList[z].chapter-1].verses[inVList[z].verse-1].startPos; 55 | verseEnd = verseStart + inPos[inVList[z].chapter-1].verses[inVList[z].verse-1].length; 56 | } 57 | if (!inEcoding) 58 | textReader.readAsText(infBlob.slice(verseStart, verseEnd), "CP1252"); 59 | else 60 | textReader.readAsText(infBlob.slice(verseStart, verseEnd), inEcoding); 61 | textReader.onload = function(e) { 62 | if(inIntro && !gotIntro) { 63 | if (e.target.result !== "") 64 | rawText.push({text: e.target.result, osisRef: inVList[z].book + "." + inVList[z].chapter + ".0", verse: 0}); 65 | gotIntro = true; 66 | } else { 67 | rawText.push({text: e.target.result, osisRef: inVList[z].osisRef, verse: inVList[z].verse}); 68 | z++; 69 | } 70 | cb(); 71 | }; 72 | }, 73 | function (inError) { 74 | //console.log(rawText); 75 | inCallback(inError, rawText); 76 | } 77 | ); 78 | 79 | }; 80 | } 81 | 82 | } 83 | 84 | var zText = { 85 | getRawEntry: getRawEntry 86 | }; 87 | 88 | module.exports = zText; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | sword.js 2 | ======= 3 | 4 | ```sword.js``` is a pure Javascript library to read the bible modules from [Crosswire](http://crosswire.org/sword). It currently supports only compressed (zText) bible modules. [BibleZ NG](https://github.com/zefanja/biblez-ng) is based on this library. 5 | 6 | Build 7 | ----- 8 | 9 | Install ```webpack``` an run ```npm run build```. For development use ```npm start``` and open ```http://localhost:8080/webpack-dev-server/``` in your browser. 10 | 11 | Usage 12 | ----- 13 | 14 | ```npm install swordjs``` then you can ```require``` it. 15 | 16 | API 17 | --- 18 | 19 | ```sword.js``` is currently in a alpha version, so the API will likely change in the future. 20 | 21 | Most API calls take a callback as the last argument. The callback will return ```null``` or an ```error``` as first argument. The second, third, ... argument is the reponse from the API. 22 | 23 | ### installMgr ### 24 | 25 | #### installMgr.getRepositories(inCallback) #### 26 | Get a list of all available repositories and takes a callback funtion as argument. The callback will return an array of the repositories as second argument (first will be ```null``` or an ```error```). Currently only the following CrossWire repos are supported: 27 | * main 28 | * beta 29 | * av11n 30 | * attic 31 | * Wycliffe 32 | * av11n attic 33 | 34 | #### installMgr.getRemoteModules(inRepo, inUrl, inCallback) #### 35 | Get a list of all modules in a repository. ```inRepo``` is an object containing the repository url and the repository type. ```inUrl``` is optional. The callback will return an array with all modules. 36 | 37 | #### installMgr.installModule(inUrl, inCallback, inProgressCallback) #### 38 | This will install a module from ```inUrl```. You can also pass a file blob from a zipped module file for offline installation as first argument. The callback will return ```null``` or an ```error``` as the first argument. The second callback is optional. It will report the progress of the module download. 39 | 40 | #### installMgr.removeModule(iModuleKey, inCallback) #### 41 | This will remove the module with the ```inModuleKey```. The callback will return ```null``` or an ```error``` as the first argument. 42 | 43 | ### moduleMgr ### 44 | 45 | ####moduleMgr.getModules(inCallback) #### 46 | This will return a list of all installed modules. 47 | 48 | ### Module ### 49 | Each module has the following properties and API: 50 | 51 | #### config #### 52 | This property contains the all the module information that is normally found in a modules *.conf file. 53 | 54 | #### renderText(inPassage, inOptions, inCallback) #### 55 | ```inPassage``` is a passage in a bible like ```Gen 1``` or ```Romans 3```. ```inOptions``` is an Object and optional. It can contain the following porperties (default values): 56 | 57 | ```javascript 58 | { 59 | oneVersePerLine: false, 60 | footnotes: false, 61 | crossReferences: false, 62 | headings: false, 63 | wordsOfChristInRed: false, 64 | intro: false, //show book or chapter introductions 65 | } 66 | ``` 67 | 68 | The callback will return an object as second argument: 69 | 70 | Example: 71 | ```javascript 72 | { 73 | text: "...", //the rendered text (HTML), 74 | footnotes: { 75 | "Gen.1.1": [{note: "/*Note text*/", n: "1"}, {...}], 76 | "Gen.1.4": [{note: "/*Note text*/", n: "2"}, {...}], 77 | ... 78 | } 79 | } 80 | ``` 81 | 82 | #### getAllBooks(inCallback) #### 83 | Returns a list of all books in a module. 84 | 85 | ###verseKey### 86 | 87 | #### verseKey.parse(inPassage, inV11n) #### 88 | Takes a passage (e.g. Matt 1:1) as argument an returns an object like this: 89 | 90 | ```javascript 91 | { 92 | osisRef: "Matt.1.1", 93 | book: "Matt", 94 | bookNum: 39, 95 | chapter: 1 96 | verse: 1 //this can also be NaN if you pass a passage the has no verse in it like "Matt 1". 97 | } 98 | ``` 99 | 100 | #### verseKey.next(inPassage, inV11n) #### 101 | Returns the next chapter that follows ```inPassage```. If you pass "Matt 1" you will get an verseKey object for "Matt 2". 102 | 103 | #### verseKey.previous(inPassage, inV11n) #### 104 | Returns the previous chapter that comes before ```inPassage```. If you pass "Mark 1" you will get an verseKey object for "Matt 28". 105 | 106 | Licence 107 | ------- 108 | 109 | ```sword.js``` is licenced under the GNU GPLv3. 110 | -------------------------------------------------------------------------------- /scripts/module.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dataMgr = require("./dataMgr"); 4 | var verseKey = require("./verseKey"); 5 | var zText = require("./zText"); 6 | var rawCom = require("./rawCom"); 7 | var filterMgr = require("./filterMgr"); 8 | var versificationMgr = require("./versificationMgr"); 9 | 10 | 11 | var otBin = null, 12 | ntBin = null; 13 | 14 | //Constructor 15 | function Module(inModName, inId, inConfig) { 16 | if (!(this instanceof Module)) { 17 | throw new TypeError("Module constructor cannot be called as a function."); 18 | } 19 | 20 | this.modKey = inModName; 21 | this.language = inConfig.language; 22 | this.id = inId; 23 | this.config = inConfig; 24 | } 25 | 26 | Module.create = function (inModName, inId, inConfig) { 27 | return new Module(inModName, inId, inConfig); 28 | }; 29 | 30 | //get a module's config 31 | function getConfig(inId, inCallback) { 32 | /*dataMgr.getDocument(inId, function (inError, inConfig) { 33 | if (!inError) 34 | inCallback(inConfig); 35 | });*/ 36 | } 37 | 38 | //get the module binary files 39 | function getBinaryBlob(inId, inCallback) { 40 | dataMgr.getBlob(inId, inCallback); 41 | } 42 | 43 | //Module Instance 44 | Module.prototype = { 45 | constructor: Module, 46 | self: this, 47 | 48 | renderText: function (inVKey, inOptions, inCallback) { 49 | var bcvPos = null, 50 | blobId = null, 51 | self = this; 52 | if (typeof inOptions === "function") 53 | inCallback = inOptions; 54 | var vList = verseKey.parseVerseList(inVKey, this.config.Versification); 55 | //console.log(vList); 56 | if(vList.length !== 0 && vList[0].osisRef !== "") { 57 | dataMgr.get(self.config.bcvPosID, function(inError, inBcv) { 58 | //console.log(inBcv); 59 | if(!inError) { 60 | if (inBcv.nt && (inBcv.nt.hasOwnProperty(vList[0].book) || inBcv.nt.hasOwnProperty(vList[0].osisRef))) { 61 | bcvPos = inBcv.nt[vList[0].book] || inBcv.nt[vList[0].osisRef]; 62 | blobId = self.config.nt; 63 | } else if (inBcv.ot && (inBcv.ot.hasOwnProperty(vList[0].book) || inBcv.ot.hasOwnProperty(vList[0].osisRef))) { 64 | bcvPos = inBcv.ot[vList[0].book] || inBcv.ot[vList[0].osisRef]; 65 | blobId = self.config.ot; 66 | } 67 | //console.log(bcvPos); 68 | 69 | if(bcvPos === null) { 70 | inCallback({message: "The requested chapter is not available in this module."}); 71 | } else { 72 | getBinaryBlob(blobId, function (inError, inBlob) { 73 | if (!inError) { 74 | if (self.config.modDrv === "zText" || self.config.modDrv === "zCom") { 75 | zText.getRawEntry(inBlob, bcvPos, vList, self.config.Encoding, inOptions.intro ? inOptions.intro : false, function (inError, inRaw) { 76 | //console.log(inError, inRaw); 77 | if (!inError) { 78 | var result = filterMgr.processText(inRaw, self.config.SourceType, self.config.Direction, inOptions); 79 | inCallback(null, result); 80 | } else 81 | inCallback(inError); 82 | }); 83 | } else if (self.config.modDrv === "RawCom") { 84 | rawCom.getRawEntry(inBlob, bcvPos, vList, self.config.Encoding, inOptions.intro ? inOptions.intro : false, function (inError, inRaw) { 85 | //console.log(inError, inRaw); 86 | if (!inError) { 87 | var result = filterMgr.processText(inRaw, self.config.SourceType, self.config.Direction, inOptions); 88 | inCallback(null, result); 89 | } else 90 | inCallback(inError); 91 | }); 92 | } 93 | 94 | } else { 95 | inCallback(inError); 96 | } 97 | 98 | }); 99 | } 100 | } else { 101 | inCallback(inError); 102 | } 103 | }); 104 | } else { 105 | inCallback({message: "Wrong passage. The requested chapter is not available in this module."}); 106 | } 107 | }, 108 | 109 | getAllBooks: function (inCallback) { 110 | versificationMgr.getAllBooks(this.config.bcvPosID, this.config.Versification, function (inError, inResult) { 111 | inCallback(inError, inResult); 112 | }); 113 | }, 114 | 115 | //inOsis can be Matt.3 116 | getVersesInChapter: function (inOsis) { 117 | return versificationMgr.getVersesInChapter(versificationMgr.getBookNum(inOsis.split(".")[0], this.config.Versification), inOsis.split(".")[1], this.config.Versification); 118 | } 119 | }; 120 | 121 | module.exports = Module; -------------------------------------------------------------------------------- /scripts/versificationMgr.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dataMgr = require("./dataMgr"); 4 | var kjv = require("../data/kjv.json"); 5 | var german = require("../data/german.json"); 6 | var catholic = require("../data/catholic.json"); 7 | var catholic2 = require("../data/catholic2.json"); 8 | var kjva = require("../data/kjva.json"); 9 | var leningrad = require("../data/leningrad.json"); 10 | var luther = require("../data/luther.json"); 11 | var lxx = require("../data/lxx.json"); 12 | var mt = require("../data/mt.json"); 13 | var nrsv = require("../data/nrsv.json"); 14 | var nrsva = require("../data/nrsva.json"); 15 | var orthodox = require("../data/orthodox.json"); 16 | var synodal = require("../data/synodal.json"); 17 | var synodalprot = require("../data/synodalprot.json"); 18 | var vulg = require("../data/vulg.json"); 19 | 20 | var versificationMgr = {}; 21 | 22 | versificationMgr.kjv = kjv; 23 | german["nt"] = kjv.nt; 24 | german["osisToBookNum"] = kjv.osisToBookNum; 25 | versificationMgr.german = german; 26 | versificationMgr.catholic = catholic; 27 | versificationMgr.catholic2 = catholic2; 28 | versificationMgr.kjva = kjva; 29 | versificationMgr.leningrad = leningrad; 30 | versificationMgr.luther = luther; 31 | versificationMgr.lxx = lxx; 32 | versificationMgr.mt = mt; 33 | versificationMgr.nrsv = nrsv; 34 | versificationMgr.nrsva = nrsva; 35 | versificationMgr.orthodox = orthodox; 36 | versificationMgr.synodal = synodal; 37 | versificationMgr.synodalprot = synodalprot; 38 | versificationMgr.vulg = vulg; 39 | 40 | function getBooksInOT (v11n) { 41 | if (v11n !== undefined && versificationMgr[v11n]) 42 | return versificationMgr[v11n].ot.length; 43 | else 44 | return versificationMgr.kjv.ot.length; 45 | } 46 | 47 | function getBooksInNT (v11n) { 48 | if (v11n !== undefined && versificationMgr[v11n]) 49 | return versificationMgr[v11n].nt.length; 50 | else 51 | return versificationMgr.kjv.nt.length; 52 | } 53 | 54 | function getChapterMax (inBookNum, v11n) { 55 | inBookNum = (inBookNum < 0) ? 0 : inBookNum; 56 | var booksOT = getBooksInOT(v11n); 57 | var testament = (inBookNum < booksOT) ? "ot" : "nt"; 58 | inBookNum = (inBookNum < booksOT) ? inBookNum : inBookNum - booksOT; 59 | if (v11n !== undefined && versificationMgr[v11n]) 60 | return versificationMgr[v11n][testament][inBookNum].maxChapter; 61 | else 62 | return versificationMgr.kjv[testament][inBookNum].maxChapter; 63 | } 64 | 65 | function getVersesInChapter (inBookNum, inChapter, v11n) { 66 | if (v11n !== undefined && versificationMgr[v11n]) 67 | return versificationMgr[v11n].versesInChapter[inBookNum][parseInt(inChapter, 10)-1]; 68 | else 69 | return versificationMgr.kjv.versesInChapter[inBookNum][parseInt(inChapter, 10)-1]; 70 | } 71 | 72 | function getBook(inBookNum, v11n) { 73 | inBookNum = (inBookNum < 0) ? 0 : inBookNum; 74 | var booksOT = getBooksInOT(v11n); 75 | var testament = (inBookNum < booksOT) ? "ot" : "nt"; 76 | inBookNum = (inBookNum < booksOT) ? inBookNum : inBookNum - booksOT; 77 | if (v11n !== undefined && versificationMgr[v11n]) 78 | return versificationMgr[v11n][testament][inBookNum]; 79 | else 80 | return versificationMgr.kjv[testament][inBookNum]; 81 | } 82 | 83 | function getBookNum(inOsis, v11n) { 84 | //console.log(inOsis, v11n, versificationMgr.kjv.osisToBookNum[inOsis]); 85 | if (v11n !== undefined && versificationMgr[v11n] && versificationMgr[v11n].osisToBookNum) 86 | return versificationMgr[v11n].osisToBookNum[inOsis]; 87 | else 88 | return versificationMgr.kjv.osisToBookNum[inOsis]; 89 | } 90 | 91 | function getAllBooks(inId, v11n, inCallback) { 92 | var books = []; 93 | /*if (v11n !== undefined && versificationMgr[v11n]) { 94 | books.push.apply(books, versificationMgr[v11n].ot); 95 | books.push.apply(books, versificationMgr[v11n].nt); 96 | } else { 97 | books.push.apply(books, versificationMgr.kjv.ot); 98 | books.push.apply(books, versificationMgr.kjv.nt); 99 | } 100 | return books;*/ 101 | var v11nData = (v11n && versificationMgr[v11n]) ? versificationMgr[v11n] : versificationMgr.kjv; 102 | dataMgr.get(inId, function (inError, inResult) { 103 | if(!inError) { 104 | if(inResult.hasOwnProperty("ot")) { 105 | var bnOt = 0; 106 | for (var otBook in inResult.ot) { 107 | bnOt = inResult.ot[otBook][0].booknum; 108 | v11nData.ot[bnOt]["bookNum"] = bnOt; 109 | books.push(v11nData.ot[bnOt]); 110 | } 111 | } 112 | if(inResult.hasOwnProperty("nt")) { 113 | var booksMax = getBooksInOT(v11n), 114 | bnNt = 0; 115 | for (var ntBook in inResult.nt) { 116 | bnNt = inResult.nt[ntBook][0].booknum-booksMax; 117 | v11nData.nt[bnNt]["bookNum"] = bnNt+booksMax; 118 | books.push(v11nData.nt[bnNt]); 119 | } 120 | } 121 | if (inCallback) inCallback(null, books); 122 | } else { 123 | if (inCallback) inCallback(inError); 124 | } 125 | }); 126 | } 127 | 128 | module.exports = { 129 | getBooksInOT: getBooksInOT, 130 | getBooksInNT: getBooksInNT, 131 | getChapterMax: getChapterMax, 132 | getVersesInChapter: getVersesInChapter, 133 | getBook: getBook, 134 | getBookNum: getBookNum, 135 | getAllBooks: getAllBooks 136 | }; -------------------------------------------------------------------------------- /scripts/dataMgr.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var JSZip = require("jszip"); 4 | var async = require("async"); 5 | var IDB = require("./idbPluginWrapper"); 6 | var tools = require("./tools"); 7 | 8 | //get some data by id 9 | function get(inId, inCallback) { 10 | IDB.getDB(function (inError, db) { 11 | if(!inError) 12 | db.get(inId, 13 | function (inResponse) { 14 | inCallback(null, inResponse); 15 | }, 16 | function (inError) {inCallback(inError);} 17 | ); 18 | else inCallback(inError); 19 | }); 20 | } 21 | 22 | //Read a module's config file and save it as an Object 23 | function saveConfig(inConfBlob, inCallback) { 24 | var confReader = new FileReader(); 25 | confReader.readAsText(inConfBlob); 26 | confReader.onload = function(e) { 27 | var configData = tools.readConf(e.target.result); 28 | 29 | //Save config data to the database and continue to build the index 30 | IDB.getDB(function (inError, db) { 31 | if(!inError) 32 | db.put(configData, 33 | function (inId) { 34 | inCallback(null, {id: inId, modKey: configData.moduleKey, modDrv: configData.ModDrv, v11n: configData.Versification}); 35 | }, 36 | function (inError) {inCallback(inError);} 37 | ); 38 | else { 39 | console.log(inError); 40 | //inCallback(inError); 41 | } 42 | }); 43 | }; 44 | } 45 | 46 | //Save the binary module files like *.bzz 47 | function saveModule(inFiles, inDoc, inCallback) { 48 | //console.log("saveModule", inFiles, inDoc); 49 | var z = inFiles.length, 50 | args = {}, 51 | path = null, 52 | driver = null; 53 | 54 | args.docId = inDoc.id; 55 | 56 | async.eachSeries(inFiles, function (file, ittCallback) { 57 | var path = file.name.split("/"), 58 | driver = path[path.length-3]; 59 | IDB.getDB(function (inError, db) { 60 | if(!inError) 61 | db.put({fileName: path[path.length-1], modKey: inDoc.modKey, driver: driver, blob: file.blob}, 62 | function (inId) { 63 | args[path[path.length-1].split(".")[0]] = inId; 64 | ittCallback(null); 65 | }, 66 | function (inError) {ittCallback(inError);} 67 | ); 68 | else inCallback(inError); 69 | }); 70 | }, function (inError) { 71 | if(!inError) updateBinaryIds(args, inCallback); 72 | else inCallback(inError); 73 | }); 74 | } 75 | 76 | function updateBinaryIds(inIds, inCallback) { 77 | //console.log("updateBinaryIds", inIds, inCallback); 78 | IDB.getDB(function (inError, db) { 79 | if(!inError) 80 | db.get(inIds.docId, 81 | function (inModule) { 82 | inModule.nt = inIds.nt; 83 | inModule.ot = inIds.ot; 84 | db.put(inModule, function(inResponse) { 85 | inCallback(null); 86 | }, 87 | function (inError) {inCallback(inError);} 88 | ); 89 | }, 90 | function (inError) {inCallback(inError);} 91 | ); 92 | else inCallback(inError); 93 | }); 94 | } 95 | 96 | function getBlob(inId, inCallback) { 97 | IDB.getDB(function (inError, db) { 98 | if(!inError) 99 | db.get(inId, 100 | function (inBlob) {inCallback(null, inBlob.blob);}, 101 | function (inError) {inCallback(inError);} 102 | ); 103 | else inCallback(inError); 104 | }); 105 | } 106 | 107 | function saveBCVPos(inOT, inNT, inDoc, inCallback) { 108 | IDB.getDB(function (inError, db) { 109 | if(!inError) 110 | db.put({modKey: inDoc.modKey, ot: inOT, nt: inNT}, 111 | function (inPosResId) { 112 | db.get(inDoc.id, 113 | function (inModule) { 114 | inModule["bcvPosID"] = inPosResId; 115 | db.put(inModule, 116 | function(inId) { 117 | inCallback(null); 118 | }, 119 | function (inError) {inCallback(inError);} 120 | ); 121 | }, 122 | function (inError) {inCallback(inError);} 123 | ); 124 | }, 125 | function (inError) {inCallback(inError);} 126 | ); 127 | else inCallback(inError); 128 | }); 129 | } 130 | 131 | function getModules(inCallback) { 132 | IDB.getDB(function (inError, db) { 133 | if(!inError) 134 | db.query(function (inResults) { 135 | inCallback(null, inResults); 136 | }, 137 | { 138 | onError: function (inError) {inCallback(inError);}, 139 | index: "modules" 140 | }); 141 | else inCallback(inError); 142 | }); 143 | } 144 | 145 | function remove(inId, inCallback) { 146 | IDB.getDB(function (inError, db) { 147 | if(!inError) 148 | db.remove(inId, 149 | inCallback(null), 150 | function (inError) { inCallback(inError);} 151 | ); 152 | else inCallback(inError); 153 | }); 154 | } 155 | 156 | function removeModule(inModuleKey, inCallback) { 157 | IDB.getDB(function (inError, db) { 158 | if(!inError) { 159 | getModules(function (inError, inModules) { 160 | if(!inError) { 161 | var found = false; 162 | inModules.forEach(function(mod) { 163 | if(mod.moduleKey === inModuleKey) { 164 | found = true; 165 | var a = (mod.blobIds) ? tools.convertObject(mod.blobIds) : [mod.bcvPosID, mod.nt, mod.ot, mod.id]; 166 | //Remove undefined values 167 | a = a.filter(function(e){return e;}); 168 | db.removeBatch(a, 169 | function() { 170 | if(inCallback) inCallback(null); 171 | }, 172 | function(inError) { 173 | if (inCallback) inCallback(inError); 174 | } 175 | ); 176 | } 177 | }); 178 | if(!found) 179 | inCallback({message: "Couldn't find the module."}); 180 | } else if(inCallback) inCallback(inError); 181 | 182 | }); 183 | } else if(inCallback) inCallback(inError); 184 | }); 185 | } 186 | 187 | function clearDatabase() { 188 | IDB.getDB(function (inError, db) { 189 | if(!inError) 190 | db.clear( 191 | function () { 192 | //console.log("cleared database"); 193 | }, 194 | function (inError) { console.log(inError);} 195 | ); 196 | else inCallback(inError); 197 | }); 198 | } 199 | 200 | function getIDBWrapper () { 201 | return IDB.getIDBWrapper(); 202 | } 203 | 204 | function errorHandler(inError, inCallback) { 205 | console.log(inError, inCallback); 206 | } 207 | 208 | var dataMgr = { 209 | clearDatabase: clearDatabase, 210 | saveConfig: saveConfig, 211 | saveModule: saveModule, 212 | saveBCVPos: saveBCVPos, 213 | getBlob: getBlob, 214 | get: get, 215 | remove: remove, 216 | removeModule: removeModule, 217 | getModules: getModules, 218 | getIDBWrapper: getIDBWrapper 219 | }; 220 | 221 | module.exports = dataMgr; -------------------------------------------------------------------------------- /data/german.json: -------------------------------------------------------------------------------- 1 | { 2 | "ot": [ 3 | {"name": "Genesis", "abbrev": "Gen", "maxChapter": 50}, 4 | {"name": "Exodus", "abbrev": "Exod", "maxChapter": 40}, 5 | {"name": "Leviticus", "abbrev": "Lev", "maxChapter": 27}, 6 | {"name": "Numbers", "abbrev": "Num", "maxChapter": 36}, 7 | {"name": "Deuteronomy", "abbrev": "Deut", "maxChapter": 34}, 8 | {"name": "Joshua", "abbrev": "Josh", "maxChapter": 24}, 9 | {"name": "Judges", "abbrev": "Judg", "maxChapter": 21}, 10 | {"name": "Ruth", "abbrev": "Ruth", "maxChapter": 4}, 11 | {"name": "I Samuel", "abbrev": "1Sam", "maxChapter": 31}, 12 | {"name": "II Samuel", "abbrev": "2Sam", "maxChapter": 24}, 13 | {"name": "I Kings", "abbrev": "1Kgs", "maxChapter": 22}, 14 | {"name": "II Kings", "abbrev": "2Kgs", "maxChapter": 25}, 15 | {"name": "I Chronicles", "abbrev": "1Chr", "maxChapter": 29}, 16 | {"name": "II Chronicles", "abbrev": "2Chr", "maxChapter": 36}, 17 | {"name": "Ezra", "abbrev": "Ezra", "maxChapter": 10}, 18 | {"name": "Nehemiah", "abbrev": "Neh", "maxChapter": 13}, 19 | {"name": "Esther", "abbrev": "Esth", "maxChapter": 10}, 20 | {"name": "Job", "abbrev": "Job", "maxChapter": 42}, 21 | {"name": "Psalms", "abbrev": "Ps", "maxChapter": 150}, 22 | {"name": "Proverbs", "abbrev": "Prov", "maxChapter": 31}, 23 | {"name": "Ecclesiastes", "abbrev": "Eccl", "maxChapter": 12}, 24 | {"name": "Song of Solomon", "abbrev": "Song", "maxChapter": 8}, 25 | {"name": "Isaiah", "abbrev": "Isa", "maxChapter": 66}, 26 | {"name": "Jeremiah", "abbrev": "Jer", "maxChapter": 52}, 27 | {"name": "Lamentations", "abbrev": "Lam", "maxChapter": 5}, 28 | {"name": "Ezekiel", "abbrev": "Ezek", "maxChapter": 48}, 29 | {"name": "Daniel", "abbrev": "Dan", "maxChapter": 12}, 30 | {"name": "Hosea", "abbrev": "Hos", "maxChapter": 14}, 31 | {"name": "Joel", "abbrev": "Joel", "maxChapter": 4}, 32 | {"name": "Amos", "abbrev": "Amos", "maxChapter": 9}, 33 | {"name": "Obadiah", "abbrev": "Obad", "maxChapter": 1}, 34 | {"name": "Jonah", "abbrev": "Jonah", "maxChapter": 4}, 35 | {"name": "Micah", "abbrev": "Mic", "maxChapter": 7}, 36 | {"name": "Nahum", "abbrev": "Nah", "maxChapter": 3}, 37 | {"name": "Habakkuk", "abbrev": "Hab", "maxChapter": 3}, 38 | {"name": "Zephaniah", "abbrev": "Zeph", "maxChapter": 3}, 39 | {"name": "Haggai", "abbrev": "Hag", "maxChapter": 2}, 40 | {"name": "Zechariah", "abbrev": "Zech", "maxChapter": 14}, 41 | {"name": "Malachi", "abbrev": "Mal", "maxChapter": 3} 42 | ], 43 | "versesInChapter": [ 44 | [31, 25, 24, 26, 32, 22, 24, 22, 29, 32, 32, 20, 18, 24, 21, 16, 27, 33, 38, 18, 34, 24, 20, 67, 34, 35, 46, 22, 35, 43, 54, 33, 20, 31, 29, 43, 36, 30, 23, 23, 57, 38, 34, 34, 28, 34, 31, 22, 33, 26], 45 | 46 | [22, 25, 22, 31, 23, 30, 29, 28, 35, 29, 10, 51, 22, 31, 27, 36, 16, 27, 25, 26, 37, 30, 33, 18, 40, 37, 21, 43, 46, 38, 18, 35, 23, 35, 35, 38, 29, 31, 43, 38], 47 | 48 | [17, 16, 17, 35, 26, 23, 38, 36, 24, 20, 47, 8, 59, 57, 33, 34, 16, 30, 37, 27, 24, 33, 44, 23, 55, 46, 34], 49 | 50 | [54, 34, 51, 49, 31, 27, 89, 26, 23, 36, 35, 16, 33, 45, 41, 35, 28, 32, 22, 29, 35, 41, 30, 25, 19, 65, 23, 31, 39, 17, 54, 42, 56, 29, 34, 13], 51 | 52 | [46, 37, 29, 49, 33, 25, 26, 20, 29, 22, 32, 31, 19, 29, 23, 22, 20, 22, 21, 20, 23, 29, 26, 22, 19, 19, 26, 69, 28, 20, 30, 52, 29, 12], 53 | 54 | [18, 24, 17, 24, 15, 27, 26, 35, 27, 43, 23, 24, 33, 15, 63, 10, 18, 28, 51, 9, 45, 34, 16, 33], 55 | 56 | [36, 23, 31, 24, 31, 40, 25, 35, 57, 18, 40, 15, 25, 20, 20, 31, 13, 31, 30, 48, 25], 57 | 58 | [22, 23, 18, 22], 59 | 60 | [28, 36, 21, 22, 12, 21, 17, 22, 27, 27, 15, 25, 23, 52, 35, 23, 58, 30, 24, 42, 16, 23, 28, 23, 44, 25, 12, 25, 11, 31, 13], 61 | 62 | [27, 32, 39, 12, 25, 23, 29, 18, 13, 19, 27, 31, 39, 33, 37, 23, 29, 32, 44, 26, 22, 51, 39, 25], 63 | 64 | [53, 46, 28, 20, 32, 38, 51, 66, 28, 29, 43, 33, 34, 31, 34, 34, 24, 46, 21, 43, 29, 54], 65 | 66 | [18, 25, 27, 44, 27, 33, 20, 29, 37, 36, 20, 22, 25, 29, 39, 20, 41, 37, 37, 21, 26, 20, 37, 20, 30], 67 | 68 | [54, 55, 24, 43, 41, 66, 40, 40, 44, 14, 47, 41, 14, 17, 29, 43, 27, 17, 19, 8, 30, 19, 32, 31, 31, 32, 34, 21, 30], 69 | 70 | [18, 17, 17, 22, 14, 42, 22, 18, 31, 19, 23, 16, 23, 14, 19, 14, 19, 34, 11, 37, 20, 12, 21, 27, 28, 23, 9, 27, 36, 27, 21, 33, 25, 33, 27, 23], 71 | 72 | [11, 70, 13, 24, 17, 22, 28, 36, 15, 44], 73 | 74 | [11, 20, 38, 17, 19, 19, 73, 18, 37, 40, 36, 47, 31], 75 | 76 | [22, 23, 15, 17, 14, 14, 10, 17, 32, 3], 77 | 78 | [22, 13, 26, 21, 27, 30, 21, 22, 35, 22, 20, 25, 28, 22, 35, 22, 16, 21, 29, 29, 34, 30, 17, 25, 6, 14, 23, 28, 25, 31, 40, 22, 33, 37, 16, 33, 24, 41, 30, 32, 26, 17], 79 | 80 | [6, 12, 9, 9, 13, 11, 18, 10, 21, 18, 7, 9, 6, 7, 5, 11, 15, 51, 15, 10, 14, 32, 6, 10, 22, 12, 14, 9, 11, 13, 25, 11, 22, 23, 28, 13, 40, 23, 14, 18, 14, 12, 5, 27, 18, 12, 10, 15, 21, 23, 21, 11, 7, 9, 24, 14, 12, 12, 18, 14, 9, 13, 12, 11, 14, 20, 8, 36, 37, 6, 24, 20, 28, 23, 11, 13, 21, 72, 13, 20, 17, 8, 19, 13, 14, 17, 7, 19, 53, 17, 16, 16, 5, 23, 11, 13, 12, 9, 9, 5, 8, 29, 22, 35, 45, 48, 43, 14, 31, 7, 10, 10, 9, 8, 18, 19, 2, 29, 176, 7, 8, 9, 4, 8, 5, 6, 5, 6, 8, 8, 3, 18, 3, 3, 21, 26, 9, 8, 24, 14, 10, 8, 12, 15, 21, 10, 20, 14, 9, 6], 81 | 82 | [33, 22, 35, 27, 23, 35, 27, 36, 18, 32, 31, 28, 25, 35, 33, 33, 28, 24, 29, 30, 31, 29, 35, 34, 28, 28, 27, 28, 27, 33, 31], 83 | 84 | [18, 26, 22, 17, 19, 12, 29, 17, 18, 20, 10, 14], 85 | 86 | [17, 17, 11, 16, 16, 12, 14, 14], 87 | 88 | [31, 22, 26, 6, 30, 13, 25, 23, 20, 34, 16, 6, 22, 32, 9, 14, 14, 7, 25, 6, 17, 25, 18, 23, 12, 21, 13, 29, 24, 33, 9, 20, 24, 17, 10, 22, 38, 22, 8, 31, 29, 25, 28, 28, 25, 13, 15, 22, 26, 11, 23, 15, 12, 17, 13, 12, 21, 14, 21, 22, 11, 12, 19, 11, 25, 24], 89 | 90 | [19, 37, 25, 31, 31, 30, 34, 23, 25, 25, 23, 17, 27, 22, 21, 21, 27, 23, 15, 18, 14, 30, 40, 10, 38, 24, 22, 17, 32, 24, 40, 44, 26, 22, 19, 32, 21, 28, 18, 16, 18, 22, 13, 30, 5, 28, 7, 47, 39, 46, 64, 34], 91 | 92 | [22, 22, 66, 22, 22], 93 | 94 | [28, 10, 27, 17, 17, 14, 27, 18, 11, 22, 25, 28, 23, 23, 8, 63, 24, 32, 14, 44, 37, 31, 49, 27, 17, 21, 36, 26, 21, 26, 18, 32, 33, 31, 15, 38, 28, 23, 29, 49, 26, 20, 27, 31, 25, 24, 23, 35], 95 | 96 | [21, 49, 33, 34, 30, 29, 28, 27, 27, 21, 45, 13], 97 | 98 | [9, 25, 5, 19, 15, 11, 16, 14, 17, 15, 11, 15, 15, 10], 99 | 100 | [20, 27, 5, 21], 101 | 102 | [15, 16, 15, 13, 27, 14, 17, 14, 15], 103 | 104 | [21], 105 | 106 | [16, 11, 10, 11], 107 | 108 | [16, 13, 12, 14, 14, 16, 20], 109 | 110 | [14, 14, 19], 111 | 112 | [17, 20, 19], 113 | 114 | [18, 15, 20], 115 | 116 | [15, 23], 117 | 118 | [17, 17, 10, 14, 11, 15, 14, 23, 17, 12, 17, 14, 9, 21], 119 | 120 | [14, 17, 24], 121 | 122 | [25, 23, 17, 25, 48, 34, 29, 34, 38, 42, 30, 50, 58, 36, 39, 28, 27, 35, 30, 34, 46, 46, 39, 51, 46, 75, 66, 20], 123 | 124 | [45, 28, 35, 41, 43, 56, 37, 38, 50, 52, 33, 44, 37, 72, 47, 20], 125 | 126 | [80, 52, 38, 44, 39, 49, 50, 56, 62, 42, 54, 59, 35, 35, 32, 31, 37, 43, 48, 47, 38, 71, 56, 53], 127 | 128 | [51, 25, 36, 54, 47, 71, 53, 59, 41, 42, 57, 50, 38, 31, 27, 33, 26, 40, 42, 31, 25], 129 | 130 | [26, 47, 26, 37, 42, 15, 60, 40, 43, 48, 30, 25, 52, 28, 41, 40, 34, 28, 40, 38, 40, 30, 35, 27, 27, 32, 44, 31], 131 | 132 | [32, 29, 31, 25, 21, 23, 25, 39, 33, 21, 36, 21, 14, 23, 33, 27], 133 | 134 | [31, 16, 23, 21, 13, 20, 40, 13, 27, 33, 34, 31, 13, 40, 58, 24], 135 | 136 | [24, 17, 18, 18, 21, 18, 16, 24, 15, 18, 33, 21, 13], 137 | 138 | [24, 21, 29, 31, 26, 18], 139 | 140 | [23, 22, 21, 32, 33, 24], 141 | 142 | [30, 30, 21, 23], 143 | 144 | [29, 23, 25, 18], 145 | 146 | [10, 20, 13, 18, 28], 147 | 148 | [12, 17, 18], 149 | 150 | [20, 15, 16, 16, 25, 21], 151 | 152 | [18, 26, 17, 22], 153 | 154 | [16, 15, 15], 155 | 156 | [25], 157 | 158 | [14, 18, 19, 16, 14, 20, 28, 13, 28, 39, 40, 29, 25], 159 | 160 | [27, 26, 18, 17, 20], 161 | 162 | [25, 25, 22, 19, 14], 163 | 164 | [21, 22, 18], 165 | 166 | [10, 29, 24, 21, 21], 167 | 168 | [13], 169 | 170 | [15], 171 | 172 | [25], 173 | 174 | [20, 29, 22, 11, 14, 17, 17, 13, 21, 11, 19, 18, 18, 20, 8, 21, 18, 24, 21, 15, 27, 21] 175 | ] 176 | } 177 | -------------------------------------------------------------------------------- /data/kjv.json: -------------------------------------------------------------------------------- 1 | { 2 | "ot": [ 3 | {"name": "Genesis", "abbrev": "Gen", "maxChapter": 50}, 4 | {"name": "Exodus", "abbrev": "Exod", "maxChapter": 40}, 5 | {"name": "Leviticus", "abbrev": "Lev", "maxChapter": 27}, 6 | {"name": "Numbers", "abbrev": "Num", "maxChapter": 36}, 7 | {"name": "Deuteronomy", "abbrev": "Deut", "maxChapter": 34}, 8 | {"name": "Joshua", "abbrev": "Josh", "maxChapter": 24}, 9 | {"name": "Judges", "abbrev": "Judg", "maxChapter": 21}, 10 | {"name": "Ruth", "abbrev": "Ruth", "maxChapter": 4}, 11 | {"name": "I Samuel", "abbrev": "1Sam", "maxChapter": 31}, 12 | {"name": "II Samuel", "abbrev": "2Sam", "maxChapter": 24}, 13 | {"name": "I Kings", "abbrev": "1Kgs", "maxChapter": 22}, 14 | {"name": "II Kings", "abbrev": "2Kgs", "maxChapter": 25}, 15 | {"name": "I Chronicles", "abbrev": "1Chr", "maxChapter": 29}, 16 | {"name": "II Chronicles", "abbrev": "2Chr", "maxChapter": 36}, 17 | {"name": "Ezra", "abbrev": "Ezra", "maxChapter": 10}, 18 | {"name": "Nehemiah", "abbrev": "Neh", "maxChapter": 13}, 19 | {"name": "Esther", "abbrev": "Esth", "maxChapter": 10}, 20 | {"name": "Job", "abbrev": "Job", "maxChapter": 42}, 21 | {"name": "Psalms", "abbrev": "Ps", "maxChapter": 150}, 22 | {"name": "Proverbs", "abbrev": "Prov", "maxChapter": 31}, 23 | {"name": "Ecclesiastes", "abbrev": "Eccl", "maxChapter": 12}, 24 | {"name": "Song of Solomon", "abbrev": "Song", "maxChapter": 8}, 25 | {"name": "Isaiah", "abbrev": "Isa", "maxChapter": 66}, 26 | {"name": "Jeremiah", "abbrev": "Jer", "maxChapter": 52}, 27 | {"name": "Lamentations", "abbrev": "Lam", "maxChapter": 5}, 28 | {"name": "Ezekiel", "abbrev": "Ezek", "maxChapter": 48}, 29 | {"name": "Daniel", "abbrev": "Dan", "maxChapter": 12}, 30 | {"name": "Hosea", "abbrev": "Hos", "maxChapter": 14}, 31 | {"name": "Joel", "abbrev": "Joel", "maxChapter": 3}, 32 | {"name": "Amos", "abbrev": "Amos", "maxChapter": 9}, 33 | {"name": "Obadiah", "abbrev": "Obad", "maxChapter": 1}, 34 | {"name": "Jonah", "abbrev": "Jonah", "maxChapter": 4}, 35 | {"name": "Micah", "abbrev": "Mic", "maxChapter": 7}, 36 | {"name": "Nahum", "abbrev": "Nah", "maxChapter": 3}, 37 | {"name": "Habakkuk", "abbrev": "Hab", "maxChapter": 3}, 38 | {"name": "Zephaniah", "abbrev": "Zeph", "maxChapter": 3}, 39 | {"name": "Haggai", "abbrev": "Hag", "maxChapter": 2}, 40 | {"name": "Zechariah", "abbrev": "Zech", "maxChapter": 14}, 41 | {"name": "Malachi", "abbrev": "Mal", "maxChapter": 4} 42 | ], 43 | "nt": [ 44 | {"name": "Matthew", "abbrev": "Matt", "maxChapter": 28}, 45 | {"name": "Mark", "abbrev": "Mark", "maxChapter": 16}, 46 | {"name": "Luke", "abbrev": "Luke", "maxChapter": 24}, 47 | {"name": "John", "abbrev": "John", "maxChapter": 21}, 48 | {"name": "Acts", "abbrev": "Acts", "maxChapter": 28}, 49 | {"name": "Romans", "abbrev": "Rom", "maxChapter": 16}, 50 | {"name": "I Corinthians", "abbrev": "1Cor", "maxChapter": 16}, 51 | {"name": "II Corinthians", "abbrev": "2Cor", "maxChapter": 13}, 52 | {"name": "Galatians", "abbrev": "Gal", "maxChapter": 6}, 53 | {"name": "Ephesians", "abbrev": "Eph", "maxChapter": 6}, 54 | {"name": "Philippians", "abbrev": "Phil", "maxChapter": 4}, 55 | {"name": "Colossians", "abbrev": "Col", "maxChapter": 4}, 56 | {"name": "I Thessalonians", "abbrev": "1Thess", "maxChapter": 5}, 57 | {"name": "II Thessalonians", "abbrev": "2Thess", "maxChapter": 3}, 58 | {"name": "I Timothy", "abbrev": "1Tim", "maxChapter": 6}, 59 | {"name": "II Timothy", "abbrev": "2Tim", "maxChapter": 4}, 60 | {"name": "Titus", "abbrev": "Titus", "maxChapter": 3}, 61 | {"name": "Philemon", "abbrev": "Phlm", "maxChapter": 1}, 62 | {"name": "Hebrews", "abbrev": "Heb", "maxChapter": 13}, 63 | {"name": "James", "abbrev": "Jas", "maxChapter": 5}, 64 | {"name": "I Peter", "abbrev": "1Pet", "maxChapter": 5}, 65 | {"name": "II Peter", "abbrev": "2Pet", "maxChapter": 3}, 66 | {"name": "I John", "abbrev": "1John", "maxChapter": 5}, 67 | {"name": "II John", "abbrev": "2John", "maxChapter": 1}, 68 | {"name": "III John", "abbrev": "3John", "maxChapter": 1}, 69 | {"name": "Jude", "abbrev": "Jude", "maxChapter": 1}, 70 | {"name": "Revelation of John", "abbrev": "Rev", "maxChapter": 22} 71 | ], 72 | "osisToBookNum": { 73 | "Gen" : 0, 74 | "Exod" : 1, 75 | "Lev" : 2, 76 | "Num" : 3, 77 | "Deut" : 4, 78 | "Josh" : 5, 79 | "Judg" : 6, 80 | "Ruth" : 7, 81 | "1Sam" : 8, 82 | "2Sam" : 9, 83 | "1Kgs" : 10, 84 | "2Kgs" : 11, 85 | "1Chr" : 12, 86 | "2Chr" : 13, 87 | "Ezra" : 14, 88 | "Neh" : 15, 89 | "Esth" : 16, 90 | "Job" : 17, 91 | "Ps" : 18, 92 | "Prov" : 19, 93 | "Eccl" : 20, 94 | "Song" : 21, 95 | "Isa" : 22, 96 | "Jer" : 23, 97 | "Lam" : 24, 98 | "Ezek" : 25, 99 | "Dan" : 26, 100 | "Hos" : 27, 101 | "Joel" : 28, 102 | "Amos" : 29, 103 | "Obad" : 30, 104 | "Jonah" : 31, 105 | "Mic" : 32, 106 | "Nah" : 33, 107 | "Hab" : 34, 108 | "Zeph" : 35, 109 | "Hag" : 36, 110 | "Zech" : 37, 111 | "Mal" : 38, 112 | "Matt" : 39, 113 | "Mark" : 40, 114 | "Luke" : 41, 115 | "John" : 42, 116 | "Acts" : 43, 117 | "Rom" : 44, 118 | "1Cor" : 45, 119 | "2Cor" : 46, 120 | "Gal" : 47, 121 | "Eph" : 48, 122 | "Phil" : 49, 123 | "Col" : 50, 124 | "1Thess" : 51, 125 | "2Thess" : 52, 126 | "1Tim" : 53, 127 | "2Tim" : 54, 128 | "Titus" : 55, 129 | "Phlm" : 56, 130 | "Heb" : 57, 131 | "Jas" : 58, 132 | "1Pet" : 59, 133 | "2Pet" : 60, 134 | "1John" : 61, 135 | "2John" : 62, 136 | "3John" : 63, 137 | "Jude" : 64, 138 | "Rev" : 65 139 | }, 140 | "versesInChapter": [ 141 | [31, 25, 24, 26, 32, 22, 24, 22, 29, 32, 32, 20, 18, 24, 21, 16, 27, 33, 38, 142 | 18, 34, 24, 20, 67, 34, 35, 46, 22, 35, 43, 55, 32, 20, 31, 29, 43, 36, 143 | 30, 23, 23, 57, 38, 34, 34, 28, 34, 31, 22, 33, 26], 144 | 145 | [22, 25, 22, 31, 23, 30, 25, 32, 35, 29, 10, 51, 22, 31, 27, 36, 16, 27, 25, 146 | 26, 36, 31, 33, 18, 40, 37, 21, 43, 46, 38, 18, 35, 23, 35, 35, 38, 29, 147 | 31, 43, 38], 148 | 149 | [17, 16, 17, 35, 19, 30, 38, 36, 24, 20, 47, 8, 59, 57, 33, 34, 16, 30, 37, 150 | 27, 24, 33, 44, 23, 55, 46, 34], 151 | 152 | [54, 34, 51, 49, 31, 27, 89, 26, 23, 36, 35, 16, 33, 45, 41, 50, 13, 32, 22, 153 | 29, 35, 41, 30, 25, 18, 65, 23, 31, 40, 16, 54, 42, 56, 29, 34, 13], 154 | 155 | [46, 37, 29, 49, 33, 25, 26, 20, 29, 22, 32, 32, 18, 29, 23, 22, 20, 22, 21, 156 | 20, 23, 30, 25, 22, 19, 19, 26, 68, 29, 20, 30, 52, 29, 12], 157 | 158 | [18, 24, 17, 24, 15, 27, 26, 35, 27, 43, 23, 24, 33, 15, 63, 10, 18, 28, 51, 159 | 9, 45, 34, 16, 33], 160 | 161 | [36, 23, 31, 24, 31, 40, 25, 35, 57, 18, 40, 15, 25, 20, 20, 31, 13, 31, 30, 162 | 48, 25], 163 | 164 | [22, 23, 18, 22], 165 | 166 | [28, 36, 21, 22, 12, 21, 17, 22, 27, 27, 15, 25, 23, 52, 35, 23, 58, 30, 24, 167 | 42, 15, 23, 29, 22, 44, 25, 12, 25, 11, 31, 13], 168 | 169 | [27, 32, 39, 12, 25, 23, 29, 18, 13, 19, 27, 31, 39, 33, 37, 23, 29, 33, 43, 170 | 26, 22, 51, 39, 25], 171 | 172 | [53, 46, 28, 34, 18, 38, 51, 66, 28, 29, 43, 33, 34, 31, 34, 34, 24, 46, 21, 173 | 43, 29, 53], 174 | 175 | [18, 25, 27, 44, 27, 33, 20, 29, 37, 36, 21, 21, 25, 29, 38, 20, 41, 37, 37, 176 | 21, 26, 20, 37, 20, 30], 177 | 178 | [54, 55, 24, 43, 26, 81, 40, 40, 44, 14, 47, 40, 14, 17, 29, 43, 27, 17, 19, 179 | 8, 30, 19, 32, 31, 31, 32, 34, 21, 30], 180 | 181 | [17, 18, 17, 22, 14, 42, 22, 18, 31, 19, 23, 16, 22, 15, 19, 14, 19, 34, 11, 182 | 37, 20, 12, 21, 27, 28, 23, 9, 27, 36, 27, 21, 33, 25, 33, 27, 23], 183 | 184 | [11, 70, 13, 24, 17, 22, 28, 36, 15, 44], 185 | 186 | [11, 20, 32, 23, 19, 19, 73, 18, 38, 39, 36, 47, 31], 187 | 188 | [22, 23, 15, 17, 14, 14, 10, 17, 32, 3], 189 | 190 | [22, 13, 26, 21, 27, 30, 21, 22, 35, 22, 20, 25, 28, 22, 35, 22, 16, 21, 29, 191 | 29, 34, 30, 17, 25, 6, 14, 23, 28, 25, 31, 40, 22, 33, 37, 16, 33, 24, 41, 192 | 30, 24, 34, 17], 193 | 194 | [6, 12, 8, 8, 12, 10, 17, 9, 20, 18, 7, 8, 6, 7, 5, 11, 15, 50, 14, 9, 13, 195 | 31, 6, 10, 22, 12, 14, 9, 11, 12, 24, 11, 22, 22, 28, 12, 40, 22, 13, 17, 196 | 13, 11, 5, 26, 17, 11, 9, 14, 20, 23, 19, 9, 6, 7, 23, 13, 11, 11, 17, 12, 197 | 8, 12, 11, 10, 13, 20, 7, 35, 36, 5, 24, 20, 28, 23, 10, 12, 20, 72, 13, 198 | 19, 16, 8, 18, 12, 13, 17, 7, 18, 52, 17, 16, 15, 5, 23, 11, 13, 12, 9, 9, 199 | 5, 8, 28, 22, 35, 45, 48, 43, 13, 31, 7, 10, 10, 9, 8, 18, 19, 2, 29, 176, 200 | 7, 8, 9, 4, 8, 5, 6, 5, 6, 8, 8, 3, 18, 3, 3, 21, 26, 9, 8, 24, 13, 10, 7, 201 | 12, 15, 21, 10, 20, 14, 9, 6], 202 | 203 | [33, 22, 35, 27, 23, 35, 27, 36, 18, 32, 31, 28, 25, 35, 33, 33, 28, 24, 29, 204 | 30, 31, 29, 35, 34, 28, 28, 27, 28, 27, 33, 31], 205 | 206 | [18, 26, 22, 16, 20, 12, 29, 17, 18, 20, 10, 14], 207 | 208 | [17, 17, 11, 16, 16, 13, 13, 14], 209 | 210 | [31, 22, 26, 6, 30, 13, 25, 22, 21, 34, 16, 6, 22, 32, 9, 14, 14, 7, 25, 6, 211 | 17, 25, 18, 23, 12, 21, 13, 29, 24, 33, 9, 20, 24, 17, 10, 22, 38, 22, 8, 212 | 31, 29, 25, 28, 28, 25, 13, 15, 22, 26, 11, 23, 15, 12, 17, 13, 12, 21, 213 | 14, 21, 22, 11, 12, 19, 12, 25, 24], 214 | 215 | [19, 37, 25, 31, 31, 30, 34, 22, 26, 25, 23, 17, 27, 22, 21, 21, 27, 23, 15, 216 | 18, 14, 30, 40, 10, 38, 24, 22, 17, 32, 24, 40, 44, 26, 22, 19, 32, 21, 217 | 28, 18, 16, 18, 22, 13, 30, 5, 28, 7, 47, 39, 46, 64, 34], 218 | 219 | [22, 22, 66, 22, 22], 220 | 221 | [28, 10, 27, 17, 17, 14, 27, 18, 11, 22, 25, 28, 23, 23, 8, 63, 24, 32, 14, 222 | 49, 32, 31, 49, 27, 17, 21, 36, 26, 21, 26, 18, 32, 33, 31, 15, 38, 28, 223 | 23, 29, 49, 26, 20, 27, 31, 25, 24, 23, 35], 224 | 225 | [21, 49, 30, 37, 31, 28, 28, 27, 27, 21, 45, 13], 226 | 227 | [11, 23, 5, 19, 15, 11, 16, 14, 17, 15, 12, 14, 16, 9], 228 | 229 | [20, 32, 21], 230 | 231 | [15, 16, 15, 13, 27, 14, 17, 14, 15], 232 | 233 | [21], 234 | 235 | [17, 10, 10, 11], 236 | 237 | [16, 13, 12, 13, 15, 16, 20], 238 | 239 | [15, 13, 19], 240 | 241 | [17, 20, 19], 242 | 243 | [18, 15, 20], 244 | 245 | [15, 23], 246 | 247 | [21, 13, 10, 14, 11, 15, 14, 23, 17, 12, 17, 14, 9, 21], 248 | 249 | [14, 17, 18, 6], 250 | 251 | [25, 23, 17, 25, 48, 34, 29, 34, 38, 42, 30, 50, 58, 36, 39, 28, 27, 35, 30, 252 | 34, 46, 46, 39, 51, 46, 75, 66, 20], 253 | 254 | [45, 28, 35, 41, 43, 56, 37, 38, 50, 52, 33, 44, 37, 72, 47, 20], 255 | 256 | [80, 52, 38, 44, 39, 49, 50, 56, 62, 42, 54, 59, 35, 35, 32, 31, 37, 43, 48, 257 | 47, 38, 71, 56, 53], 258 | 259 | [51, 25, 36, 54, 47, 71, 53, 59, 41, 42, 57, 50, 38, 31, 27, 33, 26, 40, 42, 260 | 31, 25], 261 | 262 | [26, 47, 26, 37, 42, 15, 60, 40, 43, 48, 30, 25, 52, 28, 41, 40, 34, 28, 41, 263 | 38, 40, 30, 35, 27, 27, 32, 44, 31], 264 | 265 | [32, 29, 31, 25, 21, 23, 25, 39, 33, 21, 36, 21, 14, 23, 33, 27], 266 | 267 | [31, 16, 23, 21, 13, 20, 40, 13, 27, 33, 34, 31, 13, 40, 58, 24], 268 | 269 | [24, 17, 18, 18, 21, 18, 16, 24, 15, 18, 33, 21, 14], 270 | 271 | [24, 21, 29, 31, 26, 18], 272 | 273 | [23, 22, 21, 32, 33, 24], 274 | 275 | [30, 30, 21, 23], 276 | 277 | [29, 23, 25, 18], 278 | 279 | [10, 20, 13, 18, 28], 280 | 281 | [12, 17, 18], 282 | 283 | [20, 15, 16, 16, 25, 21], 284 | 285 | [18, 26, 17, 22], 286 | 287 | [16, 15, 15], 288 | 289 | [25], 290 | 291 | [14, 18, 19, 16, 14, 20, 28, 13, 28, 39, 40, 29, 25], 292 | 293 | [27, 26, 18, 17, 20], 294 | 295 | [25, 25, 22, 19, 14], 296 | 297 | [21, 22, 18], 298 | 299 | [10, 29, 24, 21, 21], 300 | 301 | [13], 302 | 303 | [14], 304 | 305 | [25], 306 | 307 | [20, 29, 22, 11, 14, 17, 17, 13, 21, 11, 19, 17, 18, 20, 8, 21, 18, 24, 21, 308 | 15, 27, 21] 309 | ] 310 | } -------------------------------------------------------------------------------- /scripts/filters/osis.js: -------------------------------------------------------------------------------- 1 | var bcvParser = require("../../libs/bcv/js/en_bcv_parser.min.js"); 2 | var bcv = new bcvParser.bcv_parser(); 3 | var sax = require("sax"); 4 | var parser = sax.parser(true); //strict = true 5 | 6 | //* SWFilter Options 7 | var swFilterOptions = { 8 | headings: false, 9 | footnotes: false, 10 | crossReferences: false, 11 | strongsNumbers: false, 12 | wordsOfChristInRed: false, 13 | oneVersePerLine: false, 14 | array: false 15 | }; 16 | 17 | var lastTag = "", 18 | currentNode = null, 19 | currentNote = null, 20 | currentRef = null, 21 | quote = null, 22 | verseData = null, 23 | noteText = "", 24 | outText = "", 25 | renderedText = "", 26 | verseArray = [], 27 | verseNumber = "", 28 | osisRef = "", 29 | footnotesData = {}, 30 | isSelfClosing = false, 31 | isTitle = false, 32 | noteCount = 0; 33 | 34 | function processText(inRaw, inDirection, inOptions) { 35 | if (!inOptions || inOptions === {}) { 36 | inOptions = swFilterOptions; 37 | } else { 38 | inOptions.headings = (inOptions.headings) ? inOptions.headings : swFilterOptions.headings; 39 | inOptions.footnotes = (inOptions.footnotes) ? inOptions.footnotes : swFilterOptions.footnotes; 40 | inOptions.crossReferences = (inOptions.crossReferences) ? inOptions.crossReferences : swFilterOptions.crossReferences; 41 | inOptions.strongsNumbers = (inOptions.strongsNumbers) ? inOptions.strongsNumbers : swFilterOptions.strongsNumbers; 42 | inOptions.wordsOfChristInRed = (inOptions.wordsOfChristInRed) ? inOptions.wordsOfChristInRed : swFilterOptions.wordsOfChristInRed; 43 | inOptions.oneVersePerLine = (inOptions.oneVersePerLine) ? inOptions.oneVersePerLine : swFilterOptions.oneVersePerLine; 44 | inOptions.array = (inOptions.array) ? inOptions.array : swFilterOptions.array; 45 | } 46 | 47 | lastTag = ""; 48 | currentNode = null; 49 | currentNote = null; 50 | currentRef = null; 51 | quote = null; 52 | title = null; 53 | titleText = ""; 54 | verseData = null; 55 | noteText = ""; 56 | outText = ""; 57 | renderedText = ""; 58 | verseArray = []; 59 | verseNumber = ""; 60 | osisRef = ""; 61 | footnotesData = {}; 62 | isTitle = false; 63 | noteCount = 0; 64 | 65 | //Handle Parsing errors 66 | parser.onerror = function (e) { 67 | parser.resume(); 68 | }; 69 | 70 | //Text node 71 | parser.ontext = function (t) { 72 | //console.log("TEXT:", t, currentNode); 73 | if (currentNote) { 74 | outText += processFootnotes(t, inOptions); 75 | } else if (quote) { 76 | if (quote.attributes.who === "Jesus" && inOptions.wordsOfChristInRed && t) { 77 | outText += "" + t + " "; 78 | } else 79 | outText += t; 80 | } else if (currentNode) { 81 | switch (currentNode.name) { 82 | case "title": 83 | if(inOptions.headings) { 84 | titleText += t; 85 | } 86 | break; 87 | case "divineName": 88 | if(title && inOptions.headings) { 89 | titleText += "" + t + ""; 90 | } 91 | break; 92 | case "hi": 93 | outText += tagHi(currentNode, t); 94 | break; 95 | default: 96 | outText += t; 97 | break; 98 | } 99 | } else { 100 | outText += t; 101 | } 102 | 103 | 104 | }; 105 | 106 | //Handle opening tags 107 | parser.onopentag = function (node) { 108 | //console.log(node); 109 | currentNode = node; 110 | lastTag = node.name; 111 | switch (node.name) { 112 | case "xml": 113 | verseData = {osisRef: node.attributes.osisRef, verseNum: node.attributes.verseNum}; 114 | if (parseInt(verseData.verseNum, 10) === 0) { 115 | if (inDirection === "RtoL") 116 | outText += "
"; 117 | else 118 | outText += ""; 119 | } else { 120 | if (inDirection === "RtoL") 121 | outText += " " + verseData.verseNum + " "; 122 | else 123 | outText += " " + verseData.verseNum + " "; 124 | } 125 | break; 126 | case "note": 127 | if (node.attributes.type === "crossReference" && inOptions.crossReferences) 128 | outText += "["; 129 | else if (inOptions.footnotes && node.attributes.type !== "crossReference") { 130 | osisRef = node.attributes.osisRef || node.attributes.annotateRef || verseData.osisRef; 131 | if (!node.attributes.n) noteCount++; 132 | var n = node.attributes.n || noteCount; 133 | outText += "" + "*n" + n + ""; 134 | } 135 | 136 | currentNote = node; 137 | break; 138 | case "reference": 139 | currentRef = node; 140 | break; 141 | case "q": 142 | if(!node.isSelfClosing && node.attributes.who === "Jesus") 143 | quote = node; 144 | break; 145 | case "title": 146 | title = node; 147 | if (title.attributes.type === "section") 148 | titleText += "

"; 149 | else 150 | titleText += "

"; 151 | break; 152 | case "div": 153 | if(node.isSelfClosing && node.attributes.type === "paragraph" && node.attributes.sID) 154 | outText += "

"; 155 | if(node.isSelfClosing && node.attributes.type === "paragraph" && node.attributes.eID) 156 | outText += "

"; 157 | break; 158 | case "l": 159 | if(node.isSelfClosing && node.attributes.type === "x-br") 160 | outText += "
"; 161 | break; 162 | } 163 | }; 164 | 165 | parser.onclosetag = function (tagName) { 166 | //console.log("CLOSE:", tagName); 167 | switch (tagName) { 168 | case "title": 169 | if (title.attributes.type === "section") 170 | outText = titleText + "

" + outText; 171 | else 172 | outText = titleText + "" + outText; 173 | currentNode = null; 174 | title = null; 175 | titleText = ""; 176 | break; 177 | case "note": 178 | if (currentNote.attributes.type === "crossReference" && inOptions.crossReferences) 179 | outText += "]
"; 180 | noteText = ""; 181 | currentNote = null; 182 | break; 183 | case "reference": 184 | currentRef = null; 185 | break; 186 | case "q": 187 | if (!currentNode && inOptions.wordsOfChristInRed) { 188 | //outText += "
"; 189 | quote = null; 190 | } 191 | break; 192 | case "xml": 193 | if(parseInt(verseData.verseNum, 10) === 0) 194 | outText += "
"; 195 | if(inDirection === "RtoL") 196 | outText += "
"; 197 | break; 198 | } 199 | lastTag = ""; 200 | currentNode = null; 201 | }; 202 | 203 | //Handling Attributes 204 | parser.onattribute = function (attr) { 205 | //console.log(attr); 206 | }; 207 | 208 | //End of parsing 209 | parser.onend = function () { 210 | //console.log("Finished parsing XML!"); 211 | }; 212 | 213 | var tmp = ""; 214 | for (var i=0; i" + inRaw[i].text + ""; 217 | parser.write(tmp); 218 | parser.close(); 219 | if (!inOptions.array) 220 | renderedText += (inOptions.oneVersePerLine) ? "
" + outText + "
" : "" + outText + ""; 221 | else 222 | verseArray.push({text: (inOptions.oneVersePerLine) ? "
" + outText + "
" : "" + outText + "", osisRef: inRaw[i].osisRef}); 223 | outText = ""; 224 | } 225 | 226 | if(inDirection === "RtoL") 227 | renderedText = "
" + renderedText + "
"; 228 | if(!inOptions.array) 229 | return {text: renderedText, footnotes: footnotesData}; 230 | else 231 | return {verses: verseArray, footnotes: footnotesData, rtol: (inDirection === "RtoL") ? true : false}; 232 | } 233 | 234 | /* FUNCTIONS TO PROCESS SPECIFIC OSIS TAGS */ 235 | 236 | function processFootnotes(t, inOptions) { 237 | var out = ""; 238 | if (currentNote.attributes.type === "crossReference" && inOptions.crossReferences) { 239 | if (lastTag !== "reference") 240 | out += processCrossReference(t); 241 | else { 242 | var crossRef = (currentRef) ? currentRef.attributes.osisRef : currentNote.attributes.osisRef; 243 | out += "" + t + ""; 244 | } 245 | } else if (inOptions.footnotes && currentNote.attributes.type !== "crossReference") { 246 | if (lastTag === "hi") { 247 | t = tagHi(currentNode, t); 248 | } 249 | osisRef = currentNote.attributes.osisRef || currentNote.attributes.annotateRef || verseData.osisRef; 250 | var n = currentNote.attributes.n || noteCount; 251 | if (!footnotesData.hasOwnProperty(osisRef)) 252 | footnotesData[osisRef] = [{note: t, n: n}]; 253 | else { 254 | if (footnotesData[osisRef][footnotesData[osisRef].length-1].n === n) 255 | footnotesData[osisRef][footnotesData[osisRef].length-1]["note"] += t; 256 | else 257 | footnotesData[osisRef].push({note: t, n: n}); 258 | } 259 | } 260 | return out; 261 | } 262 | 263 | function processCrossReference(inText) { 264 | var out = "", 265 | osisRef = bcv.parse(inText).osis(); 266 | if (osisRef !== "" && currentRef) { 267 | var n = currentRef.attributes.n || currentNote.attributes.n; 268 | out += "" + inText + ""; 269 | } else 270 | out += inText; 271 | return out; 272 | } 273 | 274 | function tagHi (node, t) { 275 | switch (node.attributes.type) { 276 | case "italic": 277 | t = ""+t+""; 278 | break; 279 | case "bold": 280 | t = ""+t+""; 281 | break; 282 | case "line-through": 283 | t = ""+t+""; 284 | break; 285 | case "underline": 286 | t = ""+t+""; 287 | break; 288 | case "sub": 289 | t = ""+t+""; 290 | break; 291 | case "super": 292 | t = ""+t+""; 293 | break; 294 | } 295 | 296 | return t; 297 | } 298 | 299 | var osis = { 300 | processText: processText 301 | }; 302 | 303 | //Return osis filter methods 304 | module.exports = osis; -------------------------------------------------------------------------------- /data/vulg.json: -------------------------------------------------------------------------------- 1 | { 2 | "ot": [ 3 | {"name": "Genesis", "abbrev": "Gen", "maxChapter": 50}, 4 | {"name": "Exodus", "abbrev": "Exod", "maxChapter": 40}, 5 | {"name": "Leviticus", "abbrev": "Lev", "maxChapter": 27}, 6 | {"name": "Numbers", "abbrev": "Num", "maxChapter": 36}, 7 | {"name": "Deuteronomy", "abbrev": "Deut", "maxChapter": 34}, 8 | {"name": "Joshua", "abbrev": "Josh", "maxChapter": 24}, 9 | {"name": "Judges", "abbrev": "Judg", "maxChapter": 21}, 10 | {"name": "Ruth", "abbrev": "Ruth", "maxChapter": 4}, 11 | {"name": "I Samuel", "abbrev": "1Sam", "maxChapter": 31}, 12 | {"name": "II Samuel", "abbrev": "2Sam", "maxChapter": 24}, 13 | {"name": "I Kings", "abbrev": "1Kgs", "maxChapter": 22}, 14 | {"name": "II Kings", "abbrev": "2Kgs", "maxChapter": 25}, 15 | {"name": "I Chronicles", "abbrev": "1Chr", "maxChapter": 29}, 16 | {"name": "II Chronicles", "abbrev": "2Chr", "maxChapter": 36}, 17 | {"name": "Ezra", "abbrev": "Ezra", "maxChapter": 10}, 18 | {"name": "Nehemiah", "abbrev": "Neh", "maxChapter": 13}, 19 | {"name": "Tobit", "abbrev": "Tob", "maxChapter": 14}, 20 | {"name": "Judith", "abbrev": "Jdt", "maxChapter": 16}, 21 | {"name": "Esther", "abbrev": "Esth", "maxChapter": 16}, 22 | {"name": "Job", "abbrev": "Job", "maxChapter": 42}, 23 | {"name": "Psalms", "abbrev": "Ps", "maxChapter": 150}, 24 | {"name": "Proverbs", "abbrev": "Prov", "maxChapter": 31}, 25 | {"name": "Ecclesiastes", "abbrev": "Eccl", "maxChapter": 12}, 26 | {"name": "Song of Solomon", "abbrev": "Song", "maxChapter": 8}, 27 | {"name": "Wisdom", "abbrev": "Wis", "maxChapter": 19}, 28 | {"name": "Sirach", "abbrev": "Sir", "maxChapter": 51}, 29 | {"name": "Isaiah", "abbrev": "Isa", "maxChapter": 66}, 30 | {"name": "Jeremiah", "abbrev": "Jer", "maxChapter": 52}, 31 | {"name": "Lamentations", "abbrev": "Lam", "maxChapter": 5}, 32 | {"name": "Baruch", "abbrev": "Bar", "maxChapter": 6}, 33 | {"name": "Ezekiel", "abbrev": "Ezek", "maxChapter": 48}, 34 | {"name": "Daniel", "abbrev": "Dan", "maxChapter": 14}, 35 | {"name": "Hosea", "abbrev": "Hos", "maxChapter": 14}, 36 | {"name": "Joel", "abbrev": "Joel", "maxChapter": 3}, 37 | {"name": "Amos", "abbrev": "Amos", "maxChapter": 9}, 38 | {"name": "Obadiah", "abbrev": "Obad", "maxChapter": 1}, 39 | {"name": "Jonah", "abbrev": "Jonah", "maxChapter": 4}, 40 | {"name": "Micah", "abbrev": "Mic", "maxChapter": 7}, 41 | {"name": "Nahum", "abbrev": "Nah", "maxChapter": 3}, 42 | {"name": "Habakkuk", "abbrev": "Hab", "maxChapter": 3}, 43 | {"name": "Zephaniah", "abbrev": "Zeph", "maxChapter": 3}, 44 | {"name": "Haggai", "abbrev": "Hag", "maxChapter": 2}, 45 | {"name": "Zechariah", "abbrev": "Zech", "maxChapter": 14}, 46 | {"name": "Malachi", "abbrev": "Mal", "maxChapter": 4}, 47 | {"name": "I Maccabees", "abbrev": "1Macc", "maxChapter": 16}, 48 | {"name": "II Maccabees", "abbrev": "2Macc", "maxChapter": 15} 49 | ], 50 | "nt": [ 51 | {"name": "Matthew", "abbrev": "Matt", "maxChapter": 28}, 52 | {"name": "Mark", "abbrev": "Mark", "maxChapter": 16}, 53 | {"name": "Luke", "abbrev": "Luke", "maxChapter": 24}, 54 | {"name": "John", "abbrev": "John", "maxChapter": 21}, 55 | {"name": "Acts", "abbrev": "Acts", "maxChapter": 28}, 56 | {"name": "Romans", "abbrev": "Rom", "maxChapter": 16}, 57 | {"name": "I Corinthians", "abbrev": "1Cor", "maxChapter": 16}, 58 | {"name": "II Corinthians", "abbrev": "2Cor", "maxChapter": 13}, 59 | {"name": "Galatians", "abbrev": "Gal", "maxChapter": 6}, 60 | {"name": "Ephesians", "abbrev": "Eph", "maxChapter": 6}, 61 | {"name": "Philippians", "abbrev": "Phil", "maxChapter": 4}, 62 | {"name": "Colossians", "abbrev": "Col", "maxChapter": 4}, 63 | {"name": "I Thessalonians", "abbrev": "1Thess", "maxChapter": 5}, 64 | {"name": "II Thessalonians", "abbrev": "2Thess", "maxChapter": 3}, 65 | {"name": "I Timothy", "abbrev": "1Tim", "maxChapter": 6}, 66 | {"name": "II Timothy", "abbrev": "2Tim", "maxChapter": 4}, 67 | {"name": "Titus", "abbrev": "Titus", "maxChapter": 3}, 68 | {"name": "Philemon", "abbrev": "Phlm", "maxChapter": 1}, 69 | {"name": "Hebrews", "abbrev": "Heb", "maxChapter": 13}, 70 | {"name": "James", "abbrev": "Jas", "maxChapter": 5}, 71 | {"name": "I Peter", "abbrev": "1Pet", "maxChapter": 5}, 72 | {"name": "II Peter", "abbrev": "2Pet", "maxChapter": 3}, 73 | {"name": "I John", "abbrev": "1John", "maxChapter": 5}, 74 | {"name": "II John", "abbrev": "2John", "maxChapter": 1}, 75 | {"name": "III John", "abbrev": "3John", "maxChapter": 1}, 76 | {"name": "Jude", "abbrev": "Jude", "maxChapter": 1}, 77 | {"name": "Revelation of John", "abbrev": "Rev", "maxChapter": 22}, 78 | {"name": "Prayer of Manasses", "abbrev": "PrMan", "maxChapter": 1}, 79 | {"name": "I Esdras", "abbrev": "1Esd", "maxChapter": 9}, 80 | {"name": "II Esdras", "abbrev": "2Esd", "maxChapter": 16}, 81 | {"name": "Additional Psalm", "abbrev": "AddPs", "maxChapter": 1}, 82 | {"name": "Laodiceans", "abbrev": "EpLao", "maxChapter": 1} 83 | ], 84 | "osisToBookNum": { 85 | "Gen" : 0, 86 | "Exod" : 1, 87 | "Lev" : 2, 88 | "Num" : 3, 89 | "Deut" : 4, 90 | "Josh" : 5, 91 | "Judg" : 6, 92 | "Ruth" : 7, 93 | "1Sam" : 8, 94 | "2Sam" : 9, 95 | "1Kgs" : 10, 96 | "2Kgs" : 11, 97 | "1Chr" : 12, 98 | "2Chr" : 13, 99 | "Ezra" : 14, 100 | "Neh" : 15, 101 | "Tob" : 16, 102 | "Jdt" : 17, 103 | "Esth" : 18, 104 | "Job" : 19, 105 | "Ps" : 20, 106 | "Prov" : 21, 107 | "Eccl" : 22, 108 | "Song" : 23, 109 | "Wis" : 24, 110 | "Sir" : 25, 111 | "Isa" : 26, 112 | "Jer" : 27, 113 | "Lam" : 28, 114 | "Bar" : 29, 115 | "Ezek" : 30, 116 | "Dan" : 31, 117 | "Hos" : 32, 118 | "Joel" : 33, 119 | "Amos" : 34, 120 | "Obad" : 35, 121 | "Jonah" : 36, 122 | "Mic" : 37, 123 | "Nah" : 38, 124 | "Hab" : 39, 125 | "Zeph" : 40, 126 | "Hag" : 41, 127 | "Zech" : 42, 128 | "Mal" : 43, 129 | "1Macc" : 44, 130 | "2Macc" : 45, 131 | "Matt" : 46, 132 | "Mark" : 47, 133 | "Luke" : 48, 134 | "John" : 49, 135 | "Acts" : 50, 136 | "Rom" : 51, 137 | "1Cor" : 52, 138 | "2Cor" : 53, 139 | "Gal" : 54, 140 | "Eph" : 55, 141 | "Phil" : 56, 142 | "Col" : 57, 143 | "1Thess": 58, 144 | "2Thess": 59, 145 | "1Tim" : 60, 146 | "2Tim" : 61, 147 | "Titus" : 62, 148 | "Phlm" : 63, 149 | "Heb" : 64, 150 | "Jas" : 65, 151 | "1Pet" : 66, 152 | "2Pet" : 67, 153 | "1John" : 68, 154 | "2John" : 69, 155 | "3John" : 70, 156 | "Jude" : 71, 157 | "Rev" : 72, 158 | "PrMan" : 73, 159 | "1Esd" : 74, 160 | "2Esd" : 75, 161 | "AddPs" : 76, 162 | "EpLao" : 77 163 | }, 164 | "versesInChapter": [ 165 | [31, 25, 24, 26, 31, 22, 24, 22, 29, 32, 32, 20, 18, 24, 21, 16, 27, 33, 38, 18, 34, 24, 20, 67, 34, 35, 46, 22, 35, 43, 55, 32, 20, 31, 29, 43, 36, 30, 23, 23, 57, 38, 34, 34, 28, 34, 31, 22, 32, 25], 166 | 167 | [22, 25, 22, 31, 23, 30, 25, 32, 35, 29, 10, 51, 22, 31, 27, 36, 16, 27, 25, 26, 36, 31, 33, 18, 40, 37, 21, 43, 46, 38, 18, 35, 23, 35, 35, 38, 29, 31, 43, 36], 168 | 169 | [17, 16, 17, 35, 19, 30, 38, 36, 24, 20, 47, 8, 59, 57, 33, 34, 16, 30, 37, 27, 24, 33, 44, 23, 55, 45, 34], 170 | 171 | [54, 34, 51, 49, 31, 27, 89, 26, 23, 36, 34, 15, 34, 45, 41, 50, 13, 32, 22, 30, 35, 41, 30, 25, 18, 65, 23, 31, 39, 17, 54, 42, 56, 29, 34, 13], 172 | 173 | [46, 37, 29, 49, 33, 25, 26, 20, 29, 22, 32, 32, 18, 29, 23, 22, 20, 22, 21, 20, 23, 30, 25, 22, 19, 19, 26, 68, 29, 20, 30, 52, 29, 12], 174 | 175 | [18, 24, 17, 25, 16, 27, 26, 35, 27, 43, 23, 24, 33, 15, 63, 10, 18, 28, 51, 9, 43, 34, 16, 33], 176 | 177 | [36, 23, 31, 24, 32, 40, 25, 35, 57, 18, 40, 15, 25, 20, 20, 31, 13, 31, 30, 48, 24], 178 | 179 | [22, 23, 18, 22], 180 | 181 | [28, 36, 21, 22, 12, 21, 17, 22, 27, 27, 15, 25, 23, 52, 35, 23, 58, 30, 24, 43, 15, 23, 28, 23, 44, 25, 12, 25, 11, 31, 13], 182 | 183 | [27, 32, 39, 12, 25, 23, 29, 18, 13, 19, 27, 31, 39, 33, 37, 23, 29, 33, 43, 26, 22, 51, 39, 25], 184 | 185 | [53, 46, 28, 34, 18, 38, 51, 66, 28, 29, 43, 33, 34, 31, 34, 34, 24, 46, 21, 43, 29, 54], 186 | 187 | [18, 25, 27, 44, 27, 33, 20, 29, 37, 36, 21, 21, 25, 29, 38, 20, 41, 37, 37, 21, 26, 20, 37, 20, 30], 188 | 189 | [54, 55, 24, 43, 26, 81, 40, 40, 44, 14, 46, 40, 14, 17, 29, 43, 27, 17, 19, 7, 30, 19, 32, 31, 31, 32, 34, 21, 30], 190 | 191 | [17, 18, 17, 22, 14, 42, 22, 18, 31, 19, 23, 16, 22, 15, 19, 14, 19, 34, 11, 37, 20, 12, 21, 27, 28, 23, 9, 27, 36, 27, 21, 33, 25, 33, 27, 23], 192 | 193 | [11, 70, 13, 24, 17, 22, 28, 36, 15, 44], 194 | 195 | [11, 20, 31, 23, 19, 19, 73, 18, 38, 39, 36, 46, 31], 196 | 197 | [25, 23, 25, 23, 28, 22, 20, 24, 12, 13, 21, 22, 23, 17], 198 | 199 | [12, 18, 15, 17, 29, 21, 25, 34, 19, 20, 21, 20, 31, 18, 15, 31], 200 | 201 | [22, 23, 15, 17, 14, 14, 10, 17, 32, 13, 12, 6, 18, 19, 19, 24], 202 | 203 | [22, 13, 26, 21, 27, 30, 21, 22, 35, 22, 20, 25, 28, 22, 35, 23, 16, 21, 29, 29, 34, 30, 17, 25, 6, 14, 23, 28, 25, 31, 40, 22, 33, 37, 16, 33, 24, 41, 35, 28, 25, 16], 204 | 205 | [6, 13, 9, 10, 13, 11, 18, 10, 39, 8, 9, 6, 7, 5, 11, 15, 51, 15, 10, 14, 32, 6, 10, 22, 12, 14, 9, 11, 13, 25, 11, 22, 23, 28, 13, 40, 23, 14, 18, 14, 12, 6, 26, 18, 12, 10, 15, 21, 23, 21, 11, 7, 9, 24, 13, 12, 12, 18, 14, 9, 13, 12, 11, 14, 20, 8, 36, 37, 6, 24, 20, 28, 23, 11, 13, 21, 72, 13, 20, 17, 8, 19, 13, 14, 17, 7, 19, 53, 17, 16, 16, 5, 23, 11, 13, 12, 9, 9, 5, 8, 29, 22, 35, 45, 48, 43, 14, 31, 7, 10, 10, 9, 26, 9, 10, 2, 29, 176, 7, 8, 9, 4, 8, 5, 7, 5, 6, 8, 8, 3, 18, 3, 3, 21, 27, 9, 8, 24, 14, 10, 8, 12, 15, 21, 10, 11, 9, 14, 9, 6], 206 | 207 | [33, 22, 35, 27, 23, 35, 27, 36, 18, 32, 31, 28, 25, 35, 33, 33, 28, 24, 29, 30, 31, 29, 35, 34, 28, 28, 27, 28, 27, 33, 31], 208 | 209 | [18, 26, 22, 17, 19, 11, 30, 17, 18, 20, 10, 14], 210 | 211 | [16, 17, 11, 16, 17, 12, 13, 14], 212 | 213 | [16, 25, 19, 20, 24, 27, 30, 21, 19, 21, 27, 27, 19, 31, 19, 29, 20, 25, 20], 214 | 215 | [40, 23, 34, 36, 18, 37, 40, 22, 25, 34, 36, 19, 32, 27, 22, 31, 31, 33, 28, 33, 31, 33, 38, 47, 36, 28, 33, 30, 35, 27, 42, 28, 33, 31, 26, 28, 34, 39, 41, 32, 28, 26, 37, 27, 31, 23, 31, 28, 19, 31, 38], 216 | 217 | [31, 22, 26, 6, 30, 13, 25, 22, 21, 34, 16, 6, 22, 32, 9, 14, 14, 7, 25, 6, 17, 25, 18, 23, 12, 21, 13, 29, 24, 33, 9, 20, 24, 17, 10, 22, 38, 22, 8, 31, 29, 25, 28, 28, 26, 13, 15, 22, 26, 11, 23, 15, 12, 17, 13, 12, 21, 14, 21, 22, 11, 12, 19, 12, 25, 24], 218 | 219 | [19, 37, 25, 31, 31, 30, 34, 22, 26, 25, 23, 17, 27, 22, 21, 21, 27, 23, 15, 18, 14, 30, 40, 10, 38, 24, 22, 17, 32, 24, 40, 44, 26, 22, 19, 32, 20, 28, 18, 16, 18, 22, 13, 30, 5, 28, 7, 47, 39, 46, 64, 34], 220 | 221 | [22, 22, 66, 22, 22], 222 | 223 | [22, 35, 38, 37, 9, 72], 224 | 225 | [28, 9, 27, 17, 17, 14, 27, 18, 11, 22, 25, 28, 23, 23, 8, 63, 24, 32, 14, 49, 32, 31, 49, 27, 17, 21, 36, 26, 21, 26, 18, 32, 33, 31, 15, 38, 28, 23, 29, 49, 26, 20, 27, 31, 25, 24, 23, 35], 226 | 227 | [21, 49, 100, 34, 31, 28, 28, 27, 27, 21, 45, 13, 65, 42], 228 | 229 | [11, 24, 5, 19, 15, 11, 16, 14, 17, 15, 12, 14, 15, 10], 230 | 231 | [20, 32, 21], 232 | 233 | [15, 16, 15, 13, 27, 15, 17, 14, 15], 234 | 235 | [21], 236 | 237 | [16, 11, 10, 11], 238 | 239 | [16, 13, 12, 13, 14, 16, 20], 240 | 241 | [15, 13, 19], 242 | 243 | [17, 20, 19], 244 | 245 | [18, 15, 20], 246 | 247 | [14, 24], 248 | 249 | [21, 13, 10, 14, 11, 15, 14, 23, 17, 12, 17, 14, 9, 21], 250 | 251 | [14, 17, 18, 6], 252 | 253 | [67, 70, 60, 61, 68, 63, 50, 32, 73, 89, 74, 54, 54, 49, 41, 24], 254 | 255 | [36, 33, 40, 50, 27, 31, 42, 36, 29, 38, 38, 46, 26, 46, 40], 256 | 257 | [25, 23, 17, 25, 48, 34, 29, 34, 38, 42, 30, 50, 58, 36, 39, 28, 26, 35, 30, 34, 46, 46, 39, 51, 46, 75, 66, 20], 258 | 259 | [45, 28, 35, 40, 43, 56, 37, 39, 49, 52, 33, 44, 37, 72, 47, 20], 260 | 261 | [80, 52, 38, 44, 39, 49, 50, 56, 62, 42, 54, 59, 35, 35, 32, 31, 37, 43, 48, 47, 38, 71, 56, 53], 262 | 263 | [51, 25, 36, 54, 47, 72, 53, 59, 41, 42, 57, 50, 38, 31, 27, 33, 26, 40, 42, 31, 25], 264 | 265 | [26, 47, 26, 37, 42, 15, 59, 40, 43, 48, 30, 25, 52, 27, 41, 40, 34, 28, 40, 38, 40, 30, 35, 27, 27, 32, 44, 31], 266 | 267 | [32, 29, 31, 25, 21, 23, 25, 39, 33, 21, 36, 21, 14, 23, 33, 27], 268 | 269 | [31, 16, 23, 21, 13, 20, 40, 13, 27, 33, 34, 31, 13, 40, 58, 24], 270 | 271 | [24, 17, 18, 18, 21, 18, 16, 24, 15, 18, 33, 21, 13], 272 | 273 | [24, 21, 29, 31, 26, 18], 274 | 275 | [23, 22, 21, 32, 33, 24], 276 | 277 | [30, 30, 21, 23], 278 | 279 | [29, 23, 25, 18], 280 | 281 | [10, 20, 13, 18, 28], 282 | 283 | [12, 17, 18], 284 | 285 | [20, 15, 16, 16, 25, 21], 286 | 287 | [18, 26, 17, 22], 288 | 289 | [16, 15, 15], 290 | 291 | [25], 292 | 293 | [14, 18, 19, 16, 14, 20, 28, 13, 28, 39, 40, 29, 25], 294 | 295 | [27, 26, 18, 17, 20], 296 | 297 | [25, 25, 22, 19, 14], 298 | 299 | [21, 22, 18], 300 | 301 | [10, 29, 24, 21, 21], 302 | 303 | [13], 304 | 305 | [15], 306 | 307 | [25], 308 | 309 | [20, 29, 22, 11, 14, 17, 17, 13, 21, 11, 19, 18, 18, 20, 8, 21, 18, 24, 21, 15, 27, 21], 310 | 311 | [15], 312 | 313 | [58, 31, 24, 63, 73, 34, 15, 97, 56], 314 | 315 | [40, 48, 36, 52, 56, 59, 140, 63, 47, 60, 46, 51, 58, 48, 63, 78], 316 | 317 | [7], 318 | 319 | [20] 320 | ]} -------------------------------------------------------------------------------- /scripts/installMgr.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var JSZip = require("jszip"); 4 | var dataMgr = require("./dataMgr"); 5 | var versificationMgr = require("./versificationMgr"); 6 | var async = require("async"); 7 | var tools = require("./tools"); 8 | 9 | //console.log(VersificationMgr.getBooksInNT()); 10 | 11 | var start = 0, 12 | buf = null, 13 | isEnd = false; 14 | 15 | //Get a list of all available repos/sources from CrossWire's masterRepoList.conf 16 | function getRepositories(inUrl, inCallback) { 17 | if (inUrl instanceof Function) { 18 | inCallback = inUrl; 19 | inUrl = "http://crosswire.org/ftpmirror/pub/sword/masterRepoList.conf"; 20 | } 21 | 22 | download(inUrl, "text", function (inError, inResponse) { 23 | if (inResponse === "" && !inError) { 24 | inCallback("Couldn't download master repo list!"); 25 | } else if (!inError) { 26 | var repos = [], 27 | split = null, 28 | type = "", 29 | repoName = ""; 30 | inResponse.split(/[\r\n]+/g).forEach(function (repo) { 31 | split = repo.split("|"); 32 | if(split.length > 1 && split[0].search("CrossWire") !== -1) { 33 | repoName = split[0].split("=")[2]; 34 | switch (repoName) { 35 | case "CrossWire": 36 | type = "main"; 37 | break; 38 | case "CrossWire Beta": 39 | type = "beta"; 40 | break; 41 | case "CrossWire av11n": 42 | type = "av"; 43 | break; 44 | case "CrossWire Attic": 45 | type = "attic"; 46 | break; 47 | case "CrossWire Wycliffe": 48 | type = "wycliffe"; 49 | break; 50 | case "CrossWire av11n Attic": 51 | type = "avattic"; 52 | break; 53 | } 54 | repos.push({ 55 | name: repoName, 56 | type: type, 57 | url: split[1] + split[2], 58 | confUrl: "http://crosswire.org/ftpmirror" + split[2] + "/mods.d" 59 | }); 60 | } 61 | }); 62 | //console.log("REPOS", repos); 63 | inCallback(inError, repos); 64 | } else { 65 | inCallback(inError); 66 | } 67 | }); 68 | } 69 | 70 | //dirty hack to get a list of modules that is available in a repository. 71 | //FIXME: unpack mods.d.tar.gz in Javascript (untar is the problem) or ask CrossWire to compress it as zip/gzip 72 | function getModules(inRepo, inCallback) { 73 | getRemoteModules(inRepo, inCallback); 74 | } 75 | 76 | function getRemoteModules(inRepo, inUrl, inCallback) { 77 | var customUrl = true; 78 | if (inUrl instanceof Function) { 79 | inCallback = inUrl; 80 | customUrl = false; 81 | } 82 | if (!customUrl) { 83 | download(inRepo.confUrl, "document", function (inError, inResponse) { 84 | if (!inError) { 85 | var tasks = [], 86 | url = "", 87 | a = inResponse.getElementsByTagName("a"); 88 | for(var i=0;i