1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2025-08-06 05:43:51 +00:00

Include separate entries for each evaluation of a run

This commit is contained in:
Jeremy Ruston 2025-04-07 16:13:18 +01:00
parent 3a2c81192e
commit 3c6ec3f9bb
7 changed files with 344 additions and 130 deletions

View File

@ -235,7 +235,7 @@ exports.compileFilter = function(filterString,options) {
this.filterCache = Object.create(null); this.filterCache = Object.create(null);
this.filterCacheCount = 0; this.filterCacheCount = 0;
} }
if(this.filterCache[filterString] !== undefined && !wrappers.prefix && !wrappers.operator) { if(this.filterCache[filterString] !== undefined && !wrappers.prefix && !wrappers.operation && !wrappers.operator) {
return this.filterCache[filterString]; return this.filterCache[filterString];
} }
var filterParseTree; var filterParseTree;
@ -258,58 +258,64 @@ exports.compileFilter = function(filterString,options) {
var operationSubFunction = function(source,widget) { var operationSubFunction = function(source,widget) {
var accumulator = source, var accumulator = source,
results = [], results = [],
currTiddlerTitle = widget && widget.getVariable("currentTiddler"); currTiddlerTitle = widget && widget.getVariable("currentTiddler"),
$tw.utils.each(operation.operators,function(operator) { handleOperation = function() {
var operands = [], $tw.utils.each(operation.operators,function(operator) {
operatorName,operatorFunction; var operands = [],
if(!operator.operator) { operatorName,operatorFunction;
// Use the "title" operator if no operator is specified if(!operator.operator) {
operatorName = "title"; // Use the "title" operator if no operator is specified
} else if(!filterOperators[operator.operator]) { operatorName = "title";
// Unknown operators treated as "[unknown]" - at run time we can distinguish between a custom operator and falling back to the default "field" operator } else if(!filterOperators[operator.operator]) {
operatorName = "[unknown]"; // Unknown operators treated as "[unknown]" - at run time we can distinguish between a custom operator and falling back to the default "field" operator
} else { operatorName = "[unknown]";
// Use the operator function } else {
operatorName = operator.operator; // Use the operator function
} operatorName = operator.operator;
operatorFunction = filterOperators[operatorName]; }
$tw.utils.each(operator.operands,function(operand) { operatorFunction = filterOperators[operatorName];
if(operand.indirect) { $tw.utils.each(operator.operands,function(operand) {
operand.value = self.getTextReference(operand.text,"",currTiddlerTitle); if(operand.indirect) {
} else if(operand.variable) { operand.value = self.getTextReference(operand.text,"",currTiddlerTitle);
var varTree = $tw.utils.parseFilterVariable(operand.text); } else if(operand.variable) {
operand.value = widgetClass.evaluateVariable(widget,varTree.name,{params: varTree.params, source: source})[0] || ""; var varTree = $tw.utils.parseFilterVariable(operand.text);
} else { operand.value = widgetClass.evaluateVariable(widget,varTree.name,{params: varTree.params, source: source})[0] || "";
operand.value = operand.text; } else {
} operand.value = operand.text;
operands.push(operand.value); }
}); operands.push(operand.value);
// Wrap the filter operator module if required
if(wrappers.operator) {
operatorFunction = wrappers.operator.bind(self,operatorFunction);
}
// Invoke the appropriate filteroperator module
results = operatorFunction(accumulator,{
parseTree: operator,
operator: operator.operator,
operatorName: operatorName,
operand: operands.length > 0 ? operands[0] : undefined,
operands: operands,
prefix: operator.prefix,
suffix: operator.suffix,
suffixes: operator.suffixes,
regexp: operator.regexp
},{
wiki: self,
widget: widget
}); });
if($tw.utils.isArray(results)) { // Wrap the filter operator module if required
accumulator = self.makeTiddlerIterator(results); if(wrappers.operator) {
} else { operatorFunction = wrappers.operator.bind(self,operatorFunction);
accumulator = results; }
} // Invoke the appropriate filteroperator module
}); results = operatorFunction(accumulator,{
if($tw.utils.isArray(results)) { parseTree: operator,
operator: operator.operator,
operatorName: operatorName,
operand: operands.length > 0 ? operands[0] : undefined,
operands: operands,
prefix: operator.prefix,
suffix: operator.suffix,
suffixes: operator.suffixes,
regexp: operator.regexp
},{
wiki: self,
widget: widget
});
if($tw.utils.isArray(results)) {
accumulator = self.makeTiddlerIterator(results);
} else {
accumulator = results;
}
});
};
if(wrappers.operation) {
handleOperation = wrappers.operation.bind(self,handleOperation,operation);
}
handleOperation();
if($tw.utils.isArray(results)) {
return results; return results;
} else { } else {
var resultArray = []; var resultArray = [];

View File

@ -15,8 +15,12 @@ Export our filter function
exports.inspect = function(source,operator,options) { exports.inspect = function(source,operator,options) {
var self = this, var self = this,
inputFilter = operator.operands[0] || "", inputFilter = operator.operands[0] || "",
output = {input: [],runs: [], inputFilter: inputFilter}, output = {
currentRun; input: [],
runs: [],
inputFilter: inputFilter
},
currentRun,currentOperation;
// Save the input // Save the input
source(function(tiddler,title) { source(function(tiddler,title) {
output.input.push(title); output.input.push(title);
@ -30,15 +34,23 @@ exports.inspect = function(source,operator,options) {
input: results.toArray(), input: results.toArray(),
prefixName: innerOptions.prefixName, prefixName: innerOptions.prefixName,
suffixes: innerOptions.suffixes, suffixes: innerOptions.suffixes,
operators: [] operations: []
}; };
currentRun = details.operators; currentRun = details.operations;
var innerResults = filterRunPrefixFunction.call(null,operationFunction,innerOptions); var innerResults = filterRunPrefixFunction.call(null,operationFunction,innerOptions);
innerResults(results,innerSource,innerWidget); innerResults(results,innerSource,innerWidget);
details.output = results.toArray(); details.output = results.toArray();
output.runs.push(details); output.runs.push(details);
}; };
}, },
operation: function(operationFunction,operation) {
var details = {
operators: []
}
currentOperation = details.operators;
currentRun.push(details);
operationFunction();
},
operator: function(operatorFunction,innerSource,innerOperator,innerOptions) { operator: function(operatorFunction,innerSource,innerOperator,innerOptions) {
var details = { var details = {
operatorName: innerOperator.operatorName, operatorName: innerOperator.operatorName,
@ -53,7 +65,7 @@ exports.inspect = function(source,operator,options) {
innerSource(function(tiddler,title) { innerSource(function(tiddler,title) {
details.input.push(title); details.input.push(title);
}); });
currentRun.push(details); currentOperation.push(details);
var innerResults = operatorFunction.apply(null,Array.prototype.slice.call(arguments,1)); var innerResults = operatorFunction.apply(null,Array.prototype.slice.call(arguments,1));
if(!$tw.utils.isArray(innerResults)) { if(!$tw.utils.isArray(innerResults)) {
var resultArray = []; var resultArray = [];

View File

@ -93,6 +93,22 @@ tags: $:/tags/Macro
</div> </div>
\end inspect-operator \end inspect-operator
\procedure inspect-operation(jsonOperation,indexOperation)
<div class="tc-box tc-inspect-operation-box">
<div class="tc-box-header">
<span class="">Evaluation</span>
<span class="tc-pill"><$text text=<<indexOperation>> /></span>
</div>
<div class="tc-box-content">
<$list filter="[<jsonOperation>jsonindexes[operators]nsort[]]" variable="indexOperator">
<$let transclusion={{{ [[operator-]addsuffix<indexOperator>] }}}>
<$transclude $variable="inspect-operator" jsonOperator={{{ [<jsonOperation>jsonextract[operators],<indexOperator>] }}}/>
</$let>
</$list>
</div>
</div>
\end inspect-operation
\procedure inspect-run(jsonRun) \procedure inspect-run(jsonRun)
<div class="tc-box tc-inspect-run-box"> <div class="tc-box tc-inspect-run-box">
<div class="tc-box-header"> <div class="tc-box-header">
@ -107,11 +123,13 @@ tags: $:/tags/Macro
</div> </div>
<div class="tc-box-content"> <div class="tc-box-content">
<$transclude $variable="inspect-list" jsonList={{{ [<jsonRun>jsonextract[input]] }}} class="tc-box tc-inspect-input-box"/> <$transclude $variable="inspect-list" jsonList={{{ [<jsonRun>jsonextract[input]] }}} class="tc-box tc-inspect-input-box"/>
<$list filter="[<jsonRun>jsonindexes[operators]nsort[]]" variable="indexOperator"> <div class="tc-inspect-operations-wrapper">
<$let transclusion={{{ [[operator-]addsuffix<indexOperator>] }}}> <$list filter="[<jsonRun>jsonindexes[operations]nsort[]]" variable="indexOperation">
<$transclude $variable="inspect-operator" jsonOperator={{{ [<jsonRun>jsonextract[operators],<indexOperator>] }}}/> <$let transclusion={{{ [[operation-]addsuffix<indexOperation>] }}}>
</$let> <$transclude $variable="inspect-operation" jsonOperation={{{ [<jsonRun>jsonextract[operations],<indexOperation>] }}} indexOperation=<<indexOperation>>/>
</$list> </$let>
</$list>
</div>
<$transclude $variable="inspect-list" jsonList={{{ [<jsonRun>jsonextract[output]] }}} class="tc-box tc-inspect-output-box"> <$transclude $variable="inspect-list" jsonList={{{ [<jsonRun>jsonextract[output]] }}} class="tc-box tc-inspect-output-box">
</div> </div>
</div> </div>

View File

@ -8,7 +8,7 @@ title: Output
\whitespace trim \whitespace trim
\procedure test-filter() \procedure test-filter()
1 2 3 1 2 3 :sort[length[]add[1]]
\end \end
\function test-filter-wrapper() \function test-filter-wrapper()
@ -21,7 +21,7 @@ title: Output
+ +
title: ExpectedResult title: ExpectedResult
<p>1 2 3-{ <p>1 2 3 :sort[length[]add[1]]-{
"input": [ "input": [
"$:/core", "$:/core",
"ExpectedResult", "ExpectedResult",
@ -32,28 +32,32 @@ title: ExpectedResult
"input": [], "input": [],
"prefixName": "or", "prefixName": "or",
"suffixes": [], "suffixes": [],
"operators": [ "operations": [
{ {
"operatorName": "title", "operators": [
"operands": [ {
"1" "operatorName": "title",
], "operands": [
"parseTree": { "1"
"operator": "title", ],
"operands": [ "parseTree": {
{ "operator": "title",
"text": "1", "operands": [
"value": "1" {
} "text": "1",
] "value": "1"
}, }
"input": [ ]
"$:/core", },
"ExpectedResult", "input": [
"Output" "$:/core",
], "ExpectedResult",
"output": [ "Output"
"1" ],
"output": [
"1"
]
}
] ]
} }
], ],
@ -67,28 +71,32 @@ title: ExpectedResult
], ],
"prefixName": "or", "prefixName": "or",
"suffixes": [], "suffixes": [],
"operators": [ "operations": [
{ {
"operatorName": "title", "operators": [
"operands": [ {
"2" "operatorName": "title",
], "operands": [
"parseTree": { "2"
"operator": "title", ],
"operands": [ "parseTree": {
{ "operator": "title",
"text": "2", "operands": [
"value": "2" {
} "text": "2",
] "value": "2"
}, }
"input": [ ]
"$:/core", },
"ExpectedResult", "input": [
"Output" "$:/core",
], "ExpectedResult",
"output": [ "Output"
"2" ],
"output": [
"2"
]
}
] ]
} }
], ],
@ -104,28 +112,186 @@ title: ExpectedResult
], ],
"prefixName": "or", "prefixName": "or",
"suffixes": [], "suffixes": [],
"operators": [ "operations": [
{ {
"operatorName": "title", "operators": [
"operands": [ {
"3" "operatorName": "title",
], "operands": [
"parseTree": { "3"
"operator": "title", ],
"operands": [ "parseTree": {
{ "operator": "title",
"text": "3", "operands": [
"value": "3" {
} "text": "3",
] "value": "3"
}, }
"input": [ ]
"$:/core", },
"ExpectedResult", "input": [
"Output" "$:/core",
], "ExpectedResult",
"output": [ "Output"
"3" ],
"output": [
"3"
]
}
]
}
],
"output": [
"1",
"2",
"3"
]
},
{
"input": [
"1",
"2",
"3"
],
"prefixName": "sort",
"suffixes": [],
"operations": [
{
"operators": [
{
"operatorName": "length",
"operands": [
""
],
"parseTree": {
"operator": "length",
"operands": [
{
"text": "",
"value": ""
}
]
},
"input": [
"1"
],
"output": [
"1"
]
},
{
"operatorName": "add",
"operands": [
"1"
],
"parseTree": {
"operator": "add",
"operands": [
{
"text": "1",
"value": "1"
}
]
},
"input": [
"1"
],
"output": [
"2"
]
}
]
},
{
"operators": [
{
"operatorName": "length",
"operands": [
""
],
"parseTree": {
"operator": "length",
"operands": [
{
"text": "",
"value": ""
}
]
},
"input": [
"2"
],
"output": [
"1"
]
},
{
"operatorName": "add",
"operands": [
"1"
],
"parseTree": {
"operator": "add",
"operands": [
{
"text": "1",
"value": "1"
}
]
},
"input": [
"1"
],
"output": [
"2"
]
}
]
},
{
"operators": [
{
"operatorName": "length",
"operands": [
""
],
"parseTree": {
"operator": "length",
"operands": [
{
"text": "",
"value": ""
}
]
},
"input": [
"3"
],
"output": [
"1"
]
},
{
"operatorName": "add",
"operands": [
"1"
],
"parseTree": {
"operator": "add",
"operands": [
{
"text": "1",
"value": "1"
}
]
},
"input": [
"1"
],
"output": [
"2"
]
}
] ]
} }
], ],
@ -136,7 +302,7 @@ title: ExpectedResult
] ]
} }
], ],
"inputFilter": "1 2 3", "inputFilter": "1 2 3 :sort[length[]add[1]]",
"output": [ "output": [
"1", "1",
"2", "2",

View File

@ -25,4 +25,3 @@ The JSON object contains the following properties:
*** `operands`: an array of string operands passed to the operator *** `operands`: an array of string operands passed to the operator
*** `input`: the input titles passed to the operator *** `input`: the input titles passed to the operator
*** `output`: the output titles resulting from evaluating the operator *** `output`: the output titles resulting from evaluating the operator

View File

@ -6,7 +6,7 @@ type: text/vnd.tiddlywiki
<$macrocall $name=".example" n="1" eg=""" <$macrocall $name=".example" n="1" eg="""
<$transclude $variable="inspect-filter" filter="[tags[]prefix[$:/]] :sort[length[]] +[first[2]tagging[]]" inputFilter="[all[tiddlers]]"/> <$transclude $variable="inspect-filter" filter="[tags[]prefix[$:/]] :sort[length[]add[1]] +[first[2]tagging[]]" inputFilter="[all[tiddlers]]"/>
"""/> """/>
<$macrocall $name=".example" n="2" eg=""" <$macrocall $name=".example" n="2" eg="""

View File

@ -3591,6 +3591,7 @@ span.tc-translink > a:first-child {
.tc-inspect-filter-box.tc-inspect-filter-box-horizontal > .tc-box > .tc-box-content, .tc-inspect-filter-box.tc-inspect-filter-box-horizontal > .tc-box > .tc-box-content,
.tc-inspect-filter-box.tc-inspect-filter-box-horizontal .tc-inspect-run-box > .tc-box-content, .tc-inspect-filter-box.tc-inspect-filter-box-horizontal .tc-inspect-run-box > .tc-box-content,
.tc-inspect-filter-box.tc-inspect-filter-box-horizontal .tc-inspect-operation-box > .tc-box-content,
.tc-inspect-filter-box.tc-inspect-filter-box-horizontal .tc-inspect-operator-box > .tc-box-content { .tc-inspect-filter-box.tc-inspect-filter-box-horizontal .tc-inspect-operator-box > .tc-box-content {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -3598,11 +3599,23 @@ span.tc-translink > a:first-child {
align-items: flex-start; align-items: flex-start;
} }
.tc-inspect-operations-wrapper {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
}
.tc-inspect-run-box { .tc-inspect-run-box {
--box-background-color: #ffc; --box-background-color: #ffc;
--box-foreground-color: #440; --box-foreground-color: #440;
} }
.tc-inspect-operation-box {
--box-background-color: #cfc;
--box-foreground-color: #040;
}
.tc-inspect-operator-box { .tc-inspect-operator-box {
--box-background-color: #fcc; --box-background-color: #fcc;
--box-foreground-color: #400; --box-foreground-color: #400;