@milkdown/preset-commonmark 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 (154) hide show
  1. package/lib/composed/commands.d.ts +3 -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 -29
  14. package/lib/index.d.ts.map +1 -1
  15. package/lib/index.es.js +1099 -1386
  16. package/lib/index.es.js.map +1 -1
  17. package/lib/mark/emphasis.d.ts +5 -0
  18. package/lib/mark/emphasis.d.ts.map +1 -0
  19. package/lib/mark/index.d.ts +3 -4
  20. package/lib/mark/index.d.ts.map +1 -1
  21. package/lib/mark/inline-code.d.ts +5 -0
  22. package/lib/mark/inline-code.d.ts.map +1 -0
  23. package/lib/mark/link.d.ts +8 -10
  24. package/lib/mark/link.d.ts.map +1 -1
  25. package/lib/mark/strong.d.ts +4 -2
  26. package/lib/mark/strong.d.ts.map +1 -1
  27. package/lib/node/blockquote.d.ts +6 -2
  28. package/lib/node/blockquote.d.ts.map +1 -1
  29. package/lib/node/bullet-list.d.ts +5 -2
  30. package/lib/node/bullet-list.d.ts.map +1 -1
  31. package/lib/node/code-block.d.ts +10 -0
  32. package/lib/node/code-block.d.ts.map +1 -0
  33. package/lib/node/doc.d.ts +1 -1
  34. package/lib/node/doc.d.ts.map +1 -1
  35. package/lib/node/hardbreak.d.ts +4 -6
  36. package/lib/node/hardbreak.d.ts.map +1 -1
  37. package/lib/node/heading.d.ts +7 -12
  38. package/lib/node/heading.d.ts.map +1 -1
  39. package/lib/node/hr.d.ts +4 -2
  40. package/lib/node/hr.d.ts.map +1 -1
  41. package/lib/node/image.d.ts +10 -11
  42. package/lib/node/image.d.ts.map +1 -1
  43. package/lib/node/index.d.ts +6 -8
  44. package/lib/node/index.d.ts.map +1 -1
  45. package/lib/node/list-item.d.ts +6 -7
  46. package/lib/node/list-item.d.ts.map +1 -1
  47. package/lib/node/ordered-list.d.ts +5 -2
  48. package/lib/node/ordered-list.d.ts.map +1 -1
  49. package/lib/node/paragraph.d.ts +4 -2
  50. package/lib/node/paragraph.d.ts.map +1 -1
  51. package/lib/node/text.d.ts +1 -1
  52. package/lib/node/text.d.ts.map +1 -1
  53. package/lib/plugin/hardbreak-clear-mark-plugin.d.ts +2 -0
  54. package/lib/plugin/hardbreak-clear-mark-plugin.d.ts.map +1 -0
  55. package/lib/plugin/hardbreak-filter-plugin.d.ts +3 -0
  56. package/lib/plugin/hardbreak-filter-plugin.d.ts.map +1 -0
  57. package/lib/plugin/index.d.ts +9 -3
  58. package/lib/plugin/index.d.ts.map +1 -1
  59. package/lib/plugin/inline-nodes-cursor-plugin.d.ts +2 -0
  60. package/lib/plugin/inline-nodes-cursor-plugin.d.ts.map +1 -0
  61. package/lib/plugin/{inline-sync → inline-sync-plugin}/config.d.ts +2 -2
  62. package/lib/plugin/inline-sync-plugin/config.d.ts.map +1 -0
  63. package/lib/plugin/{inline-sync → inline-sync-plugin}/context.d.ts +1 -2
  64. package/lib/plugin/inline-sync-plugin/context.d.ts.map +1 -0
  65. package/lib/plugin/inline-sync-plugin/index.d.ts +3 -0
  66. package/lib/plugin/inline-sync-plugin/index.d.ts.map +1 -0
  67. package/lib/plugin/inline-sync-plugin/inline-sync-plugin.d.ts +2 -0
  68. package/lib/plugin/inline-sync-plugin/inline-sync-plugin.d.ts.map +1 -0
  69. package/lib/plugin/{inline-sync → inline-sync-plugin}/regexp.d.ts +0 -0
  70. package/lib/plugin/inline-sync-plugin/regexp.d.ts.map +1 -0
  71. package/lib/plugin/{inline-sync → inline-sync-plugin}/replacer.d.ts +1 -1
  72. package/lib/plugin/inline-sync-plugin/replacer.d.ts.map +1 -0
  73. package/lib/plugin/{inline-sync → inline-sync-plugin}/utils.d.ts +0 -0
  74. package/lib/plugin/inline-sync-plugin/utils.d.ts.map +1 -0
  75. package/lib/plugin/remark-add-order-in-list-plugin.d.ts +2 -0
  76. package/lib/plugin/remark-add-order-in-list-plugin.d.ts.map +1 -0
  77. package/lib/plugin/remark-inline-link-plugin.d.ts +2 -0
  78. package/lib/plugin/remark-inline-link-plugin.d.ts.map +1 -0
  79. package/lib/plugin/remark-line-break.d.ts +2 -0
  80. package/lib/plugin/remark-line-break.d.ts.map +1 -0
  81. package/lib/plugin/sync-heading-id-plugin.d.ts +2 -0
  82. package/lib/plugin/sync-heading-id-plugin.d.ts.map +1 -0
  83. package/lib/plugin/sync-list-order-plugin.d.ts +2 -0
  84. package/lib/plugin/sync-list-order-plugin.d.ts.map +1 -0
  85. package/package.json +9 -7
  86. package/src/composed/commands.ts +31 -0
  87. package/src/composed/index.ts +6 -0
  88. package/src/composed/inputrules.ts +13 -0
  89. package/src/composed/keymap.ts +20 -0
  90. package/src/composed/plugins.ts +23 -0
  91. package/src/composed/schema.ts +55 -0
  92. package/src/index.ts +6 -52
  93. package/src/mark/emphasis.ts +47 -0
  94. package/src/mark/index.ts +3 -10
  95. package/src/mark/inline-code.ts +70 -0
  96. package/src/mark/link.ts +96 -247
  97. package/src/mark/strong.ts +41 -36
  98. package/src/node/blockquote.ts +39 -33
  99. package/src/node/bullet-list.ts +62 -55
  100. package/src/node/code-block.ts +103 -0
  101. package/src/node/doc.ts +18 -22
  102. package/src/node/hardbreak.ts +68 -117
  103. package/src/node/heading.ts +175 -284
  104. package/src/node/hr.ts +57 -57
  105. package/src/node/image.ts +113 -209
  106. package/src/node/index.ts +6 -35
  107. package/src/node/list-item.ts +125 -141
  108. package/src/node/ordered-list.ts +70 -65
  109. package/src/node/paragraph.ts +54 -50
  110. package/src/node/text.ts +14 -16
  111. package/src/plugin/hardbreak-clear-mark-plugin.ts +45 -0
  112. package/src/plugin/hardbreak-filter-plugin.ts +33 -0
  113. package/src/plugin/index.ts +12 -14
  114. package/src/plugin/{inline-nodes-cursor.ts → inline-nodes-cursor-plugin.ts} +5 -8
  115. package/src/plugin/{inline-sync → inline-sync-plugin}/config.ts +18 -3
  116. package/src/plugin/{inline-sync → inline-sync-plugin}/context.ts +4 -6
  117. package/src/plugin/inline-sync-plugin/index.ts +4 -0
  118. package/src/plugin/{inline-sync/index.ts → inline-sync-plugin/inline-sync-plugin.ts} +14 -11
  119. package/src/plugin/{inline-sync → inline-sync-plugin}/regexp.ts +0 -0
  120. package/src/plugin/{inline-sync → inline-sync-plugin}/replacer.ts +3 -3
  121. package/src/plugin/{inline-sync → inline-sync-plugin}/utils.ts +0 -0
  122. package/src/plugin/remark-add-order-in-list-plugin.ts +16 -0
  123. package/src/plugin/remark-inline-link-plugin.ts +6 -0
  124. package/src/plugin/remark-line-break.ts +44 -0
  125. package/src/plugin/sync-heading-id-plugin.ts +55 -0
  126. package/src/plugin/sync-list-order-plugin.ts +57 -0
  127. package/lib/mark/code-inline.d.ts +0 -3
  128. package/lib/mark/code-inline.d.ts.map +0 -1
  129. package/lib/mark/em.d.ts +0 -3
  130. package/lib/mark/em.d.ts.map +0 -1
  131. package/lib/node/code-fence.d.ts +0 -7
  132. package/lib/node/code-fence.d.ts.map +0 -1
  133. package/lib/plugin/add-order-in-list.d.ts +0 -3
  134. package/lib/plugin/add-order-in-list.d.ts.map +0 -1
  135. package/lib/plugin/filter-html.d.ts +0 -3
  136. package/lib/plugin/filter-html.d.ts.map +0 -1
  137. package/lib/plugin/inline-nodes-cursor.d.ts +0 -7
  138. package/lib/plugin/inline-nodes-cursor.d.ts.map +0 -1
  139. package/lib/plugin/inline-sync/config.d.ts.map +0 -1
  140. package/lib/plugin/inline-sync/context.d.ts.map +0 -1
  141. package/lib/plugin/inline-sync/index.d.ts +0 -6
  142. package/lib/plugin/inline-sync/index.d.ts.map +0 -1
  143. package/lib/plugin/inline-sync/regexp.d.ts.map +0 -1
  144. package/lib/plugin/inline-sync/replacer.d.ts.map +0 -1
  145. package/lib/plugin/inline-sync/utils.d.ts.map +0 -1
  146. package/lib/supported-keys.d.ts +0 -23
  147. package/lib/supported-keys.d.ts.map +0 -1
  148. package/src/mark/code-inline.ts +0 -66
  149. package/src/mark/em.ts +0 -42
  150. package/src/node/code-fence.ts +0 -245
  151. package/src/plugin/add-order-in-list.ts +0 -19
  152. package/src/plugin/filter-html.ts +0 -43
  153. package/src/supported-keys.ts +0 -25
  154. package/src/types.d.ts +0 -5
@@ -1,79 +1,84 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
- import { createCmd, createCmdKey } from '@milkdown/core'
2
+ import { commandsCtx } from '@milkdown/core'
3
3
  import { expectDomTypeError } from '@milkdown/exception'
4
4
  import { wrapIn } from '@milkdown/prose/commands'
5
5
  import { wrappingInputRule } from '@milkdown/prose/inputrules'
6
- import { createNode, createShortcut } from '@milkdown/utils'
6
+ import { $command, $inputRule, $nodeAttr, $nodeSchema, $useKeymap } from '@milkdown/utils'
7
7
 
8
- import { SupportedKeys } from '../supported-keys'
8
+ /// HTML attributes for ordered list node.
9
+ export const orderedListAttr = $nodeAttr('orderedList')
9
10
 
10
- type Keys = SupportedKeys['OrderedList']
11
-
12
- export const WrapInOrderedList = createCmdKey('WrapInOrderedList')
13
-
14
- const id = 'ordered_list'
15
- export const orderedList = createNode<Keys>(utils => ({
16
- id,
17
- schema: () => ({
18
- content: 'listItem+',
19
- group: 'block',
20
- attrs: {
21
- order: {
22
- default: 1,
23
- },
24
- spread: {
25
- default: false,
26
- },
11
+ /// Schema for ordered list node.
12
+ export const orderedListSchema = $nodeSchema('ordered_list', ctx => ({
13
+ content: 'listItem+',
14
+ group: 'block',
15
+ attrs: {
16
+ order: {
17
+ default: 1,
18
+ },
19
+ spread: {
20
+ default: false,
27
21
  },
28
- parseDOM: [
29
- {
30
- tag: 'ol',
31
- getAttrs: (dom) => {
32
- if (!(dom instanceof HTMLElement))
33
- throw expectDomTypeError(dom)
22
+ },
23
+ parseDOM: [
24
+ {
25
+ tag: 'ol',
26
+ getAttrs: (dom) => {
27
+ if (!(dom instanceof HTMLElement))
28
+ throw expectDomTypeError(dom)
34
29
 
35
- return {
36
- spread: dom.dataset.spread,
37
- order: dom.hasAttribute('start') ? Number(dom.getAttribute('start')) : 1,
38
- }
39
- },
40
- },
41
- ],
42
- toDOM: node => [
43
- 'ol',
44
- {
45
- ...(node.attrs.order === 1 ? {} : node.attrs.order),
46
- 'data-spread': node.attrs.spread,
47
- 'class': utils.getClassName(node.attrs, 'ordered-list'),
48
- },
49
- 0,
50
- ],
51
- parseMarkdown: {
52
- match: ({ type, ordered }) => type === 'list' && !!ordered,
53
- runner: (state, node, type) => {
54
- const spread = node.spread != null ? `${node.spread}` : 'true'
55
- state.openNode(type, { spread }).next(node.children).closeNode()
30
+ return {
31
+ spread: dom.dataset.spread,
32
+ order: dom.hasAttribute('start') ? Number(dom.getAttribute('start')) : 1,
33
+ }
56
34
  },
57
35
  },
58
- toMarkdown: {
59
- match: node => node.type.name === id,
60
- runner: (state, node) => {
61
- state.openNode('list', undefined, { ordered: true, start: 1, spread: node.attrs.spread === 'true' })
62
- state.next(node.content)
63
- state.closeNode()
64
- },
36
+ ],
37
+ toDOM: node => [
38
+ 'ol',
39
+ {
40
+ ...ctx.get(orderedListAttr.key)(node),
41
+ ...(node.attrs.order === 1 ? {} : node.attrs.order),
42
+ 'data-spread': node.attrs.spread,
65
43
  },
66
- }),
67
- inputRules: nodeType => [
68
- wrappingInputRule(
69
- /^(\d+)\.\s$/,
70
- nodeType,
71
- match => ({ order: Number(match[1]) }),
72
- (match, node) => node.childCount + node.attrs.order === Number(match[1]),
73
- ),
44
+ 0,
74
45
  ],
75
- commands: nodeType => [createCmd(WrapInOrderedList, () => wrapIn(nodeType))],
76
- shortcuts: {
77
- [SupportedKeys.OrderedList]: createShortcut(WrapInOrderedList, 'Mod-Alt-7'),
46
+ parseMarkdown: {
47
+ match: ({ type, ordered }) => type === 'list' && !!ordered,
48
+ runner: (state, node, type) => {
49
+ const spread = node.spread != null ? `${node.spread}` : 'true'
50
+ state.openNode(type, { spread }).next(node.children).closeNode()
51
+ },
52
+ },
53
+ toMarkdown: {
54
+ match: node => node.type.name === 'ordered_list',
55
+ runner: (state, node) => {
56
+ state.openNode('list', undefined, { ordered: true, start: 1, spread: node.attrs.spread === 'true' })
57
+ state.next(node.content)
58
+ state.closeNode()
59
+ },
78
60
  },
79
61
  }))
62
+
63
+ /// Input rule for wrapping a block in ordered list node.
64
+ export const wrapInOrderedListInputRule = $inputRule(() => wrappingInputRule(
65
+ /^\s*(\d+)\.\s$/,
66
+ orderedListSchema.type(),
67
+ match => ({ order: Number(match[1]) }),
68
+ (match, node) => node.childCount + node.attrs.order === Number(match[1]),
69
+ ))
70
+
71
+ /// Command for wrapping a block in ordered list node.
72
+ export const wrapInOrderedListCommand = $command('WrapInOrderedList', () => () => wrapIn(orderedListSchema.type()))
73
+
74
+ /// Keymap for ordered list node.
75
+ /// - `Mod-Alt-7`: Wrap a block in ordered list.
76
+ export const orderedListKeymap = $useKeymap('orderedListKeymap', {
77
+ WrapInOrderedList: {
78
+ shortcuts: 'Mod-Alt-7',
79
+ command: (ctx) => {
80
+ const commands = ctx.get(commandsCtx)
81
+ return () => commands.call(wrapInOrderedListCommand.key)
82
+ },
83
+ },
84
+ })
@@ -1,62 +1,66 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
- import { createCmd, createCmdKey } from '@milkdown/core'
2
+ import { commandsCtx } from '@milkdown/core'
3
3
  import { setBlockType } from '@milkdown/prose/commands'
4
4
  import type { Node } from '@milkdown/prose/model'
5
5
  import { Fragment } from '@milkdown/prose/model'
6
- import { createNode, createShortcut } from '@milkdown/utils'
6
+ import { $command, $nodeAttr, $nodeSchema, $useKeymap } from '@milkdown/utils'
7
7
 
8
- import { SupportedKeys } from '../supported-keys'
8
+ /// HTML attributes for paragraph node.
9
+ export const paragraphAttr = $nodeAttr('paragraph')
9
10
 
10
- type Keys = SupportedKeys['Text']
11
+ /// Schema for paragraph node.
12
+ export const paragraphSchema = $nodeSchema('paragraph', ctx => ({
13
+ content: 'inline*',
14
+ group: 'block',
15
+ parseDOM: [{ tag: 'p' }],
16
+ toDOM: node => ['p', ctx.get(paragraphAttr.key)(node), 0],
17
+ parseMarkdown: {
18
+ match: node => node.type === 'paragraph',
19
+ runner: (state, node, type) => {
20
+ state.openNode(type)
21
+ if (node.children)
22
+ state.next(node.children)
11
23
 
12
- export const TurnIntoText = createCmdKey('TurnIntoText')
24
+ else
25
+ state.addText((node.value || '') as string)
13
26
 
14
- const id = 'paragraph'
15
- export const paragraph = createNode<Keys>((utils) => {
16
- return {
17
- id,
18
- schema: () => ({
19
- content: 'inline*',
20
- group: 'block',
21
- parseDOM: [{ tag: 'p' }],
22
- toDOM: node => ['p', { class: utils.getClassName(node.attrs, id) }, 0],
23
- parseMarkdown: {
24
- match: node => node.type === 'paragraph',
25
- runner: (state, node, type) => {
26
- state.openNode(type)
27
- if (node.children)
28
- state.next(node.children)
29
- else
30
- state.addText(node.value as string)
27
+ state.closeNode()
28
+ },
29
+ },
30
+ toMarkdown: {
31
+ match: node => node.type.name === 'paragraph',
32
+ runner: (state, node) => {
33
+ state.openNode('paragraph')
34
+ const lastIsHardbreak = node.childCount >= 1 && node.lastChild?.type.name === 'hardbreak'
35
+ if (lastIsHardbreak) {
36
+ const contentArr: Node[] = []
37
+ node.content.forEach((n, _, i) => {
38
+ if (i === node.childCount - 1)
39
+ return
40
+
41
+ contentArr.push(n)
42
+ })
43
+ state.next(Fragment.fromArray(contentArr))
44
+ }
45
+ else {
46
+ state.next(node.content)
47
+ }
48
+ state.closeNode()
49
+ },
50
+ },
51
+ }))
31
52
 
32
- state.closeNode()
33
- },
34
- },
35
- toMarkdown: {
36
- match: node => node.type.name === 'paragraph',
37
- runner: (state, node) => {
38
- state.openNode('paragraph')
39
- const lastIsHardbreak = node.childCount >= 1 && node.lastChild?.type.name === 'hardbreak'
40
- if (lastIsHardbreak) {
41
- const contentArr: Node[] = []
42
- node.content.forEach((n, _, i) => {
43
- if (i === node.childCount - 1)
44
- return
53
+ /// This command can turn the selected block into paragraph.
54
+ export const turnIntoTextCommand = $command('TurnIntoText', () => () => setBlockType(paragraphSchema.type()))
45
55
 
46
- contentArr.push(n)
47
- })
48
- state.next(Fragment.fromArray(contentArr))
49
- }
50
- else {
51
- state.next(node.content)
52
- }
53
- state.closeNode()
54
- },
55
- },
56
- }),
57
- commands: nodeType => [createCmd(TurnIntoText, () => setBlockType(nodeType))],
58
- shortcuts: {
59
- [SupportedKeys.Text]: createShortcut(TurnIntoText, 'Mod-Alt-0'),
56
+ /// Keymap for paragraph node.
57
+ /// - `<Mod-Alt-0>`: Turn the selected block into paragraph.
58
+ export const paragraphKeymap = $useKeymap('paragraphKeymap', {
59
+ TurnIntoText: {
60
+ shortcuts: 'Mod-Alt-0',
61
+ command: (ctx) => {
62
+ const commands = ctx.get(commandsCtx)
63
+ return () => commands.call(turnIntoTextCommand.key)
60
64
  },
61
- }
65
+ },
62
66
  })
package/src/node/text.ts CHANGED
@@ -1,21 +1,19 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
- import { createNode } from '@milkdown/utils'
2
+ import { $node } from '@milkdown/utils'
3
3
 
4
- export const text = createNode(() => ({
5
- id: 'text',
6
- schema: () => ({
7
- group: 'inline',
8
- parseMarkdown: {
9
- match: ({ type }) => type === 'text',
10
- runner: (state, node) => {
11
- state.addText(node.value as string)
12
- },
4
+ /// The bottom-level node.
5
+ export const textSchema = $node('text', () => ({
6
+ group: 'inline',
7
+ parseMarkdown: {
8
+ match: ({ type }) => type === 'text',
9
+ runner: (state, node) => {
10
+ state.addText(node.value as string)
13
11
  },
14
- toMarkdown: {
15
- match: node => node.type.name === 'text',
16
- runner: (state, node) => {
17
- state.addNode('text', undefined, node.text as string)
18
- },
12
+ },
13
+ toMarkdown: {
14
+ match: node => node.type.name === 'text',
15
+ runner: (state, node) => {
16
+ state.addNode('text', undefined, node.text as string)
19
17
  },
20
- }),
18
+ },
21
19
  }))
@@ -0,0 +1,45 @@
1
+ /* Copyright 2021, Milkdown by Mirone. */
2
+ import { Plugin, PluginKey } from '@milkdown/prose/state'
3
+ import { AddMarkStep, ReplaceStep } from '@milkdown/prose/transform'
4
+ import { $prose } from '@milkdown/utils'
5
+ import { hardbreakSchema } from '../node/hardbreak'
6
+
7
+ /// This plugin is used to clear the marks around the hardbreak node.
8
+ export const hardbreakClearMarkPlugin = $prose(() => {
9
+ return new Plugin({
10
+ key: new PluginKey('MILKDOWN_HARDBREAK_MARKS'),
11
+ appendTransaction: (trs, _oldState, newState) => {
12
+ if (!trs.length)
13
+ return
14
+
15
+ const [tr] = trs
16
+ if (!tr)
17
+ return
18
+
19
+ const [step] = tr.steps
20
+
21
+ const isInsertHr = tr.getMeta('hardbreak')
22
+ if (isInsertHr) {
23
+ if (!(step instanceof ReplaceStep))
24
+ return
25
+
26
+ const { from } = step as unknown as { from: number }
27
+ return newState.tr.setNodeMarkup(from, hardbreakSchema.type(), undefined, [])
28
+ }
29
+
30
+ const isAddMarkStep = step instanceof AddMarkStep
31
+ if (isAddMarkStep) {
32
+ let _tr = newState.tr
33
+ const { from, to } = step as unknown as { from: number; to: number }
34
+ newState.doc.nodesBetween(from, to, (node, pos) => {
35
+ if (node.type === hardbreakSchema.type())
36
+ _tr = _tr.setNodeMarkup(pos, hardbreakSchema.type(), undefined, [])
37
+ })
38
+
39
+ return _tr
40
+ }
41
+
42
+ return undefined
43
+ },
44
+ })
45
+ })
@@ -0,0 +1,33 @@
1
+ /* Copyright 2021, Milkdown by Mirone. */
2
+ import { Plugin, PluginKey } from '@milkdown/prose/state'
3
+ import { $ctx, $prose } from '@milkdown/utils'
4
+
5
+ /// This slice contains the nodes that within which the hardbreak will be ignored.
6
+ export const hardbreakFilterNodes = $ctx(['table', 'code_block'], 'hardbreakFilterNodes')
7
+
8
+ /// This plugin is used to filter the hardbreak node.
9
+ /// If the hardbreak is going to be inserted within a node that is in the `hardbreakFilterNodes`, ignore it.
10
+ export const hardbreakFilterPlugin = $prose((ctx) => {
11
+ const notIn = ctx.get(hardbreakFilterNodes.key)
12
+ return new Plugin({
13
+ key: new PluginKey('MILKDOWN_HARDBREAK_FILTER'),
14
+ filterTransaction: (tr, state) => {
15
+ const isInsertHr = tr.getMeta('hardbreak')
16
+ const [step] = tr.steps
17
+ if (isInsertHr && step) {
18
+ const { from } = step as unknown as { from: number }
19
+ const $from = state.doc.resolve(from)
20
+ let curDepth = $from.depth
21
+ let canApply = true
22
+ while (curDepth > 0) {
23
+ if (notIn.includes($from.node(curDepth).type.name))
24
+ canApply = false
25
+
26
+ curDepth--
27
+ }
28
+ return canApply
29
+ }
30
+ return true
31
+ },
32
+ })
33
+ })
@@ -1,17 +1,15 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
- import { createPlugin } from '@milkdown/utils'
3
- import links from 'remark-inline-links'
4
2
 
5
- import { addOrderInList } from './add-order-in-list'
6
- import { filterHTMLPlugin } from './filter-html'
7
- import { getInlineNodesCursorPlugin } from './inline-nodes-cursor'
8
- import { getInlineSyncPlugin, inlineSyncConfigCtx } from './inline-sync'
3
+ export * from './inline-sync-plugin'
9
4
 
10
- export { inlineSyncConfigCtx }
11
- export const commonmarkPlugins = [
12
- createPlugin(() => ({
13
- injectSlices: [inlineSyncConfigCtx],
14
- prosePlugins: (_, ctx) => [getInlineNodesCursorPlugin(), getInlineSyncPlugin(ctx)],
15
- remarkPlugins: () => [links, filterHTMLPlugin, addOrderInList],
16
- }))(),
17
- ]
5
+ export * from './remark-add-order-in-list-plugin'
6
+ export * from './remark-line-break'
7
+ export * from './remark-inline-link-plugin'
8
+
9
+ export * from './inline-nodes-cursor-plugin'
10
+
11
+ export * from './hardbreak-clear-mark-plugin'
12
+ export * from './hardbreak-filter-plugin'
13
+
14
+ export * from './sync-heading-id-plugin'
15
+ export * from './sync-list-order-plugin'
@@ -1,15 +1,12 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
2
  import { Plugin, PluginKey } from '@milkdown/prose/state'
3
3
  import { Decoration, DecorationSet } from '@milkdown/prose/view'
4
+ import { $prose } from '@milkdown/utils'
4
5
 
5
- const inlineNodesCursorPluginKey = new PluginKey('MILKDOWN_INLINE_NODES_CURSOR')
6
-
7
- /**
8
- * This plugin is to solve the chrome 98 bug:
9
- * https://discuss.prosemirror.net/t/cursor-jumps-at-the-end-of-line-when-it-betweens-two-inline-nodes/4641
10
- */
11
- export const getInlineNodesCursorPlugin = (): Plugin => {
6
+ /// This plugin is to solve the [chrome 98 bug](https://discuss.prosemirror.net/t/cursor-jumps-at-the-end-of-line-when-it-betweens-two-inline-nodes/4641).
7
+ export const inlineNodesCursorPlugin = $prose(() => {
12
8
  let lock = false
9
+ const inlineNodesCursorPluginKey = new PluginKey('MILKDOWN_INLINE_NODES_CURSOR')
13
10
  const inlineNodesCursorPlugin: Plugin = new Plugin({
14
11
  key: inlineNodesCursorPluginKey,
15
12
  state: {
@@ -90,4 +87,4 @@ export const getInlineNodesCursorPlugin = (): Plugin => {
90
87
  })
91
88
 
92
89
  return inlineNodesCursorPlugin
93
- }
90
+ })
@@ -1,11 +1,12 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
- import type { Ctx } from '@milkdown/core'
3
- import { createSlice } from '@milkdown/core'
2
+ import type { Ctx } from '@milkdown/ctx'
4
3
  import type { Node, NodeType } from '@milkdown/prose/model'
5
4
  import type { Transaction } from '@milkdown/prose/state'
5
+ import { $ctx } from '@milkdown/utils'
6
6
 
7
7
  import { swap } from './utils'
8
8
 
9
+ /// @internal
9
10
  export type ShouldSyncNode = (context: {
10
11
  prevNode: Node
11
12
  nextNode: Node
@@ -14,12 +15,14 @@ export type ShouldSyncNode = (context: {
14
15
  text: string
15
16
  }) => boolean
16
17
 
18
+ /// @internal
17
19
  export interface SyncNodePlaceholder {
18
20
  hole: string
19
21
  punctuation: string
20
22
  char: string
21
23
  }
22
24
 
25
+ /// @internal
23
26
  export interface InlineSyncConfig {
24
27
  placeholderConfig: SyncNodePlaceholder
25
28
  shouldSyncNode: ShouldSyncNode
@@ -27,6 +30,7 @@ export interface InlineSyncConfig {
27
30
  movePlaceholder: (placeholderToMove: string, text: string) => string
28
31
  }
29
32
 
33
+ /// @internal
30
34
  export const defaultConfig: InlineSyncConfig = {
31
35
  placeholderConfig: {
32
36
  hole: '∅',
@@ -54,4 +58,15 @@ export const defaultConfig: InlineSyncConfig = {
54
58
  },
55
59
  }
56
60
 
57
- export const inlineSyncConfigCtx = createSlice<InlineSyncConfig, 'inlineSyncConfig'>(defaultConfig, 'inlineSyncConfig')
61
+ /// A slice that contains the inline sync config.
62
+ /// You can set value to this slice to change the config.
63
+ ///
64
+ /// ```typescript
65
+ /// ctx.update(inlineSyncConfigCtx, (prevCfg) => ({
66
+ /// ...prevCfg,
67
+ /// // your config
68
+ /// }));
69
+ /// ```
70
+ ///
71
+ /// You can find the default config [here](https://github.com/Saul-Mirone/milkdown/blob/main/packages/preset-commonmark/src/plugin/inline-sync-plugin/config.ts).
72
+ export const inlineSyncConfig = $ctx<InlineSyncConfig, 'inlineSyncConfig'>(defaultConfig, 'inlineSyncConfig')
@@ -1,15 +1,13 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
- import type { Ctx } from '@milkdown/core'
2
+ import type { Ctx } from '@milkdown/ctx'
3
3
  import { parserCtx, serializerCtx } from '@milkdown/core'
4
4
  import type { Node } from '@milkdown/prose/model'
5
5
  import type { EditorState } from '@milkdown/prose/state'
6
6
  import { pipe } from '@milkdown/utils'
7
7
 
8
- import { inlineSyncConfigCtx } from './config'
8
+ import { inlineSyncConfig } from './config'
9
9
  import { calculatePlaceholder, keepLink, replacePunctuation } from './utils'
10
10
 
11
- export * from './config'
12
-
13
11
  export interface InlineSyncContext {
14
12
  text: string
15
13
  prevNode: Node
@@ -35,7 +33,7 @@ const getMarkdown = (ctx: Ctx, state: EditorState, node: Node, globalNode: Node[
35
33
  }
36
34
 
37
35
  const addPlaceholder = (ctx: Ctx, markdown: string) => {
38
- const config = ctx.get(inlineSyncConfigCtx)
36
+ const config = ctx.get(inlineSyncConfig.key)
39
37
  const holePlaceholder = config.placeholderConfig.hole
40
38
 
41
39
  const [firstLine = '', ...rest] = markdown.split('\n\n')
@@ -65,7 +63,7 @@ const getNewNode = (ctx: Ctx, text: string) => {
65
63
  }
66
64
 
67
65
  const collectGlobalNodes = (ctx: Ctx, state: EditorState) => {
68
- const { globalNodes } = ctx.get(inlineSyncConfigCtx)
66
+ const { globalNodes } = ctx.get(inlineSyncConfig.key)
69
67
  const nodes: Node[] = []
70
68
 
71
69
  state.doc.descendants((node) => {
@@ -0,0 +1,4 @@
1
+ /* Copyright 2021, Milkdown by Mirone. */
2
+
3
+ export * from './config'
4
+ export * from './inline-sync-plugin'
@@ -1,18 +1,23 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
- import type { Ctx } from '@milkdown/core'
2
+ import type { Ctx } from '@milkdown/ctx'
3
3
  import { editorViewCtx } from '@milkdown/core'
4
4
  import { Plugin, PluginKey } from '@milkdown/prose/state'
5
+ import { $prose } from '@milkdown/utils'
5
6
 
6
- import { inlineSyncConfigCtx } from './config'
7
+ import { inlineSyncConfig } from './config'
7
8
  import { getContextByState } from './context'
8
9
  import { runReplacer } from './replacer'
9
10
 
10
- export * from './config'
11
-
12
- export const inlineSyncPluginKey = new PluginKey('MILKDOWN_INLINE_SYNC')
13
- export const getInlineSyncPlugin = (ctx: Ctx) => {
11
+ /// This plugin is used to sync the inline mark.
12
+ /// It will create and remove marks automatically according to the user input.
13
+ ///
14
+ /// When users type something, the plugin will transform the line (for better performance) to real markdown AST by serializer
15
+ /// and render the AST to dom by parser, thus the input texts can be displayed correctly.
16
+ export const inlineSyncPlugin = $prose((ctx: Ctx) => {
14
17
  let requestId: number | null = null
15
- const inlineSyncPlugin = new Plugin<null>({
18
+ const inlineSyncPluginKey = new PluginKey('MILKDOWN_INLINE_SYNC')
19
+
20
+ return new Plugin<null>({
16
21
  key: inlineSyncPluginKey,
17
22
  state: {
18
23
  init: () => {
@@ -41,7 +46,7 @@ export const getInlineSyncPlugin = (ctx: Ctx) => {
41
46
 
42
47
  const { prevNode, nextNode, text } = context
43
48
 
44
- const { shouldSyncNode } = ctx.get(inlineSyncConfigCtx)
49
+ const { shouldSyncNode } = ctx.get(inlineSyncConfig.key)
45
50
 
46
51
  if (!shouldSyncNode({ prevNode, nextNode, ctx, tr, text }))
47
52
  return null
@@ -58,6 +63,4 @@ export const getInlineSyncPlugin = (ctx: Ctx) => {
58
63
  },
59
64
  },
60
65
  })
61
-
62
- return inlineSyncPlugin
63
- }
66
+ })
@@ -1,10 +1,10 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
- import type { Ctx } from '@milkdown/core'
2
+ import type { Ctx } from '@milkdown/ctx'
3
3
  import type { Attrs } from '@milkdown/prose/model'
4
4
  import type { EditorState, PluginKey, Transaction } from '@milkdown/prose/state'
5
5
  import { TextSelection } from '@milkdown/prose/state'
6
6
 
7
- import { inlineSyncConfigCtx } from './config'
7
+ import { inlineSyncConfig } from './config'
8
8
  import { getContextByState } from './context'
9
9
  import { calcOffset } from './utils'
10
10
 
@@ -15,7 +15,7 @@ export const runReplacer = (
15
15
  dispatch: (tr: Transaction) => void,
16
16
  attrs: Attrs,
17
17
  ) => {
18
- const { placeholderConfig } = ctx.get(inlineSyncConfigCtx)
18
+ const { placeholderConfig } = ctx.get(inlineSyncConfig.key)
19
19
  const holePlaceholder = placeholderConfig.hole
20
20
  // insert a placeholder to restore the selection
21
21
  let tr = state.tr.setMeta(key, true).insertText(holePlaceholder, state.selection.from)
@@ -0,0 +1,16 @@
1
+ /* Copyright 2021, Milkdown by Mirone. */
2
+ import { $remark } from '@milkdown/utils'
3
+ import type { Node, Parent } from 'unist'
4
+ import { visit } from 'unist-util-visit'
5
+
6
+ /// This plugin is used to add order in list for remark AST.
7
+ export const remarkAddOrderInListPlugin = $remark(() => () => (tree: Node) => {
8
+ visit(tree, 'list', (node: Parent & { ordered?: boolean; start?: number }) => {
9
+ if (node.ordered) {
10
+ const start = node.start ?? 1
11
+ node.children.forEach((child, index) => {
12
+ (child as Node & { label: number }).label = index + start
13
+ })
14
+ }
15
+ })
16
+ })
@@ -0,0 +1,6 @@
1
+ /* Copyright 2021, Milkdown by Mirone. */
2
+ import { $remark } from '@milkdown/utils'
3
+ import remarkInlineLinks from 'remark-inline-links'
4
+
5
+ /// This plugin wraps [remark-inline-links](https://github.com/remarkjs/remark-inline-links).
6
+ export const remarkInlineLinkPlugin = $remark(() => remarkInlineLinks)