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});