/*\ title: js/WikiTextCompiler.js \*/ (function(){ /*jslint node: true */ "use strict"; var ArgParser = require("./ArgParser.js").ArgParser, utils = require("./Utils.js"), util = require("util"); var WikiTextCompiler = function(store,title,parser) { this.parser = parser; this.store = store; this.title = title; }; // Compile a javascript tree into an array of string fragments var compileJavaScript = function(tree) { var output = [], compileJavaScriptTree, compileJavaScriptNode = function(node) { var p; switch(node.type) { case "StringLiteral": output.push(utils.stringify(node.value)); break; case "StringLiterals": output.push(utils.stringify(node.value.join(""))); break; case "FunctionCall": output.push("("); compileJavaScriptNode(node.name); output.push(")"); output.push("("); for(p=0; p 0 && last.type === "StringLiterals") { last.value.push(s); } else if (output.length > 0 && last.type === "StringLiteral") { last.type = "StringLiterals"; last.value = [last.value,s]; } else { output.push({type: "StringLiteral", value: s}); } }; var compileElement = function(element, options) { options = options || {}; 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) + "\""); } } pushString("<" + tagBits.join(" ") + (options.selfClosing ? " /" : "")); if(options.insertAfterAttributes) { pushString(" "); output.push(options.insertAfterAttributes); } pushString(">"); if(!options.selfClosing) { if(element.children) { compileSubTree(element.children); } pushString(""); } }; var compileMacroCall = function(name,params) { var macro = me.store.macros[name]; if(macro) { var args = new ArgParser(params,{defaultName: "anon"}), paramsProps = {}; var insertParam = function(name,arg) { if(arg.evaluated) { var prog = me.store.sandbox.parse(arg.string); paramsProps[name] = prog.elements[0]; } else { paramsProps[name] = {type: "StringLiteral", value: arg.string}; } }; for(var m in macro.params) { var param = macro.params[m]; if("byPos" in param && args.byPos[param.byPos]) { insertParam(m,args.byPos[param.byPos].v); } else if("byName" in param) { var arg = args.getValueByName(m); if(!arg && param.byName === "default") { arg = args.getValueByName("anon"); } if(arg) { insertParam(m,arg); } } } var macroCall = { type: "FunctionCall", name: { type: "Function", name: null, params: ["params"], elements: []}, "arguments": [ { type: "ObjectLiteral", properties: [] }] }; macroCall.name.elements = macro.code["text/html"].elements; for(m in paramsProps) { macroCall["arguments"][0].properties.push({ type: "PropertyAssignment", name: m, value: paramsProps[m] }); } output.push(macroCall); } else { pushString("Unknown macro '" + name + "'"); } }; compileSubTree = function(tree) { for(var t=0; t 0 && last.type === "StringLiterals") { last.value.push(s); } else if (output.length > 0 && last.type === "StringLiteral") { last.type = "StringLiterals"; last.value = [last.value,s]; } else { output.push({type: "StringLiteral", value: s}); } }; var compileElement = function(element, options) { options = options || {}; if(!options.selfClosing) { if(element.children) { compileSubTree(element.children); } } }; var compileMacroCall = function(name,params) { var macro = me.store.macros[name]; if(macro) { var args = new ArgParser(params,{defaultName: "anon"}), paramsProps = {}; var insertParam = function(name,arg) { if(arg.evaluated) { var prog = me.store.sandbox.parse(arg.string); paramsProps[name] = prog.elements[0]; } else { paramsProps[name] = {type: "StringLiteral", value: arg.string}; } }; for(var m in macro.params) { var param = macro.params[m]; if("byPos" in param && args.byPos[param.byPos]) { insertParam(m,args.byPos[param.byPos].v); } else if("byName" in param) { var arg = args.getValueByName(m); if(!arg && param.byName === "default") { arg = args.getValueByName("anon"); } if(arg) { insertParam(m,arg); } } } var macroCall = { type: "FunctionCall", name: { type: "Function", name: null, params: ["params"], elements: []}, "arguments": [ { type: "ObjectLiteral", properties: [] }] }; macroCall.name.elements = macro.code["text/plain"].elements; for(m in paramsProps) { macroCall["arguments"][0].properties.push({ type: "PropertyAssignment", name: m, value: paramsProps[m] }); } output.push(macroCall); } else { pushString("{{** Unknown macro '" + name + "' **}}"); } }; compileSubTree = function(tree) { for(var t=0; t