mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-06-03 15:14:07 +00:00
Switch to using \procedure to define new-style macros, and \function for custom filter operator functions
I now need to update the OP!
This commit is contained in:
parent
64448ae774
commit
e092113f9f
@ -20,7 +20,7 @@ Export our filter function
|
|||||||
exports.unknown = function(source,operator,options) {
|
exports.unknown = function(source,operator,options) {
|
||||||
var customDefinitionTitle = "[" + operator.operator + "[]]",
|
var customDefinitionTitle = "[" + operator.operator + "[]]",
|
||||||
customDefinition = options.widget && options.widget.getVariableInfo && options.widget.getVariableInfo(customDefinitionTitle);
|
customDefinition = options.widget && options.widget.getVariableInfo && options.widget.getVariableInfo(customDefinitionTitle);
|
||||||
if(customDefinition && customDefinition.srcVariable) {
|
if(customDefinition && customDefinition.srcVariable && customDefinition.srcVariable.isFunctionDefinition) {
|
||||||
var variables = Object.create(null);
|
var variables = Object.create(null);
|
||||||
$tw.utils.each(customDefinition.srcVariable.params,function(param,index) {
|
$tw.utils.each(customDefinition.srcVariable.params,function(param,index) {
|
||||||
var value = operator.operands[index];
|
var value = operator.operands[index];
|
||||||
@ -37,7 +37,13 @@ exports.unknown = function(source,operator,options) {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
var getVariableInfo = function(name,opts) {
|
var getVariableInfo = function(name,opts) {
|
||||||
return options.widget.getVariableInfo(name,opts);
|
if(name in variables) {
|
||||||
|
return {
|
||||||
|
text: variables[name]
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return options.widget.getVariableInfo(name,opts);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
var list = options.wiki.filterTiddlers(customDefinition.srcVariable.value,{getVariable: getVariable,getVariableInfo: getVariableInfo},source);
|
var list = options.wiki.filterTiddlers(customDefinition.srcVariable.value,{getVariable: getVariable,getVariableInfo: getVariableInfo},source);
|
||||||
if(operator.prefix === "!") {
|
if(operator.prefix === "!") {
|
||||||
|
@ -1,14 +1,18 @@
|
|||||||
/*\
|
/*\
|
||||||
title: $:/core/modules/parsers/wikiparser/rules/functiondef.js
|
title: $:/core/modules/parsers/wikiparser/rules/fnprocdef.js
|
||||||
type: application/javascript
|
type: application/javascript
|
||||||
module-type: wikirule
|
module-type: wikirule
|
||||||
|
|
||||||
Wiki pragma rule for function definitions
|
Wiki pragma rule for function and procedure definitions
|
||||||
|
|
||||||
```
|
```
|
||||||
\function name(param:defaultvalue,param2:defaultvalue)
|
\function name(param:defaultvalue,param2:defaultvalue)
|
||||||
definition text
|
definition text
|
||||||
\end
|
\end
|
||||||
|
|
||||||
|
\procedure name(param:defaultvalue,param2:defaultvalue)
|
||||||
|
definition text
|
||||||
|
\end
|
||||||
```
|
```
|
||||||
|
|
||||||
\*/
|
\*/
|
||||||
@ -18,7 +22,7 @@ definition text
|
|||||||
/*global $tw: false */
|
/*global $tw: false */
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
exports.name = "functiondef";
|
exports.name = "fnprocdef";
|
||||||
exports.types = {pragma: true};
|
exports.types = {pragma: true};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -27,7 +31,7 @@ Instantiate parse rule
|
|||||||
exports.init = function(parser) {
|
exports.init = function(parser) {
|
||||||
this.parser = parser;
|
this.parser = parser;
|
||||||
// Regexp to match
|
// Regexp to match
|
||||||
this.matchRegExp = /^\\function\s+([^(\s]+)(\(\s*([^)]*)\))?(\s*\r?\n)?/mg;
|
this.matchRegExp = /^\\(function|procedure)\s+([^(\s]+)(\(\s*([^)]*)\))?(\s*\r?\n)?/mg;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -37,9 +41,9 @@ exports.parse = function() {
|
|||||||
// Move past the macro name and parameters
|
// Move past the macro name and parameters
|
||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
// Parse the parameters
|
// Parse the parameters
|
||||||
var paramString = this.match[3],
|
var paramString = this.match[4],
|
||||||
params = [];
|
params = [];
|
||||||
if(this.match[2]) {
|
if(this.match[3]) {
|
||||||
var reParam = /\s*([^:),\s]+)(?:\s*:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|([^,"'\s]+)))?/mg,
|
var reParam = /\s*([^:),\s]+)(?:\s*:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|([^,"'\s]+)))?/mg,
|
||||||
paramMatch = reParam.exec(paramString);
|
paramMatch = reParam.exec(paramString);
|
||||||
while(paramMatch) {
|
while(paramMatch) {
|
||||||
@ -56,7 +60,7 @@ exports.parse = function() {
|
|||||||
}
|
}
|
||||||
// Is this a multiline definition?
|
// Is this a multiline definition?
|
||||||
var reEnd;
|
var reEnd;
|
||||||
if(this.match[4]) {
|
if(this.match[5]) {
|
||||||
// If so, the end of the body is marked with \end
|
// If so, the end of the body is marked with \end
|
||||||
reEnd = /(\r?\n\\end[^\S\n\r]*(?:$|\r?\n))/mg;
|
reEnd = /(\r?\n\\end[^\S\n\r]*(?:$|\r?\n))/mg;
|
||||||
} else {
|
} else {
|
||||||
@ -77,16 +81,21 @@ exports.parse = function() {
|
|||||||
text = "";
|
text = "";
|
||||||
}
|
}
|
||||||
// Save the macro definition
|
// Save the macro definition
|
||||||
return [{
|
var parseTreeNodes = [{
|
||||||
type: "set",
|
type: "set",
|
||||||
attributes: {
|
attributes: {
|
||||||
name: {type: "string", value: this.match[1]},
|
name: {type: "string", value: this.match[2]},
|
||||||
value: {type: "string", value: text}
|
value: {type: "string", value: text}
|
||||||
},
|
},
|
||||||
children: [],
|
children: [],
|
||||||
params: params,
|
params: params
|
||||||
isFunctionDefinition: true
|
|
||||||
}];
|
}];
|
||||||
|
if(this.match[1] === "function") {
|
||||||
|
parseTreeNodes[0].isFunctionDefinition = true;
|
||||||
|
} else if(this.match[1] === "procedure") {
|
||||||
|
parseTreeNodes[0].isProcedureDefinition = true;
|
||||||
|
}
|
||||||
|
return parseTreeNodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
@ -56,9 +56,10 @@ ImportVariablesWidget.prototype.execute = function(tiddlerList) {
|
|||||||
attributes: parseTreeNode.attributes,
|
attributes: parseTreeNode.attributes,
|
||||||
params: parseTreeNode.params,
|
params: parseTreeNode.params,
|
||||||
isMacroDefinition: parseTreeNode.isMacroDefinition,
|
isMacroDefinition: parseTreeNode.isMacroDefinition,
|
||||||
isFunctionDefinition: parseTreeNode.isFunctionDefinition
|
isFunctionDefinition: parseTreeNode.isFunctionDefinition,
|
||||||
|
isProcedureDefinition: parseTreeNode.isProcedureDefinition
|
||||||
};
|
};
|
||||||
if (parseTreeNode.isMacroDefinition || parseTreeNode.isFunctionDefinition) {
|
if (parseTreeNode.isMacroDefinition || parseTreeNode.isProcedureDefinition) {
|
||||||
// Macro definitions can be folded into
|
// Macro definitions can be folded into
|
||||||
// current widget instead of adding
|
// current widget instead of adding
|
||||||
// another link to the chain.
|
// another link to the chain.
|
||||||
|
@ -49,9 +49,11 @@ SetWidget.prototype.execute = function() {
|
|||||||
this.setEmptyValue = this.getAttribute("emptyValue");
|
this.setEmptyValue = this.getAttribute("emptyValue");
|
||||||
// Set context variable
|
// Set context variable
|
||||||
if(this.parseTreeNode.isMacroDefinition) {
|
if(this.parseTreeNode.isMacroDefinition) {
|
||||||
this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,!!this.parseTreeNode.isMacroDefinition);
|
this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,true);
|
||||||
} else if(this.parseTreeNode.isFunctionDefinition) {
|
} else if(this.parseTreeNode.isFunctionDefinition) {
|
||||||
this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,undefined,{isFunctionDefinition: this.parseTreeNode.isFunctionDefinition});
|
this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,undefined,{isFunctionDefinition: true});
|
||||||
|
} else if(this.parseTreeNode.isProcedureDefinition) {
|
||||||
|
this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,undefined,{isProcedureDefinition: true});
|
||||||
} else {
|
} else {
|
||||||
this.setVariable(this.setName,this.getValue());
|
this.setVariable(this.setName,this.getValue());
|
||||||
}
|
}
|
||||||
|
@ -197,8 +197,8 @@ TranscludeWidget.prototype.getTransclusionTarget = function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(parser) {
|
if(parser) {
|
||||||
// Add parameters widget for functions
|
// Add parameters widget for procedures
|
||||||
if(srcVariable.isFunctionDefinition) {
|
if(srcVariable.isProcedureDefinition) {
|
||||||
parser = {
|
parser = {
|
||||||
tree: [
|
tree: [
|
||||||
{
|
{
|
||||||
|
@ -89,6 +89,7 @@ value: value of the variable
|
|||||||
params: array of {name:, default:} for each parameter
|
params: array of {name:, default:} for each parameter
|
||||||
isMacroDefinition: true if the variable is set via a \define macro pragma (and hence should have variable substitution performed)
|
isMacroDefinition: true if the variable is set via a \define macro pragma (and hence should have variable substitution performed)
|
||||||
options includes:
|
options includes:
|
||||||
|
isProcedureDefinition: true if the variable is set via a \procedure pragma (and hence should not have variable substitution performed)
|
||||||
isFunctionDefinition: true if the variable is set via a \function pragma (and hence should not have variable substitution performed)
|
isFunctionDefinition: true if the variable is set via a \function pragma (and hence should not have variable substitution performed)
|
||||||
*/
|
*/
|
||||||
Widget.prototype.setVariable = function(name,value,params,isMacroDefinition,options) {
|
Widget.prototype.setVariable = function(name,value,params,isMacroDefinition,options) {
|
||||||
@ -97,7 +98,8 @@ Widget.prototype.setVariable = function(name,value,params,isMacroDefinition,opti
|
|||||||
value: value,
|
value: value,
|
||||||
params: params,
|
params: params,
|
||||||
isMacroDefinition: !!isMacroDefinition,
|
isMacroDefinition: !!isMacroDefinition,
|
||||||
isFunctionDefinition: !!options.isFunctionDefinition
|
isFunctionDefinition: !!options.isFunctionDefinition,
|
||||||
|
isProcedureDefinition: !!options.isProcedureDefinition
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ tags: [[$:/tags/wiki-test-spec]]
|
|||||||
title: Output
|
title: Output
|
||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
\function <$let>
|
\procedure <$let>
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$setmultiplevariables $names="[enlist:raw<paramNames>]" $values="[enlist:raw<paramValues>addprefix[--]addsuffix[--]]">
|
<$setmultiplevariables $names="[enlist:raw<paramNames>]" $values="[enlist:raw<paramValues>addprefix[--]addsuffix[--]]">
|
||||||
<$slot $name="ts-body"/>
|
<$slot $name="ts-body"/>
|
||||||
|
@ -13,7 +13,7 @@ title: Actions
|
|||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<!-- Define the <$action-mywidget> widget by defining a transcludable variable with that name -->
|
<!-- Define the <$action-mywidget> widget by defining a transcludable variable with that name -->
|
||||||
\function <$action-mywidget>(one:'Jaguar')
|
\procedure <$action-mywidget>(one:'Jaguar')
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$action-setfield $tiddler="Result" $field="text" $value=<<one>>/>
|
<$action-setfield $tiddler="Result" $field="text" $value=<<one>>/>
|
||||||
\end
|
\end
|
||||||
|
@ -16,7 +16,7 @@ title: Output
|
|||||||
title: Definition
|
title: Definition
|
||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
\function <$codeblock>(code)
|
\procedure <$codeblock>(code)
|
||||||
<$genesis $type="codeblock" $remappable="no" code={{{ [<code>addprefix[£]addsuffix[@]] }}}/>
|
<$genesis $type="codeblock" $remappable="no" code={{{ [<code>addprefix[£]addsuffix[@]] }}}/>
|
||||||
\end
|
\end
|
||||||
+
|
+
|
||||||
|
@ -17,7 +17,7 @@ title: TiddlerOne
|
|||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<!-- Redefine the <$transclude> widget by defining a transcludable variable with that name -->
|
<!-- Redefine the <$transclude> widget by defining a transcludable variable with that name -->
|
||||||
\function <$transclude>(one:'Jaguar')
|
\procedure <$transclude>(one:'Jaguar')
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$text text=<<one>>/>
|
<$text text=<<one>>/>
|
||||||
<$slot $name="body">
|
<$slot $name="body">
|
||||||
|
@ -13,7 +13,7 @@ title: TiddlerOne
|
|||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<!-- Define the <$mywidget> widget by defining a transcludable variable with that name -->
|
<!-- Define the <$mywidget> widget by defining a transcludable variable with that name -->
|
||||||
\function <$mywidget>(one:'Jaguar')
|
\procedure <$mywidget>(one:'Jaguar')
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$text text=<<one>>/>
|
<$text text=<<one>>/>
|
||||||
<$slot $name="ts-body">
|
<$slot $name="ts-body">
|
||||||
|
@ -13,7 +13,7 @@ title: TiddlerOne
|
|||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<!-- Redefine the <$text> widget by defining a transcludable variable with that name -->
|
<!-- Redefine the <$text> widget by defining a transcludable variable with that name -->
|
||||||
\function <$text>(text:'Jaguar')
|
\procedure <$text>(text:'Jaguar')
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$genesis $type="text" $remappable="no" text=<<text>>/>
|
<$genesis $type="text" $remappable="no" text=<<text>>/>
|
||||||
<$set name="<$text>" value="">
|
<$set name="<$text>" value="">
|
||||||
|
@ -13,7 +13,7 @@ title: TiddlerOne
|
|||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<!-- Redefine the <$mywidget> widget by defining a transcludable variable with that name -->
|
<!-- Redefine the <$mywidget> widget by defining a transcludable variable with that name -->
|
||||||
\function <$mywidget>($variable:'Jaguar')
|
\procedure <$mywidget>($variable:'Jaguar')
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$text text=<<$variable>>/>
|
<$text text=<<$variable>>/>
|
||||||
<$slot $name="ts-body">
|
<$slot $name="ts-body">
|
||||||
|
@ -6,7 +6,7 @@ tags: [[$:/tags/wiki-test-spec]]
|
|||||||
title: Output
|
title: Output
|
||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
\function test(one:'Jaguar')
|
\procedure test(one:'Jaguar')
|
||||||
{<$text text=<<one>>/>}
|
{<$text text=<<one>>/>}
|
||||||
\end
|
\end
|
||||||
|
|
||||||
|
@ -119,7 +119,38 @@ describe("WikiText parser tests", function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should parse function definitions with no parameters", function() {
|
it("should parse procedure definitions with no parameters", function() {
|
||||||
|
expect(parse("\\procedure myMacro\nnothing\n\\end\n")).toEqual(
|
||||||
|
|
||||||
|
[ { type : 'set', attributes : { name : { type : 'string', value : 'myMacro' }, value : { type : 'string', value : 'nothing' } }, children : [ ], params : [ ], isProcedureDefinition : true } ]
|
||||||
|
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse single line procedure definitions with no parameters", function() {
|
||||||
|
expect(parse("\\procedure myMacro nothing\n")).toEqual(
|
||||||
|
|
||||||
|
[ { type : 'set', attributes : { name : { type : 'string', value : 'myMacro' }, value : { type : 'string', value : 'nothing' } }, children : [ ], params : [ ], isProcedureDefinition : true } ]
|
||||||
|
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse procedure definitions with parameters", function() {
|
||||||
|
expect(parse("\\procedure myMacro(one,two,three,four:elephant)\nnothing\n\\end\n")).toEqual(
|
||||||
|
|
||||||
|
[ { type : 'set', attributes : { name : { type : 'string', value : 'myMacro' }, value : { type : 'string', value : 'nothing' } }, children : [ ], params : [ { name: 'one' }, { name: 'two' }, { name: 'three' }, { name: 'four', default: 'elephant' } ], isProcedureDefinition : true } ]
|
||||||
|
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse procedure definitions", function() {
|
||||||
|
expect(parse("\\procedure myMacro(one:'Jaguar')\n<$text text=<<one>>/>\n\\end\n\n")).toEqual(
|
||||||
|
|
||||||
|
[ { type : 'set', attributes : { name : { type : 'string', value : 'myMacro' }, value : { type : 'string', value : '<$text text=<<one>>/>' } }, children : [ ], params : [ { name: 'one', "default": 'Jaguar' } ], isProcedureDefinition : true } ]
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
}); it("should parse function definitions with no parameters", function() {
|
||||||
expect(parse("\\function myMacro\nnothing\n\\end\n")).toEqual(
|
expect(parse("\\function myMacro\nnothing\n\\end\n")).toEqual(
|
||||||
|
|
||||||
[ { type : 'set', attributes : { name : { type : 'string', value : 'myMacro' }, value : { type : 'string', value : 'nothing' } }, children : [ ], params : [ ], isFunctionDefinition : true } ]
|
[ { type : 'set', attributes : { name : { type : 'string', value : 'myMacro' }, value : { type : 'string', value : 'nothing' } }, children : [ ], params : [ ], isFunctionDefinition : true } ]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user