UNPKG

feeles-ide

Version:

The hackable and serializable IDE to make learning material

203 lines (174 loc) 6.78 kB
import _extends from 'babel-runtime/helpers/extends'; import _toConsumableArray from 'babel-runtime/helpers/toConsumableArray'; import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties'; // Copied from https://github.com/endaaman/markdown-react-js import markdown from 'markdown-it'; // import React, { PropTypes } from 'react' import React from 'react'; import PropTypes from 'prop-types'; // import isPlainObject from 'lodash/isPlainObject' // import assign from 'lodash/assign' // import reduce from 'lodash/reduce' // import zipObject from 'lodash/zipObject' // import sortBy from 'lodash/sortBy' // import compact from 'lodash/compact' // import camelCase from 'lodash/camelCase' // import isString from 'lodash/isString' // import fromPairs from 'lodash/fromPairs' import { isPlainObject, assign, reduce, zipObject, sortBy, compact, camelCase, isString, fromPairs } from 'lodash'; var DEFAULT_TAGS = { html: 'span' }; var DEFAULT_RULES = { image: function image(token, attrs, children) { if (children.length) { attrs = assign({}, attrs, { alt: children[0] }); } return [[token.tag, attrs]]; }, codeInline: function codeInline(token, attrs) { return [compact([token.tag, attrs, token.content])]; }, codeBlock: function codeBlock(token, attrs) { return [['pre', compact([token.tag, attrs, token.content])]]; }, fence: function fence(token, attrs) { if (token.info) { var langName = token.info.trim().split(/\s+/g)[0]; attrs = assign({}, attrs, { 'data-language': langName }); } return [['pre', compact([token.tag, attrs, token.content])]]; }, hardbreak: function hardbreak() { return [['br']]; }, softbreak: function softbreak(token, attrs, children, options) { return options.breaks ? [['br']] : '\n'; }, text: function text(token) { return token.content; }, htmlBlock: function htmlBlock(token) { return token.content; }, htmlInline: function htmlInline(token) { return token.content; }, inline: function inline(token, attrs, children) { return children; }, default: function _default(token, attrs, children, options, getNext) { if (token.nesting === 1 && token.hidden) { return getNext(); } /* plugin-related */ if (!token.tag) { return token.content; } if (token.info) { attrs = assign({}, attrs, { 'data-info': token.info.trim() }); } /* plugin-related */ return [compact([token.tag, attrs].concat(token.nesting === 1 && getNext()))]; } }; function convertTree(tokens, convertRules, options) { function convertBranch(tkns, nested) { var branch = []; if (!nested) { branch.push('html'); } function getNext() { return convertBranch(tkns, true); } var token = tkns.shift(); while (token && token.nesting !== -1) { var attrs = token.attrs && fromPairs(sortBy(token.attrs, 0)); var children = token.children && convertBranch(token.children.slice(), true); var rule = convertRules[camelCase(token.type)] || convertRules.default; branch = branch.concat(rule(token, attrs, children, options, getNext)); token = tkns.shift(); } return branch; } return convertBranch(tokens, false); } function mdReactFactory() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var onIterate = options.onIterate, _options$tags = options.tags, tags = _options$tags === undefined ? DEFAULT_TAGS : _options$tags, presetName = options.presetName, markdownOptions = options.markdownOptions, _options$enableRules = options.enableRules, enableRules = _options$enableRules === undefined ? [] : _options$enableRules, _options$disableRules = options.disableRules, disableRules = _options$disableRules === undefined ? [] : _options$disableRules, _options$plugins = options.plugins, plugins = _options$plugins === undefined ? [] : _options$plugins, _options$onGenerateKe = options.onGenerateKey, onGenerateKey = _options$onGenerateKe === undefined ? function (tag, index) { return 'mdrct-' + tag + '-' + index; } : _options$onGenerateKe, rootElementProps = _objectWithoutProperties(options, ['onIterate', 'tags', 'presetName', 'markdownOptions', 'enableRules', 'disableRules', 'plugins', 'onGenerateKey']); var md = markdown(markdownOptions || presetName).enable(enableRules).disable(disableRules); var convertRules = assign({}, DEFAULT_RULES, options.convertRules); md = reduce(plugins, function (m, plugin) { return plugin.plugin ? m.use.apply(m, [plugin.plugin].concat(_toConsumableArray(plugin.args))) : m.use(plugin); }, md); function renderChildren(tag) { return ['img', 'hr', 'br'].indexOf(tag) < 0; } function iterateTree(tree) { var level = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; var tag = tree.shift(); var key = onGenerateKey(tag, index); var props = tree.length && isPlainObject(tree[0]) ? assign(tree.shift(), { key: key }) : { key: key }; if (level === 0) { props = _extends({}, props, rootElementProps); } var children = tree.map(function (branch, idx) { return Array.isArray(branch) ? iterateTree(branch, level + 1, idx) : branch; }); tag = tags[tag] || tag; if (isString(props.style)) { props.style = zipObject(props.style.split(';').map(function (prop) { return prop.split(':'); }).map(function (keyVal) { return [camelCase(keyVal[0].trim()), keyVal[1].trim()]; })); } if (typeof onIterate === 'function') { var element = onIterate(tag, props, children, level); if (element) { return element; } } return React.createElement(tag, props, renderChildren(tag) ? children : undefined); } return function (text) { var tree = convertTree(md.parse(text, {}), convertRules, md.options); return iterateTree(tree); }; } var MDReactComponent = function MDReactComponent(props) { var text = props.text, propsWithoutText = _objectWithoutProperties(props, ['text']); return mdReactFactory(propsWithoutText)(text); }; MDReactComponent.propTypes = { text: PropTypes.string.isRequired, onIterate: PropTypes.func, onGenerateKey: PropTypes.func, tags: PropTypes.object, presetName: PropTypes.string, markdownOptions: PropTypes.object, enableRules: PropTypes.array, disableRules: PropTypes.array, convertRules: PropTypes.object, plugins: PropTypes.array, className: PropTypes.string }; export default MDReactComponent; export { mdReactFactory as mdReact };