Merge branch 'regexp_filter' of https://github.com/Skeeve/TiddlyWiki5 into Skeeve-regexp_filter

print-window-tiddler
Jermolene 2014-01-24 18:40:27 +00:00
commit edc71cb920
3 zmienionych plików z 70 dodań i 21 usunięć

Wyświetl plik

@ -32,32 +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) || "field";
}
if(operator.operator === "") {
// Empty operator means: title
else if(operator.operator === "") {
operator.operator = "title";
}
// Get the operand
bracketPos = filterString.indexOf(operator.indirect ? "}" : "]",p);
if(bracketPos === -1) {
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) {
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";
}
operator.operand = filterString.substring(p,bracketPos);
p = bracketPos + 1;
if(!operator.regexp) {
operator.operand = filterString.substring(p,nextBracketPos);
}
p = nextBracketPos + 1;
// Push this operator
operators.push(operator);
} while(filterString.charAt(p) !== "]");
@ -161,7 +186,9 @@ exports.compileFilter = function(filterString) {
results = operatorFunction(accumulator,{
operator: operator.operator,
operand: operand,
prefix: operator.prefix
prefix: operator.prefix,
field: operator.field,
regexp: operator.regexp
},{
wiki: self,
currTiddlerTitle: currTiddlerTitle

Wyświetl plik

@ -21,7 +21,14 @@ exports.field = function(source,operator,options) {
function checkTiddler(title) {
var tiddler = options.wiki.getTiddler(title);
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 === "!") {
match = !match;
}
@ -31,6 +38,10 @@ exports.field = function(source,operator,options) {
}
}
// Iterate through the source tiddlers
if(!operator.field) {
operator.field = operator.operator;
}
operator.field.toLowerCase();
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);

Wyświetl plik

@ -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: