fix: Render Mermaid diagrams in HTML export, towards #6205

This commit is contained in:
Tom Moor
2023-11-23 09:05:40 -05:00
parent ea8ebc3b2a
commit 8b68ee404a
4 changed files with 57 additions and 4 deletions

View File

@@ -32,6 +32,8 @@ type HTMLOptions = {
includeTitle?: boolean;
/** Whether to include style tags in the generated HTML (defaults to true) */
includeStyles?: boolean;
/** Whether to include the Mermaid script in the generated HTML (defaults to false) */
includeMermaid?: boolean;
/** Whether to include styles to center diff (defaults to true) */
centered?: boolean;
/**
@@ -107,6 +109,7 @@ export default class DocumentHelper {
let output = ProsemirrorHelper.toHTML(node, {
title: options?.includeTitle !== false ? document.title : undefined,
includeStyles: options?.includeStyles,
includeMermaid: options?.includeMermaid,
centered: options?.centered,
});

View File

@@ -19,6 +19,8 @@ export type HTMLOptions = {
title?: string;
/** Whether to include style tags in the generated HTML (defaults to true) */
includeStyles?: boolean;
/** Whether to include mermaidjs scripts in the generated HTML (defaults to false) */
includeMermaid?: boolean;
/** Whether to include styles to center diff (defaults to true) */
centered?: boolean;
};
@@ -144,7 +146,8 @@ export default class ProsemirrorHelper {
*/
static toHTML(node: Node, options?: HTMLOptions) {
const sheet = new ServerStyleSheet();
let html, styleTags;
let html = "";
let styleTags = "";
const Centered = options?.centered
? styled.article`
@@ -160,7 +163,7 @@ export default class ProsemirrorHelper {
<>
{options?.title && <h1 dir={rtl ? "rtl" : "ltr"}>{options.title}</h1>}
{options?.includeStyles !== false ? (
<EditorContainer dir={rtl ? "rtl" : "ltr"} rtl={rtl}>
<EditorContainer dir={rtl ? "rtl" : "ltr"} rtl={rtl} staticHTML>
{content}
</EditorContainer>
) : (
@@ -214,6 +217,40 @@ export default class ProsemirrorHelper {
target
);
// Inject mermaidjs scripts if the document contains mermaid diagrams
if (options?.includeMermaid) {
const mermaidElements = dom.window.document.querySelectorAll(
`[data-language="mermaidjs"] pre code`
);
// Unwrap <pre> tags to enable Mermaid script to correctly render inner content
for (const el of mermaidElements) {
const parent = el.parentNode as HTMLElement;
if (parent) {
while (el.firstChild) {
parent.insertBefore(el.firstChild, el);
}
parent.removeChild(el);
parent.setAttribute("class", "mermaid");
}
}
// Inject Mermaid script
if (mermaidElements.length) {
const element = dom.window.document.createElement("script");
element.setAttribute("type", "module");
element.innerHTML = `
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
mermaid.initialize({
startOnLoad: true,
fontFamily: "inherit",
});
window.status = "ready";
`;
dom.window.document.body.appendChild(element);
}
}
return dom.serialize();
}
}

View File

@@ -527,6 +527,7 @@ router.post(
content = await DocumentHelper.toHTML(document, {
signedUrls: true,
centered: true,
includeMermaid: true,
});
} else if (accept?.includes("application/pdf")) {
throw IncorrectEditionError(