1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-11-15 22:34:51 +00:00

Support case insensitive matching in prefix/suffix operators (#6468)

* Support case insensitive matching in prefix/suffix operators

Support `caseinsensitive`/`caseinsensitive` suffixes in the following
filter operators:

  * prefix
  * suffix
  * removeprefix
  * removesuffix

The suffixes have the same behaviour as in the match operator.

Closes: #6407

* Do not filter titles if suffix/removesuffix operand is empty

Issue: #6407
This commit is contained in:
Ben Webber 2022-02-22 16:38:40 +00:00 committed by GitHub
parent 49de500b5e
commit 95bd694a65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 205 additions and 54 deletions

View File

@ -16,19 +16,37 @@ Filter operator for checking if a title starts with a prefix
Export our filter function Export our filter function
*/ */
exports.prefix = function(source,operator,options) { exports.prefix = function(source,operator,options) {
var results = []; var results = [],
if(operator.prefix === "!") { suffixes = (operator.suffixes || [])[0] || [];
source(function(tiddler,title) { if(suffixes.indexOf("caseinsensitive") !== -1) {
if(title.substr(0,operator.operand.length) !== operator.operand) { var operand = operator.operand.toLowerCase();
results.push(title); if(operator.prefix === "!") {
} source(function(tiddler,title) {
}); if(title.toLowerCase().substr(0,operand.length) !== operand) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(title.toLowerCase().substr(0,operand.length) === operand) {
results.push(title);
}
});
}
} else { } else {
source(function(tiddler,title) { if(operator.prefix === "!") {
if(title.substr(0,operator.operand.length) === operator.operand) { source(function(tiddler,title) {
results.push(title); if(title.substr(0,operator.operand.length) !== operator.operand) {
} results.push(title);
}); }
});
} else {
source(function(tiddler,title) {
if(title.substr(0,operator.operand.length) === operator.operand) {
results.push(title);
}
});
}
} }
return results; return results;
}; };

View File

@ -16,12 +16,22 @@ Filter operator for removing a prefix from each title in the list. Titles that d
Export our filter function Export our filter function
*/ */
exports.removeprefix = function(source,operator,options) { exports.removeprefix = function(source,operator,options) {
var results = []; var results = [],
source(function(tiddler,title) { suffixes = (operator.suffixes || [])[0] || [];
if(title.substr(0,operator.operand.length) === operator.operand) { if(suffixes.indexOf("caseinsensitive") !== -1) {
results.push(title.substr(operator.operand.length)); var operand = operator.operand.toLowerCase();
} source(function(tiddler,title) {
}); if(title.toLowerCase().substr(0,operand.length) === operand) {
results.push(title.substr(operand.length));
}
});
} else {
source(function(tiddler,title) {
if(title.substr(0,operator.operand.length) === operator.operand) {
results.push(title.substr(operator.operand.length));
}
});
}
return results; return results;
}; };

View File

@ -16,12 +16,26 @@ Filter operator for removing a suffix from each title in the list. Titles that d
Export our filter function Export our filter function
*/ */
exports.removesuffix = function(source,operator,options) { exports.removesuffix = function(source,operator,options) {
var results = []; var results = [],
source(function(tiddler,title) { suffixes = (operator.suffixes || [])[0] || [];
if(title && title.substr(-operator.operand.length) === operator.operand) { if (!operator.operand) {
results.push(title.substr(0,title.length - operator.operand.length)); source(function(tiddler,title) {
} results.push(title);
}); });
} else if(suffixes.indexOf("caseinsensitive") !== -1) {
var operand = operator.operand.toLowerCase();
source(function(tiddler,title) {
if(title && title.toLowerCase().substr(-operand.length) === operand) {
results.push(title.substr(0,title.length - operand.length));
}
});
} else {
source(function(tiddler,title) {
if(title && title.substr(-operator.operand.length) === operator.operand) {
results.push(title.substr(0,title.length - operator.operand.length));
}
});
}
return results; return results;
}; };

View File

@ -16,19 +16,41 @@ Filter operator for checking if a title ends with a suffix
Export our filter function Export our filter function
*/ */
exports.suffix = function(source,operator,options) { exports.suffix = function(source,operator,options) {
var results = []; var results = [],
if(operator.prefix === "!") { suffixes = (operator.suffixes || [])[0] || [];
if (!operator.operand) {
source(function(tiddler,title) { source(function(tiddler,title) {
if(title.substr(-operator.operand.length) !== operator.operand) { results.push(title);
results.push(title);
}
}); });
} else if(suffixes.indexOf("caseinsensitive") !== -1) {
var operand = operator.operand.toLowerCase();
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(title.toLowerCase().substr(-operand.length) !== operand) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(title.toLowerCase().substr(-operand.length) === operand) {
results.push(title);
}
});
}
} else { } else {
source(function(tiddler,title) { if(operator.prefix === "!") {
if(title.substr(-operator.operand.length) === operator.operand) { source(function(tiddler,title) {
results.push(title); if(title.substr(-operator.operand.length) !== operator.operand) {
} results.push(title);
}); }
});
} else {
source(function(tiddler,title) {
if(title.substr(-operator.operand.length) === operator.operand) {
results.push(title);
}
});
}
} }
return results; return results;
}; };

View File

@ -314,7 +314,32 @@ Tests the filtering mechanism.
it("should handle the prefix operator", function() { it("should handle the prefix operator", function() {
expect(wiki.filterTiddlers("[prefix[Tiddler]]").join(",")).toBe("Tiddler Three,TiddlerOne"); expect(wiki.filterTiddlers("[prefix[Tiddler]]").join(",")).toBe("Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[prefix:casesensitive[tiddler]]").join(",")).toBe("");
expect(wiki.filterTiddlers("[prefix:caseinsensitive[tiddler]]").join(",")).toBe("Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[prefix[nothing]]").join(",")).toBe(""); expect(wiki.filterTiddlers("[prefix[nothing]]").join(",")).toBe("");
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]prefix[]]").join(",")).toBe("ABCDE,abcde");
});
it("should handle the suffix operator", function() {
expect(wiki.filterTiddlers("[suffix[One]]").join(",")).toBe("TiddlerOne");
expect(wiki.filterTiddlers("[suffix:casesensitive[one]]").join(",")).toBe("one");
expect(wiki.filterTiddlers("[suffix:caseinsensitive[one]]").join(",")).toBe("one,TiddlerOne");
expect(wiki.filterTiddlers("[suffix[nothing]]").join(",")).toBe("");
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]suffix[]]").join(",")).toBe("ABCDE,abcde");
});
it("should handle the removeprefix operator", function() {
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removeprefix[ABC]]").join(",")).toBe("DE");
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removeprefix:casesensitive[ABC]]").join(",")).toBe("DE");
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removeprefix:caseinsensitive[abc]]").join(",")).toBe("DE,de");
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removeprefix[]]").join(",")).toBe("ABCDE,abcde");
});
it("should handle the removesuffix operator", function() {
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removesuffix[DE]]").join(",")).toBe("ABC");
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removesuffix:casesensitive[DE]]").join(",")).toBe("ABC");
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removesuffix:caseinsensitive[de]]").join(",")).toBe("ABC,abc")
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removesuffix[]]").join(",")).toBe("ABCDE,abcde");
}); });
it("should handle the sort and sortcs operators", function() { it("should handle the sort and sortcs operators", function() {

View File

@ -1,9 +1,10 @@
created: 20150123223129000 created: 20150123223129000
modified: 20150123223321000 modified: 20220218023400000
tags: [[prefix Operator]] [[Operator Examples]] tags: [[prefix Operator]] [[Operator Examples]]
title: prefix Operator (Examples) title: prefix Operator (Examples)
type: text/vnd.tiddlywiki type: text/vnd.tiddlywiki
<<.operator-example 1 "[tag[task]!prefix[Go]]">> <<.operator-example 1 "[tag[task]!prefix[Go]]">>
<<.operator-example 2 "[prefix[$:/languages/]]">> <<.operator-example 2 "[tag[task]!prefix:caseinsensitive[go]]">>
<<.operator-example 3 "[prefix[$:/]]" "same as `[is[system]]`">> <<.operator-example 3 "[prefix[$:/languages/]]">>
<<.operator-example 4 "[prefix[$:/]]" "same as `[is[system]]`">>

View File

@ -1,7 +1,8 @@
created: 20150118132851000 created: 20150118132851000
modified: 20150123210429000 modified: 20220218023400000
tags: [[removeprefix Operator]] [[Operator Examples]] tags: [[removeprefix Operator]] [[Operator Examples]]
title: removeprefix Operator (Examples) title: removeprefix Operator (Examples)
type: text/vnd.tiddlywiki type: text/vnd.tiddlywiki
<<.operator-example 1 "[[My Cat]] [[Your Garden]] [[My Favourite Armchair]] +[removeprefix[My ]]">> <<.operator-example 1 "[[My Cat]] [[Your Garden]] [[My Favourite Armchair]] +[removeprefix[My ]]">>
<<.operator-example 2 "[[My Cat]] [[Your Garden]] [[My Favourite Armchair]] +[removeprefix:caseinsensitive[my ]]">>

View File

@ -1,9 +1,8 @@
created: 20150118132851000 created: 20150118132851000
modified: 20150123211000000 modified: 20220218023400000
tags: [[removesuffix Operator]] [[Operator Examples]] tags: [[removesuffix Operator]] [[Operator Examples]]
title: removesuffix Operator (Examples) title: removesuffix Operator (Examples)
type: text/vnd.tiddlywiki type: text/vnd.tiddlywiki
<<.operator-example 1 "SIMPLEX Googolplex Complex +[removesuffix[plex]]">> <<.operator-example 1 "SIMPLEX Googolplex Complex +[removesuffix[plex]]">>
<<.operator-example 2 "SIMPLEX Googolplex Complex +[removesuffix:caseinsensitive[plex]]">>

View File

@ -1,8 +1,9 @@
created: 20150124113652000 created: 20150124113652000
modified: 20150124113925000 modified: 20220218023400000
tags: [[suffix Operator]] [[Operator Examples]] tags: [[suffix Operator]] [[Operator Examples]]
title: suffix Operator (Examples) title: suffix Operator (Examples)
type: text/vnd.tiddlywiki type: text/vnd.tiddlywiki
<<.operator-example 1 "[suffix[.jpg]]">> <<.operator-example 1 "[suffix[.jpg]]">>
<<.operator-example 2 "[tag[task]!suffix[ing]]">> <<.operator-example 2 "[suffix:caseinsensitive[.JPG]]">>
<<.operator-example 3 "[tag[task]!suffix[ing]]">>

View File

@ -1,5 +1,5 @@
created: 20140410103123179 created: 20140410103123179
modified: 20150203192735000 modified: 20220218023400000
tags: [[Filter Operators]] [[String Operators]] [[Negatable Operators]] tags: [[Filter Operators]] [[String Operators]] [[Negatable Operators]]
title: prefix Operator title: prefix Operator
type: text/vnd.tiddlywiki type: text/vnd.tiddlywiki
@ -10,7 +10,22 @@ op-parameter: a string of characters
op-parameter-name: S op-parameter-name: S
op-output: those input titles that start with <<.place S>> op-output: those input titles that start with <<.place S>>
op-neg-output: those input tiddlers that do <<.em not>> start with <<.place S>> op-neg-output: those input tiddlers that do <<.em not>> start with <<.place S>>
op-suffix: the <<.op prefix>> operator uses a rich suffix, see below for details
<<.s-matching-is-case-sensitive>> <<.from-version "5.2.2">>
The <<.op prefix>> operator uses an extended syntax that permits multiple flags to be passed:
```
[prefix:<flag list>[<operand>]]
```
* ''flag list'': a comma delimited list of flags
* ''operand'': filter operand
The available flags are:
* ''casesensitive'': (default), this flag forces a case-sensitive match, where upper and lower case letters are considered different
* ''caseinsensitive'': overrides the default so that upper and lower case letters are considered identical for matching purposes
<<.operator-examples "prefix">> <<.operator-examples "prefix">>

View File

@ -1,5 +1,5 @@
created: 20140410103123179 created: 20140410103123179
modified: 20150203190709000 modified: 20220218023400000
tags: [[Filter Operators]] [[String Operators]] tags: [[Filter Operators]] [[String Operators]]
title: removeprefix Operator title: removeprefix Operator
type: text/vnd.tiddlywiki type: text/vnd.tiddlywiki
@ -9,9 +9,24 @@ op-input: a [[selection of titles|Title Selection]]
op-parameter: a string of characters op-parameter: a string of characters
op-parameter-name: S op-parameter-name: S
op-output: those input titles that start with <<.place S>>, but with those characters discarded op-output: those input titles that start with <<.place S>>, but with those characters discarded
op-suffix: the <<.op removeprefix>> operator uses a rich suffix, see below for details
<<.s-matching-is-case-sensitive>>
<<.tip " This filters out input titles that do not start with S. For removing S without filtering out input titles that don't start with S, see [[trim|trim Operator]].">> <<.tip " This filters out input titles that do not start with S. For removing S without filtering out input titles that don't start with S, see [[trim|trim Operator]].">>
<<.from-version "5.2.2">>
The <<.op removeprefix>> operator uses an extended syntax that permits multiple flags to be passed:
```
[removeprefix:<flag list>[<operand>]]
```
* ''flag list'': a comma delimited list of flags
* ''operand'': filter operand
The available flags are:
* ''casesensitive'': (default), this flag forces a case-sensitive match, where upper and lower case letters are considered different
* ''caseinsensitive'': overrides the default so that upper and lower case letters are considered identical for matching purposes
<<.operator-examples "removeprefix">> <<.operator-examples "removeprefix">>

View File

@ -1,5 +1,5 @@
created: 20140828133830424 created: 20140828133830424
modified: 20150203190744000 modified: 20220218023400000
tags: [[Filter Operators]] [[String Operators]] tags: [[Filter Operators]] [[String Operators]]
title: removesuffix Operator title: removesuffix Operator
type: text/vnd.tiddlywiki type: text/vnd.tiddlywiki
@ -9,9 +9,24 @@ op-input: a [[selection of titles|Title Selection]]
op-parameter: a string of characters op-parameter: a string of characters
op-parameter-name: S op-parameter-name: S
op-output: those input titles that end with <<.place S>>, but with those characters discarded op-output: those input titles that end with <<.place S>>, but with those characters discarded
op-suffix: the <<.op removesuffix>> operator uses a rich suffix, see below for details
<<.s-matching-is-case-sensitive>>
<<.tip " This filters out input titles that do not end with S. For removing S without filtering out input titles that don't end with S, see [[trim|trim Operator]].">> <<.tip " This filters out input titles that do not end with S. For removing S without filtering out input titles that don't end with S, see [[trim|trim Operator]].">>
<<.from-version "5.2.2">>
The <<.op removesuffix>> operator uses an extended syntax that permits multiple flags to be passed:
```
[removesuffix:<flag list>[<operand>]]
```
* ''flag list'': a comma delimited list of flags
* ''operand'': filter operand
The available flags are:
* ''casesensitive'': (default), this flag forces a case-sensitive match, where upper and lower case letters are considered different
* ''caseinsensitive'': overrides the default so that upper and lower case letters are considered identical for matching purposes
<<.operator-examples "removesuffix">> <<.operator-examples "removesuffix">>

View File

@ -1,5 +1,5 @@
created: 20140828133830424 created: 20140828133830424
modified: 20150203192738000 modified: 20220218023400000
tags: [[Filter Operators]] [[String Operators]] [[Negatable Operators]] tags: [[Filter Operators]] [[String Operators]] [[Negatable Operators]]
title: suffix Operator title: suffix Operator
type: text/vnd.tiddlywiki type: text/vnd.tiddlywiki
@ -10,7 +10,22 @@ op-parameter: a string of characters
op-parameter-name: S op-parameter-name: S
op-output: those input titles that end with <<.place S>> op-output: those input titles that end with <<.place S>>
op-neg-output: those input tiddlers that do <<.em not>> end with <<.place S>> op-neg-output: those input tiddlers that do <<.em not>> end with <<.place S>>
op-suffix: the <<.op suffix>> operator uses a rich suffix, see below for details
<<.s-matching-is-case-sensitive>> <<.from-version "5.2.2">>
The <<.op suffix>> operator uses an extended syntax that permits multiple flags to be passed:
```
[suffix:<flag list>[<operand>]]
```
* ''flag list'': a comma delimited list of flags
* ''operand'': filter operand
The available flags are:
* ''casesensitive'': (default), this flag forces a case-sensitive match, where upper and lower case letters are considered different
* ''caseinsensitive'': overrides the default so that upper and lower case letters are considered identical for matching purposes
<<.operator-examples "suffix">> <<.operator-examples "suffix">>