1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-06-23 13:53:15 +00:00

Add support for variable filter operands

Fixes #583
This commit is contained in:
Jermolene 2014-07-25 15:26:44 +01:00
parent d6cafa9da1
commit be040ea8a2
4 changed files with 58 additions and 22 deletions

View File

@ -33,7 +33,7 @@ function parseFilterOperation(operators,filterString,p) {
operator.prefix = filterString.charAt(p++);
}
// Get the operator name
var nextBracketPos = filterString.substring(p).search(/[\[\{\/]/);
var nextBracketPos = filterString.substring(p).search(/[\[\{<\/]/);
if(nextBracketPos === -1) {
throw "Missing [ in filter expression";
}
@ -54,24 +54,28 @@ function parseFilterOperation(operators,filterString,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) {
operator.regexp = new RegExp(rexMatch[1], rexMatch[2]);
nextBracketPos = p + rex.lastIndex - 1;
}
else {
throw "Unterminated regular expression in filter expression";
}
break;
case "{": // Curly brackets
operator.indirect = true;
nextBracketPos = filterString.indexOf("}",p);
break;
case "[": // Square brackets
nextBracketPos = filterString.indexOf("]",p);
break;
case "<": // Angle brackets
operator.variable = true;
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) {
@ -193,6 +197,9 @@ exports.compileFilter = function(filterString) {
if(operator.indirect) {
operand = self.getTextReference(operator.operand,"",currTiddlerTitle);
}
if(operator.variable) {
operand = widget.getVariable(operator.operand,"");
}
results = operatorFunction(accumulator,{
operator: operator.operator,
operand: operand,

View File

@ -270,6 +270,25 @@ describe("Filter tests", function() {
expect(wiki.filterTiddlers("[modifier{!!modifier}] +[sort[title]]",fakeWidget).join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,one,Tiddler Three");
});
it("should handle variable operands", function() {
var widget = require("$:/core/modules/widgets/widget.js");
// Create a root widget for attaching event handlers. By using it as the parentWidget for another widget tree, one can reuse the event handlers
var rootWidget = new widget.widget({
type: "widget",
children: [{type: "widget", children: []}]
},{
wiki: $tw.wiki,
document: $tw.document
});
rootWidget.makeChildWidgets();
var anchorWidget = rootWidget.children[0];
rootWidget.setVariable("myVar","Tidd");
rootWidget.setVariable("myVar2","JoeBloggs");
expect(wiki.filterTiddlers("[prefix<myVar>] +[sort[title]]",anchorWidget).join(",")).toBe("Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[modifier<myVar2>] +[sort[title]]",anchorWidget).join(",")).toBe("TiddlerOne");
});
it("should handle the before and after operators", function() {
expect(wiki.filterTiddlers("[list[TiddlerSeventh]after[TiddlerOne]]").join(",")).toBe("Tiddler Three");
expect(wiki.filterTiddlers("[list[TiddlerSeventh]after[a fourth tiddler]]").join(",")).toBe("MissingTiddler");

View File

@ -1,5 +1,5 @@
created: 20140210141217955
modified: 20140303091312363
modified: 20140725091312363
tags: dev
title: TiddlerFilter Formal Grammar
type: text/vnd.tiddlywiki
@ -34,7 +34,7 @@ Whitespace is matched with javascript "\s+", which matches space, tab, carriage
''&lt;opt-operator-suffix&gt;'' ::= ''&lt;string&gt;'' | ""
''&lt;operand&gt;'' ::= "[" ''&lt;search-string&gt;'' "]" | "{" ''&lt;indirect-search-string&gt;'' "}" | ''&lt;regex&gt;''
''&lt;operand&gt;'' ::= "[" ''&lt;search-string&gt;'' "]" | "{" ''&lt;indirect-search-string&gt;'' "}" | "<" ''&lt;variable-name-string&gt;'' ">" | ''&lt;regex&gt;''
''&lt;regex&gt;'' ::= "/" ''&lt;string&gt;'' "/" ''&lt;opt-regex-args&gt;''

View File

@ -1,5 +1,5 @@
created: 20140410101941871
modified: 20140410103229640
modified: 20140725103229640
tags: introduction
title: Introduction to Filters
type: text/vnd.tiddlywiki
@ -67,6 +67,16 @@ If a filter operator is written with curly brackets around the operand then it i
[search{$:/temp/search}]
```
! Variable Operands
If a filter operator is written with angle brackets around the operand then it is taken to be the name of a variable containing the actual value. For example, this filter selects all tiddlers containing the title of the current tiddler:
```
[search<currentTiddler>]
```
(Note that the `currentTiddler` variable is used to track the current tiddler).
! Regular Expression Operands
The "field" filter also accepts [[regular expressions|http://en.wikipedia.org/wiki/Regular_expression]] with the syntax `/regexp/(modifier)`. For example: