/* 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 wikiTextMacros = require("./WikiTextMacros.js"), 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); }; // Render the tiddler as HTML from its parse tree // type - MIME type of required output // store - store object providing context for inter-tiddler operations // title - render the tree as if it came from a tiddler of this title WikiTextParser.prototype.render = function(type,store,title) { if(type === "text/html") { return this.renderAsHtml(store,title); } else if (type === "text/plain") { return this.renderAsText(store,title); } else { return null; } }; WikiTextParser.prototype.renderAsHtml = function(store,title) { var output = [], renderSubTree; var renderElement = function(element, selfClosing) { var tagBits = [element.type]; if(element.attributes) { for(var a in element.attributes) { var r = element.attributes[a]; if(a === "style") { var s = []; for(var t in r) { s.push(t + ":" + r[t] + ";"); } r = s.join(""); } tagBits.push(a + "=\"" + utils.htmlEncode(r) + "\""); } } output.push("<" + tagBits.join(" ") + (selfClosing ? " /" : "") + ">"); if(!selfClosing) { if(element.children) { renderSubTree(element.children); } output.push(""); } }; renderSubTree = function(tree) { for(var t=0; t 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