mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-30 05:19:57 +00:00
Markdown: Let WikiText parsing handle the creation of LaTeX widgets. (#6428)
* Markdown: Let WikiText parsing handle the creation of LaTeX widgets. When embedding LaTeX snippets in inline HTML nodes, such as TiddlyRemember macros or HTML tables, the parsing of latex nodes breaks the WikiText by splitting it into pieces around the latex node. This commit fixes the issue by converting the Remarkable katex nodes back to text, using a newline to indicate a block katex snippet. This is then re-parsed by the WikiText KaTeX plugin. TESTED: Created a test wiki with: ``` $ node tiddlywiki.js test --init markdowndemo $ node tiddlywiki.js test --listen ``` * Verified markdown + KaTeX support still works as expected. * Verified that embedding LaTeX snippets in inline HTML works (e.g. `<a href="https://example.com/">$x^2$</a>`). * Verified the markdown + KaTeX support works as expected with renderWikiText set to `false`. * Style: Remove spaces between if and opening parentheses.
This commit is contained in:
parent
7d2994388b
commit
13faeaa0bd
@ -1,3 +1,3 @@
|
||||
title: $:/config/markdown/renderWikiTextPragma
|
||||
|
||||
\rules only html image macrocallinline syslink transcludeinline wikilink filteredtranscludeblock macrocallblock transcludeblock
|
||||
\rules only html image macrocallinline syslink transcludeinline wikilink filteredtranscludeblock macrocallblock transcludeblock latex-parser
|
@ -36,22 +36,26 @@ var accumulatingTypes = {
|
||||
"text": true,
|
||||
"softbreak": true
|
||||
};
|
||||
// If rendering WikiText, we treat katex nodes as text.
|
||||
if(pluginOpts.renderWikiText) {
|
||||
accumulatingTypes["katex"] = true;
|
||||
}
|
||||
|
||||
var md = new Remarkable(remarkableOpts);
|
||||
|
||||
// If tiddlywiki/katex plugin is present, use remarkable-katex to enable katex support.
|
||||
if ($tw.modules.titles["$:/plugins/tiddlywiki/katex/katex.min.js"]) {
|
||||
if($tw.modules.titles["$:/plugins/tiddlywiki/katex/katex.min.js"]) {
|
||||
var rk = require("$:/plugins/tiddlywiki/markdown/remarkable-katex.js");
|
||||
md = md.use(rk);
|
||||
}
|
||||
|
||||
if (parseAsBoolean("$:/config/markdown/linkify")) {
|
||||
if(parseAsBoolean("$:/config/markdown/linkify")) {
|
||||
md = md.use(linkify);
|
||||
}
|
||||
|
||||
function findTagWithType(nodes, startPoint, type, level) {
|
||||
for (var i = startPoint; i < nodes.length; i++) {
|
||||
if (nodes[i].type === type && nodes[i].level === level) {
|
||||
if(nodes[i].type === type && nodes[i].level === level) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@ -77,7 +81,7 @@ function convertNodes(remarkableTree, isStartOfInline) {
|
||||
var accumulatedText = '';
|
||||
function withChildren(currentIndex, currentLevel, closingType, nodes, callback) {
|
||||
var j = findTagWithType(nodes, currentIndex + 1, closingType, currentLevel);
|
||||
if (j === false) {
|
||||
if(j === false) {
|
||||
console.error("Failed to find a " + closingType + " node after position " + currentIndex);
|
||||
console.log(nodes);
|
||||
return currentIndex + 1;
|
||||
@ -101,7 +105,7 @@ function convertNodes(remarkableTree, isStartOfInline) {
|
||||
switch (currentNode.type) {
|
||||
case "paragraph_open":
|
||||
// If the paragraph is a "tight" layout paragraph, don't wrap children in a <p> tag.
|
||||
if (currentNode.tight) {
|
||||
if(currentNode.tight) {
|
||||
i = withChildren(i, currentNode.level, "paragraph_close", remarkableTree, function(children) {
|
||||
Array.prototype.push.apply(out, children);
|
||||
});
|
||||
@ -128,14 +132,14 @@ function convertNodes(remarkableTree, isStartOfInline) {
|
||||
|
||||
case "link_open":
|
||||
i = withChildren(i, currentNode.level, "link_close", remarkableTree, function(children) {
|
||||
if (currentNode.href[0] !== "#") {
|
||||
if(currentNode.href[0] !== "#") {
|
||||
// External link
|
||||
var attributes = {
|
||||
class: { type: "string", value: "tc-tiddlylink-external" },
|
||||
href: { type: "string", value: currentNode.href },
|
||||
rel: { type: "string", value: "noopener noreferrer" }
|
||||
};
|
||||
if (pluginOpts.linkNewWindow) {
|
||||
if(pluginOpts.linkNewWindow) {
|
||||
attributes.target = { type: "string", value: "_blank" };
|
||||
}
|
||||
out.push({
|
||||
@ -186,7 +190,7 @@ function convertNodes(remarkableTree, isStartOfInline) {
|
||||
break;
|
||||
|
||||
case "softbreak":
|
||||
if (remarkableOpts.breaks) {
|
||||
if(remarkableOpts.breaks) {
|
||||
out.push({
|
||||
type: "element",
|
||||
tag: "br",
|
||||
@ -208,7 +212,7 @@ function convertNodes(remarkableTree, isStartOfInline) {
|
||||
var elementTag = currentNode.type.slice(0, 2);
|
||||
i = withChildren(i, currentNode.level, elementTag + "_close", remarkableTree, function(children) {
|
||||
var attributes = {};
|
||||
if (currentNode.align) {
|
||||
if(currentNode.align) {
|
||||
attributes.style = { type: "string", value: "text-align:" + currentNode.align };
|
||||
}
|
||||
out.push({
|
||||
@ -237,6 +241,12 @@ function convertNodes(remarkableTree, isStartOfInline) {
|
||||
break;
|
||||
|
||||
case "katex":
|
||||
// If rendering WikiText, convert the katex node back to text for parsing by the WikiText LaTeX parser.
|
||||
if(pluginOpts.renderWikiText) {
|
||||
// If this is a block, add a newline to trigger the KaTeX plugins block detection.
|
||||
var displayModeSuffix = currentNode.block ? "\n" : "";
|
||||
accumulatedText = accumulatedText + "$$" + currentNode.content + displayModeSuffix + "$$";
|
||||
} else {
|
||||
out.push({
|
||||
type: "latex",
|
||||
attributes: {
|
||||
@ -244,10 +254,11 @@ function convertNodes(remarkableTree, isStartOfInline) {
|
||||
displayMode: { type: "text", value: currentNode.block ? "true" : "false" }
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (currentNode.type.substr(currentNode.type.length - 5) === "_open") {
|
||||
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 {
|
||||
@ -261,7 +272,7 @@ function convertNodes(remarkableTree, isStartOfInline) {
|
||||
}
|
||||
// We test to see if we process the block now, or if there's
|
||||
// more to accumulate first.
|
||||
if (accumulatedText
|
||||
if(accumulatedText
|
||||
&& (
|
||||
remarkableOpts.breaks ||
|
||||
(i+1) >= remarkableTree.length ||
|
||||
@ -271,7 +282,7 @@ function convertNodes(remarkableTree, isStartOfInline) {
|
||||
// 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*$/)) {
|
||||
if(!pluginOpts.renderWikiText || accumulatedText.match(/^\s*$/)) {
|
||||
out.push({
|
||||
type: "text",
|
||||
text: accumulatedText
|
||||
@ -281,7 +292,7 @@ function convertNodes(remarkableTree, isStartOfInline) {
|
||||
// handle as a block-level parse. Otherwise not.
|
||||
var parseAsInline = !(isStartOfInline && i === 0);
|
||||
var textToParse = accumulatedText;
|
||||
if (pluginOpts.renderWikiTextPragma !== "") {
|
||||
if(pluginOpts.renderWikiTextPragma !== "") {
|
||||
textToParse = pluginOpts.renderWikiTextPragma + "\n" + textToParse;
|
||||
}
|
||||
var wikiParser = $tw.wiki.parseText("text/vnd.tiddlywiki", textToParse, {
|
||||
@ -292,7 +303,7 @@ function convertNodes(remarkableTree, isStartOfInline) {
|
||||
// If we parsed as a block, but the root element the WikiText parser gave is a paragraph,
|
||||
// we should discard the paragraph, since the way Remarkable nests its nodes, this "inline"
|
||||
// node is always inside something else that's a block-level element
|
||||
if (!parseAsInline
|
||||
if(!parseAsInline
|
||||
&& rs.length === 1
|
||||
&& rs[0].type === "element"
|
||||
&& rs[0].tag === "p"
|
||||
@ -301,7 +312,7 @@ function convertNodes(remarkableTree, isStartOfInline) {
|
||||
}
|
||||
|
||||
// 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"
|
||||
&& (accumulatedText[0] === " " || accumulatedText[0] === "\n")
|
||||
) {
|
||||
|
Loading…
Reference in New Issue
Block a user