From 76cdc17f3b369182bb34808d7714aa12cc7b0974 Mon Sep 17 00:00:00 2001 From: Saq Imtiaz Date: Tue, 23 Nov 2021 14:51:42 +0100 Subject: [PATCH] Support macro parameters in filter run prefixes (#6164) * Support macro params in filter run prefixes and support substitution for variables set by filter run prefixes * feat: add support macro parameters and variable substitution for all filter run prefixes * fix: rename options argument to opts for disambiguation * feat: add support for macro params to cascade filterrun prefix --- core/modules/filterrunprefixes/cascade.js | 22 ++++++------ core/modules/filterrunprefixes/filter.js | 25 +++++++++----- core/modules/filterrunprefixes/map.js | 27 +++++++-------- core/modules/filterrunprefixes/reduce.js | 34 +++++++++---------- core/modules/filterrunprefixes/sort.js | 18 +++++----- core/modules/widgets/widget.js | 6 ++-- .../tiddlers/tests/test-prefixes-filter.js | 16 +++++++++ 7 files changed, 86 insertions(+), 62 deletions(-) diff --git a/core/modules/filterrunprefixes/cascade.js b/core/modules/filterrunprefixes/cascade.js index b42119d7b..da6894d21 100644 --- a/core/modules/filterrunprefixes/cascade.js +++ b/core/modules/filterrunprefixes/cascade.js @@ -26,17 +26,19 @@ exports.cascade = function(operationSubFunction,options) { filterFnList[index] = options.wiki.compileFilter(filter); } var output = filterFnList[index](options.wiki.makeTiddlerIterator([title]),{ - getVariable: function(name) { - switch(name) { - case "currentTiddler": - return "" + title; - case "..currentTiddler": - return widget.getVariable("currentTiddler"); - default: - return widget.getVariable(name); - } + getVariable: function(name,opts) { + opts = opts || {}; + opts.variables = { + "currentTiddler": "" + title, + "..currentTiddler": widget.getVariable("currentTiddler") + }; + if(name in opts.variables) { + return opts.variables[name]; + } else { + return widget.getVariable(name,opts); } - }); + } + }); if(output.length !== 0) { result = output[0]; return false; diff --git a/core/modules/filterrunprefixes/filter.js b/core/modules/filterrunprefixes/filter.js index 55bc25dd7..783b699c2 100644 --- a/core/modules/filterrunprefixes/filter.js +++ b/core/modules/filterrunprefixes/filter.js @@ -16,23 +16,30 @@ Export our filter function exports.filter = function(operationSubFunction,options) { return function(results,source,widget) { if(results.length > 0) { - var resultsToRemove = []; + var resultsToRemove = [], + index = 0; results.each(function(title) { var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{ - getVariable: function(name) { - switch(name) { - case "currentTiddler": - return "" + title; - case "..currentTiddler": - return widget.getVariable("currentTiddler"); - default: - return widget.getVariable(name); + getVariable: function(name,opts) { + opts = opts || {}; + opts.variables = { + "currentTiddler": "" + title, + "..currentTiddler": widget.getVariable("currentTiddler"), + "index": "" + index, + "revIndex": "" + (results.length - 1 - index), + "length": "" + results.length + }; + if(name in opts.variables) { + return opts.variables[name]; + } else { + return widget.getVariable(name,opts); } } }); if(filtered.length === 0) { resultsToRemove.push(title); } + ++index; }); results.remove(resultsToRemove); } diff --git a/core/modules/filterrunprefixes/map.js b/core/modules/filterrunprefixes/map.js index a47763c11..632b160e7 100644 --- a/core/modules/filterrunprefixes/map.js +++ b/core/modules/filterrunprefixes/map.js @@ -20,20 +20,19 @@ exports.map = function(operationSubFunction,options) { results.clear(); $tw.utils.each(inputTitles,function(title) { var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{ - getVariable: function(name) { - switch(name) { - case "currentTiddler": - return "" + title; - case "..currentTiddler": - return widget.getVariable("currentTiddler"); - case "index": - return "" + index; - case "revIndex": - return "" + (inputTitles.length - 1 - index); - case "length": - return "" + inputTitles.length; - default: - return widget.getVariable(name); + getVariable: function(name,opts) { + opts = opts || {}; + opts.variables = { + "currentTiddler": "" + title, + "..currentTiddler": widget.getVariable("currentTiddler"), + "index": "" + index, + "revIndex": "" + (inputTitles.length - 1 - index), + "length": "" + inputTitles.length + }; + if(name in opts.variables) { + return opts.variables[name]; + } else { + return widget.getVariable(name,opts); } } }); diff --git a/core/modules/filterrunprefixes/reduce.js b/core/modules/filterrunprefixes/reduce.js index 3ec30f491..8fe819e3f 100644 --- a/core/modules/filterrunprefixes/reduce.js +++ b/core/modules/filterrunprefixes/reduce.js @@ -15,26 +15,24 @@ Export our filter prefix function exports.reduce = function(operationSubFunction,options) { return function(results,source,widget) { if(results.length > 0) { - var accumulator = ""; - var index = 0; + var accumulator = "", + index = 0; results.each(function(title) { var list = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{ - getVariable: function(name) { - switch(name) { - case "currentTiddler": - return "" + title; - case "..currentTiddler": - return widget.getVariable("currentTiddler"); - case "accumulator": - return "" + accumulator; - case "index": - return "" + index; - case "revIndex": - return "" + (results.length - 1 - index); - case "length": - return "" + results.length; - default: - return widget.getVariable(name); + getVariable: function(name,opts) { + opts = opts || {}; + opts.variables = { + "currentTiddler": "" + title, + "..currentTiddler": widget.getVariable("currentTiddler"), + "index": "" + index, + "revIndex": "" + (results.length - 1 - index), + "length": "" + results.length, + "accumulator": "" + accumulator + }; + if(name in opts.variables) { + return opts.variables[name]; + } else { + return widget.getVariable(name,opts); } } }); diff --git a/core/modules/filterrunprefixes/sort.js b/core/modules/filterrunprefixes/sort.js index 7bf8142c6..6865b175c 100644 --- a/core/modules/filterrunprefixes/sort.js +++ b/core/modules/filterrunprefixes/sort.js @@ -26,14 +26,16 @@ exports.sort = function(operationSubFunction,options) { compareFn; results.each(function(title) { var key = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{ - getVariable: function(name) { - switch(name) { - case "currentTiddler": - return "" + title; - case "..currentTiddler": - return widget.getVariable("currentTiddler"); - default: - return widget.getVariable(name); + getVariable: function(name,opts) { + opts = opts || {}; + opts.variables = { + "currentTiddler": "" + title, + "..currentTiddler": widget.getVariable("currentTiddler") + }; + if(name in opts.variables) { + return opts.variables[name]; + } else { + return widget.getVariable(name,opts); } } }); diff --git a/core/modules/widgets/widget.js b/core/modules/widgets/widget.js index 847b003ff..0ba2444b6 100755 --- a/core/modules/widgets/widget.js +++ b/core/modules/widgets/widget.js @@ -122,7 +122,7 @@ Widget.prototype.getVariableInfo = function(name,options) { }); // Only substitute variable references if this variable was defined with the \define pragma if(variable.isMacroDefinition) { - value = this.substituteVariableReferences(value); + value = this.substituteVariableReferences(value,options); } return { text: value, @@ -175,10 +175,10 @@ Widget.prototype.resolveVariableParameters = function(formalParams,actualParams) return results; }; -Widget.prototype.substituteVariableReferences = function(text) { +Widget.prototype.substituteVariableReferences = function(text,options) { var self = this; return (text || "").replace(/\$\(([^\)\$]+)\)\$/g,function(match,p1,offset,string) { - return self.getVariable(p1,{defaultValue: ""}); + return options.variables && options.variables[p1] || (self.getVariable(p1,{defaultValue: ""})); }); }; diff --git a/editions/test/tiddlers/tests/test-prefixes-filter.js b/editions/test/tiddlers/tests/test-prefixes-filter.js index 1008f9279..cedf2d291 100644 --- a/editions/test/tiddlers/tests/test-prefixes-filter.js +++ b/editions/test/tiddlers/tests/test-prefixes-filter.js @@ -419,6 +419,22 @@ describe("'reduce' and 'intersection' filter prefix tests", function() { // Prepend the position in the list using the index and length variables expect(wiki.filterTiddlers("[tag[shopping]] :map[get[title]addprefix[-]addprefixaddprefix[of]addprefix]").join(",")).toBe("0of4-Brownies,1of4-Chick Peas,2of4-Milk,3of4-Rice Pudding"); }); + + it("should handle macro parameters for filter run prefixes",function() { + var widget = require("$:/core/modules/widgets/widget.js"); + var rootWidget = new widget.widget({ type:"widget", children:[ {type:"widget", children:[]} ] }, + { wiki:wiki, document:$tw.document}); + rootWidget.makeChildWidgets(); + var anchorWidget = rootWidget.children[0]; + rootWidget.setVariable("greet","Hello $name$",[{name:"name"}],true); + rootWidget.setVariable("echo","$text$",[{name:"text"}],true); + // :map prefix + expect(wiki.filterTiddlers("1 :map[subfilterjoin[ ]]",anchorWidget).join(",")).toBe("Hello Tom"); + expect(wiki.filterTiddlers('[tag[shopping]] :map[]',anchorWidget).join(",")).toBe("0 Brownies,1 Chick Peas,2 Milk,3 Rice Pudding"); + // :reduce prefix + expect(wiki.filterTiddlers("1 :reduce[subfilterjoin[ ]]",anchorWidget).join(",")).toBe("Hello Tom"); + expect(wiki.filterTiddlers('[tag[shopping]] :reduce[]',anchorWidget).join(",")).toBe(" 0 Brownies, 1 Chick Peas, 2 Milk, 3 Rice Pudding,"); + }); }); })(); \ No newline at end of file