mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-02-06 18:20:22 +00:00
Compare commits
23 Commits
background
...
dynamic-ma
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e1625afab5 | ||
|
|
2e89771129 | ||
|
|
b6a91521d6 | ||
|
|
8ebf052e25 | ||
|
|
a29ae908e2 | ||
|
|
ff352d63da | ||
|
|
4729e15925 | ||
|
|
7ec985f8e6 | ||
|
|
cadddc13dc | ||
|
|
a2f38ef51d | ||
|
|
54ebf60a05 | ||
|
|
5d72fb0608 | ||
|
|
30e6092819 | ||
|
|
4305a0bb92 | ||
|
|
b3144300ee | ||
|
|
205e8cf9c9 | ||
|
|
ad4c1ca5a1 | ||
|
|
5136e33f07 | ||
|
|
744f6e7a3b | ||
|
|
1ded43f6ea | ||
|
|
48e6863a89 | ||
|
|
f5d5a23aff | ||
|
|
2d6b6b5011 |
@@ -107,13 +107,14 @@ exports.parseStringLiteral = function(source,pos) {
|
||||
type: "string",
|
||||
start: pos
|
||||
};
|
||||
var reString = /(?:"""([\s\S]*?)"""|"([^"]*)")|(?:'([^']*)')/g;
|
||||
var reString = /(?:"""([\s\S]*?)"""|"([^"]*)")|(?:'([^']*)')|\[\[((?:[^\]]|\](?!\]))*)\]\]/g;
|
||||
reString.lastIndex = pos;
|
||||
var match = reString.exec(source);
|
||||
if(match && match.index === pos) {
|
||||
node.value = match[1] !== undefined ? match[1] :(
|
||||
match[2] !== undefined ? match[2] : match[3]
|
||||
);
|
||||
match[2] !== undefined ? match[2] : (
|
||||
match[3] !== undefined ? match[3] : match[4]
|
||||
));
|
||||
node.end = pos + match[0].length;
|
||||
return node;
|
||||
} else {
|
||||
@@ -173,7 +174,7 @@ exports.parseMacroParameter = function(source,pos) {
|
||||
start: pos
|
||||
};
|
||||
// Define our regexp
|
||||
const reMacroParameter = /(?:([A-Za-z0-9\-_]+)\s*:)?(?:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|\[\[([^\]]*)\]\]|((?:(?:>(?!>))|[^\s>"'])+)))/y;
|
||||
const reMacroParameter = /(?:([A-Za-z0-9\-_]+)\s*:)?(?:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|\[\[((?:[^\]]|\](?!\]))*)\]\]|((?:(?:>(?!>))|[^\s>"'])+)))/y;
|
||||
// Skip whitespace
|
||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||
// Look for the parameter
|
||||
@@ -206,28 +207,152 @@ exports.parseMacroParameter = function(source,pos) {
|
||||
Look for a macro invocation. Returns null if not found, or {type: "transclude", attributes:, start:, end:}
|
||||
*/
|
||||
exports.parseMacroInvocationAsTransclusion = function(source,pos) {
|
||||
var node = $tw.utils.parseMacroInvocation(source,pos);
|
||||
if(node) {
|
||||
var positionalName = 0,
|
||||
transclusion = {
|
||||
type: "transclude",
|
||||
start: node.start,
|
||||
end: node.end
|
||||
};
|
||||
$tw.utils.addAttributeToParseTreeNode(transclusion,"$variable",node.name);
|
||||
$tw.utils.each(node.params,function(param) {
|
||||
var name = param.name;
|
||||
if(name) {
|
||||
if(name.charAt(0) === "$") {
|
||||
name = "$" + name;
|
||||
}
|
||||
$tw.utils.addAttributeToParseTreeNode(transclusion,{name: name,type: "string", value: param.value, start: param.start, end: param.end});
|
||||
} else {
|
||||
$tw.utils.addAttributeToParseTreeNode(transclusion,{name: (positionalName++) + "",type: "string", value: param.value, start: param.start, end: param.end});
|
||||
}
|
||||
});
|
||||
return transclusion;
|
||||
var node = {
|
||||
type: "transclude",
|
||||
start: pos,
|
||||
attributes: {},
|
||||
orderedAttributes: []
|
||||
};
|
||||
// Define our regexps
|
||||
var reVarName = /([^\s>"'=:]+)/g;
|
||||
// Skip whitespace
|
||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||
// Look for a double opening angle bracket
|
||||
var token = $tw.utils.parseTokenString(source,pos,"<<");
|
||||
if(!token) {
|
||||
return null;
|
||||
}
|
||||
pos = token.end;
|
||||
// Get the variable name for the macro
|
||||
token = $tw.utils.parseTokenRegExp(source,pos,reVarName);
|
||||
if(!token) {
|
||||
return null;
|
||||
}
|
||||
$tw.utils.addAttributeToParseTreeNode(node,"$variable",token.match[1]);
|
||||
pos = token.end;
|
||||
// Check that the tag is terminated by a space or >>
|
||||
if(!$tw.utils.parseWhiteSpace(source,pos) && !(source.charAt(pos) === ">" && source.charAt(pos + 1) === ">") ) {
|
||||
return null;
|
||||
}
|
||||
// Process attributes
|
||||
pos = $tw.utils.parseMacroParametersAsAttributes(node,source,pos);
|
||||
// Skip whitespace
|
||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||
// Look for a double closing angle bracket
|
||||
token = $tw.utils.parseTokenString(source,pos,">>");
|
||||
if(!token) {
|
||||
return null;
|
||||
}
|
||||
node.end = token.end;
|
||||
return node;
|
||||
};
|
||||
|
||||
/*
|
||||
Parse macro parameters as attributes. Returns the position after the last attribute
|
||||
*/
|
||||
exports.parseMacroParametersAsAttributes = function(node,source,pos) {
|
||||
var position = 0,
|
||||
attribute = $tw.utils.parseMacroParameterAsAttribute(source,pos);
|
||||
while(attribute) {
|
||||
if(!attribute.name) {
|
||||
attribute.name = (position++) + "";
|
||||
attribute.isPositional = true;
|
||||
}
|
||||
node.orderedAttributes.push(attribute);
|
||||
node.attributes[attribute.name] = attribute;
|
||||
pos = attribute.end;
|
||||
// Get the next attribute
|
||||
attribute = $tw.utils.parseMacroParameterAsAttribute(source,pos);
|
||||
}
|
||||
node.end = pos;
|
||||
return pos;
|
||||
};
|
||||
|
||||
/*
|
||||
Parse a macro parameter as an attribute. Returns null if not found, otherwise returns {name:, type: "filtered|string|indirect|macro", value|filter|textReference:, start:, end:,}, with the name being optional
|
||||
*/
|
||||
exports.parseMacroParameterAsAttribute = function(source,pos) {
|
||||
var node = {
|
||||
start: pos
|
||||
};
|
||||
// Define our regexps
|
||||
var reAttributeName = /([^\/\s>"'`=:]+)/g,
|
||||
reUnquotedAttribute = /((?:(?:>(?!>))|[^\s>"'])+)/g,
|
||||
reFilteredValue = /\{\{\{([\S\s]+?)\}\}\}/g,
|
||||
reIndirectValue = /\{\{([^\}]+)\}\}/g,
|
||||
reSubstitutedValue = /(?:```([\s\S]*?)```|`([^`]|[\S\s]*?)`)/g;
|
||||
// Skip whitespace
|
||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||
// Get the attribute name and the separator token
|
||||
var nameToken = $tw.utils.parseTokenRegExp(source,pos,reAttributeName),
|
||||
namePos = nameToken && $tw.utils.skipWhiteSpace(source,nameToken.end),
|
||||
separatorToken = nameToken && $tw.utils.parseTokenRegExp(source,namePos,/=|:/g),
|
||||
isNewStyleSeparator = false; // If there is no separator then we don't allow new style values
|
||||
// If we have a name and a separator then we have a named attribute
|
||||
if(nameToken && separatorToken) {
|
||||
node.name = nameToken.match[1];
|
||||
// key value separator is `=` or `:`
|
||||
node.assignmentOperator = separatorToken.match[0];
|
||||
pos = separatorToken.end;
|
||||
isNewStyleSeparator = (node.assignmentOperator === "=");
|
||||
}
|
||||
// Skip whitespace
|
||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||
// Look for a string literal
|
||||
var stringLiteral = $tw.utils.parseStringLiteral(source,pos);
|
||||
if(stringLiteral) {
|
||||
pos = stringLiteral.end;
|
||||
node.type = "string";
|
||||
node.value = stringLiteral.value;
|
||||
// Mark the value as having been quoted in the source
|
||||
node.quoted = true;
|
||||
} else {
|
||||
// Look for a filtered value
|
||||
var filteredValue = $tw.utils.parseTokenRegExp(source,pos,reFilteredValue);
|
||||
if(filteredValue && isNewStyleSeparator) {
|
||||
pos = filteredValue.end;
|
||||
node.type = "filtered";
|
||||
node.filter = filteredValue.match[1];
|
||||
} else {
|
||||
// Look for an indirect value
|
||||
var indirectValue = $tw.utils.parseTokenRegExp(source,pos,reIndirectValue);
|
||||
if(indirectValue && isNewStyleSeparator) {
|
||||
pos = indirectValue.end;
|
||||
node.type = "indirect";
|
||||
node.textReference = indirectValue.match[1];
|
||||
} else {
|
||||
// Look for a unquoted value
|
||||
var unquotedValue = $tw.utils.parseTokenRegExp(source,pos,reUnquotedAttribute);
|
||||
if(unquotedValue) {
|
||||
pos = unquotedValue.end;
|
||||
node.type = "string";
|
||||
node.value = unquotedValue.match[1];
|
||||
} else {
|
||||
// Look for a macro invocation value
|
||||
var macroInvocation = $tw.utils.parseMacroInvocationAsTransclusion(source,pos);
|
||||
if(macroInvocation && isNewStyleSeparator) {
|
||||
pos = macroInvocation.end;
|
||||
node.type = "macro";
|
||||
node.value = macroInvocation;
|
||||
} else {
|
||||
var substitutedValue = $tw.utils.parseTokenRegExp(source,pos,reSubstitutedValue);
|
||||
if(substitutedValue && isNewStyleSeparator) {
|
||||
pos = substitutedValue.end;
|
||||
node.type = "substituted";
|
||||
node.rawValue = substitutedValue.match[1] || substitutedValue.match[2];
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Bail if we don't have a value
|
||||
if(!node.type) {
|
||||
return null;
|
||||
}
|
||||
// Update the end position
|
||||
node.end = pos;
|
||||
return node;
|
||||
};
|
||||
|
||||
@@ -296,7 +421,7 @@ exports.parseFilterVariable = function(source) {
|
||||
};
|
||||
|
||||
/*
|
||||
Look for an HTML attribute definition. Returns null if not found, otherwise returns {type: "attribute", name:, type: "filtered|string|indirect|macro", value|filter|textReference:, start:, end:,}
|
||||
Look for an HTML attribute definition. Returns null if not found, otherwise returns {name:, type: "filtered|string|indirect|macro", value|filter|textReference:, start:, end:,}
|
||||
*/
|
||||
exports.parseAttribute = function(source,pos) {
|
||||
var node = {
|
||||
@@ -354,7 +479,7 @@ exports.parseAttribute = function(source,pos) {
|
||||
node.value = unquotedValue.match[1];
|
||||
} else {
|
||||
// Look for a macro invocation value
|
||||
var macroInvocation = $tw.utils.parseMacroInvocation(source,pos);
|
||||
var macroInvocation = $tw.utils.parseMacroInvocationAsTransclusion(source,pos);
|
||||
if(macroInvocation) {
|
||||
pos = macroInvocation.end;
|
||||
node.type = "macro";
|
||||
@@ -375,6 +500,7 @@ exports.parseAttribute = function(source,pos) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If there is no equals sign or colon, then this is an attribute with no value, defaulting to "true"
|
||||
node.type = "string";
|
||||
node.value = "true";
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ exports.parse = function() {
|
||||
var paramString = this.match[2],
|
||||
params = [];
|
||||
if(paramString !== "") {
|
||||
var reParam = /\s*([A-Za-z0-9\-_]+)(?:\s*:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|\[\[([^\]]*)\]\]|([^"'\s]+)))?/mg,
|
||||
var reParam = /\s*([A-Za-z0-9\-_]+)(?:\s*:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|\[\[((?:[^\]]|\](?!\]))*)\]\]|([^"'\s]+)))?/mg,
|
||||
paramMatch = reParam.exec(paramString);
|
||||
while(paramMatch) {
|
||||
// Save the parameter details
|
||||
|
||||
@@ -414,7 +414,21 @@ Widget.prototype.computeAttribute = function(attribute,options) {
|
||||
value = [value];
|
||||
}
|
||||
} else if(attribute.type === "macro") {
|
||||
var variableInfo = this.getVariableInfo(attribute.value.name,{params: attribute.value.params});
|
||||
// Get the macro name
|
||||
var macroName = attribute.value.attributes["$variable"].value;
|
||||
// Collect macro parameters
|
||||
var params = [];
|
||||
$tw.utils.each(attribute.value.orderedAttributes,function(attr) {
|
||||
var param = {
|
||||
value: self.computeAttribute(attr)
|
||||
};
|
||||
if(attr.name && !attr.isPositional) {
|
||||
param.name = attr.name;
|
||||
}
|
||||
params.push(param);
|
||||
});
|
||||
// Invoke the macro
|
||||
var variableInfo = this.getVariableInfo(macroName,{params: params});
|
||||
if(options.asList) {
|
||||
value = variableInfo.resultList;
|
||||
} else {
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
created: 20150220191009000
|
||||
modified: 20150602092431500
|
||||
title: $:/editions/tw5.com/railroad/macro-parameter-value
|
||||
title: $:/editions/tw5.com/railroad/call-parameter-value
|
||||
type: text/vnd.tiddlywiki.railroad
|
||||
|
||||
( '"""' [:{/'tout sauf """'/}] '"""'
|
||||
| '"' [:{/'tout sauf "'/}] '"'
|
||||
| "'" [:{/"tout sauf '"/}] "'"
|
||||
| "[[" [:{/"tout sauf ]"/}] "]]"
|
||||
| "`" [:{/"tout sauf `"/}] "`"
|
||||
| "```" [:{/"tout sauf ```"/}] "```"
|
||||
| {/"""tout sauf ' " ou espacevierge"""/}
|
||||
)
|
||||
|
||||
@@ -25,4 +25,4 @@ The <<.place param-nom>> is a sequence of letters (`A`--`Z`, `a`--`z`), digits (
|
||||
|
||||
The <<.place valeur>> is specified as follows<<dp>>
|
||||
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/macro-parameter-value}}/>
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/call-parameter-value}}/>
|
||||
|
||||
@@ -33,7 +33,7 @@ parametre.nom [: [:espace] ":" [:espace] defaut ]
|
||||
|
||||
La valeur par <<.place défaut>> d'un paramètre est spécifiée comme suit<<:>>
|
||||
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/macro-parameter-value}}/>
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/call-parameter-value}}/>
|
||||
|
||||
La définition de la <<.place suite>> se fait comme suit<<:>>
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
title: Macros/Dynamic/Attribute
|
||||
description: Attribute macrocall with dynamic paramters
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Output
|
||||
|
||||
\define mamacromamacro(param:"red")
|
||||
It is $param$
|
||||
\end
|
||||
|
||||
<$text text=<<mamacromamacro>>/>
|
||||
-
|
||||
<$text text=<<mamacromamacro param={{{ [[a]addprefix[b]] }}}>>/>
|
||||
-
|
||||
<$text text=<<mamacromamacro param>>/>
|
||||
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>It is red
|
||||
-
|
||||
It is ba
|
||||
-
|
||||
It is param
|
||||
</p>
|
||||
@@ -0,0 +1,23 @@
|
||||
title: Macros/Dynamic/Standalone
|
||||
description: Standalone macrocall with dynamic paramters
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Output
|
||||
|
||||
\whitespace trim
|
||||
|
||||
\define mamacro(one:"red",two:"green")
|
||||
It is $one$ and $two$ or <<__one__>> and <<__two__>>.
|
||||
\end
|
||||
|
||||
<<mamacro>>
|
||||
|
||||
<<mamacro one={{{ [[b]addprefix[a]] }}}>>
|
||||
|
||||
|
||||
<<mamacro one>>
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>It is red and green or red and green.</p><p>It is ab and green or ab and green.</p><p>It is one and green or one and green.</p>
|
||||
@@ -0,0 +1,9 @@
|
||||
tags: $:/tags/wikitext-serialize-test-spec
|
||||
title: Serialize/DynamicMacroMixed
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<mymacro static:"value" dynamic={{reference}} filter={{{ [tag[test]] }}}>>
|
||||
|
||||
<$macrocall $name="mymacro" static="value" dynamic=<<inner>>/>
|
||||
|
||||
<<mymacro `substituted $(var)$`>>
|
||||
@@ -0,0 +1,9 @@
|
||||
tags: $:/tags/wikitext-serialize-test-spec
|
||||
title: Serialize/DynamicMacroParams
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<mymacro param={{Something}}>>
|
||||
|
||||
<<mymacro param={{{ [<myvar>addprefix[https:]] }}}>>
|
||||
|
||||
<$macrocall $name="outermacro" inner=<<innermacro arg="value">>/>
|
||||
@@ -0,0 +1,7 @@
|
||||
tags: $:/tags/wikitext-serialize-test-spec
|
||||
title: Serialize/DynamicWidgetAttribute
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<div class=<<mymacro param={{Something}}>>>content</div>
|
||||
|
||||
<$button actions=<<myactions target={{!!title}}>>/>
|
||||
@@ -7,3 +7,7 @@ type: text/vnd.tiddlywiki
|
||||
<<.def "macro calls">>
|
||||
|
||||
<<alert "primary" "primary alert" width:"60%">>
|
||||
|
||||
<<john one:val1 two:val2 three:"quoted value">>
|
||||
|
||||
<<test unquoted:value quoted:"value" number:123>>
|
||||
|
||||
@@ -3,3 +3,5 @@ title: Serialize/MacroCallInline
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
These are macro calls in a line: <<name "value" "value2">> and <<.def "macro calls">> <<alert "primary" "primary alert" width:"60%">>
|
||||
|
||||
Testing unquoted parameters: <<john one:val1 two:val2>> and <<test param:value other:"quoted">>.
|
||||
|
||||
@@ -235,11 +235,307 @@ describe("HTML tag new parser tests", function() {
|
||||
expect(parser.parseTag("< $mytag attrib1='something' attrib2=else thing>",0)).toEqual(
|
||||
null
|
||||
);
|
||||
expect(parser.parseTag("<$mytag attrib3=<<myMacro one:two three:'four and five'>>>",0)).toEqual(
|
||||
{ type : "mytag", start : 0, attributes : { attrib3 : { type : "macro", start : 7, name : "attrib3", value : { type : "macrocall", start : 16, params : [ { type : "macro-parameter", start : 25, value : "two", name : "one", end : 33 }, { type : "macro-parameter", start : 33, value : "four and five", name : "three", end : 55 } ], name : "myMacro", end : 57 }, end : 57 } }, orderedAttributes: [ { type : "macro", start : 7, name : "attrib3", value : { type : "macrocall", start : 16, params : [ { type : "macro-parameter", start : 25, value : "two", name : "one", end : 33 }, { type : "macro-parameter", start : 33, value : "four and five", name : "three", end : 55 } ], name : "myMacro", end : 57 }, end : 57 } ], tag : "$mytag", end : 58 }
|
||||
expect(parser.parseTag("<$mytag attrib3=<<myMacro one:two three:'four and five'>>>", 0)).toEqual(
|
||||
{
|
||||
"type": "mytag",
|
||||
"start": 0,
|
||||
"attributes": {
|
||||
"attrib3": {
|
||||
"start": 7,
|
||||
"name": "attrib3",
|
||||
"type": "macro",
|
||||
"value": {
|
||||
"type": "transclude",
|
||||
"start": 16,
|
||||
"attributes": {
|
||||
"$variable": {
|
||||
"name": "$variable",
|
||||
"type": "string",
|
||||
"value": "myMacro"
|
||||
},
|
||||
"one": {
|
||||
"start": 25,
|
||||
"name": "one",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "two",
|
||||
"end": 33
|
||||
},
|
||||
"three": {
|
||||
"start": 33,
|
||||
"name": "three",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "four and five",
|
||||
"quoted": true,
|
||||
"end": 55
|
||||
}
|
||||
},
|
||||
"orderedAttributes": [
|
||||
{
|
||||
"name": "$variable",
|
||||
"type": "string",
|
||||
"value": "myMacro"
|
||||
},
|
||||
{
|
||||
"start": 25,
|
||||
"name": "one",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "two",
|
||||
"end": 33
|
||||
},
|
||||
{
|
||||
"start": 33,
|
||||
"name": "three",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "four and five",
|
||||
"quoted": true,
|
||||
"end": 55
|
||||
}
|
||||
],
|
||||
"end": 57
|
||||
},
|
||||
"end": 57
|
||||
}
|
||||
},
|
||||
"orderedAttributes": [
|
||||
{
|
||||
"start": 7,
|
||||
"name": "attrib3",
|
||||
"type": "macro",
|
||||
"value": {
|
||||
"type": "transclude",
|
||||
"start": 16,
|
||||
"attributes": {
|
||||
"$variable": {
|
||||
"name": "$variable",
|
||||
"type": "string",
|
||||
"value": "myMacro"
|
||||
},
|
||||
"one": {
|
||||
"start": 25,
|
||||
"name": "one",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "two",
|
||||
"end": 33
|
||||
},
|
||||
"three": {
|
||||
"start": 33,
|
||||
"name": "three",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "four and five",
|
||||
"quoted": true,
|
||||
"end": 55
|
||||
}
|
||||
},
|
||||
"orderedAttributes": [
|
||||
{
|
||||
"name": "$variable",
|
||||
"type": "string",
|
||||
"value": "myMacro"
|
||||
},
|
||||
{
|
||||
"start": 25,
|
||||
"name": "one",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "two",
|
||||
"end": 33
|
||||
},
|
||||
{
|
||||
"start": 33,
|
||||
"name": "three",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "four and five",
|
||||
"quoted": true,
|
||||
"end": 55
|
||||
}
|
||||
],
|
||||
"end": 57
|
||||
},
|
||||
"end": 57
|
||||
}
|
||||
],
|
||||
"tag": "$mytag",
|
||||
"end": 58
|
||||
}
|
||||
);
|
||||
expect(parser.parseTag("<$mytag attrib1='something' attrib2=else thing attrib3=<<myMacro one:two three:'four and five'>>>",0)).toEqual(
|
||||
{ type : "mytag", start : 0, attributes : { attrib1 : { type : "string", start : 7, name : "attrib1", value : "something", end : 27 }, attrib2 : { type : "string", start : 27, name : "attrib2", value : "else", end : 40 }, thing : { type : "string", start : 40, name : "thing", value : "true", end : 47 }, attrib3 : { type : "macro", start : 47, name : "attrib3", value : { type : "macrocall", start : 55, params : [ { type : "macro-parameter", start : 64, value : "two", name : "one", end : 72 }, { type : "macro-parameter", start : 72, value : "four and five", name : "three", end : 94 } ], name : "myMacro", end : 96 }, end : 96 } }, orderedAttributes: [ { type : "string", start : 7, name : "attrib1", value : "something", end : 27 }, { type : "string", start : 27, name : "attrib2", value : "else", end : 40 }, { type : "string", start : 40, name : "thing", value : "true", end : 47 }, { type : "macro", start : 47, name : "attrib3", value : { type : "macrocall", start : 55, params : [ { type : "macro-parameter", start : 64, value : "two", name : "one", end : 72 }, { type : "macro-parameter", start : 72, value : "four and five", name : "three", end : 94 } ], name : "myMacro", end : 96 }, end : 96 } ], tag : "$mytag", end : 97 }
|
||||
{
|
||||
"type": "mytag",
|
||||
"start": 0,
|
||||
"attributes": {
|
||||
"attrib1": {
|
||||
"start": 7,
|
||||
"name": "attrib1",
|
||||
"type": "string",
|
||||
"value": "something",
|
||||
"end": 27
|
||||
},
|
||||
"attrib2": {
|
||||
"start": 27,
|
||||
"name": "attrib2",
|
||||
"type": "string",
|
||||
"value": "else",
|
||||
"end": 40
|
||||
},
|
||||
"thing": {
|
||||
"start": 40,
|
||||
"name": "thing",
|
||||
"type": "string",
|
||||
"value": "true",
|
||||
"end": 47
|
||||
},
|
||||
"attrib3": {
|
||||
"start": 47,
|
||||
"name": "attrib3",
|
||||
"type": "macro",
|
||||
"value": {
|
||||
"type": "transclude",
|
||||
"start": 55,
|
||||
"attributes": {
|
||||
"$variable": {
|
||||
"name": "$variable",
|
||||
"type": "string",
|
||||
"value": "myMacro"
|
||||
},
|
||||
"one": {
|
||||
"start": 64,
|
||||
"name": "one",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "two",
|
||||
"end": 72
|
||||
},
|
||||
"three": {
|
||||
"start": 72,
|
||||
"name": "three",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "four and five",
|
||||
"quoted": true,
|
||||
"end": 94
|
||||
}
|
||||
},
|
||||
"orderedAttributes": [
|
||||
{
|
||||
"name": "$variable",
|
||||
"type": "string",
|
||||
"value": "myMacro"
|
||||
},
|
||||
{
|
||||
"start": 64,
|
||||
"name": "one",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "two",
|
||||
"end": 72
|
||||
},
|
||||
{
|
||||
"start": 72,
|
||||
"name": "three",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "four and five",
|
||||
"quoted": true,
|
||||
"end": 94
|
||||
}
|
||||
],
|
||||
"end": 96
|
||||
},
|
||||
"end": 96
|
||||
}
|
||||
},
|
||||
"orderedAttributes": [
|
||||
{
|
||||
"start": 7,
|
||||
"name": "attrib1",
|
||||
"type": "string",
|
||||
"value": "something",
|
||||
"end": 27
|
||||
},
|
||||
{
|
||||
"start": 27,
|
||||
"name": "attrib2",
|
||||
"type": "string",
|
||||
"value": "else",
|
||||
"end": 40
|
||||
},
|
||||
{
|
||||
"start": 40,
|
||||
"name": "thing",
|
||||
"type": "string",
|
||||
"value": "true",
|
||||
"end": 47
|
||||
},
|
||||
{
|
||||
"start": 47,
|
||||
"name": "attrib3",
|
||||
"type": "macro",
|
||||
"value": {
|
||||
"type": "transclude",
|
||||
"start": 55,
|
||||
"attributes": {
|
||||
"$variable": {
|
||||
"name": "$variable",
|
||||
"type": "string",
|
||||
"value": "myMacro"
|
||||
},
|
||||
"one": {
|
||||
"start": 64,
|
||||
"name": "one",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "two",
|
||||
"end": 72
|
||||
},
|
||||
"three": {
|
||||
"start": 72,
|
||||
"name": "three",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "four and five",
|
||||
"quoted": true,
|
||||
"end": 94
|
||||
}
|
||||
},
|
||||
"orderedAttributes": [
|
||||
{
|
||||
"name": "$variable",
|
||||
"type": "string",
|
||||
"value": "myMacro"
|
||||
},
|
||||
{
|
||||
"start": 64,
|
||||
"name": "one",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "two",
|
||||
"end": 72
|
||||
},
|
||||
{
|
||||
"start": 72,
|
||||
"name": "three",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "four and five",
|
||||
"quoted": true,
|
||||
"end": 94
|
||||
}
|
||||
],
|
||||
"end": 96
|
||||
},
|
||||
"end": 96
|
||||
}
|
||||
],
|
||||
"tag": "$mytag",
|
||||
"end": 97
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -261,7 +261,7 @@ describe("WikiText parser tests", function() {
|
||||
);
|
||||
expect(parse("text <<john one:val1 two: 'val \"2\"' three: \"val '3'\" four: \"\"\"val 4\"5'\"\"\" five: [[val 5]] >>")).toEqual(
|
||||
|
||||
[{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"text","text":"text ","start":0,"end":5},{"type":"transclude","start":5,"end":92,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"},"one":{"name":"one","type":"string","value":"val1","start":11,"end":20},"two":{"name":"two","type":"string","value":"val \"2\"","start":20,"end":35},"three":{"name":"three","type":"string","value":"val '3'","start":35,"end":52},"four":{"name":"four","type":"string","value":"val 4\"5'","start":52,"end":73},"five":{"name":"five","type":"string","value":"val 5","start":73,"end":89}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"one","type":"string","value":"val1","start":11,"end":20},{"name":"two","type":"string","value":"val \"2\"","start":20,"end":35},{"name":"three","type":"string","value":"val '3'","start":35,"end":52},{"name":"four","type":"string","value":"val 4\"5'","start":52,"end":73},{"name":"five","type":"string","value":"val 5","start":73,"end":89}]}],"start":0,"end":92}]
|
||||
[{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"text","text":"text ","start":0,"end":5},{"type":"transclude","start":5,"end":92,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"},"one":{"name":"one","assignmentOperator":":","type":"string","value":"val1","start":11,"end":20},"two":{"name":"two","assignmentOperator":":","type":"string","value":"val \"2\"","quoted":true,"start":20,"end":35},"three":{"name":"three","assignmentOperator":":","type":"string","value":"val '3'","quoted":true,"start":35,"end":52},"four":{"name":"four","assignmentOperator":":","type":"string","value":"val 4\"5'","quoted":true,"start":52,"end":73},"five":{"name":"five","assignmentOperator":":","type":"string","value":"val 5","quoted":true,"start":73,"end":89}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"one","assignmentOperator":":","type":"string","value":"val1","start":11,"end":20},{"name":"two","assignmentOperator":":","type":"string","value":"val \"2\"","quoted":true,"start":20,"end":35},{"name":"three","assignmentOperator":":","type":"string","value":"val '3'","quoted":true,"start":35,"end":52},{"name":"four","assignmentOperator":":","type":"string","value":"val 4\"5'","quoted":true,"start":52,"end":73},{"name":"five","assignmentOperator":":","type":"string","value":"val 5","quoted":true,"start":73,"end":89}]}],"start":0,"end":92}]
|
||||
|
||||
);
|
||||
expect(parse("ignored << carrots <<john>>")).toEqual(
|
||||
@@ -287,7 +287,7 @@ describe("WikiText parser tests", function() {
|
||||
);
|
||||
expect(parse("text <<outie one:'my <<innie>>' >>")).toEqual(
|
||||
|
||||
[{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"text","text":"text ","start":0,"end":5},{"type":"transclude","start":5,"end":34,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"outie"},"one":{"name":"one","type":"string","value":"my <<innie>>","start":12,"end":31}},"orderedAttributes":[{"name":"$variable","type":"string","value":"outie"},{"name":"one","type":"string","value":"my <<innie>>","start":12,"end":31}]}],"start":0,"end":34}]
|
||||
[{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"text","text":"text ","start":0,"end":5},{"type":"transclude","start":5,"end":34,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"outie"},"one":{"name":"one","assignmentOperator":":","type":"string","value":"my <<innie>>","quoted":true,"start":12,"end":31}},"orderedAttributes":[{"name":"$variable","type":"string","value":"outie"},{"name":"one","assignmentOperator":":","type":"string","value":"my <<innie>>","quoted":true,"start":12,"end":31}]}],"start":0,"end":34}]
|
||||
|
||||
);
|
||||
|
||||
@@ -301,7 +301,7 @@ describe("WikiText parser tests", function() {
|
||||
);
|
||||
expect(parse("<<john one:val1 two: 'val \"2\"' three: \"val '3'\" four: \"\"\"val 4\"5'\"\"\" five: [[val 5]] >>")).toEqual(
|
||||
|
||||
[{"type":"transclude","start":0,"end":87,"rule":"macrocallblock","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"},"one":{"name":"one","type":"string","value":"val1","start":6,"end":15},"two":{"name":"two","type":"string","value":"val \"2\"","start":15,"end":30},"three":{"name":"three","type":"string","value":"val '3'","start":30,"end":47},"four":{"name":"four","type":"string","value":"val 4\"5'","start":47,"end":68},"five":{"name":"five","type":"string","value":"val 5","start":68,"end":84}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"one","type":"string","value":"val1","start":6,"end":15},{"name":"two","type":"string","value":"val \"2\"","start":15,"end":30},{"name":"three","type":"string","value":"val '3'","start":30,"end":47},{"name":"four","type":"string","value":"val 4\"5'","start":47,"end":68},{"name":"five","type":"string","value":"val 5","start":68,"end":84}],"isBlock":true}]
|
||||
[{"type":"transclude","start":0,"end":87,"rule":"macrocallblock","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"},"one":{"name":"one","assignmentOperator":":","type":"string","value":"val1","start":6,"end":15},"two":{"name":"two","assignmentOperator":":","type":"string","value":"val \"2\"","quoted":true,"start":15,"end":30},"three":{"name":"three","assignmentOperator":":","type":"string","value":"val '3'","quoted":true,"start":30,"end":47},"four":{"name":"four","assignmentOperator":":","type":"string","value":"val 4\"5'","quoted":true,"start":47,"end":68},"five":{"name":"five","assignmentOperator":":","type":"string","value":"val 5","quoted":true,"start":68,"end":84}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"one","assignmentOperator":":","type":"string","value":"val1","start":6,"end":15},{"name":"two","assignmentOperator":":","type":"string","value":"val \"2\"","quoted":true,"start":15,"end":30},{"name":"three","assignmentOperator":":","type":"string","value":"val '3'","quoted":true,"start":30,"end":47},{"name":"four","assignmentOperator":":","type":"string","value":"val 4\"5'","quoted":true,"start":47,"end":68},{"name":"five","assignmentOperator":":","type":"string","value":"val 5","quoted":true,"start":68,"end":84}],"isBlock":true}]
|
||||
|
||||
);
|
||||
expect(parse("<< carrots\n\n<<john>>")).toEqual(
|
||||
@@ -321,12 +321,12 @@ describe("WikiText parser tests", function() {
|
||||
);
|
||||
expect(parse("<<multiline arg:\"\"\"\n\nwikitext\n\"\"\" >>")).toEqual(
|
||||
|
||||
[{"type":"transclude","start":0,"end":36,"rule":"macrocallblock","attributes":{"$variable":{"name":"$variable","type":"string","value":"multiline"},"arg":{"name":"arg","type":"string","value":"\n\nwikitext\n","start":11,"end":33}},"orderedAttributes":[{"name":"$variable","type":"string","value":"multiline"},{"name":"arg","type":"string","value":"\n\nwikitext\n","start":11,"end":33}],"isBlock":true}]
|
||||
[{"type":"transclude","start":0,"end":36,"rule":"macrocallblock","attributes":{"$variable":{"name":"$variable","type":"string","value":"multiline"},"arg":{"name":"arg","assignmentOperator":":","type":"string","value":"\n\nwikitext\n","quoted":true,"start":11,"end":33}},"orderedAttributes":[{"name":"$variable","type":"string","value":"multiline"},{"name":"arg","assignmentOperator":":","type":"string","value":"\n\nwikitext\n","quoted":true,"start":11,"end":33}],"isBlock":true}]
|
||||
|
||||
);
|
||||
expect(parse("<<outie one:'my <<innie>>' >>")).toEqual(
|
||||
|
||||
[ { type: "transclude", start: 0, rule: "macrocallblock", attributes: { $variable: {name: "$variable", type:"string", value: "outie"}, one: {name: "one", type:"string", value: "my <<innie>>", start: 7, end: 26} }, orderedAttributes: [ {name: "$variable", type:"string", value: "outie"}, {name: "one", type:"string", value: "my <<innie>>", start: 7, end: 26} ], end: 29, isBlock: true } ]
|
||||
[ { type: "transclude", start: 0, rule: "macrocallblock", attributes: { $variable: {name: "$variable", type:"string", value: "outie"}, one: {name: "one", assignmentOperator: ":", type:"string", value: "my <<innie>>", quoted: true, start: 7, end: 26} }, orderedAttributes: [ {name: "$variable", type:"string", value: "outie"}, {name: "one", assignmentOperator: ":", type:"string", value: "my <<innie>>", quoted: true, start: 7, end: 26} ], end: 29, isBlock: true } ]
|
||||
|
||||
);
|
||||
});
|
||||
@@ -334,23 +334,23 @@ describe("WikiText parser tests", function() {
|
||||
it("should parse tricky macrocall parameters", function() {
|
||||
expect(parse("<<john pa>am>>")).toEqual(
|
||||
|
||||
[{"type":"transclude","start":0,"end":14,"attributes":{"0":{"name":"0","type":"string","value":"pa>am","start":6,"end":12},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"pa>am","start":6,"end":12}],"isBlock":true,"rule":"macrocallblock"}]
|
||||
[{"type":"transclude","start":0,"end":14,"attributes":{"0":{"name":"0","type":"string","value":"pa>am","start":6,"end":12,"isPositional":true},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"pa>am","start":6,"end":12,"isPositional":true}],"isBlock":true,"rule":"macrocallblock"}]
|
||||
|
||||
);
|
||||
expect(parse("<<john param> >>")).toEqual(
|
||||
|
||||
[{"type":"transclude","start":0,"end":16,"attributes":{"0":{"name":"0","type":"string","value":"param>","start":6,"end":13},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"param>","start":6,"end":13}],"isBlock":true,"rule":"macrocallblock"}]
|
||||
[{"type":"transclude","start":0,"end":16,"attributes":{"0":{"name":"0","type":"string","value":"param>","start":6,"end":13,"isPositional":true},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"param>","start":6,"end":13,"isPositional":true}],"isBlock":true,"rule":"macrocallblock"}]
|
||||
|
||||
);
|
||||
expect(parse("<<john param>>>")).toEqual(
|
||||
|
||||
[{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"transclude","start":0,"end":14,"rule":"macrocallinline","attributes":{"0":{"name":"0","type":"string","value":"param","start":6,"end":12},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"param","start":6,"end":12}]},{"type":"text","text":">","start":14,"end":15}],"start":0,"end":15}]
|
||||
[{"type":"element","rule":"parseblock","tag":"p","children":[{"type":"transclude","start":0,"end":14,"rule":"macrocallinline","attributes":{"0":{"name":"0","type":"string","value":"param","start":6,"end":12,"isPositional":true},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"param","start":6,"end":12,"isPositional":true}]},{"type":"text","text":">","start":14,"end":15}],"start":0,"end":15}]
|
||||
|
||||
);
|
||||
// equals signs should be allowed
|
||||
expect(parse("<<john var>=4 >>")).toEqual(
|
||||
|
||||
[{"type":"transclude","start":0,"end":16,"attributes":{"0":{"name":"0","type":"string","value":"var>=4","start":6,"end":13},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"var>=4","start":6,"end":13}],"isBlock":true,"rule":"macrocallblock"}]
|
||||
[{"type":"transclude","start":0,"end":16,"attributes":{"0":{"name":"0","type":"string","value":"var>=4","start":6,"end":13,"isPositional":true},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"var>=4","start":6,"end":13,"isPositional":true}],"isBlock":true,"rule":"macrocallblock"}]
|
||||
|
||||
);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
caption: function
|
||||
created: 20220909111836951
|
||||
modified: 20230419103154328
|
||||
modified: 20260130210336084
|
||||
op-input: a [[selection of titles|Title Selection]] passed as input to the function <<.place F>>
|
||||
op-output: the [[selection of titles|Title Selection]] returned from the function <<.place F>>
|
||||
op-parameter: first parameter is the [[function name|Functions]], subsequent parameters are passed to the function by position
|
||||
@@ -10,7 +10,7 @@ tags: [[Filter Operators]]
|
||||
title: function Operator
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.from-version "5.3.0">> The <<.op function>> operator applies a named [[function|Functions]] to the input titles, and returns the results from the function. The function is invoked once with all of the input titles (in contrast, the [[filter Operator]] invokes its function separately for each input title).
|
||||
<<.from-version "5.3.0">> The <<.op function>> operator applies a named [[function|Functions]] to the input titles, and returns the results from the function. The function is called once with all of the input titles (in contrast, the [[filter Operator]] calls its function separately for each input title).
|
||||
|
||||
The first parameter of the <<.op function>> operator specifies the name of the function to be called. Subsequent parameters are passed to the function.
|
||||
|
||||
|
||||
@@ -16,12 +16,13 @@ Functions are usually defined with the [[Pragma: \function]]:
|
||||
\end
|
||||
```
|
||||
|
||||
Functions can be invoked in several ways:
|
||||
Functions can be called in several ways:
|
||||
|
||||
* Directly transclude functions with the syntax `<<myfun param:"value">>`
|
||||
* Assign functions to widget attributes with the syntax `<div class=<<myfun param:"value">>>`
|
||||
* Invoke functions via the [[function Operator]] with the syntax `[function[myfun],[value],...]`
|
||||
* Directly invoke functions whose names contain a period as custom filter operators with the syntax `[my.fun[value]]` or `[.myfun[value]]`
|
||||
* Using the [[Calls]] syntax:
|
||||
** Directly transclude functions with the syntax `<<myfun param:"value">>`
|
||||
** Assign functions to widget attributes with the syntax `<div class=<<myfun param:"value">>>`
|
||||
* Call functions via the [[function Operator]] with the syntax `[function[myfun],[value],...]`
|
||||
* Directly call functions whose names contain a period as custom filter operators with the syntax `[my.fun[value]]` or `[.myfun[value]]`
|
||||
|
||||
!! How Functions Work
|
||||
|
||||
|
||||
43
editions/tw5.com/tiddlers/macros/syntax/Call Syntax.tid
Normal file
43
editions/tw5.com/tiddlers/macros/syntax/Call Syntax.tid
Normal file
@@ -0,0 +1,43 @@
|
||||
created: 20240310165023000
|
||||
modified: 20260125212303316
|
||||
tags: [[Call Syntax]]
|
||||
title: Call Syntax
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.preamble """What follows is a formal presentation of the syntax of the WikiText syntax for procedure/function/macro calls, using [[railroad diagrams|Railroad Diagrams]].""">>
|
||||
|
||||
!! callee-name
|
||||
|
||||
<$railroad text="""
|
||||
"<<" [[ callee-name |Calls]] [: [[whitespace|"Filter Whitespace"]] [:{param-value}] ]">>"
|
||||
"""/>
|
||||
|
||||
* The <<.place callee-name>> is a sequence of non-whitespace characters other than `(` or `>`.
|
||||
|
||||
* <<.place whitespace>> denotes a sequence of [[whitespace characters|Filter Whitespace]].
|
||||
|
||||
!!! param-value
|
||||
|
||||
Each ''individual'' <<.place param-value>> has the following syntax:
|
||||
|
||||
<$railroad text="""
|
||||
\start none
|
||||
\end none
|
||||
(
|
||||
value
|
||||
|
|
||||
param-name [:space] (
|
||||
":" [:space] value [: space]
|
||||
|
|
||||
"=" [:space] new-value [: space]
|
||||
)
|
||||
)
|
||||
"""/>
|
||||
|
||||
* The <<.place param-name>> is a sequence of letters (`A`--`Z`, `a`--`z`), digits (`0`--`9`), hyphens (`-`) and underscores (`_`).
|
||||
|
||||
* The <<.place value>> is specified as follows:
|
||||
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/call-parameter-value}}/>
|
||||
|
||||
* <<.from-version 5.4.0>> The <<.place new-value>> can either be a plain <<.place value>> or a full <<.place callee-name>> call, allowing for dynamic parameter values.
|
||||
@@ -1,11 +1,13 @@
|
||||
created: 20150220191009000
|
||||
modified: 20150221111554000
|
||||
title: $:/editions/tw5.com/railroad/macro-parameter-value
|
||||
modified: 20260125212303316
|
||||
title: $:/editions/tw5.com/railroad/call-parameter-value
|
||||
type: text/vnd.tiddlywiki.railroad
|
||||
|
||||
( '"""' [:{/'anything but """'/}] '"""'
|
||||
| '"' [:{/'anything but "'/}] '"'
|
||||
| "'" [:{/"anything but '"/}] "'"
|
||||
| "[[" [:{/"anything but ]"/}] "]]"
|
||||
| "`" [:{/"anything but `"/}] "`"
|
||||
| "```" [:{/"anything but ```"/}] "```"
|
||||
| {/"""anything but ' " or whitespace"""/}
|
||||
)
|
||||
@@ -1,31 +1,7 @@
|
||||
created: 20150221105732000
|
||||
modified: 20150221222352000
|
||||
tags: [[Macro Syntax]] $:/deprecated
|
||||
modified: 20260125212303316
|
||||
tags: $:/deprecated
|
||||
title: Macro Call Syntax
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.deprecated-since "5.3.0" "Procedure Call Syntax">>
|
||||
|
||||
----------
|
||||
|
||||
<<.preamble """What follows is a formal presentation of the syntax of the WikiText syntax for macro calls, using [[railroad diagrams|Railroad Diagrams]]. A [[simpler overview|Macro Calls in WikiText]] is also available.""">>
|
||||
|
||||
<$railroad text="""
|
||||
"<<" name [: space [:{param-value}] ]">>"
|
||||
"""/>
|
||||
|
||||
<<.place space>> denotes a sequence of [[whitespace characters|Filter Whitespace]].
|
||||
|
||||
The [[macro|Macros]]'s <<.place name>> is a sequence of non-whitespace characters other than `(` or `>`.
|
||||
|
||||
Each individual <<.place param-value>> has the following syntax:
|
||||
|
||||
<$railroad text="""
|
||||
[: param-name [:space] ":" [:space] ] value [: space]
|
||||
"""/>
|
||||
|
||||
The <<.place param-name>> is a sequence of letters (`A`--`Z`, `a`--`z`), digits (`0`--`9`), hyphens (`-`) and underscores (`_`).
|
||||
|
||||
The <<.place value>> is specified as follows:
|
||||
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/macro-parameter-value}}/>
|
||||
<<.deprecated-since "5.3.0" "Call Syntax">>
|
||||
|
||||
@@ -37,7 +37,7 @@ param-name [: [:space] ":" [:space] default ]
|
||||
|
||||
The optional <<.place default>> value of a parameter is specified as follows:
|
||||
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/macro-parameter-value}}/>
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/call-parameter-value}}/>
|
||||
|
||||
The <<.place rest>> of the definition has the following syntax:
|
||||
|
||||
|
||||
@@ -1,33 +1,6 @@
|
||||
created: 20240310165023000
|
||||
modified: 20240310172648116
|
||||
tags: [[Procedure Syntax]]
|
||||
modified: 20260125212303316
|
||||
title: Procedure Call Syntax
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.preamble """What follows is a formal presentation of the syntax of the WikiText syntax for procedure calls, using [[railroad diagrams|Railroad Diagrams]].""">>
|
||||
|
||||
!! procedure-name
|
||||
|
||||
<$railroad text="""
|
||||
"<<" [[ procedure-name |Procedures]] [: [[whitespace|"Filter Whitespace"]] [:{param-value}] ]">>"
|
||||
"""/>
|
||||
|
||||
* The [[procedure's|Procedures]] <<.place procedure-name>> is a sequence of non-whitespace characters other than `(` or `>`.
|
||||
|
||||
* <<.place whitespace>> denotes a sequence of [[whitespace characters|Filter Whitespace]].
|
||||
|
||||
!!! param-value
|
||||
|
||||
Each ''individual'' <<.place param-value>> has the following syntax:
|
||||
|
||||
<$railroad text="""
|
||||
\start none
|
||||
\end none
|
||||
[: param-name [:[[whitespace|"Filter Whitespace"]]] ":" [:[[whitespace|"Filter Whitespace"]]] ] value [: [[whitespace|"Filter Whitespace"]] ]
|
||||
"""/>
|
||||
|
||||
* The <<.place param-name>> is a sequence of letters (`A`--`Z`, `a`--`z`), digits (`0`--`9`), hyphens (`-`) and underscores (`_`).
|
||||
|
||||
* The <<.place value>> is specified as follows:
|
||||
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/macro-parameter-value}}/>
|
||||
<<.deprecated-since "5.4.0" "Call Syntax">>
|
||||
@@ -1,6 +1,6 @@
|
||||
created: 20240310165023000
|
||||
modified: 20240310175033730
|
||||
tags: [[Procedure Syntax]]
|
||||
tags: [[Call Syntax]]
|
||||
title: Procedure Definition Syntax
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
@@ -73,7 +73,7 @@ Each ''individual'' <<.place parameter>> has the following syntax:
|
||||
|
||||
* <<.place default>> is an optional value of a parameter is specified as follows:
|
||||
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/macro-parameter-value}}/>
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/call-parameter-value}}/>
|
||||
|
||||
!! body
|
||||
|
||||
|
||||
@@ -6,6 +6,6 @@ type: text/vnd.tiddlywiki
|
||||
|
||||
Plain text description can be found at [[Procedures]]
|
||||
|
||||
<<list-links filter:"[tag[Procedure Syntax]]">>
|
||||
<<list-links filter:"[tag[Call Syntax]]">>
|
||||
|
||||
<<.tip "The railroad boxes in the linked tiddlers can be used to navigate.">>
|
||||
|
||||
@@ -1,56 +1,7 @@
|
||||
caption: Procedure Calls
|
||||
created: 20221007130006705
|
||||
modified: 20230419103154329
|
||||
tags: WikiText Procedures
|
||||
modified: 20260125212303316
|
||||
title: Procedure Calls
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
!! Introduction
|
||||
|
||||
This tiddler describes the different ways in which [[procedure|Procedures]] can be called.
|
||||
|
||||
!! Procedure Call Transclusion Shortcut
|
||||
|
||||
To call a [[procedure|Procedures]], place `<<`double angle brackets`>>` around the name and any parameter values.
|
||||
|
||||
```
|
||||
<<my-procedure param:"This is the parameter value">>
|
||||
```
|
||||
|
||||
By default, parameters are listed in the same order as in the procedure definition. A parameter can be labelled with its name and a colon to allow them to be listed in a different order.
|
||||
|
||||
If no value is specified for a parameter, the default value given for that parameter in the [[procedure definition|Procedure Definitions]] is used instead. (If no default value was defined, the parameter is blank).
|
||||
|
||||
Each parameter value can be enclosed in `'`single quotes`'`, `"`double quotes`"`, `"""`triple double quotes`"""` or `[[`double square brackets`]]`. Triple double quotes allow a value to contain almost anything. If a value contains no spaces or single or double quotes, it requires no delimiters.
|
||||
|
||||
See the discussion about [[parser modes|WikiText parser mode: macro examples]]
|
||||
|
||||
!! Procedure Calls with <<.wlink TranscludeWidget>> Widget
|
||||
|
||||
The shortcut syntax expands to the <<.wlink TranscludeWidget>> widget with the `$variable` attribute specifying the name of the procedure to transclude.
|
||||
|
||||
```
|
||||
<$transclude $variable="my-procedure" param="This is the parameter value"/>
|
||||
```
|
||||
|
||||
The widget itself offers greater flexibility than the shortcut syntax, including the ability to specify dynamic parameter values.
|
||||
|
||||
!! Assigning Procedure Calls to Attribute Values
|
||||
|
||||
The text of a procedure can be directly assigned to an attribute of a widget or HTML element. The result of the procedure is not wikified, which means that [[parameter handling|Procedure Parameter Handling]] does not take place.
|
||||
|
||||
```
|
||||
<div class=<<myclasses>>>
|
||||
...
|
||||
</div>
|
||||
```
|
||||
|
||||
!! Using Procedure Calls in Filters
|
||||
|
||||
Procedure calls can be used in filters. The text is not wikified which again means that the parameters will be ignored.
|
||||
|
||||
```
|
||||
<$list filter="[<my-procedure>]">
|
||||
...
|
||||
</$list>
|
||||
```
|
||||
<<.deprecated-since "5.4.0" "Calls">>
|
||||
@@ -33,6 +33,6 @@ Procedures are implemented as a special kind of [[variable|Variables]]. The only
|
||||
!! Using Procedures
|
||||
|
||||
* [[Procedure Definitions]] describes how to create procedures
|
||||
* [[Procedure Calls]] describes how to use procedures
|
||||
* [[Calls]] describes how to use procedures
|
||||
* [[Procedure Parameter Handling]] describes how procedure parameters work
|
||||
* [[Procedure Syntax]] is a formal syntax description using railroad diagrams
|
||||
* [[Call Syntax]] is a formal syntax description using railroad diagrams
|
||||
|
||||
56
editions/tw5.com/tiddlers/procedures/calls/Calls.tid
Normal file
56
editions/tw5.com/tiddlers/procedures/calls/Calls.tid
Normal file
@@ -0,0 +1,56 @@
|
||||
caption: Calls
|
||||
created: 20221007130006705
|
||||
modified: 20260125212303316
|
||||
tags: WikiText Procedures Functions Macros
|
||||
title: Calls
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
!! Introduction
|
||||
|
||||
This tiddler describes the different ways in which [[procedures|Procedures]], [[functions|Functions]] and [[macros|Macros]] can be called. See [[Call Syntax]] for a formal description of the syntax.
|
||||
|
||||
!! Call Transclusion Shortcut
|
||||
|
||||
To perform a call, place `<<`double angle brackets`>>` around the callee name and any parameter values.
|
||||
|
||||
```
|
||||
<<my-procedure param="This is the parameter value">>
|
||||
```
|
||||
|
||||
By default, parameters are interpreted as being in the same order as in the definition. A parameter value can be labelled with its name and an equals sign to allow them to be listed in a different order.
|
||||
|
||||
If no value is specified for a parameter, the default value given for that parameter in the [[procedure definition|Procedure Definitions]], [[function definition|Function Definitions]] or [[macro definition|Macro Definitions]] is used instead. (If no default value was defined, the parameter is blank).
|
||||
|
||||
Each parameter value can be enclosed in `'`single quotes`'`, `"`double quotes`"`, `"""`triple double quotes`"""` or `[[`double square brackets`]]`. Triple double quotes allow a value to contain almost anything. If a value contains no spaces or single or double quotes, it requires no delimiters. [[Substituted Attribute Values]] enclosed in single or triple back quotes are also supported.
|
||||
|
||||
See the discussion about [[parser modes|WikiText parser mode: macro examples]]
|
||||
|
||||
!! Calls with <<.wlink TranscludeWidget>> Widget
|
||||
|
||||
The shortcut syntax expands to the <<.wlink TranscludeWidget>> widget with the `$variable` attribute specifying the name of the procedure to transclude.
|
||||
|
||||
```
|
||||
<$transclude $variable="my-procedure" param="This is the parameter value"/>
|
||||
```
|
||||
|
||||
The widget itself offers greater flexibility than the shortcut syntax, including the ability to override it with a custom widget.
|
||||
|
||||
!! Assigning Results of Calls to Attribute Values
|
||||
|
||||
The text returned from a call can be directly assigned to an attribute of a widget or HTML element. The result of the call is not wikified, which means that [[parameter handling|Procedure Parameter Handling]] does not take place.
|
||||
|
||||
```
|
||||
<div class=<<myclasses>>>
|
||||
...
|
||||
</div>
|
||||
```
|
||||
|
||||
!! Using Calls in Filters
|
||||
|
||||
Calls can be used in filters. The text is not wikified which again means that the parameters will be ignored.
|
||||
|
||||
```
|
||||
<$list filter="[<my-procedure>]">
|
||||
...
|
||||
</$list>
|
||||
```
|
||||
42
editions/tw5.com/tiddlers/releasenotes/5.4.0/#9055.tid
Normal file
42
editions/tw5.com/tiddlers/releasenotes/5.4.0/#9055.tid
Normal file
@@ -0,0 +1,42 @@
|
||||
title: $:/changenotes/5.4.0/#9055
|
||||
description: Dynamic parameters for macro/procedure/function calls
|
||||
release: 5.4.0
|
||||
tags: $:/tags/ChangeNote
|
||||
change-type: enhancement
|
||||
change-category: hackability
|
||||
github-links: https://github.com/TiddlyWiki/TiddlyWiki5/pull/9055
|
||||
github-contributors: Jermolene
|
||||
|
||||
This PR extends the handling of macro/procedure/function made via the `<<..>>` syntax to allow parameters to be specified dynamically instead of just as static strings. To indicate the new syntax the colon that usually separates a parameter name from its value is replaced by an equals sign.
|
||||
|
||||
For example, by it is now possible to do things like this:
|
||||
|
||||
```
|
||||
<<mymacro param={{Something}}>>
|
||||
```
|
||||
|
||||
Or even this:
|
||||
|
||||
```
|
||||
<div class=<<mymacro param={{Something}}>>>
|
||||
```
|
||||
|
||||
Or this:
|
||||
|
||||
```
|
||||
<div class=<<mymacro param={{{ [<myvar>addprefix[https:] }}}>>>
|
||||
```
|
||||
|
||||
Parameters can also be specified for the inner call:
|
||||
|
||||
```
|
||||
<div class=<<mymacro param={{{ [<innermacro p={{Something}}>addprefix[https:] }}}>>>
|
||||
```
|
||||
|
||||
The extended syntax can be used in three different settings:
|
||||
|
||||
* As a standalone construction
|
||||
* As a widget attribute value
|
||||
* As a filter operand value
|
||||
|
||||
In all cases, it is now possible to use an equals sign instead of a colon to allow parameter values to be passed as a transclusion, filter expression or nested call.
|
||||
@@ -0,0 +1,48 @@
|
||||
title: Improvements to Macro Calls in v5.4.0
|
||||
tags: v5.4.0
|
||||
|
||||
<$macrocall $name='wikitext-example-without-html'
|
||||
src="""\define testmacro(one)
|
||||
Result: $one$.
|
||||
\end testmacro
|
||||
|
||||
<<testmacro one={{{ [[There]addprefix[Hello]] }}}>>
|
||||
"""/>
|
||||
|
||||
<$macrocall $name='wikitext-example-without-html'
|
||||
src="""\function testfunction(one)
|
||||
[<one>addprefix[Hello]]
|
||||
\end testfunction
|
||||
|
||||
<<testfunction one={{{ [[re]addprefix[The]] }}}>>
|
||||
"""/>
|
||||
|
||||
<$macrocall $name='wikitext-example-without-html'
|
||||
src="""\define testmacro(one)
|
||||
Result: $one$.
|
||||
\end testmacro
|
||||
|
||||
<$text text=<<testmacro one={{{ [[There]addprefix[Hello]] }}}>>/>
|
||||
"""/>
|
||||
|
||||
<$macrocall $name='wikitext-example-without-html'
|
||||
src="""\function testfunction(one)
|
||||
[<one>addprefix[Hello]]
|
||||
\end testfunction
|
||||
|
||||
<$text text=<<testfunction one={{{ [[re]addprefix[The]] }}}>>/>
|
||||
"""/>
|
||||
|
||||
<$macrocall $name='wikitext-example'
|
||||
src="""\define innermacro(one)
|
||||
:$one$:$one$:
|
||||
\end innermacro
|
||||
|
||||
\define mymacro(param)
|
||||
|$param$|$param$|
|
||||
\end mymacro
|
||||
|
||||
<div class=<<mymacro param={{{ [<innermacro one={{$:/palette}}>addprefix[The palette named ]] }}}>>>
|
||||
Content
|
||||
</div>
|
||||
"""/>
|
||||
@@ -0,0 +1,52 @@
|
||||
created: 20230726145210484
|
||||
modified: 20260130210336084
|
||||
tags: [[Variable Usage]]
|
||||
title: Behaviour of called variables depends on how the variable was declared
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
\define m1(a1) $a1$ - <<__a1__>> - <<a1>>
|
||||
\procedure p1(a1) $a1$ - <<__a1__>> - <<a1>>
|
||||
\function f1(a1) "$a1$" "-" [<__a1__>] ="-" [<a1>] :and[join[ ]]
|
||||
|
||||
Called in normal wikitext context: `<$transclude $variable=myvar/>` or `<<myvar>>`
|
||||
|
||||
{{Behaviour of variables called via normal wikitext}}
|
||||
|
||||
Called via widget attribute: `<div class=<<myvar>>/>`
|
||||
|
||||
{{Behaviour of variables called via widget attributes}}
|
||||
|
||||
Called via filter operator parameter: `[<myvar>]`
|
||||
|
||||
{{Behaviour of variables called via filter operator parameter}}
|
||||
|
||||
Called via function call in a filter expression: `[function[.myfun]]`
|
||||
|
||||
{{Behaviour of variables called via filter expression function call}}
|
||||
|
||||
!! Examples
|
||||
|
||||
Below is an example macro, procedure and function definition. All three forms of parameter substitution `$a1$`, `<<__a1__>>`, and `<<a1>>` are included in each definition. The output helps illustrate when each form of substitution will or will not have affect.
|
||||
|
||||
```
|
||||
\define m1(a1) $a1$ - <<__a1__>> - <<a1>>
|
||||
\procedure p1(a1) $a1$ - <<__a1__>> - <<a1>>
|
||||
\function f1(a1) $a1$ "-" [<__a1__>] ="-" [<a1>] :and[join[ ]]
|
||||
```
|
||||
|
||||
| !Variable transclusion|!output |
|
||||
| `<<m1 foo>>`|<<m1 foo>>|
|
||||
| `<<p1 foo>>`|<<p1 foo>>|
|
||||
| `<<f1 foo>>`|<<f1 foo>>|
|
||||
| !Widget attribute|!output |
|
||||
| `<$text text=<<m1 foo>>/>`|<$text text=<<m1 foo>>/>|
|
||||
| `<$text text=<<p1 foo>>/>`|<$text text=<<p1 foo>>/>|
|
||||
| `<$text text=<<f1 foo>>/>`|<$text text=<<f1 foo>>/>|
|
||||
| !Filter operator parameter|!output |
|
||||
| `[<m1 foo>]`|<$text text={{{[<m1 foo>]}}}/>|
|
||||
| `[<p1 foo>]`|<$text text={{{[<p1 foo>]}}}/>|
|
||||
| `[<f1 foo>]`|<$text text={{{[<f1 foo>]}}}/>|
|
||||
| !Function call in filter expression|!output |
|
||||
| `[function[m1],[foo]]`|<$text text={{{[function[m1],[foo]]}}}/>|
|
||||
| `[function[p1],[foo]]`|<$text text={{{[function[p1],[foo]]}}}/>|
|
||||
| `[function[f1],[foo]]`|<$text text={{{[function[f1],[foo]]}}}/>|
|
||||
@@ -1,52 +1,6 @@
|
||||
created: 20230726145210484
|
||||
modified: 20240619211734149
|
||||
tags: [[Variable Usage]]
|
||||
title: Behaviour of invoked variables depends on how the variable was declared
|
||||
modified: 20260130210336084
|
||||
title: Behaviour of called variables depends on how the variable was declared
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
\define m1(a1) $a1$ - <<__a1__>> - <<a1>>
|
||||
\procedure p1(a1) $a1$ - <<__a1__>> - <<a1>>
|
||||
\function f1(a1) "$a1$" "-" [<__a1__>] ="-" [<a1>] :and[join[ ]]
|
||||
|
||||
Invoked in normal wikitext context: `<$transclude $variable=myvar/>` or `<<myvar>>`
|
||||
|
||||
{{Behaviour of variables invoked via normal wikitext}}
|
||||
|
||||
Invoked via widget attribute: `<div class=<<myvar>>/>`
|
||||
|
||||
{{Behaviour of variables invoked via widget attributes}}
|
||||
|
||||
Invoked via filter operator parameter: `[<myvar>]`
|
||||
|
||||
{{Behaviour of variables invoked via filter operator parameter}}
|
||||
|
||||
Invoked via function call in a filter expression: `[function[.myfun]]`
|
||||
|
||||
{{Behaviour of variables invoked via filter expression function call}}
|
||||
|
||||
!! Examples
|
||||
|
||||
Below is an example macro, procedure and function definition. All three forms of parameter substitution `$a1$`, `<<__a1__>>`, and `<<a1>>` are included in each definition. The output helps illustrate when each form of substitution will or will not have affect.
|
||||
|
||||
```
|
||||
\define m1(a1) $a1$ - <<__a1__>> - <<a1>>
|
||||
\procedure p1(a1) $a1$ - <<__a1__>> - <<a1>>
|
||||
\function f1(a1) $a1$ "-" [<__a1__>] ="-" [<a1>] :and[join[ ]]
|
||||
```
|
||||
|
||||
| !Variable transclusion|!output |
|
||||
| `<<m1 foo>>`|<<m1 foo>>|
|
||||
| `<<p1 foo>>`|<<p1 foo>>|
|
||||
| `<<f1 foo>>`|<<f1 foo>>|
|
||||
| !Widget attribute|!output |
|
||||
| `<$text text=<<m1 foo>>/>`|<$text text=<<m1 foo>>/>|
|
||||
| `<$text text=<<p1 foo>>/>`|<$text text=<<p1 foo>>/>|
|
||||
| `<$text text=<<f1 foo>>/>`|<$text text=<<f1 foo>>/>|
|
||||
| !Filter operator parameter|!output |
|
||||
| `[<m1 foo>]`|<$text text={{{[<m1 foo>]}}}/>|
|
||||
| `[<p1 foo>]`|<$text text={{{[<p1 foo>]}}}/>|
|
||||
| `[<f1 foo>]`|<$text text={{{[<f1 foo>]}}}/>|
|
||||
| !Function call in filter expression|!output |
|
||||
| `[function[m1],[foo]]`|<$text text={{{[function[m1],[foo]]}}}/>|
|
||||
| `[function[p1],[foo]]`|<$text text={{{[function[p1],[foo]]}}}/>|
|
||||
| `[function[f1],[foo]]`|<$text text={{{[function[f1],[foo]]}}}/>|
|
||||
See [[Behaviour of called variables depends on how the variable was declared]].
|
||||
@@ -6,5 +6,5 @@ type: text/vnd.tiddlywiki
|
||||
|
||||
|tc-first-col-min-width|k
|
||||
|!how declared|!behaviour|
|
||||
|\define, <<.wlink SetWidget>>, <<.wlink LetWidget>>, <<.wlink VarsWidget>>, \procedure, \widget|Every function is a variable, but only variables defined using \function are invokable using the <<.olink function>> filter operator. Attempts to use a non-function variable is the same as if the function doesn't exist. The behavior in this case is like the identity function. All filter input is passed unchanged to the output.|
|
||||
|\define, <<.wlink SetWidget>>, <<.wlink LetWidget>>, <<.wlink VarsWidget>>, \procedure, \widget|Every function is a variable, but only variables defined using \function are callable using the <<.olink function>> filter operator. Attempts to use a non-function variable is the same as if the function doesn't exist. The behavior in this case is like the identity function. All filter input is passed unchanged to the output.|
|
||||
|\function|The body text of the function is treated as a filter expression and evaluated. This filter expression can itself contain a function call. Filter expressions can be factored out into functions arbitrarily deep.|
|
||||
@@ -1,58 +1,7 @@
|
||||
caption: Macro Calls
|
||||
created: 20150220182252000
|
||||
modified: 20230419103154328
|
||||
tags: WikiText Macros
|
||||
title: Macro Calls
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
!! Introduction
|
||||
|
||||
This tiddler describes the different ways in which [[macros|Macros]] can be called.
|
||||
|
||||
!! Macro Call Transclusion Shortcut
|
||||
|
||||
To call a [[macro|Macros]], place `<<`double angle brackets`>>` around the name and any parameter values.
|
||||
|
||||
```
|
||||
<<mymacro param:"This is the parameter value">>
|
||||
```
|
||||
|
||||
By default, parameters are listed in the same order as in the macro's definition. A parameter can be labelled with its name and a colon to allow them to be listed in a different order.
|
||||
|
||||
If no value is specified for a parameter, the default value given for that parameter in the [[macro definition|Macro Definitions]] is used instead. (If no default value was defined, the parameter is blank).
|
||||
|
||||
Each parameter value can be enclosed in `'`single quotes`'`, `"`double quotes`"`, `"""`triple double quotes`"""` or `[[`double square brackets`]]`. Triple double quotes allow a value to contain almost anything. If a value contains no spaces or single or double quotes, it requires no delimiters.
|
||||
|
||||
A more formal [[presentation|Macro Call Syntax]] of this syntax is also available.
|
||||
|
||||
See some [[examples|Macro Calls in WikiText (Examples)]] and discussion about [[parser modes|WikiText parser mode: macro examples]].
|
||||
|
||||
!! Macro Calls with <<.wlink TranscludeWidget>> Widget
|
||||
|
||||
The shortcut syntax expands to the <<.wlink TranscludeWidget>> widget with the `$variable` attribute specifying the name of the macro to transclude.
|
||||
|
||||
```
|
||||
<$transclude $variable="mymacro" param="This is the parameter value"/>
|
||||
```
|
||||
|
||||
The widget itself offers greater flexibility than the shortcut syntax, including the ability to specify parameter values.
|
||||
|
||||
!! Assigning Macro Calls to Attribute Values
|
||||
|
||||
The result of a macro can be directly assigned to an attribute of a widget or HTML element. The result of the macro is not wikified, but the [[parameter substitution|Macro Parameter Handling]] is performed.
|
||||
|
||||
```
|
||||
<div class=<<myclasses "Horizontal">>>
|
||||
...
|
||||
</div>
|
||||
```
|
||||
|
||||
!! Using Macro Calls in Filters
|
||||
|
||||
Macro calls can be used in filters:
|
||||
|
||||
```
|
||||
<$list filter="[<mymacro param:'value'>]">
|
||||
...
|
||||
</$list>
|
||||
```
|
||||
<<.deprecated-since "5.4.0" "Calls">>
|
||||
@@ -18,7 +18,7 @@ exports.serialize = function (node) {
|
||||
if(node.orderedAttributes) {
|
||||
node.orderedAttributes.forEach(function (attribute) {
|
||||
if(attribute.name !== "$variable") {
|
||||
result += " " + $tw.utils.serializeAttribute(attribute,{assignmentSymbol:":"});
|
||||
result += " " + $tw.utils.serializeAttribute(attribute);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -62,14 +62,27 @@ exports.serializeAttribute = function(node,options) {
|
||||
}
|
||||
// If name is number, means it is a positional attribute and name is omitted
|
||||
var positional = parseInt(node.name) >= 0,
|
||||
// `=` in a widget and might be `:` in a macro
|
||||
assign = positional ? "" : (options.assignmentSymbol || "="),
|
||||
// Use the original assignment operator if available, otherwise default to '='
|
||||
assign = positional ? "" : (node.assignmentOperator || "="),
|
||||
attributeString = positional ? "" : node.name;
|
||||
if(node.type === "string") {
|
||||
if(node.value === "true") {
|
||||
return attributeString;
|
||||
}
|
||||
attributeString += assign + '"' + node.value + '"';
|
||||
// For macro parameters (using ':' separator), preserve unquoted values
|
||||
// For widget attributes (using '=' separator), always use quotes
|
||||
if(assign === ":" && !node.quoted) {
|
||||
attributeString += assign + node.value;
|
||||
} else if(assign === "") {
|
||||
// Positional parameter
|
||||
if(!node.quoted) {
|
||||
attributeString += node.value;
|
||||
} else {
|
||||
attributeString += '"' + node.value + '"';
|
||||
}
|
||||
} else {
|
||||
attributeString += assign + '"' + node.value + '"';
|
||||
}
|
||||
} else if(node.type === "filtered") {
|
||||
attributeString += assign + "{{{" + node.filter + "}}}";
|
||||
} else if(node.type === "indirect") {
|
||||
@@ -77,11 +90,36 @@ exports.serializeAttribute = function(node,options) {
|
||||
} else if(node.type === "substituted") {
|
||||
attributeString += assign + "`" + node.rawValue + "`";
|
||||
} else if(node.type === "macro") {
|
||||
if(node.value && typeof node.value === "object" && node.value.type === "macrocall") {
|
||||
var params = node.value.params.map(function(param) {
|
||||
return param.value;
|
||||
}).join(" ");
|
||||
attributeString += assign + "<<" + node.value.name + " " + params + ">>";
|
||||
if(node.value && typeof node.value === "object") {
|
||||
if(node.value.type === "transclude") {
|
||||
// Handle the transclude-based macro call structure
|
||||
var macroName = node.value.attributes && node.value.attributes["$variable"] ?
|
||||
node.value.attributes["$variable"].value : "";
|
||||
if(!macroName) {
|
||||
return null;
|
||||
}
|
||||
var params = [];
|
||||
if(node.value.orderedAttributes) {
|
||||
node.value.orderedAttributes.forEach(function(attr) {
|
||||
if(attr.name !== "$variable") {
|
||||
var paramStr = exports.serializeAttribute(attr);
|
||||
if(paramStr) {
|
||||
params.push(paramStr);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
attributeString += assign + "<<" + macroName + (params.length > 0 ? " " + params.join(" ") : "") + ">>";
|
||||
} else if(node.value.type === "macrocall") {
|
||||
// Handle the classical macrocall structure for backwards compatibility
|
||||
var params = node.value.params.map(function(param) {
|
||||
return param.value;
|
||||
}).join(" ");
|
||||
attributeString += assign + "<<" + node.value.name + " " + params + ">>";
|
||||
} else {
|
||||
// Unsupported macro structure
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
// Unsupported macro structure
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user