Skip to content

Commit 23c134f

Browse files
authored
Merge pull request #518 from ImtiazKhanDS/add_mermaid_diagrams
Adding mermaidJS for mermaid graphs
2 parents dfa9137 + 29e5146 commit 23c134f

File tree

3 files changed

+109
-2
lines changed

3 files changed

+109
-2
lines changed

fasthtml/_modidx.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
'fasthtml.js': { 'fasthtml.js.HighlightJS': ('api/js.html#highlightjs', 'fasthtml/js.py'),
114114
'fasthtml.js.KatexMarkdownJS': ('api/js.html#katexmarkdownjs', 'fasthtml/js.py'),
115115
'fasthtml.js.MarkdownJS': ('api/js.html#markdownjs', 'fasthtml/js.py'),
116+
'fasthtml.js.MermaidJS': ('api/js.html#mermaidjs', 'fasthtml/js.py'),
116117
'fasthtml.js.SortableJS': ('api/js.html#sortablejs', 'fasthtml/js.py'),
117118
'fasthtml.js.dark_media': ('api/js.html#dark_media', 'fasthtml/js.py'),
118119
'fasthtml.js.light_media': ('api/js.html#light_media', 'fasthtml/js.py')},

fasthtml/js.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/03_js.ipynb.
44

55
# %% auto 0
6-
__all__ = ['marked_imp', 'npmcdn', 'light_media', 'dark_media', 'MarkdownJS', 'KatexMarkdownJS', 'HighlightJS', 'SortableJS']
6+
__all__ = ['marked_imp', 'npmcdn', 'light_media', 'dark_media', 'MarkdownJS', 'KatexMarkdownJS', 'HighlightJS', 'SortableJS',
7+
'MermaidJS']
78

89
# %% ../nbs/api/03_js.ipynb
910
import re
@@ -87,3 +88,43 @@ def SortableJS(
8788
proc_htmx('%s', Sortable.create);
8889
""" % sel
8990
return Script(src, type='module')
91+
92+
# %% ../nbs/api/03_js.ipynb
93+
def MermaidJS(
94+
sel='.language-mermaid', # CSS selector for mermaid elements
95+
theme='base', # Mermaid theme to use
96+
):
97+
"Implements browser-based Mermaid diagram rendering."
98+
src = """
99+
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
100+
101+
mermaid.initialize({
102+
startOnLoad: false,
103+
theme: '%s',
104+
securityLevel: 'loose',
105+
flowchart: { useMaxWidth: false, useMaxHeight: false }
106+
});
107+
108+
function renderMermaidDiagrams(element, index) {
109+
try {
110+
const graphDefinition = element.textContent;
111+
const graphId = `mermaid-diagram-${index}`;
112+
mermaid.render(graphId, graphDefinition)
113+
.then(({svg, bindFunctions}) => {
114+
element.innerHTML = svg;
115+
bindFunctions?.(element);
116+
})
117+
.catch(error => {
118+
console.error(`Error rendering Mermaid diagram ${index}:`, error);
119+
element.innerHTML = `<p>Error rendering diagram: ${error.message}</p>`;
120+
});
121+
} catch (error) {
122+
console.error(`Error processing Mermaid diagram ${index}:`, error);
123+
}
124+
}
125+
126+
// Assuming proc_htmx is a function that triggers rendering
127+
proc_htmx('%s', renderMermaidDiagrams);
128+
""" % (theme, sel)
129+
return Script(src, type='module')
130+

nbs/api/03_js.ipynb

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,72 @@
274274
"execution_count": null,
275275
"metadata": {},
276276
"outputs": [],
277-
"source": []
277+
"source": [
278+
"#| export\n",
279+
"def MermaidJS(\n",
280+
" sel='.language-mermaid', # CSS selector for mermaid elements\n",
281+
" theme='base', # Mermaid theme to use\n",
282+
" ):\n",
283+
" \"Implements browser-based Mermaid diagram rendering.\"\n",
284+
" src = \"\"\"\n",
285+
"import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';\n",
286+
"\n",
287+
"mermaid.initialize({\n",
288+
" startOnLoad: false,\n",
289+
" theme: '%s',\n",
290+
" securityLevel: 'loose',\n",
291+
" flowchart: { useMaxWidth: false, useMaxHeight: false }\n",
292+
"});\n",
293+
"\n",
294+
"function renderMermaidDiagrams(element, index) {\n",
295+
" try {\n",
296+
" const graphDefinition = element.textContent;\n",
297+
" const graphId = `mermaid-diagram-${index}`;\n",
298+
" mermaid.render(graphId, graphDefinition)\n",
299+
" .then(({svg, bindFunctions}) => {\n",
300+
" element.innerHTML = svg;\n",
301+
" bindFunctions?.(element);\n",
302+
" })\n",
303+
" .catch(error => {\n",
304+
" console.error(`Error rendering Mermaid diagram ${index}:`, error);\n",
305+
" element.innerHTML = `<p>Error rendering diagram: ${error.message}</p>`;\n",
306+
" });\n",
307+
" } catch (error) {\n",
308+
" console.error(`Error processing Mermaid diagram ${index}:`, error);\n",
309+
" }\n",
310+
"}\n",
311+
"\n",
312+
"// Assuming proc_htmx is a function that triggers rendering\n",
313+
"proc_htmx('%s', renderMermaidDiagrams);\n",
314+
"\"\"\" % (theme, sel)\n",
315+
" return Script(src, type='module')\n"
316+
]
317+
},
318+
{
319+
"cell_type": "markdown",
320+
"metadata": {},
321+
"source": [
322+
"```python\n",
323+
"app, rt = fast_app(hdrs=[MermaidJS()])\n",
324+
"@rt('/')\n",
325+
"def get():\n",
326+
" return Titled(\"Mermaid Examples\", \n",
327+
" # Assigning 'marked' class to components renders content as markdown\n",
328+
" Pre(Code(cls =\"language-mermaid\")('''flowchart TD\n",
329+
" A[main] --> B[\"fact(5)\"] --> C[\"fact(4)\"] --> D[\"fact(3)\"] --> E[\"fact(2)\"] --> F[\"fact(1)\"] --> G[\"fact(0)\"]\n",
330+
" ''')))\n",
331+
"```\n",
332+
"In a markdown file, just like a code cell you can define \n",
333+
"\n",
334+
"\\```mermaid\n",
335+
"\n",
336+
" graph TD\n",
337+
" A --> B \n",
338+
" B --> C \n",
339+
" C --> E\n",
340+
"\n",
341+
"\\```"
342+
]
278343
}
279344
],
280345
"metadata": {

0 commit comments

Comments
 (0)