124 lines
2.6 KiB
TypeScript
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(),
|
|
}
|
|
},
|
|
})
|