1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-11-27 03:57:21 +00:00

implemented the new regexp syntax

This commit is contained in:
Stephan Hradek 2014-01-14 22:08:05 +01:00
parent 81de74342d
commit 14ca91a949
2 changed files with 50 additions and 37 deletions

View File

@ -32,55 +32,57 @@ function parseFilterOperation(operators,filterString,p) {
if(filterString.charAt(p) === "!") {
operator.prefix = filterString.charAt(p++);
}
// Get the operator name
bracketPos = filterString.indexOf("[",p);
curlyBracketPos = filterString.indexOf("{",p);
if((bracketPos === -1) && (curlyBracketPos === -1)) {
var nextBracketPos = filterString.substring(p).search(/[\[\{\/]/);
if(nextBracketPos === -1) {
throw "Missing [ in filter expression";
}
if(bracketPos === -1 || (curlyBracketPos !== -1 && curlyBracketPos < bracketPos)) {
// Curly brackets
operator.indirect = true;
operator.operator = filterString.substring(p,curlyBracketPos);
p = curlyBracketPos + 1;
} else {
// Square brackets
operator.operator = filterString.substring(p,bracketPos);
p = bracketPos + 1;
}
nextBracketPos += p;
var bracket = filterString.charAt(nextBracketPos);
operator.operator = filterString.substring(p,nextBracketPos);
// Any suffix?
var colon = operator.operator.indexOf(':');
if(colon > -1) {
operator.field = operator.operator.substring(colon+1);
operator.operator = operator.operator.substring(0,colon);
operator.operator = operator.operator.substring(0,colon) || "field";
}
if(operator.operator === "") {
// Empty operator means: title
else if(operator.operator === "") {
operator.operator = "title";
}
var rexMatch;
// regexp?
if(!operator.indirect && filterString.charAt(p) === "/") {
var rex = /^\/((?:[^\\\/]*|\\.))*\/([igm]*)\]/g;
rexMatch = rex.exec(filterString.substring(p));
p = nextBracketPos + 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) {
try {
operator.regexp = new RegExp(rexMatch[1], rexMatch[2]);
}
catch(e) {
// an error in the regexp -> Will do string matching
}
operator.operand = filterString.substr(p,rex.lastIndex-1);
p += rex.lastIndex;
operator.regexp = new RegExp(rexMatch[1], rexMatch[2]);
nextBracketPos = p + rex.lastIndex - 1;
}
}
// Get the operand
if(!rexMatch) {
bracketPos = filterString.indexOf(operator.indirect ? "}" : "]",p);
if(bracketPos === -1) {
throw "Missing closing bracket in filter expression";
else {
throw "Unterminated regular expression in filter expression";
}
operator.operand = filterString.substring(p,bracketPos);
p = bracketPos + 1;
break;
}
if(nextBracketPos === -1) {
throw "Missing closing bracket in filter expression";
}
if(!operator.regexp) {
operator.operand = filterString.substring(p,nextBracketPos);
}
p = nextBracketPos + 1;
// Push this operator
operators.push(operator);
} while(filterString.charAt(p) !== "]");

View File

@ -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
* ''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
* ''{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
* ''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
@ -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''.
! 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
Operators are combined into runs that function as logically ANDed expressions by bashing them together and merging the square brackets: