All checks were successful
Publish To Prod / deploy_and_publish (push) Successful in 35s
233 lines
8.3 KiB
JavaScript
233 lines
8.3 KiB
JavaScript
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.htmlToSlate = htmlToSlate;
|
|
exports.markdownToHtml = markdownToHtml;
|
|
exports.markdownToRemark = markdownToRemark;
|
|
exports.markdownToSlate = markdownToSlate;
|
|
exports.remarkToMarkdown = remarkToMarkdown;
|
|
exports.slateToMarkdown = slateToMarkdown;
|
|
var _trimEnd2 = _interopRequireDefault(require("lodash/trimEnd"));
|
|
var _unified = _interopRequireDefault(require("unified"));
|
|
var _unistBuilder = _interopRequireDefault(require("unist-builder"));
|
|
var _remarkParse = _interopRequireDefault(require("remark-parse"));
|
|
var _remarkStringify = _interopRequireDefault(require("remark-stringify"));
|
|
var _remarkRehype = _interopRequireDefault(require("remark-rehype"));
|
|
var _rehypeStringify = _interopRequireDefault(require("rehype-stringify"));
|
|
var _rehypeParse = _interopRequireDefault(require("rehype-parse"));
|
|
var _rehypeRemark = _interopRequireDefault(require("rehype-remark"));
|
|
var _remarkRehypeShortcodes = _interopRequireDefault(require("./remarkRehypeShortcodes"));
|
|
var _rehypePaperEmoji = _interopRequireDefault(require("./rehypePaperEmoji"));
|
|
var _remarkAssertParents = _interopRequireDefault(require("./remarkAssertParents"));
|
|
var _remarkPaddedLinks = _interopRequireDefault(require("./remarkPaddedLinks"));
|
|
var _remarkWrapHtml = _interopRequireDefault(require("./remarkWrapHtml"));
|
|
var _remarkSlate = _interopRequireDefault(require("./remarkSlate"));
|
|
var _remarkSquashReferences = _interopRequireDefault(require("./remarkSquashReferences"));
|
|
var _remarkShortcodes = require("./remarkShortcodes");
|
|
var _remarkEscapeMarkdownEntities = _interopRequireDefault(require("./remarkEscapeMarkdownEntities"));
|
|
var _remarkStripTrailingBreaks = _interopRequireDefault(require("./remarkStripTrailingBreaks"));
|
|
var _remarkAllowHtmlEntities = _interopRequireDefault(require("./remarkAllowHtmlEntities"));
|
|
var _slateRemark = _interopRequireDefault(require("./slateRemark"));
|
|
var _MarkdownControl = require("../MarkdownControl");
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
/**
|
|
* This module contains all serializers for the Markdown widget.
|
|
*
|
|
* The value of a Markdown widget is transformed to various formats during
|
|
* editing, and these formats are referenced throughout serializer source
|
|
* documentation. Below is brief glossary of the formats used.
|
|
*
|
|
* - Markdown {string}
|
|
* The stringified Markdown value. The value of the field is persisted
|
|
* (stored) in this format, and the stringified value is also used when the
|
|
* editor is in "raw" Markdown mode.
|
|
*
|
|
* - MDAST {object}
|
|
* Also loosely referred to as "Remark". MDAST stands for MarkDown AST
|
|
* (Abstract Syntax Tree), and is an object representation of a Markdown
|
|
* document. Underneath, it's a Unist tree with a Markdown-specific schema.
|
|
* MDAST syntax is a part of the Unified ecosystem, and powers the Remark
|
|
* processor, so Remark plugins may be used.
|
|
*
|
|
* - HAST {object}
|
|
* Also loosely referred to as "Rehype". HAST, similar to MDAST, is an object
|
|
* representation of an HTML document. The field value takes this format
|
|
* temporarily before the document is stringified to HTML.
|
|
*
|
|
* - HTML {string}
|
|
* The field value is stringified to HTML for preview purposes - the HTML value
|
|
* is never parsed, it is output only.
|
|
*
|
|
* - Slate Raw AST {object}
|
|
* Slate's Raw AST is a very simple and unopinionated object representation of
|
|
* a document in a Slate editor. We define our own Markdown-specific schema
|
|
* for serialization to/from Slate's Raw AST and MDAST.
|
|
*/
|
|
|
|
/**
|
|
* Deserialize a Markdown string to an MDAST.
|
|
*/
|
|
function markdownToRemark(markdown, remarkPlugins) {
|
|
const processor = (0, _unified.default)().use(_remarkParse.default, {
|
|
fences: true,
|
|
commonmark: true
|
|
}).use(markdownToRemarkRemoveTokenizers, {
|
|
inlineTokenizers: ['url']
|
|
}).use(_remarkShortcodes.remarkParseShortcodes, {
|
|
plugins: (0, _MarkdownControl.getEditorComponents)()
|
|
}).use(_remarkAllowHtmlEntities.default).use(_remarkSquashReferences.default).use(remarkPlugins);
|
|
|
|
/**
|
|
* Parse the Markdown string input to an MDAST.
|
|
*/
|
|
const parsed = processor.parse(markdown);
|
|
|
|
/**
|
|
* Further transform the MDAST with plugins.
|
|
*/
|
|
const result = processor.runSync(parsed);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Remove named tokenizers from the parser, effectively deactivating them.
|
|
*/
|
|
function markdownToRemarkRemoveTokenizers({
|
|
inlineTokenizers
|
|
}) {
|
|
inlineTokenizers && inlineTokenizers.forEach(tokenizer => {
|
|
delete this.Parser.prototype.inlineTokenizers[tokenizer];
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Serialize an MDAST to a Markdown string.
|
|
*/
|
|
function remarkToMarkdown(obj, remarkPlugins) {
|
|
/**
|
|
* Rewrite the remark-stringify text visitor to simply return the text value,
|
|
* without encoding or escaping any characters. This means we're completely
|
|
* trusting the markdown that we receive.
|
|
*/
|
|
function remarkAllowAllText() {
|
|
const Compiler = this.Compiler;
|
|
const visitors = Compiler.prototype.visitors;
|
|
visitors.text = node => node.value;
|
|
}
|
|
|
|
/**
|
|
* Provide an empty MDAST if no value is provided.
|
|
*/
|
|
const mdast = obj || (0, _unistBuilder.default)('root', [(0, _unistBuilder.default)('paragraph', [(0, _unistBuilder.default)('text', '')])]);
|
|
const remarkToMarkdownPluginOpts = {
|
|
commonmark: true,
|
|
fences: true,
|
|
listItemIndent: '1',
|
|
/**
|
|
* Use asterisk for everything, it's the most versatile. Eventually using
|
|
* other characters should be an option.
|
|
*/
|
|
bullet: '*',
|
|
emphasis: '*',
|
|
strong: '*',
|
|
rule: '-'
|
|
};
|
|
const processor = (0, _unified.default)().use({
|
|
settings: remarkToMarkdownPluginOpts
|
|
}).use(_remarkEscapeMarkdownEntities.default).use(_remarkStripTrailingBreaks.default).use(_remarkStringify.default).use(remarkAllowAllText).use((0, _remarkShortcodes.createRemarkShortcodeStringifier)({
|
|
plugins: (0, _MarkdownControl.getEditorComponents)()
|
|
})).use(remarkPlugins);
|
|
|
|
/**
|
|
* Transform the MDAST with plugins.
|
|
*/
|
|
const processedMdast = processor.runSync(mdast);
|
|
|
|
/**
|
|
* Serialize the MDAST to markdown.
|
|
*/
|
|
const markdown = processor.stringify(processedMdast).replace(/\r?/g, '');
|
|
|
|
/**
|
|
* Return markdown with trailing whitespace removed.
|
|
*/
|
|
return (0, _trimEnd2.default)(markdown);
|
|
}
|
|
|
|
/**
|
|
* Convert Markdown to HTML.
|
|
*/
|
|
function markdownToHtml(markdown, {
|
|
getAsset,
|
|
resolveWidget,
|
|
remarkPlugins = []
|
|
} = {}) {
|
|
const mdast = markdownToRemark(markdown, remarkPlugins);
|
|
const hast = (0, _unified.default)().use(_remarkRehypeShortcodes.default, {
|
|
plugins: (0, _MarkdownControl.getEditorComponents)(),
|
|
getAsset,
|
|
resolveWidget
|
|
}).use(_remarkRehype.default, {
|
|
allowDangerousHTML: true
|
|
}).runSync(mdast);
|
|
const html = (0, _unified.default)().use(_rehypeStringify.default, {
|
|
allowDangerousHtml: true,
|
|
allowDangerousCharacters: true,
|
|
closeSelfClosing: true,
|
|
entities: {
|
|
useNamedReferences: true
|
|
}
|
|
}).stringify(hast);
|
|
return html;
|
|
}
|
|
|
|
/**
|
|
* Deserialize an HTML string to Slate's Raw AST. Currently used for HTML
|
|
* pastes.
|
|
*/
|
|
function htmlToSlate(html) {
|
|
const hast = (0, _unified.default)().use(_rehypeParse.default, {
|
|
fragment: true
|
|
}).parse(html);
|
|
const mdast = (0, _unified.default)().use(_rehypePaperEmoji.default).use(_rehypeRemark.default, {
|
|
minify: false
|
|
}).runSync(hast);
|
|
const slateRaw = (0, _unified.default)().use(_remarkAssertParents.default).use(_remarkPaddedLinks.default).use(_remarkWrapHtml.default).use(_remarkSlate.default).runSync(mdast);
|
|
return slateRaw;
|
|
}
|
|
|
|
/**
|
|
* Convert Markdown to Slate's Raw AST.
|
|
*/
|
|
function markdownToSlate(markdown, {
|
|
voidCodeBlock,
|
|
remarkPlugins = []
|
|
} = {}) {
|
|
const mdast = markdownToRemark(markdown, remarkPlugins);
|
|
const slateRaw = (0, _unified.default)().use(_remarkWrapHtml.default).use(_remarkSlate.default, {
|
|
voidCodeBlock
|
|
}).runSync(mdast);
|
|
return slateRaw.children;
|
|
}
|
|
|
|
/**
|
|
* Convert a Slate Raw AST to Markdown.
|
|
*
|
|
* Requires shortcode plugins to parse shortcode nodes back to text.
|
|
*
|
|
* Note that Unified is not utilized for the conversion from Slate's Raw AST to
|
|
* MDAST. The conversion is manual because Unified can only operate on Unist
|
|
* trees.
|
|
*/
|
|
function slateToMarkdown(raw, {
|
|
voidCodeBlock,
|
|
remarkPlugins = []
|
|
} = {}) {
|
|
const mdast = (0, _slateRemark.default)(raw, {
|
|
voidCodeBlock
|
|
});
|
|
const markdown = remarkToMarkdown(mdast, remarkPlugins);
|
|
return markdown;
|
|
} |