diff --git a/core/modules/filters/unknown.js b/core/modules/filters/unknown.js index 7e962b30f..c2e2912a4 100644 --- a/core/modules/filters/unknown.js +++ b/core/modules/filters/unknown.js @@ -20,7 +20,7 @@ Export our filter function exports.unknown = function(source,operator,options) { var customDefinitionTitle = "[" + operator.operator + "[]]", customDefinition = options.widget && options.widget.getVariableInfo && options.widget.getVariableInfo(customDefinitionTitle); - if(customDefinition && customDefinition.srcVariable) { + if(customDefinition && customDefinition.srcVariable && customDefinition.srcVariable.isFunctionDefinition) { var variables = Object.create(null); $tw.utils.each(customDefinition.srcVariable.params,function(param,index) { var value = operator.operands[index]; @@ -37,7 +37,13 @@ exports.unknown = function(source,operator,options) { }; }; var getVariableInfo = function(name,opts) { - return options.widget.getVariableInfo(name,opts); + if(name in variables) { + return { + text: variables[name] + }; + } else { + return options.widget.getVariableInfo(name,opts); + }; } var list = options.wiki.filterTiddlers(customDefinition.srcVariable.value,{getVariable: getVariable,getVariableInfo: getVariableInfo},source); if(operator.prefix === "!") { diff --git a/core/modules/parsers/wikiparser/rules/functiondef.js b/core/modules/parsers/wikiparser/rules/fnprocdef.js similarity index 74% rename from core/modules/parsers/wikiparser/rules/functiondef.js rename to core/modules/parsers/wikiparser/rules/fnprocdef.js index 59d66f9c0..037172c57 100644 --- a/core/modules/parsers/wikiparser/rules/functiondef.js +++ b/core/modules/parsers/wikiparser/rules/fnprocdef.js @@ -1,14 +1,18 @@ /*\ -title: $:/core/modules/parsers/wikiparser/rules/functiondef.js +title: $:/core/modules/parsers/wikiparser/rules/fnprocdef.js type: application/javascript module-type: wikirule -Wiki pragma rule for function definitions +Wiki pragma rule for function and procedure definitions ``` \function name(param:defaultvalue,param2:defaultvalue) definition text \end + +\procedure name(param:defaultvalue,param2:defaultvalue) +definition text +\end ``` \*/ @@ -18,7 +22,7 @@ definition text /*global $tw: false */ "use strict"; -exports.name = "functiondef"; +exports.name = "fnprocdef"; exports.types = {pragma: true}; /* @@ -27,7 +31,7 @@ Instantiate parse rule exports.init = function(parser) { this.parser = parser; // Regexp to match - this.matchRegExp = /^\\function\s+([^(\s]+)(\(\s*([^)]*)\))?(\s*\r?\n)?/mg; + this.matchRegExp = /^\\(function|procedure)\s+([^(\s]+)(\(\s*([^)]*)\))?(\s*\r?\n)?/mg; }; /* @@ -37,9 +41,9 @@ exports.parse = function() { // Move past the macro name and parameters this.parser.pos = this.matchRegExp.lastIndex; // Parse the parameters - var paramString = this.match[3], + var paramString = this.match[4], params = []; - if(this.match[2]) { + if(this.match[3]) { var reParam = /\s*([^:),\s]+)(?:\s*:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|([^,"'\s]+)))?/mg, paramMatch = reParam.exec(paramString); while(paramMatch) { @@ -56,7 +60,7 @@ exports.parse = function() { } // Is this a multiline definition? var reEnd; - if(this.match[4]) { + if(this.match[5]) { // If so, the end of the body is marked with \end reEnd = /(\r?\n\\end[^\S\n\r]*(?:$|\r?\n))/mg; } else { @@ -77,16 +81,21 @@ exports.parse = function() { text = ""; } // Save the macro definition - return [{ + var parseTreeNodes = [{ type: "set", attributes: { - name: {type: "string", value: this.match[1]}, + name: {type: "string", value: this.match[2]}, value: {type: "string", value: text} }, children: [], - params: params, - isFunctionDefinition: true + params: params }]; + if(this.match[1] === "function") { + parseTreeNodes[0].isFunctionDefinition = true; + } else if(this.match[1] === "procedure") { + parseTreeNodes[0].isProcedureDefinition = true; + } + return parseTreeNodes; }; })(); diff --git a/core/modules/widgets/importvariables.js b/core/modules/widgets/importvariables.js index bae920d67..edea63311 100644 --- a/core/modules/widgets/importvariables.js +++ b/core/modules/widgets/importvariables.js @@ -56,9 +56,10 @@ ImportVariablesWidget.prototype.execute = function(tiddlerList) { attributes: parseTreeNode.attributes, params: parseTreeNode.params, isMacroDefinition: parseTreeNode.isMacroDefinition, - isFunctionDefinition: parseTreeNode.isFunctionDefinition + isFunctionDefinition: parseTreeNode.isFunctionDefinition, + isProcedureDefinition: parseTreeNode.isProcedureDefinition }; - if (parseTreeNode.isMacroDefinition || parseTreeNode.isFunctionDefinition) { + if (parseTreeNode.isMacroDefinition || parseTreeNode.isProcedureDefinition) { // Macro definitions can be folded into // current widget instead of adding // another link to the chain. diff --git a/core/modules/widgets/setvariable.js b/core/modules/widgets/setvariable.js index e176cd21d..41a5d95c8 100755 --- a/core/modules/widgets/setvariable.js +++ b/core/modules/widgets/setvariable.js @@ -49,9 +49,11 @@ SetWidget.prototype.execute = function() { this.setEmptyValue = this.getAttribute("emptyValue"); // Set context variable if(this.parseTreeNode.isMacroDefinition) { - this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,!!this.parseTreeNode.isMacroDefinition); + this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,true); } else if(this.parseTreeNode.isFunctionDefinition) { - this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,undefined,{isFunctionDefinition: this.parseTreeNode.isFunctionDefinition}); + this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,undefined,{isFunctionDefinition: true}); + } else if(this.parseTreeNode.isProcedureDefinition) { + this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,undefined,{isProcedureDefinition: true}); } else { this.setVariable(this.setName,this.getValue()); } diff --git a/core/modules/widgets/transclude.js b/core/modules/widgets/transclude.js index afe247ad7..dcb31ad01 100755 --- a/core/modules/widgets/transclude.js +++ b/core/modules/widgets/transclude.js @@ -197,8 +197,8 @@ TranscludeWidget.prototype.getTransclusionTarget = function() { } } if(parser) { - // Add parameters widget for functions - if(srcVariable.isFunctionDefinition) { + // Add parameters widget for procedures + if(srcVariable.isProcedureDefinition) { parser = { tree: [ { diff --git a/core/modules/widgets/widget.js b/core/modules/widgets/widget.js index 74162e52b..fc90a7dc2 100755 --- a/core/modules/widgets/widget.js +++ b/core/modules/widgets/widget.js @@ -89,6 +89,7 @@ value: value of the variable params: array of {name:, default:} for each parameter isMacroDefinition: true if the variable is set via a \define macro pragma (and hence should have variable substitution performed) options includes: + isProcedureDefinition: true if the variable is set via a \procedure pragma (and hence should not have variable substitution performed) isFunctionDefinition: true if the variable is set via a \function pragma (and hence should not have variable substitution performed) */ Widget.prototype.setVariable = function(name,value,params,isMacroDefinition,options) { @@ -97,7 +98,8 @@ Widget.prototype.setVariable = function(name,value,params,isMacroDefinition,opti value: value, params: params, isMacroDefinition: !!isMacroDefinition, - isFunctionDefinition: !!options.isFunctionDefinition + isFunctionDefinition: !!options.isFunctionDefinition, + isProcedureDefinition: !!options.isProcedureDefinition }; }; diff --git a/editions/test/tiddlers/tests/data/genesis-widget/RedefineLet.tid b/editions/test/tiddlers/tests/data/genesis-widget/RedefineLet.tid index 8ef331924..136b16fb8 100644 --- a/editions/test/tiddlers/tests/data/genesis-widget/RedefineLet.tid +++ b/editions/test/tiddlers/tests/data/genesis-widget/RedefineLet.tid @@ -6,7 +6,7 @@ tags: [[$:/tags/wiki-test-spec]] title: Output \whitespace trim -\function <$let> +\procedure <$let> \whitespace trim <$setmultiplevariables $names="[enlist:raw]" $values="[enlist:rawaddprefix[--]addsuffix[--]]"> <$slot $name="ts-body"/> diff --git a/editions/test/tiddlers/tests/data/transclude/CustomWidget-ActionWidget.tid b/editions/test/tiddlers/tests/data/transclude/CustomWidget-ActionWidget.tid index 19e617d68..62793dbda 100644 --- a/editions/test/tiddlers/tests/data/transclude/CustomWidget-ActionWidget.tid +++ b/editions/test/tiddlers/tests/data/transclude/CustomWidget-ActionWidget.tid @@ -13,7 +13,7 @@ title: Actions \whitespace trim -\function <$action-mywidget>(one:'Jaguar') +\procedure <$action-mywidget>(one:'Jaguar') \whitespace trim <$action-setfield $tiddler="Result" $field="text" $value=<>/> \end diff --git a/editions/test/tiddlers/tests/data/transclude/CustomWidget-Override-Codeblock.tid b/editions/test/tiddlers/tests/data/transclude/CustomWidget-Override-Codeblock.tid index 4da0f2033..0741e378b 100644 --- a/editions/test/tiddlers/tests/data/transclude/CustomWidget-Override-Codeblock.tid +++ b/editions/test/tiddlers/tests/data/transclude/CustomWidget-Override-Codeblock.tid @@ -16,7 +16,7 @@ title: Output title: Definition \whitespace trim -\function <$codeblock>(code) +\procedure <$codeblock>(code) <$genesis $type="codeblock" $remappable="no" code={{{ [addprefix[£]addsuffix[@]] }}}/> \end + diff --git a/editions/test/tiddlers/tests/data/transclude/CustomWidget-OverrideTransclude.tid b/editions/test/tiddlers/tests/data/transclude/CustomWidget-OverrideTransclude.tid index 08290b2bb..15a289da8 100644 --- a/editions/test/tiddlers/tests/data/transclude/CustomWidget-OverrideTransclude.tid +++ b/editions/test/tiddlers/tests/data/transclude/CustomWidget-OverrideTransclude.tid @@ -17,7 +17,7 @@ title: TiddlerOne \whitespace trim -\function <$transclude>(one:'Jaguar') +\procedure <$transclude>(one:'Jaguar') \whitespace trim <$text text=<>/> <$slot $name="body"> diff --git a/editions/test/tiddlers/tests/data/transclude/CustomWidget-Simple.tid b/editions/test/tiddlers/tests/data/transclude/CustomWidget-Simple.tid index 74ecb575d..3dadabd03 100644 --- a/editions/test/tiddlers/tests/data/transclude/CustomWidget-Simple.tid +++ b/editions/test/tiddlers/tests/data/transclude/CustomWidget-Simple.tid @@ -13,7 +13,7 @@ title: TiddlerOne \whitespace trim -\function <$mywidget>(one:'Jaguar') +\procedure <$mywidget>(one:'Jaguar') \whitespace trim <$text text=<>/> <$slot $name="ts-body"> diff --git a/editions/test/tiddlers/tests/data/transclude/CustomWidget-TextWidgetOverride.tid b/editions/test/tiddlers/tests/data/transclude/CustomWidget-TextWidgetOverride.tid index 62e52c7a8..53ba3d7e8 100644 --- a/editions/test/tiddlers/tests/data/transclude/CustomWidget-TextWidgetOverride.tid +++ b/editions/test/tiddlers/tests/data/transclude/CustomWidget-TextWidgetOverride.tid @@ -13,7 +13,7 @@ title: TiddlerOne \whitespace trim -\function <$text>(text:'Jaguar') +\procedure <$text>(text:'Jaguar') \whitespace trim <$genesis $type="text" $remappable="no" text=<>/> <$set name="<$text>" value=""> diff --git a/editions/test/tiddlers/tests/data/transclude/CustomWidget-VariableAttribute.tid b/editions/test/tiddlers/tests/data/transclude/CustomWidget-VariableAttribute.tid index 70e1b1d09..0b5ba9e81 100644 --- a/editions/test/tiddlers/tests/data/transclude/CustomWidget-VariableAttribute.tid +++ b/editions/test/tiddlers/tests/data/transclude/CustomWidget-VariableAttribute.tid @@ -13,7 +13,7 @@ title: TiddlerOne \whitespace trim -\function <$mywidget>($variable:'Jaguar') +\procedure <$mywidget>($variable:'Jaguar') \whitespace trim <$text text=<<$variable>>/> <$slot $name="ts-body"> diff --git a/editions/test/tiddlers/tests/data/transclude/Parameterised-Shortcut.tid b/editions/test/tiddlers/tests/data/transclude/Parameterised-Shortcut.tid index 5612793cc..0499cf2d6 100644 --- a/editions/test/tiddlers/tests/data/transclude/Parameterised-Shortcut.tid +++ b/editions/test/tiddlers/tests/data/transclude/Parameterised-Shortcut.tid @@ -6,7 +6,7 @@ tags: [[$:/tags/wiki-test-spec]] title: Output \whitespace trim -\function test(one:'Jaguar') +\procedure test(one:'Jaguar') {<$text text=<>/>} \end diff --git a/editions/test/tiddlers/tests/test-wikitext-parser.js b/editions/test/tiddlers/tests/test-wikitext-parser.js index 25d5c3437..95d68a258 100644 --- a/editions/test/tiddlers/tests/test-wikitext-parser.js +++ b/editions/test/tiddlers/tests/test-wikitext-parser.js @@ -119,7 +119,38 @@ describe("WikiText parser tests", function() { ); }); - it("should parse function definitions with no parameters", function() { + it("should parse procedure definitions with no parameters", function() { + expect(parse("\\procedure myMacro\nnothing\n\\end\n")).toEqual( + + [ { type : 'set', attributes : { name : { type : 'string', value : 'myMacro' }, value : { type : 'string', value : 'nothing' } }, children : [ ], params : [ ], isProcedureDefinition : true } ] + + ); + }); + + it("should parse single line procedure definitions with no parameters", function() { + expect(parse("\\procedure myMacro nothing\n")).toEqual( + + [ { type : 'set', attributes : { name : { type : 'string', value : 'myMacro' }, value : { type : 'string', value : 'nothing' } }, children : [ ], params : [ ], isProcedureDefinition : true } ] + + ); + }); + + it("should parse procedure definitions with parameters", function() { + expect(parse("\\procedure myMacro(one,two,three,four:elephant)\nnothing\n\\end\n")).toEqual( + + [ { type : 'set', attributes : { name : { type : 'string', value : 'myMacro' }, value : { type : 'string', value : 'nothing' } }, children : [ ], params : [ { name: 'one' }, { name: 'two' }, { name: 'three' }, { name: 'four', default: 'elephant' } ], isProcedureDefinition : true } ] + + ); + }); + + it("should parse procedure definitions", function() { + expect(parse("\\procedure myMacro(one:'Jaguar')\n<$text text=<>/>\n\\end\n\n")).toEqual( + + [ { type : 'set', attributes : { name : { type : 'string', value : 'myMacro' }, value : { type : 'string', value : '<$text text=<>/>' } }, children : [ ], params : [ { name: 'one', "default": 'Jaguar' } ], isProcedureDefinition : true } ] + + ); + + }); it("should parse function definitions with no parameters", function() { expect(parse("\\function myMacro\nnothing\n\\end\n")).toEqual( [ { type : 'set', attributes : { name : { type : 'string', value : 'myMacro' }, value : { type : 'string', value : 'nothing' } }, children : [ ], params : [ ], isFunctionDefinition : true } ]