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)

236 lines 10.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.splitInlineListEnv = exports.finalizeListItems = exports.ItemsAddToPrev = exports.ItemsListPush = exports.ListItems = exports.ListItemsBlock = void 0; var tslib_1 = require("tslib"); var latex_list_tokens_1 = require("./latex-list-tokens"); var helper_1 = require("../md-block-rule/helper"); var consts_1 = require("../common/consts"); /** * Processes block-style LaTeX list items by parsing their content * using the block parser. This is used for items whose content * contains block environments (e.g., \begin{table}, \begin{figure}, etc.). * * @param state - Markdown-It processing state * @param items - Array of parsed list items */ var ListItemsBlock = function (state, items) { var e_1, _a; var _b; if (!items || items.length === 0) { return; } try { for (var items_1 = tslib_1.__values(items), items_1_1 = items_1.next(); !items_1_1.done; items_1_1 = items_1.next()) { var item = items_1_1.value; var rawContent = (_b = item === null || item === void 0 ? void 0 : item.content) !== null && _b !== void 0 ? _b : ''; var itemContent = rawContent.trim(); (0, helper_1.SetTokensBlockParse)(state, itemContent, { startLine: item.startLine, endLine: item.endLine + 1, disableBlockRules: true }); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (items_1_1 && !items_1_1.done && (_a = items_1.return)) _a.call(items_1); } finally { if (e_1) throw e_1.error; } } }; exports.ListItemsBlock = ListItemsBlock; /** * Processes LaTeX list items and generates Markdown-It tokens * for both inline content and nested list structures. * * @param state - Markdown-It list processing state * @param items - Parsed list items from LaTeX environment * @param itemizeLevelTokens - Current itemize nesting level * @param enumerateLevelTypes - Current enumerate nesting level * @param li - Optional starting value for enumerate items * @param iOpen - Current count of open list environments * @param itemizeLevelContents - Itemize content depth level * * @returns {ListItemsResult} Updated open-list count and computed padding */ var ListItems = function (state, items, itemizeLevelTokens, enumerateLevelTypes, li, iOpen, itemizeLevelContents) { var e_2, _a, e_3, _b; var _c, _d; var padding = 0; if (!items || items.length === 0) { return { iOpen: iOpen, padding: padding }; } try { for (var items_2 = tslib_1.__values(items), items_2_1 = items_2.next(); !items_2_1.done; items_2_1 = items_2.next()) { var listItem = items_2_1.value; state.env.parentType = state.parentType; state.env.isBlock = true; state.env.prentLevel = state.prentLevel; state.env.inheritedListType = state.parentType; listItem.content = listItem.content.trim(); // Detect block-level item content if (consts_1.LATEX_BLOCK_ENV_OPEN_RE.test(listItem.content) || (listItem.content.indexOf('`') > -1)) { var match = listItem.content.match(consts_1.LATEX_ITEM_COMMAND_RE); if (match) { (0, latex_list_tokens_1.setTokenListItemOpenBlock)(state, listItem.startLine, listItem.endLine + 1, match[1], li, itemizeLevelTokens, enumerateLevelTypes, itemizeLevelContents); if (li && li.hasOwnProperty('value')) { li = null; } var rawContent = (_d = (_c = listItem === null || listItem === void 0 ? void 0 : listItem.content) === null || _c === void 0 ? void 0 : _c.slice(match.index + match[0].length)) !== null && _d !== void 0 ? _d : ''; var blockContent = rawContent.trim(); (0, helper_1.SetTokensBlockParse)(state, blockContent, { disableBlockRules: true }); continue; } } // Parse inline children var inlineChildren = []; state.md.inline.parse(listItem.content.trim(), state.md, state.env, inlineChildren); // Context shared across child token processing var ctx = { li: li, padding: padding, iOpen: iOpen, itemizeLevelTokens: itemizeLevelTokens, enumerateLevelTypes: enumerateLevelTypes, itemizeLevelContents: itemizeLevelContents }; try { // Process each inline child token for (var inlineChildren_1 = (e_3 = void 0, tslib_1.__values(inlineChildren)), inlineChildren_1_1 = inlineChildren_1.next(); !inlineChildren_1_1.done; inlineChildren_1_1 = inlineChildren_1.next()) { var child = inlineChildren_1_1.value; (0, latex_list_tokens_1.processListChildToken)(state, listItem, child, ctx); } } catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (inlineChildren_1_1 && !inlineChildren_1_1.done && (_b = inlineChildren_1.return)) _b.call(inlineChildren_1); } finally { if (e_3) throw e_3.error; } } // Update context after processing children li = ctx.li; padding = ctx.padding; iOpen = ctx.iOpen; state.env.isBlock = false; } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (items_2_1 && !items_2_1.done && (_a = items_2.return)) _a.call(items_2); } finally { if (e_2) throw e_2.error; } } return { iOpen: iOpen, padding: padding }; }; exports.ListItems = ListItems; /** * Splits a line of LaTeX list content into logical items based on `\item` * and appends them to the given `items` array. * * Special handling: * - If `\item` appears in the middle of the line and both the prefix and * suffix contain backticks, the whole line is treated as a continuation * of the previous item. * - Otherwise, text before `\item` is appended to the previous item * (if any), and the rest is processed recursively as a new item segment. * * The function mutates and also returns the `items` array for convenience. * * @param items - Accumulator of parsed list items * @param content - Current line content * @param startLine - Line number where this piece starts * @param endLine - Line number where this piece ends * @returns The updated array of parsed list items */ var ItemsListPush = function (items, content, startLine, endLine) { var index = content.indexOf('\\item'); // No "\item" in the line or at the very start: treat whole line as one chunk if (index <= 0) { items.push({ content: content, startLine: startLine, endLine: endLine }); return items; } var before = content.slice(0, index); var after = content.slice(index); var hasBacktickBefore = before.includes("`"); var hasBacktickAfter = after.includes("`"); // Case 1: both parts contain backticks → treat as continuation of previous item if (hasBacktickBefore && hasBacktickAfter) { if (items.length > 0) { var lastIndex = items.length - 1; items[lastIndex].content += "\n" + content; items[lastIndex].endLine += 1; } else { items.push({ content: content, startLine: startLine, endLine: endLine }); } return items; } // Case 2: normal case with "\item" in the middle if (items.length > 0) { // Append prefix to previous item var lastIndex = items.length - 1; items[lastIndex].content += "\n" + before; items[lastIndex].endLine += 1; } else if (before.trim().length > 0) { // No previous items: keep prefix as a separate item items.push({ content: before, startLine: startLine, endLine: endLine }); } // Recursively process the remaining part starting from "\item" return (0, exports.ItemsListPush)(items, after, startLine, endLine); }; exports.ItemsListPush = ItemsListPush; /** * Appends the given line to the previous parsed list item if it exists, * or creates a new list item from the line if the list is empty and * the line is not an inline list environment closing command. * * This is used to merge continuation lines into the last list item. * * @param items - Accumulated list of parsed items * @param lineText - Current line text to append or add as a new item * @param nextLine - Line number of the current line * @returns The updated list of parsed items */ var ItemsAddToPrev = function (items, lineText, nextLine) { if (items.length > 0) { var lastIndex = items.length - 1; items[lastIndex].content += "\n" + lineText; items[lastIndex].endLine = nextLine; return items; } // No previous items: optionally create a new item, // but skip pure inline end-of-list commands. if (!consts_1.END_LIST_ENV_INLINE_RE.test(lineText)) { (0, exports.ItemsListPush)(items, lineText, nextLine, nextLine); } return items; }; exports.ItemsAddToPrev = ItemsAddToPrev; var finalizeListItems = function (state, items, itemizeLevelTokens, enumerateLevelTypes, li, iOpen, itemizeLevelContents, tokenStart) { var dataItems = (0, exports.ListItems)(state, items, itemizeLevelTokens, enumerateLevelTypes, li, iOpen, itemizeLevelContents); if (tokenStart) { var p = tokenStart; if (!p.padding || p.padding < dataItems.padding) { p.padding = dataItems.padding; if (p.padding > 3) { p.attrSet("data-padding-inline-start", String(dataItems.padding * 14)); } } } return { iOpen: dataItems.iOpen, items: [], li: null, }; }; exports.finalizeListItems = finalizeListItems; var splitInlineListEnv = function (lineText, match) { var sB = match.index > 0 ? lineText.slice(0, match.index).trim() : ""; var sE = match.index + match[0].length < lineText.length ? lineText.slice(match.index + match[0].length).trim() : ""; var isBacktickEscapedPair = sB.includes("`") && sE.includes("`"); return { sB: sB, sE: sE, isBacktickEscapedPair: isBacktickEscapedPair }; }; exports.splitInlineListEnv = splitInlineListEnv; //# sourceMappingURL=latex-list-items.js.map