UNPKG

@tiptap/extension-code

Version:

code extension for tiptap

134 lines (114 loc) 2.82 kB
import { Mark, markInputRule, markPasteRule, mergeAttributes } from '@tiptap/core' export interface CodeOptions { /** * The HTML attributes applied to the code element. * @default {} * @example { class: 'foo' } */ HTMLAttributes: Record<string, any> } declare module '@tiptap/core' { interface Commands<ReturnType> { code: { /** * Set a code mark */ setCode: () => ReturnType /** * Toggle inline code */ toggleCode: () => ReturnType /** * Unset a code mark */ unsetCode: () => ReturnType } } } /** * Regular expressions to match inline code blocks enclosed in backticks. * It matches: * - An opening backtick, followed by * - Any text that doesn't include a backtick (captured for marking), followed by * - A closing backtick as the final character. * This ensures that any text between backticks is formatted as code, * regardless of the surrounding characters (exception being another backtick). */ export const inputRegex = /(^|[^`])`([^`]+)`(?!`)$/ /** * Matches inline code while pasting. */ export const pasteRegex = /(^|[^`])`([^`]+)`(?!`)/g /** * This extension allows you to mark text as inline code. * @see https://tiptap.dev/api/marks/code */ export const Code = Mark.create<CodeOptions>({ name: 'code', addOptions() { return { HTMLAttributes: {}, } }, excludes: '_', code: true, exitable: true, parseHTML() { return [{ tag: 'code' }] }, renderHTML({ HTMLAttributes }) { return ['code', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0] }, markdownTokenName: 'codespan', parseMarkdown: (token, helpers) => { // Convert 'codespan' token to code mark // For codespan tokens, we use the raw text content, not tokens return helpers.applyMark('code', [{ type: 'text', text: token.text || '' }]) }, renderMarkdown: (node, h) => { if (!node.content) { return '' } return `\`${h.renderChildren(node.content)}\`` }, addCommands() { return { setCode: () => ({ commands }) => { return commands.setMark(this.name) }, toggleCode: () => ({ commands }) => { return commands.toggleMark(this.name) }, unsetCode: () => ({ commands }) => { return commands.unsetMark(this.name) }, } }, addKeyboardShortcuts() { return { 'Mod-e': () => this.editor.commands.toggleCode(), } }, addInputRules() { return [ markInputRule({ find: inputRegex, type: this.type, }), ] }, addPasteRules() { return [ markPasteRule({ find: pasteRegex, type: this.type, }), ] }, })