diff --git a/src/components/Widgets/Markdown/unified.js b/src/components/Widgets/Markdown/unified.js index e63c1342..bade1642 100644 --- a/src/components/Widgets/Markdown/unified.js +++ b/src/components/Widgets/Markdown/unified.js @@ -202,19 +202,49 @@ const remarkShortcodes = ({ plugins }) => { } }; + +/** + * This plugin doesn't actually transform Remark (MDAST) nodes to Rehype + * (HAST) nodes, but rather, it prepares an MDAST shortcode node for HAST + * conversion by replacing the shortcode text with stringified HTML for + * previewing the shortcode output. + */ const remarkToRehypeShortcodes = ({ plugins, getAsset }) => { return transform; - function transform(node) { - const children = node.children ? node.children.map(transform) : node.children; - if (!has(node, ['data', 'shortcode'])) { - return { ...node, children }; - } + function transform(root) { + const transformedChildren = map(root.children, processShortcodes); + return { ...root, children: transformedChildren }; + } + + /** + * Mapping function to transform nodes that contain shortcodes. + */ + function processShortcodes(node) { + /** + * If the node doesn't contain shortcode data, return the original node. + */ + if (!has(node, ['data', 'shortcode'])) return node; + + /** + * Get shortcode data from the node, and retrieve the matching plugin by + * key. + */ const { shortcode, shortcodeData } = node.data; const plugin = plugins.get(shortcode); + + /** + * Run the shortcode plugin's `toPreview` method, which will return either + * an HTML string or a React component. If a React component is returned, + * render it to an HTML string. + */ const value = plugin.toPreview(shortcodeData, getAsset); const valueHtml = typeof value === 'string' ? value : renderToString(value); - return { ...node, value: valueHtml }; + + /** + * Return a new 'html' type node containing the shortcode preview markup. + */ + return u('html', valueHtml); } };