89 lines
2.5 KiB
TypeScript
89 lines
2.5 KiB
TypeScript
import { createDocument, getSchema } from '@tiptap/react'
|
|
import { StarterKit } from '@tiptap/starter-kit'
|
|
import { MarkdownSerializer, defaultMarkdownSerializer } from 'prosemirror-markdown'
|
|
import BulletList from '@tiptap/extension-bullet-list'
|
|
import ListItem from '@tiptap/extension-list-item'
|
|
import OrderedList from '@tiptap/extension-ordered-list'
|
|
import CodeBlock from '@tiptap/extension-code-block'
|
|
import Paragraph from '@tiptap/extension-paragraph'
|
|
|
|
import { Reference } from './referenceType'
|
|
|
|
import ReferenceExtension, {
|
|
REFERENCE_TYPE_ATTRIBUTE_NAME,
|
|
REFERENCE_VALUE_ATTRIBUTE_NAME,
|
|
} from 'editor/extensions/reference'
|
|
|
|
|
|
export const extensions = [
|
|
StarterKit.configure({
|
|
blockquote: false,
|
|
bold: false,
|
|
// code: false,
|
|
dropcursor: false,
|
|
hardBreak: false,
|
|
// heading: false,
|
|
horizontalRule: false,
|
|
italic: false,
|
|
strike: false,
|
|
paragraph: false,
|
|
|
|
// We use the Ordered List, Code block, Bullet List and List item from explicit packages
|
|
// so we can use their names in the markdown serializer.
|
|
codeBlock: false,
|
|
bulletList: false,
|
|
listItem: false,
|
|
orderedList: false,
|
|
}),
|
|
Paragraph,
|
|
CodeBlock,
|
|
OrderedList,
|
|
ListItem,
|
|
BulletList,
|
|
ReferenceExtension,
|
|
]
|
|
|
|
const schema = getSchema(extensions)
|
|
|
|
const serializer = new MarkdownSerializer({
|
|
...defaultMarkdownSerializer.nodes,
|
|
[OrderedList.name]: defaultMarkdownSerializer.nodes.ordered_list,
|
|
[ListItem.name]: defaultMarkdownSerializer.nodes.list_item,
|
|
[BulletList.name]: defaultMarkdownSerializer.nodes.bullet_list,
|
|
[CodeBlock.name]: defaultMarkdownSerializer.nodes.code_block,
|
|
[Paragraph.name]: (state, node) => {
|
|
state.text('\n')
|
|
state.renderInline(node)
|
|
},
|
|
[ReferenceExtension.name]: (state, node) => {
|
|
state.text(' `' + node.attrs[REFERENCE_VALUE_ATTRIBUTE_NAME] + '` ')
|
|
},
|
|
}, {
|
|
...defaultMarkdownSerializer.marks,
|
|
})
|
|
|
|
|
|
export function html2markdown(html: string): [string, Reference[]] {
|
|
const node = createDocument(html, schema)
|
|
const markdown = serializer.serialize(node)
|
|
|
|
const references: Reference[] = []
|
|
|
|
node.descendants(n => {
|
|
if (n.type.name === ReferenceExtension.name) {
|
|
references.push({
|
|
type: n.attrs[REFERENCE_TYPE_ATTRIBUTE_NAME],
|
|
value: n.attrs[REFERENCE_VALUE_ATTRIBUTE_NAME],
|
|
})
|
|
}
|
|
})
|
|
|
|
const uniqueReferences = references.filter((reference, index, self) =>
|
|
index === self.findIndex((r) => (
|
|
r.type === reference.type && r.value === reference.value
|
|
))
|
|
)
|
|
|
|
return [markdown, uniqueReferences]
|
|
}
|