mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-27 03:57:21 +00:00
Added skeleton support for evaluated macro parameters
This commit is contained in:
parent
02a2630dd6
commit
4c11503bae
@ -14,7 +14,11 @@ Options and their defaults are:
|
||||
defaultName: null,
|
||||
defaultValue: null,
|
||||
noNames: false,
|
||||
cascadeDefaults: false
|
||||
cascadeDefaults: false,
|
||||
allowEval: true
|
||||
globals: null
|
||||
|
||||
`globals` is the global variable object provided to evaluated parameters
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
@ -22,23 +26,26 @@ Options and their defaults are:
|
||||
/*jslint node: true */
|
||||
"use strict";
|
||||
|
||||
var Sandbox = require("./Sandbox.js").Sandbox;
|
||||
|
||||
var ArgParser = function(argString,options) {
|
||||
var parseToken = function(match,p) {
|
||||
var n;
|
||||
if(match[p]) // Double quoted
|
||||
n = match[p];
|
||||
else if(match[p+1]) // Single quoted
|
||||
n = match[p+1];
|
||||
else if(match[p+2]) // Double-square-bracket quoted
|
||||
n = match[p+2];
|
||||
else if(match[p+3]) // Double-brace quoted
|
||||
n = match[p+3];
|
||||
else if(match[p+4]) // Unquoted
|
||||
n = match[p+4];
|
||||
else if(match[p+5]) // empty quote
|
||||
n = "";
|
||||
return n;
|
||||
};
|
||||
var n;
|
||||
if(match[p]) { // Double quoted
|
||||
n = match[p];
|
||||
} else if(match[p+1]) { // Single quoted
|
||||
n = match[p+1];
|
||||
} else if(match[p+2]) { // Double-square-bracket quoted
|
||||
n = match[p+2];
|
||||
} else if(match[p+3]) { // Double-brace quoted
|
||||
n = options.allowEval === false ? match[p+3] : Sandbox(match[p+3],options.globals);
|
||||
} else if(match[p+4]) { // Unquoted
|
||||
n = match[p+4];
|
||||
} else if(match[p+5]) { // empty quote
|
||||
n = "";
|
||||
}
|
||||
return n;
|
||||
};
|
||||
this.byPos = [];
|
||||
var dblQuote = "(?:\"((?:(?:\\\\\")|[^\"])+)\")",
|
||||
sngQuote = "(?:'((?:(?:\\\\\')|[^'])+)')",
|
||||
|
53
js/Sandbox.js
Normal file
53
js/Sandbox.js
Normal file
@ -0,0 +1,53 @@
|
||||
/*\
|
||||
title: js/Sandbox.js
|
||||
|
||||
Execute a fragment of JavaScript in a sandbox
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true */
|
||||
"use strict";
|
||||
|
||||
var uglify = require("uglify-js");
|
||||
|
||||
var safeEval = function(e) {
|
||||
return eval(e);
|
||||
};
|
||||
|
||||
var Sandbox = function(code,globals) {
|
||||
var globalNames = [],
|
||||
globalValues = [],
|
||||
collectGlobals = function(globals) {
|
||||
if(globals) {
|
||||
for(var g in globals) {
|
||||
globalNames.push(g);
|
||||
globalValues.push(globals[g]);
|
||||
}
|
||||
}
|
||||
};
|
||||
// Collect the supplied globals
|
||||
collectGlobals(globals);
|
||||
// Add the default globals
|
||||
collectGlobals({
|
||||
tiddlywiki: "5"
|
||||
});
|
||||
// Compose the code
|
||||
var out = [];
|
||||
out.push("(function(")
|
||||
out.push(globalNames.join(","));
|
||||
out.push(") { return ");
|
||||
out.push(code);
|
||||
out.push(";})");
|
||||
// Parse the code
|
||||
var tree = uglify.parser.parse(out.join(""));
|
||||
// XXX: Sanitise the code by checking for references to globals
|
||||
// Recompile the code
|
||||
var compiledCode = uglify.uglify.gen_code(tree);
|
||||
// Execute it
|
||||
return eval(compiledCode).apply(null,globalValues);
|
||||
};
|
||||
|
||||
exports.Sandbox = Sandbox;
|
||||
|
||||
})();
|
@ -129,7 +129,19 @@ WikiTextRenderer.prototype.executeMacro = function(macroNode,title) {
|
||||
var macroInfo = WikiTextRenderer.macros[macroNode.name];
|
||||
macroNode.output = [];
|
||||
if(macroInfo) {
|
||||
macroInfo.handler.call(this,macroNode,title);
|
||||
var args;
|
||||
if(macroInfo.argOptions) {
|
||||
var argOptions = {
|
||||
globals: {
|
||||
title: title
|
||||
}
|
||||
};
|
||||
for(var g in macroInfo.argOptions) {
|
||||
argOptions[g] = macroInfo.argOptions[g];
|
||||
}
|
||||
args = new ArgParser(macroNode.params,argOptions);
|
||||
}
|
||||
macroInfo.handler.call(this,macroNode,args,title);
|
||||
} else {
|
||||
macroNode.output.push({type: "text", value: "Unknown macro " + macroNode.name});
|
||||
}
|
||||
@ -139,18 +151,25 @@ WikiTextRenderer.versionTiddlyWiki = "2.6.5";
|
||||
|
||||
WikiTextRenderer.macros = {
|
||||
allTags: {
|
||||
handler: function(macroNode,title) {
|
||||
handler: function(macroNode,args,title) {
|
||||
}
|
||||
},
|
||||
br: {
|
||||
handler: function(macroNode,title) {
|
||||
handler: function(macroNode,args,title) {
|
||||
macroNode.output.push({type: "br"});
|
||||
}
|
||||
},
|
||||
echo: {
|
||||
argOptions: {defaultName: "anon"},
|
||||
handler: function(macroNode,args,title) {
|
||||
var globals = {title: title};
|
||||
macroNode.output.push({type: "text", value: args.byPos[0].v});
|
||||
}
|
||||
},
|
||||
timeline: {
|
||||
handler: function(macroNode,title) {
|
||||
var args = new ArgParser(macroNode.params,{defaultName:"anon"}),
|
||||
anonByPos = args.getValuesByName("anon",[]),
|
||||
argOptions: {defaultName:"anon"},
|
||||
handler: function(macroNode,args,title) {
|
||||
var anonByPos = args.getValuesByName("anon",[]),
|
||||
field = anonByPos[0] || "modified",
|
||||
limit = anonByPos[1] || null,
|
||||
dateformat = anonByPos[2] || "DD MMM YYYY",
|
||||
@ -214,9 +233,9 @@ WikiTextRenderer.macros = {
|
||||
}
|
||||
},
|
||||
list: {
|
||||
handler: function(macroNode,title) {
|
||||
var args = new ArgParser(macroNode.params,{defaultName:"type"}),
|
||||
type = args.getValueByName("type","all"),
|
||||
argOptions: {defaultName:"type"},
|
||||
handler: function(macroNode,args,title) {
|
||||
var type = args.getValueByName("type","all"),
|
||||
template = args.getValueByName("template",null),
|
||||
templateType = "text/x-tiddlywiki", templateText = "<<view title link>>",
|
||||
emptyMessage = args.getValueByName("emptyMessage",null);
|
||||
@ -275,29 +294,29 @@ WikiTextRenderer.macros = {
|
||||
}
|
||||
},
|
||||
slider: {
|
||||
handler: function(macroNode,title) {
|
||||
handler: function(macroNode,args,title) {
|
||||
}
|
||||
},
|
||||
tabs: {
|
||||
handler: function(macroNode,title) {
|
||||
handler: function(macroNode,args,title) {
|
||||
}
|
||||
},
|
||||
tag: {
|
||||
handler: function(macroNode,title) {
|
||||
handler: function(macroNode,args,title) {
|
||||
}
|
||||
},
|
||||
tagging: {
|
||||
handler: function(macroNode,title) {
|
||||
handler: function(macroNode,args,title) {
|
||||
}
|
||||
},
|
||||
tags: {
|
||||
handler: function(macroNode,title) {
|
||||
handler: function(macroNode,args,title) {
|
||||
}
|
||||
},
|
||||
tiddler: {
|
||||
handler: function(macroNode,title) {
|
||||
var args = new ArgParser(macroNode.params,{defaultName:"name",cascadeDefaults:true}),
|
||||
targetTitle = args.getValueByName("name",null),
|
||||
argOptions: {defaultName:"name",cascadeDefaults:true},
|
||||
handler: function(macroNode,args,title) {
|
||||
var targetTitle = args.getValueByName("name",null),
|
||||
withTokens = args.getValuesByName("with",[]),
|
||||
tiddler = this.store.getTiddler(targetTitle),
|
||||
text = this.store.getTiddlerText(targetTitle,""),
|
||||
@ -312,22 +331,22 @@ WikiTextRenderer.macros = {
|
||||
}
|
||||
},
|
||||
today: {
|
||||
handler: function(macroNode,title) {
|
||||
argOptions: {noNames:true},
|
||||
handler: function(macroNode,args,title) {
|
||||
var now = new Date(),
|
||||
args = new ArgParser(macroNode.params,{noNames:true}),
|
||||
value = args.byPos[0] ? utils.formatDateString(now,args.byPos[0].v) : now.toLocaleString();
|
||||
macroNode.output.push({type: "text", value: value});
|
||||
}
|
||||
},
|
||||
version: {
|
||||
handler: function(macroNode,title) {
|
||||
handler: function(macroNode,args,title) {
|
||||
macroNode.output.push({type: "text", value: WikiTextRenderer.versionTiddlyWiki});
|
||||
}
|
||||
},
|
||||
view: {
|
||||
handler: function(macroNode,title) {
|
||||
var args = new ArgParser(macroNode.params,{noNames:true}),
|
||||
field = args.byPos[0] ? args.byPos[0].v : null,
|
||||
argOptions: {noNames:true},
|
||||
handler: function(macroNode,args,title) {
|
||||
var field = args.byPos[0] ? args.byPos[0].v : null,
|
||||
format = args.byPos[1] ? args.byPos[1].v : "text",
|
||||
tiddler = this.store.getTiddler(title),
|
||||
value = tiddler ? tiddler.fields[field] : null;
|
||||
|
@ -7,7 +7,6 @@
|
||||
Given the absolute path of a srcModule, and a relative reference to a dstModule, return the fully resolved module name
|
||||
*/
|
||||
function resolveModuleName(srcModule,dstModule) {
|
||||
console.log("Resolving " + dstModule + " in the context of " + srcModule);
|
||||
var src = srcModule.split("/"),
|
||||
dst = dstModule.split("/"),
|
||||
c;
|
||||
|
@ -8,3 +8,5 @@ TiddlyWiki is a unique [[wiki|WikiWikiWeb]] that people [[love using|Raves]] to
|
||||
TiddlyWiki is written in [[HTML]], [[CSS]] and JavaScript to run on any reasonably modern [[browser|Browsers]] without needing any ServerSide logic. It allows anyone to create personal SelfContained hypertext documents that can be published to a WebServer, sent by email, stored in a DropBox or kept on a USB thumb drive to make a WikiOnAStick. Because it doesn't need to be installed and configured it makes a great GuerillaWiki. This is revision <<version>> of TiddlyWiki, and is published under an OpenSourceLicense.
|
||||
|
||||
Unlike most wikis, TiddlyWiki doesn't directly support group collaboration; it is a wiki in the sense of elevating linking be a part of the punctuation of writing. You can easily publish a TiddlyWiki you have created by placing the single file on a web server (for instance the homepage hosting provided by many ISPs). If you need full group collaboration features, there are several HostedOptions to choose from.
|
||||
|
||||
<<echo {{2+2 /* something */ - 3 * 17 + title + tiddlywiki + out.length}}>>
|
||||
|
@ -9,6 +9,7 @@ recipe: tiddlers/split.recipe
|
||||
|
||||
jslib: ../test/tiddlywiki.2.6.5/source/tiddlywiki/jquery/jquery.js
|
||||
|
||||
jsmodule: ../js/Sandbox.js
|
||||
jsmodule: ../js/ArgParser.js
|
||||
jsmodule: ../js/FileRetriever.js
|
||||
jsmodule: ../js/Utils.js
|
||||
|
Loading…
Reference in New Issue
Block a user