mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-08-08 23:03:50 +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"),
|
quotes: $tw.wiki.getTiddlerText("$:/config/markdown/quotes"),
|
||||||
typographer: parseAsBoolean("$:/config/markdown/typographer")
|
typographer: parseAsBoolean("$:/config/markdown/typographer")
|
||||||
};
|
};
|
||||||
|
var accumulatingTypes = {
|
||||||
|
"text": true,
|
||||||
|
"softbreak": true
|
||||||
|
};
|
||||||
|
|
||||||
var md = new Remarkable(remarkableOpts);
|
var md = new Remarkable(remarkableOpts);
|
||||||
|
|
||||||
@ -64,7 +68,7 @@ function findTagWithType(nodes, startPoint, type, level) {
|
|||||||
*/
|
*/
|
||||||
function convertNodes(remarkableTree, isStartOfInline) {
|
function convertNodes(remarkableTree, isStartOfInline) {
|
||||||
let out = [];
|
let out = [];
|
||||||
|
var accumulatedText = '';
|
||||||
function wrappedElement(elementTag, currentIndex, currentLevel, closingType, nodes) {
|
function wrappedElement(elementTag, currentIndex, currentLevel, closingType, nodes) {
|
||||||
var j = findTagWithType(nodes, currentIndex + 1, closingType, currentLevel);
|
var j = findTagWithType(nodes, currentIndex + 1, closingType, currentLevel);
|
||||||
if (j === false) {
|
if (j === false) {
|
||||||
@ -84,17 +88,28 @@ function convertNodes(remarkableTree, isStartOfInline) {
|
|||||||
|
|
||||||
for (var i = 0; i < remarkableTree.length; i++) {
|
for (var i = 0; i < remarkableTree.length; i++) {
|
||||||
var currentNode = remarkableTree[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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
var j = findTagWithType(remarkableTree, i + 1, "link_close", currentNode.level);
|
||||||
|
|
||||||
if (currentNode.href[0] !== "#") {
|
if (currentNode.href[0] !== "#") {
|
||||||
@ -122,16 +137,17 @@ function convertNodes(remarkableTree, isStartOfInline) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
i = j;
|
i = j;
|
||||||
} else if (currentNode.type.substr(currentNode.type.length - 5) === "_open") {
|
break;
|
||||||
var tagName = currentNode.type.substr(0, currentNode.type.length - 5);
|
|
||||||
i = wrappedElement(tagName, i, currentNode.level, tagName + "_close", remarkableTree);
|
case "code":
|
||||||
} else if (currentNode.type === "code") {
|
|
||||||
out.push({
|
out.push({
|
||||||
type: "element",
|
type: "element",
|
||||||
tag: currentNode.block ? "pre" : "code",
|
tag: currentNode.block ? "pre" : "code",
|
||||||
children: [{ type: "text", text: currentNode.content }]
|
children: [{ type: "text", text: currentNode.content }]
|
||||||
});
|
});
|
||||||
} else if (currentNode.type === "fence") {
|
break;
|
||||||
|
|
||||||
|
case "fence":
|
||||||
out.push({
|
out.push({
|
||||||
type: "codeblock",
|
type: "codeblock",
|
||||||
attributes: {
|
attributes: {
|
||||||
@ -139,7 +155,9 @@ function convertNodes(remarkableTree, isStartOfInline) {
|
|||||||
code: { type: "string", value: currentNode.content }
|
code: { type: "string", value: currentNode.content }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (currentNode.type === "image") {
|
break;
|
||||||
|
|
||||||
|
case "image":
|
||||||
out.push({
|
out.push({
|
||||||
type: "image",
|
type: "image",
|
||||||
attributes: {
|
attributes: {
|
||||||
@ -147,32 +165,77 @@ function convertNodes(remarkableTree, isStartOfInline) {
|
|||||||
source: { type: "string", value: decodeURIComponent(currentNode.src) }
|
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({
|
out.push({
|
||||||
type: "element",
|
type: "element",
|
||||||
tag: "br",
|
tag: "br",
|
||||||
});
|
});
|
||||||
} else if (currentNode.type == 'hr') {
|
break;
|
||||||
|
|
||||||
|
case "hr":
|
||||||
out.push({
|
out.push({
|
||||||
type: 'element',
|
type: 'element',
|
||||||
tag: 'hr',
|
tag: 'hr',
|
||||||
});
|
});
|
||||||
} else if (currentNode.type === "inline") {
|
break;
|
||||||
|
|
||||||
|
case "inline":
|
||||||
out = out.concat(convertNodes(currentNode.children, true));
|
out = out.concat(convertNodes(currentNode.children, true));
|
||||||
} else if (currentNode.type === "text") {
|
break;
|
||||||
if (!pluginOpts.renderWikiText) {
|
|
||||||
|
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({
|
out.push({
|
||||||
type: "text",
|
type: "text",
|
||||||
text: currentNode.content
|
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 {
|
} 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,
|
// 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.
|
// handle as a block-level parse. Otherwise not.
|
||||||
var parseAsInline = !(isStartOfInline && i === 0);
|
var parseAsInline = !(isStartOfInline && i === 0);
|
||||||
var textToParse = currentNode.content;
|
var textToParse = accumulatedText;
|
||||||
if (pluginOpts.renderWikiTextPragma !== "") {
|
if (pluginOpts.renderWikiTextPragma !== "") {
|
||||||
textToParse = pluginOpts.renderWikiTextPragma + "\n" + textToParse;
|
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 the original text element started with a space, add it back in
|
||||||
if (rs.length > 0
|
if (rs.length > 0
|
||||||
&& rs[0].type === "text"
|
&& rs[0].type === "text"
|
||||||
&& currentNode.content[0] === " "
|
&& (accumulatedText[0] === " " || accumulatedText[0] === "\n")
|
||||||
) {
|
) {
|
||||||
rs[0].text = " " + rs[0].text;
|
rs[0].text = " " + rs[0].text;
|
||||||
}
|
}
|
||||||
out = out.concat(rs);
|
out = out.concat(rs);
|
||||||
}
|
}
|
||||||
} else {
|
accumulatedText = '';
|
||||||
console.error("Unknown node type: " + currentNode.type, currentNode);
|
|
||||||
out.push({
|
|
||||||
type: "text",
|
|
||||||
text: currentNode.content
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user