1 import {MarkdownSerializer, defaultMarkdownSerializer, MarkdownSerializerState} from "prosemirror-markdown";
2 import {docToHtml} from "./util";
4 const nodes = defaultMarkdownSerializer.nodes;
5 const marks = defaultMarkdownSerializer.marks;
8 nodes.callout = function (state, node) {
9 writeNodeAsHtml(state, node);
12 nodes.table = function (state, node) {
13 writeNodeAsHtml(state, node);
16 nodes.iframe = function (state, node) {
17 writeNodeAsHtml(state, node);
20 nodes.details = function (state, node) {
21 wrapNodeWithHtml(state, node, '<details>', '</details>');
24 nodes.details_summary = function(state, node) {
25 writeNodeAsHtml(state, node);
28 function isPlainURL(link, parent, index, side) {
29 if (link.attrs.title || !/^\w+:/.test(link.attrs.href)) {
32 const content = parent.child(index + (side < 0 ? -1 : 0));
33 if (!content.isText || content.text != link.attrs.href || content.marks[content.marks.length - 1] != link) {
36 if (index == (side < 0 ? 1 : parent.childCount - 1)) {
39 const next = parent.child(index + (side < 0 ? -2 : 1));
40 return !link.isInSet(next.marks)
44 open(state, mark, parent, index) {
45 const attrs = mark.attrs;
47 return `<a href="${attrs.target}" ${attrs.title ? `title="${attrs.title}"` : ''} target="${attrs.target}">`
49 return isPlainURL(mark, parent, index, 1) ? "<" : "["
51 close(state, mark, parent, index) {
52 if (mark.attrs.target) {
55 return isPlainURL(mark, parent, index, -1) ? ">"
56 : "](" + state.esc(mark.attrs.href) + (mark.attrs.title ? " " + state.quote(mark.attrs.title) : "") + ")"
61 open: '<span style="text-decoration: underline;">',
66 open: '<span style="text-decoration: line-through;">',
81 open(state, mark, parent, index) {
82 return `<span style="color: ${mark.attrs.color};">`
87 marks.background_color = {
88 open(state, mark, parent, index) {
89 return `<span style="background-color: ${mark.attrs.color};">`
95 * @param {MarkdownSerializerState} state
96 * @param {PmNode} node
98 function writeNodeAsHtml(state, node) {
99 const html = docToHtml({content: [node]});
101 state.ensureNewLine();
107 * @param {MarkdownSerializerState} state
108 * @param {PmNode} node
109 * @param {String} openTag
110 * @param {String} closeTag
112 function wrapNodeWithHtml(state, node, openTag, closeTag) {
113 state.write(openTag);
114 state.ensureNewLine();
115 state.renderContent(node);
116 state.write(closeTag);
118 state.ensureNewLine();
122 // Update serializers to just write out as HTML if we have an attribute
123 // or element that cannot be represented in commonmark without losing
124 // formatting or content.
125 for (const [nodeType, serializerFunction] of Object.entries(nodes)) {
126 nodes[nodeType] = function (state, node, parent, index) {
127 if (node.attrs.align || node.attrs.height || node.attrs.width) {
128 writeNodeAsHtml(state, node);
130 serializerFunction(state, node, parent, index);
136 const serializer = new MarkdownSerializer(nodes, marks);
138 export default serializer;