mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-08-05 21:33:52 +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,
|
defaultName: null,
|
||||||
defaultValue: null,
|
defaultValue: null,
|
||||||
noNames: false,
|
noNames: false,
|
||||||
cascadeDefaults: false
|
cascadeDefaults: false,
|
||||||
|
allowEval: true
|
||||||
|
globals: null
|
||||||
|
|
||||||
|
`globals` is the global variable object provided to evaluated parameters
|
||||||
|
|
||||||
\*/
|
\*/
|
||||||
(function(){
|
(function(){
|
||||||
@ -22,23 +26,26 @@ Options and their defaults are:
|
|||||||
/*jslint node: true */
|
/*jslint node: true */
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
var Sandbox = require("./Sandbox.js").Sandbox;
|
||||||
|
|
||||||
var ArgParser = function(argString,options) {
|
var ArgParser = function(argString,options) {
|
||||||
var parseToken = function(match,p) {
|
var parseToken = function(match,p) {
|
||||||
var n;
|
var n;
|
||||||
if(match[p]) // Double quoted
|
if(match[p]) { // Double quoted
|
||||||
n = match[p];
|
n = match[p];
|
||||||
else if(match[p+1]) // Single quoted
|
} else if(match[p+1]) { // Single quoted
|
||||||
n = match[p+1];
|
n = match[p+1];
|
||||||
else if(match[p+2]) // Double-square-bracket quoted
|
} else if(match[p+2]) { // Double-square-bracket quoted
|
||||||
n = match[p+2];
|
n = match[p+2];
|
||||||
else if(match[p+3]) // Double-brace quoted
|
} else if(match[p+3]) { // Double-brace quoted
|
||||||
n = match[p+3];
|
n = options.allowEval === false ? match[p+3] : Sandbox(match[p+3],options.globals);
|
||||||
else if(match[p+4]) // Unquoted
|
} else if(match[p+4]) { // Unquoted
|
||||||
n = match[p+4];
|
n = match[p+4];
|
||||||
else if(match[p+5]) // empty quote
|
} else if(match[p+5]) { // empty quote
|
||||||
n = "";
|
n = "";
|
||||||
return n;
|
}
|
||||||
};
|
return n;
|
||||||
|
};
|
||||||
this.byPos = [];
|
this.byPos = [];
|
||||||
var dblQuote = "(?:\"((?:(?:\\\\\")|[^\"])+)\")",
|
var dblQuote = "(?:\"((?:(?:\\\\\")|[^\"])+)\")",
|
||||||
sngQuote = "(?:'((?:(?:\\\\\')|[^'])+)')",
|
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];
|
var macroInfo = WikiTextRenderer.macros[macroNode.name];
|
||||||
macroNode.output = [];
|
macroNode.output = [];
|
||||||
if(macroInfo) {
|
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 {
|
} else {
|
||||||
macroNode.output.push({type: "text", value: "Unknown macro " + macroNode.name});
|
macroNode.output.push({type: "text", value: "Unknown macro " + macroNode.name});
|
||||||
}
|
}
|
||||||
@ -139,18 +151,25 @@ WikiTextRenderer.versionTiddlyWiki = "2.6.5";
|
|||||||
|
|
||||||
WikiTextRenderer.macros = {
|
WikiTextRenderer.macros = {
|
||||||
allTags: {
|
allTags: {
|
||||||
handler: function(macroNode,title) {
|
handler: function(macroNode,args,title) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
br: {
|
br: {
|
||||||
handler: function(macroNode,title) {
|
handler: function(macroNode,args,title) {
|
||||||
macroNode.output.push({type: "br"});
|
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: {
|
timeline: {
|
||||||
handler: function(macroNode,title) {
|
argOptions: {defaultName:"anon"},
|
||||||
var args = new ArgParser(macroNode.params,{defaultName:"anon"}),
|
handler: function(macroNode,args,title) {
|
||||||
anonByPos = args.getValuesByName("anon",[]),
|
var anonByPos = args.getValuesByName("anon",[]),
|
||||||
field = anonByPos[0] || "modified",
|
field = anonByPos[0] || "modified",
|
||||||
limit = anonByPos[1] || null,
|
limit = anonByPos[1] || null,
|
||||||
dateformat = anonByPos[2] || "DD MMM YYYY",
|
dateformat = anonByPos[2] || "DD MMM YYYY",
|
||||||
@ -214,9 +233,9 @@ WikiTextRenderer.macros = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
list: {
|
list: {
|
||||||
handler: function(macroNode,title) {
|
argOptions: {defaultName:"type"},
|
||||||
var args = new ArgParser(macroNode.params,{defaultName:"type"}),
|
handler: function(macroNode,args,title) {
|
||||||
type = args.getValueByName("type","all"),
|
var type = args.getValueByName("type","all"),
|
||||||
template = args.getValueByName("template",null),
|
template = args.getValueByName("template",null),
|
||||||
templateType = "text/x-tiddlywiki", templateText = "<<view title link>>",
|
templateType = "text/x-tiddlywiki", templateText = "<<view title link>>",
|
||||||
emptyMessage = args.getValueByName("emptyMessage",null);
|
emptyMessage = args.getValueByName("emptyMessage",null);
|
||||||
@ -275,29 +294,29 @@ WikiTextRenderer.macros = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
slider: {
|
slider: {
|
||||||
handler: function(macroNode,title) {
|
handler: function(macroNode,args,title) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tabs: {
|
tabs: {
|
||||||
handler: function(macroNode,title) {
|
handler: function(macroNode,args,title) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tag: {
|
tag: {
|
||||||
handler: function(macroNode,title) {
|
handler: function(macroNode,args,title) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tagging: {
|
tagging: {
|
||||||
handler: function(macroNode,title) {
|
handler: function(macroNode,args,title) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tags: {
|
tags: {
|
||||||
handler: function(macroNode,title) {
|
handler: function(macroNode,args,title) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tiddler: {
|
tiddler: {
|
||||||
handler: function(macroNode,title) {
|
argOptions: {defaultName:"name",cascadeDefaults:true},
|
||||||
var args = new ArgParser(macroNode.params,{defaultName:"name",cascadeDefaults:true}),
|
handler: function(macroNode,args,title) {
|
||||||
targetTitle = args.getValueByName("name",null),
|
var targetTitle = args.getValueByName("name",null),
|
||||||
withTokens = args.getValuesByName("with",[]),
|
withTokens = args.getValuesByName("with",[]),
|
||||||
tiddler = this.store.getTiddler(targetTitle),
|
tiddler = this.store.getTiddler(targetTitle),
|
||||||
text = this.store.getTiddlerText(targetTitle,""),
|
text = this.store.getTiddlerText(targetTitle,""),
|
||||||
@ -312,22 +331,22 @@ WikiTextRenderer.macros = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
today: {
|
today: {
|
||||||
handler: function(macroNode,title) {
|
argOptions: {noNames:true},
|
||||||
|
handler: function(macroNode,args,title) {
|
||||||
var now = new Date(),
|
var now = new Date(),
|
||||||
args = new ArgParser(macroNode.params,{noNames:true}),
|
|
||||||
value = args.byPos[0] ? utils.formatDateString(now,args.byPos[0].v) : now.toLocaleString();
|
value = args.byPos[0] ? utils.formatDateString(now,args.byPos[0].v) : now.toLocaleString();
|
||||||
macroNode.output.push({type: "text", value: value});
|
macroNode.output.push({type: "text", value: value});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
version: {
|
version: {
|
||||||
handler: function(macroNode,title) {
|
handler: function(macroNode,args,title) {
|
||||||
macroNode.output.push({type: "text", value: WikiTextRenderer.versionTiddlyWiki});
|
macroNode.output.push({type: "text", value: WikiTextRenderer.versionTiddlyWiki});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
view: {
|
view: {
|
||||||
handler: function(macroNode,title) {
|
argOptions: {noNames:true},
|
||||||
var args = new ArgParser(macroNode.params,{noNames:true}),
|
handler: function(macroNode,args,title) {
|
||||||
field = args.byPos[0] ? args.byPos[0].v : null,
|
var field = args.byPos[0] ? args.byPos[0].v : null,
|
||||||
format = args.byPos[1] ? args.byPos[1].v : "text",
|
format = args.byPos[1] ? args.byPos[1].v : "text",
|
||||||
tiddler = this.store.getTiddler(title),
|
tiddler = this.store.getTiddler(title),
|
||||||
value = tiddler ? tiddler.fields[field] : null;
|
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
|
Given the absolute path of a srcModule, and a relative reference to a dstModule, return the fully resolved module name
|
||||||
*/
|
*/
|
||||||
function resolveModuleName(srcModule,dstModule) {
|
function resolveModuleName(srcModule,dstModule) {
|
||||||
console.log("Resolving " + dstModule + " in the context of " + srcModule);
|
|
||||||
var src = srcModule.split("/"),
|
var src = srcModule.split("/"),
|
||||||
dst = dstModule.split("/"),
|
dst = dstModule.split("/"),
|
||||||
c;
|
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.
|
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.
|
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
|
jslib: ../test/tiddlywiki.2.6.5/source/tiddlywiki/jquery/jquery.js
|
||||||
|
|
||||||
|
jsmodule: ../js/Sandbox.js
|
||||||
jsmodule: ../js/ArgParser.js
|
jsmodule: ../js/ArgParser.js
|
||||||
jsmodule: ../js/FileRetriever.js
|
jsmodule: ../js/FileRetriever.js
|
||||||
jsmodule: ../js/Utils.js
|
jsmodule: ../js/Utils.js
|
||||||
|
Loading…
x
Reference in New Issue
Block a user