mermaid diagram
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
let mermaidPromise;
|
||||
|
||||
async function getMermaid() {
|
||||
if (!mermaidPromise) {
|
||||
mermaidPromise = import("https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs").then(
|
||||
(module) => {
|
||||
const mermaid = module.default ?? module;
|
||||
mermaid.initialize({ startOnLoad: false });
|
||||
return mermaid;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
return mermaidPromise;
|
||||
}
|
||||
|
||||
function readDiagramSource(block) {
|
||||
const code = block.querySelector("code");
|
||||
return (code?.textContent ?? block.textContent ?? "").trim();
|
||||
}
|
||||
|
||||
async function renderBlock(block) {
|
||||
if (block.dataset.mermaidOverrideState) {
|
||||
return;
|
||||
}
|
||||
|
||||
const source = readDiagramSource(block);
|
||||
if (!source) {
|
||||
block.dataset.mermaidOverrideState = "empty";
|
||||
return;
|
||||
}
|
||||
|
||||
block.dataset.mermaidOverrideState = "pending";
|
||||
|
||||
try {
|
||||
const mermaid = await getMermaid();
|
||||
const replacement = document.createElement("div");
|
||||
replacement.className = "mermaid";
|
||||
replacement.textContent = source;
|
||||
replacement.dataset.mermaidOverrideState = "rendered";
|
||||
block.replaceWith(replacement);
|
||||
await mermaid.run({ nodes: [replacement] });
|
||||
} catch (error) {
|
||||
block.dataset.mermaidOverrideState = "failed";
|
||||
console.warn("Mermaid override failed", error);
|
||||
}
|
||||
}
|
||||
|
||||
function findBlocks(root = document) {
|
||||
const blocks = [];
|
||||
|
||||
if (root instanceof Element && root.matches("pre.mermaid")) {
|
||||
blocks.push(root);
|
||||
}
|
||||
|
||||
if (root instanceof Document || root instanceof Element) {
|
||||
blocks.push(...root.querySelectorAll("pre.mermaid"));
|
||||
}
|
||||
|
||||
return blocks;
|
||||
}
|
||||
|
||||
function renderAll(root = document) {
|
||||
for (const block of findBlocks(root)) {
|
||||
void renderBlock(block);
|
||||
}
|
||||
}
|
||||
|
||||
function installObserver() {
|
||||
if (!(document.body instanceof HTMLBodyElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
for (const mutation of mutations) {
|
||||
for (const node of mutation.addedNodes) {
|
||||
if (node instanceof Element) {
|
||||
renderAll(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(document.body, { childList: true, subtree: true });
|
||||
}
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
renderAll();
|
||||
installObserver();
|
||||
});
|
||||
} else {
|
||||
renderAll();
|
||||
installObserver();
|
||||
}
|
||||
|
||||
window.addEventListener("pageshow", () => renderAll());
|
||||
window.addEventListener("popstate", () => renderAll());
|
||||
+41
-38
@@ -10,44 +10,47 @@ It also treats Markdown as the single source of truth for both MCP resources and
|
||||
|
||||
## Completed-State Layout
|
||||
|
||||
```text
|
||||
project-root/
|
||||
|
|
||||
|- pyproject.toml
|
||||
|- uv.lock
|
||||
|- zensical.toml
|
||||
|
|
||||
|- docs/
|
||||
| |- index.md
|
||||
| |- architecture.md
|
||||
| |- mcp_layout.md
|
||||
|
|
||||
|- site/
|
||||
| |- ... static files built by zensical ...
|
||||
|
|
||||
|- skills/
|
||||
| |- pytest-scaffolding/
|
||||
| | |- SKILL.md
|
||||
| | |- references/
|
||||
| |- python-logging-dictconfig/
|
||||
| | |- SKILL.md
|
||||
| | |- references/
|
||||
| |- fastapi-uv-docker/
|
||||
| |- SKILL.md
|
||||
| |- references/
|
||||
|
|
||||
|- src/
|
||||
|- personal_mcp/
|
||||
|- main.py
|
||||
|- web/
|
||||
| |- app.py
|
||||
| |- docs_mount.py
|
||||
|- catalog/
|
||||
| |- server.py
|
||||
|- skills/
|
||||
|- pytest_scaffolding/
|
||||
|- python_logging_dictconfig/
|
||||
|- fastapi_uv_docker/
|
||||
```mermaid
|
||||
---
|
||||
config:
|
||||
themeVariables:
|
||||
treeView:
|
||||
labelColor: '#FFFFFF'
|
||||
lineColor: '#FFFFFF'
|
||||
---
|
||||
treeView-beta
|
||||
"project-root"
|
||||
"pyproject.toml"
|
||||
"uv.lock"
|
||||
"zensical.toml"
|
||||
"docs"
|
||||
"index.md"
|
||||
"architecture.md"
|
||||
"mcp_layout.md"
|
||||
"site"
|
||||
"static build output"
|
||||
"skills"
|
||||
"pytest-scaffolding"
|
||||
"SKILL.md"
|
||||
"references"
|
||||
"python-logging-dictconfig"
|
||||
"SKILL.md"
|
||||
"references"
|
||||
"fastapi-uv-docker"
|
||||
"SKILL.md"
|
||||
"references"
|
||||
"src"
|
||||
"personal_mcp"
|
||||
"main.py"
|
||||
"web"
|
||||
"app.py"
|
||||
"docs_mount.py"
|
||||
"catalog"
|
||||
"server.py"
|
||||
"skills"
|
||||
"pytest_scaffolding"
|
||||
"python_logging_dictconfig"
|
||||
"fastapi_uv_docker"
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
.mermaid svg text,
|
||||
.mermaid svg tspan,
|
||||
.mermaid svg foreignObject,
|
||||
.mermaid svg foreignObject div,
|
||||
.mermaid svg foreignObject span,
|
||||
.mermaid svg .nodeLabel,
|
||||
.mermaid svg .edgeLabel {
|
||||
color: var(--md-primary-bg-color, #fff);
|
||||
fill: var(--md-primary-bg-color, #fff);
|
||||
}
|
||||
|
||||
.mermaid svg .treeView-node-label {
|
||||
fill: var(--md-primary-bg-color, #fff) !important;
|
||||
}
|
||||
Reference in New Issue
Block a user