dd/node_modules/@tiptap/extension-underline/src/underline.ts
2026-06-14 15:46:45 +08:00

124 lines
2.6 KiB
TypeScript

import { Mark, mergeAttributes } from '@tiptap/core'
export interface UnderlineOptions {
/**
* HTML attributes to add to the underline element.
* @default {}
* @example { class: 'foo' }
*/
HTMLAttributes: Record<string, any>
}
declare module '@tiptap/core' {
interface Commands<ReturnType> {
underline: {
/**
* Set an underline mark
* @example editor.commands.setUnderline()
*/
setUnderline: () => ReturnType
/**
* Toggle an underline mark
* @example editor.commands.toggleUnderline()
*/
toggleUnderline: () => ReturnType
/**
* Unset an underline mark
* @example editor.commands.unsetUnderline()
*/
unsetUnderline: () => ReturnType
}
}
}
/**
* This extension allows you to create underline text.
* @see https://www.tiptap.dev/api/marks/underline
*/
export const Underline = Mark.create<UnderlineOptions>({
name: 'underline',
addOptions() {
return {
HTMLAttributes: {},
}
},
parseHTML() {
return [
{
tag: 'u',
},
{
style: 'text-decoration',
consuming: false,
getAttrs: style => ((style as string).includes('underline') ? {} : false),
},
]
},
renderHTML({ HTMLAttributes }) {
return ['u', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]
},
parseMarkdown(token, helpers) {
return helpers.applyMark(this.name || 'underline', helpers.parseInline(token.tokens || []))
},
renderMarkdown(node, helpers) {
return `++${helpers.renderChildren(node)}++`
},
markdownTokenizer: {
name: 'underline',
level: 'inline',
start(src) {
return src.indexOf('++')
},
tokenize(src, _tokens, lexer) {
const rule = /^(\+\+)([\s\S]+?)(\+\+)/
const match = rule.exec(src)
if (!match) {
return undefined
}
const innerContent = match[2].trim()
return {
type: 'underline',
raw: match[0],
text: innerContent,
tokens: lexer.inlineTokens(innerContent),
}
},
},
addCommands() {
return {
setUnderline:
() =>
({ commands }) => {
return commands.setMark(this.name)
},
toggleUnderline:
() =>
({ commands }) => {
return commands.toggleMark(this.name)
},
unsetUnderline:
() =>
({ commands }) => {
return commands.unsetMark(this.name)
},
}
},
addKeyboardShortcuts() {
return {
'Mod-u': () => this.editor.commands.toggleUnderline(),
'Mod-U': () => this.editor.commands.toggleUnderline(),
}
},
})