diff --git a/core/modules/filters/strings.js b/core/modules/filters/strings.js new file mode 100644 index 000000000..d44cdc956 --- /dev/null +++ b/core/modules/filters/strings.js @@ -0,0 +1,70 @@ +/*\ +title: $:/core/modules/filters/strings.js +type: application/javascript +module-type: filteroperator + +Filter operators for strings. Unary/binary operators work on each item in turn, and return a new item list. + +Sum/product/maxall/minall operate on the entire list, returning a single item. + +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +exports.length = makeStringBinaryOperator( + function(a) {return [("" + a).length];} +); + +exports.uppercase = makeStringBinaryOperator( + function(a) {return [("" + a).toUpperCase()];} +); + +exports.lowercase = makeStringBinaryOperator( + function(a) {return [("" + a).toLowerCase()];} +); + +exports.trim = makeStringBinaryOperator( + function(a) {return [$tw.utils.trim(a)];} +); + +exports.concat = makeStringBinaryOperator( + function(a,b) {return ["" + a + b];} +); + +exports.split = makeStringBinaryOperator( + function(a,b) {return [("" + a).split(b)];} +); + +exports.join = makeStringArrayOperator( + function(accumulator,value,operand) { + return "" + (accumulator ? accumulator + (operand || "") + value : value); + } +); + +function makeStringBinaryOperator(fnCalc) { + return function(source,operator,options) { + var result = []; + source(function(tiddler,title) { + Array.prototype.push.apply(result,fnCalc(title,operator.operand || "")); + }); + return result; + }; +} + +function makeStringArrayOperator(fnCalc,initialValue) { + initialValue = initialValue || ""; + return function(source,operator,options) { + var result = []; + source(function(tiddler,title) { + result.push(title); + }); + return [result.reduce(function(accumulator,currentValue) { + return fnCalc(accumulator,currentValue,operator.operand || ""); + },initialValue)]; + }; +} + +})(); diff --git a/editions/test/tiddlers/tests/test-filters.js b/editions/test/tiddlers/tests/test-filters.js index 7ade538e5..c9bbf6d0d 100644 --- a/editions/test/tiddlers/tests/test-filters.js +++ b/editions/test/tiddlers/tests/test-filters.js @@ -361,7 +361,17 @@ describe("Filter tests", function() { expect(wiki.filterTiddlers("[list[TiddlerSeventh]before[MissingTiddler]]").join(",")).toBe("a fourth tiddler"); }); - it("should handle the math operators", function() { + it("should handle the string operators", function() { + expect(wiki.filterTiddlers("John Paul George Ringo +[length[]]").join(",")).toBe("4,4,6,5"); + expect(wiki.filterTiddlers("John Paul George Ringo +[uppercase[]]").join(",")).toBe("JOHN,PAUL,GEORGE,RINGO"); + expect(wiki.filterTiddlers("John Paul George Ringo +[lowercase[]]").join(",")).toBe("john,paul,george,ringo"); + expect(wiki.filterTiddlers("John Paul George Ringo +[concat[y]]").join(",")).toBe("Johny,Pauly,Georgey,Ringoy"); + expect(wiki.filterTiddlers("John Paul George Ringo +[split[]]").join(",")).toBe("J,o,h,n,P,a,u,l,G,e,o,r,g,e,R,i,n,g,o"); + expect(wiki.filterTiddlers("John Paul George Ringo +[join[ ]split[e]join[ee]split[ ]]").join(",")).toBe("John,Paul,G,org,,Ringo"); + expect(wiki.filterTiddlers("[[ John ]] [[Paul ]] [[ George]] Ringo +[trim[]join[-]]").join(",")).toBe("John-Paul-George-Ringo"); + }); + + it("should handle the mathematics operators", function() { expect(wiki.filterTiddlers("[[2]add[2]]").join(",")).toBe("4"); expect(wiki.filterTiddlers("[[4]subtract[2]]").join(",")).toBe("2"); expect(wiki.filterTiddlers("[[24]divide[8]]").join(",")).toBe("3");