dopry/netlify-cms

View on GitHub
src/components/Widgets/Markdown/serializers/remarkSquashReferences.js

Summary

Maintainability
A
1 hr
Test Coverage
import { without } from 'lodash';
import u from 'unist-builder';
import mdastDefinitions from 'mdast-util-definitions';

/**
 * Raw markdown may contain image references or link references. Because there
 * is no way to maintain these references within the Slate AST, we convert image
 * and link references to standard images and links by putting their url's
 * inline. The definitions are then removed from the document.
 *
 * For example, the following markdown:
 *
 * ```
 * ![alpha][bravo]
 *
 * [bravo]: http://example.com/example.jpg
 * ```
 *
 * Yields:
 *
 * ```
 * ![alpha](http://example.com/example.jpg)
 * ```
 *
 */
export default function remarkSquashReferences() {
  return getTransform;

  function getTransform(node) {
    const getDefinition = mdastDefinitions(node);
    return transform.call(null, getDefinition, node);
  }

  function transform(getDefinition, node) {

    /**
     * Bind the `getDefinition` function to `transform` and recursively map all
     * nodes.
     */
    const boundTransform = transform.bind(null, getDefinition);
    const children = node.children ? node.children.map(boundTransform) : node.children;

    /**
     * Combine reference and definition nodes into standard image and link
     * nodes.
     */
    if (['imageReference', 'linkReference'].includes(node.type)) {
      const type = node.type === 'imageReference' ? 'image' : 'link';
      const { title, url } = getDefinition(node.identifier) || {};
      return u(type, { title, url, alt: node.alt }, children);
    }

    /**
     * Remove definition nodes and filter the resulting null values from the
     * filtered children array.
     */
    if(node.type === 'definition') {
      return null;
    }

    const filteredChildren = without(children, null);

    return { ...node, children: filteredChildren };
  }
}