Support for macro params in filter operands (#5836)

* Exploratory pass at adding support for macro params in filter operands

* whitspace correction

* rename varInfo to varTree for disambiguation

* Refactored parseMacroInvocation to be re-usable, performance improvements for variables with no params and tests

* Revised regular expression and removed spurious white space changes

* Revised regular expression and removed spurious white space changes

* More whitespace cleanup and added more tests for edge cases

* Added test for macro params with square brackets
new-json-store-area
Saq Imtiaz 2021-06-29 23:21:39 +02:00 zatwierdzone przez GitHub
rodzic 70e60cd93f
commit 041c3e817c
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
3 zmienionych plików z 76 dodań i 9 usunięć

Wyświetl plik

@ -253,7 +253,8 @@ exports.compileFilter = function(filterString) {
if(operand.indirect) {
operand.value = self.getTextReference(operand.text,"",currTiddlerTitle);
} else if(operand.variable) {
operand.value = widget.getVariable(operand.text,{defaultValue: ""});
var varTree = $tw.utils.parseFilterVariable(operand.text);
operand.value = widget.getVariable(varTree.name,{params:varTree.params,defaultValue: ""});
} else {
operand.value = operand.text;
}

Wyświetl plik

@ -123,6 +123,19 @@ exports.parseStringLiteral = function(source,pos) {
}
};
exports.parseMacroParameters = function(node,source,pos) {
// Process parameters
var parameter = $tw.utils.parseMacroParameter(source,pos);
while(parameter) {
node.params.push(parameter);
pos = parameter.end;
// Get the next parameter
parameter = $tw.utils.parseMacroParameter(source,pos);
}
node.end = pos;
return node;
}
/*
Look for a macro invocation parameter. Returns null if not found, or {type: "macro-parameter", name:, value:, start:, end:}
*/
@ -187,14 +200,8 @@ exports.parseMacroInvocation = function(source,pos) {
}
node.name = name.match[1];
pos = name.end;
// Process parameters
var parameter = $tw.utils.parseMacroParameter(source,pos);
while(parameter) {
node.params.push(parameter);
pos = parameter.end;
// Get the next parameter
parameter = $tw.utils.parseMacroParameter(source,pos);
}
node = $tw.utils.parseMacroParameters(node,source,pos);
pos = node.end;
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
// Look for a double greater than sign
@ -208,6 +215,29 @@ exports.parseMacroInvocation = function(source,pos) {
return node;
};
exports.parseFilterVariable = function(source) {
var node = {
name: "",
params: [],
},
pos = 0,
reName = /([^\s"']+)/g;
// If there is no whitespace or it is an empty string then there are no macro parameters
if(/^\S*$/.test(source)) {
node.name = source;
return node;
}
// Get the variable name
var nameMatch = $tw.utils.parseTokenRegExp(source,pos,reName);
if(nameMatch) {
node.name = nameMatch.match[1];
pos = nameMatch.end;
node = $tw.utils.parseMacroParameters(node,source,pos);
delete node.end;
}
return node;
};
/*
Look for an HTML attribute definition. Returns null if not found, otherwise returns {type: "attribute", name:, valueType: "string|indirect|macro", value:, start:, end:,}
*/

Wyświetl plik

@ -825,6 +825,42 @@ function runTests(wiki) {
expect(wiki.filterTiddlers("[charcode[]]").join(" ")).toBe("");
});
it("should parse filter variable parameters", function(){
expect($tw.utils.parseFilterVariable("currentTiddler")).toEqual(
{ name: 'currentTiddler', params: [ ] }
);
expect($tw.utils.parseFilterVariable("now DDMM")).toEqual(
{ name: 'now', params: [{ type: 'macro-parameter', start: 3, value: 'DDMM', end: 8 }] }
);
expect($tw.utils.parseFilterVariable("now DDMM UTC")).toEqual(
{ name: 'now', params: [{ type: 'macro-parameter', start: 3, value: 'DDMM', end: 8 }, { type: 'macro-parameter', start: 8, value: 'UTC', end: 12 }] }
);
expect($tw.utils.parseFilterVariable("now format:DDMM")).toEqual(
{ name: 'now', params: [{ type: 'macro-parameter', name:'format', start: 3, value: 'DDMM', end: 15 }] }
);
expect($tw.utils.parseFilterVariable("now format:'DDMM'")).toEqual(
{ name: 'now', params: [{ type: 'macro-parameter', name:'format', start: 3, value: 'DDMM', end: 17 }] }
);
expect($tw.utils.parseFilterVariable("nowformat:'DDMM'")).toEqual(
{ name: 'nowformat:\'DDMM\'', params: [] }
);
expect($tw.utils.parseFilterVariable("nowformat:'DD MM'")).toEqual(
{ name: 'nowformat:', params: [{ type: 'macro-parameter', start: 10, value: 'DD MM', end: 17 }] }
);
expect($tw.utils.parseFilterVariable("now [UTC]YYYY0MM0DD0hh0mm0ssXXX")).toEqual(
{ name: 'now', params: [{ type: 'macro-parameter', start: 3, value: '[UTC]YYYY0MM0DD0hh0mm0ssXXX', end: 31 }] }
);
expect($tw.utils.parseFilterVariable("now '[UTC]YYYY0MM0DD0hh0mm0ssXXX'")).toEqual(
{ name: 'now', params: [{ type: 'macro-parameter', start: 3, value: '[UTC]YYYY0MM0DD0hh0mm0ssXXX', end: 33 }] }
);
expect($tw.utils.parseFilterVariable("now format:'[UTC]YYYY0MM0DD0hh0mm0ssXXX'")).toEqual(
{ name: 'now', params: [{ type: 'macro-parameter', start: 3, name:'format', value: '[UTC]YYYY0MM0DD0hh0mm0ssXXX', end: 40 }] }
);
expect($tw.utils.parseFilterVariable("")).toEqual(
{ name: '', params: [] }
);
});
}
});