@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.
- package/lib/composed/commands.d.ts +3 -0
- package/lib/composed/commands.d.ts.map +1 -0
- package/lib/composed/index.d.ts +6 -0
- package/lib/composed/index.d.ts.map +1 -0
- package/lib/composed/inputrules.d.ts +3 -0
- package/lib/composed/inputrules.d.ts.map +1 -0
- package/lib/composed/keymap.d.ts +3 -0
- package/lib/composed/keymap.d.ts.map +1 -0
- package/lib/composed/plugins.d.ts +3 -0
- package/lib/composed/plugins.d.ts.map +1 -0
- package/lib/composed/schema.d.ts +3 -0
- package/lib/composed/schema.d.ts.map +1 -0
- package/lib/index.d.ts +4 -29
- package/lib/index.d.ts.map +1 -1
- package/lib/index.es.js +1099 -1386
- package/lib/index.es.js.map +1 -1
- package/lib/mark/emphasis.d.ts +5 -0
- package/lib/mark/emphasis.d.ts.map +1 -0
- package/lib/mark/index.d.ts +3 -4
- package/lib/mark/index.d.ts.map +1 -1
- package/lib/mark/inline-code.d.ts +5 -0
- package/lib/mark/inline-code.d.ts.map +1 -0
- package/lib/mark/link.d.ts +8 -10
- package/lib/mark/link.d.ts.map +1 -1
- package/lib/mark/strong.d.ts +4 -2
- package/lib/mark/strong.d.ts.map +1 -1
- package/lib/node/blockquote.d.ts +6 -2
- package/lib/node/blockquote.d.ts.map +1 -1
- package/lib/node/bullet-list.d.ts +5 -2
- package/lib/node/bullet-list.d.ts.map +1 -1
- package/lib/node/code-block.d.ts +10 -0
- package/lib/node/code-block.d.ts.map +1 -0
- package/lib/node/doc.d.ts +1 -1
- package/lib/node/doc.d.ts.map +1 -1
- package/lib/node/hardbreak.d.ts +4 -6
- package/lib/node/hardbreak.d.ts.map +1 -1
- package/lib/node/heading.d.ts +7 -12
- package/lib/node/heading.d.ts.map +1 -1
- package/lib/node/hr.d.ts +4 -2
- package/lib/node/hr.d.ts.map +1 -1
- package/lib/node/image.d.ts +10 -11
- package/lib/node/image.d.ts.map +1 -1
- package/lib/node/index.d.ts +6 -8
- package/lib/node/index.d.ts.map +1 -1
- package/lib/node/list-item.d.ts +6 -7
- package/lib/node/list-item.d.ts.map +1 -1
- package/lib/node/ordered-list.d.ts +5 -2
- package/lib/node/ordered-list.d.ts.map +1 -1
- package/lib/node/paragraph.d.ts +4 -2
- package/lib/node/paragraph.d.ts.map +1 -1
- package/lib/node/text.d.ts +1 -1
- package/lib/node/text.d.ts.map +1 -1
- package/lib/plugin/hardbreak-clear-mark-plugin.d.ts +2 -0
- package/lib/plugin/hardbreak-clear-mark-plugin.d.ts.map +1 -0
- package/lib/plugin/hardbreak-filter-plugin.d.ts +3 -0
- package/lib/plugin/hardbreak-filter-plugin.d.ts.map +1 -0
- package/lib/plugin/index.d.ts +9 -3
- package/lib/plugin/index.d.ts.map +1 -1
- package/lib/plugin/inline-nodes-cursor-plugin.d.ts +2 -0
- package/lib/plugin/inline-nodes-cursor-plugin.d.ts.map +1 -0
- package/lib/plugin/{inline-sync → inline-sync-plugin}/config.d.ts +2 -2
- package/lib/plugin/inline-sync-plugin/config.d.ts.map +1 -0
- package/lib/plugin/{inline-sync → inline-sync-plugin}/context.d.ts +1 -2
- package/lib/plugin/inline-sync-plugin/context.d.ts.map +1 -0
- package/lib/plugin/inline-sync-plugin/index.d.ts +3 -0
- package/lib/plugin/inline-sync-plugin/index.d.ts.map +1 -0
- package/lib/plugin/inline-sync-plugin/inline-sync-plugin.d.ts +2 -0
- package/lib/plugin/inline-sync-plugin/inline-sync-plugin.d.ts.map +1 -0
- package/lib/plugin/{inline-sync → inline-sync-plugin}/regexp.d.ts +0 -0
- package/lib/plugin/inline-sync-plugin/regexp.d.ts.map +1 -0
- package/lib/plugin/{inline-sync → inline-sync-plugin}/replacer.d.ts +1 -1
- package/lib/plugin/inline-sync-plugin/replacer.d.ts.map +1 -0
- package/lib/plugin/{inline-sync → inline-sync-plugin}/utils.d.ts +0 -0
- package/lib/plugin/inline-sync-plugin/utils.d.ts.map +1 -0
- package/lib/plugin/remark-add-order-in-list-plugin.d.ts +2 -0
- package/lib/plugin/remark-add-order-in-list-plugin.d.ts.map +1 -0
- package/lib/plugin/remark-inline-link-plugin.d.ts +2 -0
- package/lib/plugin/remark-inline-link-plugin.d.ts.map +1 -0
- package/lib/plugin/remark-line-break.d.ts +2 -0
- package/lib/plugin/remark-line-break.d.ts.map +1 -0
- package/lib/plugin/sync-heading-id-plugin.d.ts +2 -0
- package/lib/plugin/sync-heading-id-plugin.d.ts.map +1 -0
- package/lib/plugin/sync-list-order-plugin.d.ts +2 -0
- package/lib/plugin/sync-list-order-plugin.d.ts.map +1 -0
- package/package.json +9 -7
- package/src/composed/commands.ts +31 -0
- package/src/composed/index.ts +6 -0
- package/src/composed/inputrules.ts +13 -0
- package/src/composed/keymap.ts +20 -0
- package/src/composed/plugins.ts +23 -0
- package/src/composed/schema.ts +55 -0
- package/src/index.ts +6 -52
- package/src/mark/emphasis.ts +47 -0
- package/src/mark/index.ts +3 -10
- package/src/mark/inline-code.ts +70 -0
- package/src/mark/link.ts +96 -247
- package/src/mark/strong.ts +41 -36
- package/src/node/blockquote.ts +39 -33
- package/src/node/bullet-list.ts +62 -55
- package/src/node/code-block.ts +103 -0
- package/src/node/doc.ts +18 -22
- package/src/node/hardbreak.ts +68 -117
- package/src/node/heading.ts +175 -284
- package/src/node/hr.ts +57 -57
- package/src/node/image.ts +113 -209
- package/src/node/index.ts +6 -35
- package/src/node/list-item.ts +125 -141
- package/src/node/ordered-list.ts +70 -65
- package/src/node/paragraph.ts +54 -50
- package/src/node/text.ts +14 -16
- package/src/plugin/hardbreak-clear-mark-plugin.ts +45 -0
- package/src/plugin/hardbreak-filter-plugin.ts +33 -0
- package/src/plugin/index.ts +12 -14
- package/src/plugin/{inline-nodes-cursor.ts → inline-nodes-cursor-plugin.ts} +5 -8
- package/src/plugin/{inline-sync → inline-sync-plugin}/config.ts +18 -3
- package/src/plugin/{inline-sync → inline-sync-plugin}/context.ts +4 -6
- package/src/plugin/inline-sync-plugin/index.ts +4 -0
- package/src/plugin/{inline-sync/index.ts → inline-sync-plugin/inline-sync-plugin.ts} +14 -11
- package/src/plugin/{inline-sync → inline-sync-plugin}/regexp.ts +0 -0
- package/src/plugin/{inline-sync → inline-sync-plugin}/replacer.ts +3 -3
- package/src/plugin/{inline-sync → inline-sync-plugin}/utils.ts +0 -0
- package/src/plugin/remark-add-order-in-list-plugin.ts +16 -0
- package/src/plugin/remark-inline-link-plugin.ts +6 -0
- package/src/plugin/remark-line-break.ts +44 -0
- package/src/plugin/sync-heading-id-plugin.ts +55 -0
- package/src/plugin/sync-list-order-plugin.ts +57 -0
- package/lib/mark/code-inline.d.ts +0 -3
- package/lib/mark/code-inline.d.ts.map +0 -1
- package/lib/mark/em.d.ts +0 -3
- package/lib/mark/em.d.ts.map +0 -1
- package/lib/node/code-fence.d.ts +0 -7
- package/lib/node/code-fence.d.ts.map +0 -1
- package/lib/plugin/add-order-in-list.d.ts +0 -3
- package/lib/plugin/add-order-in-list.d.ts.map +0 -1
- package/lib/plugin/filter-html.d.ts +0 -3
- package/lib/plugin/filter-html.d.ts.map +0 -1
- package/lib/plugin/inline-nodes-cursor.d.ts +0 -7
- package/lib/plugin/inline-nodes-cursor.d.ts.map +0 -1
- package/lib/plugin/inline-sync/config.d.ts.map +0 -1
- package/lib/plugin/inline-sync/context.d.ts.map +0 -1
- package/lib/plugin/inline-sync/index.d.ts +0 -6
- package/lib/plugin/inline-sync/index.d.ts.map +0 -1
- package/lib/plugin/inline-sync/regexp.d.ts.map +0 -1
- package/lib/plugin/inline-sync/replacer.d.ts.map +0 -1
- package/lib/plugin/inline-sync/utils.d.ts.map +0 -1
- package/lib/supported-keys.d.ts +0 -23
- package/lib/supported-keys.d.ts.map +0 -1
- package/src/mark/code-inline.ts +0 -66
- package/src/mark/em.ts +0 -42
- package/src/node/code-fence.ts +0 -245
- package/src/plugin/add-order-in-list.ts +0 -19
- package/src/plugin/filter-html.ts +0 -43
- package/src/supported-keys.ts +0 -25
- package/src/types.d.ts +0 -5
package/src/mark/strong.ts
CHANGED
|
@@ -1,42 +1,47 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import {
|
|
2
|
+
import { commandsCtx } from '@milkdown/core'
|
|
3
3
|
import { toggleMark } from '@milkdown/prose/commands'
|
|
4
|
-
import {
|
|
4
|
+
import { $command, $markAttr, $markSchema, $useKeymap } from '@milkdown/utils'
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
/// HTML attributes for the strong mark.
|
|
7
|
+
export const strongAttr = $markAttr('strong')
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
match: node => node.type === 'strong',
|
|
24
|
-
runner: (state, node, markType) => {
|
|
25
|
-
state.openMark(markType)
|
|
26
|
-
state.next(node.children)
|
|
27
|
-
state.closeMark(markType)
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
toMarkdown: {
|
|
31
|
-
match: mark => mark.type.name === id,
|
|
32
|
-
runner: (state, mark) => {
|
|
33
|
-
state.withMark(mark, 'strong')
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
}),
|
|
37
|
-
commands: markType => [createCmd(ToggleBold, () => toggleMark(markType))],
|
|
38
|
-
shortcuts: {
|
|
39
|
-
[SupportedKeys.Bold]: createShortcut(ToggleBold, 'Mod-b'),
|
|
9
|
+
/// Strong mark schema.
|
|
10
|
+
export const strongSchema = $markSchema('strong', ctx => ({
|
|
11
|
+
inclusive: false,
|
|
12
|
+
parseDOM: [
|
|
13
|
+
{ tag: 'b' },
|
|
14
|
+
{ tag: 'strong' },
|
|
15
|
+
{ style: 'font-style', getAttrs: value => (value === 'bold') as false },
|
|
16
|
+
],
|
|
17
|
+
toDOM: mark => ['strong', ctx.get(strongAttr.key)(mark)],
|
|
18
|
+
parseMarkdown: {
|
|
19
|
+
match: node => node.type === 'strong',
|
|
20
|
+
runner: (state, node, markType) => {
|
|
21
|
+
state.openMark(markType)
|
|
22
|
+
state.next(node.children)
|
|
23
|
+
state.closeMark(markType)
|
|
40
24
|
},
|
|
41
|
-
}
|
|
25
|
+
},
|
|
26
|
+
toMarkdown: {
|
|
27
|
+
match: mark => mark.type.name === 'strong',
|
|
28
|
+
runner: (state, mark) => {
|
|
29
|
+
state.withMark(mark, 'strong')
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
}))
|
|
33
|
+
|
|
34
|
+
/// A command to toggle the strong mark.
|
|
35
|
+
export const toggleStrongCommand = $command('ToggleStrong', () => () => toggleMark(strongSchema.type()))
|
|
36
|
+
|
|
37
|
+
/// Keymap for the strong mark.
|
|
38
|
+
/// - `Mod-b` - Toggle the strong mark.
|
|
39
|
+
export const strongKeymap = $useKeymap('strongKeymap', {
|
|
40
|
+
ToggleBold: {
|
|
41
|
+
shortcuts: ['Mod-b'],
|
|
42
|
+
command: (ctx) => {
|
|
43
|
+
const commands = ctx.get(commandsCtx)
|
|
44
|
+
return () => commands.call(toggleStrongCommand.key)
|
|
45
|
+
},
|
|
46
|
+
},
|
|
42
47
|
})
|
package/src/node/blockquote.ts
CHANGED
|
@@ -1,43 +1,49 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import {
|
|
2
|
+
import { commandsCtx } from '@milkdown/core'
|
|
3
3
|
import { wrapIn } from '@milkdown/prose/commands'
|
|
4
4
|
import { wrappingInputRule } from '@milkdown/prose/inputrules'
|
|
5
|
-
import {
|
|
5
|
+
import type { $NodeSchema } from '@milkdown/utils'
|
|
6
|
+
import { $command, $inputRule, $nodeAttr, $nodeSchema, $useKeymap } from '@milkdown/utils'
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
/// HTML attributes for blockquote node.
|
|
9
|
+
export const blockquoteAttr = $nodeAttr('blockquote')
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
/// Schema for blockquote node.
|
|
12
|
+
export const blockquoteSchema: $NodeSchema<'blockquote'> = $nodeSchema('blockquote', ctx => ({
|
|
13
|
+
content: 'block+',
|
|
14
|
+
group: 'block',
|
|
15
|
+
defining: true,
|
|
16
|
+
parseDOM: [{ tag: 'blockquote' }],
|
|
17
|
+
toDOM: node => ['blockquote', ctx.get(blockquoteAttr.key)(node), 0],
|
|
18
|
+
parseMarkdown: {
|
|
19
|
+
match: ({ type }) => type === 'blockquote',
|
|
20
|
+
runner: (state, node, type) => {
|
|
21
|
+
state.openNode(type).next(node.children).closeNode()
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
toMarkdown: {
|
|
25
|
+
match: node => node.type.name === 'blockquote',
|
|
26
|
+
runner: (state, node) => {
|
|
27
|
+
state.openNode('blockquote').next(node.content).closeNode()
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
}))
|
|
10
31
|
|
|
11
|
-
|
|
32
|
+
/// This input rule will convert a line that starts with `> ` into a blockquote.
|
|
33
|
+
/// You can type `> ` at the start of a line to create a blockquote.
|
|
34
|
+
export const wrapInBlockquoteInputRule = $inputRule(() => wrappingInputRule(/^\s*>\s$/, blockquoteSchema.type()))
|
|
12
35
|
|
|
13
|
-
|
|
36
|
+
/// This command will wrap the current selection in a blockquote.
|
|
37
|
+
export const wrapInBlockquoteCommand = $command('WrapInBlockquote', () => () => wrapIn(blockquoteSchema.type()))
|
|
14
38
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
toDOM: node => ['blockquote', { class: utils.getClassName(node.attrs, id) }, 0],
|
|
24
|
-
parseMarkdown: {
|
|
25
|
-
match: ({ type }) => type === id,
|
|
26
|
-
runner: (state, node, type) => {
|
|
27
|
-
state.openNode(type).next(node.children).closeNode()
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
toMarkdown: {
|
|
31
|
-
match: node => node.type.name === id,
|
|
32
|
-
runner: (state, node) => {
|
|
33
|
-
state.openNode('blockquote').next(node.content).closeNode()
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
}),
|
|
37
|
-
inputRules: nodeType => [wrappingInputRule(/^\s*>\s$/, nodeType)],
|
|
38
|
-
commands: nodeType => [createCmd(WrapInBlockquote, () => wrapIn(nodeType))],
|
|
39
|
-
shortcuts: {
|
|
40
|
-
[SupportedKeys.Blockquote]: createShortcut(WrapInBlockquote, 'Mod-Shift-b'),
|
|
39
|
+
/// Keymap for blockquote.
|
|
40
|
+
/// - `Mod-Shift-b`: Wrap selection in blockquote.
|
|
41
|
+
export const blockquoteKeymap = $useKeymap('blockquoteKeymap', {
|
|
42
|
+
WrapInBlockquote: {
|
|
43
|
+
shortcuts: 'Mod-Shift-b',
|
|
44
|
+
command: (ctx) => {
|
|
45
|
+
const commands = ctx.get(commandsCtx)
|
|
46
|
+
return () => commands.call(wrapInBlockquoteCommand.key)
|
|
41
47
|
},
|
|
42
|
-
}
|
|
48
|
+
},
|
|
43
49
|
})
|
package/src/node/bullet-list.ts
CHANGED
|
@@ -1,72 +1,79 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import {
|
|
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 {
|
|
6
|
+
import { $command, $inputRule, $nodeAttr, $nodeSchema, $useKeymap } from '@milkdown/utils'
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
/// HTML attributes for bullet list node.
|
|
9
|
+
export const bulletListAttr = $nodeAttr('bulletList')
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
export const WrapInBulletList = createCmdKey('WrapInBulletList')
|
|
13
|
-
|
|
14
|
-
export const bulletList = createNode<Keys>((utils) => {
|
|
15
|
-
const id = 'bullet_list'
|
|
11
|
+
/// Schema for bullet list node.
|
|
12
|
+
export const bulletListSchema = $nodeSchema('bullet_list', (ctx) => {
|
|
16
13
|
return {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
spread: {
|
|
23
|
-
default: false,
|
|
24
|
-
},
|
|
14
|
+
content: 'listItem+',
|
|
15
|
+
group: 'block',
|
|
16
|
+
attrs: {
|
|
17
|
+
spread: {
|
|
18
|
+
default: false,
|
|
25
19
|
},
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
20
|
+
},
|
|
21
|
+
parseDOM: [
|
|
22
|
+
{
|
|
23
|
+
tag: 'ul',
|
|
24
|
+
getAttrs: (dom) => {
|
|
25
|
+
if (!(dom instanceof HTMLElement))
|
|
26
|
+
throw expectDomTypeError(dom)
|
|
32
27
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
},
|
|
28
|
+
return {
|
|
29
|
+
spread: dom.dataset.spread,
|
|
30
|
+
}
|
|
37
31
|
},
|
|
38
|
-
],
|
|
39
|
-
toDOM: (node) => {
|
|
40
|
-
return [
|
|
41
|
-
'ul',
|
|
42
|
-
{
|
|
43
|
-
'data-spread': node.attrs.spread,
|
|
44
|
-
'class': utils.getClassName(node.attrs, 'bullet-list'),
|
|
45
|
-
},
|
|
46
|
-
0,
|
|
47
|
-
]
|
|
48
32
|
},
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
33
|
+
],
|
|
34
|
+
toDOM: (node) => {
|
|
35
|
+
return [
|
|
36
|
+
'ul',
|
|
37
|
+
{
|
|
38
|
+
...ctx.get(bulletListAttr.key)(node),
|
|
39
|
+
'data-spread': node.attrs.spread,
|
|
54
40
|
},
|
|
41
|
+
0,
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
parseMarkdown: {
|
|
45
|
+
match: ({ type, ordered }) => type === 'list' && !ordered,
|
|
46
|
+
runner: (state, node, type) => {
|
|
47
|
+
const spread = node.spread != null ? `${node.spread}` : 'false'
|
|
48
|
+
state.openNode(type, { spread }).next(node.children).closeNode()
|
|
55
49
|
},
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
50
|
+
},
|
|
51
|
+
toMarkdown: {
|
|
52
|
+
match: node => node.type.name === 'bullet_list',
|
|
53
|
+
runner: (state, node) => {
|
|
54
|
+
state
|
|
55
|
+
.openNode('list', undefined, { ordered: false, spread: node.attrs.spread === 'true' })
|
|
56
|
+
.next(node.content)
|
|
57
|
+
.closeNode()
|
|
64
58
|
},
|
|
65
|
-
}),
|
|
66
|
-
inputRules: nodeType => [wrappingInputRule(/^\s*([-+*])\s$/, nodeType)],
|
|
67
|
-
commands: nodeType => [createCmd(WrapInBulletList, () => wrapIn(nodeType))],
|
|
68
|
-
shortcuts: {
|
|
69
|
-
[SupportedKeys.BulletList]: createShortcut(WrapInBulletList, 'Mod-Alt-8'),
|
|
70
59
|
},
|
|
71
60
|
}
|
|
72
61
|
})
|
|
62
|
+
|
|
63
|
+
/// Input rule for wrapping a block in bullet list node.
|
|
64
|
+
export const wrapInBulletListInputRule = $inputRule(() => wrappingInputRule(/^\s*([-+*])\s$/, bulletListSchema.type()))
|
|
65
|
+
|
|
66
|
+
/// Command for creating bullet list node.
|
|
67
|
+
export const wrapInBulletListCommand = $command('WrapInBulletList', () => () => wrapIn(bulletListSchema.type()))
|
|
68
|
+
|
|
69
|
+
/// Keymap for bullet list node.
|
|
70
|
+
/// - `Mod-Alt-8`: Wrap a block in bullet list.
|
|
71
|
+
export const bulletListKeymap = $useKeymap('bulletListKeymap', {
|
|
72
|
+
WrapInBulletList: {
|
|
73
|
+
shortcuts: 'Mod-Alt-8',
|
|
74
|
+
command: (ctx) => {
|
|
75
|
+
const commands = ctx.get(commandsCtx)
|
|
76
|
+
return () => commands.call(wrapInBulletListCommand.key)
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
})
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
+
import { commandsCtx } from '@milkdown/core'
|
|
3
|
+
import { expectDomTypeError } from '@milkdown/exception'
|
|
4
|
+
import { setBlockType } from '@milkdown/prose/commands'
|
|
5
|
+
import { textblockTypeInputRule } from '@milkdown/prose/inputrules'
|
|
6
|
+
import { $command, $inputRule, $nodeAttr, $nodeSchema, $useKeymap } from '@milkdown/utils'
|
|
7
|
+
|
|
8
|
+
/// HTML attributes for code block node.
|
|
9
|
+
export const codeBlockAttr = $nodeAttr('codeBlock', () => ({
|
|
10
|
+
pre: {},
|
|
11
|
+
code: {},
|
|
12
|
+
}))
|
|
13
|
+
|
|
14
|
+
/// Schema for code block node.
|
|
15
|
+
export const codeBlockSchema = $nodeSchema('code_block', (ctx) => {
|
|
16
|
+
return {
|
|
17
|
+
content: 'text*',
|
|
18
|
+
group: 'block',
|
|
19
|
+
marks: '',
|
|
20
|
+
defining: true,
|
|
21
|
+
code: true,
|
|
22
|
+
attrs: {
|
|
23
|
+
language: {
|
|
24
|
+
default: '',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
parseDOM: [
|
|
28
|
+
{
|
|
29
|
+
tag: 'pre',
|
|
30
|
+
preserveWhitespace: 'full',
|
|
31
|
+
getAttrs: (dom) => {
|
|
32
|
+
if (!(dom instanceof HTMLElement))
|
|
33
|
+
throw expectDomTypeError(dom)
|
|
34
|
+
|
|
35
|
+
return { language: dom.dataset.language }
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
toDOM: (node) => {
|
|
40
|
+
const attr = ctx.get(codeBlockAttr.key)(node)
|
|
41
|
+
return [
|
|
42
|
+
'pre',
|
|
43
|
+
{
|
|
44
|
+
...attr.pre,
|
|
45
|
+
'data-language': node.attrs.language,
|
|
46
|
+
},
|
|
47
|
+
['code', attr.code, 0],
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
parseMarkdown: {
|
|
51
|
+
match: ({ type }) => type === 'code',
|
|
52
|
+
runner: (state, node, type) => {
|
|
53
|
+
const language = node.lang as string
|
|
54
|
+
const value = node.value as string
|
|
55
|
+
state.openNode(type, { language })
|
|
56
|
+
if (value)
|
|
57
|
+
state.addText(value)
|
|
58
|
+
|
|
59
|
+
state.closeNode()
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
toMarkdown: {
|
|
63
|
+
match: node => node.type.name === 'code_block',
|
|
64
|
+
runner: (state, node) => {
|
|
65
|
+
state.addNode('code', undefined, node.content.firstChild?.text || '', {
|
|
66
|
+
lang: node.attrs.language,
|
|
67
|
+
})
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
/// A input rule for creating code block.
|
|
74
|
+
/// For example, ` ```javascript ` will create a code block with language javascript.
|
|
75
|
+
export const createCodeBlockInputRule = $inputRule(() => textblockTypeInputRule(/^```(?<language>[a-z]*)?[\s\n]$/, codeBlockSchema.type(), match => ({
|
|
76
|
+
language: match.groups?.language ?? '',
|
|
77
|
+
})))
|
|
78
|
+
|
|
79
|
+
/// A command for creating code block.
|
|
80
|
+
/// You can pass the language of the code block as the parameter.
|
|
81
|
+
export const createCodeBlockCommand = $command('CreateCodeBlock', () => (language = '') => setBlockType(codeBlockSchema.type(), { language }))
|
|
82
|
+
|
|
83
|
+
/// A command for updating the code block language of the target position.
|
|
84
|
+
export const updateCodeBlockLanguageCommand = $command('UpdateCodeBlockLanguage', () => ({ pos, language }: { pos: number; language: string } = { pos: -1, language: '' }) => (state, dispatch) => {
|
|
85
|
+
if (pos >= 0) {
|
|
86
|
+
dispatch?.(state.tr.setNodeAttribute(pos, 'language', language))
|
|
87
|
+
return true
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return false
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
/// Keymap for code block.
|
|
94
|
+
/// - `Mod-Alt-c`: Create a code block.
|
|
95
|
+
export const codeBlockKeymap = $useKeymap('codeBlockKeymap', {
|
|
96
|
+
CreateCodeBlock: {
|
|
97
|
+
shortcuts: 'Mod-Alt-c',
|
|
98
|
+
command: (ctx) => {
|
|
99
|
+
const commands = ctx.get(commandsCtx)
|
|
100
|
+
return () => commands.call(createCodeBlockCommand.key)
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
})
|
package/src/node/doc.ts
CHANGED
|
@@ -1,24 +1,20 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import {
|
|
2
|
+
import { $node } from '@milkdown/utils'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
},
|
|
22
|
-
}),
|
|
23
|
-
}
|
|
24
|
-
})
|
|
4
|
+
/// The top-level document node.
|
|
5
|
+
export const docSchema = $node('doc', () => ({
|
|
6
|
+
content: 'block+',
|
|
7
|
+
parseMarkdown: {
|
|
8
|
+
match: ({ type }) => type === 'root',
|
|
9
|
+
runner: (state, node, type) => {
|
|
10
|
+
state.injectRoot(node, type)
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
toMarkdown: {
|
|
14
|
+
match: node => node.type.name === 'doc',
|
|
15
|
+
runner: (state, node) => {
|
|
16
|
+
state.openNode('root')
|
|
17
|
+
state.next(node.content)
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
}))
|
package/src/node/hardbreak.ts
CHANGED
|
@@ -1,125 +1,76 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { createNode, createShortcut } from '@milkdown/utils'
|
|
2
|
+
import { commandsCtx } from '@milkdown/core'
|
|
3
|
+
import { Selection } from '@milkdown/prose/state'
|
|
4
|
+
import { $command, $nodeAttr, $nodeSchema, $useKeymap } from '@milkdown/utils'
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export const
|
|
12
|
-
|
|
13
|
-
export const HardbreakFilterPluginKey = new PluginKey('MILKDOWN_HARDBREAK_FILTER')
|
|
14
|
-
|
|
15
|
-
export const hardbreak = createNode<
|
|
16
|
-
Keys,
|
|
17
|
-
{
|
|
18
|
-
notIn: string[]
|
|
19
|
-
}
|
|
20
|
-
>((utils, options) => {
|
|
21
|
-
const notIn = options?.notIn ?? ['table', 'fence']
|
|
6
|
+
/// HTML attributes for the hardbreak node.
|
|
7
|
+
///
|
|
8
|
+
/// Default value:
|
|
9
|
+
/// - `data-is-inline` - Whether the hardbreak is inline.
|
|
10
|
+
export const hardbreakAttr = $nodeAttr('hardbreak', (node) => {
|
|
22
11
|
return {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
group: 'inline',
|
|
27
|
-
selectable: false,
|
|
28
|
-
parseDOM: [{ tag: 'br' }],
|
|
29
|
-
toDOM: node => ['br', { class: utils.getClassName(node.attrs, 'hardbreak') }],
|
|
30
|
-
parseMarkdown: {
|
|
31
|
-
match: ({ type }) => type === 'break',
|
|
32
|
-
runner: (state, _, type) => {
|
|
33
|
-
state.addNode(type)
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
toMarkdown: {
|
|
37
|
-
match: node => node.type.name === 'hardbreak',
|
|
38
|
-
runner: (state) => {
|
|
39
|
-
state.addNode('break')
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
}),
|
|
43
|
-
commands: type => [
|
|
44
|
-
createCmd(InsertHardbreak, () => (state, dispatch) => {
|
|
45
|
-
const { selection, tr } = state
|
|
46
|
-
if (selection.empty) {
|
|
47
|
-
// Transform two successive hardbreak into a new line
|
|
48
|
-
const node = selection.$from.node()
|
|
49
|
-
if (node.childCount > 0 && node.lastChild?.type.name === 'hardbreak') {
|
|
50
|
-
dispatch?.(
|
|
51
|
-
tr
|
|
52
|
-
.replaceRangeWith(selection.to - 1, selection.to, state.schema.node('paragraph'))
|
|
53
|
-
.setSelection(Selection.near(tr.doc.resolve(selection.to)))
|
|
54
|
-
.scrollIntoView(),
|
|
55
|
-
)
|
|
56
|
-
return true
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
dispatch?.(tr.setMeta('hardbreak', true).replaceSelectionWith(type.create()).scrollIntoView())
|
|
60
|
-
return true
|
|
61
|
-
}),
|
|
62
|
-
],
|
|
63
|
-
shortcuts: {
|
|
64
|
-
[SupportedKeys.HardBreak]: createShortcut(InsertHardbreak, 'Shift-Enter'),
|
|
65
|
-
},
|
|
66
|
-
prosePlugins: type => [
|
|
67
|
-
new Plugin({
|
|
68
|
-
key: HardbreakFilterPluginKey,
|
|
69
|
-
filterTransaction: (tr, state) => {
|
|
70
|
-
const isInsertHr = tr.getMeta('hardbreak')
|
|
71
|
-
const [step] = tr.steps
|
|
72
|
-
if (isInsertHr && step) {
|
|
73
|
-
const { from } = step as unknown as { from: number }
|
|
74
|
-
const $from = state.doc.resolve(from)
|
|
75
|
-
let curDepth = $from.depth
|
|
76
|
-
let canApply = true
|
|
77
|
-
while (curDepth > 0) {
|
|
78
|
-
if (notIn.includes($from.node(curDepth).type.name))
|
|
79
|
-
canApply = false
|
|
80
|
-
|
|
81
|
-
curDepth--
|
|
82
|
-
}
|
|
83
|
-
return canApply
|
|
84
|
-
}
|
|
85
|
-
return true
|
|
86
|
-
},
|
|
87
|
-
}),
|
|
88
|
-
new Plugin({
|
|
89
|
-
key: new PluginKey('MILKDOWN_HARDBREAK_MARKS'),
|
|
90
|
-
appendTransaction: (trs, _oldState, newState) => {
|
|
91
|
-
if (!trs.length)
|
|
92
|
-
return
|
|
93
|
-
const [tr] = trs
|
|
94
|
-
if (!tr)
|
|
95
|
-
return
|
|
96
|
-
|
|
97
|
-
const [step] = tr.steps
|
|
98
|
-
|
|
99
|
-
const isInsertHr = tr.getMeta('hardbreak')
|
|
100
|
-
if (isInsertHr) {
|
|
101
|
-
if (!(step instanceof ReplaceStep))
|
|
102
|
-
return
|
|
103
|
-
|
|
104
|
-
const { from } = step as unknown as { from: number }
|
|
105
|
-
return newState.tr.setNodeMarkup(from, type, undefined, [])
|
|
106
|
-
}
|
|
12
|
+
'data-is-inline': node.attrs.isInline,
|
|
13
|
+
}
|
|
14
|
+
})
|
|
107
15
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
16
|
+
/// Hardbreak node schema.
|
|
17
|
+
export const hardbreakSchema = $nodeSchema('hardbreak', ctx => ({
|
|
18
|
+
inline: true,
|
|
19
|
+
group: 'inline',
|
|
20
|
+
attrs: {
|
|
21
|
+
isInline: {
|
|
22
|
+
default: false,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
selectable: false,
|
|
26
|
+
parseDOM: [{ tag: 'br' }],
|
|
27
|
+
toDOM: node => ['br', ctx.get(hardbreakAttr.key)(node)],
|
|
28
|
+
parseMarkdown: {
|
|
29
|
+
match: ({ type }) => type === 'break',
|
|
30
|
+
runner: (state, node, type) => {
|
|
31
|
+
state.addNode(type, { isInline: Boolean(node.data?.isInline) })
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
toMarkdown: {
|
|
35
|
+
match: node => node.type.name === 'hardbreak',
|
|
36
|
+
runner: (state, node) => {
|
|
37
|
+
if (node.attrs.isInline)
|
|
38
|
+
state.addNode('text', undefined, '\n')
|
|
116
39
|
|
|
117
|
-
|
|
118
|
-
|
|
40
|
+
else
|
|
41
|
+
state.addNode('break')
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
}))
|
|
119
45
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
46
|
+
/// Command to insert a hardbreak.
|
|
47
|
+
export const insertHardbreakCommand = $command('InsertHardbreak', () => () => (state, dispatch) => {
|
|
48
|
+
const { selection, tr } = state
|
|
49
|
+
if (selection.empty) {
|
|
50
|
+
// Transform two successive hardbreak into a new line
|
|
51
|
+
const node = selection.$from.node()
|
|
52
|
+
if (node.childCount > 0 && node.lastChild?.type.name === 'hardbreak') {
|
|
53
|
+
dispatch?.(
|
|
54
|
+
tr
|
|
55
|
+
.replaceRangeWith(selection.to - 1, selection.to, state.schema.node('paragraph'))
|
|
56
|
+
.setSelection(Selection.near(tr.doc.resolve(selection.to)))
|
|
57
|
+
.scrollIntoView(),
|
|
58
|
+
)
|
|
59
|
+
return true
|
|
60
|
+
}
|
|
124
61
|
}
|
|
62
|
+
dispatch?.(tr.setMeta('hardbreak', true).replaceSelectionWith(hardbreakSchema.type().create()).scrollIntoView())
|
|
63
|
+
return true
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
/// Keymap for the hardbreak node.
|
|
67
|
+
/// - `Shift-Enter` - Insert a hardbreak.
|
|
68
|
+
export const hardbreakKeymap = $useKeymap('hardbreakKeymap', {
|
|
69
|
+
InsertHardbreak: {
|
|
70
|
+
shortcuts: 'Shift-Enter',
|
|
71
|
+
command: (ctx) => {
|
|
72
|
+
const commands = ctx.get(commandsCtx)
|
|
73
|
+
return () => commands.call(insertHardbreakCommand.key)
|
|
74
|
+
},
|
|
75
|
+
},
|
|
125
76
|
})
|