@jvs-milkdown/preset-commonmark 1.0.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.
- package/LICENSE +21 -0
- package/README.md +11 -0
- package/lib/__internal__/index.d.ts +3 -0
- package/lib/__internal__/index.d.ts.map +1 -0
- package/lib/__internal__/serialize-text.d.ts +4 -0
- package/lib/__internal__/serialize-text.d.ts.map +1 -0
- package/lib/__internal__/with-meta.d.ts +3 -0
- package/lib/__internal__/with-meta.d.ts.map +1 -0
- package/lib/__test__/html.spec.d.ts +2 -0
- package/lib/__test__/html.spec.d.ts.map +1 -0
- package/lib/__test__/trailing-space.spec.d.ts +2 -0
- package/lib/__test__/trailing-space.spec.d.ts.map +1 -0
- package/lib/__test__/vitest.setup.d.ts +1 -0
- package/lib/__test__/vitest.setup.d.ts.map +1 -0
- package/lib/commands/index.d.ts +20 -0
- package/lib/commands/index.d.ts.map +1 -0
- 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 +4 -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 +8 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +2153 -0
- package/lib/index.js.map +1 -0
- package/lib/mark/emphasis.d.ts +7 -0
- package/lib/mark/emphasis.d.ts.map +1 -0
- package/lib/mark/index.d.ts +5 -0
- package/lib/mark/index.d.ts.map +1 -0
- package/lib/mark/inline-code.d.ts +6 -0
- package/lib/mark/inline-code.d.ts.map +1 -0
- package/lib/mark/link.d.ts +9 -0
- package/lib/mark/link.d.ts.map +1 -0
- package/lib/mark/strong.d.ts +6 -0
- package/lib/mark/strong.d.ts.map +1 -0
- package/lib/node/blockquote.d.ts +7 -0
- package/lib/node/blockquote.d.ts.map +1 -0
- package/lib/node/bullet-list.d.ts +6 -0
- package/lib/node/bullet-list.d.ts.map +1 -0
- 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 +2 -0
- package/lib/node/doc.d.ts.map +1 -0
- package/lib/node/hardbreak.d.ts +5 -0
- package/lib/node/hardbreak.d.ts.map +1 -0
- package/lib/node/heading.d.ts +11 -0
- package/lib/node/heading.d.ts.map +1 -0
- package/lib/node/hr.d.ts +5 -0
- package/lib/node/hr.d.ts.map +1 -0
- package/lib/node/html.d.ts +3 -0
- package/lib/node/html.d.ts.map +1 -0
- package/lib/node/image.d.ts +11 -0
- package/lib/node/image.d.ts.map +1 -0
- package/lib/node/index.d.ts +14 -0
- package/lib/node/index.d.ts.map +1 -0
- package/lib/node/list-item.d.ts +8 -0
- package/lib/node/list-item.d.ts.map +1 -0
- package/lib/node/ordered-list.d.ts +6 -0
- package/lib/node/ordered-list.d.ts.map +1 -0
- package/lib/node/paragraph.d.ts +5 -0
- package/lib/node/paragraph.d.ts.map +1 -0
- package/lib/node/text.d.ts +2 -0
- package/lib/node/text.d.ts.map +1 -0
- 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 +12 -0
- package/lib/plugin/index.d.ts.map +1 -0
- 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/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-html-transformer.d.ts +2 -0
- package/lib/plugin/remark-html-transformer.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/remark-marker-plugin.d.ts +2 -0
- package/lib/plugin/remark-marker-plugin.d.ts.map +1 -0
- package/lib/plugin/remark-preserve-empty-line.d.ts +2 -0
- package/lib/plugin/remark-preserve-empty-line.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/lib/tsconfig.tsbuildinfo +1 -0
- package/package.json +44 -0
- package/src/__internal__/index.ts +2 -0
- package/src/__internal__/serialize-text.ts +21 -0
- package/src/__internal__/with-meta.ts +15 -0
- package/src/__test__/html.spec.ts +46 -0
- package/src/__test__/trailing-space.spec.ts +27 -0
- package/src/__test__/vitest.setup.ts +65 -0
- package/src/commands/index.ts +140 -0
- package/src/composed/commands.ts +72 -0
- package/src/composed/index.ts +5 -0
- package/src/composed/inputrules.ts +34 -0
- package/src/composed/keymap.ts +29 -0
- package/src/composed/plugins.ts +35 -0
- package/src/composed/schema.ts +92 -0
- package/src/index.ts +26 -0
- package/src/mark/emphasis.ts +130 -0
- package/src/mark/index.ts +4 -0
- package/src/mark/inline-code.ts +123 -0
- package/src/mark/link.ts +134 -0
- package/src/mark/strong.ts +130 -0
- package/src/node/blockquote.ts +100 -0
- package/src/node/bullet-list.ts +129 -0
- package/src/node/code-block.ts +176 -0
- package/src/node/doc.ts +26 -0
- package/src/node/hardbreak.ts +134 -0
- package/src/node/heading.ts +271 -0
- package/src/node/hr.ts +87 -0
- package/src/node/html.ts +66 -0
- package/src/node/image.ts +173 -0
- package/src/node/index.ts +14 -0
- package/src/node/list-item.ts +244 -0
- package/src/node/ordered-list.ts +141 -0
- package/src/node/paragraph.ts +136 -0
- package/src/node/text.ts +25 -0
- package/src/plugin/hardbreak-clear-mark-plugin.ts +58 -0
- package/src/plugin/hardbreak-filter-plugin.ts +46 -0
- package/src/plugin/index.ts +14 -0
- package/src/plugin/inline-nodes-cursor-plugin.ts +103 -0
- package/src/plugin/remark-add-order-in-list-plugin.ts +29 -0
- package/src/plugin/remark-html-transformer.ts +74 -0
- package/src/plugin/remark-inline-link-plugin.ts +20 -0
- package/src/plugin/remark-line-break.ts +69 -0
- package/src/plugin/remark-marker-plugin.ts +33 -0
- package/src/plugin/remark-preserve-empty-line.ts +49 -0
- package/src/plugin/sync-heading-id-plugin.ts +67 -0
- package/src/plugin/sync-list-order-plugin.ts +112 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { findNodeInSelection } from '@jvs-milkdown/prose'
|
|
2
|
+
import {
|
|
3
|
+
Node,
|
|
4
|
+
type Attrs,
|
|
5
|
+
type MarkType,
|
|
6
|
+
type NodeType,
|
|
7
|
+
} from '@jvs-milkdown/prose/model'
|
|
8
|
+
import { TextSelection } from '@jvs-milkdown/prose/state'
|
|
9
|
+
import { findWrapping } from '@jvs-milkdown/prose/transform'
|
|
10
|
+
import { $command } from '@jvs-milkdown/utils'
|
|
11
|
+
|
|
12
|
+
/// A command to check if a mark is selected.
|
|
13
|
+
export const isMarkSelectedCommand = $command(
|
|
14
|
+
'IsMarkSelected',
|
|
15
|
+
() => (markType?: MarkType) => (state) => {
|
|
16
|
+
if (!markType) return false
|
|
17
|
+
const { doc, selection } = state
|
|
18
|
+
const hasLink = doc.rangeHasMark(selection.from, selection.to, markType)
|
|
19
|
+
return hasLink
|
|
20
|
+
}
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
/// A command to check if a node is selected.
|
|
24
|
+
export const isNodeSelectedCommand = $command(
|
|
25
|
+
'IsNoteSelected',
|
|
26
|
+
() => (nodeType?: NodeType) => (state) => {
|
|
27
|
+
if (!nodeType) return false
|
|
28
|
+
const result = findNodeInSelection(state, nodeType)
|
|
29
|
+
return result.hasNode
|
|
30
|
+
}
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
/// A command to clear text in the current block.
|
|
34
|
+
export const clearTextInCurrentBlockCommand = $command(
|
|
35
|
+
'ClearTextInCurrentBlock',
|
|
36
|
+
() => () => (state, dispatch) => {
|
|
37
|
+
let tr = state.tr
|
|
38
|
+
const { $from, $to } = tr.selection
|
|
39
|
+
const { pos: from } = $from
|
|
40
|
+
const { pos: right } = $to
|
|
41
|
+
const left = from - $from.node().content.size
|
|
42
|
+
if (left < 0) return false
|
|
43
|
+
|
|
44
|
+
tr = tr.deleteRange(left, right)
|
|
45
|
+
dispatch?.(tr)
|
|
46
|
+
return true
|
|
47
|
+
}
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
/// Set block type to target block and attribute.
|
|
51
|
+
export const setBlockTypeCommand = $command(
|
|
52
|
+
'SetBlockType',
|
|
53
|
+
() =>
|
|
54
|
+
(payload?: { nodeType: NodeType; attrs?: Attrs | null }) =>
|
|
55
|
+
(state, dispatch) => {
|
|
56
|
+
const { nodeType, attrs = null } = payload ?? {}
|
|
57
|
+
if (!nodeType) return false
|
|
58
|
+
const tr = state.tr
|
|
59
|
+
const { from, to } = tr.selection
|
|
60
|
+
try {
|
|
61
|
+
tr.setBlockType(from, to, nodeType, attrs)
|
|
62
|
+
} catch {
|
|
63
|
+
return false
|
|
64
|
+
}
|
|
65
|
+
dispatch?.(tr)
|
|
66
|
+
return true
|
|
67
|
+
}
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
/// A command to wrap the current block with a block type.
|
|
71
|
+
export const wrapInBlockTypeCommand = $command(
|
|
72
|
+
'WrapInBlockType',
|
|
73
|
+
() =>
|
|
74
|
+
(payload?: { nodeType: NodeType; attrs?: Attrs | null }) =>
|
|
75
|
+
(state, dispatch) => {
|
|
76
|
+
const { nodeType, attrs = null } = payload ?? {}
|
|
77
|
+
if (!nodeType) return false
|
|
78
|
+
|
|
79
|
+
let tr = state.tr
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
const { $from, $to } = tr.selection
|
|
83
|
+
const blockRange = $from.blockRange($to)
|
|
84
|
+
const wrapping = blockRange && findWrapping(blockRange, nodeType, attrs)
|
|
85
|
+
if (!wrapping) return false
|
|
86
|
+
tr = tr.wrap(blockRange, wrapping)
|
|
87
|
+
} catch {
|
|
88
|
+
return false
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
dispatch?.(tr)
|
|
92
|
+
return true
|
|
93
|
+
}
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
/// A command to add a block type to the current selection.
|
|
97
|
+
export const addBlockTypeCommand = $command(
|
|
98
|
+
'AddBlockType',
|
|
99
|
+
() =>
|
|
100
|
+
(payload?: { nodeType: NodeType | Node; attrs?: Attrs | null }) =>
|
|
101
|
+
(state, dispatch) => {
|
|
102
|
+
const { nodeType, attrs = null } = payload ?? {}
|
|
103
|
+
if (!nodeType) return false
|
|
104
|
+
const tr = state.tr
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
const node =
|
|
108
|
+
nodeType instanceof Node ? nodeType : nodeType.createAndFill(attrs)
|
|
109
|
+
if (!node) return false
|
|
110
|
+
|
|
111
|
+
tr.replaceSelectionWith(node)
|
|
112
|
+
} catch {
|
|
113
|
+
return false
|
|
114
|
+
}
|
|
115
|
+
dispatch?.(tr)
|
|
116
|
+
return true
|
|
117
|
+
}
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
/// A command to select text near a position.
|
|
121
|
+
export const selectTextNearPosCommand = $command(
|
|
122
|
+
'SelectTextNearPos',
|
|
123
|
+
() => (payload?: { pos?: number }) => (state, dispatch) => {
|
|
124
|
+
const { pos } = payload ?? {}
|
|
125
|
+
if (pos == null) return false
|
|
126
|
+
|
|
127
|
+
const clamp = (value: number, min: number, max: number) =>
|
|
128
|
+
Math.min(Math.max(value, min), max)
|
|
129
|
+
|
|
130
|
+
const tr = state.tr
|
|
131
|
+
try {
|
|
132
|
+
const $pos = state.doc.resolve(clamp(pos, 0, state.doc.content.size))
|
|
133
|
+
tr.setSelection(TextSelection.near($pos))
|
|
134
|
+
} catch {
|
|
135
|
+
return false
|
|
136
|
+
}
|
|
137
|
+
dispatch?.(tr.scrollIntoView())
|
|
138
|
+
return true
|
|
139
|
+
}
|
|
140
|
+
)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { MilkdownPlugin } from '@jvs-milkdown/ctx'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
addBlockTypeCommand,
|
|
5
|
+
clearTextInCurrentBlockCommand,
|
|
6
|
+
isMarkSelectedCommand,
|
|
7
|
+
isNodeSelectedCommand,
|
|
8
|
+
selectTextNearPosCommand,
|
|
9
|
+
setBlockTypeCommand,
|
|
10
|
+
wrapInBlockTypeCommand,
|
|
11
|
+
} from '../commands'
|
|
12
|
+
import {
|
|
13
|
+
toggleEmphasisCommand,
|
|
14
|
+
toggleInlineCodeCommand,
|
|
15
|
+
toggleLinkCommand,
|
|
16
|
+
toggleStrongCommand,
|
|
17
|
+
updateLinkCommand,
|
|
18
|
+
} from '../mark'
|
|
19
|
+
import {
|
|
20
|
+
createCodeBlockCommand,
|
|
21
|
+
downgradeHeadingCommand,
|
|
22
|
+
insertHardbreakCommand,
|
|
23
|
+
insertHrCommand,
|
|
24
|
+
insertImageCommand,
|
|
25
|
+
liftFirstListItemCommand,
|
|
26
|
+
liftListItemCommand,
|
|
27
|
+
sinkListItemCommand,
|
|
28
|
+
splitListItemCommand,
|
|
29
|
+
turnIntoTextCommand,
|
|
30
|
+
updateImageCommand,
|
|
31
|
+
wrapInBlockquoteCommand,
|
|
32
|
+
wrapInBulletListCommand,
|
|
33
|
+
wrapInHeadingCommand,
|
|
34
|
+
wrapInOrderedListCommand,
|
|
35
|
+
} from '../node'
|
|
36
|
+
|
|
37
|
+
/// @internal
|
|
38
|
+
export const commands: MilkdownPlugin[] = [
|
|
39
|
+
turnIntoTextCommand,
|
|
40
|
+
wrapInBlockquoteCommand,
|
|
41
|
+
wrapInHeadingCommand,
|
|
42
|
+
downgradeHeadingCommand,
|
|
43
|
+
createCodeBlockCommand,
|
|
44
|
+
insertHardbreakCommand,
|
|
45
|
+
insertHrCommand,
|
|
46
|
+
|
|
47
|
+
insertImageCommand,
|
|
48
|
+
updateImageCommand,
|
|
49
|
+
|
|
50
|
+
wrapInOrderedListCommand,
|
|
51
|
+
wrapInBulletListCommand,
|
|
52
|
+
sinkListItemCommand,
|
|
53
|
+
splitListItemCommand,
|
|
54
|
+
liftListItemCommand,
|
|
55
|
+
liftFirstListItemCommand,
|
|
56
|
+
|
|
57
|
+
toggleEmphasisCommand,
|
|
58
|
+
toggleInlineCodeCommand,
|
|
59
|
+
toggleStrongCommand,
|
|
60
|
+
|
|
61
|
+
toggleLinkCommand,
|
|
62
|
+
updateLinkCommand,
|
|
63
|
+
|
|
64
|
+
isMarkSelectedCommand,
|
|
65
|
+
isNodeSelectedCommand,
|
|
66
|
+
|
|
67
|
+
clearTextInCurrentBlockCommand,
|
|
68
|
+
setBlockTypeCommand,
|
|
69
|
+
wrapInBlockTypeCommand,
|
|
70
|
+
addBlockTypeCommand,
|
|
71
|
+
selectTextNearPosCommand,
|
|
72
|
+
]
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { MilkdownPlugin } from '@jvs-milkdown/ctx'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
emphasisStarInputRule,
|
|
5
|
+
emphasisUnderscoreInputRule,
|
|
6
|
+
inlineCodeInputRule,
|
|
7
|
+
strongInputRule,
|
|
8
|
+
} from '../mark'
|
|
9
|
+
import {
|
|
10
|
+
createCodeBlockInputRule,
|
|
11
|
+
insertHrInputRule,
|
|
12
|
+
wrapInBlockquoteInputRule,
|
|
13
|
+
wrapInBulletListInputRule,
|
|
14
|
+
wrapInHeadingInputRule,
|
|
15
|
+
wrapInOrderedListInputRule,
|
|
16
|
+
} from '../node'
|
|
17
|
+
|
|
18
|
+
/// @internal
|
|
19
|
+
export const inputRules: MilkdownPlugin[] = [
|
|
20
|
+
wrapInBlockquoteInputRule,
|
|
21
|
+
wrapInBulletListInputRule,
|
|
22
|
+
wrapInOrderedListInputRule,
|
|
23
|
+
createCodeBlockInputRule,
|
|
24
|
+
insertHrInputRule,
|
|
25
|
+
wrapInHeadingInputRule,
|
|
26
|
+
].flat()
|
|
27
|
+
|
|
28
|
+
/// @internal
|
|
29
|
+
export const markInputRules: MilkdownPlugin[] = [
|
|
30
|
+
emphasisStarInputRule,
|
|
31
|
+
emphasisUnderscoreInputRule,
|
|
32
|
+
inlineCodeInputRule,
|
|
33
|
+
strongInputRule,
|
|
34
|
+
]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { MilkdownPlugin } from '@jvs-milkdown/ctx'
|
|
2
|
+
|
|
3
|
+
import { emphasisKeymap, inlineCodeKeymap, strongKeymap } from '../mark'
|
|
4
|
+
import {
|
|
5
|
+
blockquoteKeymap,
|
|
6
|
+
bulletListKeymap,
|
|
7
|
+
codeBlockKeymap,
|
|
8
|
+
hardbreakKeymap,
|
|
9
|
+
headingKeymap,
|
|
10
|
+
listItemKeymap,
|
|
11
|
+
orderedListKeymap,
|
|
12
|
+
paragraphKeymap,
|
|
13
|
+
} from '../node'
|
|
14
|
+
|
|
15
|
+
/// @internal
|
|
16
|
+
export const keymap: MilkdownPlugin[] = [
|
|
17
|
+
blockquoteKeymap,
|
|
18
|
+
codeBlockKeymap,
|
|
19
|
+
hardbreakKeymap,
|
|
20
|
+
headingKeymap,
|
|
21
|
+
listItemKeymap,
|
|
22
|
+
orderedListKeymap,
|
|
23
|
+
bulletListKeymap,
|
|
24
|
+
paragraphKeymap,
|
|
25
|
+
|
|
26
|
+
emphasisKeymap,
|
|
27
|
+
inlineCodeKeymap,
|
|
28
|
+
strongKeymap,
|
|
29
|
+
].flat()
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { MilkdownPlugin } from '@jvs-milkdown/ctx'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
hardbreakClearMarkPlugin,
|
|
5
|
+
hardbreakFilterNodes,
|
|
6
|
+
hardbreakFilterPlugin,
|
|
7
|
+
inlineNodesCursorPlugin,
|
|
8
|
+
remarkAddOrderInListPlugin,
|
|
9
|
+
remarkHtmlTransformer,
|
|
10
|
+
remarkInlineLinkPlugin,
|
|
11
|
+
remarkLineBreak,
|
|
12
|
+
remarkMarker,
|
|
13
|
+
remarkPreserveEmptyLinePlugin,
|
|
14
|
+
syncHeadingIdPlugin,
|
|
15
|
+
syncListOrderPlugin,
|
|
16
|
+
} from '../plugin'
|
|
17
|
+
|
|
18
|
+
/// @internal
|
|
19
|
+
export const plugins: MilkdownPlugin[] = [
|
|
20
|
+
hardbreakClearMarkPlugin,
|
|
21
|
+
hardbreakFilterNodes,
|
|
22
|
+
hardbreakFilterPlugin,
|
|
23
|
+
|
|
24
|
+
inlineNodesCursorPlugin,
|
|
25
|
+
|
|
26
|
+
remarkAddOrderInListPlugin,
|
|
27
|
+
remarkInlineLinkPlugin,
|
|
28
|
+
remarkLineBreak,
|
|
29
|
+
remarkHtmlTransformer,
|
|
30
|
+
remarkMarker,
|
|
31
|
+
remarkPreserveEmptyLinePlugin,
|
|
32
|
+
|
|
33
|
+
syncHeadingIdPlugin,
|
|
34
|
+
syncListOrderPlugin,
|
|
35
|
+
].flat()
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { MilkdownPlugin } from '@jvs-milkdown/ctx'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
emphasisAttr,
|
|
5
|
+
emphasisSchema,
|
|
6
|
+
inlineCodeAttr,
|
|
7
|
+
inlineCodeSchema,
|
|
8
|
+
linkAttr,
|
|
9
|
+
linkSchema,
|
|
10
|
+
strongAttr,
|
|
11
|
+
strongSchema,
|
|
12
|
+
} from '../mark'
|
|
13
|
+
import {
|
|
14
|
+
blockquoteAttr,
|
|
15
|
+
blockquoteSchema,
|
|
16
|
+
bulletListAttr,
|
|
17
|
+
bulletListSchema,
|
|
18
|
+
codeBlockAttr,
|
|
19
|
+
codeBlockSchema,
|
|
20
|
+
docSchema,
|
|
21
|
+
hardbreakAttr,
|
|
22
|
+
hardbreakSchema,
|
|
23
|
+
headingAttr,
|
|
24
|
+
headingIdGenerator,
|
|
25
|
+
headingSchema,
|
|
26
|
+
hrAttr,
|
|
27
|
+
hrSchema,
|
|
28
|
+
htmlAttr,
|
|
29
|
+
htmlSchema,
|
|
30
|
+
imageAttr,
|
|
31
|
+
imageSchema,
|
|
32
|
+
listItemAttr,
|
|
33
|
+
listItemSchema,
|
|
34
|
+
orderedListAttr,
|
|
35
|
+
orderedListSchema,
|
|
36
|
+
paragraphAttr,
|
|
37
|
+
paragraphSchema,
|
|
38
|
+
textSchema,
|
|
39
|
+
} from '../node'
|
|
40
|
+
|
|
41
|
+
/// @internal
|
|
42
|
+
export const schema: MilkdownPlugin[] = [
|
|
43
|
+
docSchema,
|
|
44
|
+
|
|
45
|
+
paragraphAttr,
|
|
46
|
+
paragraphSchema,
|
|
47
|
+
|
|
48
|
+
headingIdGenerator,
|
|
49
|
+
headingAttr,
|
|
50
|
+
headingSchema,
|
|
51
|
+
|
|
52
|
+
hardbreakAttr,
|
|
53
|
+
hardbreakSchema,
|
|
54
|
+
|
|
55
|
+
blockquoteAttr,
|
|
56
|
+
blockquoteSchema,
|
|
57
|
+
|
|
58
|
+
codeBlockAttr,
|
|
59
|
+
codeBlockSchema,
|
|
60
|
+
|
|
61
|
+
hrAttr,
|
|
62
|
+
hrSchema,
|
|
63
|
+
|
|
64
|
+
imageAttr,
|
|
65
|
+
imageSchema,
|
|
66
|
+
|
|
67
|
+
bulletListAttr,
|
|
68
|
+
bulletListSchema,
|
|
69
|
+
|
|
70
|
+
orderedListAttr,
|
|
71
|
+
orderedListSchema,
|
|
72
|
+
|
|
73
|
+
listItemAttr,
|
|
74
|
+
listItemSchema,
|
|
75
|
+
|
|
76
|
+
emphasisAttr,
|
|
77
|
+
emphasisSchema,
|
|
78
|
+
|
|
79
|
+
strongAttr,
|
|
80
|
+
strongSchema,
|
|
81
|
+
|
|
82
|
+
inlineCodeAttr,
|
|
83
|
+
inlineCodeSchema,
|
|
84
|
+
|
|
85
|
+
linkAttr,
|
|
86
|
+
linkSchema,
|
|
87
|
+
|
|
88
|
+
htmlAttr,
|
|
89
|
+
htmlSchema,
|
|
90
|
+
|
|
91
|
+
textSchema,
|
|
92
|
+
].flat()
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { MilkdownPlugin } from '@jvs-milkdown/ctx'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
commands,
|
|
5
|
+
inputRules,
|
|
6
|
+
keymap,
|
|
7
|
+
markInputRules,
|
|
8
|
+
plugins,
|
|
9
|
+
schema,
|
|
10
|
+
} from './composed'
|
|
11
|
+
|
|
12
|
+
export * from './node'
|
|
13
|
+
export * from './mark'
|
|
14
|
+
export * from './plugin'
|
|
15
|
+
export * from './composed'
|
|
16
|
+
export * from './commands'
|
|
17
|
+
|
|
18
|
+
/// The commonmark preset, includes all the plugins.
|
|
19
|
+
export const commonmark: MilkdownPlugin[] = [
|
|
20
|
+
schema,
|
|
21
|
+
inputRules,
|
|
22
|
+
markInputRules,
|
|
23
|
+
commands,
|
|
24
|
+
keymap,
|
|
25
|
+
plugins,
|
|
26
|
+
].flat()
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { commandsCtx, remarkStringifyOptionsCtx } from '@jvs-milkdown/core'
|
|
2
|
+
import { markRule } from '@jvs-milkdown/prose'
|
|
3
|
+
import { toggleMark } from '@jvs-milkdown/prose/commands'
|
|
4
|
+
import {
|
|
5
|
+
$command,
|
|
6
|
+
$inputRule,
|
|
7
|
+
$markAttr,
|
|
8
|
+
$markSchema,
|
|
9
|
+
$useKeymap,
|
|
10
|
+
} from '@jvs-milkdown/utils'
|
|
11
|
+
|
|
12
|
+
import { withMeta } from '../__internal__'
|
|
13
|
+
|
|
14
|
+
/// HTML attributes for the emphasis mark.
|
|
15
|
+
export const emphasisAttr = $markAttr('emphasis')
|
|
16
|
+
|
|
17
|
+
withMeta(emphasisAttr, {
|
|
18
|
+
displayName: 'Attr<emphasis>',
|
|
19
|
+
group: 'Emphasis',
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
/// Emphasis mark schema.
|
|
23
|
+
export const emphasisSchema = $markSchema('emphasis', (ctx) => ({
|
|
24
|
+
attrs: {
|
|
25
|
+
marker: {
|
|
26
|
+
default: ctx.get(remarkStringifyOptionsCtx).emphasis || '*',
|
|
27
|
+
validate: 'string',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
parseDOM: [
|
|
31
|
+
{ tag: 'i' },
|
|
32
|
+
{ tag: 'em' },
|
|
33
|
+
{ style: 'font-style', getAttrs: (value) => (value === 'italic') as false },
|
|
34
|
+
],
|
|
35
|
+
toDOM: (mark) => ['em', ctx.get(emphasisAttr.key)(mark)],
|
|
36
|
+
parseMarkdown: {
|
|
37
|
+
match: (node) => node.type === 'emphasis',
|
|
38
|
+
runner: (state, node, markType) => {
|
|
39
|
+
state.openMark(markType, { marker: node.marker })
|
|
40
|
+
state.next(node.children)
|
|
41
|
+
state.closeMark(markType)
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
toMarkdown: {
|
|
45
|
+
match: (mark) => mark.type.name === 'emphasis',
|
|
46
|
+
runner: (state, mark) => {
|
|
47
|
+
state.withMark(mark, 'emphasis', undefined, {
|
|
48
|
+
marker: mark.attrs.marker,
|
|
49
|
+
})
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
}))
|
|
53
|
+
|
|
54
|
+
withMeta(emphasisSchema.mark, {
|
|
55
|
+
displayName: 'MarkSchema<emphasis>',
|
|
56
|
+
group: 'Emphasis',
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
withMeta(emphasisSchema.ctx, {
|
|
60
|
+
displayName: 'MarkSchemaCtx<emphasis>',
|
|
61
|
+
group: 'Emphasis',
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
/// A command to toggle the emphasis mark.
|
|
65
|
+
export const toggleEmphasisCommand = $command('ToggleEmphasis', (ctx) => () => {
|
|
66
|
+
return toggleMark(emphasisSchema.type(ctx))
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
withMeta(toggleEmphasisCommand, {
|
|
70
|
+
displayName: 'Command<toggleEmphasisCommand>',
|
|
71
|
+
group: 'Emphasis',
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
/// Input rule for use `*` to create emphasis mark.
|
|
75
|
+
export const emphasisStarInputRule = $inputRule((ctx) => {
|
|
76
|
+
return markRule(/(?:^|[^*])\*([^*]+)\*$/, emphasisSchema.type(ctx), {
|
|
77
|
+
getAttr: () => ({
|
|
78
|
+
marker: '*',
|
|
79
|
+
}),
|
|
80
|
+
updateCaptured: ({ fullMatch, start }) =>
|
|
81
|
+
!fullMatch.startsWith('*')
|
|
82
|
+
? { fullMatch: fullMatch.slice(1), start: start + 1 }
|
|
83
|
+
: {},
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
withMeta(emphasisStarInputRule, {
|
|
88
|
+
displayName: 'InputRule<emphasis>|Star',
|
|
89
|
+
group: 'Emphasis',
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
/// Input rule for use `_` to create emphasis mark.
|
|
93
|
+
export const emphasisUnderscoreInputRule = $inputRule((ctx) => {
|
|
94
|
+
return markRule(/\b_(?![_\s])(.*?[^_\s])_\b/, emphasisSchema.type(ctx), {
|
|
95
|
+
getAttr: () => ({
|
|
96
|
+
marker: '_',
|
|
97
|
+
}),
|
|
98
|
+
updateCaptured: ({ fullMatch, start }) =>
|
|
99
|
+
!fullMatch.startsWith('_')
|
|
100
|
+
? { fullMatch: fullMatch.slice(1), start: start + 1 }
|
|
101
|
+
: {},
|
|
102
|
+
})
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
withMeta(emphasisUnderscoreInputRule, {
|
|
106
|
+
displayName: 'InputRule<emphasis>|Underscore',
|
|
107
|
+
group: 'Emphasis',
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
/// Keymap for the emphasis mark.
|
|
111
|
+
/// - `Mod-i` - Toggle the emphasis mark.
|
|
112
|
+
export const emphasisKeymap = $useKeymap('emphasisKeymap', {
|
|
113
|
+
ToggleEmphasis: {
|
|
114
|
+
shortcuts: 'Mod-i',
|
|
115
|
+
command: (ctx) => {
|
|
116
|
+
const commands = ctx.get(commandsCtx)
|
|
117
|
+
return () => commands.call(toggleEmphasisCommand.key)
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
withMeta(emphasisKeymap.ctx, {
|
|
123
|
+
displayName: 'KeymapCtx<emphasis>',
|
|
124
|
+
group: 'Emphasis',
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
withMeta(emphasisKeymap.shortcuts, {
|
|
128
|
+
displayName: 'Keymap<emphasis>',
|
|
129
|
+
group: 'Emphasis',
|
|
130
|
+
})
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import type { MarkType } from '@jvs-milkdown/prose/model'
|
|
2
|
+
|
|
3
|
+
import { commandsCtx } from '@jvs-milkdown/core'
|
|
4
|
+
import { markRule } from '@jvs-milkdown/prose'
|
|
5
|
+
import {
|
|
6
|
+
$command,
|
|
7
|
+
$inputRule,
|
|
8
|
+
$markAttr,
|
|
9
|
+
$markSchema,
|
|
10
|
+
$useKeymap,
|
|
11
|
+
} from '@jvs-milkdown/utils'
|
|
12
|
+
|
|
13
|
+
import { withMeta } from '../__internal__'
|
|
14
|
+
|
|
15
|
+
/// HTML attributes for the inlineCode mark.
|
|
16
|
+
export const inlineCodeAttr = $markAttr('inlineCode')
|
|
17
|
+
|
|
18
|
+
withMeta(inlineCodeAttr, {
|
|
19
|
+
displayName: 'Attr<inlineCode>',
|
|
20
|
+
group: 'InlineCode',
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
/// InlineCode mark schema.
|
|
24
|
+
export const inlineCodeSchema = $markSchema('inlineCode', (ctx) => ({
|
|
25
|
+
priority: 100,
|
|
26
|
+
code: true,
|
|
27
|
+
parseDOM: [{ tag: 'code' }],
|
|
28
|
+
toDOM: (mark) => ['code', ctx.get(inlineCodeAttr.key)(mark)],
|
|
29
|
+
parseMarkdown: {
|
|
30
|
+
match: (node) => node.type === 'inlineCode',
|
|
31
|
+
runner: (state, node, markType) => {
|
|
32
|
+
state.openMark(markType)
|
|
33
|
+
state.addText(node.value as string)
|
|
34
|
+
state.closeMark(markType)
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
toMarkdown: {
|
|
38
|
+
match: (mark) => mark.type.name === 'inlineCode',
|
|
39
|
+
runner: (state, mark, node) => {
|
|
40
|
+
state.withMark(mark, 'inlineCode', node.text || '')
|
|
41
|
+
return true
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
}))
|
|
45
|
+
|
|
46
|
+
withMeta(inlineCodeSchema.mark, {
|
|
47
|
+
displayName: 'MarkSchema<inlineCode>',
|
|
48
|
+
group: 'InlineCode',
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
withMeta(inlineCodeSchema.ctx, {
|
|
52
|
+
displayName: 'MarkSchemaCtx<inlineCode>',
|
|
53
|
+
group: 'InlineCode',
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
/// A command to toggle the inlineCode mark.
|
|
57
|
+
export const toggleInlineCodeCommand = $command(
|
|
58
|
+
'ToggleInlineCode',
|
|
59
|
+
(ctx) => () => (state, dispatch) => {
|
|
60
|
+
const { selection, tr } = state
|
|
61
|
+
if (selection.empty) return false
|
|
62
|
+
const { from, to } = selection
|
|
63
|
+
|
|
64
|
+
const has = state.doc.rangeHasMark(from, to, inlineCodeSchema.type(ctx))
|
|
65
|
+
// remove exists inlineCode mark if have
|
|
66
|
+
if (has) {
|
|
67
|
+
dispatch?.(tr.removeMark(from, to, inlineCodeSchema.type(ctx)))
|
|
68
|
+
return true
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const restMarksName = Object.keys(state.schema.marks).filter(
|
|
72
|
+
(x) => x !== inlineCodeSchema.type.name
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
// remove other marks
|
|
76
|
+
restMarksName
|
|
77
|
+
.map((name) => state.schema.marks[name] as MarkType)
|
|
78
|
+
.forEach((t) => {
|
|
79
|
+
tr.removeMark(from, to, t)
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
// add inlineCode mark
|
|
83
|
+
dispatch?.(tr.addMark(from, to, inlineCodeSchema.type(ctx).create()))
|
|
84
|
+
return true
|
|
85
|
+
}
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
withMeta(toggleInlineCodeCommand, {
|
|
89
|
+
displayName: 'Command<toggleInlineCodeCommand>',
|
|
90
|
+
group: 'InlineCode',
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
/// Input rule for create inlineCode mark.
|
|
94
|
+
export const inlineCodeInputRule = $inputRule((ctx) => {
|
|
95
|
+
return markRule(/(?:`)([^`]+)(?:`)$/, inlineCodeSchema.type(ctx))
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
withMeta(inlineCodeInputRule, {
|
|
99
|
+
displayName: 'InputRule<inlineCodeInputRule>',
|
|
100
|
+
group: 'InlineCode',
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
/// Keymap for the inlineCode mark.
|
|
104
|
+
/// - `Mod-e` - Toggle the inlineCode mark.
|
|
105
|
+
export const inlineCodeKeymap = $useKeymap('inlineCodeKeymap', {
|
|
106
|
+
ToggleInlineCode: {
|
|
107
|
+
shortcuts: 'Mod-e',
|
|
108
|
+
command: (ctx) => {
|
|
109
|
+
const commands = ctx.get(commandsCtx)
|
|
110
|
+
return () => commands.call(toggleInlineCodeCommand.key)
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
withMeta(inlineCodeKeymap.ctx, {
|
|
116
|
+
displayName: 'KeymapCtx<inlineCode>',
|
|
117
|
+
group: 'InlineCode',
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
withMeta(inlineCodeKeymap.shortcuts, {
|
|
121
|
+
displayName: 'Keymap<inlineCode>',
|
|
122
|
+
group: 'InlineCode',
|
|
123
|
+
})
|