@milkdown/preset-gfm 6.5.4 → 7.0.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/lib/composed/commands.d.ts +8 -0
  2. package/lib/composed/commands.d.ts.map +1 -0
  3. package/lib/composed/index.d.ts +6 -0
  4. package/lib/composed/index.d.ts.map +1 -0
  5. package/lib/composed/inputrules.d.ts +3 -0
  6. package/lib/composed/inputrules.d.ts.map +1 -0
  7. package/lib/composed/keymap.d.ts +3 -0
  8. package/lib/composed/keymap.d.ts.map +1 -0
  9. package/lib/composed/plugins.d.ts +3 -0
  10. package/lib/composed/plugins.d.ts.map +1 -0
  11. package/lib/composed/schema.d.ts +3 -0
  12. package/lib/composed/schema.d.ts.map +1 -0
  13. package/lib/index.d.ts +4 -34
  14. package/lib/index.d.ts.map +1 -1
  15. package/lib/index.es.js +634 -2328
  16. package/lib/index.es.js.map +1 -1
  17. package/lib/mark/index.d.ts +2 -0
  18. package/lib/mark/index.d.ts.map +1 -0
  19. package/lib/mark/strike-through.d.ts +5 -0
  20. package/lib/mark/strike-through.d.ts.map +1 -0
  21. package/lib/node/footnote/definition.d.ts +2 -0
  22. package/lib/node/footnote/definition.d.ts.map +1 -0
  23. package/lib/{footnote → node/footnote}/index.d.ts +0 -0
  24. package/lib/node/footnote/index.d.ts.map +1 -0
  25. package/lib/node/footnote/reference.d.ts +2 -0
  26. package/lib/node/footnote/reference.d.ts.map +1 -0
  27. package/lib/node/index.d.ts +4 -0
  28. package/lib/node/index.d.ts.map +1 -0
  29. package/lib/node/table/index.d.ts +32 -0
  30. package/lib/node/table/index.d.ts.map +1 -0
  31. package/lib/node/table/utils.d.ts +26 -0
  32. package/lib/node/table/utils.d.ts.map +1 -0
  33. package/lib/node/task-list-item.d.ts +2 -0
  34. package/lib/node/task-list-item.d.ts.map +1 -0
  35. package/lib/plugin/auto-insert-zero-space-plugin.d.ts +2 -0
  36. package/lib/plugin/auto-insert-zero-space-plugin.d.ts.map +1 -0
  37. package/lib/plugin/column-resizing-plugin.d.ts +2 -0
  38. package/lib/plugin/column-resizing-plugin.d.ts.map +1 -0
  39. package/lib/plugin/index.d.ts +5 -0
  40. package/lib/plugin/index.d.ts.map +1 -0
  41. package/lib/plugin/remark-gfm-plugin.d.ts +2 -0
  42. package/lib/plugin/remark-gfm-plugin.d.ts.map +1 -0
  43. package/lib/plugin/table-editing-plugin.d.ts +2 -0
  44. package/lib/plugin/table-editing-plugin.d.ts.map +1 -0
  45. package/package.json +13 -10
  46. package/src/composed/commands.ts +24 -0
  47. package/src/composed/index.ts +6 -0
  48. package/src/composed/inputrules.ts +8 -0
  49. package/src/composed/keymap.ts +10 -0
  50. package/src/composed/plugins.ts +11 -0
  51. package/src/composed/schema.ts +20 -0
  52. package/src/index.ts +6 -89
  53. package/src/mark/index.ts +2 -0
  54. package/src/mark/strike-through.ts +46 -0
  55. package/src/node/footnote/definition.ts +70 -0
  56. package/src/{footnote → node/footnote}/index.ts +0 -0
  57. package/src/node/footnote/reference.ts +60 -0
  58. package/src/node/index.ts +4 -0
  59. package/src/node/table/index.ts +318 -0
  60. package/src/node/table/utils.ts +509 -0
  61. package/src/node/task-list-item.ts +88 -0
  62. package/src/{table/plugin/auto-insert-zero-space.ts → plugin/auto-insert-zero-space-plugin.ts} +14 -15
  63. package/src/plugin/column-resizing-plugin.ts +6 -0
  64. package/src/plugin/index.ts +5 -0
  65. package/src/plugin/remark-gfm-plugin.ts +6 -0
  66. package/src/plugin/table-editing-plugin.ts +6 -0
  67. package/lib/footnote/definition.d.ts +0 -3
  68. package/lib/footnote/definition.d.ts.map +0 -1
  69. package/lib/footnote/index.d.ts.map +0 -1
  70. package/lib/footnote/reference.d.ts +0 -3
  71. package/lib/footnote/reference.d.ts.map +0 -1
  72. package/lib/footnote/utils.d.ts +0 -3
  73. package/lib/footnote/utils.d.ts.map +0 -1
  74. package/lib/strike-through.d.ts +0 -3
  75. package/lib/strike-through.d.ts.map +0 -1
  76. package/lib/supported-keys.d.ts +0 -28
  77. package/lib/supported-keys.d.ts.map +0 -1
  78. package/lib/table/command.d.ts +0 -4
  79. package/lib/table/command.d.ts.map +0 -1
  80. package/lib/table/index.d.ts +0 -10
  81. package/lib/table/index.d.ts.map +0 -1
  82. package/lib/table/nodes/index.d.ts +0 -12
  83. package/lib/table/nodes/index.d.ts.map +0 -1
  84. package/lib/table/operator-plugin/actions.d.ts +0 -20
  85. package/lib/table/operator-plugin/actions.d.ts.map +0 -1
  86. package/lib/table/operator-plugin/calc-pos.d.ts +0 -3
  87. package/lib/table/operator-plugin/calc-pos.d.ts.map +0 -1
  88. package/lib/table/operator-plugin/constant.d.ts +0 -6
  89. package/lib/table/operator-plugin/constant.d.ts.map +0 -1
  90. package/lib/table/operator-plugin/helper.d.ts +0 -7
  91. package/lib/table/operator-plugin/helper.d.ts.map +0 -1
  92. package/lib/table/operator-plugin/index.d.ts +0 -6
  93. package/lib/table/operator-plugin/index.d.ts.map +0 -1
  94. package/lib/table/operator-plugin/style.d.ts +0 -3
  95. package/lib/table/operator-plugin/style.d.ts.map +0 -1
  96. package/lib/table/operator-plugin/widget.d.ts +0 -8
  97. package/lib/table/operator-plugin/widget.d.ts.map +0 -1
  98. package/lib/table/plugin/auto-insert-zero-space.d.ts +0 -3
  99. package/lib/table/plugin/auto-insert-zero-space.d.ts.map +0 -1
  100. package/lib/table/plugin/cell-selection.d.ts +0 -40
  101. package/lib/table/plugin/cell-selection.d.ts.map +0 -1
  102. package/lib/table/plugin/column-resizing.d.ts +0 -18
  103. package/lib/table/plugin/column-resizing.d.ts.map +0 -1
  104. package/lib/table/plugin/commands.d.ts +0 -30
  105. package/lib/table/plugin/commands.d.ts.map +0 -1
  106. package/lib/table/plugin/copy-paste.d.ts +0 -14
  107. package/lib/table/plugin/copy-paste.d.ts.map +0 -1
  108. package/lib/table/plugin/fix-tables.d.ts +0 -7
  109. package/lib/table/plugin/fix-tables.d.ts.map +0 -1
  110. package/lib/table/plugin/index.d.ts +0 -4
  111. package/lib/table/plugin/index.d.ts.map +0 -1
  112. package/lib/table/plugin/schema.d.ts +0 -4
  113. package/lib/table/plugin/schema.d.ts.map +0 -1
  114. package/lib/table/plugin/table-editing.d.ts +0 -9
  115. package/lib/table/plugin/table-editing.d.ts.map +0 -1
  116. package/lib/table/plugin/table-map.d.ts +0 -44
  117. package/lib/table/plugin/table-map.d.ts.map +0 -1
  118. package/lib/table/plugin/table-view.d.ts +0 -15
  119. package/lib/table/plugin/table-view.d.ts.map +0 -1
  120. package/lib/table/plugin/types.d.ts +0 -15
  121. package/lib/table/plugin/types.d.ts.map +0 -1
  122. package/lib/table/plugin/util.d.ts +0 -16
  123. package/lib/table/plugin/util.d.ts.map +0 -1
  124. package/lib/table/utils.d.ts +0 -21
  125. package/lib/table/utils.d.ts.map +0 -1
  126. package/lib/task-list-item.d.ts +0 -9
  127. package/lib/task-list-item.d.ts.map +0 -1
  128. package/src/footnote/definition.ts +0 -187
  129. package/src/footnote/reference.ts +0 -178
  130. package/src/footnote/utils.ts +0 -4
  131. package/src/strike-through.ts +0 -43
  132. package/src/supported-keys.ts +0 -13
  133. package/src/table/command.ts +0 -20
  134. package/src/table/index.ts +0 -13
  135. package/src/table/nodes/index.ts +0 -189
  136. package/src/table/operator-plugin/actions.ts +0 -116
  137. package/src/table/operator-plugin/calc-pos.ts +0 -36
  138. package/src/table/operator-plugin/constant.ts +0 -7
  139. package/src/table/operator-plugin/helper.ts +0 -39
  140. package/src/table/operator-plugin/index.ts +0 -110
  141. package/src/table/operator-plugin/style.ts +0 -123
  142. package/src/table/operator-plugin/widget.ts +0 -57
  143. package/src/table/plugin/cell-selection.ts +0 -381
  144. package/src/table/plugin/column-resizing.ts +0 -288
  145. package/src/table/plugin/commands.ts +0 -594
  146. package/src/table/plugin/copy-paste.ts +0 -322
  147. package/src/table/plugin/fix-tables.ts +0 -132
  148. package/src/table/plugin/index.ts +0 -4
  149. package/src/table/plugin/schema.ts +0 -120
  150. package/src/table/plugin/table-editing.ts +0 -369
  151. package/src/table/plugin/table-map.ts +0 -345
  152. package/src/table/plugin/table-view.ts +0 -80
  153. package/src/table/plugin/types.ts +0 -16
  154. package/src/table/plugin/util.ts +0 -119
  155. package/src/table/utils.ts +0 -165
  156. package/src/task-list-item.ts +0 -159
@@ -1,187 +0,0 @@
1
- /* Copyright 2021, Milkdown by Mirone. */
2
-
3
- import type { ThemeInputChipType } from '@milkdown/core'
4
- import { commandsCtx, createCmd, createCmdKey, editorViewCtx } from '@milkdown/core'
5
- import { expectDomTypeError } from '@milkdown/exception'
6
- import { findSelectedNodeOfType } from '@milkdown/prose'
7
- import { wrappingInputRule } from '@milkdown/prose/inputrules'
8
- import { NodeSelection, Plugin, PluginKey } from '@milkdown/prose/state'
9
- import type { EditorView } from '@milkdown/prose/view'
10
- import { createNode } from '@milkdown/utils'
11
-
12
- import { getFootnoteDefId, getFootnoteRefId } from './utils'
13
-
14
- const key = new PluginKey('MILKDOWN_FOOTNOTE_DEF_INPUT')
15
- export const ModifyFootnoteDef = createCmdKey<string>('ModifyFootnoteDef')
16
-
17
- export const footnoteDefinition = createNode((utils) => {
18
- const id = 'footnote_definition'
19
- const markdownId = 'footnoteDefinition'
20
-
21
- return {
22
- id,
23
- schema: ctx => ({
24
- group: 'block',
25
- content: 'block+',
26
- defining: true,
27
- attrs: {
28
- label: {
29
- default: '',
30
- },
31
- },
32
- parseDOM: [
33
- {
34
- tag: `div[data-type="${id}"]`,
35
- getAttrs: (dom) => {
36
- if (!(dom instanceof HTMLElement))
37
- throw expectDomTypeError(dom)
38
-
39
- return {
40
- label: dom.dataset.label,
41
- }
42
- },
43
- contentElement: 'dd',
44
- },
45
- ],
46
- toDOM: (node) => {
47
- const label = node.attrs.label
48
- const className = utils.getClassName(node.attrs, 'footnote-definition')
49
-
50
- const dt = document.createElement('dt')
51
- dt.textContent = `[${label}]:`
52
- dt.onclick = () => {
53
- const view = ctx.get(editorViewCtx)
54
- const selection = NodeSelection.create(view.state.doc, view.state.selection.from - 2)
55
- view.dispatch(view.state.tr.setSelection(selection))
56
- }
57
-
58
- const a = document.createElement('a')
59
- a.href = `#${getFootnoteRefId(label)}`
60
- a.contentEditable = 'false'
61
- a.textContent = '↩'
62
- a.onmousedown = (e) => {
63
- e.preventDefault()
64
- }
65
-
66
- return [
67
- 'div',
68
- {
69
- 'class': className,
70
- 'data-label': label,
71
- 'data-type': id,
72
- 'id': getFootnoteDefId(label),
73
- },
74
- ['div', { class: 'footnote-definition_content' }, dt, ['dd', 0]],
75
- ['div', { class: 'footnote-definition_anchor' }, a],
76
- ]
77
- },
78
- parseMarkdown: {
79
- match: ({ type }) => type === markdownId,
80
- runner: (state, node, type) => {
81
- state
82
- .openNode(type, {
83
- label: node.label as string,
84
- })
85
- .next(node.children)
86
- .closeNode()
87
- },
88
- },
89
- toMarkdown: {
90
- match: node => node.type.name === id,
91
- runner: (state, node) => {
92
- state
93
- .openNode(markdownId, undefined, {
94
- label: node.attrs.label,
95
- identifier: node.attrs.label,
96
- })
97
- .next(node.content)
98
- .closeNode()
99
- },
100
- },
101
- }),
102
- commands: nodeType => [
103
- createCmd(ModifyFootnoteDef, (label = '') => (state, dispatch) => {
104
- const node = findSelectedNodeOfType(state.selection, nodeType)
105
- if (!node)
106
- return false
107
-
108
- const { tr } = state
109
- const _tr = tr.setNodeMarkup(node.pos, undefined, { ...node.node.attrs, label })
110
- dispatch?.(_tr.setSelection(NodeSelection.create(_tr.doc, node.pos)))
111
-
112
- return true
113
- }),
114
- ],
115
- inputRules: nodeType => [
116
- wrappingInputRule(
117
- /(?:\[\^)([^:]+)(?::)$/,
118
- nodeType,
119
- (match) => {
120
- const label = match[1] ?? 'footnote'
121
- return {
122
- label,
123
- }
124
- },
125
- () => false,
126
- ),
127
- ],
128
- prosePlugins: (type, ctx) => {
129
- return [
130
- new Plugin({
131
- key,
132
- view: (editorView) => {
133
- const inputChipRenderer = utils.themeManager.get<ThemeInputChipType>('input-chip', {
134
- width: '12em',
135
- placeholder: 'Input Footnote Label',
136
- onUpdate: (value) => {
137
- ctx.get(commandsCtx).call(ModifyFootnoteDef, value)
138
- },
139
- isBindMode: true,
140
- })
141
- if (!inputChipRenderer)
142
- return {}
143
- const shouldDisplay = (view: EditorView) =>
144
- Boolean(type && findSelectedNodeOfType(view.state.selection, type))
145
- const getCurrentLabel = (view: EditorView) => {
146
- const result = findSelectedNodeOfType(view.state.selection, type)
147
- if (!result)
148
- return
149
-
150
- const value = result.node.attrs.label
151
- return value
152
- }
153
- const renderByView = (view: EditorView) => {
154
- if (!view.editable)
155
- return
156
-
157
- const display = shouldDisplay(view)
158
- if (display) {
159
- inputChipRenderer.show(view)
160
- inputChipRenderer.update(getCurrentLabel(view))
161
- }
162
- else {
163
- inputChipRenderer.hide()
164
- }
165
- }
166
- inputChipRenderer.init(editorView)
167
- renderByView(editorView)
168
-
169
- return {
170
- update: (view, prevState) => {
171
- const isEqualSelection
172
- = prevState?.doc.eq(view.state.doc) && prevState.selection.eq(view.state.selection)
173
- if (isEqualSelection)
174
- return
175
-
176
- renderByView(view)
177
- },
178
- destroy: () => {
179
- inputChipRenderer.destroy()
180
- },
181
- }
182
- },
183
- }),
184
- ]
185
- },
186
- }
187
- })
@@ -1,178 +0,0 @@
1
- /* Copyright 2021, Milkdown by Mirone. */
2
-
3
- import type { ThemeInputChipType } from '@milkdown/core'
4
- import { commandsCtx, createCmd, createCmdKey, editorViewCtx } from '@milkdown/core'
5
- import { expectDomTypeError } from '@milkdown/exception'
6
- import { findSelectedNodeOfType } from '@milkdown/prose'
7
- import { InputRule } from '@milkdown/prose/inputrules'
8
- import { NodeSelection, Plugin, PluginKey } from '@milkdown/prose/state'
9
- import type { EditorView } from '@milkdown/prose/view'
10
- import { createNode } from '@milkdown/utils'
11
-
12
- import { getFootnoteDefId, getFootnoteRefId } from './utils'
13
-
14
- export const ModifyFootnoteRef = createCmdKey<string>('ModifyFootnoteRef')
15
- const key = new PluginKey('MILKDOWN_FOOTNOTE_REF_INPUT')
16
-
17
- export const footnoteReference = createNode((utils) => {
18
- const id = 'footnote_reference'
19
-
20
- return {
21
- id,
22
- schema: ctx => ({
23
- group: 'inline',
24
- inline: true,
25
- atom: true,
26
- attrs: {
27
- label: {
28
- default: '',
29
- },
30
- },
31
- parseDOM: [
32
- {
33
- tag: `sup[data-type="${id}"]`,
34
- getAttrs: (dom) => {
35
- if (!(dom instanceof HTMLElement))
36
- throw expectDomTypeError(dom)
37
-
38
- return {
39
- label: dom.dataset.label,
40
- }
41
- },
42
- },
43
- ],
44
- toDOM: (node) => {
45
- const label = node.attrs.label
46
- const a = document.createElement('a')
47
- const href = `#${getFootnoteDefId(label)}`
48
- a.href = href
49
- a.textContent = `[${label}]`
50
- a.onclick = (e) => {
51
- const view = ctx.get(editorViewCtx)
52
- if (view.editable)
53
- e.preventDefault()
54
- }
55
- a.ondblclick = () => {
56
- const view = ctx.get(editorViewCtx)
57
- if (view.editable)
58
- window.location.href = href
59
- }
60
- return [
61
- 'sup',
62
- {
63
- 'data-label': label,
64
- 'data-type': id,
65
- 'id': getFootnoteRefId(label),
66
- },
67
- a,
68
- ]
69
- },
70
- parseMarkdown: {
71
- match: ({ type }) => type === 'footnoteReference',
72
- runner: (state, node, type) => {
73
- state.addNode(type, {
74
- label: node.label as string,
75
- })
76
- },
77
- },
78
- toMarkdown: {
79
- match: node => node.type.name === id,
80
- runner: (state, node) => {
81
- state.addNode('footnoteReference', undefined, undefined, {
82
- label: node.attrs.label,
83
- identifier: node.attrs.label,
84
- })
85
- },
86
- },
87
- }),
88
- commands: nodeType => [
89
- createCmd(ModifyFootnoteRef, (label = '') => (state, dispatch) => {
90
- const node = findSelectedNodeOfType(state.selection, nodeType)
91
- if (!node)
92
- return false
93
-
94
- const { tr } = state
95
- const _tr = tr.setNodeMarkup(node.pos, undefined, { ...node.node.attrs, label })
96
- dispatch?.(_tr.setSelection(NodeSelection.create(_tr.doc, node.pos)))
97
-
98
- return true
99
- }),
100
- ],
101
- inputRules: nodeType => [
102
- new InputRule(/(?:\[\^)([^\]]+)(?:\])$/, (state, match, start, end) => {
103
- const $start = state.doc.resolve(start)
104
- const index = $start.index()
105
- const $end = state.doc.resolve(end)
106
- if (!$start.parent.canReplaceWith(index, $end.index(), nodeType))
107
- return null
108
-
109
- const label = match[1]
110
- return state.tr.replaceRangeWith(
111
- start,
112
- end,
113
- nodeType.create({
114
- label,
115
- }),
116
- )
117
- }),
118
- ],
119
- prosePlugins: (type, ctx) => {
120
- const inputChipRenderer = utils.themeManager.get<ThemeInputChipType>('input-chip', {
121
- width: '12em',
122
- placeholder: 'Input Footnote Label',
123
- onUpdate: (value) => {
124
- ctx.get(commandsCtx).call(ModifyFootnoteRef, value)
125
- },
126
- isBindMode: true,
127
- })
128
- if (!inputChipRenderer)
129
- return []
130
- const shouldDisplay = (view: EditorView) =>
131
- Boolean(type && findSelectedNodeOfType(view.state.selection, type))
132
- const getCurrentLabel = (view: EditorView) => {
133
- const result = findSelectedNodeOfType(view.state.selection, type)
134
- if (!result)
135
- return
136
-
137
- const value = result.node.attrs.label
138
- return value
139
- }
140
- const renderByView = (view: EditorView) => {
141
- if (!view.editable)
142
- return
143
-
144
- const display = shouldDisplay(view)
145
- if (display) {
146
- inputChipRenderer.show(view)
147
- inputChipRenderer.update(getCurrentLabel(view))
148
- }
149
- else {
150
- inputChipRenderer.hide()
151
- }
152
- }
153
- return [
154
- new Plugin({
155
- key,
156
- view: (editorView) => {
157
- inputChipRenderer.init(editorView)
158
- renderByView(editorView)
159
-
160
- return {
161
- update: (view, prevState) => {
162
- const isEqualSelection
163
- = prevState?.doc.eq(view.state.doc) && prevState.selection.eq(view.state.selection)
164
- if (isEqualSelection)
165
- return
166
-
167
- renderByView(view)
168
- },
169
- destroy: () => {
170
- inputChipRenderer.destroy()
171
- },
172
- }
173
- },
174
- }),
175
- ]
176
- },
177
- }
178
- })
@@ -1,4 +0,0 @@
1
- /* Copyright 2021, Milkdown by Mirone. */
2
- export const getFootnoteRefId = (label: string) => `footnote-ref-${label}`
3
-
4
- export const getFootnoteDefId = (label: string) => `footnote-def-${label}`
@@ -1,43 +0,0 @@
1
- /* Copyright 2021, Milkdown by Mirone. */
2
- import { createCmd, createCmdKey } from '@milkdown/core'
3
- import { toggleMark } from '@milkdown/prose/commands'
4
- import { createMark, createShortcut } from '@milkdown/utils'
5
-
6
- import { SupportedKeys } from './supported-keys'
7
-
8
- type Keys = SupportedKeys['StrikeThrough']
9
-
10
- export const ToggleStrikeThrough = createCmdKey('ToggleStrikeThrough')
11
-
12
- const id = 'strike_through'
13
- export const strikeThrough = createMark<Keys>((utils) => {
14
- return {
15
- id,
16
- schema: () => ({
17
- inclusive: false,
18
- parseDOM: [
19
- { tag: 'del' },
20
- { style: 'text-decoration', getAttrs: value => (value === 'line-through') as false },
21
- ],
22
- toDOM: mark => ['del', { class: utils.getClassName(mark.attrs, 'strike-through') }],
23
- parseMarkdown: {
24
- match: node => node.type === 'delete',
25
- runner: (state, node, markType) => {
26
- state.openMark(markType)
27
- state.next(node.children)
28
- state.closeMark(markType)
29
- },
30
- },
31
- toMarkdown: {
32
- match: mark => mark.type.name === id,
33
- runner: (state, mark) => {
34
- state.withMark(mark, 'delete')
35
- },
36
- },
37
- }),
38
- commands: markType => [createCmd(ToggleStrikeThrough, () => toggleMark(markType))],
39
- shortcuts: {
40
- [SupportedKeys.StrikeThrough]: createShortcut(ToggleStrikeThrough, 'Mod-Alt-x'),
41
- },
42
- }
43
- })
@@ -1,13 +0,0 @@
1
- /* Copyright 2021, Milkdown by Mirone. */
2
- import { SupportedKeys as CommonmarkKeys } from '@milkdown/preset-commonmark'
3
-
4
- import { SupportedKeys as TableKeys } from './table'
5
-
6
- export const SupportedKeys = {
7
- ...CommonmarkKeys,
8
- ...TableKeys,
9
- StrikeThrough: 'StrikeThrough',
10
- TaskList: 'TaskList',
11
- } as const
12
- // eslint-disable-next-line @typescript-eslint/no-redeclare
13
- export type SupportedKeys = typeof SupportedKeys
@@ -1,20 +0,0 @@
1
- /* Copyright 2021, Milkdown by Mirone. */
2
- import type { Node, NodeType } from '@milkdown/prose/model'
3
- import type { Command } from '@milkdown/prose/state'
4
- import { Selection } from '@milkdown/prose/state'
5
-
6
- import { isInTable } from './plugin/util'
7
-
8
- export const exitTable
9
- = (node: NodeType): Command =>
10
- (state, dispatch) => {
11
- if (!isInTable(state))
12
- return false
13
-
14
- const { $head } = state.selection
15
- const pos = $head.after()
16
- const tr = state.tr.replaceWith(pos, pos, node.createAndFill() as Node)
17
- tr.setSelection(Selection.near(tr.doc.resolve(pos), 1))
18
- dispatch?.(tr.scrollIntoView())
19
- return true
20
- }
@@ -1,13 +0,0 @@
1
- /* Copyright 2021, Milkdown by Mirone. */
2
- import { BreakTable, InsertTable, NextCell, PrevCell } from './nodes'
3
-
4
- export { BreakTable, InsertTable, NextCell, PrevCell, SupportedKeys, table } from './nodes'
5
- export { createTable } from './utils'
6
-
7
- export const commands = {
8
- NextCell,
9
- PrevCell,
10
- BreakTable,
11
- InsertTable,
12
- } as const
13
- export type Commands = typeof commands
@@ -1,189 +0,0 @@
1
- /* Copyright 2021, Milkdown by Mirone. */
2
- import type { MarkdownNode } from '@milkdown/core'
3
- import { createCmd, createCmdKey, schemaCtx } from '@milkdown/core'
4
- import { InputRule } from '@milkdown/prose/inputrules'
5
- import type { NodeType } from '@milkdown/prose/model'
6
- import { Selection, TextSelection } from '@milkdown/prose/state'
7
- import { createPlugin, createShortcut } from '@milkdown/utils'
8
-
9
- import { exitTable } from '../command'
10
- import { operatorPlugin } from '../operator-plugin'
11
- import { autoInsertZeroSpace } from '../plugin/auto-insert-zero-space'
12
- import { columnResizing } from '../plugin/column-resizing'
13
- import { goToNextCell } from '../plugin/commands'
14
- import { schema } from '../plugin/schema'
15
- import { tableEditing } from '../plugin/table-editing'
16
- import { createTable } from '../utils'
17
-
18
- export const SupportedKeys = {
19
- NextCell: 'NextCell',
20
- PrevCell: 'PrevCell',
21
- ExitTable: 'ExitTable',
22
- } as const
23
- // eslint-disable-next-line @typescript-eslint/no-redeclare
24
- export type SupportedKeys = typeof SupportedKeys
25
-
26
- type Keys = keyof SupportedKeys
27
-
28
- export const PrevCell = createCmdKey('PrevCell')
29
- export const NextCell = createCmdKey('NextCell')
30
- export const BreakTable = createCmdKey('BreakTable')
31
- export const InsertTable = createCmdKey('InsertTable')
32
-
33
- export const table = createPlugin<Keys, Record<string, unknown>, keyof typeof schema>((utils) => {
34
- return {
35
- schema: () => ({
36
- node: {
37
- table: {
38
- ...schema.table,
39
- parseMarkdown: {
40
- match: node => node.type === 'table',
41
- runner: (state, node, type) => {
42
- const align = node.align as (string | null)[]
43
- const children = (node.children as MarkdownNode[]).map((x, i) => ({
44
- ...x,
45
- align,
46
- isHeader: i === 0,
47
- }))
48
- state.openNode(type)
49
- state.next(children)
50
- state.closeNode()
51
- },
52
- },
53
- toMarkdown: {
54
- match: node => node.type.name === 'table',
55
- runner: (state, node) => {
56
- const firstLine = node.content.firstChild?.content
57
- if (!firstLine)
58
- return
59
-
60
- const align: (string | null)[] = []
61
- firstLine.forEach((cell) => {
62
- align.push(cell.attrs.alignment)
63
- })
64
- state.openNode('table', undefined, { align })
65
- state.next(node.content)
66
- state.closeNode()
67
- },
68
- },
69
- },
70
- table_row: {
71
- ...schema.table_row,
72
- parseMarkdown: {
73
- match: node => node.type === 'tableRow',
74
- runner: (state, node, type) => {
75
- const align = node.align as (string | null)[]
76
- const children = (node.children as MarkdownNode[]).map((x, i) => ({
77
- ...x,
78
- align: align[i],
79
- isHeader: node.isHeader,
80
- }))
81
- state.openNode(type)
82
- state.next(children)
83
- state.closeNode()
84
- },
85
- },
86
- toMarkdown: {
87
- match: node => node.type.name === 'table_row',
88
- runner: (state, node) => {
89
- state.openNode('tableRow')
90
- state.next(node.content)
91
- state.closeNode()
92
- },
93
- },
94
- },
95
- table_cell: {
96
- ...schema.table_cell,
97
- parseMarkdown: {
98
- match: node => node.type === 'tableCell' && !node.isHeader,
99
- runner: (state, node, type) => {
100
- const align = node.align as string
101
- state
102
- .openNode(type, { alignment: align })
103
- .openNode(state.schema.nodes.paragraph as NodeType)
104
- .next(node.children)
105
- .closeNode()
106
- .closeNode()
107
- },
108
- },
109
- toMarkdown: {
110
- match: node => node.type.name === 'table_cell',
111
- runner: (state, node) => {
112
- state.openNode('tableCell').next(node.content).closeNode()
113
- },
114
- },
115
- },
116
- table_header: {
117
- ...schema.table_header,
118
- parseMarkdown: {
119
- match: node => node.type === 'tableCell' && !!node.isHeader,
120
- runner: (state, node, type) => {
121
- const align = node.align as string
122
- state.openNode(type, { alignment: align })
123
- state.openNode(state.schema.nodes.paragraph as NodeType)
124
- state.next(node.children)
125
- state.closeNode()
126
- state.closeNode()
127
- },
128
- },
129
- toMarkdown: {
130
- match: node => node.type.name === 'table_header',
131
- runner: (state, node) => {
132
- state.openNode('tableCell')
133
- state.next(node.content)
134
- state.closeNode()
135
- },
136
- },
137
- },
138
- },
139
- }),
140
- inputRules: (nodeType, ctx) => [
141
- new InputRule(/^\|\|\s$/, (state, _match, start, end) => {
142
- const $start = state.doc.resolve(start)
143
- if (!$start.node(-1).canReplaceWith($start.index(-1), $start.indexAfter(-1), nodeType.table))
144
- return null
145
-
146
- const tableNode = createTable(ctx.get(schemaCtx))
147
- const tr = state.tr.replaceRangeWith(start, end, tableNode).scrollIntoView()
148
- return tr.setSelection(TextSelection.create(tr.doc, start + 3))
149
- }),
150
- new InputRule(/^\|(?<col>\d+)[xX](?<row>\d+)\|\s$/, (state, match, start, end) => {
151
- const $start = state.doc.resolve(start)
152
- if (!$start.node(-1).canReplaceWith($start.index(-1), $start.indexAfter(-1), nodeType.table))
153
- return null
154
-
155
- const tableNode = createTable(
156
- ctx.get(schemaCtx),
157
- Number(match.groups?.row),
158
- Number(match.groups?.col),
159
- )
160
- const tr = state.tr.replaceRangeWith(start, end, tableNode).scrollIntoView()
161
- return tr.setSelection(TextSelection.create(tr.doc, start + 3))
162
- }),
163
- ],
164
- commands: (_, ctx) => [
165
- createCmd(PrevCell, () => goToNextCell(-1)),
166
- createCmd(NextCell, () => goToNextCell(1)),
167
- createCmd(BreakTable, () => exitTable(ctx.get(schemaCtx).nodes.paragraph as NodeType)),
168
- createCmd(InsertTable, () => (state, dispatch) => {
169
- const { selection, tr } = state
170
- const { from } = selection
171
- const table = createTable(ctx.get(schemaCtx))
172
- const _tr = tr.replaceSelectionWith(table)
173
- const sel = Selection.findFrom(_tr.doc.resolve(from), 1, true)
174
- if (sel)
175
- dispatch?.(_tr.setSelection(sel))
176
-
177
- return true
178
- }),
179
- ],
180
- shortcuts: {
181
- [SupportedKeys.NextCell]: createShortcut(NextCell, 'Mod-]'),
182
- [SupportedKeys.PrevCell]: createShortcut(PrevCell, 'Mod-['),
183
- [SupportedKeys.ExitTable]: createShortcut(BreakTable, 'Mod-Enter'),
184
- },
185
- prosePlugins: (_, ctx) => {
186
- return [operatorPlugin(ctx, utils), autoInsertZeroSpace(), columnResizing(), tableEditing()]
187
- },
188
- }
189
- })