UNPKG

@milkdown/preset-commonmark

Version:

The commonmark preset of [milkdown](https://milkdown.dev/).

123 lines (104 loc) 3.16 kB
import type { MarkType } from '@milkdown/prose/model' import { commandsCtx } from '@milkdown/core' import { markRule } from '@milkdown/prose' import { $command, $inputRule, $markAttr, $markSchema, $useKeymap, } from '@milkdown/utils' import { withMeta } from '../__internal__' /// HTML attributes for the inlineCode mark. export const inlineCodeAttr = $markAttr('inlineCode') withMeta(inlineCodeAttr, { displayName: 'Attr<inlineCode>', group: 'InlineCode', }) /// InlineCode mark schema. export const inlineCodeSchema = $markSchema('inlineCode', (ctx) => ({ priority: 100, code: true, parseDOM: [{ tag: 'code' }], toDOM: (mark) => ['code', ctx.get(inlineCodeAttr.key)(mark)], parseMarkdown: { match: (node) => node.type === 'inlineCode', runner: (state, node, markType) => { state.openMark(markType) state.addText(node.value as string) state.closeMark(markType) }, }, toMarkdown: { match: (mark) => mark.type.name === 'inlineCode', runner: (state, mark, node) => { state.withMark(mark, 'inlineCode', node.text || '') }, }, })) withMeta(inlineCodeSchema.mark, { displayName: 'MarkSchema<inlineCode>', group: 'InlineCode', }) withMeta(inlineCodeSchema.ctx, { displayName: 'MarkSchemaCtx<inlineCode>', group: 'InlineCode', }) /// A command to toggle the inlineCode mark. export const toggleInlineCodeCommand = $command( 'ToggleInlineCode', (ctx) => () => (state, dispatch) => { const { selection, tr } = state if (selection.empty) return false const { from, to } = selection const has = state.doc.rangeHasMark(from, to, inlineCodeSchema.type(ctx)) // remove exists inlineCode mark if have if (has) { dispatch?.(tr.removeMark(from, to, inlineCodeSchema.type(ctx))) return true } const restMarksName = Object.keys(state.schema.marks).filter( (x) => x !== inlineCodeSchema.type.name ) // remove other marks restMarksName .map((name) => state.schema.marks[name] as MarkType) .forEach((t) => { tr.removeMark(from, to, t) }) // add inlineCode mark dispatch?.(tr.addMark(from, to, inlineCodeSchema.type(ctx).create())) return true } ) withMeta(toggleInlineCodeCommand, { displayName: 'Command<toggleInlineCodeCommand>', group: 'InlineCode', }) /// Input rule for create inlineCode mark. export const inlineCodeInputRule = $inputRule((ctx) => { return markRule(/(?:`)([^`]+)(?:`)$/, inlineCodeSchema.type(ctx)) }) withMeta(inlineCodeInputRule, { displayName: 'InputRule<inlineCodeInputRule>', group: 'InlineCode', }) /// Keymap for the inlineCode mark. /// - `Mod-e` - Toggle the inlineCode mark. export const inlineCodeKeymap = $useKeymap('inlineCodeKeymap', { ToggleInlineCode: { shortcuts: 'Mod-e', command: (ctx) => { const commands = ctx.get(commandsCtx) return () => commands.call(toggleInlineCodeCommand.key) }, }, }) withMeta(inlineCodeKeymap.ctx, { displayName: 'KeymapCtx<inlineCode>', group: 'InlineCode', }) withMeta(inlineCodeKeymap.shortcuts, { displayName: 'Keymap<inlineCode>', group: 'InlineCode', })