UNPKG

js-markdown

Version:
395 lines (313 loc) 10.4 kB
'use strict'; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _Util = _interopRequireDefault(require("./utils/Util")); var _Str = _interopRequireDefault(require("./utils/Str")); var _Header = _interopRequireDefault(require("./utils/Header")); var _syntax = _interopRequireDefault(require("./syntax")); function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } // String at method polyfill if (!String.prototype.at) { (function () { 'use strict'; String.prototype.at = _Str["default"].at; })(); } Markdown.Dialect = { DEFAULT: 'DEFAULT', DERBY: 'DERBY' }; /** * Markdown constructor * @param data * @constructor */ function Markdown() { var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; this.initData = data; this.renderTree = null; this.html = ''; this.fullInfo = !!options.fullInfo; this.dialect = options.dialect || Markdown.Dialect.DEFAULT; } /** * static method * @param data */ Markdown.parse = function (data, options) { return new Markdown(data, options).render(); }; /** -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- parse -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */ /** * traverse block types to identify line syntax * @param line * @param index * @param lines * @param renderTree * @returns {*} */ Markdown.prototype.parseBlock = function (line, index, lines, renderTree) { var result; for (var i = 0, len = _syntax["default"][this.dialect].blockTypes.length; i < len; i++) { result = _syntax["default"][_syntax["default"][this.dialect].blockTypes[i]].parse.call(this, line, index, lines, renderTree); if (!result) { continue; } return result; } return; }; /** * split markdown file to block nodes according to lines, and append to renderTree * @param lines * @param renderTree */ Markdown.prototype.parseBlocks = function (lines, renderTree) { var line, block; for (var i = 0, len = lines.length; i < len; i++) { line = lines[i]; var result = this.parseBlock(line, i, lines, renderTree); if (result) { var _result = (0, _slicedToArray2["default"])(result, 2); block = _result[0]; i = _result[1]; } else { block = { type: 'Text', rawValue: line }; } if (renderTree && renderTree.children && block) { renderTree.children.push(block); } } }; /** * match inline syntax * @param str * @param children * @returns {*} */ Markdown.prototype.matchInline = function (str, children) { var reg = /([\s\S]*?)(\\|(?:!\[)|(?:\[\^)|\[|<|`|( \n)|\*|_|\n|\s)/; var result = _Str["default"].matchUrl(str); if (result) { return [{ type: 'Anchor', rawValue: result[0] }, result[0].length]; } result = str.match(reg); if (!result) { return [{ type: 'Text', rawValue: str }, str.length]; } else if (result[1]) { return [{ type: 'Text', rawValue: result[1] }, result[1].length]; } var res; if (result[2] in _syntax["default"][this.dialect].inlineTypes) { res = _syntax["default"][_syntax["default"][this.dialect].inlineTypes[result[2]]].parse.call(this, str, children, this.renderTree); } else if (result[2] === '\n' && str === '\n') { return [{ type: 'Text', rawValue: '' }, result[2].length]; } return res || [{ type: 'Text', rawValue: result[2] }, result[2].length]; }; /** * split line to several inline nodes * @param node */ Markdown.prototype.parseInline = function (node) { if (!node.rawValue || node.type === 'BlockCode' || node.type === 'InlineCode') { return; } var children = []; var result, inline, len; while (node.rawValue.length > 0) { result = this.matchInline(node.rawValue, children); if (!result) { break; } var _result2 = result; var _result3 = (0, _slicedToArray2["default"])(_result2, 2); inline = _result3[0]; len = _result3[1]; node.rawValue = node.rawValue.slice(len); if (inline) { if (inline.type === 'Text' && children && children.length > 0 && children[children.length - 1].type === 'Text') { children[children.length - 1].rawValue += inline.rawValue; } else { children.push(inline); } } } if (children.length > 0) { if (!node.children) { node.children = []; } node.children = [].concat(children, (0, _toConsumableArray2["default"])(node.children)); } }; /** * traverse renderTree to parse inline syntax * @param renderTree */ Markdown.prototype.parseInlines = function (renderTree) { _Util["default"].postOrderTraverse.call(this, renderTree, this.parseInline); }; /** * first time format footnotes after parsed blocks */ Markdown.prototype.formatFootnotes = function () { var footnotes = this.renderTree.footnotes; var result = [], temp = {}; if (!footnotes || footnotes.length < 1) { return; } result = footnotes.filter(function (item) { return isNaN(item.key); }); var _iterator = _createForOfIteratorHelper(footnotes), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var item = _step.value; if (!isNaN(item.key)) { temp[item.key] = item; } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } var _iterator2 = _createForOfIteratorHelper(Object.keys(temp).sort()), _step2; try { for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { var index = _step2.value; result.splice(index - 1, 0, temp[index]); } } catch (err) { _iterator2.e(err); } finally { _iterator2.f(); } this.renderTree.footnotes = result; }; /** * second time format footnotes after parsed parse inline * in order to filter some footnotes not used */ Markdown.prototype.reformatFootnotes = function () { this.renderTree.footnotes = this.renderTree.footnotes.filter(function (item) { return item.activated; }); }; /** * generate the render tree from the input markdown data */ Markdown.prototype.parseTree = function () { var data = _Str["default"].formatCRLF(this.initData), lines = data.split('\n'); this.renderTree = { isRoot: true, metaData: {}, referenceDefine: {}, headerTree: _Header["default"].initRoot(), footnotes: [], children: [] }; this.parseBlocks(lines, this.renderTree); this.formatFootnotes(); this.parseInlines(this.renderTree); this.reformatFootnotes(); }; /** -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- render -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */ /** * render tree to html string * @param node * @returns {*} */ Markdown.prototype.toHTML = function () { var node = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.renderTree; var string = ''; if (node.children && node.children.length > 0) { for (var i = 0, len = node.children.length; i < len; i++) { string += this.toHTML(node.children[i]); } } if (node.type && _syntax["default"][node.type] && _syntax["default"][node.type].render) { return _syntax["default"][node.type].render(string, node, this.renderTree); } else { return node.rawValue || '' + string; } return string; }; /** * footnotes to html string * @returns {*} */ Markdown.prototype.renderFootnotes = function () { if (!this.renderTree.footnotes || this.renderTree.footnotes.length < 1) { return ''; } var footnotes = this.renderTree.footnotes.map(function (item, index) { return { type: 'FootnoteListItem', index: index, rawValue: item.rawValue }; }), node = { type: 'Footnote', children: [{ type: 'List', isOrder: true, children: footnotes }] }; this.parseInlines(node); return this.toHTML(node); }; /** * render html string for result */ Markdown.prototype.renderHTML = function () { this.html = this.toHTML(this.renderTree); this.html += this.renderFootnotes(); }; /** -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- main -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */ /** * markdown render main method * @returns {*|string} */ Markdown.prototype.render = function () { this.parseTree(); this.renderHTML(); return this.fullInfo ? { html: this.html, renderTree: this.renderTree } : this.html; }; var _default = Markdown; exports["default"] = _default;