@milkdown/preset-commonmark 7.2.3 → 7.3.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 (54) hide show
  1. package/lib/composed/plugins.d.ts.map +1 -1
  2. package/lib/index.es.js +608 -594
  3. package/lib/index.es.js.map +1 -1
  4. package/lib/mark/emphasis.d.ts.map +1 -1
  5. package/lib/mark/link.d.ts.map +1 -1
  6. package/lib/mark/strong.d.ts.map +1 -1
  7. package/lib/node/blockquote.d.ts.map +1 -1
  8. package/lib/node/bullet-list.d.ts.map +1 -1
  9. package/lib/node/code-block.d.ts.map +1 -1
  10. package/lib/node/list-item.d.ts.map +1 -1
  11. package/lib/node/ordered-list.d.ts.map +1 -1
  12. package/lib/node/paragraph.d.ts.map +1 -1
  13. package/lib/plugin/inline-sync-plugin/context.d.ts.map +1 -1
  14. package/lib/plugin/inline-sync-plugin/regexp.d.ts +5 -0
  15. package/lib/plugin/inline-sync-plugin/regexp.d.ts.map +1 -1
  16. package/lib/plugin/inline-sync-plugin/utils.d.ts +1 -0
  17. package/lib/plugin/inline-sync-plugin/utils.d.ts.map +1 -1
  18. package/lib/plugin/remark-add-order-in-list-plugin.d.ts +1 -1
  19. package/lib/plugin/remark-add-order-in-list-plugin.d.ts.map +1 -1
  20. package/lib/plugin/remark-html-transformer.d.ts +1 -1
  21. package/lib/plugin/remark-html-transformer.d.ts.map +1 -1
  22. package/lib/plugin/remark-inline-link-plugin.d.ts +1 -1
  23. package/lib/plugin/remark-inline-link-plugin.d.ts.map +1 -1
  24. package/lib/plugin/remark-line-break.d.ts +1 -1
  25. package/lib/plugin/remark-line-break.d.ts.map +1 -1
  26. package/lib/plugin/remark-marker-plugin.d.ts +1 -1
  27. package/lib/plugin/remark-marker-plugin.d.ts.map +1 -1
  28. package/package.json +8 -10
  29. package/src/composed/plugins.ts +1 -1
  30. package/src/mark/emphasis.ts +2 -4
  31. package/src/mark/inline-code.ts +4 -4
  32. package/src/mark/link.ts +5 -5
  33. package/src/mark/strong.ts +2 -5
  34. package/src/node/blockquote.ts +2 -2
  35. package/src/node/bullet-list.ts +2 -2
  36. package/src/node/code-block.ts +2 -2
  37. package/src/node/hardbreak.ts +2 -2
  38. package/src/node/heading.ts +10 -10
  39. package/src/node/hr.ts +5 -5
  40. package/src/node/image.ts +6 -6
  41. package/src/node/list-item.ts +8 -7
  42. package/src/node/ordered-list.ts +3 -3
  43. package/src/node/paragraph.ts +1 -1
  44. package/src/plugin/hardbreak-clear-mark-plugin.ts +4 -4
  45. package/src/plugin/inline-sync-plugin/context.ts +8 -5
  46. package/src/plugin/inline-sync-plugin/regexp.ts +7 -0
  47. package/src/plugin/inline-sync-plugin/utils.ts +16 -1
  48. package/src/plugin/remark-add-order-in-list-plugin.ts +9 -5
  49. package/src/plugin/remark-html-transformer.ts +13 -8
  50. package/src/plugin/remark-inline-link-plugin.ts +7 -2
  51. package/src/plugin/remark-line-break.ts +9 -4
  52. package/src/plugin/remark-marker-plugin.ts +10 -5
  53. package/src/plugin/sync-heading-id-plugin.ts +1 -1
  54. package/src/plugin/sync-list-order-plugin.ts +4 -4
@@ -6,7 +6,7 @@ import { hardbreakSchema } from '../node'
6
6
  import { withMeta } from '../__internal__'
7
7
 
8
8
  /// This plugin is used to clear the marks around the hardbreak node.
9
- export const hardbreakClearMarkPlugin = $prose(() => {
9
+ export const hardbreakClearMarkPlugin = $prose((ctx) => {
10
10
  return new Plugin({
11
11
  key: new PluginKey('MILKDOWN_HARDBREAK_MARKS'),
12
12
  appendTransaction: (trs, _oldState, newState) => {
@@ -25,7 +25,7 @@ export const hardbreakClearMarkPlugin = $prose(() => {
25
25
  return
26
26
 
27
27
  const { from } = step as unknown as { from: number }
28
- return newState.tr.setNodeMarkup(from, hardbreakSchema.type(), undefined, [])
28
+ return newState.tr.setNodeMarkup(from, hardbreakSchema.type(ctx), undefined, [])
29
29
  }
30
30
 
31
31
  const isAddMarkStep = step instanceof AddMarkStep
@@ -33,8 +33,8 @@ export const hardbreakClearMarkPlugin = $prose(() => {
33
33
  let _tr = newState.tr
34
34
  const { from, to } = step as unknown as { from: number; to: number }
35
35
  newState.doc.nodesBetween(from, to, (node, pos) => {
36
- if (node.type === hardbreakSchema.type())
37
- _tr = _tr.setNodeMarkup(pos, hardbreakSchema.type(), undefined, [])
36
+ if (node.type === hardbreakSchema.type(ctx))
37
+ _tr = _tr.setNodeMarkup(pos, hardbreakSchema.type(ctx), undefined, [])
38
38
  })
39
39
 
40
40
  return _tr
@@ -6,7 +6,8 @@ import type { EditorState } from '@milkdown/prose/state'
6
6
  import { pipe } from '@milkdown/utils'
7
7
 
8
8
  import { inlineSyncConfig } from './config'
9
- import { calculatePlaceholder, keepLink, replacePunctuation } from './utils'
9
+ import { calculatePlaceholder, keepLink, mergeSlash, replacePunctuation } from './utils'
10
+ import { asterisk, asteriskHolder, underline, underlineHolder } from './regexp'
10
11
 
11
12
  export interface InlineSyncContext {
12
13
  text: string
@@ -23,9 +24,7 @@ const getMarkdown = (ctx: Ctx, state: EditorState, node: Node, globalNode: Node[
23
24
  const serializer = ctx.get(serializerCtx)
24
25
  const doc = state.schema.topNodeType.create(undefined, [node, ...globalNode])
25
26
 
26
- const markdown = serializer(doc)
27
-
28
- return markdown
27
+ return serializer(doc)
29
28
  }
30
29
 
31
30
  const addPlaceholder = (ctx: Ctx, markdown: string) => {
@@ -36,7 +35,7 @@ const addPlaceholder = (ctx: Ctx, markdown: string) => {
36
35
 
37
36
  const movePlaceholder = (text: string) => config.movePlaceholder(holePlaceholder, text)
38
37
 
39
- const handleText = pipe(replacePunctuation(holePlaceholder), movePlaceholder, keepLink)
38
+ const handleText = pipe(replacePunctuation(holePlaceholder), movePlaceholder, keepLink, mergeSlash)
40
39
 
41
40
  let text = handleText(firstLine)
42
41
  const placeholder = calculatePlaceholder(config.placeholderConfig)(text)
@@ -103,6 +102,10 @@ export const getContextByState = (ctx: Ctx, state: EditorState): InlineSyncConte
103
102
  // @ts-expect-error hijack the mark attribute
104
103
  link.attrs.href = link.attrs.href.replace(placeholder, '')
105
104
  }
105
+ if (node.text?.includes(asteriskHolder) || node.text?.includes(underlineHolder)) {
106
+ // @ts-expect-error hijack the attribute
107
+ node.text = node.text.replaceAll(asteriskHolder, asterisk).replaceAll(underlineHolder, underline)
108
+ }
106
109
  })
107
110
 
108
111
  return {
@@ -6,3 +6,10 @@ export const keepLinkRegexp = /\[(?<span>((www|https:\/\/|http:\/\/)[^\s\]]+))]\
6
6
 
7
7
  export const punctuationRegexp = (holePlaceholder: string) =>
8
8
  new RegExp(`\\\\(?=[^\\w\\s${holePlaceholder}\\\\]|_)`, 'g')
9
+
10
+ export const ZERO_WIDTH_SPACE = '\u200B'
11
+
12
+ export const asterisk = `${ZERO_WIDTH_SPACE}*`
13
+ export const asteriskHolder = `${ZERO_WIDTH_SPACE}*`
14
+ export const underline = `${ZERO_WIDTH_SPACE}_`
15
+ export const underlineHolder = `${ZERO_WIDTH_SPACE}⎽`
@@ -3,7 +3,14 @@
3
3
  import type { Node } from '@milkdown/prose/model'
4
4
 
5
5
  import type { SyncNodePlaceholder } from './config'
6
- import { keepLinkRegexp, punctuationRegexp } from './regexp'
6
+ import {
7
+ asterisk,
8
+ asteriskHolder,
9
+ keepLinkRegexp,
10
+ punctuationRegexp,
11
+ underline,
12
+ underlineHolder,
13
+ } from './regexp'
7
14
 
8
15
  export const keepLink = (str: string) => {
9
16
  let text = str
@@ -17,6 +24,14 @@ export const keepLink = (str: string) => {
17
24
  return text
18
25
  }
19
26
 
27
+ export const mergeSlash = (str: string) => {
28
+ return str
29
+ .replaceAll(/\\\\\*/g, asterisk)
30
+ .replaceAll(/\\\\_/g, underline)
31
+ .replaceAll(asterisk, asteriskHolder)
32
+ .replaceAll(underline, underlineHolder)
33
+ }
34
+
20
35
  export const swap = (text: string, first: number, last: number) => {
21
36
  const arr = text.split('')
22
37
  const temp = arr[first]
@@ -1,22 +1,26 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
2
  import { $remark } from '@milkdown/utils'
3
- import type { Node, Parent } from 'unist'
4
3
  import { visit } from 'unist-util-visit'
5
4
  import { withMeta } from '../__internal__'
6
5
 
7
6
  /// This plugin is used to add order in list for remark AST.
8
- export const remarkAddOrderInListPlugin = $remark(() => () => (tree: Node) => {
9
- visit(tree, 'list', (node: Parent & { ordered?: boolean; start?: number }) => {
7
+ export const remarkAddOrderInListPlugin = $remark('remarkAddOrderInList', () => () => (tree) => {
8
+ visit(tree, 'list', (node) => {
10
9
  if (node.ordered) {
11
10
  const start = node.start ?? 1
12
11
  node.children.forEach((child, index) => {
13
- (child as Node & { label: number }).label = index + start
12
+ (child as unknown as Record<string, number>).label = index + start
14
13
  })
15
14
  }
16
15
  })
17
16
  })
18
17
 
19
- withMeta(remarkAddOrderInListPlugin, {
18
+ withMeta(remarkAddOrderInListPlugin.plugin, {
20
19
  displayName: 'Remark<remarkAddOrderInListPlugin>',
21
20
  group: 'Remark',
22
21
  })
22
+
23
+ withMeta(remarkAddOrderInListPlugin.options, {
24
+ displayName: 'RemarkConfig<remarkAddOrderInListPlugin>',
25
+ group: 'Remark',
26
+ })
@@ -1,10 +1,10 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
2
  import { $remark } from '@milkdown/utils'
3
- import type { Literal, Node, Parent } from 'unist'
3
+ import type { Node } from '@milkdown/transformer'
4
4
  import { withMeta } from '../__internal__'
5
5
 
6
- const isParent = (node: Node): node is Parent => !!(node as Parent).children
7
- const isHTML = (node: Node): node is Literal<string> => node.type === 'html'
6
+ const isParent = (node: Node): node is Node & { children: Node[] } => !!(node as Node & { children: Node[] }).children
7
+ const isHTML = (node: Node): node is Node & { children: Node[]; value: unknown } => node.type === 'html'
8
8
 
9
9
  function flatMapWithDepth(ast: Node, fn: (node: Node, index: number, parent: Node | null) => Node[]) {
10
10
  return transform(ast, 0, null)[0]
@@ -34,22 +34,27 @@ function flatMapWithDepth(ast: Node, fn: (node: Node, index: number, parent: Nod
34
34
 
35
35
  /// @internal
36
36
  /// This plugin should be deprecated after we support HTML.
37
- export const remarkHtmlTransformer = $remark(() => () => (tree: Node) => {
37
+ export const remarkHtmlTransformer = $remark('remarkHTMLTransformer', () => () => (tree: Node) => {
38
38
  flatMapWithDepth(tree, (node, _index, parent) => {
39
39
  if (!isHTML(node))
40
40
  return [node]
41
41
 
42
42
  if (parent?.type === 'root') {
43
- (node as Literal & { children: Literal[] }).children = [{ ...node }]
44
- delete (node as Literal).value
45
- node.type = 'paragraph'
43
+ node.children = [{ ...node }]
44
+ delete node.value;
45
+ (node as { type: string }).type = 'paragraph'
46
46
  }
47
47
 
48
48
  return [node]
49
49
  })
50
50
  })
51
51
 
52
- withMeta(remarkHtmlTransformer, {
52
+ withMeta(remarkHtmlTransformer.plugin, {
53
53
  displayName: 'Remark<remarkHtmlTransformer>',
54
54
  group: 'Remark',
55
55
  })
56
+
57
+ withMeta(remarkHtmlTransformer.options, {
58
+ displayName: 'RemarkConfig<remarkHtmlTransformer>',
59
+ group: 'Remark',
60
+ })
@@ -4,9 +4,14 @@ import remarkInlineLinks from 'remark-inline-links'
4
4
  import { withMeta } from '../__internal__'
5
5
 
6
6
  /// This plugin wraps [remark-inline-links](https://github.com/remarkjs/remark-inline-links).
7
- export const remarkInlineLinkPlugin = $remark(() => remarkInlineLinks)
7
+ export const remarkInlineLinkPlugin = $remark('remarkInlineLink', () => remarkInlineLinks)
8
8
 
9
- withMeta(remarkInlineLinkPlugin, {
9
+ withMeta(remarkInlineLinkPlugin.plugin, {
10
10
  displayName: 'Remark<remarkInlineLinkPlugin>',
11
11
  group: 'Remark',
12
12
  })
13
+
14
+ withMeta(remarkInlineLinkPlugin.options, {
15
+ displayName: 'RemarkConfig<remarkInlineLinkPlugin>',
16
+ group: 'Remark',
17
+ })
@@ -1,15 +1,15 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
2
  import { $remark } from '@milkdown/utils'
3
- import type { Literal, Node, Parent } from 'unist'
3
+ import type { Node } from '@milkdown/transformer'
4
4
  import { visit } from 'unist-util-visit'
5
5
  import { withMeta } from '../__internal__'
6
6
 
7
7
  /// This plugin is used to add inline line break for remark AST.
8
8
  /// The inline line break should be treated as a `space`.
9
9
  /// And the normal line break should be treated as a `LF`.
10
- export const remarkLineBreak = $remark(() => () => (tree: Node) => {
10
+ export const remarkLineBreak = $remark('remarkLineBreak', () => () => (tree: Node) => {
11
11
  const find = /[\t ]*(?:\r?\n|\r)/g
12
- visit(tree, 'text', (node: Literal, index: number, parent: Parent) => {
12
+ visit(tree, 'text', (node: Node & { value: string }, index: number, parent: Node & { children: Node[] }) => {
13
13
  if (!node.value || typeof node.value !== 'string')
14
14
  return
15
15
 
@@ -44,7 +44,12 @@ export const remarkLineBreak = $remark(() => () => (tree: Node) => {
44
44
  })
45
45
  })
46
46
 
47
- withMeta(remarkLineBreak, {
47
+ withMeta(remarkLineBreak.plugin, {
48
48
  displayName: 'Remark<remarkLineBreak>',
49
49
  group: 'Remark',
50
50
  })
51
+
52
+ withMeta(remarkLineBreak.options, {
53
+ displayName: 'RemarkConfig<remarkLineBreak>',
54
+ group: 'Remark',
55
+ })
@@ -1,20 +1,25 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
2
  import { $remark } from '@milkdown/utils'
3
- import type { Node } from 'unist'
4
- import type { VFile } from 'vfile'
3
+ import type { Node } from '@milkdown/transformer'
5
4
  import { visit } from 'unist-util-visit'
6
5
  import { withMeta } from '../__internal__'
7
6
 
8
- export const remarkMarker = $remark(() => () => (tree: Node, file: VFile) => {
7
+ /// This plugin is used to keep the marker (`_` and `*`) of emphasis and strong nodes.
8
+ export const remarkMarker = $remark('remarkMarker', () => () => (tree, file) => {
9
9
  const getMarker = (node: Node) => {
10
10
  return (file.value as string).charAt(node.position!.start.offset!)
11
11
  }
12
- visit(tree, node => ['strong', 'emphasis'].includes(node.type), (node: Node) => {
12
+ visit(tree, (node: Node) => ['strong', 'emphasis'].includes(node.type), (node: Node) => {
13
13
  (node as Node & { marker: string }).marker = getMarker(node)
14
14
  })
15
15
  })
16
16
 
17
- withMeta(remarkMarker, {
17
+ withMeta(remarkMarker.plugin, {
18
18
  displayName: 'Remark<remarkMarker>',
19
19
  group: 'Remark',
20
20
  })
21
+
22
+ withMeta(remarkMarker.options, {
23
+ displayName: 'RemarkConfig<remarkMarker>',
24
+ group: 'Remark',
25
+ })
@@ -20,7 +20,7 @@ export const syncHeadingIdPlugin = $prose((ctx) => {
20
20
  let found = false
21
21
 
22
22
  view.state.doc.descendants((node, pos) => {
23
- if (node.type === headingSchema.type()) {
23
+ if (node.type === headingSchema.type(ctx)) {
24
24
  if (node.textContent.trim().length === 0)
25
25
  return
26
26
 
@@ -9,14 +9,14 @@ import { bulletListSchema } from '../node'
9
9
  import { withMeta } from '../__internal__'
10
10
 
11
11
  /// This plugin is used to keep the label of list item up to date in ordered list.
12
- export const syncListOrderPlugin = $prose(() => {
12
+ export const syncListOrderPlugin = $prose((ctx) => {
13
13
  const syncOrderLabel = (view: EditorView) => {
14
14
  if (view.composing || !view.editable)
15
15
  return
16
16
 
17
- const orderedListType = orderedListSchema.type()
18
- const bulletListType = bulletListSchema.type()
19
- const listItemType = listItemSchema.type()
17
+ const orderedListType = orderedListSchema.type(ctx)
18
+ const bulletListType = bulletListSchema.type(ctx)
19
+ const listItemType = listItemSchema.type(ctx)
20
20
  const state = view.state
21
21
  const handleNodeItem = (attrs: Record<string, any>, index: number): boolean => {
22
22
  let changed = false