mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-23 10:07:19 +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:
parent
84cd761c8c
commit
e01b354f7d
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user