UNPKG

swordjs

Version:

swordjs - access modules from crosswire.org/sword in JS

304 lines (282 loc) 11 kB
var bcvParser = require("../../libs/bcv/js/en_bcv_parser.min.js"); var bcv = new bcvParser.bcv_parser(); var sax = require("sax"); var parser = sax.parser(true); //strict = true //* SWFilter Options var swFilterOptions = { headings: false, footnotes: false, crossReferences: false, strongsNumbers: false, wordsOfChristInRed: false, oneVersePerLine: false, array: false }; var lastTag = "", currentNode = null, currentNote = null, currentRef = null, quote = null, verseData = null, noteText = "", outText = "", renderedText = "", verseArray = [], verseNumber = "", osisRef = "", footnotesData = {}, isSelfClosing = false, isTitle = false, noteCount = 0; function processText(inRaw, inDirection, inOptions) { if (!inOptions || inOptions === {}) { inOptions = swFilterOptions; } else { inOptions.headings = (inOptions.headings) ? inOptions.headings : swFilterOptions.headings; inOptions.footnotes = (inOptions.footnotes) ? inOptions.footnotes : swFilterOptions.footnotes; inOptions.crossReferences = (inOptions.crossReferences) ? inOptions.crossReferences : swFilterOptions.crossReferences; inOptions.strongsNumbers = (inOptions.strongsNumbers) ? inOptions.strongsNumbers : swFilterOptions.strongsNumbers; inOptions.wordsOfChristInRed = (inOptions.wordsOfChristInRed) ? inOptions.wordsOfChristInRed : swFilterOptions.wordsOfChristInRed; inOptions.oneVersePerLine = (inOptions.oneVersePerLine) ? inOptions.oneVersePerLine : swFilterOptions.oneVersePerLine; inOptions.array = (inOptions.array) ? inOptions.array : swFilterOptions.array; } lastTag = ""; currentNode = null; currentNote = null; currentRef = null; quote = null; title = null; titleText = ""; verseData = null; noteText = ""; outText = ""; renderedText = ""; verseArray = []; verseNumber = ""; osisRef = ""; footnotesData = {}; isTitle = false; noteCount = 0; //Handle Parsing errors parser.onerror = function (e) { parser.resume(); }; //Text node parser.ontext = function (t) { //console.log("TEXT:", t, currentNode); if (currentNote) { outText += processFootnotes(t, inOptions); } else if (quote) { if (quote.attributes.who === "Jesus" && inOptions.wordsOfChristInRed && t) { outText += "<span style='color: red'><span class='sword-woc'>" + t + " </span></span>"; } else outText += t; } else if (currentNode) { switch (currentNode.name) { case "title": if(inOptions.headings) { titleText += t; } break; case "divineName": if(title && inOptions.headings) { titleText += "<span class='sword-divine-name'>" + t + "</span>"; } break; case "hi": outText += tagHi(currentNode, t); break; default: outText += t; break; } } else { outText += t; } }; //Handle opening tags parser.onopentag = function (node) { //console.log(node); currentNode = node; lastTag = node.name; switch (node.name) { case "xml": verseData = {osisRef: node.attributes.osisRef, verseNum: node.attributes.verseNum}; if (parseInt(verseData.verseNum, 10) === 0) { if (inDirection === "RtoL") outText += "<span dir='rtl'><div class='sword-intro'>"; else outText += "<span class='sword-intro'>"; } else { if (inDirection === "RtoL") outText += "<span dir='rtl'><a href=\"?type=verseNum&osisRef=" + verseData.osisRef + "\" class='verse-number'> " + verseData.verseNum + " </a></span><span dir='rtl'>"; else outText += "<a href=\"?type=verseNum&osisRef=" + verseData.osisRef + "\" class='verse-number'> " + verseData.verseNum + " </a>"; } break; case "note": if (node.attributes.type === "crossReference" && inOptions.crossReferences) outText += "<span class='sword-cross-reference'>["; else if (inOptions.footnotes && node.attributes.type !== "crossReference") { osisRef = node.attributes.osisRef || node.attributes.annotateRef || verseData.osisRef; if (!node.attributes.n) noteCount++; var n = node.attributes.n || noteCount; outText += "<a class='sword-footnote' href=\"?type=footnote&osisRef=" + osisRef + "&n=" + n+ "\"><sup>" + "*n" + n + "</sup></a>"; } currentNote = node; break; case "reference": currentRef = node; break; case "q": if(!node.isSelfClosing && node.attributes.who === "Jesus") quote = node; break; case "title": title = node; if (title.attributes.type === "section") titleText += "<h3>"; else titleText += "<h1>"; break; case "div": if(node.isSelfClosing && node.attributes.type === "paragraph" && node.attributes.sID) outText += "<p>"; if(node.isSelfClosing && node.attributes.type === "paragraph" && node.attributes.eID) outText += "</p>"; break; case "l": if(node.isSelfClosing && node.attributes.type === "x-br") outText += "<br>"; break; } }; parser.onclosetag = function (tagName) { //console.log("CLOSE:", tagName); switch (tagName) { case "title": if (title.attributes.type === "section") outText = titleText + "</h3>" + outText; else outText = titleText + "</h1>" + outText; currentNode = null; title = null; titleText = ""; break; case "note": if (currentNote.attributes.type === "crossReference" && inOptions.crossReferences) outText += "]</span> "; noteText = ""; currentNote = null; break; case "reference": currentRef = null; break; case "q": if (!currentNode && inOptions.wordsOfChristInRed) { //outText += "</span>"; quote = null; } break; case "xml": if(parseInt(verseData.verseNum, 10) === 0) outText += "</div>"; if(inDirection === "RtoL") outText += "</span>"; break; } lastTag = ""; currentNode = null; }; //Handling Attributes parser.onattribute = function (attr) { //console.log(attr); }; //End of parsing parser.onend = function () { //console.log("Finished parsing XML!"); }; var tmp = ""; for (var i=0; i<inRaw.length; i++) { //console.log(inRaw[i].text); tmp = "<xml osisRef='" + inRaw[i].osisRef + "' verseNum = '" + inRaw[i].verse + "'>" + inRaw[i].text + "</xml>"; parser.write(tmp); parser.close(); if (!inOptions.array) renderedText += (inOptions.oneVersePerLine) ? "<div class='verse' id = '" + inRaw[i].osisRef + "'>" + outText + "</div>" : "<span class='verse' id = '" + inRaw[i].osisRef + "'>" + outText + "</span>"; else verseArray.push({text: (inOptions.oneVersePerLine) ? "<div class='verse' id = '" + inRaw[i].osisRef + "'>" + outText + "</div>" : "<span class='verse' id = '" + inRaw[i].osisRef + "'>" + outText + "</span>", osisRef: inRaw[i].osisRef}); outText = ""; } if(inDirection === "RtoL") renderedText = "<div style='text-align: right;'>" + renderedText + "</div>"; if(!inOptions.array) return {text: renderedText, footnotes: footnotesData}; else return {verses: verseArray, footnotes: footnotesData, rtol: (inDirection === "RtoL") ? true : false}; } /* FUNCTIONS TO PROCESS SPECIFIC OSIS TAGS */ function processFootnotes(t, inOptions) { var out = ""; if (currentNote.attributes.type === "crossReference" && inOptions.crossReferences) { if (lastTag !== "reference") out += processCrossReference(t); else { var crossRef = (currentRef) ? currentRef.attributes.osisRef : currentNote.attributes.osisRef; out += "<a href=\"?type=crossReference&osisRef=" + crossRef + "&n=" + currentNote.attributes.n + "\">" + t + "</a>"; } } else if (inOptions.footnotes && currentNote.attributes.type !== "crossReference") { if (lastTag === "hi") { t = tagHi(currentNode, t); } osisRef = currentNote.attributes.osisRef || currentNote.attributes.annotateRef || verseData.osisRef; var n = currentNote.attributes.n || noteCount; if (!footnotesData.hasOwnProperty(osisRef)) footnotesData[osisRef] = [{note: t, n: n}]; else { if (footnotesData[osisRef][footnotesData[osisRef].length-1].n === n) footnotesData[osisRef][footnotesData[osisRef].length-1]["note"] += t; else footnotesData[osisRef].push({note: t, n: n}); } } return out; } function processCrossReference(inText) { var out = "", osisRef = bcv.parse(inText).osis(); if (osisRef !== "" && currentRef) { var n = currentRef.attributes.n || currentNote.attributes.n; out += "<a href=\"?type=crossReference&osisRef=" + osisRef + "&n=" + n + "\">" + inText + "</a>"; } else out += inText; return out; } function tagHi (node, t) { switch (node.attributes.type) { case "italic": t = "<i>"+t+"</i>"; break; case "bold": t = "<b>"+t+"</b>"; break; case "line-through": t = "<s>"+t+"</s>"; break; case "underline": t = "<u>"+t+"</u>"; break; case "sub": t = "<sub>"+t+"</sub>"; break; case "super": t = "<sup>"+t+"</sup>"; break; } return t; } var osis = { processText: processText }; //Return osis filter methods module.exports = osis;