@milkdown/preset-commonmark
Version:
The commonmark preset of [milkdown](https://milkdown.dev/).
130 lines (115 loc) • 3.21 kB
text/typescript
import { commandsCtx } from '@milkdown/core'
import { expectDomTypeError } from '@milkdown/exception'
import { wrapIn } from '@milkdown/prose/commands'
import { wrappingInputRule } from '@milkdown/prose/inputrules'
import {
$command,
$inputRule,
$nodeAttr,
$nodeSchema,
$useKeymap,
} from '@milkdown/utils'
import { withMeta } from '../__internal__'
/// HTML attributes for bullet list node.
export const bulletListAttr = $nodeAttr('bulletList')
withMeta(bulletListAttr, {
displayName: 'Attr<bulletList>',
group: 'BulletList',
})
/// Schema for bullet list node.
export const bulletListSchema = $nodeSchema('bullet_list', (ctx) => {
return {
content: 'listItem+',
group: 'block',
attrs: {
spread: {
default: false,
validate: 'boolean',
},
},
parseDOM: [
{
tag: 'ul',
getAttrs: (dom) => {
if (!(dom instanceof HTMLElement)) throw expectDomTypeError(dom)
return {
spread: dom.dataset.spread === 'true',
}
},
},
],
toDOM: (node) => {
return [
'ul',
{
...ctx.get(bulletListAttr.key)(node),
'data-spread': node.attrs.spread,
},
0,
]
},
parseMarkdown: {
match: ({ type, ordered }) => type === 'list' && !ordered,
runner: (state, node, type) => {
const spread = node.spread != null ? `${node.spread}` : 'false'
state.openNode(type, { spread }).next(node.children).closeNode()
},
},
toMarkdown: {
match: (node) => node.type.name === 'bullet_list',
runner: (state, node) => {
state
.openNode('list', undefined, {
ordered: false,
spread: node.attrs.spread,
})
.next(node.content)
.closeNode()
},
},
}
})
withMeta(bulletListSchema.node, {
displayName: 'NodeSchema<bulletList>',
group: 'BulletList',
})
withMeta(bulletListSchema.ctx, {
displayName: 'NodeSchemaCtx<bulletList>',
group: 'BulletList',
})
/// Input rule for wrapping a block in bullet list node.
export const wrapInBulletListInputRule = $inputRule((ctx) =>
wrappingInputRule(/^\s*([-+*])\s$/, bulletListSchema.type(ctx))
)
withMeta(wrapInBulletListInputRule, {
displayName: 'InputRule<wrapInBulletListInputRule>',
group: 'BulletList',
})
/// Command for creating bullet list node.
export const wrapInBulletListCommand = $command(
'WrapInBulletList',
(ctx) => () => wrapIn(bulletListSchema.type(ctx))
)
withMeta(wrapInBulletListCommand, {
displayName: 'Command<wrapInBulletListCommand>',
group: 'BulletList',
})
/// Keymap for bullet list node.
/// - `Mod-Alt-8`: Wrap a block in bullet list.
export const bulletListKeymap = $useKeymap('bulletListKeymap', {
WrapInBulletList: {
shortcuts: 'Mod-Alt-8',
command: (ctx) => {
const commands = ctx.get(commandsCtx)
return () => commands.call(wrapInBulletListCommand.key)
},
},
})
withMeta(bulletListKeymap.ctx, {
displayName: 'KeymapCtx<bulletListKeymap>',
group: 'BulletList',
})
withMeta(bulletListKeymap.shortcuts, {
displayName: 'Keymap<bulletListKeymap>',
group: 'BulletList',
})