Add more start-end range attributes for AST

This commit is contained in:
Gk0Wk 2023-11-29 22:35:39 +08:00
parent d3e62ec56a
commit e2b9a4ed57
10 changed files with 72 additions and 24 deletions

View File

@ -31,6 +31,7 @@ exports.init = function(parser) {
exports.parse = function() { exports.parse = function() {
// Move past the match // Move past the match
var start = this.parser.pos;
this.parser.pos = this.matchRegExp.lastIndex; this.parser.pos = this.matchRegExp.lastIndex;
// Create the link unless it is suppressed // Create the link unless it is suppressed
if(this.match[0].substr(0,1) === "~") { if(this.match[0].substr(0,1) === "~") {
@ -46,7 +47,7 @@ exports.parse = function() {
rel: {type: "string", value: "noopener noreferrer"} rel: {type: "string", value: "noopener noreferrer"}
}, },
children: [{ children: [{
type: "text", text: this.match[0] type: "text", text: this.match[0], start: start, end: this.parser.pos
}] }]
}]; }];
} }

View File

@ -74,6 +74,7 @@ exports.parse = function() {
// Match the list marker // Match the list marker
var reMatch = /([\*#;:>]+)/mg; var reMatch = /([\*#;:>]+)/mg;
reMatch.lastIndex = this.parser.pos; reMatch.lastIndex = this.parser.pos;
var start = this.parser.pos;
var match = reMatch.exec(this.parser.source); var match = reMatch.exec(this.parser.source);
if(!match || match.index !== this.parser.pos) { if(!match || match.index !== this.parser.pos) {
break; break;
@ -94,9 +95,21 @@ exports.parse = function() {
} }
// Construct the list element or reuse the previous one at this level // Construct the list element or reuse the previous one at this level
if(listStack.length <= t) { if(listStack.length <= t) {
var listElement = {type: "element", tag: listInfo.listTag, children: [ var listElement = {
{type: "element", tag: listInfo.itemTag, children: []} type: "element",
]}; tag: listInfo.listTag,
children: [
{
type: "element",
tag: listInfo.itemTag,
children: [],
start: start,
end: this.parser.pos,
}
],
start: start,
end: this.parser.pos,
};
// Link this list element into the last child item of the parent list item // Link this list element into the last child item of the parent list item
if(t) { if(t) {
var prevListItem = listStack[t-1].children[listStack[t-1].children.length-1]; var prevListItem = listStack[t-1].children[listStack[t-1].children.length-1];
@ -105,7 +118,13 @@ exports.parse = function() {
// Save this element in the stack // Save this element in the stack
listStack[t] = listElement; listStack[t] = listElement;
} else if(t === (match[0].length - 1)) { } else if(t === (match[0].length - 1)) {
listStack[t].children.push({type: "element", tag: listInfo.itemTag, children: []}); listStack[t].children.push({
type: "element",
tag: listInfo.itemTag,
children: [],
start: start,
end: this.parser.pos,
});
} }
} }
if(listStack.length > match[0].length) { if(listStack.length > match[0].length) {
@ -118,6 +137,8 @@ exports.parse = function() {
this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true}); this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});
var tree = this.parser.parseInlineRun(/(\r?\n)/mg); var tree = this.parser.parseInlineRun(/(\r?\n)/mg);
lastListItem.children.push.apply(lastListItem.children,tree); lastListItem.children.push.apply(lastListItem.children,tree);
lastListItem.end = this.parser.pos;
listStack[listStack.length-1].end = this.parser.pos;
if(classes.length > 0) { if(classes.length > 0) {
$tw.utils.addClassToParseTreeNode(lastListItem,classes.join(" ")); $tw.utils.addClassToParseTreeNode(lastListItem,classes.join(" "));
} }

View File

@ -97,12 +97,15 @@ exports.parseLink = function(source,pos) {
} }
// Pull out the tooltip and URL // Pull out the tooltip and URL
var tooltip, URL; var tooltip, URL;
textNode.start = pos;
if(splitPos) { if(splitPos) {
URL = source.substring(splitPos + 1,closePos).trim(); URL = source.substring(splitPos + 1,closePos).trim();
textNode.text = source.substring(pos,splitPos).trim(); textNode.text = source.substring(pos,splitPos).trim();
textNode.end = splitPos;
} else { } else {
URL = source.substring(pos,closePos).trim(); URL = source.substring(pos,closePos).trim();
textNode.text = URL; textNode.text = URL;
textNode.end = closePos;
} }
node.attributes.href = {type: "string", value: URL}; node.attributes.href = {type: "string", value: URL};
node.attributes.target = {type: "string", value: "_blank"}; node.attributes.target = {type: "string", value: "_blank"};

View File

@ -29,10 +29,15 @@ exports.init = function(parser) {
exports.parse = function() { exports.parse = function() {
// Move past the match // Move past the match
var start = this.parser.pos;
this.parser.pos = this.matchRegExp.lastIndex; this.parser.pos = this.matchRegExp.lastIndex;
// Process the link // Process the link
var text = this.match[1], var text = this.match[1],
link = this.match[2] || text; link = this.match[2] || text,
textEndPos = this.parser.source.indexOf("|", start);
if (textEndPos < 0 || textEndPos > this.matchRegExp.lastIndex) {
textEndPos = this.matchRegExp.lastIndex - 2;
}
if($tw.utils.isLinkExternal(link)) { if($tw.utils.isLinkExternal(link)) {
return [{ return [{
type: "element", type: "element",
@ -44,7 +49,7 @@ exports.parse = function() {
rel: {type: "string", value: "noopener noreferrer"} rel: {type: "string", value: "noopener noreferrer"}
}, },
children: [{ children: [{
type: "text", text: text type: "text", text: text, start: start, end: textEndPos
}] }]
}]; }];
} else { } else {
@ -54,7 +59,7 @@ exports.parse = function() {
to: {type: "string", value: link} to: {type: "string", value: link}
}, },
children: [{ children: [{
type: "text", text: text type: "text", text: text, start: start, end: textEndPos
}] }]
}]; }];
} }

View File

@ -9,7 +9,7 @@ Wiki text rule for quote blocks. For example:
<<<.optionalClass(es) optional cited from <<<.optionalClass(es) optional cited from
a quote a quote
<<< <<<
<<<.optionalClass(es) <<<.optionalClass(es)
a quote a quote
<<< optional cited from <<< optional cited from
@ -20,11 +20,11 @@ Quotes can be quoted by putting more <s
``` ```
<<< <<<
Quote Level 1 Quote Level 1
<<<< <<<<
QuoteLevel 2 QuoteLevel 2
<<<< <<<<
<<< <<<
``` ```
@ -50,30 +50,38 @@ exports.parse = function() {
var reEndString = "^" + this.match[1] + "(?!<)"; var reEndString = "^" + this.match[1] + "(?!<)";
// Move past the <s // Move past the <s
this.parser.pos = this.matchRegExp.lastIndex; this.parser.pos = this.matchRegExp.lastIndex;
// Parse any classes, whitespace and then the optional cite itself // Parse any classes, whitespace and then the optional cite itself
classes.push.apply(classes, this.parser.parseClasses()); classes.push.apply(classes, this.parser.parseClasses());
this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true}); this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});
var citeStart = this.parser.pos;
var cite = this.parser.parseInlineRun(/(\r?\n)/mg); var cite = this.parser.parseInlineRun(/(\r?\n)/mg);
var citeEnd = this.parser.pos;
// before handling the cite, parse the body of the quote // before handling the cite, parse the body of the quote
var tree= this.parser.parseBlocks(reEndString); var tree = this.parser.parseBlocks(reEndString);
// If we got a cite, put it before the text // If we got a cite, put it before the text
if(cite.length > 0) { if(cite.length > 0) {
tree.unshift({ tree.unshift({
type: "element", type: "element",
tag: "cite", tag: "cite",
children: cite children: cite,
start: citeStart,
end: citeEnd
}); });
} }
// Parse any optional cite // Parse any optional cite
this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true}); this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});
citeStart = this.parser.pos;
cite = this.parser.parseInlineRun(/(\r?\n)/mg); cite = this.parser.parseInlineRun(/(\r?\n)/mg);
citeEnd = this.parser.pos;
// If we got a cite, push it // If we got a cite, push it
if(cite.length > 0) { if(cite.length > 0) {
tree.push({ tree.push({
type: "element", type: "element",
tag: "cite", tag: "cite",
children: cite children: cite,
start: citeStart,
end: citeEnd
}); });
} }
// Return the blockquote element // Return the blockquote element

View File

@ -29,10 +29,11 @@ exports.init = function(parser) {
exports.parse = function() { exports.parse = function() {
var match = this.match[0]; var match = this.match[0];
// Move past the match // Move past the match
var start = this.parser.pos;
this.parser.pos = this.matchRegExp.lastIndex; this.parser.pos = this.matchRegExp.lastIndex;
// Create the link unless it is suppressed // Create the link unless it is suppressed
if(match.substr(0,1) === "~") { if(match.substr(0,1) === "~") {
return [{type: "text", text: match.substr(1)}]; return [{type: "text", text: match.substr(1), start: start+1, end: this.parser.pos}];
} else { } else {
return [{ return [{
type: "link", type: "link",
@ -41,10 +42,12 @@ exports.parse = function() {
}, },
children: [{ children: [{
type: "text", type: "text",
text: match text: match,
start: start,
end: this.parser.pos
}] }]
}]; }];
} }
}; };
})(); })();

View File

@ -150,7 +150,7 @@ exports.parse = function() {
} else { } else {
// Otherwise, create a new row if this one is of a different type // Otherwise, create a new row if this one is of a different type
if(rowType !== currRowType) { if(rowType !== currRowType) {
rowContainer = {type: "element", tag: rowContainerTypes[rowType], children: []}; rowContainer = {type: "element", tag: rowContainerTypes[rowType], children: [], start: this.parser.pos, end: this.parser.pos};
table.children.push(rowContainer); table.children.push(rowContainer);
currRowType = rowType; currRowType = rowType;
} }
@ -178,6 +178,7 @@ exports.parse = function() {
// Increment the row count // Increment the row count
rowCount++; rowCount++;
} }
rowContainer.end = this.parser.pos;
} }
rowMatch = rowRegExp.exec(this.parser.source); rowMatch = rowRegExp.exec(this.parser.source);
} }

View File

@ -46,6 +46,7 @@ exports.parse = function() {
renderType = this.match[2]; renderType = this.match[2];
// Move past the match // Move past the match
this.parser.pos = this.matchRegExp.lastIndex; this.parser.pos = this.matchRegExp.lastIndex;
var start = this.parser.pos;
// Look for the end of the block // Look for the end of the block
reEnd.lastIndex = this.parser.pos; reEnd.lastIndex = this.parser.pos;
var match = reEnd.exec(this.parser.source), var match = reEnd.exec(this.parser.source),
@ -74,7 +75,9 @@ exports.parse = function() {
tag: "pre", tag: "pre",
children: [{ children: [{
type: "text", type: "text",
text: text text: text,
start: start,
end: this.parser.pos
}] }]
}]; }];
} }

View File

@ -36,6 +36,7 @@ exports.parse = function() {
// Get the details of the match // Get the details of the match
var linkText = this.match[0]; var linkText = this.match[0];
// Move past the macro call // Move past the macro call
var start = this.parser.pos;
this.parser.pos = this.matchRegExp.lastIndex; this.parser.pos = this.matchRegExp.lastIndex;
// If the link starts with the unwikilink character then just output it as plain text // If the link starts with the unwikilink character then just output it as plain text
if(linkText.substr(0,1) === $tw.config.textPrimitives.unWikiLink) { if(linkText.substr(0,1) === $tw.config.textPrimitives.unWikiLink) {
@ -57,7 +58,9 @@ exports.parse = function() {
}, },
children: [{ children: [{
type: "text", type: "text",
text: linkText text: linkText,
start: start,
end: this.parser.pos
}] }]
}]; }];
}; };

View File

@ -254,7 +254,7 @@ WikiParser.prototype.parseBlock = function(terminatorRegExpString) {
var start = this.pos; var start = this.pos;
var children = this.parseInlineRun(terminatorRegExp); var children = this.parseInlineRun(terminatorRegExp);
var end = this.pos; var end = this.pos;
return [{type: "element", tag: "p", children: children, start: start, end: end, parseRule: null }]; return [{type: "element", tag: "p", children: children, start: start, end: end, parseRule: undefined }];
}; };
/* /*
@ -354,7 +354,7 @@ WikiParser.prototype.parseInlineRunUnterminated = function(options) {
if (subTree[subTree.length - 1].end === undefined) subTree[subTree.length - 1].end = this.pos; if (subTree[subTree.length - 1].end === undefined) subTree[subTree.length - 1].end = this.pos;
} }
var rule = Object.getPrototypeOf(nextMatch.rule); var rule = Object.getPrototypeOf(nextMatch.rule);
for (const node of subTree) node.rule = rule; $tw.utils.each(subTree, function (node) { node.rule = rule; });
tree.push.apply(tree,subTree); tree.push.apply(tree,subTree);
// Look for the next run rule // Look for the next run rule
nextMatch = this.findNextMatch(this.inlineRules,this.pos); nextMatch = this.findNextMatch(this.inlineRules,this.pos);
@ -441,7 +441,7 @@ WikiParser.prototype.pushTextWidget = function(array,text,start,end) {
text = $tw.utils.trim(text); text = $tw.utils.trim(text);
} }
if(text) { if(text) {
array.push({type: "text", text: text, start: start, end: end, parseRule: null}); array.push({type: "text", text: text, start: start, end: end, parseRule: undefined});
} }
}; };