feat(mermaid): improvement navigation (#1575)

* feat(mermaid): custom stuff

Signed-off-by: Aaron Pham <contact@aarnphm.xyz>

* chore: use mermaid and update clipboard content

Signed-off-by: Aaron Pham <contact@aarnphm.xyz>

* fix: explicitly use center div

Signed-off-by: Aaron Pham <contact@aarnphm.xyz>

---------

Signed-off-by: Aaron Pham <contact@aarnphm.xyz>
This commit is contained in:
Aaron Pham
2024-11-10 18:13:12 -05:00
committed by GitHub
parent 0ad9111388
commit 1ab9c91df1
6 changed files with 1118 additions and 84 deletions

View File

@ -6,11 +6,14 @@ import rehypeRaw from "rehype-raw"
import { SKIP, visit } from "unist-util-visit"
import path from "path"
import { splitAnchor } from "../../util/path"
import { JSResource } from "../../util/resources"
import { JSResource, CSSResource } from "../../util/resources"
// @ts-ignore
import calloutScript from "../../components/scripts/callout.inline.ts"
// @ts-ignore
import checkboxScript from "../../components/scripts/checkbox.inline.ts"
// @ts-ignore
import mermaidExtensionScript from "../../components/scripts/mermaid.inline.ts"
import mermaidStyle from "../../components/styles/mermaid.inline.scss"
import { FilePath, pathToRoot, slugTag, slugifyFilePath } from "../../util/path"
import { toHast } from "mdast-util-to-hast"
import { toHtml } from "hast-util-to-html"
@ -279,6 +282,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>>
// internal link
const url = fp + anchor
return {
type: "link",
url,
@ -515,6 +519,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>>
node.data = {
hProperties: {
className: ["mermaid"],
"data-clipboard": JSON.stringify(node.value),
},
}
}
@ -659,10 +664,138 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>>
})
}
if (opts.mermaid) {
plugins.push(() => {
return (tree: HtmlRoot, _file) => {
visit(tree, "element", (node: Element, _idx, parent) => {
if (
node.tagName === "code" &&
((node.properties?.className ?? []) as string[])?.includes("mermaid")
) {
parent!.children = [
{
type: "element",
tagName: "button",
properties: {
className: ["expand-button"],
"aria-label": "Expand mermaid diagram",
"aria-hidden": "true",
"data-view-component": true,
},
children: [
{
type: "element",
tagName: "svg",
properties: {
width: 16,
height: 16,
viewBox: "0 0 16 16",
fill: "currentColor",
},
children: [
{
type: "element",
tagName: "path",
properties: {
fillRule: "evenodd",
d: "M3.72 3.72a.75.75 0 011.06 1.06L2.56 7h10.88l-2.22-2.22a.75.75 0 011.06-1.06l3.5 3.5a.75.75 0 010 1.06l-3.5 3.5a.75.75 0 11-1.06-1.06l2.22-2.22H2.56l2.22 2.22a.75.75 0 11-1.06 1.06l-3.5-3.5a.75.75 0 010-1.06l3.5-3.5z",
},
children: [],
},
],
},
],
},
node,
{
type: "element",
tagName: "div",
properties: { id: "mermaid-container" },
children: [
{
type: "element",
tagName: "div",
properties: { id: "mermaid-space" },
children: [
{
type: "element",
tagName: "div",
properties: { className: ["mermaid-header"] },
children: [
{
type: "element",
tagName: "button",
properties: {
className: ["close-button"],
"aria-label": "close button",
},
children: [
{
type: "element",
tagName: "svg",
properties: {
"aria-hidden": "true",
xmlns: "http://www.w3.org/2000/svg",
width: 24,
height: 24,
viewBox: "0 0 24 24",
fill: "none",
stroke: "currentColor",
"stroke-width": "2",
"stroke-linecap": "round",
"stroke-linejoin": "round",
},
children: [
{
type: "element",
tagName: "line",
properties: {
x1: 18,
y1: 6,
x2: 6,
y2: 18,
},
children: [],
},
{
type: "element",
tagName: "line",
properties: {
x1: 6,
y1: 6,
x2: 18,
y2: 18,
},
children: [],
},
],
},
],
},
],
},
{
type: "element",
tagName: "div",
properties: { className: ["mermaid-content"] },
children: [],
},
],
},
],
},
]
}
})
}
})
}
return plugins
},
externalResources() {
const js: JSResource[] = []
const css: CSSResource[] = []
if (opts.enableCheckbox) {
js.push({
@ -682,32 +815,18 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>>
if (opts.mermaid) {
js.push({
script: `
let mermaidImport = undefined
document.addEventListener('nav', async () => {
if (document.querySelector("code.mermaid")) {
mermaidImport ||= await import('https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.7.0/mermaid.esm.min.mjs')
const mermaid = mermaidImport.default
const darkMode = document.documentElement.getAttribute('saved-theme') === 'dark'
mermaid.initialize({
startOnLoad: false,
securityLevel: 'loose',
theme: darkMode ? 'dark' : 'default'
})
await mermaid.run({
querySelector: '.mermaid'
})
}
});
`,
script: mermaidExtensionScript,
loadTime: "afterDOMReady",
moduleType: "module",
contentType: "inline",
})
css.push({
content: mermaidStyle,
inline: true,
})
}
return { js }
return { js, css }
},
}
}