1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-12-24 17:10:29 +00:00

Refactor $parameters widget

The objective is to add a $depth attribute so that it is possible to reach up to retrieve the parameters of ancestor transclusions. However, doing so requires changing the encoding of parameter names so that it is not possible for a user parameter to clash with an attribute like $depth. So now we have to double up dollars on any attribute names seen by the parameters widget, just like with the transclude widget itself.
This commit is contained in:
jeremy@jermolene.com 2022-05-31 09:03:20 +01:00
parent 150266c731
commit 006ae6e759
8 changed files with 142 additions and 62 deletions

View File

@ -40,8 +40,13 @@ exports.parse = function() {
var attributes = Object.create(null),
orderedAttributes = [];
$tw.utils.each(params,function(param) {
var attribute = {name: param.name, type: "string", value: param["default"] || ""};
attributes[param.name] = attribute;
var name = param.name;
// Parameter names starting with dollar must be escaped to double dollars for the parameters widget
if(name.charAt(0) === "$") {
name = "$" + name;
}
var attribute = {name: name, type: "string", value: param["default"] || ""};
attributes[name] = attribute;
orderedAttributes.push(attribute);
});
// Save the macro definition

View File

@ -42,21 +42,41 @@ Compute the internal state of the widget
*/
ParametersWidget.prototype.execute = function() {
var self = this;
// Find the parent transclusion
var transclusionWidget = this.parentWidget;
while(transclusionWidget && !(transclusionWidget instanceof TranscludeWidget)) {
transclusionWidget = transclusionWidget.parentWidget;
this.parametersDepth = parseInt(this.getAttribute("$depth","1"),10) || 1;
// Find the parent transclusions
var pointer = this.parentWidget,
depth = this.parametersDepth;
while(pointer) {
if(pointer instanceof TranscludeWidget) {
depth--;
if(depth === 0) {
break;
}
}
pointer = pointer.parentWidget;
}
// Process each parameter
if(transclusionWidget) {
if(pointer instanceof TranscludeWidget) {
// Get the value for each defined parameter
$tw.utils.each($tw.utils.getOrderedAttributesFromParseTreeNode(self.parseTreeNode),function(attr,index) {
var name = attr.name,
value = transclusionWidget.getTransclusionParameter(name,index,self.getAttribute(name,""));
self.setVariable(name,value);
});
$tw.utils.each(transclusionWidget.getTransclusionMetaVariables(),function(value,name) {
var name = attr.name;
// If the attribute name starts with $$ then reduce to a single dollar
if(name.substr(0,2) === "$$") {
name = name.substr(1);
}
var value = pointer.getTransclusionParameter(name,index,self.getAttribute(attr.name,""));
self.setVariable(name,value);
});
// Assign any metaparameters
var assignMetaParameter = function(name) {
var variableName = self.getAttribute("$" + name);
if(variableName !== undefined) {
self.setVariable(variableName,pointer.getTransclusionMetaParameter(name));
}
};
assignMetaParameter("parseAsInline");
assignMetaParameter("parseTreeNodes");
assignMetaParameter("params");
}
// Construct the child widgets
this.makeChildWidgets();

View File

@ -198,7 +198,12 @@ TranscludeWidget.prototype.getTransclusionTarget = function() {
type: parser.type
}
$tw.utils.each(srcVariable.params,function(param) {
$tw.utils.addAttributeToParseTreeNode(parser.tree[0],param.name,param["default"])
var name = param.name;
// Parameter names starting with dollar must be escaped to double dollars
if(name.charAt(0) === "$") {
name = "$" + name;
}
$tw.utils.addAttributeToParseTreeNode(parser.tree[0],name,param["default"])
});
} else {
// For macros and ordinary variables, wrap the parse tree in a vars widget assigning the parameters to variables named "__paramname__"
@ -299,14 +304,19 @@ TranscludeWidget.prototype.getTransclusionParameter = function(name,index,defaul
};
/*
Get a hashmap of the special variables to be provided by the parameters widget
Get one of the special parameters to be provided by the parameters widget
*/
TranscludeWidget.prototype.getTransclusionMetaVariables = function() {
var variables = {
"@parseAsInline": this.parseAsInline ? "yes" : "no",
"@params": JSON.stringify(this.stringParametersByName)
};
return variables;
TranscludeWidget.prototype.getTransclusionMetaParameter = function(name) {
switch(name) {
case "parseAsInline":
return this.parseAsInline ? "yes" : "no";
case "parseTreeNodes":
return JSON.stringify(this.parseTreeNode);
case "params":
return JSON.stringify(this.stringParametersByName);
default:
return "";
}
};
/*

View File

@ -5,13 +5,15 @@ Import this component to make all the child transclusions visible.
Block transclusions are shown in red, and inline transclusions are shown in green.
-->
\widget $transclude(tiddler,$tiddler,mode,$mode)
<!-- Replicate the logic of the transclude widget to determine the output mode, and hence the tag and colour to use for output -->
<$let
\widget $transclude
<!-- Use a parameters widget so that we can access the `$params` data -->
<$parameters tiddler="" $$tiddler="" mode="" $$mode="" $params="@params">
<!-- Replicate the logic of the transclude widget to determine the output mode, and hence the tag and colour to use for output -->
<$let
mode={{{ [[$mode]is[variable]then<$mode>!is[blank]] :else[[mode]is[variable]then<mode>!is[blank]] :else[<parseAsInline>match[yes]then[inline]else[block]] }}}
outputTag={{{ [<mode>match[inline]then[span]else[div]] }}}
outputColour={{{ [<mode>match[inline]then[green]else[red]] }}}
>
>
<!-- Use divs or spans according to the mode -->
<$genesis $type="element" $tag=<<outputTag>> style="color:white;padding:4px;" style.background=<<outputColour>>>
<$genesis $type="element" $tag=<<outputTag>> style="display: inline-block;">
@ -41,5 +43,6 @@ Block transclusions are shown in red, and inline transclusions are shown in gree
</$list>
</$genesis>
</$genesis>
<$let>
</$let>
</$parameters>
\end

View File

@ -8,9 +8,11 @@ title: Output
\whitespace trim
\widget $let
\whitespace trim
<$parameters $params="@params">
<$setmultiplevariables $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>addprefix[--]addsuffix[--]]">
<$slot $name="ts-body"/>
</$setmultiplevariables>
</$parameters>
\end
<$let
one="Elephant"

View File

@ -0,0 +1,34 @@
title: Transclude/Parameterised/Depth
description: Parameterised transclusion using the $depth attribute
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
<$transclude $tiddler='TiddlerOne' one='Ferret'/>
|
<$transclude $tiddler='TiddlerOne'/>
|
<$transclude $tiddler='TiddlerOne' one='Ferret' $$two="Osprey"/>
|
<$transclude $tiddler='TiddlerOne' $$two="Falcon"/>
+
title: TiddlerOne
\whitespace trim
{{TiddlerTwo}}
+
title: TiddlerTwo
\whitespace trim
<$parameters one='Jaguar' $$two='Piranha' $depth="2">
<$text text=<<one>>/>:<$text text=<<$two>>/>
</$parameters>
<$parameters one='Leopard' $$two='Coelacanth'>
(<$text text=<<one>>/>|<$text text=<<$two>>/>)
</$parameters>
+
title: ExpectedResult
<p>Ferret:Piranha(Leopard|Coelacanth)|Jaguar:Piranha(Leopard|Coelacanth)|Ferret:Osprey(Leopard|Coelacanth)|Jaguar:Falcon(Leopard|Coelacanth)</p>

View File

@ -17,17 +17,18 @@ title: Output
title: TiddlerOne
\whitespace trim
\parameters(zero:'Jaguar',one:'Lizard',two:'Mole')
<$parameters zero='Jaguar' $$one='Lizard' two='Mole' $params="@params">
<$list filter="[<@params>jsonindexes[]]">
{<$text text=<<currentTiddler>>/>: <$text text={{{ [<@params>jsonget<currentTiddler>] }}}/>}
</$list>
</$parameters>
+
title: TiddlerTwo
\whitespace trim
\parameters(zero:'Mouse',one:'Horse',two:'Owl')
(<$transclude $tiddler=<<currentTiddler>> zero=<<zero>> one=<<one>> two=<<two>>/>)
\parameters(zero:'Mouse',$one:'Horse',two:'Owl')
(<$transclude $tiddler=<<currentTiddler>> zero=<<zero>> $$one=<<$one>> two=<<two>>/>)
+
title: ExpectedResult
<p>{0:}{1:}{2:}</p><p></p><p>{0:Ferret}</p><p>{0:Butterfly}{1:Moth}</p><p>{0:Beetle}{1:Scorpion}{2:Snake}</p><p>({one:Scorpion}{two:Snake}{zero:Beetle})</p>
<p>{0:}{1:}{2:}</p><p></p><p>{0:Ferret}</p><p>{0:Butterfly}{1:Moth}</p><p>{0:Beetle}{1:Scorpion}{2:Snake}</p><p>({$one:Scorpion}{two:Snake}{zero:Beetle})</p>

View File

@ -7,15 +7,20 @@ title: Output
\whitespace trim
<$transclude $tiddler='TiddlerOne' one='Ferret'/>
|
<$transclude $tiddler='TiddlerOne'/>
|
<$transclude $tiddler='TiddlerOne' one='Ferret' $$two="Osprey"/>
|
<$transclude $tiddler='TiddlerOne' $$two="Falcon"/>
+
title: TiddlerOne
\whitespace trim
<$parameters one='Jaguar'>
<$text text=<<one>>/>
<$parameters one='Jaguar' $$two='Piranha'>
<$text text=<<one>>/>:<$text text=<<$two>>/>
</$parameters>
+
title: ExpectedResult
<p>FerretJaguar</p>
<p>Ferret:Piranha|Jaguar:Piranha|Ferret:Osprey|Jaguar:Falcon</p>