1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-09-27 14:48:19 +00:00

Allow for macros and classes at both run level and block level

Involving a bit of a refactoring of the parameters to the
$tw.Tree.Macro constructor
This commit is contained in:
Jeremy Ruston 2012-05-28 15:51:52 +01:00
parent aa4d435a67
commit 49a3cb8ede
18 changed files with 89 additions and 50 deletions

View File

@ -14,7 +14,6 @@ Zooming chooser macro
exports.info = {
name: "chooser",
wrapperTag: "div",
params: {
},
events: ["touchstart","touchmove","touchend","mouseover","mousemove","mouseup","mouseout"]

View File

@ -79,11 +79,10 @@ exports.getSliderChildren = function() {
if(this.hasParameter("content")) {
return this.wiki.parseText("text/x-tiddlywiki",this.params.content).tree;
} else if(this.hasParameter("target")) {
return [$tw.Tree.Macro(
"tiddler",
{target: this.params.target},
null,
this.wiki)];
return [$tw.Tree.Macro("tiddler",{
srcParams: {target: this.params.target},
wiki: this.wiki
})];
} else {
return [$tw.Tree.errorNode("No content specified for slider")];
}

View File

@ -148,10 +148,10 @@ exports.executeMacro = function() {
var storyJson = JSON.parse(this.wiki.getTiddlerText(this.params.story)),
storyNode = $tw.Tree.Element("div",{},[]);
for(var t=0; t<storyJson.tiddlers.length; t++) {
var m = $tw.Tree.Macro("tiddler",
{target: storyJson.tiddlers[t].title,template: storyJson.tiddlers[t].template},
null,
this.wiki);
var m = $tw.Tree.Macro("tiddler",{
srcParams: {target: storyJson.tiddlers[t].title,template: storyJson.tiddlers[t].template},
wiki: this.wiki
});
m.execute(this.parents,this.tiddlerTitle);
storyNode.children.push($tw.Tree.Element("div",{},[m]));
}
@ -199,10 +199,10 @@ exports.refreshInDom = function(changes) {
if(tiddlerNode === null) {
// If not, render the tiddler
var m = $tw.Tree.Element("div",{},[
$tw.Tree.Macro("tiddler",
{target: story.tiddlers[t].title,template: story.tiddlers[t].template},
null,
this.wiki)
$tw.Tree.Macro("tiddler",{
srcParams: {target: story.tiddlers[t].title,template: story.tiddlers[t].template},
wiki: this.wiki
})
]);
m.execute(this.parents,this.tiddlerTitle);
m.renderInDom(this.children[0].domNode,this.children[0].domNode.childNodes[t]);

View File

@ -54,10 +54,11 @@ exports.executeMacro = function() {
if(value === undefined) {
return [];
} else {
var link = $tw.Tree.Macro("link",
{to: value},
[$tw.Tree.Text(value)],
this.wiki);
var link = $tw.Tree.Macro("link",{
srcParams: {to: value},
content: [$tw.Tree.Text(value)],
wiki: this.wiki
});
link.execute(parents,this.tiddlerTitle);
return [link];
}

View File

@ -14,7 +14,6 @@ Zooming navigator macro
exports.info = {
name: "zoomer",
wrapperTag: "div",
params: {
},
events: ["touchstart","touchmove","touchend"]

View File

@ -18,7 +18,7 @@ exports.blockParser = true;
exports.regExpString = "\\{\\{(?:[^\\{\\r\\n]+)\\{$";
exports.parse = function(match) {
exports.parse = function(match,isBlock) {
var tree = [],
reStart = /\{\{([^\{\r\n]+){(?:\r?\n)?/mg,
reEnd = /(\}\}\}$(?:\r?\n)?)/mg,

View File

@ -18,7 +18,7 @@ exports.blockParser = true;
exports.regExpString = "!{1,6}";
exports.parse = function(match) {
exports.parse = function(match,isBlock) {
this.pos = match.index + match[0].length;
var classedRun = this.parseClassedRun(/(\r?\n)/mg);
return [$tw.Tree.Element("h1",{"class": classedRun["class"]},classedRun.tree)];

View File

@ -19,7 +19,7 @@ exports.runParser = true;
exports.regExpString = "<[A-Za-z]+\\s*[^>]*>";
exports.parse = function(match) {
exports.parse = function(match,isBlock) {
var reStart = /<([A-Za-z]+)(\s*[^>]*)>/mg,
reAttr = /\s*([A-Za-z\-_]+)(?:\s*=\s*(?:("[^"]*")|('[^']*')|([^"'\s]+)))?/mg;
reStart.lastIndex = this.pos;

View File

@ -30,7 +30,7 @@ var listTypes = {
/*
*/
exports.parse = function(match) {
exports.parse = function(match,isBlock) {
var listStack = [], // Array containing list elements for the previous row in the list
t, listInfo, listElement, itemElement, previousRootListTag;
// Cycle through the rows in the list

View File

@ -18,7 +18,7 @@ exports.blockParser = true;
exports.regExpString = "-{3,}\r?\n";
exports.parse = function(match) {
exports.parse = function(match,isBlock) {
this.pos = match.index + match[0].length;
return [$tw.Tree.Element("hr",{},[])];
};

View File

@ -54,7 +54,7 @@ WikiTextRenderer.prototype.parseBlock = function() {
rule = this.parser.blockRules[t];
}
}
return rule ? rule.parse.call(this,match) : [];
return rule ? rule.parse.call(this,match,true) : [];
} else {
// Treat it as a paragraph if we didn't find a block rule
return [$tw.Tree.Element("p",{},this.parseRun())];
@ -111,7 +111,7 @@ WikiTextRenderer.prototype.parseRun = function(terminatorRegExp) {
}
}
if(rule) {
tree.push.apply(tree,rule.parse.call(this,runRuleMatch));
tree.push.apply(tree,rule.parse.call(this,runRuleMatch,false));
}
// Look for the next run rule
this.parser.runRegExp.lastIndex = this.pos;

View File

@ -19,13 +19,17 @@ exports.blockParser = true;
exports.regExpString = "<<";
exports.parse = function(match) {
exports.parse = function(match,isBlock) {
var regExp = /<<(?:([!@£\$%\^\&\*\(\)`\~'"\|\\\/;\:\.\,\+\=\-\_\{\}])|([^>\s]+))(?:\s*)((?:[^>]|(?:>(?!>)))*)>>/mg;
regExp.lastIndex = this.pos;
match = regExp.exec(this.source);
if(match && match.index === this.pos) {
this.pos = match.index + match[0].length;
var macroNode = $tw.Tree.Macro(match[1] || match[2],match[3],[],this.wiki);
var macroNode = $tw.Tree.Macro(match[1] || match[2],{
srcParams: match[3],
isBlock: isBlock,
wiki: this.wiki
});
this.dependencies.mergeDependencies(macroNode.dependencies);
return [macroNode];
}

View File

@ -18,7 +18,7 @@ exports.runParser = true;
exports.regExpString = "\\[\\[";
exports.parse = function(match) {
exports.parse = function(match,isBlock) {
var regExp = /\[\[(.*?)(?:\|(~)?(.*?))?\]\]/mg;
regExp.lastIndex = this.pos;
match = regExp.exec(this.source);
@ -26,7 +26,11 @@ exports.parse = function(match) {
var text = match[1],
link = match[3] || text;
this.pos = match.index + match[0].length;
var macroNode = $tw.Tree.Macro("link",{to: link},[$tw.Tree.Text(text)],this.wiki);
var macroNode = $tw.Tree.Macro("link",{
srcParams: {to: link},
content: [$tw.Tree.Text(text)],
wiki: this.wiki
});
this.dependencies.mergeDependencies(macroNode.dependencies);
return [macroNode];
}

View File

@ -33,7 +33,7 @@ textPrimitives.wikiLink = "(?:(?:" + textPrimitives.upperLetter + "+" +
exports.regExpString = textPrimitives.unWikiLink + "?" + textPrimitives.wikiLink;
exports.parse = function(match) {
exports.parse = function(match,isBlock) {
this.pos = match.index + match[0].length;
// If the link starts with the unwikilink character then just output it as plain text
if(match[0].substr(0,1) === textPrimitives.unWikiLink) {
@ -48,7 +48,11 @@ exports.parse = function(match) {
return [$tw.Tree.Text(match[0])];
}
}
var macroNode = $tw.Tree.Macro("link",{to: match[0]},[$tw.Tree.Text(match[0])],this.wiki);
var macroNode = $tw.Tree.Macro("link",{
srcParams: {to: match[0]},
content: [$tw.Tree.Text(match[0])],
wiki: this.wiki
});
this.dependencies.mergeDependencies(macroNode.dependencies);
return [macroNode];
};

View File

@ -38,10 +38,14 @@ TiddlyTextParser.prototype.parse = function(type,text) {
var macroName = match[2] || match[3];
if(match[1]) { // Transclusion
macroNode = $tw.Tree.Macro("tiddler",{
target: match[1]
},[],this.wiki);
srcParams: {target: match[1]},
wiki: this.wiki
});
} else if(macroName) { // Macro call
macroNode = $tw.Tree.Macro(macroName,match[4],[],this.wiki);
macroNode = $tw.Tree.Macro(macroName,{
srcParams: match[4],
wiki: this.wiki
});
}
output.push(macroNode);
dependencies.mergeDependencies(macroNode.dependencies);

View File

@ -103,9 +103,13 @@ var enclosedTextHelper = function(w) {
}
};
var insertMacroCall = function(w,output,name,params,children) {
var insertMacroCall = function(w,output,name,params,content) {
if(name in w.wiki.macros) {
var macroNode = $tw.Tree.Macro(name,params,children,w.wiki);
var macroNode = $tw.Tree.Macro(name,{
srcParams: params,
content: content,
wiki: w.wiki
});
w.dependencies.mergeDependencies(macroNode.dependencies);
output.push(macroNode);
}

View File

@ -17,32 +17,39 @@ var Node = require("./node.js").Node;
/*
Construct a renderer node representing a macro invocation
macroName: name of the macro
options: see below
The options available are:
srcParams: a string or a hashmap of parameters (each can be a string, or a fn(tiddler,wiki) for evaluated parameters)
children: optional array of child nodes
store: reference to the WikiStore associated with this macro
content: optional array of child nodes
wiki: reference to the WikiStore associated with this macro
dependencies: optional Dependencies object representing the dependencies of this macro
isBlock: true if this macro is being used as an HTML block
Note that the dependencies will be evaluated if not provided.
*/
var Macro = function(macroName,srcParams,content,wiki,dependencies) {
var MacroClass = wiki ? wiki.macros[macroName] : null; // Get the macro class
var Macro = function(macroName,options) {
options = options || {};
var MacroClass = options.wiki ? options.wiki.macros[macroName] : null; // Get the macro class
if(this instanceof Macro) {
// Save the details
this.macroName = macroName;
this.srcParams = srcParams || {};
this.content = content || [];
this.wiki = wiki;
this.dependencies = dependencies;
this.srcParams = options.srcParams || {};
this.content = options.content || [];
this.wiki = options.wiki;
this.dependencies = options.dependencies;
this.isBlock = options.isBlock;
// Parse the macro parameters if required
if(typeof this.srcParams === "string") {
this.srcParams = this.parseMacroParamString(srcParams);
this.srcParams = this.parseMacroParamString(this.srcParams);
}
// Evaluate the dependencies if required
if(macroName && !this.dependencies) {
this.dependencies = this.evaluateDependencies();
}
// Get a reference to the static information about this macro
if(wiki && wiki.macros[macroName]) {
if(MacroClass) {
this.MacroClass = MacroClass;
this.info = MacroClass.prototype.info;
}
@ -51,7 +58,7 @@ var Macro = function(macroName,srcParams,content,wiki,dependencies) {
if(!MacroClass) {
throw "Unknown macro '" + macroName + "'";
}
return new MacroClass(macroName,srcParams,content,wiki,dependencies);
return new MacroClass(macroName,options);
}
};
@ -129,7 +136,13 @@ Macro.prototype.cloneContent = function() {
};
Macro.prototype.clone = function() {
return new this.MacroClass(this.macroName,this.srcParams,this.cloneContent(),this.wiki,this.dependencies);
return new this.MacroClass(this.macroName,{
srcParams: this.srcParams,
content: this.cloneContent(),
wiki: this.wiki,
isBlock: this.isBlock,
dependencies: this.dependencies
});
};
Macro.prototype.execute = function(parents,tiddlerTitle) {
@ -164,7 +177,7 @@ Macro.prototype.render = function(type) {
Macro.prototype.renderInDom = function(parentDomNode,insertBefore) {
// Create the wrapper node for the macro
var domNode = document.createElement(this.info.wrapperTag || "span");
var domNode = document.createElement(this.isBlock ? "div" : "span");
this.domNode = domNode;
if(insertBefore) {
parentDomNode.insertBefore(domNode,insertBefore);

View File

@ -82,3 +82,11 @@ This is my nice and simple block of text. HelloThere
And another:
<article class="hello" mysignal data-thing='Nothing'><div class="another" mysignal2 data-thing='NothingElse'>This time the text is all squashed up, without line breaks</div></article>
---
Macro calls can be inline like this: <<version>>
Or, at paragraph block level:
<<version>>