diff --git a/core/modules/parsers/wikiparser/rules/parameters.js b/core/modules/parsers/wikiparser/rules/parameters.js index 745d7b7dd..561c1c545 100644 --- a/core/modules/parsers/wikiparser/rules/parameters.js +++ b/core/modules/parsers/wikiparser/rules/parameters.js @@ -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 diff --git a/core/modules/widgets/parameters.js b/core/modules/widgets/parameters.js index d741ffe2c..ce65ac101 100644 --- a/core/modules/widgets/parameters.js +++ b/core/modules/widgets/parameters.js @@ -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(); diff --git a/core/modules/widgets/transclude.js b/core/modules/widgets/transclude.js index c4c4c0321..d98e6b7e4 100755 --- a/core/modules/widgets/transclude.js +++ b/core/modules/widgets/transclude.js @@ -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 ""; + } }; /* diff --git a/core/ui/Components/VisibleTransclude.tid b/core/ui/Components/VisibleTransclude.tid index f654c0520..57ba0a05f 100644 --- a/core/ui/Components/VisibleTransclude.tid +++ b/core/ui/Components/VisibleTransclude.tid @@ -5,41 +5,44 @@ 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) - -<$let - mode={{{ [[$mode]is[variable]then<$mode>!is[blank]] :else[[mode]is[variable]then!is[blank]] :else[match[yes]then[inline]else[block]] }}} - outputTag={{{ [match[inline]then[span]else[div]] }}} - outputColour={{{ [match[inline]then[green]else[red]] }}} -> - - <$genesis $type="element" $tag=<> style="color:white;padding:4px;" style.background=<>> - <$genesis $type="element" $tag=<> style="display: inline-block;"> -
- - <$list filter="[<@params>jsonindexes[]]" emptyMessage="(none)"> -
- <$text text=<>/><$text text=": "/><$text text={{{ [<@params>jsonget] }}}/> -
+\widget $transclude + +<$parameters tiddler="" $$tiddler="" mode="" $$mode="" $params="@params"> + + <$let + mode={{{ [[$mode]is[variable]then<$mode>!is[blank]] :else[[mode]is[variable]then!is[blank]] :else[match[yes]then[inline]else[block]] }}} + outputTag={{{ [match[inline]then[span]else[div]] }}} + outputColour={{{ [match[inline]then[green]else[red]] }}} + > + + <$genesis $type="element" $tag=<> style="color:white;padding:4px;" style.background=<>> + <$genesis $type="element" $tag=<> style="display: inline-block;"> +
+ + <$list filter="[<@params>jsonindexes[]]" emptyMessage="(none)"> +
+ <$text text=<>/><$text text=": "/><$text text={{{ [<@params>jsonget] }}}/> +
+ +
+ + <$genesis $type="element" $tag=<> style="background:white;color:black;padding:4px;"> + + <$list filter="[<@params>jsonindexes[]] :filter[prefix[$]] +[limit[1]]" variable="ignore" emptyMessage=""" + + <$genesis $type="transclude" $remappable="no" $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget]" recursionMarker="no" mode=<>> + + <$slot $name="ts-raw" $depth="2"/> + + """> + + <$genesis $type="transclude" $remappable="no" $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget]" $$recursionMarker="no" $$mode=<>> + + <$slot $name="ts-raw" $depth="2"/> + -
+ - <$genesis $type="element" $tag=<> style="background:white;color:black;padding:4px;"> - - <$list filter="[<@params>jsonindexes[]] :filter[prefix[$]] +[limit[1]]" variable="ignore" emptyMessage=""" - - <$genesis $type="transclude" $remappable="no" $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget]" recursionMarker="no" mode=<>> - - <$slot $name="ts-raw" $depth="2"/> - - """> - - <$genesis $type="transclude" $remappable="no" $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget]" $$recursionMarker="no" $$mode=<>> - - <$slot $name="ts-raw" $depth="2"/> - - - - -<$let> + + \end diff --git a/editions/test/tiddlers/tests/data/genesis-widget/RedefineLet.tid b/editions/test/tiddlers/tests/data/genesis-widget/RedefineLet.tid index 126d1bf33..99bf18e24 100644 --- a/editions/test/tiddlers/tests/data/genesis-widget/RedefineLet.tid +++ b/editions/test/tiddlers/tests/data/genesis-widget/RedefineLet.tid @@ -8,9 +8,11 @@ title: Output \whitespace trim \widget $let \whitespace trim +<$parameters $params="@params"> <$setmultiplevariables $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsongetaddprefix[--]addsuffix[--]]"> <$slot $name="ts-body"/> + \end <$let one="Elephant" diff --git a/editions/test/tiddlers/tests/data/transclude/Parameterised-Depth.tid b/editions/test/tiddlers/tests/data/transclude/Parameterised-Depth.tid new file mode 100644 index 000000000..064e225c8 --- /dev/null +++ b/editions/test/tiddlers/tests/data/transclude/Parameterised-Depth.tid @@ -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=<>/>:<$text text=<<$two>>/> + +<$parameters one='Leopard' $$two='Coelacanth'> + (<$text text=<>/>|<$text text=<<$two>>/>) + ++ +title: ExpectedResult + +

Ferret:Piranha(Leopard|Coelacanth)|Jaguar:Piranha(Leopard|Coelacanth)|Ferret:Osprey(Leopard|Coelacanth)|Jaguar:Falcon(Leopard|Coelacanth)

\ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/transclude/Parameterised-Name-Values.tid b/editions/test/tiddlers/tests/data/transclude/Parameterised-Name-Values.tid index a80abc00c..9d62a7897 100644 --- a/editions/test/tiddlers/tests/data/transclude/Parameterised-Name-Values.tid +++ b/editions/test/tiddlers/tests/data/transclude/Parameterised-Name-Values.tid @@ -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=<>/>: <$text text={{{ [<@params>jsonget] }}}/>} + + title: TiddlerTwo \whitespace trim -\parameters(zero:'Mouse',one:'Horse',two:'Owl') -(<$transclude $tiddler=<> zero=<> one=<> two=<>/>) +\parameters(zero:'Mouse',$one:'Horse',two:'Owl') +(<$transclude $tiddler=<> zero=<> $$one=<<$one>> two=<>/>) + title: ExpectedResult -

{0:}{1:}{2:}

{0:Ferret}

{0:Butterfly}{1:Moth}

{0:Beetle}{1:Scorpion}{2:Snake}

({one:Scorpion}{two:Snake}{zero:Beetle})

\ No newline at end of file +

{0:}{1:}{2:}

{0:Ferret}

{0:Butterfly}{1:Moth}

{0:Beetle}{1:Scorpion}{2:Snake}

({$one:Scorpion}{two:Snake}{zero:Beetle})

\ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/transclude/Parameterised-Simple.tid b/editions/test/tiddlers/tests/data/transclude/Parameterised-Simple.tid index a6228d625..0268f9e59 100644 --- a/editions/test/tiddlers/tests/data/transclude/Parameterised-Simple.tid +++ b/editions/test/tiddlers/tests/data/transclude/Parameterised-Simple.tid @@ -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=<>/> +<$parameters one='Jaguar' $$two='Piranha'> + <$text text=<>/>:<$text text=<<$two>>/> + title: ExpectedResult -

FerretJaguar

\ No newline at end of file +

Ferret:Piranha|Jaguar:Piranha|Ferret:Osprey|Jaguar:Falcon

\ No newline at end of file