@milkdown/preset-commonmark 7.4.0 → 7.5.8

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 (69) hide show
  1. package/lib/__internal__/serialize-text.d.ts.map +1 -1
  2. package/lib/__internal__/with-meta.d.ts.map +1 -1
  3. package/lib/composed/commands.d.ts.map +1 -1
  4. package/lib/composed/inputrules.d.ts.map +1 -1
  5. package/lib/composed/keymap.d.ts.map +1 -1
  6. package/lib/composed/schema.d.ts.map +1 -1
  7. package/lib/index.d.ts.map +1 -1
  8. package/lib/index.es.js +544 -400
  9. package/lib/index.es.js.map +1 -1
  10. package/lib/mark/emphasis.d.ts.map +1 -1
  11. package/lib/mark/inline-code.d.ts.map +1 -1
  12. package/lib/mark/link.d.ts.map +1 -1
  13. package/lib/mark/strong.d.ts.map +1 -1
  14. package/lib/node/blockquote.d.ts.map +1 -1
  15. package/lib/node/bullet-list.d.ts.map +1 -1
  16. package/lib/node/code-block.d.ts.map +1 -1
  17. package/lib/node/hardbreak.d.ts.map +1 -1
  18. package/lib/node/heading.d.ts.map +1 -1
  19. package/lib/node/hr.d.ts.map +1 -1
  20. package/lib/node/html.d.ts.map +1 -1
  21. package/lib/node/image.d.ts.map +1 -1
  22. package/lib/node/list-item.d.ts.map +1 -1
  23. package/lib/node/ordered-list.d.ts.map +1 -1
  24. package/lib/node/paragraph.d.ts.map +1 -1
  25. package/lib/plugin/hardbreak-clear-mark-plugin.d.ts.map +1 -1
  26. package/lib/plugin/hardbreak-filter-plugin.d.ts.map +1 -1
  27. package/lib/plugin/inline-nodes-cursor-plugin.d.ts.map +1 -1
  28. package/lib/plugin/remark-add-order-in-list-plugin.d.ts.map +1 -1
  29. package/lib/plugin/remark-html-transformer.d.ts.map +1 -1
  30. package/lib/plugin/remark-inline-link-plugin.d.ts.map +1 -1
  31. package/lib/plugin/remark-line-break.d.ts.map +1 -1
  32. package/lib/plugin/remark-marker-plugin.d.ts.map +1 -1
  33. package/lib/plugin/sync-heading-id-plugin.d.ts.map +1 -1
  34. package/lib/plugin/sync-list-order-plugin.d.ts.map +1 -1
  35. package/package.json +10 -16
  36. package/src/__internal__/serialize-text.ts +3 -4
  37. package/src/__internal__/with-meta.ts +4 -1
  38. package/src/composed/commands.ts +7 -1
  39. package/src/composed/inputrules.ts +14 -2
  40. package/src/composed/keymap.ts +10 -1
  41. package/src/composed/schema.ts +10 -1
  42. package/src/index.ts +16 -2
  43. package/src/mark/emphasis.ts +19 -9
  44. package/src/mark/inline-code.ts +40 -30
  45. package/src/mark/link.ts +55 -45
  46. package/src/mark/strong.ts +13 -7
  47. package/src/node/blockquote.ts +34 -20
  48. package/src/node/bullet-list.ts +20 -7
  49. package/src/node/code-block.ts +43 -18
  50. package/src/node/doc.ts +1 -1
  51. package/src/node/hardbreak.ts +50 -28
  52. package/src/node/heading.ts +44 -27
  53. package/src/node/hr.ts +27 -28
  54. package/src/node/html.ts +10 -8
  55. package/src/node/image.ts +57 -43
  56. package/src/node/list-item.ts +35 -18
  57. package/src/node/ordered-list.ts +31 -15
  58. package/src/node/paragraph.ts +10 -10
  59. package/src/node/text.ts +1 -1
  60. package/src/plugin/hardbreak-clear-mark-plugin.ts +16 -9
  61. package/src/plugin/hardbreak-filter-plugin.ts +5 -3
  62. package/src/plugin/inline-nodes-cursor-plugin.ts +13 -6
  63. package/src/plugin/remark-add-order-in-list-plugin.ts +13 -10
  64. package/src/plugin/remark-html-transformer.ts +24 -17
  65. package/src/plugin/remark-inline-link-plugin.ts +4 -1
  66. package/src/plugin/remark-line-break.ts +39 -26
  67. package/src/plugin/remark-marker-plugin.ts +14 -7
  68. package/src/plugin/sync-heading-id-plugin.ts +13 -8
  69. package/src/plugin/sync-list-order-plugin.ts +12 -11
@@ -9,31 +9,38 @@ export const hardbreakClearMarkPlugin = $prose((ctx) => {
9
9
  return new Plugin({
10
10
  key: new PluginKey('MILKDOWN_HARDBREAK_MARKS'),
11
11
  appendTransaction: (trs, _oldState, newState) => {
12
- if (!trs.length)
13
- return
12
+ if (!trs.length) return
14
13
 
15
14
  const [tr] = trs
16
- if (!tr)
17
- return
15
+ if (!tr) return
18
16
 
19
17
  const [step] = tr.steps
20
18
 
21
19
  const isInsertHr = tr.getMeta('hardbreak')
22
20
  if (isInsertHr) {
23
- if (!(step instanceof ReplaceStep))
24
- return
21
+ if (!(step instanceof ReplaceStep)) return
25
22
 
26
23
  const { from } = step as unknown as { from: number }
27
- return newState.tr.setNodeMarkup(from, hardbreakSchema.type(ctx), undefined, [])
24
+ return newState.tr.setNodeMarkup(
25
+ from,
26
+ hardbreakSchema.type(ctx),
27
+ undefined,
28
+ []
29
+ )
28
30
  }
29
31
 
30
32
  const isAddMarkStep = step instanceof AddMarkStep
31
33
  if (isAddMarkStep) {
32
34
  let _tr = newState.tr
33
- const { from, to } = step as unknown as { from: number, to: number }
35
+ const { from, to } = step as unknown as { from: number; to: number }
34
36
  newState.doc.nodesBetween(from, to, (node, pos) => {
35
37
  if (node.type === hardbreakSchema.type(ctx))
36
- _tr = _tr.setNodeMarkup(pos, hardbreakSchema.type(ctx), undefined, [])
38
+ _tr = _tr.setNodeMarkup(
39
+ pos,
40
+ hardbreakSchema.type(ctx),
41
+ undefined,
42
+ []
43
+ )
37
44
  })
38
45
 
39
46
  return _tr
@@ -3,7 +3,10 @@ import { $ctx, $prose } from '@milkdown/utils'
3
3
  import { withMeta } from '../__internal__'
4
4
 
5
5
  /// This slice contains the nodes that within which the hardbreak will be ignored.
6
- export const hardbreakFilterNodes = $ctx(['table', 'code_block'], 'hardbreakFilterNodes')
6
+ export const hardbreakFilterNodes = $ctx(
7
+ ['table', 'code_block'],
8
+ 'hardbreakFilterNodes'
9
+ )
7
10
 
8
11
  withMeta(hardbreakFilterNodes, {
9
12
  displayName: 'Ctx<hardbreakFilterNodes>',
@@ -25,8 +28,7 @@ export const hardbreakFilterPlugin = $prose((ctx) => {
25
28
  let curDepth = $from.depth
26
29
  let canApply = true
27
30
  while (curDepth > 0) {
28
- if (notIn.includes($from.node(curDepth).type.name))
29
- canApply = false
31
+ if (notIn.includes($from.node(curDepth).type.name)) canApply = false
30
32
 
31
33
  curDepth--
32
34
  }
@@ -6,7 +6,9 @@ import { withMeta } from '../__internal__'
6
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
7
  export const inlineNodesCursorPlugin = $prose(() => {
8
8
  let lock = false
9
- const inlineNodesCursorPluginKey = new PluginKey('MILKDOWN_INLINE_NODES_CURSOR')
9
+ const inlineNodesCursorPluginKey = new PluginKey(
10
+ 'MILKDOWN_INLINE_NODES_CURSOR'
11
+ )
10
12
  const inlineNodesCursorPlugin: Plugin = new Plugin({
11
13
  key: inlineNodesCursorPluginKey,
12
14
  state: {
@@ -14,13 +16,19 @@ export const inlineNodesCursorPlugin = $prose(() => {
14
16
  return false
15
17
  },
16
18
  apply(tr) {
17
- if (!tr.selection.empty)
18
- return false
19
+ if (!tr.selection.empty) return false
19
20
 
20
21
  const pos = tr.selection.$from
21
22
  const left = pos.nodeBefore
22
23
  const right = pos.nodeAfter
23
- if (left && right && left.isInline && !left.isText && right.isInline && !right.isText)
24
+ if (
25
+ left &&
26
+ right &&
27
+ left.isInline &&
28
+ !left.isText &&
29
+ right.isInline &&
30
+ !right.isText
31
+ )
24
32
  return true
25
33
 
26
34
  return false
@@ -46,8 +54,7 @@ export const inlineNodesCursorPlugin = $prose(() => {
46
54
  },
47
55
  compositionstart: (view) => {
48
56
  const active = inlineNodesCursorPlugin.getState(view.state)
49
- if (active)
50
- lock = true
57
+ if (active) lock = true
51
58
 
52
59
  return false
53
60
  },
@@ -3,16 +3,19 @@ import { visit } from 'unist-util-visit'
3
3
  import { withMeta } from '../__internal__'
4
4
 
5
5
  /// This plugin is used to add order in list for remark AST.
6
- export const remarkAddOrderInListPlugin = $remark('remarkAddOrderInList', () => () => (tree) => {
7
- visit(tree, 'list', (node) => {
8
- if (node.ordered) {
9
- const start = node.start ?? 1
10
- node.children.forEach((child, index) => {
11
- (child as unknown as Record<string, number>).label = index + start
12
- })
13
- }
14
- })
15
- })
6
+ export const remarkAddOrderInListPlugin = $remark(
7
+ 'remarkAddOrderInList',
8
+ () => () => (tree) => {
9
+ visit(tree, 'list', (node) => {
10
+ if (node.ordered) {
11
+ const start = node.start ?? 1
12
+ node.children.forEach((child, index) => {
13
+ ;(child as unknown as Record<string, number>).label = index + start
14
+ })
15
+ }
16
+ })
17
+ }
18
+ )
16
19
 
17
20
  withMeta(remarkAddOrderInListPlugin.plugin, {
18
21
  displayName: 'Remark<remarkAddOrderInListPlugin>',
@@ -2,10 +2,16 @@ import { $remark } from '@milkdown/utils'
2
2
  import type { Node } from '@milkdown/transformer'
3
3
  import { withMeta } from '../__internal__'
4
4
 
5
- const isParent = (node: Node): node is Node & { children: Node[] } => !!(node as Node & { children: Node[] }).children
6
- const isHTML = (node: Node): node is Node & { children: Node[], value: unknown } => node.type === 'html'
5
+ const isParent = (node: Node): node is Node & { children: Node[] } =>
6
+ !!(node as Node & { children: Node[] }).children
7
+ const isHTML = (
8
+ node: Node
9
+ ): node is Node & { children: Node[]; value: unknown } => node.type === 'html'
7
10
 
8
- function flatMapWithDepth(ast: Node, fn: (node: Node, index: number, parent: Node | null) => Node[]) {
11
+ function flatMapWithDepth(
12
+ ast: Node,
13
+ fn: (node: Node, index: number, parent: Node | null) => Node[]
14
+ ) {
9
15
  return transform(ast, 0, null)[0]
10
16
 
11
17
  function transform(node: Node, index: number, parent: Node | null) {
@@ -18,8 +24,7 @@ function flatMapWithDepth(ast: Node, fn: (node: Node, index: number, parent: Nod
18
24
  if (xs) {
19
25
  for (let j = 0, m = xs.length; j < m; j++) {
20
26
  const item = xs[j]
21
- if (item)
22
- out.push(item)
27
+ if (item) out.push(item)
23
28
  }
24
29
  }
25
30
  }
@@ -33,20 +38,22 @@ function flatMapWithDepth(ast: Node, fn: (node: Node, index: number, parent: Nod
33
38
 
34
39
  /// @internal
35
40
  /// This plugin should be deprecated after we support HTML.
36
- export const remarkHtmlTransformer = $remark('remarkHTMLTransformer', () => () => (tree: Node) => {
37
- flatMapWithDepth(tree, (node, _index, parent) => {
38
- if (!isHTML(node))
39
- return [node]
41
+ export const remarkHtmlTransformer = $remark(
42
+ 'remarkHTMLTransformer',
43
+ () => () => (tree: Node) => {
44
+ flatMapWithDepth(tree, (node, _index, parent) => {
45
+ if (!isHTML(node)) return [node]
40
46
 
41
- if (parent?.type === 'root') {
42
- node.children = [{ ...node }]
43
- delete node.value;
44
- (node as { type: string }).type = 'paragraph'
45
- }
47
+ if (parent?.type === 'root') {
48
+ node.children = [{ ...node }]
49
+ delete node.value
50
+ ;(node as { type: string }).type = 'paragraph'
51
+ }
46
52
 
47
- return [node]
48
- })
49
- })
53
+ return [node]
54
+ })
55
+ }
56
+ )
50
57
 
51
58
  withMeta(remarkHtmlTransformer.plugin, {
52
59
  displayName: 'Remark<remarkHtmlTransformer>',
@@ -3,7 +3,10 @@ import remarkInlineLinks from 'remark-inline-links'
3
3
  import { withMeta } from '../__internal__'
4
4
 
5
5
  /// This plugin wraps [remark-inline-links](https://github.com/remarkjs/remark-inline-links).
6
- export const remarkInlineLinkPlugin = $remark('remarkInlineLink', () => remarkInlineLinks)
6
+ export const remarkInlineLinkPlugin = $remark(
7
+ 'remarkInlineLink',
8
+ () => remarkInlineLinks
9
+ )
7
10
 
8
11
  withMeta(remarkInlineLinkPlugin.plugin, {
9
12
  displayName: 'Remark<remarkInlineLinkPlugin>',
@@ -6,42 +6,55 @@ import { withMeta } from '../__internal__'
6
6
  /// This plugin is used to add inline line break for remark AST.
7
7
  /// The inline line break should be treated as a `space`.
8
8
  /// And the normal line break should be treated as a `LF`.
9
- export const remarkLineBreak = $remark('remarkLineBreak', () => () => (tree: Node) => {
10
- const find = /[\t ]*(?:\r?\n|\r)/g
11
- visit(tree, 'text', (node: Node & { value: string }, index: number, parent: Node & { children: Node[] }) => {
12
- if (!node.value || typeof node.value !== 'string')
13
- return
9
+ export const remarkLineBreak = $remark(
10
+ 'remarkLineBreak',
11
+ () => () => (tree: Node) => {
12
+ const find = /[\t ]*(?:\r?\n|\r)/g
13
+ visit(
14
+ tree,
15
+ 'text',
16
+ (
17
+ node: Node & { value: string },
18
+ index: number,
19
+ parent: Node & { children: Node[] }
20
+ ) => {
21
+ if (!node.value || typeof node.value !== 'string') return
14
22
 
15
- const result = []
16
- let start = 0
23
+ const result = []
24
+ let start = 0
17
25
 
18
- find.lastIndex = 0
26
+ find.lastIndex = 0
19
27
 
20
- let match = find.exec(node.value)
28
+ let match = find.exec(node.value)
21
29
 
22
- while (match) {
23
- const position = match.index
30
+ while (match) {
31
+ const position = match.index
24
32
 
25
- if (start !== position)
26
- result.push({ type: 'text', value: node.value.slice(start, position) })
33
+ if (start !== position)
34
+ result.push({
35
+ type: 'text',
36
+ value: node.value.slice(start, position),
37
+ })
27
38
 
28
- result.push({ type: 'break', data: { isInline: true } })
29
- start = position + match[0].length
30
- match = find.exec(node.value)
31
- }
39
+ result.push({ type: 'break', data: { isInline: true } })
40
+ start = position + match[0].length
41
+ match = find.exec(node.value)
42
+ }
32
43
 
33
- const hasResultAndIndex = result.length > 0 && parent && typeof index === 'number'
44
+ const hasResultAndIndex =
45
+ result.length > 0 && parent && typeof index === 'number'
34
46
 
35
- if (!hasResultAndIndex)
36
- return
47
+ if (!hasResultAndIndex) return
37
48
 
38
- if (start < node.value.length)
39
- result.push({ type: 'text', value: node.value.slice(start) })
49
+ if (start < node.value.length)
50
+ result.push({ type: 'text', value: node.value.slice(start) })
40
51
 
41
- parent.children.splice(index, 1, ...result)
42
- return index + result.length
43
- })
44
- })
52
+ parent.children.splice(index, 1, ...result)
53
+ return index + result.length
54
+ }
55
+ )
56
+ }
57
+ )
45
58
 
46
59
  withMeta(remarkLineBreak.plugin, {
47
60
  displayName: 'Remark<remarkLineBreak>',
@@ -4,14 +4,21 @@ import { visit } from 'unist-util-visit'
4
4
  import { withMeta } from '../__internal__'
5
5
 
6
6
  /// This plugin is used to keep the marker (`_` and `*`) of emphasis and strong nodes.
7
- export const remarkMarker = $remark('remarkMarker', () => () => (tree, file) => {
8
- const getMarker = (node: Node) => {
9
- return (file.value as string).charAt(node.position!.start.offset!)
7
+ export const remarkMarker = $remark(
8
+ 'remarkMarker',
9
+ () => () => (tree, file) => {
10
+ const getMarker = (node: Node) => {
11
+ return (file.value as string).charAt(node.position!.start.offset!)
12
+ }
13
+ visit(
14
+ tree,
15
+ (node: Node) => ['strong', 'emphasis'].includes(node.type),
16
+ (node: Node) => {
17
+ ;(node as Node & { marker: string }).marker = getMarker(node)
18
+ }
19
+ )
10
20
  }
11
- visit(tree, (node: Node) => ['strong', 'emphasis'].includes(node.type), (node: Node) => {
12
- (node as Node & { marker: string }).marker = getMarker(node)
13
- })
14
- })
21
+ )
15
22
 
16
23
  withMeta(remarkMarker.plugin, {
17
24
  displayName: 'Remark<remarkMarker>',
@@ -10,21 +10,26 @@ export const syncHeadingIdPlugin = $prose((ctx) => {
10
10
  const headingIdPluginKey = new PluginKey('MILKDOWN_HEADING_ID')
11
11
 
12
12
  const updateId = (view: EditorView) => {
13
- if (view.composing)
14
- return
13
+ if (view.composing) return
15
14
 
16
15
  const getId = ctx.get(headingIdGenerator.key)
17
16
  const tr = view.state.tr.setMeta('addToHistory', false)
18
17
 
19
18
  let found = false
19
+ const idMap: Record<string, number> = {}
20
20
 
21
21
  view.state.doc.descendants((node, pos) => {
22
22
  if (node.type === headingSchema.type(ctx)) {
23
- if (node.textContent.trim().length === 0)
24
- return
23
+ if (node.textContent.trim().length === 0) return
25
24
 
26
25
  const attrs = node.attrs
27
- const id = getId(node)
26
+ let id = getId(node)
27
+ if (idMap[id]) {
28
+ idMap[id]! += 1
29
+ id += `-#${idMap[id]}`
30
+ } else {
31
+ idMap[id] = 1
32
+ }
28
33
 
29
34
  if (attrs.id !== id) {
30
35
  found = true
@@ -36,8 +41,7 @@ export const syncHeadingIdPlugin = $prose((ctx) => {
36
41
  }
37
42
  })
38
43
 
39
- if (found)
40
- view.dispatch(tr)
44
+ if (found) view.dispatch(tr)
41
45
  }
42
46
 
43
47
  return new Plugin({
@@ -46,7 +50,8 @@ export const syncHeadingIdPlugin = $prose((ctx) => {
46
50
  updateId(view)
47
51
 
48
52
  return {
49
- update: (view) => {
53
+ update: (view, prevState) => {
54
+ if (view.state.doc.eq(prevState.doc)) return
50
55
  updateId(view)
51
56
  },
52
57
  }
@@ -10,14 +10,16 @@ import { withMeta } from '../__internal__'
10
10
  /// This plugin is used to keep the label of list item up to date in ordered list.
11
11
  export const syncListOrderPlugin = $prose((ctx) => {
12
12
  const syncOrderLabel = (view: EditorView) => {
13
- if (view.composing || !view.editable)
14
- return
13
+ if (view.composing || !view.editable) return
15
14
 
16
15
  const orderedListType = orderedListSchema.type(ctx)
17
16
  const bulletListType = bulletListSchema.type(ctx)
18
17
  const listItemType = listItemSchema.type(ctx)
19
18
  const state = view.state
20
- const handleNodeItem = (attrs: Record<string, any>, index: number): boolean => {
19
+ const handleNodeItem = (
20
+ attrs: Record<string, any>,
21
+ index: number
22
+ ): boolean => {
21
23
  let changed = false
22
24
  const expectedLabel = `${index + 1}.`
23
25
  if (attrs.label !== expectedLabel) {
@@ -41,14 +43,15 @@ export const syncListOrderPlugin = $prose((ctx) => {
41
43
  if (child.type === listItemType) {
42
44
  const attrs = { ...child.attrs }
43
45
  const changed = handleNodeItem(attrs, index)
44
- if (changed)
45
- tr = tr.setNodeMarkup(pos, undefined, attrs)
46
+ if (changed) tr = tr.setNodeMarkup(pos, undefined, attrs)
46
47
  }
47
48
  return false
48
49
  })
49
50
  }
50
- }
51
- else if (node.type === listItemType && parent?.type === orderedListType) {
51
+ } else if (
52
+ node.type === listItemType &&
53
+ parent?.type === orderedListType
54
+ ) {
52
55
  const attrs = { ...node.attrs }
53
56
  let changed = false
54
57
  if (attrs.listType !== 'ordered') {
@@ -57,8 +60,7 @@ export const syncListOrderPlugin = $prose((ctx) => {
57
60
  }
58
61
 
59
62
  const base = parent?.maybeChild(0)
60
- if (base)
61
- changed = handleNodeItem(attrs, index)
63
+ if (base) changed = handleNodeItem(attrs, index)
62
64
 
63
65
  if (changed) {
64
66
  tr = tr.setNodeMarkup(pos, undefined, attrs)
@@ -67,8 +69,7 @@ export const syncListOrderPlugin = $prose((ctx) => {
67
69
  }
68
70
  })
69
71
 
70
- if (needDispatch)
71
- view.dispatch(tr.setMeta('addToHistory', false))
72
+ if (needDispatch) view.dispatch(tr.setMeta('addToHistory', false))
72
73
  }
73
74
  return new Plugin({
74
75
  key: new PluginKey('MILKDOWN_KEEP_LIST_ORDER'),