1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-06-24 22:33:16 +00:00

Corrected issue with markdowns softbreaks AND whitespace between md markup (#4684)

* Corrected issue with markdowns softbreaks

It wasn't respecting the $:/config/markdown/breaks setting.
It was effectively always "true".
Also, no more errors when encountering hardbreaks.

* Corrected introduced md bug

Made it so after each md type, accumulated text may be flushed.

* Changed convertNodes to use switch statement

It's faster, less text, easier to read, and now debuggers don't play
duck-duck-goose with every if-else block.

* whitespace text is no longer forgotten

* Fixed issue with text after md pattern and \n
This commit is contained in:
Cameron Fischer 2020-06-11 07:09:10 -04:00 committed by GitHub
parent 84cd761c8c
commit e01b354f7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -32,6 +32,10 @@ var remarkableOpts = {
quotes: $tw.wiki.getTiddlerText("$:/config/markdown/quotes"),
typographer: parseAsBoolean("$:/config/markdown/typographer")
};
var accumulatingTypes = {
"text": true,
"softbreak": true
};
var md = new Remarkable(remarkableOpts);
@ -64,7 +68,7 @@ function findTagWithType(nodes, startPoint, type, level) {
*/
function convertNodes(remarkableTree, isStartOfInline) {
let out = [];
var accumulatedText = '';
function wrappedElement(elementTag, currentIndex, currentLevel, closingType, nodes) {
var j = findTagWithType(nodes, currentIndex + 1, closingType, currentLevel);
if (j === false) {
@ -84,17 +88,28 @@ function convertNodes(remarkableTree, isStartOfInline) {
for (var i = 0; i < remarkableTree.length; i++) {
var currentNode = remarkableTree[i];
if (currentNode.type === "paragraph_open") {
switch (currentNode.type) {
case "paragraph_open":
i = wrappedElement("p", i, currentNode.level, "paragraph_close", remarkableTree);
} else if (currentNode.type === "heading_open") {
break;
case "heading_open":
i = wrappedElement("h" + currentNode.hLevel, i, currentNode.level, "heading_close", remarkableTree);
} else if (currentNode.type === "bullet_list_open") {
break;
case "bullet_list_open":
i = wrappedElement("ul", i, currentNode.level, "bullet_list_close", remarkableTree);
} else if (currentNode.type == 'ordered_list_open') {
break;
case "ordered_list_open":
i = wrappedElement('ol', i, currentNode.level,'ordered_list_close', remarkableTree);
} else if (currentNode.type === "list_item_open") {
break;
case "list_item_open":
i = wrappedElement("li", i, currentNode.level, "list_item_close", remarkableTree);
} else if (currentNode.type === "link_open") {
break;
case "link_open":
var j = findTagWithType(remarkableTree, i + 1, "link_close", currentNode.level);
if (currentNode.href[0] !== "#") {
@ -122,16 +137,17 @@ function convertNodes(remarkableTree, isStartOfInline) {
});
}
i = j;
} else if (currentNode.type.substr(currentNode.type.length - 5) === "_open") {
var tagName = currentNode.type.substr(0, currentNode.type.length - 5);
i = wrappedElement(tagName, i, currentNode.level, tagName + "_close", remarkableTree);
} else if (currentNode.type === "code") {
break;
case "code":
out.push({
type: "element",
tag: currentNode.block ? "pre" : "code",
children: [{ type: "text", text: currentNode.content }]
});
} else if (currentNode.type === "fence") {
break;
case "fence":
out.push({
type: "codeblock",
attributes: {
@ -139,7 +155,9 @@ function convertNodes(remarkableTree, isStartOfInline) {
code: { type: "string", value: currentNode.content }
}
});
} else if (currentNode.type === "image") {
break;
case "image":
out.push({
type: "image",
attributes: {
@ -147,32 +165,77 @@ function convertNodes(remarkableTree, isStartOfInline) {
source: { type: "string", value: decodeURIComponent(currentNode.src) }
}
});
} else if (currentNode.type === "softbreak") {
break;
case "softbreak":
if (remarkableOpts.breaks) {
out.push({
type: "element",
tag: "br",
});
} else {
accumulatedText = accumulatedText + '\n';
}
break;
case "hardbreak":
out.push({
type: "element",
tag: "br",
});
} else if (currentNode.type == 'hr') {
break;
case "hr":
out.push({
type: 'element',
tag: 'hr',
});
} else if (currentNode.type === "inline") {
break;
case "inline":
out = out.concat(convertNodes(currentNode.children, true));
} else if (currentNode.type === "text") {
if (!pluginOpts.renderWikiText) {
break;
case "text":
// We need to merge this text block with the upcoming text block and parse it all together.
accumulatedText = accumulatedText + currentNode.content;
break;
default:
if (currentNode.type.substr(currentNode.type.length - 5) === "_open") {
var tagName = currentNode.type.substr(0, currentNode.type.length - 5);
i = wrappedElement(tagName, i, currentNode.level, tagName + "_close", remarkableTree);
} else {
console.error("Unknown node type: " + currentNode.type, currentNode);
out.push({
type: "text",
text: currentNode.content
});
}
break;
}
// We test to see if we process the block now, or if there's
// more to accumulate first.
if (accumulatedText
&& (
remarkableOpts.breaks ||
(i+1) >= remarkableTree.length ||
!accumulatingTypes[remarkableTree[i+1].type]
)
) {
// The Markdown compiler thinks this is just text.
// Hand off to the WikiText parser to see if there's more to render
// But only if it's configured to, and we have more than whitespace
if (!pluginOpts.renderWikiText || accumulatedText.match(/^\s*$/)) {
out.push({
type: "text",
text: accumulatedText
});
} else {
// The Markdown compiler thinks this is just text.
// Hand off to the WikiText parser to see if there's more to render
// If we're inside a block element (div, p, td, h1), and this is the first child in the tree,
// handle as a block-level parse. Otherwise not.
var parseAsInline = !(isStartOfInline && i === 0);
var textToParse = currentNode.content;
var textToParse = accumulatedText;
if (pluginOpts.renderWikiTextPragma !== "") {
textToParse = pluginOpts.renderWikiTextPragma + "\n" + textToParse;
}
@ -195,18 +258,13 @@ function convertNodes(remarkableTree, isStartOfInline) {
// If the original text element started with a space, add it back in
if (rs.length > 0
&& rs[0].type === "text"
&& currentNode.content[0] === " "
&& (accumulatedText[0] === " " || accumulatedText[0] === "\n")
) {
rs[0].text = " " + rs[0].text;
}
out = out.concat(rs);
}
} else {
console.error("Unknown node type: " + currentNode.type, currentNode);
out.push({
type: "text",
text: currentNode.content
});
accumulatedText = '';
}
}
return out;