mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-01-11 18:00:26 +00:00
Merge branch 'regexp_filter' of https://github.com/Skeeve/TiddlyWiki5 into Skeeve-regexp_filter
This commit is contained in:
commit
edc71cb920
@ -32,32 +32,57 @@ function parseFilterOperation(operators,filterString,p) {
|
|||||||
if(filterString.charAt(p) === "!") {
|
if(filterString.charAt(p) === "!") {
|
||||||
operator.prefix = filterString.charAt(p++);
|
operator.prefix = filterString.charAt(p++);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the operator name
|
// Get the operator name
|
||||||
bracketPos = filterString.indexOf("[",p);
|
var nextBracketPos = filterString.substring(p).search(/[\[\{\/]/);
|
||||||
curlyBracketPos = filterString.indexOf("{",p);
|
if(nextBracketPos === -1) {
|
||||||
if((bracketPos === -1) && (curlyBracketPos === -1)) {
|
|
||||||
throw "Missing [ in filter expression";
|
throw "Missing [ in filter expression";
|
||||||
}
|
}
|
||||||
if(bracketPos === -1 || (curlyBracketPos !== -1 && curlyBracketPos < bracketPos)) {
|
nextBracketPos += p;
|
||||||
// Curly brackets
|
var bracket = filterString.charAt(nextBracketPos);
|
||||||
operator.indirect = true;
|
operator.operator = filterString.substring(p,nextBracketPos);
|
||||||
operator.operator = filterString.substring(p,curlyBracketPos);
|
|
||||||
p = curlyBracketPos + 1;
|
// Any suffix?
|
||||||
} else {
|
var colon = operator.operator.indexOf(':');
|
||||||
// Square brackets
|
if(colon > -1) {
|
||||||
operator.operator = filterString.substring(p,bracketPos);
|
operator.field = operator.operator.substring(colon+1);
|
||||||
p = bracketPos + 1;
|
operator.operator = operator.operator.substring(0,colon) || "field";
|
||||||
}
|
}
|
||||||
if(operator.operator === "") {
|
// Empty operator means: title
|
||||||
|
else if(operator.operator === "") {
|
||||||
operator.operator = "title";
|
operator.operator = "title";
|
||||||
}
|
}
|
||||||
// Get the operand
|
|
||||||
bracketPos = filterString.indexOf(operator.indirect ? "}" : "]",p);
|
p = nextBracketPos + 1;
|
||||||
if(bracketPos === -1) {
|
switch (bracket) {
|
||||||
|
case '{': // Curly brackets
|
||||||
|
operator.indirect = true;
|
||||||
|
nextBracketPos = filterString.indexOf('}',p);
|
||||||
|
break;
|
||||||
|
case '[': // Square brackets
|
||||||
|
nextBracketPos = filterString.indexOf(']',p);
|
||||||
|
break;
|
||||||
|
case '/': // regexp brackets
|
||||||
|
var rex = /^((?:[^\\\/]*|\\.))*\/(?:\(([mygi]+)\))?/g,
|
||||||
|
rexMatch = rex.exec(filterString.substring(p));
|
||||||
|
if(rexMatch) {
|
||||||
|
operator.regexp = new RegExp(rexMatch[1], rexMatch[2]);
|
||||||
|
nextBracketPos = p + rex.lastIndex - 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw "Unterminated regular expression in filter expression";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nextBracketPos === -1) {
|
||||||
throw "Missing closing bracket in filter expression";
|
throw "Missing closing bracket in filter expression";
|
||||||
}
|
}
|
||||||
operator.operand = filterString.substring(p,bracketPos);
|
if(!operator.regexp) {
|
||||||
p = bracketPos + 1;
|
operator.operand = filterString.substring(p,nextBracketPos);
|
||||||
|
}
|
||||||
|
p = nextBracketPos + 1;
|
||||||
|
|
||||||
// Push this operator
|
// Push this operator
|
||||||
operators.push(operator);
|
operators.push(operator);
|
||||||
} while(filterString.charAt(p) !== "]");
|
} while(filterString.charAt(p) !== "]");
|
||||||
@ -161,7 +186,9 @@ exports.compileFilter = function(filterString) {
|
|||||||
results = operatorFunction(accumulator,{
|
results = operatorFunction(accumulator,{
|
||||||
operator: operator.operator,
|
operator: operator.operator,
|
||||||
operand: operand,
|
operand: operand,
|
||||||
prefix: operator.prefix
|
prefix: operator.prefix,
|
||||||
|
field: operator.field,
|
||||||
|
regexp: operator.regexp
|
||||||
},{
|
},{
|
||||||
wiki: self,
|
wiki: self,
|
||||||
currTiddlerTitle: currTiddlerTitle
|
currTiddlerTitle: currTiddlerTitle
|
||||||
|
@ -21,7 +21,14 @@ exports.field = function(source,operator,options) {
|
|||||||
function checkTiddler(title) {
|
function checkTiddler(title) {
|
||||||
var tiddler = options.wiki.getTiddler(title);
|
var tiddler = options.wiki.getTiddler(title);
|
||||||
if(tiddler) {
|
if(tiddler) {
|
||||||
var match = tiddler.getFieldString(operator.operator) === operator.operand;
|
var match,
|
||||||
|
text = tiddler.getFieldString(operator.field);
|
||||||
|
if(operator.regexp) {
|
||||||
|
match = !! operator.regexp.exec(text);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
match = text === operator.operand;
|
||||||
|
}
|
||||||
if(operator.prefix === "!") {
|
if(operator.prefix === "!") {
|
||||||
match = !match;
|
match = !match;
|
||||||
}
|
}
|
||||||
@ -31,6 +38,10 @@ exports.field = function(source,operator,options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Iterate through the source tiddlers
|
// Iterate through the source tiddlers
|
||||||
|
if(!operator.field) {
|
||||||
|
operator.field = operator.operator;
|
||||||
|
}
|
||||||
|
operator.field.toLowerCase();
|
||||||
if($tw.utils.isArray(source)) {
|
if($tw.utils.isArray(source)) {
|
||||||
$tw.utils.each(source,function(title) {
|
$tw.utils.each(source,function(title) {
|
||||||
checkTiddler(title);
|
checkTiddler(title);
|
||||||
|
@ -44,7 +44,8 @@ A filter string consists of one or more runs of filter operators that each look
|
|||||||
* ''prefix'': tests whether a tiddlers title starts with the prefix specified in the operand
|
* ''prefix'': tests whether a tiddlers title starts with the prefix specified in the operand
|
||||||
* ''limit'': limits the number of subresults to the integer specified in the operand
|
* ''limit'': limits the number of subresults to the integer specified in the operand
|
||||||
* ''tag'': tests whether a given tag is (`[tag[mytag]]`) or is not (`[!tag[mytag]]`) present on the tiddler
|
* ''tag'': tests whether a given tag is (`[tag[mytag]]`) or is not (`[!tag[mytag]]`) present on the tiddler
|
||||||
* ''{field}'': tests whether a tiddler field has a specified value (`[modifier[Jeremy]]`) or not (`[!modifier[Jeremy]]`)
|
* ''field:{field}'': or
|
||||||
|
* ''{field}'': tests whether a tiddler field has a specified value (`[modifier[Jeremy]]` or `[field:modifier[Jeremy]]`) or not (`[!modifier[Jeremy]]`)
|
||||||
* ''tags'': selects the tags on the currently selected tiddlers
|
* ''tags'': selects the tags on the currently selected tiddlers
|
||||||
* ''tagging'': selects the tiddlers tagged with the currently selected tiddlers
|
* ''tagging'': selects the tiddlers tagged with the currently selected tiddlers
|
||||||
* ''untagged'': selects the any of the selected tiddlers that do not have at least one tag
|
* ''untagged'': selects the any of the selected tiddlers that do not have at least one tag
|
||||||
@ -79,6 +80,16 @@ If a filter operator is written with curly brackets around the operand then it i
|
|||||||
|
|
||||||
''[search{$:/temp/search}]'': selects all tiddlers containing the string contained in the tiddler titled ''$:/temp/search''.
|
''[search{$:/temp/search}]'': selects all tiddlers containing the string contained in the tiddler titled ''$:/temp/search''.
|
||||||
|
|
||||||
|
! Regular Expression Filters
|
||||||
|
|
||||||
|
The field-filter also accepts regular expressions in the form `/regexp/(modifier)`. Please refer to you favourite JavaScript documentation to learn more about regular expressions and modifiers.
|
||||||
|
|
||||||
|
In the easiest form, regular expressions allow you do do a search on substrings for every field:
|
||||||
|
|
||||||
|
* `field:title/example/`: searches for all tiddlers having "example" in its title.
|
||||||
|
* `field:title:/example$/`: `$` is an "anchor" for the end of the text. So "example" has to be the end of the title.
|
||||||
|
* `field:text/jeremy|ruston/(i)`: Searches for tiddlers containing Jeremy's first or last name, ignoring the case.
|
||||||
|
|
||||||
! Runs
|
! Runs
|
||||||
|
|
||||||
Operators are combined into runs that function as logically ANDed expressions by bashing them together and merging the square brackets:
|
Operators are combined into runs that function as logically ANDed expressions by bashing them together and merging the square brackets:
|
||||||
|
Loading…
Reference in New Issue
Block a user