Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/editors/slate/elements/heading/index.tsx
1698 views
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
import React from "react";
7
import { register, SlateElement } from "../register";
8
import { useFileContext } from "@cocalc/frontend/lib/file-context";
9
10
export interface Heading extends SlateElement {
11
type: "heading";
12
level: number;
13
}
14
15
register({
16
slateType: "heading",
17
18
toSlate: ({ token, children }) => {
19
return {
20
type: "heading",
21
level: parseInt(token.tag?.slice(1) ?? "1"),
22
children,
23
};
24
},
25
26
StaticElement: ({ attributes, children, element }) => {
27
if (element.type != "heading") throw Error("bug");
28
29
const { HeadingTagComponent } = useFileContext();
30
if (HeadingTagComponent != null) {
31
// support custom heading component for static rendering.
32
return (
33
<HeadingTagComponent {...attributes} level={element.level}>
34
{children}
35
</HeadingTagComponent>
36
);
37
}
38
const { level } = element;
39
const id = toId(toText(element));
40
return React.createElement(`h${level}`, { id, ...attributes }, children);
41
},
42
});
43
44
function toText(element) {
45
if (element.text != null) {
46
return element.text;
47
}
48
if (element.children != null) {
49
let s = "";
50
for (const child of element.children) {
51
s += toText(child);
52
}
53
return s;
54
}
55
return "";
56
}
57
58
// We automatically generate id's for headers as follows:
59
// We make the underlying text lower case, replace spaces by dashes,
60
// and delete all other punctuation.
61
// This matches with some other markdown processor we were evidently once using.
62
function toId(text: string): string {
63
return text
64
.toLowerCase()
65
.replace(/\s+/g, "-")
66
.replace(/[.,\/#!$%\^&\*;:{}=_`~()]/g, "");
67
}
68
69