From 09330968cc7b1dab798a9774bdc8160ad12a787d Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Tue, 20 Nov 2018 13:29:44 +0000 Subject: [PATCH] New "else" prefix for filters (#3558) * Experimental "else" prefix for filters See #3557 * Docs updates for "else" filter runs --- core/modules/filters.js | 9 ++++++++- editions/test/tiddlers/tests/test-filters.js | 7 +++++++ .../tiddlers/filters/syntax/Filter Expression.tid | 10 ++++++---- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/core/modules/filters.js b/core/modules/filters.js index e9117bec1..fdad467d2 100644 --- a/core/modules/filters.js +++ b/core/modules/filters.js @@ -119,7 +119,7 @@ exports.parseFilter = function(filterString) { p = 0, // Current position in the filter string match; var whitespaceRegExp = /(\s+)/mg, - operandRegExp = /((?:\+|\-)?)(?:(\[)|(?:"([^"]*)")|(?:'([^']*)')|([^\s\[\]]+))/mg; + operandRegExp = /((?:\+|\-|~)?)(?:(\[)|(?:"([^"]*)")|(?:'([^']*)')|([^\s\[\]]+))/mg; while(p < filterString.length) { // Skip any whitespace whitespaceRegExp.lastIndex = p; @@ -259,6 +259,13 @@ exports.compileFilter = function(filterString) { results.splice(0,results.length); $tw.utils.pushTop(results,operationSubFunction(source,widget)); }; + case "~": // This operation is unioned into the result only if the main result so far is empty + return function(results,source,widget) { + if(results.length === 0) { + // Main result so far is empty + $tw.utils.pushTop(results,operationSubFunction(source,widget)); + } + }; } })()); }); diff --git a/editions/test/tiddlers/tests/test-filters.js b/editions/test/tiddlers/tests/test-filters.js index 191168ae4..0ef8f551d 100644 --- a/editions/test/tiddlers/tests/test-filters.js +++ b/editions/test/tiddlers/tests/test-filters.js @@ -102,6 +102,13 @@ describe("Filter tests", function() { // Our tests + it("should handle the ~ prefix", function() { + expect(wiki.filterTiddlers("[modifier[JoeBloggs]] ~[[No such tiddler]]").join(",")).toBe("TiddlerOne"); + expect(wiki.filterTiddlers("[modifier[JaneBloggs]] ~[[No such tiddler]]").join(",")).toBe("No such tiddler"); + expect(wiki.filterTiddlers("~[[No such tiddler]]").join(",")).toBe("No such tiddler"); + expect(wiki.filterTiddlers("[my-field[present]] ~[[No such tiddler]]").join(",")).toBe("No such tiddler"); + }); + it("should handle the lookup operator", function() { expect(wiki.filterTiddlers("Six Seventh 8 +[lookup[Tiddler]]").join(",")).toBe("Missing inaction from TiddlerOne,,Tidd"); expect(wiki.filterTiddlers("Six Seventh 8 +[lookup:8[Tiddler]]").join(",")).toBe("Missing inaction from TiddlerOne,Tidd,Tidd"); diff --git a/editions/tw5.com/tiddlers/filters/syntax/Filter Expression.tid b/editions/tw5.com/tiddlers/filters/syntax/Filter Expression.tid index 430a900cd..8550fa394 100644 --- a/editions/tw5.com/tiddlers/filters/syntax/Filter Expression.tid +++ b/editions/tw5.com/tiddlers/filters/syntax/Filter Expression.tid @@ -1,5 +1,5 @@ created: 20150124182421000 -modified: 20171212073225103 +modified: 20181120125803533 tags: [[Filter Syntax]] title: Filter Expression type: text/vnd.tiddlywiki @@ -7,7 +7,7 @@ type: text/vnd.tiddlywiki <$railroad text=""" [{: [: [[whitespace|"Filter Whitespace"]] ] - ("+"|:-|"-") + ("+"|"~"|:-|"-") [[run|"Filter Run"]] }] """/> @@ -19,6 +19,7 @@ If a run has: * no prefix, its output titles are [[dominantly appended|Dominant Append]] to the filter's output * the prefix `-`, output titles are <<.em removed>> from the filter's output (if such tiddlers exist) * the prefix `+`, it receives the filter output so far as its input; its output then <<.em "replaces">> all filter ouput so far and forms the input for the next run +* <<.from-version "5.1.18">> the prefix `~`, if the filter output so far is an empty list then the output titles of the run are [[dominantly appended|Dominant Append]] to the filter's output. If the filter output so far is not an empty list then the run is ignored In technical / logical terms: @@ -26,11 +27,12 @@ In technical / logical terms: |`run` |union of sets |... OR run | |`+run` |intersection of sets |... AND run | |`-run` |difference of sets |... AND NOT run | +|`~run` |else |... ELSE run | -A run's input is normally a list of all the non-[[shadow|ShadowTiddlers]] tiddler titles in the wiki (in no particular order). But the `+` prefix can change this: +The input of a run is normally a list of all the non-[[shadow|ShadowTiddlers]] tiddler titles in the wiki (in no particular order). But the `+` prefix can change this: |Prefix|Input|h -|`-` or none| <$link to="all Operator">`[all[]]` tiddler titles, unless otherwise determined by the first [[filter operator|Filter Operators]]| +|`-`, `~` or none| <$link to="all Operator">`[all[]]` tiddler titles, unless otherwise determined by the first [[filter operator|Filter Operators]]| |`+`|the filter output of all previous runs so far| Precisely because of varying inputs, be aware that both prefixes `-` and `+` do not behave inverse to one another!