a tool for shared writing and social publishing
1import { Schema, Node, MarkSpec } from "prosemirror-model";
2import { marks } from "prosemirror-schema-basic";
3import { theme } from "tailwind.config";
4
5let baseSchema = {
6 marks: {
7 strong: marks.strong,
8 em: marks.em,
9 code: {
10 parseDOM: [
11 {
12 tag: "code",
13 },
14 ],
15
16 toDOM() {
17 return ["code", { class: "inline-code" }, 0];
18 },
19 } as MarkSpec,
20 underline: {
21 parseDOM: [
22 { tag: "u" },
23 {
24 style: "text-decoration=underline",
25 },
26 {
27 style: "text-decoration=none",
28 clearMark: (m) => m.type.name == "underline",
29 },
30 ],
31 toDOM() {
32 return ["u", { class: "underline" }, 0];
33 },
34 } as MarkSpec,
35 strikethrough: {
36 parseDOM: [
37 { tag: "s" },
38 { tag: "del" },
39 {
40 style: `text-decoration=line-through`,
41 },
42 {
43 style: "text-decoration=none",
44 clearMark: (m) => m.type.name == "strikethrough",
45 },
46 ],
47 toDOM() {
48 return [
49 "s",
50 {
51 style: `text-decoration-color: ${theme.colors.tertiary};`,
52 },
53 0,
54 ];
55 },
56 } as MarkSpec,
57 highlight: {
58 attrs: {
59 color: {
60 default: "1",
61 },
62 },
63 parseDOM: [
64 {
65 tag: "span.highlight",
66 getAttrs(dom: HTMLElement) {
67 return {
68 color: dom.getAttribute("data-color"),
69 };
70 },
71 },
72 ],
73 toDOM(node) {
74 let { color } = node.attrs;
75 return [
76 "span",
77 {
78 class: "highlight",
79 "data-color": color,
80 style: `background-color: ${color === "1" ? theme.colors["highlight-1"] : color === "2" ? theme.colors["highlight-2"] : theme.colors["highlight-3"]}`,
81 },
82 0,
83 ];
84 },
85 } as MarkSpec,
86 link: {
87 attrs: {
88 href: {},
89 },
90 inclusive: false,
91 parseDOM: [
92 {
93 tag: "a[href]",
94 getAttrs(dom: HTMLElement) {
95 return {
96 href: dom.getAttribute("href"),
97 };
98 },
99 },
100 ],
101 toDOM(node) {
102 let { href } = node.attrs;
103 return ["a", { href, target: "_blank" }, 0];
104 },
105 } as MarkSpec,
106 },
107 nodes: {
108 doc: { content: "block" },
109 paragraph: {
110 content: "inline*",
111 group: "block",
112 parseDOM: [{ tag: "p" }],
113 toDOM: () => ["p", 0] as const,
114 },
115 text: {
116 group: "inline",
117 },
118 },
119};
120export const schema = new Schema(baseSchema);
121
122export const multiBlockSchema = new Schema({
123 marks: baseSchema.marks,
124 nodes: { ...baseSchema.nodes, doc: { content: "block+" } },
125});