/* WikiTextParser.js Parses a block of tiddlywiki-format wiki text into a parse tree object. HTML elements are stored in the tree like this: {type: "div", attributes: { attr1: value, style: { name: value, name2: value2 } }, children: [ {child}, {child}, ]} Text nodes are: {type: "text", value: "string of text node"} */ /*jslint node: true */ "use strict"; var wikiTextRules = require("./WikiTextRules.js").wikiTextRules, utils = require("./Utils.js"), util = require("util"); var WikiTextParser = function(text) { this.autoLinkWikiWords = true; this.source = text; this.nextMatch = 0; this.tree = []; this.output = null; this.subWikify(this.tree); }; WikiTextParser.prototype.outputText = function(place,startPos,endPos) { if(startPos < endPos) { place.push({type: "text", value: this.source.substring(startPos,endPos)}); } }; WikiTextParser.prototype.subWikify = function(output,terminator) { // Handle the terminated and unterminated cases separately, this speeds up wikifikation by about 30% if(terminator) this.subWikifyTerm(output,new RegExp("(" + terminator + ")","mg")); else this.subWikifyUnterm(output); }; WikiTextParser.prototype.subWikifyUnterm = function(output) { // subWikify can be indirectly recursive, so we need to save the old output pointer var oldOutput = this.output; this.output = output; // Get the first match wikiTextRules.rulesRegExp.lastIndex = this.nextMatch; var ruleMatch = wikiTextRules.rulesRegExp.exec(this.source); while(ruleMatch) { // Output any text before the match if(ruleMatch.index > this.nextMatch) this.outputText(this.output,this.nextMatch,ruleMatch.index); // Set the match parameters for the handler this.matchStart = ruleMatch.index; this.matchLength = ruleMatch[0].length; this.matchText = ruleMatch[0]; this.nextMatch = wikiTextRules.rulesRegExp.lastIndex; // Figure out which rule matched and call its handler var t; for(t=1; t this.nextMatch) this.outputText(this.output,this.nextMatch,terminatorMatch.index); // Set the match parameters this.matchText = terminatorMatch[1]; this.matchLength = terminatorMatch[1].length; this.matchStart = terminatorMatch.index; this.nextMatch = this.matchStart + this.matchLength; // Restore the output pointer this.output = oldOutput; return; } // It must be a rule match; output any text before the match if(ruleMatch.index > this.nextMatch) this.outputText(this.output,this.nextMatch,ruleMatch.index); // Set the match parameters this.matchStart = ruleMatch.index; this.matchLength = ruleMatch[0].length; this.matchText = ruleMatch[0]; this.nextMatch = wikiTextRules.rulesRegExp.lastIndex; // Figure out which rule matched and call its handler var t; for(t=1; t