From b8bdb0aeeb0875f3b3f7b6ad85f6fb6e5d208cba Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Fri, 7 Mar 2025 21:48:36 +0000 Subject: [PATCH] Introduce let filter run prefix for assigning filter run result to a variable --- core/modules/filterrunprefixes/let.js | 37 +++++++++++++++++++ core/modules/filters.js | 8 +++- .../tests/data/let-filter-prefix/All.tid | 12 ++++++ .../tests/data/let-filter-prefix/Simple.tid | 12 ++++++ .../filters/syntax/Let Filter Run Prefix.tid | 23 ++++++++++++ .../syntax/Named Filter Run Prefix.tid | 1 + 6 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 core/modules/filterrunprefixes/let.js create mode 100644 editions/test/tiddlers/tests/data/let-filter-prefix/All.tid create mode 100644 editions/test/tiddlers/tests/data/let-filter-prefix/Simple.tid create mode 100644 editions/tw5.com/tiddlers/filters/syntax/Let Filter Run Prefix.tid diff --git a/core/modules/filterrunprefixes/let.js b/core/modules/filterrunprefixes/let.js new file mode 100644 index 000000000..e8218bab4 --- /dev/null +++ b/core/modules/filterrunprefixes/let.js @@ -0,0 +1,37 @@ +/*\ +title: $:/core/modules/filterrunprefixes/let.js +type: application/javascript +module-type: filterrunprefix + +Assign a value to a variable + +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +/* +Export our filter prefix function +*/ +exports.let = function(operationSubFunction,options) { + // Save the variable name + var name = options.suffixes[0][0]; + // Return the filter run prefix function + return function(results,source,widget) { + // Set the input source to the incoming results + var inputSource = widget.wiki.makeTiddlerIterator(results.toArray()); + // Assign the result of the subfunction to the variable + var variables = {}; + variables[name] = operationSubFunction(inputSource,widget)[0] || ""; + // Clear the results + results.clear(); + // Return the variables + return { + variables: variables + }; + }; +}; + +})(); diff --git a/core/modules/filters.js b/core/modules/filters.js index aa82a352a..62f6e7213 100644 --- a/core/modules/filters.js +++ b/core/modules/filters.js @@ -348,7 +348,13 @@ exports.compileFilter = function(filterString) { self.filterRecursionCount = (self.filterRecursionCount || 0) + 1; if(self.filterRecursionCount < MAX_FILTER_DEPTH) { $tw.utils.each(operationFunctions,function(operationFunction) { - operationFunction(results,source,widget); + var operationResult = operationFunction(results,source,widget); + if(operationResult) { + if(operationResult.variables) { + // If the filter run prefix has returned variables, create a new fake widget with those variables + widget = widget.makeFakeWidgetWithVariables(operationResult.variables); + } + } }); } else { results.push("/**-- Excessive filter recursion --**/"); diff --git a/editions/test/tiddlers/tests/data/let-filter-prefix/All.tid b/editions/test/tiddlers/tests/data/let-filter-prefix/All.tid new file mode 100644 index 000000000..9167ec712 --- /dev/null +++ b/editions/test/tiddlers/tests/data/let-filter-prefix/All.tid @@ -0,0 +1,12 @@ +title: LetFilterRunPrefix/All +description: Usage of "all[]" operator within "let" filter run prefix +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: Output + +<$text text={{{ [[colossus]] :let:another[all[]] [] +[join[-]] }}}/> ++ +title: ExpectedResult + +

colossus

\ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/let-filter-prefix/Simple.tid b/editions/test/tiddlers/tests/data/let-filter-prefix/Simple.tid new file mode 100644 index 000000000..6385c83e2 --- /dev/null +++ b/editions/test/tiddlers/tests/data/let-filter-prefix/Simple.tid @@ -0,0 +1,12 @@ +title: LetFilterRunPrefix/Simple +description: Simple usage of "let" filter run prefix +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: Output + +<$text text={{{ :let:varname[[magpie]] [] +[join[-]] }}}/> ++ +title: ExpectedResult + +

magpie

\ No newline at end of file diff --git a/editions/tw5.com/tiddlers/filters/syntax/Let Filter Run Prefix.tid b/editions/tw5.com/tiddlers/filters/syntax/Let Filter Run Prefix.tid new file mode 100644 index 000000000..88ec3f6ac --- /dev/null +++ b/editions/tw5.com/tiddlers/filters/syntax/Let Filter Run Prefix.tid @@ -0,0 +1,23 @@ +created: 20250307212252946 +from-version: 5.3.7 +modified: 20250307212252946 +rp-input: all titles from previous filter runs +rp-output: an empty title list is always returned from the "let" filter run prefix +rp-purpose: assign the result of a filter run to a variable +tags: [[Named Filter Run Prefix]] +title: Let Filter Run Prefix +type: text/vnd.tiddlywiki + +<$railroad text=""" +\start none +\end none +( ":let" ) +( ":" ) +( : "variable" ) +( ":" ) +[[run|"Filter Run"]] +"""/> + +The `:let` filter run prefix assigns the first result of a filter run to a variable that is made available to the remaining [[filter runs|Filter Run]] in the [[filter expression|Filter Expression]]. If the filter run does not return any results then the variable is set to an empty string. + +Within the filter run the [[all Operator]] with an empty parameter retrieves all the titles from the previous filter runs, instead of the usual behaviour of retieving all the titles that were passed to the filter expression. diff --git a/editions/tw5.com/tiddlers/filters/syntax/Named Filter Run Prefix.tid b/editions/tw5.com/tiddlers/filters/syntax/Named Filter Run Prefix.tid index 31534479e..df7315a67 100644 --- a/editions/tw5.com/tiddlers/filters/syntax/Named Filter Run Prefix.tid +++ b/editions/tw5.com/tiddlers/filters/syntax/Named Filter Run Prefix.tid @@ -23,6 +23,7 @@ A named filter run prefix can precede any [[run|Filter Run]] of a [[filter expre [[<":or"> |"Or Filter Run Prefix"]] | [[<":reduce"> |"Reduce Filter Run Prefix"]] | [[<":sort"> /"v5.2.0"/ |"Sort Filter Run Prefix"]] | +[[<":let"> /"v5.3.7"/ |"Let Filter Run Prefix"]] | [[<":then"> /"v5.3.0"/ |"Then Filter Run Prefix"]]) [[run|"Filter Run"]] """/>