UNPKG

mathpix-markdown-it

Version:

Mathpix-markdown-it is an open source implementation of the mathpix-markdown spec written in Typescript. It relies on the following open source libraries: MathJax v3 (to render math with SVGs), markdown-it (for standard Markdown parsing)

212 lines 9.81 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseBlockIntoTokenChildren = exports.SetTokensBlockParse = void 0; var tslib_1 = require("tslib"); // Matches leading markdown block markers on the first line: // - up to 3 spaces + "#" heading // - or one/many ">" blockquote markers with arbitrary spaces between // - or fenced code block (```... or ~~~...) var MD_BLOCK_LEADING_RE = /^(\s{0,3})(#{1,6}(?=\s|$)|>[\s>]*|(`{3,}|~{3,})[^\n]*)/; var defaultRulesToDisable = ['list']; /** * If the first line looks like a markdown block (heading, quote, fence), * escape the first block marker character (prepend "\") so markdown-it's * block rules do not trigger on it. Used only inside SetTokensBlockParse. */ var escapeLeadingMarkdownBlockLine = function (content) { var _a; var lines = content.split('\n'); if (lines.length === 0) return content; var first = lines[0]; var m = first.match(MD_BLOCK_LEADING_RE); if (!m) { return content; } var indent = (_a = m[1]) !== null && _a !== void 0 ? _a : ''; // leading spaces (0–3) var rest = first.slice(indent.length); // starts with '#', '>', ``` or ~~~ if (!rest.length) { return content; } // Escape the very first marker character: // "# ..." -> "\# ..." // "> > > foo" -> "\> > > foo" // "```code" -> "\```code" // "~~~code" -> "\~~~code" var escapedRest = '\\' + rest[0] + rest.slice(1); lines[0] = indent + escapedRest; return lines.join('\n'); }; /** * Parses a block of content with markdown-it and pushes the resulting * block tokens into the current state, with optional control over * line mapping, inline rendering, PPTX-specific behavior and temporary * disabling of selected block rules (list/blockquote/fence/heading). */ var SetTokensBlockParse = function (state, content, options) { var e_1, _a; if (options === void 0) { options = {}; } var startLine = options.startLine, endLine = options.endLine, _b = options.isInline, isInline = _b === void 0 ? false : _b, _c = options.contentPositions, contentPositions = _c === void 0 ? null : _c, _d = options.forPptx, forPptx = _d === void 0 ? false : _d, _e = options.disableBlockRules, disableBlockRules = _e === void 0 ? false : _e; var children = []; var envIsInline = !!state.env.isInline; var envSubTabular = !!state.env.subTabular; var envInheritedListType = state.env.inheritedListType; state.env.isInline = disableBlockRules; // When block rules are disabled, neutralize leading markdown block markers // on the first line so markdown-it does not treat them as real block syntax. var safeContent = disableBlockRules ? escapeLeadingMarkdownBlockLine(content) : content; if (disableBlockRules) { var blockRuler = state.md.block.ruler; // 1. Let's remember which of these rules were included var rulesToReEnable = []; if (blockRuler.__rules__) { var _loop_1 = function (name_1) { var rule = blockRuler.__rules__.find(function (r) { return r.name === name_1; }); if (rule && rule.enabled) { rulesToReEnable.push(name_1); } }; try { for (var defaultRulesToDisable_1 = tslib_1.__values(defaultRulesToDisable), defaultRulesToDisable_1_1 = defaultRulesToDisable_1.next(); !defaultRulesToDisable_1_1.done; defaultRulesToDisable_1_1 = defaultRulesToDisable_1.next()) { var name_1 = defaultRulesToDisable_1_1.value; _loop_1(name_1); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (defaultRulesToDisable_1_1 && !defaultRulesToDisable_1_1.done && (_a = defaultRulesToDisable_1.return)) _a.call(defaultRulesToDisable_1); } finally { if (e_1) throw e_1.error; } } } // 2. Temporarily disable only those that were actually enabled. blockRuler.disable(rulesToReEnable, true); try { state.md.block.parse(safeContent, state.md, state.env, children); } finally { // 3. Only restore what we turned off ourselves. blockRuler.enable(rulesToReEnable, true); } } else { state.md.block.parse(safeContent, state.md, state.env, children); } state.env.isInline = envIsInline; state.env.subTabular = envSubTabular; state.env.inheritedListType = envInheritedListType; var isFirst = true; for (var j = 0; j < children.length; j++) { var child = children[j]; // Push token to state state.tokens.push(child); var token = child; if (isInline && j === 0 && token.type === "paragraph_open") { if (token.attrs) { var style = token.attrGet('style'); if (style) { token.attrSet('style', "display: inline; " + style); } else { token.attrs.push(['style', "display: inline;"]); } } else { token.attrSet('style', "display: inline;"); } token.attrSet('data-display', 'inline'); } if (startLine && endLine) { token.map = [startLine, endLine]; } if ((contentPositions === null || contentPositions === void 0 ? void 0 : contentPositions.hasOwnProperty('startLine')) && child.map) { token.map = [contentPositions.startLine + child.map[0], contentPositions.startLine + child.map[1]]; if (j === 1 && child.type === "inline") { token.bMarks = contentPositions.bMarks; } } if (forPptx && isInline && isFirst && token.type === "paragraph_close") { state.push('paragraph_close', 'div', -1); isFirst = false; } } }; exports.SetTokensBlockParse = SetTokensBlockParse; /** * Parses a markdown fragment into block tokens and appends them to `token.children`. * Optionally disables a predefined set of markdown-it block rules (see `defaultRulesToDisable`) * and neutralizes leading block markers on the first line to prevent accidental block parsing. * @param state - markdown-it parsing state. * @param content - Markdown fragment to parse. * @param token - Target token that will receive parsed children. * @param opts - Parsing options. * @returns Parsed child tokens (also appended to `token.children`). */ var parseBlockIntoTokenChildren = function (state, content, token, opts) { var e_2, _a, _b; var _c, _d, _e; if (opts === void 0) { opts = {}; } var _f = opts.disableBlockRules, disableBlockRules = _f === void 0 ? false : _f; var children = []; var envInheritedListType = (_c = state.env) === null || _c === void 0 ? void 0 : _c.inheritedListType; // When block rules are disabled, neutralize leading markdown block markers on first line. var safeContent = disableBlockRules ? escapeLeadingMarkdownBlockLine(content) : content; if (disableBlockRules) { var blockRuler = (_e = (_d = state.md) === null || _d === void 0 ? void 0 : _d.block) === null || _e === void 0 ? void 0 : _e.ruler; // 1. Let's remember which of these rules were included var rulesToReEnable = []; try { if (blockRuler === null || blockRuler === void 0 ? void 0 : blockRuler.__rules__) { var _loop_2 = function (name_2) { var rule = blockRuler.__rules__.find(function (r) { return r.name === name_2; }); if (rule === null || rule === void 0 ? void 0 : rule.enabled) { rulesToReEnable.push(name_2); } }; try { for (var defaultRulesToDisable_2 = tslib_1.__values(defaultRulesToDisable), defaultRulesToDisable_2_1 = defaultRulesToDisable_2.next(); !defaultRulesToDisable_2_1.done; defaultRulesToDisable_2_1 = defaultRulesToDisable_2.next()) { var name_2 = defaultRulesToDisable_2_1.value; _loop_2(name_2); } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (defaultRulesToDisable_2_1 && !defaultRulesToDisable_2_1.done && (_a = defaultRulesToDisable_2.return)) _a.call(defaultRulesToDisable_2); } finally { if (e_2) throw e_2.error; } } } // 2. Temporarily disable only those that were actually enabled. if (rulesToReEnable.length) { blockRuler === null || blockRuler === void 0 ? void 0 : blockRuler.disable(rulesToReEnable, true); } state.md.block.parse(safeContent, state.md, state.env, children); } finally { if (rulesToReEnable.length) { blockRuler === null || blockRuler === void 0 ? void 0 : blockRuler.enable(rulesToReEnable, true); } } } else { state.md.block.parse(safeContent, state.md, state.env, children); } if (!token.children) { token.children = []; } if (children.length) { (_b = token.children).push.apply(_b, tslib_1.__spreadArray([], tslib_1.__read(children), false)); } if (state.env) { state.env.inheritedListType = envInheritedListType; } return children; }; exports.parseBlockIntoTokenChildren = parseBlockIntoTokenChildren; //# sourceMappingURL=helper.js.map