1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2025-04-06 02:37:14 +00:00

Merge 0a3a7a901a11f2a5a448a320ac886d9c7ac11893 into 961e74f73d230d0028efb586db07699120eac888

This commit is contained in:
Robin Munn 2025-04-04 15:00:27 +02:00 committed by GitHub
commit 504c2f437e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 110 additions and 0 deletions

View File

@ -0,0 +1,75 @@
/*\
title: $:/core/modules/filters/interleave.js
type: application/javascript
module-type: filteroperator
Interleave two or more lists one item at a time
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Interleave two or more lists
*/
exports.interleave = function(source,operator,options) {
var allowDuplicates = false;
switch(operator.suffix) {
case "raw":
allowDuplicates = true;
break;
case "dedupe":
allowDuplicates = false;
break;
}
var results = new $tw.utils.LinkedList();
var pushResult = allowDuplicates ? results.push.bind(results) : results.pushTop.bind(results);
// Alternately, could use the following function definition instead:
// function pushResult(item) {
// if(allowDuplicates) {
// results.push(item);
// } else {
// results.pushTop(item);
// }
// }
var input = [];
source(function(tiddler,title) {
input.push(title);
});
var lists = [input];
operator.operands.forEach(function(operand) {
var list = $tw.utils.parseStringArray(operand,true);
lists.push(list);
});
var listCount = lists.length;
var indices = new Array(listCount);
var remaining = new Array(listCount);
lists.forEach(function(list,index) {
indices[index] = 0;
remaining[index] = (list.length > 0);
});
var current = 0;
while(remaining.some(Boolean)) {
var list = lists[current];
var index = indices[current];
if(remaining[current]) {
pushResult(list[index]);
if(index+1 < list.length) {
indices[current] = index+1;
} else {
remaining[current] = false;
}
}
current = (current+1) % listCount;
}
return results.makeTiddlerIterator(options.wiki);
};
})();

View File

@ -821,6 +821,41 @@ Tests the filtering mechanism.
expect(wiki.filterTiddlers("a b c d e +[insertbefore:end[b],[foo]]").join(",")).toBe("a,c,d,e,b");
expect(wiki.filterTiddlers("a b c d e +[insertbefore:end[b],<foo>]").join(",")).toBe("a,c,d,e,b");
});
it("should handle the interleave operator", function() {
expect(wiki.filterTiddlers("").join(",")).toBe("");
// Interleaving two same-length lists
expect(wiki.filterTiddlers("a b c +[interleave[1 2 3]]").join(",")).toBe("a,1,b,2,c,3");
// Two lists of length 1 should also work
expect(wiki.filterTiddlers("a +[interleave[1]]").join(",")).toBe("a,1");
// Two lists of length 0 should produce an empty list
// Note the + so we don't get [all[tiddlers]] as input
expect(wiki.filterTiddlers("+[interleave[]]").join(",")).toBe("");
// Two lists of different lengths should interleave until one list is exhausted, then take rest of other list
expect(wiki.filterTiddlers("a b c d +[interleave[1 2 3]]").join(",")).toBe("a,1,b,2,c,3,d");
expect(wiki.filterTiddlers("a b c d e +[interleave[1 2 3]]").join(",")).toBe("a,1,b,2,c,3,d,e");
expect(wiki.filterTiddlers("a b c d e f +[interleave[1 2 3]]").join(",")).toBe("a,1,b,2,c,3,d,e,f");
expect(wiki.filterTiddlers("a b c +[interleave[1 2 3 4]]").join(",")).toBe("a,1,b,2,c,3,4");
expect(wiki.filterTiddlers("a b c +[interleave[1 2 3 4 5]]").join(",")).toBe("a,1,b,2,c,3,4,5");
expect(wiki.filterTiddlers("a b c +[interleave[1 2 3 4 5 6]]").join(",")).toBe("a,1,b,2,c,3,4,5,6");
// Interleaving with an empty list produces the original list unchanged
expect(wiki.filterTiddlers("a b c +[interleave[]]").join(",")).toBe("a,b,c");
expect(wiki.filterTiddlers("+[interleave[a b c]]").join(",")).toBe("a,b,c");
// Three or more lists can be interleaved using multiple parameters
expect(wiki.filterTiddlers("a b c +[interleave[1 2 3],[red green blue]]").join(",")).toBe("a,1,red,b,2,green,c,3,blue");
// If any list runs out of items, rest continue interleaving
expect(wiki.filterTiddlers("a b c d e f g h +[interleave[red green blue],[1 2 3 4 5]]").join(",")).toBe("a,red,1,b,green,2,c,blue,3,d,4,e,5,f,g,h");
// An empty list in the middle of the parameters won't cause issues
expect(wiki.filterTiddlers("a b c +[interleave[1 2 3],[],[red green blue]]").join(",")).toBe("a,1,red,b,2,green,c,3,blue");
// Can interleave as many lists we we want; we'll test four and five lists
expect(wiki.filterTiddlers("a b c +[interleave[1 2 3],[red green blue],[10 20 30]]").join(",")).toBe("a,1,red,10,b,2,green,20,c,3,blue,30");
expect(wiki.filterTiddlers("a b c +[interleave[1 2 3],[red green blue],[x y z],[10 20 30]]").join(",")).toBe("a,1,red,x,10,b,2,green,y,20,c,3,blue,z,30");
// De-duplicates output by default
expect(wiki.filterTiddlers("a b c d +[interleave[1 2 3 2]]").join(",")).toBe("a,1,b,c,3,d,2");
// Use suffix "raw" to skip de-duplicating
expect(wiki.filterTiddlers("a b c d +[interleave:raw[1 2 3 2]]").join(",")).toBe("a,1,b,2,c,3,d,2");
});
it("should handle the move operator", function() {
expect(wiki.filterTiddlers("a b c d e +[move[c]]").join(",")).toBe("a,b,d,c,e");