mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-07-02 18:12:57 +00:00

I switched this optimisation off back in ed35d91be6c6e188c80bc0994fa83acd7526d225, in October 2013, as part of a big refactoring of the parsing and widget mechanism. I’ve been meaning to switch it back on for some time. My rough measurements suggest that this optimisation can reduce rendering time by 5-10%.
92 lines
2.3 KiB
JavaScript
92 lines
2.3 KiB
JavaScript
/*\
|
|
title: $:/core/modules/parsers/wikiparser/rules/macrodef.js
|
|
type: application/javascript
|
|
module-type: wikirule
|
|
|
|
Wiki pragma rule for macro definitions
|
|
|
|
```
|
|
\define name(param:defaultvalue,param2:defaultvalue)
|
|
definition text, including $param$ markers
|
|
\end
|
|
```
|
|
|
|
\*/
|
|
(function(){
|
|
|
|
/*jslint node: true, browser: true */
|
|
/*global $tw: false */
|
|
"use strict";
|
|
|
|
exports.name = "macrodef";
|
|
exports.types = {pragma: true};
|
|
|
|
/*
|
|
Instantiate parse rule
|
|
*/
|
|
exports.init = function(parser) {
|
|
this.parser = parser;
|
|
// Regexp to match
|
|
this.matchRegExp = /^\\define\s+([^(\s]+)\(\s*([^)]*)\)(\s*\r?\n)?/mg;
|
|
};
|
|
|
|
/*
|
|
Parse the most recent match
|
|
*/
|
|
exports.parse = function() {
|
|
// Move past the macro name and parameters
|
|
this.parser.pos = this.matchRegExp.lastIndex;
|
|
// Parse the parameters
|
|
var paramString = this.match[2],
|
|
params = [];
|
|
if(paramString !== "") {
|
|
var reParam = /\s*([A-Za-z0-9\-_]+)(?:\s*:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|\[\[([^\]]*)\]\]|([^"'\s]+)))?/mg,
|
|
paramMatch = reParam.exec(paramString);
|
|
while(paramMatch) {
|
|
// Save the parameter details
|
|
var paramInfo = {name: paramMatch[1]},
|
|
defaultValue = paramMatch[2] || paramMatch[3] || paramMatch[4] || paramMatch[5] || paramMatch[6];
|
|
if(defaultValue) {
|
|
paramInfo["default"] = defaultValue;
|
|
}
|
|
params.push(paramInfo);
|
|
// Look for the next parameter
|
|
paramMatch = reParam.exec(paramString);
|
|
}
|
|
}
|
|
// Is this a multiline definition?
|
|
var reEnd;
|
|
if(this.match[3]) {
|
|
// If so, the end of the body is marked with \end
|
|
reEnd = /(\r?\n\\end[^\S\n\r]*(?:$|\r?\n))/mg;
|
|
} else {
|
|
// Otherwise, the end of the definition is marked by the end of the line
|
|
reEnd = /(\r?\n)/mg;
|
|
// Move past any whitespace
|
|
this.parser.pos = $tw.utils.skipWhiteSpace(this.parser.source,this.parser.pos);
|
|
}
|
|
// Find the end of the definition
|
|
reEnd.lastIndex = this.parser.pos;
|
|
var text,
|
|
endMatch = reEnd.exec(this.parser.source);
|
|
if(endMatch) {
|
|
text = this.parser.source.substring(this.parser.pos,endMatch.index);
|
|
this.parser.pos = endMatch.index + endMatch[0].length;
|
|
} else {
|
|
// We didn't find the end of the definition, so we'll make it blank
|
|
text = "";
|
|
}
|
|
// Save the macro definition
|
|
return [{
|
|
type: "set",
|
|
attributes: {
|
|
name: {type: "string", value: this.match[1]},
|
|
value: {type: "string", value: text}
|
|
},
|
|
children: [],
|
|
params: params
|
|
}];
|
|
};
|
|
|
|
})();
|