@milkdown/preset-commonmark 6.5.4 → 7.0.0-next.0

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 (153) 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 +2 -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 +1101 -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.d.ts → inline-nodes-cursor-plugin.d.ts} +2 -3
  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 +30 -0
  87. package/src/composed/index.ts +6 -0
  88. package/src/composed/inputrules.ts +12 -0
  89. package/src/composed/keymap.ts +19 -0
  90. package/src/composed/plugins.ts +21 -0
  91. package/src/composed/schema.ts +54 -0
  92. package/src/index.ts +5 -52
  93. package/src/mark/emphasis.ts +42 -0
  94. package/src/mark/index.ts +3 -10
  95. package/src/mark/inline-code.ts +64 -0
  96. package/src/mark/link.ts +87 -247
  97. package/src/mark/strong.ts +35 -36
  98. package/src/node/blockquote.ts +32 -33
  99. package/src/node/bullet-list.ts +56 -56
  100. package/src/node/code-block.ts +93 -0
  101. package/src/node/doc.ts +17 -22
  102. package/src/node/hardbreak.ts +60 -117
  103. package/src/node/heading.ts +158 -281
  104. package/src/node/hr.ts +51 -57
  105. package/src/node/image.ts +102 -209
  106. package/src/node/index.ts +6 -35
  107. package/src/node/list-item.ts +81 -142
  108. package/src/node/ordered-list.ts +64 -65
  109. package/src/node/paragraph.ts +48 -50
  110. package/src/node/text.ts +13 -16
  111. package/src/plugin/hardbreak-clear-mark-plugin.ts +44 -0
  112. package/src/plugin/hardbreak-filter-plugin.ts +31 -0
  113. package/src/plugin/index.ts +12 -14
  114. package/src/plugin/{inline-nodes-cursor.ts → inline-nodes-cursor-plugin.ts} +4 -4
  115. package/src/plugin/{inline-sync → inline-sync-plugin}/config.ts +4 -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} +9 -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 +15 -0
  123. package/src/plugin/remark-inline-link-plugin.ts +5 -0
  124. package/src/plugin/remark-line-break.ts +41 -0
  125. package/src/plugin/sync-heading-id-plugin.ts +53 -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.map +0 -1
  138. package/lib/plugin/inline-sync/config.d.ts.map +0 -1
  139. package/lib/plugin/inline-sync/context.d.ts.map +0 -1
  140. package/lib/plugin/inline-sync/index.d.ts +0 -6
  141. package/lib/plugin/inline-sync/index.d.ts.map +0 -1
  142. package/lib/plugin/inline-sync/regexp.d.ts.map +0 -1
  143. package/lib/plugin/inline-sync/replacer.d.ts.map +0 -1
  144. package/lib/plugin/inline-sync/utils.d.ts.map +0 -1
  145. package/lib/supported-keys.d.ts +0 -23
  146. package/lib/supported-keys.d.ts.map +0 -1
  147. package/src/mark/code-inline.ts +0 -66
  148. package/src/mark/em.ts +0 -42
  149. package/src/node/code-fence.ts +0 -245
  150. package/src/plugin/add-order-in-list.ts +0 -19
  151. package/src/plugin/filter-html.ts +0 -43
  152. package/src/supported-keys.ts +0 -25
  153. package/src/types.d.ts +0 -5
@@ -1,79 +1,78 @@
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
+ export const orderedListAttr = $nodeAttr('orderedList')
9
9
 
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
- },
10
+ export const orderedListSchema = $nodeSchema('ordered_list', ctx => ({
11
+ content: 'listItem+',
12
+ group: 'block',
13
+ attrs: {
14
+ order: {
15
+ default: 1,
16
+ },
17
+ spread: {
18
+ default: false,
27
19
  },
28
- parseDOM: [
29
- {
30
- tag: 'ol',
31
- getAttrs: (dom) => {
32
- if (!(dom instanceof HTMLElement))
33
- throw expectDomTypeError(dom)
20
+ },
21
+ parseDOM: [
22
+ {
23
+ tag: 'ol',
24
+ getAttrs: (dom) => {
25
+ if (!(dom instanceof HTMLElement))
26
+ throw expectDomTypeError(dom)
34
27
 
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()
28
+ return {
29
+ spread: dom.dataset.spread,
30
+ order: dom.hasAttribute('start') ? Number(dom.getAttribute('start')) : 1,
31
+ }
56
32
  },
57
33
  },
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
- },
34
+ ],
35
+ toDOM: node => [
36
+ 'ol',
37
+ {
38
+ ...ctx.get(orderedListAttr.key)(node),
39
+ ...(node.attrs.order === 1 ? {} : node.attrs.order),
40
+ 'data-spread': node.attrs.spread,
65
41
  },
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
- ),
42
+ 0,
74
43
  ],
75
- commands: nodeType => [createCmd(WrapInOrderedList, () => wrapIn(nodeType))],
76
- shortcuts: {
77
- [SupportedKeys.OrderedList]: createShortcut(WrapInOrderedList, 'Mod-Alt-7'),
44
+ parseMarkdown: {
45
+ match: ({ type, ordered }) => type === 'list' && !!ordered,
46
+ runner: (state, node, type) => {
47
+ const spread = node.spread != null ? `${node.spread}` : 'true'
48
+ state.openNode(type, { spread }).next(node.children).closeNode()
49
+ },
50
+ },
51
+ toMarkdown: {
52
+ match: node => node.type.name === 'ordered_list',
53
+ runner: (state, node) => {
54
+ state.openNode('list', undefined, { ordered: true, start: 1, spread: node.attrs.spread === 'true' })
55
+ state.next(node.content)
56
+ state.closeNode()
57
+ },
78
58
  },
79
59
  }))
60
+
61
+ export const wrapInOrderedListInputRule = $inputRule(() => wrappingInputRule(
62
+ /^\s*(\d+)\.\s$/,
63
+ orderedListSchema.type(),
64
+ match => ({ order: Number(match[1]) }),
65
+ (match, node) => node.childCount + node.attrs.order === Number(match[1]),
66
+ ))
67
+
68
+ export const wrapInOrderedListCommand = $command('WrapInOrderedList', () => () => wrapIn(orderedListSchema.type()))
69
+
70
+ export const orderedListKeymap = $useKeymap('orderedListKeymap', {
71
+ WrapInOrderedList: {
72
+ shortcuts: 'Mod-Alt-7',
73
+ command: (ctx) => {
74
+ const commands = ctx.get(commandsCtx)
75
+ return () => commands.call(wrapInOrderedListCommand.key)
76
+ },
77
+ },
78
+ })
@@ -1,62 +1,60 @@
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
+ export const paragraphAttr = $nodeAttr('paragraph')
9
+ export const paragraphSchema = $nodeSchema('paragraph', ctx => ({
10
+ content: 'inline*',
11
+ group: 'block',
12
+ parseDOM: [{ tag: 'p' }],
13
+ toDOM: node => ['p', ctx.get(paragraphAttr.key)(node), 0],
14
+ parseMarkdown: {
15
+ match: node => node.type === 'paragraph',
16
+ runner: (state, node, type) => {
17
+ state.openNode(type)
18
+ if (node.children)
19
+ state.next(node.children)
9
20
 
10
- type Keys = SupportedKeys['Text']
21
+ else
22
+ state.addText((node.value || '') as string)
11
23
 
12
- export const TurnIntoText = createCmdKey('TurnIntoText')
24
+ state.closeNode()
25
+ },
26
+ },
27
+ toMarkdown: {
28
+ match: node => node.type.name === 'paragraph',
29
+ runner: (state, node) => {
30
+ state.openNode('paragraph')
31
+ const lastIsHardbreak = node.childCount >= 1 && node.lastChild?.type.name === 'hardbreak'
32
+ if (lastIsHardbreak) {
33
+ const contentArr: Node[] = []
34
+ node.content.forEach((n, _, i) => {
35
+ if (i === node.childCount - 1)
36
+ return
13
37
 
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)
38
+ contentArr.push(n)
39
+ })
40
+ state.next(Fragment.fromArray(contentArr))
41
+ }
42
+ else {
43
+ state.next(node.content)
44
+ }
45
+ state.closeNode()
46
+ },
47
+ },
48
+ }))
31
49
 
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
50
+ export const turnIntoTextCommand = $command('TurnIntoText', () => () => setBlockType(paragraphSchema.type()))
45
51
 
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'),
52
+ export const paragraphKeymap = $useKeymap('paragraphKeymap', {
53
+ TurnIntoText: {
54
+ shortcuts: 'Mod-Alt-0',
55
+ command: (ctx) => {
56
+ const commands = ctx.get(commandsCtx)
57
+ return () => commands.call(turnIntoTextCommand.key)
60
58
  },
61
- }
59
+ },
62
60
  })
package/src/node/text.ts CHANGED
@@ -1,21 +1,18 @@
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
+ export const textSchema = $node('text', () => ({
5
+ group: 'inline',
6
+ parseMarkdown: {
7
+ match: ({ type }) => type === 'text',
8
+ runner: (state, node) => {
9
+ state.addText(node.value as string)
13
10
  },
14
- toMarkdown: {
15
- match: node => node.type.name === 'text',
16
- runner: (state, node) => {
17
- state.addNode('text', undefined, node.text as string)
18
- },
11
+ },
12
+ toMarkdown: {
13
+ match: node => node.type.name === 'text',
14
+ runner: (state, node) => {
15
+ state.addNode('text', undefined, node.text as string)
19
16
  },
20
- }),
17
+ },
21
18
  }))
@@ -0,0 +1,44 @@
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
+ export const hardbreakClearMarkPlugin = $prose(() => {
8
+ return new Plugin({
9
+ key: new PluginKey('MILKDOWN_HARDBREAK_MARKS'),
10
+ appendTransaction: (trs, _oldState, newState) => {
11
+ if (!trs.length)
12
+ return
13
+
14
+ const [tr] = trs
15
+ if (!tr)
16
+ return
17
+
18
+ const [step] = tr.steps
19
+
20
+ const isInsertHr = tr.getMeta('hardbreak')
21
+ if (isInsertHr) {
22
+ if (!(step instanceof ReplaceStep))
23
+ return
24
+
25
+ const { from } = step as unknown as { from: number }
26
+ return newState.tr.setNodeMarkup(from, hardbreakSchema.type(), undefined, [])
27
+ }
28
+
29
+ const isAddMarkStep = step instanceof AddMarkStep
30
+ if (isAddMarkStep) {
31
+ let _tr = newState.tr
32
+ const { from, to } = step as unknown as { from: number; to: number }
33
+ newState.doc.nodesBetween(from, to, (node, pos) => {
34
+ if (node.type === hardbreakSchema.type())
35
+ _tr = _tr.setNodeMarkup(pos, hardbreakSchema.type(), undefined, [])
36
+ })
37
+
38
+ return _tr
39
+ }
40
+
41
+ return undefined
42
+ },
43
+ })
44
+ })
@@ -0,0 +1,31 @@
1
+ /* Copyright 2021, Milkdown by Mirone. */
2
+ import { Plugin, PluginKey } from '@milkdown/prose/state'
3
+ import { $ctx, $prose } from '@milkdown/utils'
4
+
5
+ export const hardbreakFilterNodes = $ctx(['table', 'code_block'], 'hardbreakFilterNodes')
6
+
7
+ // If the hardbreak is going to be inserted within a node that is in the `hardbreakFilterNodes`, ignore it.
8
+ export const hardbreakFilterPlugin = $prose((ctx) => {
9
+ const notIn = ctx.get(hardbreakFilterNodes.key)
10
+ return new Plugin({
11
+ key: new PluginKey('MILKDOWN_HARDBREAK_FILTER'),
12
+ filterTransaction: (tr, state) => {
13
+ const isInsertHr = tr.getMeta('hardbreak')
14
+ const [step] = tr.steps
15
+ if (isInsertHr && step) {
16
+ const { from } = step as unknown as { from: number }
17
+ const $from = state.doc.resolve(from)
18
+ let curDepth = $from.depth
19
+ let canApply = true
20
+ while (curDepth > 0) {
21
+ if (notIn.includes($from.node(curDepth).type.name))
22
+ canApply = false
23
+
24
+ curDepth--
25
+ }
26
+ return canApply
27
+ }
28
+ return true
29
+ },
30
+ })
31
+ })
@@ -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,15 @@
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
-
5
- const inlineNodesCursorPluginKey = new PluginKey('MILKDOWN_INLINE_NODES_CURSOR')
4
+ import { $prose } from '@milkdown/utils'
6
5
 
7
6
  /**
8
7
  * This plugin is to solve the chrome 98 bug:
9
8
  * https://discuss.prosemirror.net/t/cursor-jumps-at-the-end-of-line-when-it-betweens-two-inline-nodes/4641
10
9
  */
11
- export const getInlineNodesCursorPlugin = (): Plugin => {
10
+ export const inlineNodesCursorPlugin = $prose(() => {
12
11
  let lock = false
12
+ const inlineNodesCursorPluginKey = new PluginKey('MILKDOWN_INLINE_NODES_CURSOR')
13
13
  const inlineNodesCursorPlugin: Plugin = new Plugin({
14
14
  key: inlineNodesCursorPluginKey,
15
15
  state: {
@@ -90,4 +90,4 @@ export const getInlineNodesCursorPlugin = (): Plugin => {
90
90
  })
91
91
 
92
92
  return inlineNodesCursorPlugin
93
- }
93
+ })
@@ -1,8 +1,8 @@
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
 
@@ -54,4 +54,5 @@ export const defaultConfig: InlineSyncConfig = {
54
54
  },
55
55
  }
56
56
 
57
- export const inlineSyncConfigCtx = createSlice<InlineSyncConfig, 'inlineSyncConfig'>(defaultConfig, 'inlineSyncConfig')
57
+ // export const inlineSyncConfigCtx = createSlice<InlineSyncConfig, 'inlineSyncConfig'>(defaultConfig, 'inlineSyncConfig')
58
+ 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,18 @@
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
+ export const inlineSyncPlugin = $prose((ctx: Ctx) => {
14
12
  let requestId: number | null = null
15
- const inlineSyncPlugin = new Plugin<null>({
13
+ const inlineSyncPluginKey = new PluginKey('MILKDOWN_INLINE_SYNC')
14
+
15
+ return new Plugin<null>({
16
16
  key: inlineSyncPluginKey,
17
17
  state: {
18
18
  init: () => {
@@ -41,7 +41,7 @@ export const getInlineSyncPlugin = (ctx: Ctx) => {
41
41
 
42
42
  const { prevNode, nextNode, text } = context
43
43
 
44
- const { shouldSyncNode } = ctx.get(inlineSyncConfigCtx)
44
+ const { shouldSyncNode } = ctx.get(inlineSyncConfig.key)
45
45
 
46
46
  if (!shouldSyncNode({ prevNode, nextNode, ctx, tr, text }))
47
47
  return null
@@ -58,6 +58,4 @@ export const getInlineSyncPlugin = (ctx: Ctx) => {
58
58
  },
59
59
  },
60
60
  })
61
-
62
- return inlineSyncPlugin
63
- }
61
+ })
@@ -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,15 @@
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
+ export const remarkAddOrderInListPlugin = $remark(() => () => (tree: Node) => {
7
+ visit(tree, 'list', (node: Parent & { ordered?: boolean; start?: number }) => {
8
+ if (node.ordered) {
9
+ const start = node.start ?? 1
10
+ node.children.forEach((child, index) => {
11
+ (child as Node & { label: number }).label = index + start
12
+ })
13
+ }
14
+ })
15
+ })
@@ -0,0 +1,5 @@
1
+ /* Copyright 2021, Milkdown by Mirone. */
2
+ import { $remark } from '@milkdown/utils'
3
+ import remarkInlineLinks from 'remark-inline-links'
4
+
5
+ export const remarkInlineLinkPlugin = $remark(() => remarkInlineLinks)
@@ -0,0 +1,41 @@
1
+ /* Copyright 2021, Milkdown by Mirone. */
2
+ import { $remark } from '@milkdown/utils'
3
+ import type { Literal, Node, Parent } from 'unist'
4
+ import { visit } from 'unist-util-visit'
5
+
6
+ export const remarkLineBreak = $remark(() => () => (tree: Node) => {
7
+ const find = /[\t ]*(?:\r?\n|\r)/g
8
+ visit(tree, 'text', (node: Literal, index: number, parent: Parent) => {
9
+ if (!node.value || typeof node.value !== 'string')
10
+ return
11
+
12
+ const result = []
13
+ let start = 0
14
+
15
+ find.lastIndex = 0
16
+
17
+ let match = find.exec(node.value)
18
+
19
+ while (match) {
20
+ const position = match.index
21
+
22
+ if (start !== position)
23
+ result.push({ type: 'text', value: node.value.slice(start, position) })
24
+
25
+ result.push({ type: 'break', data: { isInline: true } })
26
+ start = position + match[0].length
27
+ match = find.exec(node.value)
28
+ }
29
+
30
+ const hasResultAndIndex = result.length > 0 && parent && typeof index === 'number'
31
+
32
+ if (!hasResultAndIndex)
33
+ return
34
+
35
+ if (start < node.value.length)
36
+ result.push({ type: 'text', value: node.value.slice(start) })
37
+
38
+ parent.children.splice(index, 1, ...result)
39
+ return index + result.length
40
+ })
41
+ })