schema.ts (4318B)
1 import {Schema, MarkSpec} from "prosemirror-model" 2 3 /// Document schema for the data model used by CommonMark. 4 export const schema = new Schema({ 5 nodes: { 6 doc: { 7 content: "block+" 8 }, 9 10 paragraph: { 11 content: "inline*", 12 group: "block", 13 parseDOM: [{tag: "p"}], 14 toDOM() { return ["p", 0] } 15 }, 16 17 blockquote: { 18 content: "block+", 19 group: "block", 20 parseDOM: [{tag: "blockquote"}], 21 toDOM() { return ["blockquote", 0] } 22 }, 23 24 horizontal_rule: { 25 group: "block", 26 parseDOM: [{tag: "hr"}], 27 toDOM() { return ["div", ["hr"]] } 28 }, 29 30 heading: { 31 attrs: {level: {default: 1}}, 32 content: "(text | image)*", 33 group: "block", 34 defining: true, 35 parseDOM: [{tag: "h1", attrs: {level: 1}}, 36 {tag: "h2", attrs: {level: 2}}, 37 {tag: "h3", attrs: {level: 3}}, 38 {tag: "h4", attrs: {level: 4}}, 39 {tag: "h5", attrs: {level: 5}}, 40 {tag: "h6", attrs: {level: 6}}], 41 toDOM(node) { return ["h" + node.attrs.level, 0] } 42 }, 43 44 code_block: { 45 content: "text*", 46 group: "block", 47 code: true, 48 defining: true, 49 marks: "", 50 attrs: {params: {default: ""}}, 51 parseDOM: [{tag: "pre", preserveWhitespace: "full", getAttrs: node => ( 52 {params: (node as HTMLElement).getAttribute("data-params") || ""} 53 )}], 54 toDOM(node) { return ["pre", node.attrs.params ? {"data-params": node.attrs.params} : {}, ["code", 0]] } 55 }, 56 57 ordered_list: { 58 content: "list_item+", 59 group: "block", 60 attrs: {order: {default: 1}, tight: {default: false}}, 61 parseDOM: [{tag: "ol", getAttrs(dom) { 62 return {order: (dom as HTMLElement).hasAttribute("start") ? +(dom as HTMLElement).getAttribute("start")! : 1, 63 tight: (dom as HTMLElement).hasAttribute("data-tight")} 64 }}], 65 toDOM(node) { 66 return ["ol", {start: node.attrs.order == 1 ? null : node.attrs.order, 67 "data-tight": node.attrs.tight ? "true" : null}, 0] 68 } 69 }, 70 71 bullet_list: { 72 content: "list_item+", 73 group: "block", 74 attrs: {tight: {default: false}}, 75 parseDOM: [{tag: "ul", getAttrs: dom => ({tight: (dom as HTMLElement).hasAttribute("data-tight")})}], 76 toDOM(node) { return ["ul", {"data-tight": node.attrs.tight ? "true" : null}, 0] } 77 }, 78 79 list_item: { 80 content: "block+", 81 defining: true, 82 parseDOM: [{tag: "li"}], 83 toDOM() { return ["li", 0] } 84 }, 85 86 text: { 87 group: "inline" 88 }, 89 90 image: { 91 inline: true, 92 attrs: { 93 src: {}, 94 alt: {default: null}, 95 title: {default: null} 96 }, 97 group: "inline", 98 draggable: true, 99 parseDOM: [{tag: "img[src]", getAttrs(dom) { 100 return { 101 src: (dom as HTMLElement).getAttribute("src"), 102 title: (dom as HTMLElement).getAttribute("title"), 103 alt: (dom as HTMLElement).getAttribute("alt") 104 } 105 }}], 106 toDOM(node) { return ["img", node.attrs] } 107 }, 108 109 hard_break: { 110 inline: true, 111 group: "inline", 112 selectable: false, 113 parseDOM: [{tag: "br"}], 114 toDOM() { return ["br"] } 115 } 116 }, 117 118 marks: { 119 em: { 120 parseDOM: [ 121 {tag: "i"}, {tag: "em"}, 122 {style: "font-style=italic"}, 123 {style: "font-style=normal", clearMark: m => m.type.name == "em"} 124 ], 125 toDOM() { return ["em"] } 126 }, 127 128 strong: { 129 parseDOM: [ 130 {tag: "strong"}, 131 {tag: "b", getAttrs: node => node.style.fontWeight != "normal" && null}, 132 {style: "font-weight=400", clearMark: m => m.type.name == "strong"}, 133 {style: "font-weight", getAttrs: value => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null} 134 ], 135 toDOM() { return ["strong"] } 136 } as MarkSpec, 137 138 link: { 139 attrs: { 140 href: {}, 141 title: {default: null} 142 }, 143 inclusive: false, 144 parseDOM: [{tag: "a[href]", getAttrs(dom) { 145 return {href: (dom as HTMLElement).getAttribute("href"), title: dom.getAttribute("title")} 146 }}], 147 toDOM(node) { return ["a", node.attrs] } 148 }, 149 150 code: { 151 code: true, 152 parseDOM: [{tag: "code"}], 153 toDOM() { return ["code"] } 154 } 155 } 156 })