mirror of
https://github.com/nocodb/nocodb.git
synced 2026-05-02 19:37:09 +00:00
65 lines
1.7 KiB
TypeScript
65 lines
1.7 KiB
TypeScript
import type { Mark, Node } from '@tiptap/pm/model'
|
|
import { MarkdownSerializerState as BaseMarkdownSerializerState } from '@tiptap/pm/markdown'
|
|
import { trimInline } from '../util/markdown'
|
|
|
|
interface InlineState {
|
|
delimiter?: string
|
|
start?: number
|
|
end?: number
|
|
}
|
|
|
|
/**
|
|
* Override default MarkdownSerializerState to:
|
|
* - handle commonmark delimiters (https://spec.commonmark.org/0.29/#left-flanking-delimiter-run)
|
|
*/
|
|
export class MarkdownSerializerState extends BaseMarkdownSerializerState {
|
|
inTable = false
|
|
public inlines: InlineState[] = []
|
|
public out = ''
|
|
|
|
constructor(nodes, marks, options) {
|
|
super(nodes, marks, options ?? {})
|
|
this.inlines = []
|
|
}
|
|
|
|
override render(node: Node, parent: Node, index: number): void {
|
|
super.render(node, parent, index)
|
|
const top = this.inlines[this.inlines.length - 1]
|
|
if (top?.start && top?.end) {
|
|
const { delimiter, start, end } = this.normalizeInline(top)
|
|
this.out = trimInline(this.out, delimiter, start, end)
|
|
this.inlines.pop()
|
|
}
|
|
}
|
|
|
|
override markString(mark: Mark, open: boolean, parent: Node, index: number): string {
|
|
const info = this.marks[mark.type.name]
|
|
if (info.expelEnclosingWhitespace) {
|
|
if (open) {
|
|
this.inlines.push({
|
|
start: this.out.length,
|
|
delimiter: info.open,
|
|
})
|
|
} else {
|
|
const top = this.inlines.pop() || {}
|
|
this.inlines.push({
|
|
...top,
|
|
end: this.out.length,
|
|
})
|
|
}
|
|
}
|
|
return super.markString(mark, open, parent, index)
|
|
}
|
|
|
|
normalizeInline(inline) {
|
|
let { start } = inline
|
|
while (this.out.charAt(start).match(/\s/)) {
|
|
start++
|
|
}
|
|
return {
|
|
...inline,
|
|
start,
|
|
}
|
|
}
|
|
}
|