@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.
- package/lib/__internal__/serialize-text.d.ts.map +1 -1
- package/lib/__internal__/with-meta.d.ts.map +1 -1
- package/lib/composed/commands.d.ts.map +1 -1
- package/lib/composed/inputrules.d.ts.map +1 -1
- package/lib/composed/keymap.d.ts.map +1 -1
- package/lib/composed/schema.d.ts.map +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.es.js +544 -400
- package/lib/index.es.js.map +1 -1
- package/lib/mark/emphasis.d.ts.map +1 -1
- package/lib/mark/inline-code.d.ts.map +1 -1
- package/lib/mark/link.d.ts.map +1 -1
- package/lib/mark/strong.d.ts.map +1 -1
- package/lib/node/blockquote.d.ts.map +1 -1
- package/lib/node/bullet-list.d.ts.map +1 -1
- package/lib/node/code-block.d.ts.map +1 -1
- package/lib/node/hardbreak.d.ts.map +1 -1
- package/lib/node/heading.d.ts.map +1 -1
- package/lib/node/hr.d.ts.map +1 -1
- package/lib/node/html.d.ts.map +1 -1
- package/lib/node/image.d.ts.map +1 -1
- package/lib/node/list-item.d.ts.map +1 -1
- package/lib/node/ordered-list.d.ts.map +1 -1
- package/lib/node/paragraph.d.ts.map +1 -1
- package/lib/plugin/hardbreak-clear-mark-plugin.d.ts.map +1 -1
- package/lib/plugin/hardbreak-filter-plugin.d.ts.map +1 -1
- package/lib/plugin/inline-nodes-cursor-plugin.d.ts.map +1 -1
- package/lib/plugin/remark-add-order-in-list-plugin.d.ts.map +1 -1
- package/lib/plugin/remark-html-transformer.d.ts.map +1 -1
- package/lib/plugin/remark-inline-link-plugin.d.ts.map +1 -1
- package/lib/plugin/remark-line-break.d.ts.map +1 -1
- package/lib/plugin/remark-marker-plugin.d.ts.map +1 -1
- package/lib/plugin/sync-heading-id-plugin.d.ts.map +1 -1
- package/lib/plugin/sync-list-order-plugin.d.ts.map +1 -1
- package/package.json +10 -16
- package/src/__internal__/serialize-text.ts +3 -4
- package/src/__internal__/with-meta.ts +4 -1
- package/src/composed/commands.ts +7 -1
- package/src/composed/inputrules.ts +14 -2
- package/src/composed/keymap.ts +10 -1
- package/src/composed/schema.ts +10 -1
- package/src/index.ts +16 -2
- package/src/mark/emphasis.ts +19 -9
- package/src/mark/inline-code.ts +40 -30
- package/src/mark/link.ts +55 -45
- package/src/mark/strong.ts +13 -7
- package/src/node/blockquote.ts +34 -20
- package/src/node/bullet-list.ts +20 -7
- package/src/node/code-block.ts +43 -18
- package/src/node/doc.ts +1 -1
- package/src/node/hardbreak.ts +50 -28
- package/src/node/heading.ts +44 -27
- package/src/node/hr.ts +27 -28
- package/src/node/html.ts +10 -8
- package/src/node/image.ts +57 -43
- package/src/node/list-item.ts +35 -18
- package/src/node/ordered-list.ts +31 -15
- package/src/node/paragraph.ts +10 -10
- package/src/node/text.ts +1 -1
- package/src/plugin/hardbreak-clear-mark-plugin.ts +16 -9
- package/src/plugin/hardbreak-filter-plugin.ts +5 -3
- package/src/plugin/inline-nodes-cursor-plugin.ts +13 -6
- package/src/plugin/remark-add-order-in-list-plugin.ts +13 -10
- package/src/plugin/remark-html-transformer.ts +24 -17
- package/src/plugin/remark-inline-link-plugin.ts +4 -1
- package/src/plugin/remark-line-break.ts +39 -26
- package/src/plugin/remark-marker-plugin.ts +14 -7
- package/src/plugin/sync-heading-id-plugin.ts +13 -8
- package/src/plugin/sync-list-order-plugin.ts +12 -11
package/src/mark/link.ts
CHANGED
|
@@ -14,7 +14,7 @@ withMeta(linkAttr, {
|
|
|
14
14
|
})
|
|
15
15
|
|
|
16
16
|
/// Link mark schema.
|
|
17
|
-
export const linkSchema = $markSchema('link', ctx => ({
|
|
17
|
+
export const linkSchema = $markSchema('link', (ctx) => ({
|
|
18
18
|
attrs: {
|
|
19
19
|
href: {},
|
|
20
20
|
title: { default: null },
|
|
@@ -23,16 +23,18 @@ export const linkSchema = $markSchema('link', ctx => ({
|
|
|
23
23
|
{
|
|
24
24
|
tag: 'a[href]',
|
|
25
25
|
getAttrs: (dom) => {
|
|
26
|
-
if (!(dom instanceof HTMLElement))
|
|
27
|
-
throw expectDomTypeError(dom)
|
|
26
|
+
if (!(dom instanceof HTMLElement)) throw expectDomTypeError(dom)
|
|
28
27
|
|
|
29
|
-
return {
|
|
28
|
+
return {
|
|
29
|
+
href: dom.getAttribute('href'),
|
|
30
|
+
title: dom.getAttribute('title'),
|
|
31
|
+
}
|
|
30
32
|
},
|
|
31
33
|
},
|
|
32
34
|
],
|
|
33
|
-
toDOM: mark => ['a', { ...ctx.get(linkAttr.key)(mark), ...mark.attrs }],
|
|
35
|
+
toDOM: (mark) => ['a', { ...ctx.get(linkAttr.key)(mark), ...mark.attrs }],
|
|
34
36
|
parseMarkdown: {
|
|
35
|
-
match: node => node.type === 'link',
|
|
37
|
+
match: (node) => node.type === 'link',
|
|
36
38
|
runner: (state, node, markType) => {
|
|
37
39
|
const url = node.url as string
|
|
38
40
|
const title = node.title as string
|
|
@@ -42,7 +44,7 @@ export const linkSchema = $markSchema('link', ctx => ({
|
|
|
42
44
|
},
|
|
43
45
|
},
|
|
44
46
|
toMarkdown: {
|
|
45
|
-
match: mark => mark.type.name === 'link',
|
|
47
|
+
match: (mark) => mark.type.name === 'link',
|
|
46
48
|
runner: (state, mark) => {
|
|
47
49
|
state.withMark(mark, 'link', undefined, {
|
|
48
50
|
title: mark.attrs.title,
|
|
@@ -64,7 +66,12 @@ export interface UpdateLinkCommandPayload {
|
|
|
64
66
|
}
|
|
65
67
|
/// A command to toggle the link mark.
|
|
66
68
|
/// You can pass the `href` and `title` to the link.
|
|
67
|
-
export const toggleLinkCommand = $command(
|
|
69
|
+
export const toggleLinkCommand = $command(
|
|
70
|
+
'ToggleLink',
|
|
71
|
+
(ctx) =>
|
|
72
|
+
(payload: UpdateLinkCommandPayload = {}) =>
|
|
73
|
+
toggleMark(linkSchema.type(ctx), payload)
|
|
74
|
+
)
|
|
68
75
|
|
|
69
76
|
withMeta(toggleLinkCommand, {
|
|
70
77
|
displayName: 'Command<toggleLinkCommand>',
|
|
@@ -73,48 +80,51 @@ withMeta(toggleLinkCommand, {
|
|
|
73
80
|
|
|
74
81
|
/// A command to update the link mark.
|
|
75
82
|
/// You can pass the `href` and `title` to update the link.
|
|
76
|
-
export const updateLinkCommand = $command(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
83
|
+
export const updateLinkCommand = $command(
|
|
84
|
+
'UpdateLink',
|
|
85
|
+
(ctx) =>
|
|
86
|
+
(payload: UpdateLinkCommandPayload = {}) =>
|
|
87
|
+
(state, dispatch) => {
|
|
88
|
+
if (!dispatch) return false
|
|
89
|
+
|
|
90
|
+
let node: ProseNode | undefined
|
|
91
|
+
let pos = -1
|
|
92
|
+
const { selection } = state
|
|
93
|
+
const { from, to } = selection
|
|
94
|
+
state.doc.nodesBetween(from, from === to ? to + 1 : to, (n, p) => {
|
|
95
|
+
if (linkSchema.type(ctx).isInSet(n.marks)) {
|
|
96
|
+
node = n
|
|
97
|
+
pos = p
|
|
98
|
+
return false
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return undefined
|
|
102
|
+
})
|
|
93
103
|
|
|
94
|
-
|
|
95
|
-
return false
|
|
104
|
+
if (!node) return false
|
|
96
105
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
return false
|
|
106
|
+
const mark = node.marks.find(({ type }) => type === linkSchema.type(ctx))
|
|
107
|
+
if (!mark) return false
|
|
100
108
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
109
|
+
const start = pos
|
|
110
|
+
const end = pos + node.nodeSize
|
|
111
|
+
const { tr } = state
|
|
112
|
+
const linkMark = linkSchema
|
|
113
|
+
.type(ctx)
|
|
114
|
+
.create({ ...mark.attrs, ...payload })
|
|
115
|
+
if (!linkMark) return false
|
|
107
116
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
117
|
+
dispatch(
|
|
118
|
+
tr
|
|
119
|
+
.removeMark(start, end, mark)
|
|
120
|
+
.addMark(start, end, linkMark)
|
|
121
|
+
.setSelection(new TextSelection(tr.selection.$anchor))
|
|
122
|
+
.scrollIntoView()
|
|
123
|
+
)
|
|
115
124
|
|
|
116
|
-
|
|
117
|
-
}
|
|
125
|
+
return true
|
|
126
|
+
}
|
|
127
|
+
)
|
|
118
128
|
|
|
119
129
|
withMeta(updateLinkCommand, {
|
|
120
130
|
displayName: 'Command<updateLinkCommand>',
|
package/src/mark/strong.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { commandsCtx, remarkStringifyOptionsCtx } from '@milkdown/core'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
$command,
|
|
4
|
+
$inputRule,
|
|
5
|
+
$markAttr,
|
|
6
|
+
$markSchema,
|
|
7
|
+
$useKeymap,
|
|
8
|
+
} from '@milkdown/utils'
|
|
3
9
|
import { toggleMark } from '@milkdown/prose/commands'
|
|
4
10
|
import { markRule } from '@milkdown/prose'
|
|
5
11
|
import { withMeta } from '../__internal__'
|
|
@@ -13,7 +19,7 @@ withMeta(strongAttr, {
|
|
|
13
19
|
})
|
|
14
20
|
|
|
15
21
|
/// Strong mark schema.
|
|
16
|
-
export const strongSchema = $markSchema('strong', ctx => ({
|
|
22
|
+
export const strongSchema = $markSchema('strong', (ctx) => ({
|
|
17
23
|
attrs: {
|
|
18
24
|
marker: {
|
|
19
25
|
default: ctx.get(remarkStringifyOptionsCtx).strong || '*',
|
|
@@ -22,11 +28,11 @@ export const strongSchema = $markSchema('strong', ctx => ({
|
|
|
22
28
|
parseDOM: [
|
|
23
29
|
{ tag: 'b' },
|
|
24
30
|
{ tag: 'strong' },
|
|
25
|
-
{ style: 'font-style', getAttrs: value => (value === 'bold') as false },
|
|
31
|
+
{ style: 'font-style', getAttrs: (value) => (value === 'bold') as false },
|
|
26
32
|
],
|
|
27
|
-
toDOM: mark => ['strong', ctx.get(strongAttr.key)(mark)],
|
|
33
|
+
toDOM: (mark) => ['strong', ctx.get(strongAttr.key)(mark)],
|
|
28
34
|
parseMarkdown: {
|
|
29
|
-
match: node => node.type === 'strong',
|
|
35
|
+
match: (node) => node.type === 'strong',
|
|
30
36
|
runner: (state, node, markType) => {
|
|
31
37
|
state.openMark(markType, { marker: node.marker })
|
|
32
38
|
state.next(node.children)
|
|
@@ -34,7 +40,7 @@ export const strongSchema = $markSchema('strong', ctx => ({
|
|
|
34
40
|
},
|
|
35
41
|
},
|
|
36
42
|
toMarkdown: {
|
|
37
|
-
match: mark => mark.type.name === 'strong',
|
|
43
|
+
match: (mark) => mark.type.name === 'strong',
|
|
38
44
|
runner: (state, mark) => {
|
|
39
45
|
state.withMark(mark, 'strong', undefined, {
|
|
40
46
|
marker: mark.attrs.marker,
|
|
@@ -54,7 +60,7 @@ withMeta(strongSchema.ctx, {
|
|
|
54
60
|
})
|
|
55
61
|
|
|
56
62
|
/// A command to toggle the strong mark.
|
|
57
|
-
export const toggleStrongCommand = $command('ToggleStrong', ctx => () => {
|
|
63
|
+
export const toggleStrongCommand = $command('ToggleStrong', (ctx) => () => {
|
|
58
64
|
return toggleMark(strongSchema.type(ctx))
|
|
59
65
|
})
|
|
60
66
|
|
package/src/node/blockquote.ts
CHANGED
|
@@ -2,7 +2,13 @@ import { commandsCtx } from '@milkdown/core'
|
|
|
2
2
|
import { wrapIn } from '@milkdown/prose/commands'
|
|
3
3
|
import { wrappingInputRule } from '@milkdown/prose/inputrules'
|
|
4
4
|
import type { $NodeSchema } from '@milkdown/utils'
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
$command,
|
|
7
|
+
$inputRule,
|
|
8
|
+
$nodeAttr,
|
|
9
|
+
$nodeSchema,
|
|
10
|
+
$useKeymap,
|
|
11
|
+
} from '@milkdown/utils'
|
|
6
12
|
import { withMeta } from '../__internal__'
|
|
7
13
|
|
|
8
14
|
/// HTML attributes for blockquote node.
|
|
@@ -14,25 +20,28 @@ withMeta(blockquoteAttr, {
|
|
|
14
20
|
})
|
|
15
21
|
|
|
16
22
|
/// Schema for blockquote node.
|
|
17
|
-
export const blockquoteSchema: $NodeSchema<'blockquote'> = $nodeSchema(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
export const blockquoteSchema: $NodeSchema<'blockquote'> = $nodeSchema(
|
|
24
|
+
'blockquote',
|
|
25
|
+
(ctx) => ({
|
|
26
|
+
content: 'block+',
|
|
27
|
+
group: 'block',
|
|
28
|
+
defining: true,
|
|
29
|
+
parseDOM: [{ tag: 'blockquote' }],
|
|
30
|
+
toDOM: (node) => ['blockquote', ctx.get(blockquoteAttr.key)(node), 0],
|
|
31
|
+
parseMarkdown: {
|
|
32
|
+
match: ({ type }) => type === 'blockquote',
|
|
33
|
+
runner: (state, node, type) => {
|
|
34
|
+
state.openNode(type).next(node.children).closeNode()
|
|
35
|
+
},
|
|
27
36
|
},
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
toMarkdown: {
|
|
38
|
+
match: (node) => node.type.name === 'blockquote',
|
|
39
|
+
runner: (state, node) => {
|
|
40
|
+
state.openNode('blockquote').next(node.content).closeNode()
|
|
41
|
+
},
|
|
33
42
|
},
|
|
34
|
-
}
|
|
35
|
-
|
|
43
|
+
})
|
|
44
|
+
)
|
|
36
45
|
|
|
37
46
|
withMeta(blockquoteSchema.node, {
|
|
38
47
|
displayName: 'NodeSchema<blockquote>',
|
|
@@ -46,7 +55,9 @@ withMeta(blockquoteSchema.ctx, {
|
|
|
46
55
|
|
|
47
56
|
/// This input rule will convert a line that starts with `> ` into a blockquote.
|
|
48
57
|
/// You can type `> ` at the start of a line to create a blockquote.
|
|
49
|
-
export const wrapInBlockquoteInputRule = $inputRule(ctx =>
|
|
58
|
+
export const wrapInBlockquoteInputRule = $inputRule((ctx) =>
|
|
59
|
+
wrappingInputRule(/^\s*>\s$/, blockquoteSchema.type(ctx))
|
|
60
|
+
)
|
|
50
61
|
|
|
51
62
|
withMeta(wrapInBlockquoteInputRule, {
|
|
52
63
|
displayName: 'InputRule<wrapInBlockquoteInputRule>',
|
|
@@ -54,7 +65,10 @@ withMeta(wrapInBlockquoteInputRule, {
|
|
|
54
65
|
})
|
|
55
66
|
|
|
56
67
|
/// This command will wrap the current selection in a blockquote.
|
|
57
|
-
export const wrapInBlockquoteCommand = $command(
|
|
68
|
+
export const wrapInBlockquoteCommand = $command(
|
|
69
|
+
'WrapInBlockquote',
|
|
70
|
+
(ctx) => () => wrapIn(blockquoteSchema.type(ctx))
|
|
71
|
+
)
|
|
58
72
|
|
|
59
73
|
withMeta(wrapInBlockquoteCommand, {
|
|
60
74
|
displayName: 'Command<wrapInBlockquoteCommand>',
|
package/src/node/bullet-list.ts
CHANGED
|
@@ -2,7 +2,13 @@ import { commandsCtx } from '@milkdown/core'
|
|
|
2
2
|
import { expectDomTypeError } from '@milkdown/exception'
|
|
3
3
|
import { wrapIn } from '@milkdown/prose/commands'
|
|
4
4
|
import { wrappingInputRule } from '@milkdown/prose/inputrules'
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
$command,
|
|
7
|
+
$inputRule,
|
|
8
|
+
$nodeAttr,
|
|
9
|
+
$nodeSchema,
|
|
10
|
+
$useKeymap,
|
|
11
|
+
} from '@milkdown/utils'
|
|
6
12
|
import { withMeta } from '../__internal__'
|
|
7
13
|
|
|
8
14
|
/// HTML attributes for bullet list node.
|
|
@@ -27,8 +33,7 @@ export const bulletListSchema = $nodeSchema('bullet_list', (ctx) => {
|
|
|
27
33
|
{
|
|
28
34
|
tag: 'ul',
|
|
29
35
|
getAttrs: (dom) => {
|
|
30
|
-
if (!(dom instanceof HTMLElement))
|
|
31
|
-
throw expectDomTypeError(dom)
|
|
36
|
+
if (!(dom instanceof HTMLElement)) throw expectDomTypeError(dom)
|
|
32
37
|
|
|
33
38
|
return {
|
|
34
39
|
spread: dom.dataset.spread,
|
|
@@ -54,10 +59,13 @@ export const bulletListSchema = $nodeSchema('bullet_list', (ctx) => {
|
|
|
54
59
|
},
|
|
55
60
|
},
|
|
56
61
|
toMarkdown: {
|
|
57
|
-
match: node => node.type.name === 'bullet_list',
|
|
62
|
+
match: (node) => node.type.name === 'bullet_list',
|
|
58
63
|
runner: (state, node) => {
|
|
59
64
|
state
|
|
60
|
-
.openNode('list', undefined, {
|
|
65
|
+
.openNode('list', undefined, {
|
|
66
|
+
ordered: false,
|
|
67
|
+
spread: node.attrs.spread === 'true',
|
|
68
|
+
})
|
|
61
69
|
.next(node.content)
|
|
62
70
|
.closeNode()
|
|
63
71
|
},
|
|
@@ -76,7 +84,9 @@ withMeta(bulletListSchema.ctx, {
|
|
|
76
84
|
})
|
|
77
85
|
|
|
78
86
|
/// Input rule for wrapping a block in bullet list node.
|
|
79
|
-
export const wrapInBulletListInputRule = $inputRule(ctx =>
|
|
87
|
+
export const wrapInBulletListInputRule = $inputRule((ctx) =>
|
|
88
|
+
wrappingInputRule(/^\s*([-+*])\s$/, bulletListSchema.type(ctx))
|
|
89
|
+
)
|
|
80
90
|
|
|
81
91
|
withMeta(wrapInBulletListInputRule, {
|
|
82
92
|
displayName: 'InputRule<wrapInBulletListInputRule>',
|
|
@@ -84,7 +94,10 @@ withMeta(wrapInBulletListInputRule, {
|
|
|
84
94
|
})
|
|
85
95
|
|
|
86
96
|
/// Command for creating bullet list node.
|
|
87
|
-
export const wrapInBulletListCommand = $command(
|
|
97
|
+
export const wrapInBulletListCommand = $command(
|
|
98
|
+
'WrapInBulletList',
|
|
99
|
+
(ctx) => () => wrapIn(bulletListSchema.type(ctx))
|
|
100
|
+
)
|
|
88
101
|
|
|
89
102
|
withMeta(wrapInBulletListCommand, {
|
|
90
103
|
displayName: 'Command<wrapInBulletListCommand>',
|
package/src/node/code-block.ts
CHANGED
|
@@ -2,7 +2,13 @@ import { commandsCtx } from '@milkdown/core'
|
|
|
2
2
|
import { expectDomTypeError } from '@milkdown/exception'
|
|
3
3
|
import { setBlockType } from '@milkdown/prose/commands'
|
|
4
4
|
import { textblockTypeInputRule } from '@milkdown/prose/inputrules'
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
$command,
|
|
7
|
+
$inputRule,
|
|
8
|
+
$nodeAttr,
|
|
9
|
+
$nodeSchema,
|
|
10
|
+
$useKeymap,
|
|
11
|
+
} from '@milkdown/utils'
|
|
6
12
|
import { withMeta } from '../__internal__'
|
|
7
13
|
|
|
8
14
|
/// HTML attributes for code block node.
|
|
@@ -34,8 +40,7 @@ export const codeBlockSchema = $nodeSchema('code_block', (ctx) => {
|
|
|
34
40
|
tag: 'pre',
|
|
35
41
|
preserveWhitespace: 'full',
|
|
36
42
|
getAttrs: (dom) => {
|
|
37
|
-
if (!(dom instanceof HTMLElement))
|
|
38
|
-
throw expectDomTypeError(dom)
|
|
43
|
+
if (!(dom instanceof HTMLElement)) throw expectDomTypeError(dom)
|
|
39
44
|
|
|
40
45
|
return { language: dom.dataset.language }
|
|
41
46
|
},
|
|
@@ -58,14 +63,13 @@ export const codeBlockSchema = $nodeSchema('code_block', (ctx) => {
|
|
|
58
63
|
const language = node.lang as string
|
|
59
64
|
const value = node.value as string
|
|
60
65
|
state.openNode(type, { language })
|
|
61
|
-
if (value)
|
|
62
|
-
state.addText(value)
|
|
66
|
+
if (value) state.addText(value)
|
|
63
67
|
|
|
64
68
|
state.closeNode()
|
|
65
69
|
},
|
|
66
70
|
},
|
|
67
71
|
toMarkdown: {
|
|
68
|
-
match: node => node.type.name === 'code_block',
|
|
72
|
+
match: (node) => node.type.name === 'code_block',
|
|
69
73
|
runner: (state, node) => {
|
|
70
74
|
state.addNode('code', undefined, node.content.firstChild?.text || '', {
|
|
71
75
|
lang: node.attrs.language,
|
|
@@ -87,9 +91,15 @@ withMeta(codeBlockSchema.ctx, {
|
|
|
87
91
|
|
|
88
92
|
/// A input rule for creating code block.
|
|
89
93
|
/// For example, ` ```javascript ` will create a code block with language javascript.
|
|
90
|
-
export const createCodeBlockInputRule = $inputRule(
|
|
91
|
-
|
|
92
|
-
|
|
94
|
+
export const createCodeBlockInputRule = $inputRule((ctx) =>
|
|
95
|
+
textblockTypeInputRule(
|
|
96
|
+
/^```(?<language>[a-z]*)?[\s\n]$/,
|
|
97
|
+
codeBlockSchema.type(ctx),
|
|
98
|
+
(match) => ({
|
|
99
|
+
language: match.groups?.language ?? '',
|
|
100
|
+
})
|
|
101
|
+
)
|
|
102
|
+
)
|
|
93
103
|
|
|
94
104
|
withMeta(createCodeBlockInputRule, {
|
|
95
105
|
displayName: 'InputRule<createCodeBlockInputRule>',
|
|
@@ -98,7 +108,12 @@ withMeta(createCodeBlockInputRule, {
|
|
|
98
108
|
|
|
99
109
|
/// A command for creating code block.
|
|
100
110
|
/// You can pass the language of the code block as the parameter.
|
|
101
|
-
export const createCodeBlockCommand = $command(
|
|
111
|
+
export const createCodeBlockCommand = $command(
|
|
112
|
+
'CreateCodeBlock',
|
|
113
|
+
(ctx) =>
|
|
114
|
+
(language = '') =>
|
|
115
|
+
setBlockType(codeBlockSchema.type(ctx), { language })
|
|
116
|
+
)
|
|
102
117
|
|
|
103
118
|
withMeta(createCodeBlockCommand, {
|
|
104
119
|
displayName: 'Command<createCodeBlockCommand>',
|
|
@@ -106,14 +121,24 @@ withMeta(createCodeBlockCommand, {
|
|
|
106
121
|
})
|
|
107
122
|
|
|
108
123
|
/// A command for updating the code block language of the target position.
|
|
109
|
-
export const updateCodeBlockLanguageCommand = $command(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
124
|
+
export const updateCodeBlockLanguageCommand = $command(
|
|
125
|
+
'UpdateCodeBlockLanguage',
|
|
126
|
+
() =>
|
|
127
|
+
(
|
|
128
|
+
{ pos, language }: { pos: number; language: string } = {
|
|
129
|
+
pos: -1,
|
|
130
|
+
language: '',
|
|
131
|
+
}
|
|
132
|
+
) =>
|
|
133
|
+
(state, dispatch) => {
|
|
134
|
+
if (pos >= 0) {
|
|
135
|
+
dispatch?.(state.tr.setNodeAttribute(pos, 'language', language))
|
|
136
|
+
return true
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return false
|
|
140
|
+
}
|
|
141
|
+
)
|
|
117
142
|
|
|
118
143
|
withMeta(updateCodeBlockLanguageCommand, {
|
|
119
144
|
displayName: 'Command<updateCodeBlockLanguageCommand>',
|
package/src/node/doc.ts
CHANGED
package/src/node/hardbreak.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { withMeta } from '../__internal__'
|
|
|
9
9
|
/// - `data-is-inline` - Whether the hardbreak is inline.
|
|
10
10
|
export const hardbreakAttr = $nodeAttr('hardbreak', (node) => {
|
|
11
11
|
return {
|
|
12
|
+
'data-type': 'hardbreak',
|
|
12
13
|
'data-is-inline': node.attrs.isInline,
|
|
13
14
|
}
|
|
14
15
|
})
|
|
@@ -19,7 +20,7 @@ withMeta(hardbreakAttr, {
|
|
|
19
20
|
})
|
|
20
21
|
|
|
21
22
|
/// Hardbreak node schema.
|
|
22
|
-
export const hardbreakSchema = $nodeSchema('hardbreak', ctx => ({
|
|
23
|
+
export const hardbreakSchema = $nodeSchema('hardbreak', (ctx) => ({
|
|
23
24
|
inline: true,
|
|
24
25
|
group: 'inline',
|
|
25
26
|
attrs: {
|
|
@@ -28,23 +29,33 @@ export const hardbreakSchema = $nodeSchema('hardbreak', ctx => ({
|
|
|
28
29
|
},
|
|
29
30
|
},
|
|
30
31
|
selectable: false,
|
|
31
|
-
parseDOM: [
|
|
32
|
-
|
|
32
|
+
parseDOM: [
|
|
33
|
+
{ tag: 'br' },
|
|
34
|
+
{
|
|
35
|
+
tag: 'span[data-type="hardbreak"]',
|
|
36
|
+
getAttrs: () => ({ isInline: true }),
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
toDOM: (node) =>
|
|
40
|
+
node.attrs.isInline
|
|
41
|
+
? ['span', ctx.get(hardbreakAttr.key)(node), ' ']
|
|
42
|
+
: ['br', ctx.get(hardbreakAttr.key)(node)],
|
|
33
43
|
parseMarkdown: {
|
|
34
44
|
match: ({ type }) => type === 'break',
|
|
35
45
|
runner: (state, node, type) => {
|
|
36
|
-
state.addNode(type, {
|
|
46
|
+
state.addNode(type, {
|
|
47
|
+
isInline: Boolean(
|
|
48
|
+
(node.data as undefined | { isInline: boolean })?.isInline
|
|
49
|
+
),
|
|
50
|
+
})
|
|
37
51
|
},
|
|
38
52
|
},
|
|
39
53
|
leafText: () => '\n',
|
|
40
54
|
toMarkdown: {
|
|
41
|
-
match: node => node.type.name === 'hardbreak',
|
|
55
|
+
match: (node) => node.type.name === 'hardbreak',
|
|
42
56
|
runner: (state, node) => {
|
|
43
|
-
if (node.attrs.isInline)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
else
|
|
47
|
-
state.addNode('break')
|
|
57
|
+
if (node.attrs.isInline) state.addNode('text', undefined, '\n')
|
|
58
|
+
else state.addNode('break')
|
|
48
59
|
},
|
|
49
60
|
},
|
|
50
61
|
}))
|
|
@@ -60,27 +71,38 @@ withMeta(hardbreakSchema.ctx, {
|
|
|
60
71
|
})
|
|
61
72
|
|
|
62
73
|
/// Command to insert a hardbreak.
|
|
63
|
-
export const insertHardbreakCommand = $command(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
74
|
+
export const insertHardbreakCommand = $command(
|
|
75
|
+
'InsertHardbreak',
|
|
76
|
+
(ctx) => () => (state, dispatch) => {
|
|
77
|
+
const { selection, tr } = state
|
|
78
|
+
if (!(selection instanceof TextSelection)) return false
|
|
67
79
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
80
|
+
if (selection.empty) {
|
|
81
|
+
// Transform two successive hardbreak into a new line
|
|
82
|
+
const node = selection.$from.node()
|
|
83
|
+
if (node.childCount > 0 && node.lastChild?.type.name === 'hardbreak') {
|
|
84
|
+
dispatch?.(
|
|
85
|
+
tr
|
|
86
|
+
.replaceRangeWith(
|
|
87
|
+
selection.to - 1,
|
|
88
|
+
selection.to,
|
|
89
|
+
state.schema.node('paragraph')
|
|
90
|
+
)
|
|
91
|
+
.setSelection(Selection.near(tr.doc.resolve(selection.to)))
|
|
92
|
+
.scrollIntoView()
|
|
93
|
+
)
|
|
94
|
+
return true
|
|
95
|
+
}
|
|
79
96
|
}
|
|
97
|
+
dispatch?.(
|
|
98
|
+
tr
|
|
99
|
+
.setMeta('hardbreak', true)
|
|
100
|
+
.replaceSelectionWith(hardbreakSchema.type(ctx).create())
|
|
101
|
+
.scrollIntoView()
|
|
102
|
+
)
|
|
103
|
+
return true
|
|
80
104
|
}
|
|
81
|
-
|
|
82
|
-
return true
|
|
83
|
-
})
|
|
105
|
+
)
|
|
84
106
|
|
|
85
107
|
withMeta(insertHardbreakCommand, {
|
|
86
108
|
displayName: 'Command<insertHardbreakCommand>',
|