/* @flow */
import trim from 'lodash/trim';
import Remarkable from 'remarkable';
import {htmlToArray, parseHTML, htmlToJSX} from './jsx';
const md = new Remarkable('full', {html: true, linkify: true, typographer: true});
/**
* Useful utilities for working with Markdown.
*
* @module markdown
*/
/**
* If a simple single line string is passed to the Markdown parser it thinks that it's a paragraph (it sort of
* technically is) and unnecessarily wraps it into `<p></p>`, which most often is not the desired behavior.
*
* This function converts Markdown to HTML and then removes the wrapping paragraph if it is the only top level tag
* unwrapping its contents.
*
* @memberof module:markdown
* @private
* @method markdownToUnwrappedHTML
* @param {string} markdown - an arbitrary Markdown string
* @return {string} an HTML string
*/
export function markdownToUnwrappedHTML(markdown: string): string {
const html = trim(md.render(markdown)),
{dom, children} = parseHTML(html);
if (1 !== children.length) {
return html;
}
const [child] = children,
{type, name} = child;
return 'tag' === type && 'p' === name ? dom(child).html() : html;
}
/**
* Converts an arbitrary Markdown string to an array of plain objects describing React Elements for easy
* serialization/unserialization.
*
* @memberof module:markdown
* @method markdownToArray
* @param {string} [markdown=""] - an arbitrary Markdown string
* @return {Array<string|Object>} an array of plain objects describing React Elements
* @example
* import {markdownToArray} from 'webcompiler';
* // or - import {markdownToArray} from 'webcompiler/lib/markdown';
* // or - var markdownToArray = require('webcompiler').markdownToArray;
* // or - var markdownToArray = require('webcompiler/lib/markdown').markdownToArray;
*
* markdownToArray('# Hello world!'); // [{type: 'h1', children: ['Hello world!']}]
*/
export function markdownToArray(markdown: string = ''): Array<string | Object> {
markdown = trim(markdown);
return markdown ? htmlToArray(markdownToUnwrappedHTML(markdown)) : [];
}
/**
* Converts an arbitrary Markdown string to an array of React Elements
*
* @memberof module:markdown
* @method markdownToJSX
* @param {string} [markdown=""] - an arbitrary Markdown string
* @return {Array<ReactElement>} an array of React Elements
* @example
* import {markdownToJSX} from 'webcompiler';
* // or - import {markdownToJSX} from 'webcompiler/lib/markdown';
* // or - var markdownToJSX = require('webcompiler').markdownToJSX;
* // or - var markdownToJSX = require('webcompiler/lib/markdown').markdownToJSX;
*
* <div>{markdownToJSX('# Hello world!')}</div>
*/
export function markdownToJSX(markdown: string = ''): any[] {
markdown = trim(markdown);
return markdown ? htmlToJSX(markdownToUnwrappedHTML(markdown)) : [];
}
/**
* Converts an arbitrary Markdown string to an HTML string
*
* @memberof module:markdown
* @method markdownToHTML
* @param {string} [markdown=""] - an arbitrary Markdown string
* @return {string} an HTML string
* @example
* import {markdownToHTML} from 'webcompiler';
* // or - import {markdownToHTML} from 'webcompiler/lib/markdown';
* // or - var markdownToHTML = require('webcompiler').markdownToHTML;
* // or - var markdownToHTML = require('webcompiler/lib/markdown').markdownToHTML;
*
* markdownToHTML('# Hello world!'); // <h1>Hello world!</h1>
*/
export function markdownToHTML(markdown: string = ''): string {
markdown = trim(markdown);
return markdown ? markdownToUnwrappedHTML(markdown) : '';
}