mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-09-09 06:16:06 +00:00
Refactored wikitext parser to deal better with terminated blocks
This commit is contained in:
@@ -16,7 +16,6 @@ exports.info = {
|
|||||||
name: "button",
|
name: "button",
|
||||||
params: {
|
params: {
|
||||||
name: {byName: "default", type: "text"},
|
name: {byName: "default", type: "text"},
|
||||||
label: {byName: true, type: "text"},
|
|
||||||
"class": {byName: true, type: "text"}
|
"class": {byName: true, type: "text"}
|
||||||
},
|
},
|
||||||
events: ["click"]
|
events: ["click"]
|
||||||
@@ -43,7 +42,10 @@ exports.executeMacro = function() {
|
|||||||
if(this.classes) {
|
if(this.classes) {
|
||||||
$tw.utils.pushTop(attributes["class"],this.classes);
|
$tw.utils.pushTop(attributes["class"],this.classes);
|
||||||
}
|
}
|
||||||
return $tw.Tree.Element("button",attributes,[$tw.Tree.Text(this.params.label)]);
|
for(var t=0; t<this.content.length; t++) {
|
||||||
|
this.content[t].execute(this.parents,this.tiddlerTitle);
|
||||||
|
}
|
||||||
|
return $tw.Tree.Element("button",attributes,this.content);
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
@@ -23,13 +23,11 @@ var WikiTextRenderer = function(text,options) {
|
|||||||
this.parser = options.parser;
|
this.parser = options.parser;
|
||||||
this.tree = [];
|
this.tree = [];
|
||||||
this.dependencies = new $tw.Dependencies();
|
this.dependencies = new $tw.Dependencies();
|
||||||
|
// Parse the text into runs or blocks
|
||||||
if(options.isRun) {
|
if(options.isRun) {
|
||||||
this.tree.push.apply(this.tree,this.parseRun(null));
|
this.tree.push.apply(this.tree,this.parseRun());
|
||||||
} else {
|
} else {
|
||||||
// Parse the text into blocks
|
this.tree.push.apply(this.tree,this.parseBlocks());
|
||||||
while(this.pos < this.sourceLength) {
|
|
||||||
this.tree.push.apply(this.tree,this.parseBlock());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -41,9 +39,14 @@ WikiTextRenderer.prototype = new Renderer();
|
|||||||
WikiTextRenderer.constructor = WikiTextRenderer;
|
WikiTextRenderer.constructor = WikiTextRenderer;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Parse a block of text at the current position
|
Parse a block from the current position
|
||||||
|
terminatorRegExpString: optional regular expression string that identifies the end of plain paragraphs. Must not include capturing parenthesis
|
||||||
|
options: see below
|
||||||
|
Options are:
|
||||||
|
leaveTerminator: True if the terminator shouldn't be consumed
|
||||||
*/
|
*/
|
||||||
WikiTextRenderer.prototype.parseBlock = function() {
|
WikiTextRenderer.prototype.parseBlock = function(terminatorRegExpString,options) {
|
||||||
|
var terminatorRegExp = terminatorRegExpString ? new RegExp("(" + terminatorRegExpString + "|\\r?\\n\\r?\\n)","mg") : /(\r?\n\r?\n)/mg;
|
||||||
this.skipWhitespace();
|
this.skipWhitespace();
|
||||||
if(this.pos >= this.sourceLength) {
|
if(this.pos >= this.sourceLength) {
|
||||||
return [];
|
return [];
|
||||||
@@ -61,17 +64,44 @@ WikiTextRenderer.prototype.parseBlock = function() {
|
|||||||
return rule ? rule.parse.call(this,match,true) : [];
|
return rule ? rule.parse.call(this,match,true) : [];
|
||||||
} else {
|
} else {
|
||||||
// Treat it as a paragraph if we didn't find a block rule
|
// Treat it as a paragraph if we didn't find a block rule
|
||||||
return [$tw.Tree.Element("p",{},this.parseRun())];
|
return [$tw.Tree.Element("p",{},this.parseRun(terminatorRegExp,options))];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Parse blocks of text until a terminating regexp is encountered
|
Parse blocks of text until a terminating regexp is encountered or the end of the text
|
||||||
terminatorRegExp: terminating regular expression
|
terminatorRegExpString: terminating regular expression
|
||||||
|
options: see below
|
||||||
|
|
||||||
|
Options are:
|
||||||
addClass: optional CSS class to add to each block
|
addClass: optional CSS class to add to each block
|
||||||
*/
|
*/
|
||||||
WikiTextRenderer.prototype.parseBlockTerminated = function(terminatorRegExp,className) {
|
WikiTextRenderer.prototype.parseBlocks = function(terminatorRegExpString,options) {
|
||||||
|
if(terminatorRegExpString) {
|
||||||
|
return this.parseBlocksTerminated(terminatorRegExpString,options);
|
||||||
|
} else {
|
||||||
|
return this.parseBlocksUnterminated(options);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parse a block from the current position to the end of the text
|
||||||
|
*/
|
||||||
|
WikiTextRenderer.prototype.parseBlocksUnterminated = function(options) {
|
||||||
var tree = [];
|
var tree = [];
|
||||||
|
while(this.pos < this.sourceLength) {
|
||||||
|
tree.push.apply(tree,this.parseBlock());
|
||||||
|
}
|
||||||
|
return tree;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parse blocks of text until a terminating regexp is encountered. See parseBlocks() for details
|
||||||
|
*/
|
||||||
|
WikiTextRenderer.prototype.parseBlocksTerminated = function(terminatorRegExpString,options) {
|
||||||
|
options = options || {};
|
||||||
|
var terminatorRegExp = new RegExp("(" + terminatorRegExpString + ")","mg"),
|
||||||
|
tree = [];
|
||||||
// Skip any whitespace
|
// Skip any whitespace
|
||||||
this.skipWhitespace();
|
this.skipWhitespace();
|
||||||
// Check if we've got the end marker
|
// Check if we've got the end marker
|
||||||
@@ -79,10 +109,10 @@ WikiTextRenderer.prototype.parseBlockTerminated = function(terminatorRegExp,clas
|
|||||||
var match = terminatorRegExp.exec(this.source);
|
var match = terminatorRegExp.exec(this.source);
|
||||||
// Parse the text into blocks
|
// Parse the text into blocks
|
||||||
while(this.pos < this.sourceLength && !(match && match.index === this.pos)) {
|
while(this.pos < this.sourceLength && !(match && match.index === this.pos)) {
|
||||||
var blocks = this.parseBlock();
|
var blocks = this.parseBlock(terminatorRegExpString,{leaveTerminator: true});
|
||||||
for(var t=0; t<blocks.length; t++) {
|
for(var t=0; t<blocks.length; t++) {
|
||||||
if(className) {
|
if(options.addClass) {
|
||||||
blocks[t].addClass(className);
|
blocks[t].addClass(options.addClass);
|
||||||
}
|
}
|
||||||
tree.push(blocks[t]);
|
tree.push(blocks[t]);
|
||||||
}
|
}
|
||||||
@@ -117,10 +147,10 @@ Options are:
|
|||||||
Returns an array of tree nodes
|
Returns an array of tree nodes
|
||||||
*/
|
*/
|
||||||
WikiTextRenderer.prototype.parseRun = function(terminatorRegExp,options) {
|
WikiTextRenderer.prototype.parseRun = function(terminatorRegExp,options) {
|
||||||
if(terminatorRegExp === null) {
|
if(terminatorRegExp) {
|
||||||
return this.parseRunUnterminated(options);
|
|
||||||
} else {
|
|
||||||
return this.parseRunTerminated(terminatorRegExp,options);
|
return this.parseRunTerminated(terminatorRegExp,options);
|
||||||
|
} else {
|
||||||
|
return this.parseRunUnterminated(options);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -163,7 +193,6 @@ WikiTextRenderer.prototype.parseRunTerminated = function(terminatorRegExp,option
|
|||||||
options = options || {};
|
options = options || {};
|
||||||
var tree = [];
|
var tree = [];
|
||||||
// Find the next occurrence of the terminator
|
// Find the next occurrence of the terminator
|
||||||
terminatorRegExp = terminatorRegExp || /(\r?\n\r?\n)/mg;
|
|
||||||
terminatorRegExp.lastIndex = this.pos;
|
terminatorRegExp.lastIndex = this.pos;
|
||||||
var terminatorMatch = terminatorRegExp.exec(this.source);
|
var terminatorMatch = terminatorRegExp.exec(this.source);
|
||||||
// Find the next occurrence of a runrule
|
// Find the next occurrence of a runrule
|
||||||
|
@@ -33,13 +33,13 @@ exports.regExpString = "\\{\\{(?:[^\\{\\r\\n]+)\\{$\\r?\\n";
|
|||||||
exports.parse = function(match,isBlock) {
|
exports.parse = function(match,isBlock) {
|
||||||
var tree = [],
|
var tree = [],
|
||||||
reStart = /\{\{([^\{\r\n]+){\r?\n/mg,
|
reStart = /\{\{([^\{\r\n]+){\r?\n/mg,
|
||||||
reEnd = /(\}\}\}$(?:\r?\n)?)/mg,
|
reEndString = "(\\}\\}\\}$(?:\\r?\\n)?)",
|
||||||
endMatch;
|
endMatch;
|
||||||
reStart.lastIndex = this.pos;
|
reStart.lastIndex = this.pos;
|
||||||
match = reStart.exec(this.source);
|
match = reStart.exec(this.source);
|
||||||
if(match) {
|
if(match) {
|
||||||
this.pos = match.index + match[0].length;
|
this.pos = match.index + match[0].length;
|
||||||
tree = this.parseBlockTerminated(reEnd,match[1]);
|
tree = this.parseBlocks(reEndString,{addClass: match[1]});
|
||||||
}
|
}
|
||||||
return tree;
|
return tree;
|
||||||
};
|
};
|
||||||
|
@@ -49,10 +49,11 @@ exports.parse = function(match,isBlock) {
|
|||||||
attrMatch = reAttr.exec(startMatch[2]);
|
attrMatch = reAttr.exec(startMatch[2]);
|
||||||
}
|
}
|
||||||
this.pos = startMatch.index + startMatch[0].length;
|
this.pos = startMatch.index + startMatch[0].length;
|
||||||
var reEnd = new RegExp("(</" + startMatch[1] + ">)","mg"),
|
var reEndString = "(</" + startMatch[1] + ">)",
|
||||||
|
reEnd = new RegExp(reEndString,"mg"),
|
||||||
content;
|
content;
|
||||||
if(isBlock) {
|
if(isBlock) {
|
||||||
content = this.parseBlockTerminated(reEnd);
|
content = this.parseBlocks(reEndString);
|
||||||
} else {
|
} else {
|
||||||
content = this.parseRun(reEnd);
|
content = this.parseRun(reEnd);
|
||||||
}
|
}
|
||||||
|
@@ -37,7 +37,7 @@ exports.parse = function(match,isBlock) {
|
|||||||
if(match[5]) {
|
if(match[5]) {
|
||||||
// If the macro has content then parse it as a block or run
|
// If the macro has content then parse it as a block or run
|
||||||
if(isBlock) {
|
if(isBlock) {
|
||||||
content = this.parseBlockTerminated(/(^>>$)/mg);
|
content = this.parseBlocks(">>");
|
||||||
} else {
|
} else {
|
||||||
content = this.parseRun(/(>>)/mg);
|
content = this.parseRun(/(>>)/mg);
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
title: $:/templates/EditTemplate
|
title: $:/templates/EditTemplate
|
||||||
modifier: JeremyRuston
|
modifier: JeremyRuston
|
||||||
|
|
||||||
<<view title>> <<button SaveTiddler label:"done" class:"btn btn-mini btn-success">>
|
<<view title>> <<button SaveTiddler class:"btn btn-mini btn-success"><Done>>
|
||||||
{{title{
|
{{title{
|
||||||
<<edit draft.title>>
|
<<edit draft.title>>
|
||||||
}}}
|
}}}
|
||||||
|
@@ -2,7 +2,7 @@ title: $:/templates/ViewTemplate
|
|||||||
modifier: JeremyRuston
|
modifier: JeremyRuston
|
||||||
|
|
||||||
{{title{
|
{{title{
|
||||||
<div><span><<view title>></span><<button EditTiddler label:"edit" class:"btn btn-mini btn-primary">></div>
|
<div><span><<view title>></span><<button EditTiddler class:"btn btn-mini btn-primary"><Edit>></div>
|
||||||
}}}
|
}}}
|
||||||
{{small{
|
{{small{
|
||||||
<div><<view modifier link>> <<view modified date>> <<view tags>> </div>
|
<div><<view modifier link>> <<view modified date>> <<view tags>> </div>
|
||||||
|
Reference in New Issue
Block a user