Skip to content

Commit 4a6da81

Browse files
committed
fix #5861 -- add mermaidjs support for all markdown in cocalc
1 parent 2c11eee commit 4a6da81

File tree

4 files changed

+774
-62
lines changed

4 files changed

+774
-62
lines changed

src/packages/frontend/editors/slate/elements/code-block/index.tsx

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { DARK_GREY_BORDER } from "../../util";
1616
import { useFileContext } from "@cocalc/frontend/lib/file-context";
1717
import { Icon } from "@cocalc/frontend/components/icon";
1818
import { isEqual } from "lodash";
19+
import ShowError from "@cocalc/frontend/components/error";
1920

2021
export interface CodeBlock extends SlateElement {
2122
type: "code_block";
@@ -47,6 +48,7 @@ const StaticElement: React.FC<RenderElementProps> = ({
4748

4849
const [newValue, setNewValue] = useState<string | null>(null);
4950
const runRef = useRef<any>(null);
51+
const mermaidRef = useRef<any>(null);
5052

5153
const [output, setOutput] = useState<null | ReactNode>(null);
5254

@@ -88,6 +90,42 @@ const StaticElement: React.FC<RenderElementProps> = ({
8890
}, 1);
8991
};
9092

93+
const isMermaid = temporaryInfo ?? element.info == "mermaid";
94+
const [mermaidError, setMermaidError] = useState<string>("");
95+
96+
useEffect(() => {
97+
const elt = mermaidRef.current;
98+
if (!isMermaid || !elt) {
99+
return;
100+
}
101+
(async () => {
102+
try {
103+
setMermaidError("");
104+
const mermaid = (await import("mermaid")).default;
105+
mermaid.initialize({
106+
startOnLoad: false,
107+
});
108+
elt.removeAttribute("data-processed");
109+
await mermaid.run({
110+
nodes: [elt],
111+
});
112+
} catch (err) {
113+
setMermaidError(err.str ?? `${err}`);
114+
}
115+
})();
116+
}, [isMermaid, newValue ?? element.value]);
117+
118+
if (isMermaid) {
119+
return (
120+
<div {...attributes} style={{ marginBottom: "1em", textIndent: 0 }}>
121+
<pre className="mermaid" ref={mermaidRef}>
122+
{newValue ?? element.value}
123+
</pre>
124+
<ShowError error={mermaidError} setError={setMermaidError} />
125+
</div>
126+
);
127+
}
128+
91129
// textIndent: 0 is needed due to task lists -- see https://github.com/sagemathinc/cocalc/issues/6074
92130
// editable since even CodeMirrorStatic is editable, but meant to be *ephemeral* editing.
93131
return (

src/packages/frontend/editors/slate/elements/code-block/info-to-mode.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import detectLanguage from "@cocalc/frontend/misc/detect-language";
55
// when preferKernel is true return the actual kernel name or language.
66
export default function infoToMode(
77
info: string | undefined | null,
8-
options: { value?: string; preferKernel?: boolean } = {}
8+
options: { value?: string; preferKernel?: boolean } = {},
99
): string {
1010
const { value, preferKernel } = options;
1111
info = info?.trim().toLowerCase();
@@ -14,6 +14,10 @@ export default function infoToMode(
1414
info = detectLanguage(value);
1515
}
1616

17+
if (info == "mermaid") {
18+
return "md";
19+
}
20+
1721
// Format that seems to work well with github (unlike python-markdown and rmarkdown!), and we
1822
// use internally, e.g.,
1923
// py {kernel='sage-9.8'} or py {kernel="sage-9.8"}

src/packages/frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@
122122
"mathjax": "^2.7.9",
123123
"md5": "^2",
124124
"memoize-one": "^5.1.1",
125+
"mermaid": "^10.9.1",
125126
"node-forge": "^1.0.0",
126127
"nyc": "^15.1.0",
127128
"octicons": "^3.5.0",

0 commit comments

Comments
 (0)