diff --git a/src/components/Widgets/Markdown/MarkdownControl/VisualEditor/index.js b/src/components/Widgets/Markdown/MarkdownControl/VisualEditor/index.js index 26f36ee0..b801510f 100644 --- a/src/components/Widgets/Markdown/MarkdownControl/VisualEditor/index.js +++ b/src/components/Widgets/Markdown/MarkdownControl/VisualEditor/index.js @@ -193,6 +193,7 @@ const RULES = [ return { kind: 'inline', type: 'image', + isVoid: true, nodes: [], data: { src: el.attribs.src, diff --git a/src/components/Widgets/Markdown/unified.js b/src/components/Widgets/Markdown/unified.js index 0d7e6957..6a306e35 100644 --- a/src/components/Widgets/Markdown/unified.js +++ b/src/components/Widgets/Markdown/unified.js @@ -1,3 +1,4 @@ +import find from 'lodash/find'; import unified from 'unified'; import markdownToRemark from 'remark-parse'; import remarkToRehype from 'remark-rehype'; @@ -12,22 +13,61 @@ const remarkParseConfig = { fences: true }; const remarkStringifyConfig = { listItemIndent: '1', fences: true }; const rehypeParseConfig = { fragment: true }; -export const markdownToHtml = markdown => - unified() +const rehypeRemoveEmpty = () => { + const isVoidElement = node => ['img', 'hr'].includes(node.tagName); + const isNonEmptyText = node => node.type === 'text' && node.value; + const isNonEmptyNode = node => { + return isVoidElement(node) || isNonEmptyText(node) || find(node.children, isNonEmptyNode); + }; + + const transform = node => { + if (isVoidElement(node) || isNonEmptyText(node)) { + return node; + } + if (node.children) { + node.children = node.children.reduce((acc, childNode) => { + if (isVoidElement(childNode) || isNonEmptyText(childNode)) { + return acc.concat(childNode); + } + return find(childNode.children, isNonEmptyNode) ? acc.concat(transform(childNode)) : acc; + }, []); + } + return node; + }; + return transform; +}; + +const rehypePaperEmoji = () => { + const transform = node => { + if (node.tagName === 'img' && node.properties.dataEmojiCh) { + return { type: 'text', value: node.properties.dataEmojiCh }; + } + node.children = node.children ? node.children.map(transform) : node.children; + return node; + }; + return transform; +}; + +export const markdownToHtml = markdown => { + console.log('markdownToHtml input', markdown); + const result = unified() .use(markdownToRemark, remarkParseConfig) .use(remarkToRehype) - .use(rehypeSanitize) - .use(rehypeMinifyWhitespace) .use(rehypeToHtml) .processSync(markdown) .contents; + console.log('markdownToHtml output', result); + return result; +} -export const htmlToMarkdown = html => - unified() +export const htmlToMarkdown = html => { + console.log('htmlToMarkdown input', html); + const result = unified() .use(htmlToRehype, rehypeParseConfig) - .use(rehypeSanitize) - .use(rehypeMinifyWhitespace) .use(rehypeToRemark) .use(remarkToMarkdown, remarkStringifyConfig) .processSync(html) .contents; + console.log('htmlToMarkdown output', result); + return result; +};