mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-09-29 07:20:47 +00:00
Refactor the filter mechanism
Long overdue rewrite to make it simpler, and break the filter operators out into individual modules.
This commit is contained in:
parent
6ada78daa2
commit
0cf5dc699e
@ -12,274 +12,6 @@ Adds tiddler filtering to the $tw.Wiki object.
|
|||||||
/*global $tw: false */
|
/*global $tw: false */
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
exports.filterTiddlers = function(filterString,currTiddlerTitle,tiddlerList) {
|
|
||||||
var fn = this.compileFilter(filterString);
|
|
||||||
return fn.call(this,tiddlerList || this.tiddlers,currTiddlerTitle);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Compiling a filter gives a JavaScript function that is invoked as `this.filter(source)`, where `source` is a hashmap of source tiddler titles (the values don't matter, so it is possible to use a store or a changes object). It returns an array of tiddler titles that satisfy the filter
|
|
||||||
*/
|
|
||||||
exports.compileFilter = function(filterString) {
|
|
||||||
var filter = this.parseFilter(filterString),
|
|
||||||
output = [],
|
|
||||||
t,operation,operationInfo,type,p,operator,operatorInfo,fn;
|
|
||||||
output.push(this.filterFragments.prologue);
|
|
||||||
for(t=0; t<filter.length; t++) {
|
|
||||||
operation = filter[t];
|
|
||||||
operationInfo = this.filterFragments.operation.prefix[operation.prefix || ""];
|
|
||||||
output.push(operationInfo.prologue);
|
|
||||||
type = "selector";
|
|
||||||
if(operation.prefix === "+") {
|
|
||||||
type = "filter";
|
|
||||||
}
|
|
||||||
for(p=0; p<operation.operators.length; p++) {
|
|
||||||
operator = operation.operators[p];
|
|
||||||
operatorInfo = this.operators[operator.operator];
|
|
||||||
if(!operatorInfo) { // Check for it being a field operator
|
|
||||||
operatorInfo = this.operators.field;
|
|
||||||
}
|
|
||||||
output.push(operatorInfo[type](operator));
|
|
||||||
type = "filter";
|
|
||||||
}
|
|
||||||
output.push(operationInfo.epilogue);
|
|
||||||
}
|
|
||||||
output.push(this.filterFragments.epilogue);
|
|
||||||
try {
|
|
||||||
/*jslint evil: true */
|
|
||||||
fn = eval(output.join("\n"));
|
|
||||||
} catch(ex) {
|
|
||||||
throw "Error in filter expression: " + ex;
|
|
||||||
}
|
|
||||||
return fn;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.filterFragments = {
|
|
||||||
prologue: "(function(source,currTiddlerTitle) {\nvar results = [], subResults, subResultsTemp, title, r, t;",
|
|
||||||
epilogue: "return results;\n})",
|
|
||||||
operation: {
|
|
||||||
prefix: {
|
|
||||||
"": {
|
|
||||||
prologue: "subResults = [];",
|
|
||||||
epilogue: "$tw.utils.pushTop(results,subResults);"
|
|
||||||
},
|
|
||||||
"+": {
|
|
||||||
prologue: "subResults = results.slice(0);\nresults.splice(0,results.length);",
|
|
||||||
epilogue: "$tw.utils.pushTop(results,subResults);"
|
|
||||||
},
|
|
||||||
"-": {
|
|
||||||
prologue: "subResults = [];",
|
|
||||||
epilogue: "$tw.utils.removeArrayEntries(results,subResults);"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.operators = {
|
|
||||||
"title": { // Filter by title
|
|
||||||
selector: function(operator) {
|
|
||||||
if(operator.prefix === "!") {
|
|
||||||
return "for(title in source) {if(title !== \"" + $tw.utils.stringify(operator.operand) + "\") {$tw.utils.pushTop(subResults,title);}}";
|
|
||||||
} else {
|
|
||||||
return "$tw.utils.pushTop(subResults,\"" + $tw.utils.stringify(operator.operand) + "\");";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
filter: function(operator) {
|
|
||||||
var op = operator.prefix === "!" ? "!" : "=";
|
|
||||||
return "if(subResults.indexOf(\"" + $tw.utils.stringify(operator.operand) + "\") " + op + "== -1) {subResults = [\"" + $tw.utils.stringify(operator.operand) + "\"];} else {subResults = [];}";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"prefix": { // Filter by title prefix
|
|
||||||
selector: function(operator) {
|
|
||||||
var op = operator.prefix === "!" ? "!" : "=";
|
|
||||||
return "for(title in source) {if(title.substr(0," + operator.operand.length + ")" + op + "==\"" + $tw.utils.stringify(operator.operand) + "\") {$tw.utils.pushTop(subResults,title);}}";
|
|
||||||
},
|
|
||||||
filter: function(operator) {
|
|
||||||
var op = operator.prefix === "!" ? "=" : "!";
|
|
||||||
return "for(r=subResults.length-1; r>=0; r--) {if(title.substr(0," + operator.operand.length + ")" + op + "==\"" + $tw.utils.stringify(operator.operand) + "\") {subResults.splice(r,1);}}";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"is": { // Filter by status
|
|
||||||
selector: function(operator) {
|
|
||||||
var op = operator.prefix === "!" ? "!" : "";
|
|
||||||
switch(operator.operand) {
|
|
||||||
case "current":
|
|
||||||
if(operator.prefix === "!") {
|
|
||||||
return "for(title in source) {if(title !== currTiddlerTitle) {$tw.utils.pushTop(subResults,title);}}";
|
|
||||||
} else {
|
|
||||||
return "$tw.utils.pushTop(subResults,currTiddlerTitle);";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "system":
|
|
||||||
return "for(title in source) {if(" + op + "this.isSystemTiddler(title)) {$tw.utils.pushTop(subResults,title);}}";
|
|
||||||
case "shadow":
|
|
||||||
if(operator.prefix === "!") {
|
|
||||||
return "for(title in source) {if(!this.isShadowTiddler(title)) {$tw.utils.pushTop(subResults,title);}}";
|
|
||||||
} else {
|
|
||||||
return "for(title in this.shadowTiddlers) {$tw.utils.pushTop(subResults,title);}";
|
|
||||||
}
|
|
||||||
case "missing":
|
|
||||||
if(operator.prefix === "!") {
|
|
||||||
return "for(title in source) {$tw.utils.pushTop(subResults,title);}";
|
|
||||||
} else {
|
|
||||||
return "var m = this.getMissingTitles(); for(t=0; t<m.length; t++) {$tw.utils.pushTop(subResults,m[t]);}";
|
|
||||||
}
|
|
||||||
case "orphan":
|
|
||||||
if(operator.prefix === "!") {
|
|
||||||
return "var m = this.getOrphanTitles(); for(title in source) {if(m.indexOf(title) === -1) {$tw.utils.pushTop(subResults,title);}}";
|
|
||||||
} else {
|
|
||||||
return "var m = this.getOrphanTitles(); for(t=0; t<m.length; t++) {$tw.utils.pushTop(subResults,m[t]);}";
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw "Unknown operand for 'is' filter operator";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
filter: function(operator) {
|
|
||||||
var op = operator.prefix === "!" ? "" : "!";
|
|
||||||
switch(operator.operand) {
|
|
||||||
case "current":
|
|
||||||
if(operator.prefix === "!") {
|
|
||||||
return "for(r=subResults.length-1; r>=0; r--) {if(subResults[r] === currTiddlerTitle) {subResults.splice(r,1);}}";
|
|
||||||
} else {
|
|
||||||
return "r = subResults.indexOf(currTiddlerTitle);\nif(r !== -1) {subResults = [currTiddlerTitle];} else {subResults = [];}";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "system":
|
|
||||||
return "for(r=subResults.length-1; r>=0; r--) {if(" + op + "this.isSystemTiddler(subResults[r])) {subResults.splice(r,1);}}";
|
|
||||||
case "shadow":
|
|
||||||
return "for(r=subResults.length-1; r>=0; r--) {if(" + op + "this.isShadowTiddler(subResults[r])) {subResults.splice(r,1);}}";
|
|
||||||
case "missing":
|
|
||||||
return "t = this.getMissingTitles(); for(r=subResults.length-1; r>=0; r--) {if(" + op + "!$tw.utils.hop(t,subResults[r])) {subResults.splice(r,1);}}";
|
|
||||||
case "orphan":
|
|
||||||
if(operator.prefix === "!") {
|
|
||||||
return "t = this.getOrphanTitles(); for(r=subResults.length-1; r>=0; r--) {if(t.indexOf(subResults[r]) === -1) {subResults.splice(r,1);}}";
|
|
||||||
} else {
|
|
||||||
return "t = this.getOrphanTitles(); for(r=subResults.length-1; r>=0; r--) {if(t.indexOf(subResults[r]) !== -1) {subResults.splice(r,1);}}";
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw "Unknown operand for 'is' filter operator";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tag": { // Filter by tag
|
|
||||||
selector: function(operator) {
|
|
||||||
var op = operator.prefix === "!" ? "!" : "";
|
|
||||||
return "for(title in source) {if(" + op + "this.getTiddler(title).hasTag(\"" + $tw.utils.stringify(operator.operand) + "\")) {$tw.utils.pushTop(subResults,title);}}";
|
|
||||||
},
|
|
||||||
filter: function(operator) {
|
|
||||||
var op = operator.prefix === "!" ? "" : "!";
|
|
||||||
return "for(r=subResults.length-1; r>=0; r--) {if(" + op + "this.getTiddler(subResults[r]).hasTag(\"" + $tw.utils.stringify(operator.operand) + "\")) {subResults.splice(r,1);}}";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tags": { // Return all tags used on selected tiddlers
|
|
||||||
selector: function(operator) {
|
|
||||||
return "for(title in source) {r = this.getTiddler(title); if(r && r.fields.tags) {$tw.utils.pushTop(subResults,r.fields.tags);}}";
|
|
||||||
},
|
|
||||||
filter: function(operator) {
|
|
||||||
return "subResultsTemp = subResults;\nsubResults = [];for(t=subResultsTemp.length-1; t>=0; t--) {r = this.getTiddler(subResultsTemp[t]); if(r && r.fields.tags) {$tw.utils.pushTop(subResults,r.fields.tags);}}";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tagging": { // Return all tiddlers tagged with any of the selected tags
|
|
||||||
selector: function(operator) {
|
|
||||||
return "for(title in source) {$tw.utils.pushTop(subResults,this.getTiddlersWithTag(title));}";
|
|
||||||
},
|
|
||||||
filter: function(operator) {
|
|
||||||
return "subResultsTemp = subResults;\nsubResults = [];for(t=subResultsTemp.length-1; t>=0; t--) {$tw.utils.pushTop(subResults,this.getTiddlersWithTag(subResultsTemp[t]));}";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"links": { // Return outgoing links on selected tiddlers
|
|
||||||
selector: function(operator) {
|
|
||||||
return "for(title in source) {r = this.getTiddlerLinks(title); $tw.utils.pushTop(subResults,r);}";
|
|
||||||
},
|
|
||||||
filter: function(operator) {
|
|
||||||
return "subResultsTemp = subResults;\nsubResults = [];for(t=subResultsTemp.length-1; t>=0; t--) {r = this.getTiddlerLinks(subResultsTemp[t]); $tw.utils.pushTop(subResults,r);}";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"backlinks": { // Return incoming links on selected tiddlers
|
|
||||||
selector: function(operator) {
|
|
||||||
return "for(title in source) {r = this.getTiddlerBacklinks(title); $tw.utils.pushTop(subResults,r);}";
|
|
||||||
},
|
|
||||||
filter: function(operator) {
|
|
||||||
return "subResultsTemp = subResults;\nsubResults = [];for(t=subResultsTemp.length-1; t>=0; t--) {r = this.getTiddlerBacklinks(subResultsTemp[t]); $tw.utils.pushTop(subResults,r);}";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"has": { // Filter by presence of a particular field
|
|
||||||
selector: function(operator) {
|
|
||||||
var op = operator.prefix === "!" ? "=" : "!";
|
|
||||||
return "for(title in source) {if(this.getTiddler(title).fields[\"" + $tw.utils.stringify(operator.operand) + "\"] " + op + "== undefined) {$tw.utils.pushTop(subResults,title);}}";
|
|
||||||
},
|
|
||||||
filter: function(operator) {
|
|
||||||
var op = operator.prefix === "!" ? "!" : "=";
|
|
||||||
return "for(r=subResults.length-1; r>=0; r--) {if(this.getTiddler(subResults[r]).fields[\"" + $tw.utils.stringify(operator.operand) + "\"] " + op + "== undefined) {subResults.splice(r,1);}}";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sort": { // Sort selected tiddlers
|
|
||||||
selector: function(operator) {
|
|
||||||
throw "Cannot use sort operator at the start of a filter operation";
|
|
||||||
},
|
|
||||||
filter: function(operator) {
|
|
||||||
var desc = operator.prefix === "!" ? "true" : "false";
|
|
||||||
return "this.sortTiddlers(subResults,\"" + $tw.utils.stringify(operator.operand) + "\"," + desc + ");";
|
|
||||||
}
|
|
||||||
}, // Case insensitive sort of selected tiddlers
|
|
||||||
"sort-case-sensitive": {
|
|
||||||
selector: function(operator) {
|
|
||||||
throw "Cannot use sort operator at the start of a filter operation";
|
|
||||||
},
|
|
||||||
filter: function(operator) {
|
|
||||||
var desc = operator.prefix === "!" ? "true" : "false";
|
|
||||||
return "this.sortTiddlers(subResults,\"" + $tw.utils.stringify(operator.operand) + "\"," + desc + ",true);";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"limit": { // Limit number of members of selection
|
|
||||||
selector: function(operator) {
|
|
||||||
throw "Cannot use limit operator at the start of a filter operation";
|
|
||||||
},
|
|
||||||
filter: function(operator) {
|
|
||||||
var limit = parseInt(operator.operand,10),
|
|
||||||
base = operator.prefix === "!" ? 0 : limit;
|
|
||||||
return "if(subResults.length > " + limit + ") {subResults.splice(" + base + ",subResults.length-" + limit + ");}";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"list": { // Select all tiddlers that are listed (or not listed) in the specified tiddler
|
|
||||||
selector: function(operator) {
|
|
||||||
if(operator.prefix === "!") {
|
|
||||||
return "var list = this.getTiddlerList(\"" + $tw.utils.stringify(operator.operand) + "\");" +
|
|
||||||
"for(title in source) {if(list.indexOf(title) === -1) {$tw.utils.pushTop(subResults,title);}}";
|
|
||||||
} else {
|
|
||||||
return "$tw.utils.pushTop(subResults,this.getTiddlerList(\"" + $tw.utils.stringify(operator.operand) + "\"));";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
filter: function(operator) {
|
|
||||||
var op = operator.prefix === "!" ? "!==" : "===";
|
|
||||||
return "var list = this.getTiddlerList(\"" + $tw.utils.stringify(operator.operand) + "\");" +
|
|
||||||
"for(r=subResults.length-1; r>=0; r--) {if(list.indexOf(title) " + op + " -1) {subResults.splice(r,1);}}";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"searchVia": { // Search for the string in the operand tiddler
|
|
||||||
selector: function(operator) {
|
|
||||||
var op = operator.prefix === "!" ? "true" : "false";
|
|
||||||
return "var term = this.getTiddler(\"" + $tw.utils.stringify(operator.operand) + "\").fields.text;" +
|
|
||||||
"$tw.utils.pushTop(subResults,this.search(term,{titles: source, invert: " + op + ", exclude: [\"" + $tw.utils.stringify(operator.operand) + "\"]}));";
|
|
||||||
},
|
|
||||||
filter: function(operator) {
|
|
||||||
var op = operator.prefix === "!" ? "true" : "false";
|
|
||||||
return "var term = this.getTiddler(\"" + $tw.utils.stringify(operator.operand) + "\").fields.text;" +
|
|
||||||
"subResults = this.search(term,{titles: subResults, invert: " + op + ", exclude: [\"" + $tw.utils.stringify(operator.operand) + "\"]});";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"field": { // Special handler for field comparisons
|
|
||||||
selector: function(operator) {
|
|
||||||
var op = operator.prefix === "!" ? "!" : "=";
|
|
||||||
return "for(title in source) {if(this.getTiddler(title).fields[\"" + $tw.utils.stringify(operator.operator) + "\"] " + op + "== \"" + operator.operand + "\") {$tw.utils.pushTop(subResults,title);}}";
|
|
||||||
},
|
|
||||||
filter: function(operator) {
|
|
||||||
var op = operator.prefix === "!" ? "=" : "!";
|
|
||||||
return "for(r=subResults.length-1; r>=0; r--) {if(this.getTiddler(subResults[r]).fields[\"" + $tw.utils.stringify(operator.operator) + "\"] " + op + "== \"" + operator.operand + "\") {subResults.splice(r,1);}}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Parses an operation within a filter string
|
Parses an operation within a filter string
|
||||||
results: Array of array of operator nodes into which results should be inserted
|
results: Array of array of operator nodes into which results should be inserted
|
||||||
@ -376,4 +108,70 @@ exports.parseFilter = function(filterString) {
|
|||||||
return results;
|
return results;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.getFilterOperators = function() {
|
||||||
|
if(!this.filterOperators) {
|
||||||
|
$tw.Wiki.prototype.filterOperators = {};
|
||||||
|
$tw.modules.applyMethods("filteroperator",this.filterOperators);
|
||||||
|
}
|
||||||
|
return this.filterOperators;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.filterTiddlers = function(filterString,currTiddlerTitle,tiddlerList) {
|
||||||
|
var fn = this.compileFilter(filterString);
|
||||||
|
return fn.call(this,tiddlerList || this.tiddlers,currTiddlerTitle);
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.compileFilter = function(filterString) {
|
||||||
|
var filterParseTree = this.parseFilter(filterString);
|
||||||
|
// Get the hashmap of filter operator functions
|
||||||
|
var filterOperators = this.getFilterOperators();
|
||||||
|
// Assemble array of functions, one for each operation
|
||||||
|
var operationFunctions = [];
|
||||||
|
// Step through the operations
|
||||||
|
var self = this;
|
||||||
|
$tw.utils.each(filterParseTree,function(operation) {
|
||||||
|
// Create a function for the chain of operators in the operation
|
||||||
|
var operationSubFunction = function(source,currTiddlerTitle) {
|
||||||
|
var accumulator = source,
|
||||||
|
results = [];
|
||||||
|
$tw.utils.each(operation.operators,function(operator) {
|
||||||
|
var operatorFunction = filterOperators[operator.operator] || filterOperators.field || function(source,operator,operations) {
|
||||||
|
return ["Filter Error: unknown operator '" + operator.operator + "'"];
|
||||||
|
};
|
||||||
|
results = operatorFunction(accumulator,operator,{wiki: self, currTiddlerTitle: currTiddlerTitle});
|
||||||
|
accumulator = results;
|
||||||
|
});
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
// Wrap the operator functions in a wrapper function that depends on the prefix
|
||||||
|
operationFunctions.push((function() {
|
||||||
|
switch(operation.prefix || "") {
|
||||||
|
case "": // No prefix means that the operation is unioned into the result
|
||||||
|
return function(results,source,currTiddlerTitle) {
|
||||||
|
$tw.utils.pushTop(results,operationSubFunction(source,currTiddlerTitle));
|
||||||
|
};
|
||||||
|
case "-": // The results of this operation are removed from the main result
|
||||||
|
return function(results,source,currTiddlerTitle) {
|
||||||
|
$tw.utils.removeArrayEntries(results,operationSubFunction(source,currTiddlerTitle));
|
||||||
|
};
|
||||||
|
case "+": // This operation is applied to the main results so far
|
||||||
|
return function(results,source,currTiddlerTitle) {
|
||||||
|
// This replaces all the elements of the array, but keeps the actual array so that references to it are preserved
|
||||||
|
source = results.slice(0);
|
||||||
|
results.splice(0,results.length);
|
||||||
|
$tw.utils.pushTop(results,operationSubFunction(source,currTiddlerTitle));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})());
|
||||||
|
});
|
||||||
|
// Return a function that applies the operations to a source array/hashmap of tiddler titles
|
||||||
|
return function(source,currTiddlerTitle) {
|
||||||
|
var results = [];
|
||||||
|
$tw.utils.each(operationFunctions,function(operationFunction) {
|
||||||
|
operationFunction(results,source,currTiddlerTitle);
|
||||||
|
});
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
37
core/modules/filters/backlinks.js
Normal file
37
core/modules/filters/backlinks.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/backlinks.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: filteroperator
|
||||||
|
|
||||||
|
Filter operator for returning all the backlinks from a tiddler
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.backlinks = function(source,operator,options) {
|
||||||
|
var results = [];
|
||||||
|
// Function to check an individual title
|
||||||
|
function checkTiddler(title) {
|
||||||
|
$tw.utils.pushTop(results,options.wiki.getTiddlerBacklinks(title));
|
||||||
|
};
|
||||||
|
// Iterate through the source tiddlers
|
||||||
|
if($tw.utils.isArray(source)) {
|
||||||
|
$tw.utils.each(source,function(title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$tw.utils.each(source,function(element,title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
46
core/modules/filters/field.js
Normal file
46
core/modules/filters/field.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/field.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: filteroperator
|
||||||
|
|
||||||
|
Filter operator for comparing fields for equality
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.field = function(source,operator,options) {
|
||||||
|
var results = [];
|
||||||
|
// Function to check an individual title
|
||||||
|
function checkTiddler(title) {
|
||||||
|
var tiddler = options.wiki.getTiddler(title);
|
||||||
|
if(tiddler) {
|
||||||
|
var match = tiddler.fields[operator.operator] === operator.operand;
|
||||||
|
if(operator.prefix === "!") {
|
||||||
|
match = !match;
|
||||||
|
}
|
||||||
|
if(match) {
|
||||||
|
results.push(title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Iterate through the source tiddlers
|
||||||
|
if($tw.utils.isArray(source)) {
|
||||||
|
$tw.utils.each(source,function(title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$tw.utils.each(source,function(element,title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
46
core/modules/filters/has.js
Normal file
46
core/modules/filters/has.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/has.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: filteroperator
|
||||||
|
|
||||||
|
Filter operator for checking if a tiddler has the specified field
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.has = function(source,operator,options) {
|
||||||
|
var results = [];
|
||||||
|
// Function to check an individual title
|
||||||
|
function checkTiddler(title) {
|
||||||
|
var tiddler = options.wiki.getTiddler(title);
|
||||||
|
if(tiddler) {
|
||||||
|
var match = $tw.utils.hop(tiddler.fields,operator.operand);
|
||||||
|
if(operator.prefix === "!") {
|
||||||
|
match = !match;
|
||||||
|
}
|
||||||
|
if(match) {
|
||||||
|
results.push(title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Iterate through the source tiddlers
|
||||||
|
if($tw.utils.isArray(source)) {
|
||||||
|
$tw.utils.each(source,function(title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$tw.utils.each(source,function(element,title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
39
core/modules/filters/is.js
Normal file
39
core/modules/filters/is.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/is.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: filteroperator
|
||||||
|
|
||||||
|
Filter operator for checking tiddler properties
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var isFilterOperators;
|
||||||
|
|
||||||
|
function getIsFilterOperators() {
|
||||||
|
if(!isFilterOperators) {
|
||||||
|
isFilterOperators = {};
|
||||||
|
$tw.modules.applyMethods("isfilteroperator",isFilterOperators);
|
||||||
|
}
|
||||||
|
return isFilterOperators;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.is = function(source,operator,options) {
|
||||||
|
// Dispatch to the correct isfilteroperator
|
||||||
|
var isFilterOperators = getIsFilterOperators();
|
||||||
|
var isFilterOperator = isFilterOperators[operator.operand];
|
||||||
|
if(isFilterOperator) {
|
||||||
|
return isFilterOperator(source,operator.prefix,options);
|
||||||
|
} else {
|
||||||
|
return ["Filter Error: Unknown operand for the 'is' filter operator"];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
49
core/modules/filters/is/current.js
Normal file
49
core/modules/filters/is/current.js
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/is/current.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: isfilteroperator
|
||||||
|
|
||||||
|
Filter function for [is[current]]
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.current = function(source,prefix,options) {
|
||||||
|
var results = [];
|
||||||
|
// Function to check a tiddler
|
||||||
|
function checkTiddler(title) {
|
||||||
|
if(title !== options.currTiddlerTitle) {
|
||||||
|
results.push(title);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Iterate through the source tiddlers
|
||||||
|
if($tw.utils.isArray(source)) {
|
||||||
|
if(prefix === "!") {
|
||||||
|
$tw.utils.each(source,function(title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if(source.indexOf(options.currTiddlerTitle) !== -1) {
|
||||||
|
results.push(options.currTiddlerTitle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(prefix === "!") {
|
||||||
|
$tw.utils.each(source,function(element,title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
results.push(options.currTiddlerTitle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
48
core/modules/filters/is/missing.js
Normal file
48
core/modules/filters/is/missing.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/is/missing.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: isfilteroperator
|
||||||
|
|
||||||
|
Filter function for [is[missing]]
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.missing = function(source,prefix,options) {
|
||||||
|
var results = [],
|
||||||
|
missingTitles;
|
||||||
|
// Iterate through the source tiddlers
|
||||||
|
if($tw.utils.isArray(source)) {
|
||||||
|
missingTitles = options.wiki.getMissingTitles();
|
||||||
|
$tw.utils.each(source,function(title) {
|
||||||
|
var match = missingTitles.indexOf(title) !== -1;
|
||||||
|
if(prefix === "!") {
|
||||||
|
match = !match;
|
||||||
|
}
|
||||||
|
if(match) {
|
||||||
|
results.push(title);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if(prefix !== "!") {
|
||||||
|
missingTitles = options.wiki.getMissingTitles();
|
||||||
|
$tw.utils.each(missingTitles,function(title) {
|
||||||
|
results.push(title);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$tw.utils.each(source,function(element,title) {
|
||||||
|
results.push(title);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
46
core/modules/filters/is/orphan.js
Normal file
46
core/modules/filters/is/orphan.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/is/orphan.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: isfilteroperator
|
||||||
|
|
||||||
|
Filter function for [is[orphan]]
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.orphan = function(source,prefix,options) {
|
||||||
|
var results = [],
|
||||||
|
orphanTitles = options.wiki.getOrphanTitles();
|
||||||
|
// Iterate through the source tiddlers
|
||||||
|
if($tw.utils.isArray(source)) {
|
||||||
|
$tw.utils.each(source,function(title) {
|
||||||
|
var match = orphanTitles.indexOf(title) !== -1;
|
||||||
|
if(prefix === "!") {
|
||||||
|
match = !match;
|
||||||
|
}
|
||||||
|
if(match) {
|
||||||
|
results.push(title);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$tw.utils.each(source,function(element,title) {
|
||||||
|
var match = orphanTitles.indexOf(title) !== -1;
|
||||||
|
if(prefix === "!") {
|
||||||
|
match = !match;
|
||||||
|
}
|
||||||
|
if(match) {
|
||||||
|
results.push(title);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
49
core/modules/filters/is/shadow.js
Normal file
49
core/modules/filters/is/shadow.js
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/is/shadow.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: isfilteroperator
|
||||||
|
|
||||||
|
Filter function for [is[shadow]]
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.shadow = function(source,prefix,options) {
|
||||||
|
var results = [];
|
||||||
|
// Function to check a tiddler
|
||||||
|
function checkTiddler(title) {
|
||||||
|
var match = options.wiki.isShadowTiddler(title);
|
||||||
|
if(prefix === "!") {
|
||||||
|
match = !match;
|
||||||
|
}
|
||||||
|
if(match) {
|
||||||
|
results.push(title);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Iterate through the source tiddlers
|
||||||
|
if($tw.utils.isArray(source)) {
|
||||||
|
$tw.utils.each(source,function(title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if(prefix !== "!") {
|
||||||
|
$tw.utils.each(options.wiki.shadowTiddlers,function(tiddler,title) {
|
||||||
|
results.push(title);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$tw.utils.each(source,function(element,title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
43
core/modules/filters/is/system.js
Normal file
43
core/modules/filters/is/system.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/is/system.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: isfilteroperator
|
||||||
|
|
||||||
|
Filter function for [is[system]]
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.system = function(source,prefix,options) {
|
||||||
|
var results = [];
|
||||||
|
// Function to check a tiddler
|
||||||
|
function checkTiddler(title) {
|
||||||
|
var match = options.wiki.isSystemTiddler(title);
|
||||||
|
if(prefix === "!") {
|
||||||
|
match = !match;
|
||||||
|
}
|
||||||
|
if(match) {
|
||||||
|
results.push(title);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Iterate through the source tiddlers
|
||||||
|
if($tw.utils.isArray(source)) {
|
||||||
|
$tw.utils.each(source,function(title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$tw.utils.each(source,function(element,title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
38
core/modules/filters/limit.js
Normal file
38
core/modules/filters/limit.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/limit.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: filteroperator
|
||||||
|
|
||||||
|
Filter operator for chopping the results to a specified maximum number of entries
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.limit = function(source,operator,options) {
|
||||||
|
var results = [];
|
||||||
|
// Convert to an array if necessary
|
||||||
|
if(!$tw.utils.isArray(source)) {
|
||||||
|
var copy = [];
|
||||||
|
$tw.utils.each(source,function(element,title) {
|
||||||
|
copy.push(title);
|
||||||
|
});
|
||||||
|
source = copy;
|
||||||
|
}
|
||||||
|
// Slice the array if necessary
|
||||||
|
var limit = Math.min(source.length,parseInt(operator.operand,10));
|
||||||
|
if(operator.prefix === "!") {
|
||||||
|
results = source.slice(source.length - limit,limit);
|
||||||
|
} else {
|
||||||
|
results = source.slice(0,limit);
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
37
core/modules/filters/links.js
Normal file
37
core/modules/filters/links.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/links.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: filteroperator
|
||||||
|
|
||||||
|
Filter operator for returning all the links from a tiddler
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.links = function(source,operator,options) {
|
||||||
|
var results = [];
|
||||||
|
// Function to check an individual title
|
||||||
|
function checkTiddler(title) {
|
||||||
|
$tw.utils.pushTop(results,options.wiki.getTiddlerLinks(title));
|
||||||
|
};
|
||||||
|
// Iterate through the source tiddlers
|
||||||
|
if($tw.utils.isArray(source)) {
|
||||||
|
$tw.utils.each(source,function(title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$tw.utils.each(source,function(element,title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
47
core/modules/filters/list.js
Normal file
47
core/modules/filters/list.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/list.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: filteroperator
|
||||||
|
|
||||||
|
Filter operator returning the tiddlers whose title is listed in the operand tiddler
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.list = function(source,operator,options) {
|
||||||
|
var results = [],
|
||||||
|
list = options.wiki.getTiddlerList(operator.operand);
|
||||||
|
function checkTiddler(title) {
|
||||||
|
var match = list.indexOf(title) !== -1;
|
||||||
|
if(operator.prefix === "!") {
|
||||||
|
match = !match;
|
||||||
|
}
|
||||||
|
if(match) {
|
||||||
|
results.push(title);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Iterate through the source tiddlers
|
||||||
|
if($tw.utils.isArray(source)) {
|
||||||
|
$tw.utils.each(source,function(title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if(operator.prefix !== "!") {
|
||||||
|
results = list;
|
||||||
|
} else {
|
||||||
|
$tw.utils.each(source,function(element,title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
46
core/modules/filters/prefix.js
Normal file
46
core/modules/filters/prefix.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/prefix.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: filteroperator
|
||||||
|
|
||||||
|
Filter operator for checking if a title starts with a prefix
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.prefix = function(source,operator,options) {
|
||||||
|
var results = [];
|
||||||
|
// Function to check an individual title
|
||||||
|
function checkTiddler(title) {
|
||||||
|
var tiddler = options.wiki.getTiddler(title);
|
||||||
|
if(tiddler) {
|
||||||
|
var match = tiddler.fields.title.substr(0,operator.operand.length) === operator.operand;
|
||||||
|
if(operator.prefix === "!") {
|
||||||
|
match = !match;
|
||||||
|
}
|
||||||
|
if(match) {
|
||||||
|
results.push(title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Iterate through the source tiddlers
|
||||||
|
if($tw.utils.isArray(source)) {
|
||||||
|
$tw.utils.each(source,function(title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$tw.utils.each(source,function(element,title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
28
core/modules/filters/searchVia.js
Normal file
28
core/modules/filters/searchVia.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/searchVia.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: filteroperator
|
||||||
|
|
||||||
|
Filter operator for searching for the text in the operand tiddler
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.searchVia = function(source,operator,options) {
|
||||||
|
var term = options.wiki.getTiddlerText(operator.operand,""),
|
||||||
|
invert = operator.prefix === "!";
|
||||||
|
return options.wiki.search(term,{
|
||||||
|
titles: source,
|
||||||
|
invert: invert,
|
||||||
|
exclude: [operator.operand]
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
32
core/modules/filters/sort.js
Normal file
32
core/modules/filters/sort.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/sort.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: filteroperator
|
||||||
|
|
||||||
|
Filter operator for sorting
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.sort = function(source,operator,options) {
|
||||||
|
var results;
|
||||||
|
if($tw.utils.isArray(source)) {
|
||||||
|
results = source;
|
||||||
|
} else {
|
||||||
|
results = [];
|
||||||
|
$tw.utils.each(source,function(element,title) {
|
||||||
|
results.push(title);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
options.wiki.sortTiddlers(results,operator.operand,operator.prefix === "!");
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
32
core/modules/filters/sortcs.js
Normal file
32
core/modules/filters/sortcs.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/sortcs.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: filteroperator
|
||||||
|
|
||||||
|
Filter operator for case-sensitive sorting
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.sortcs = function(source,operator,options) {
|
||||||
|
var results;
|
||||||
|
if($tw.utils.isArray(source)) {
|
||||||
|
results = source;
|
||||||
|
} else {
|
||||||
|
results = [];
|
||||||
|
$tw.utils.each(source,function(element,title) {
|
||||||
|
results.push(title);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
options.wiki.sortTiddlers(results,operator.operand,operator.prefix === "!",true);
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
46
core/modules/filters/tag.js
Normal file
46
core/modules/filters/tag.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/tag.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: filteroperator
|
||||||
|
|
||||||
|
Filter operator for checking for the presence of a tag
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.tag = function(source,operator,options) {
|
||||||
|
var results = [];
|
||||||
|
// Function to check an individual title
|
||||||
|
function checkTiddler(title) {
|
||||||
|
var tiddler = options.wiki.getTiddler(title);
|
||||||
|
if(tiddler) {
|
||||||
|
var match = tiddler.hasTag(operator.operand);
|
||||||
|
if(operator.prefix === "!") {
|
||||||
|
match = !match;
|
||||||
|
}
|
||||||
|
if(match) {
|
||||||
|
results.push(title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Iterate through the source tiddlers
|
||||||
|
if($tw.utils.isArray(source)) {
|
||||||
|
$tw.utils.each(source,function(title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$tw.utils.each(source,function(element,title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
37
core/modules/filters/tagging.js
Normal file
37
core/modules/filters/tagging.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/tagging.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: filteroperator
|
||||||
|
|
||||||
|
Filter operator returning all tiddlers that are tagged with the selected tiddlers
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.tagging = function(source,operator,options) {
|
||||||
|
var results = [];
|
||||||
|
// Function to check an individual title
|
||||||
|
function checkTiddler(title) {
|
||||||
|
$tw.utils.pushTop(results,options.wiki.getTiddlersWithTag(title));
|
||||||
|
};
|
||||||
|
// Iterate through the source tiddlers
|
||||||
|
if($tw.utils.isArray(source)) {
|
||||||
|
$tw.utils.each(source,function(title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$tw.utils.each(source,function(element,title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
40
core/modules/filters/tags.js
Normal file
40
core/modules/filters/tags.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/tags.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: filteroperator
|
||||||
|
|
||||||
|
Filter operator returning all tiddlers tagging the selected tiddlers
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.tags = function(source,operator,options) {
|
||||||
|
var results = [];
|
||||||
|
// Function to check an individual title
|
||||||
|
function checkTiddler(title) {
|
||||||
|
var tiddler = options.wiki.getTiddler(title);
|
||||||
|
if(tiddler && tiddler.fields.tags) {
|
||||||
|
$tw.utils.pushTop(results,tiddler.fields.tags);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Iterate through the source tiddlers
|
||||||
|
if($tw.utils.isArray(source)) {
|
||||||
|
$tw.utils.each(source,function(title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$tw.utils.each(source,function(element,title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
53
core/modules/filters/title.js
Normal file
53
core/modules/filters/title.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/title.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: filteroperator
|
||||||
|
|
||||||
|
Filter operator for comparing title fields for equality
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.title = function(source,operator,options) {
|
||||||
|
var results = [];
|
||||||
|
// Function to check an individual title
|
||||||
|
function checkTiddler(title) {
|
||||||
|
var tiddler = options.wiki.getTiddler(title);
|
||||||
|
if(tiddler) {
|
||||||
|
var match = tiddler.fields[operator.operator] === operator.operand;
|
||||||
|
if(operator.prefix === "!") {
|
||||||
|
match = !match;
|
||||||
|
}
|
||||||
|
if(match) {
|
||||||
|
results.push(title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Iterate through the source tiddlers
|
||||||
|
if($tw.utils.isArray(source)) {
|
||||||
|
$tw.utils.each(source,function(title) {
|
||||||
|
checkTiddler(title);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// If we're filtering a hashmap we change the behaviour to pass through missing tiddlers
|
||||||
|
if(operator.prefix !== "!") {
|
||||||
|
results.push(operator.operand);
|
||||||
|
} else {
|
||||||
|
$tw.utils.each(source,function(element,title) {
|
||||||
|
if(title !== operator.operand) {
|
||||||
|
checkTiddler(title);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
181
editions/test/tiddlers/tests/test-filters.js
Normal file
181
editions/test/tiddlers/tests/test-filters.js
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
/*\
|
||||||
|
title: test-filters.js
|
||||||
|
type: application/javascript
|
||||||
|
tags: [[$:/tags/test-spec]]
|
||||||
|
|
||||||
|
Tests the filtering mechanism.
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
describe("Filter tests", function() {
|
||||||
|
|
||||||
|
// Create a wiki
|
||||||
|
var wiki = new $tw.Wiki();
|
||||||
|
|
||||||
|
// Some helpers
|
||||||
|
var addShadowTiddler = function(fields) {
|
||||||
|
var tiddler = new $tw.Tiddler(fields);
|
||||||
|
wiki.shadowTiddlers[tiddler.fields.title] = {tiddler: tiddler};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add a few tiddlers
|
||||||
|
wiki.addTiddler({
|
||||||
|
title: "TiddlerOne",
|
||||||
|
text: "The quick brown fox in $:/TiddlerTwo",
|
||||||
|
tags: ["one"],
|
||||||
|
modifier: "JoeBloggs"});
|
||||||
|
wiki.addTiddler({
|
||||||
|
title: "$:/TiddlerTwo",
|
||||||
|
text: "The rain in Spain\nfalls mainly on the plain and [[a fourth tiddler]]",
|
||||||
|
tags: ["two"]});
|
||||||
|
wiki.addTiddler({
|
||||||
|
title: "Tiddler Three",
|
||||||
|
text: "The speed of sound in light\n\nThere is no TiddlerZero but TiddlerSix",
|
||||||
|
tags: ["one","two"]});
|
||||||
|
wiki.addTiddler({
|
||||||
|
title: "a fourth tiddler",
|
||||||
|
text: "The quality of mercy is not drained by [[Tiddler Three]]",
|
||||||
|
tags: []});
|
||||||
|
// And some shadows
|
||||||
|
addShadowTiddler({
|
||||||
|
title: "$:/TiddlerFive",
|
||||||
|
text: "Everything in federation",
|
||||||
|
tags: ["two"]});
|
||||||
|
addShadowTiddler({
|
||||||
|
title: "TiddlerSix",
|
||||||
|
text: "Missing inaction from TiddlerOne",
|
||||||
|
tags: []});
|
||||||
|
addShadowTiddler({
|
||||||
|
title: "TiddlerSeventh",
|
||||||
|
text: "TiddlerOne\nTiddler Three\na fourth tiddler\nMissingTiddler",
|
||||||
|
tags: []});
|
||||||
|
addShadowTiddler({
|
||||||
|
title: "Tiddler8",
|
||||||
|
text: "Tidd",
|
||||||
|
tags: []});
|
||||||
|
|
||||||
|
// Our tests
|
||||||
|
|
||||||
|
it("should handle the title operator", function() {
|
||||||
|
expect(wiki.filterTiddlers("TiddlerOne [title[$:/TiddlerTwo]] [[Tiddler Three]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three");
|
||||||
|
expect(wiki.filterTiddlers("[!title[Tiddler Three]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,a fourth tiddler");
|
||||||
|
expect(wiki.filterTiddlers("TiddlerOne [title[$:/TiddlerTwo]] [[Tiddler Three]] [[A Missing Tiddler]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three,A Missing Tiddler");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle the field operator", function() {
|
||||||
|
expect(wiki.filterTiddlers("[modifier[JoeBloggs]]").join(",")).toBe("TiddlerOne");
|
||||||
|
expect(wiki.filterTiddlers("[!modifier[JoeBloggs]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,a fourth tiddler");
|
||||||
|
expect(wiki.filterTiddlers("[!is[system]!modifier[JoeBloggs]]").join(",")).toBe("Tiddler Three,a fourth tiddler");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle the prefix operator", function() {
|
||||||
|
expect(wiki.filterTiddlers("[prefix[Tiddler]]").join(",")).toBe("TiddlerOne,Tiddler Three");
|
||||||
|
expect(wiki.filterTiddlers("[prefix[nothing]]").join(",")).toBe("");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle the sort and sortcs operators", function() {
|
||||||
|
expect(wiki.filterTiddlers("[sort[title]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,Tiddler Three,TiddlerOne");
|
||||||
|
expect(wiki.filterTiddlers("[!sort[title]]").join(",")).toBe("TiddlerOne,Tiddler Three,a fourth tiddler,$:/TiddlerTwo");
|
||||||
|
expect(wiki.filterTiddlers("[sortcs[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,TiddlerOne,a fourth tiddler");
|
||||||
|
expect(wiki.filterTiddlers("[!sortcs[title]]").join(",")).toBe("a fourth tiddler,TiddlerOne,Tiddler Three,$:/TiddlerTwo");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle the tag operator", function() {
|
||||||
|
expect(wiki.filterTiddlers("[tag[one]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne");
|
||||||
|
expect(wiki.filterTiddlers("[!tag[one]sort[title]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler");
|
||||||
|
expect(wiki.filterTiddlers("[prefix[Tidd]tag[one]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne");
|
||||||
|
expect(wiki.filterTiddlers("[!is[shadow]tag[two]sort[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three");
|
||||||
|
expect(wiki.filterTiddlers("[is[shadow]tag[two]sort[title]]").join(",")).toBe("$:/TiddlerFive");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle the tags operator", function() {
|
||||||
|
expect(wiki.filterTiddlers("[tags[]sort[title]]").join(",")).toBe("one,two");
|
||||||
|
expect(wiki.filterTiddlers("[[TiddlerOne]tags[]sort[title]]").join(",")).toBe("one");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle the tagging operator", function() {
|
||||||
|
expect(wiki.filterTiddlers("[[one]tagging[]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne");
|
||||||
|
expect(wiki.filterTiddlers("[[two]tagging[]sort[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three");
|
||||||
|
expect(wiki.filterTiddlers("[is[current]tagging[]sort[title]]","one").join(",")).toBe("Tiddler Three,TiddlerOne");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle the links operator", function() {
|
||||||
|
expect(wiki.filterTiddlers("[!is[shadow]links[]sort[title]]").join(",")).toBe("a fourth tiddler,Tiddler Three,TiddlerSix,TiddlerTwo,TiddlerZero");
|
||||||
|
expect(wiki.filterTiddlers("[is[shadow]links[]sort[title]]").join(",")).toBe("MissingTiddler,TiddlerOne");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle the backlinks operator", function() {
|
||||||
|
expect(wiki.filterTiddlers("[!is[shadow]backlinks[]sort[title]]").join(",")).toBe("a fourth tiddler");
|
||||||
|
expect(wiki.filterTiddlers("[is[shadow]backlinks[]sort[title]]").join(",")).toBe("Tiddler Three");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle the has operator", function() {
|
||||||
|
expect(wiki.filterTiddlers("[has[modifier]sort[title]]").join(",")).toBe("TiddlerOne");
|
||||||
|
expect(wiki.filterTiddlers("[!has[modifier]sort[title]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,Tiddler Three");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle the limit operator", function() {
|
||||||
|
expect(wiki.filterTiddlers("[!is[system]sort[title]limit[2]]").join(",")).toBe("a fourth tiddler,Tiddler Three");
|
||||||
|
expect(wiki.filterTiddlers("[prefix[Tid]sort[title]limit[1]]").join(",")).toBe("Tiddler Three");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle the list operator", function() {
|
||||||
|
expect(wiki.filterTiddlers("[list[TiddlerSeventh]sort[title]]").join(",")).toBe("a fourth tiddler,MissingTiddler,Tiddler Three,TiddlerOne");
|
||||||
|
expect(wiki.filterTiddlers("[tag[one]list[TiddlerSeventh]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle the searchVia operator", function() {
|
||||||
|
expect(wiki.filterTiddlers("[searchVia[Tiddler8]sort[title]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,Tiddler Three,TiddlerOne");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("testing the is operator",function() {
|
||||||
|
|
||||||
|
it("should handle the '[is[current]]' operator", function() {
|
||||||
|
expect(wiki.filterTiddlers("[is[current]]","Tiddler Three").join(",")).toBe("Tiddler Three");
|
||||||
|
expect(wiki.filterTiddlers("[[Tiddler Three]is[current]]","Tiddler Three").join(",")).toBe("Tiddler Three");
|
||||||
|
expect(wiki.filterTiddlers("[[$:/TiddlerTwo]is[current]]","Tiddler Three").join(",")).toBe("");
|
||||||
|
expect(wiki.filterTiddlers("[!is[current]sort[title]]","Tiddler Three").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,TiddlerOne");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle the '[is[system]]' operator", function() {
|
||||||
|
expect(wiki.filterTiddlers("[is[system]]").join(",")).toBe("$:/TiddlerTwo");
|
||||||
|
expect(wiki.filterTiddlers("[!is[system]sort[title]]").join(",")).toBe("a fourth tiddler,Tiddler Three,TiddlerOne");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle the '[is[shadow]]' operator", function() {
|
||||||
|
expect(wiki.filterTiddlers("[is[shadow]sort[title]]").join(",")).toBe("$:/TiddlerFive,Tiddler8,TiddlerSeventh,TiddlerSix");
|
||||||
|
expect(wiki.filterTiddlers("[!is[shadow]sort[title]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,Tiddler Three,TiddlerOne");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle the '[is[missing]]' operator", function() {
|
||||||
|
expect(wiki.filterTiddlers("[is[missing]]").join(",")).toBe("TiddlerZero,TiddlerSix,TiddlerTwo");
|
||||||
|
expect(wiki.filterTiddlers("[!is[missing]sort[title]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,Tiddler Three,TiddlerOne");
|
||||||
|
expect(wiki.filterTiddlers("[[TiddlerOne]is[missing]]").join(",")).toBe("");
|
||||||
|
expect(wiki.filterTiddlers("[[TiddlerZero]is[missing]]").join(",")).toBe("TiddlerZero");
|
||||||
|
expect(wiki.filterTiddlers("[!title[Tiddler Three]is[missing]]").join(",")).toBe("");
|
||||||
|
expect(wiki.filterTiddlers("[!title[Tiddler Three]!is[missing]sort[title]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,TiddlerOne");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle the '[is[orphan]]' operator", function() {
|
||||||
|
expect(wiki.filterTiddlers("[is[orphan]sort[title]]").join(",")).toBe("a fourth tiddler,TiddlerOne");
|
||||||
|
expect(wiki.filterTiddlers("[!is[orphan]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three");
|
||||||
|
expect(wiki.filterTiddlers("[[TiddlerOne]is[orphan]]").join(",")).toBe("TiddlerOne");
|
||||||
|
expect(wiki.filterTiddlers("[[TiddlerOne]!is[orphan]]").join(",")).toBe("");
|
||||||
|
expect(wiki.filterTiddlers("[!title[Tiddler Three]is[orphan]sort[title]]").join(",")).toBe("a fourth tiddler,TiddlerOne");
|
||||||
|
expect(wiki.filterTiddlers("[!title[Tiddler Three]!is[orphan]]").join(",")).toBe("$:/TiddlerTwo");
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle the operand prefixes", function() {
|
||||||
|
expect(wiki.filterTiddlers("[prefix[Tiddler]] +[sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne");
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
@ -46,11 +46,11 @@ Welcome to TiddlyWiki created by Jeremy Ruston; Copyright © 2004-2007 Jerem
|
|||||||
<div id="contentWrapper"></div>
|
<div id="contentWrapper"></div>
|
||||||
<div id="contentStash"></div>
|
<div id="contentStash"></div>
|
||||||
<div id="shadowArea">
|
<div id="shadowArea">
|
||||||
{{{ [prefix[{shadow}]] +[sort-case-sensitive[title]] ||$:/core/templates/html-div-tiddler-remove-prefix}}}
|
{{{ [prefix[{shadow}]] +[sortcs[title]] ||$:/core/templates/html-div-tiddler-remove-prefix}}}
|
||||||
</div>
|
</div>
|
||||||
<!--POST-SHADOWAREA-->
|
<!--POST-SHADOWAREA-->
|
||||||
<div id="storeArea">
|
<div id="storeArea">
|
||||||
{{{ [prefix[{tiddler}]] +[sort-case-sensitive[title]] ||$:/core/templates/html-div-tiddler-remove-prefix}}}
|
{{{ [prefix[{tiddler}]] +[sortcs[title]] ||$:/core/templates/html-div-tiddler-remove-prefix}}}
|
||||||
{{{ [prefix[{plugin}]] ||$:/core/templates/plain-text-tiddler}}}
|
{{{ [prefix[{plugin}]] ||$:/core/templates/plain-text-tiddler}}}
|
||||||
{{{ [prefix[{posttiddlers}]] ||$:/core/templates/plain-text-tiddler}}}
|
{{{ [prefix[{posttiddlers}]] ||$:/core/templates/plain-text-tiddler}}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -33,7 +33,7 @@ A filter string consists of one or more runs of filter operators that each look
|
|||||||
* ''is'': tests whether a tiddler is a member of the system defined set named in the operand (see below)
|
* ''is'': tests whether a tiddler is a member of the system defined set named in the operand (see below)
|
||||||
* ''has'': tests whether a tiddler has the field specified in the operand
|
* ''has'': tests whether a tiddler has the field specified in the operand
|
||||||
* ''sort'': sorts the tiddlers by the field specified in the operand
|
* ''sort'': sorts the tiddlers by the field specified in the operand
|
||||||
* ''sort-case-sensitive'': a case sensitive sort of the current tiddlers by the field specified in the operand
|
* ''sortcs'': a case sensitive sort of the current tiddlers by the field specified in the operand
|
||||||
* ''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
|
||||||
|
Loading…
Reference in New Issue
Block a user