{"version":3,"file":"enumerate-DJ7Sv0R9.cjs","names":[],"sources":["../utils/enumerate.ts"],"sourcesContent":["import { arg } from \"@unified-latex/unified-latex-builder\";\nimport * as Ast from \"@unified-latex/unified-latex-types\";\nimport { match } from \"@unified-latex/unified-latex-util-match\";\nimport { printRaw } from \"@unified-latex/unified-latex-util-print-raw\";\nimport { updateRenderInfo } from \"@unified-latex/unified-latex-util-render-info\";\nimport {\n    lastSignificantNode,\n    lastSignificantNodeIndex,\n} from \"@unified-latex/unified-latex-util-replace\";\nimport { splitOnMacro } from \"@unified-latex/unified-latex-util-split\";\nimport { trim, trimEnd } from \"@unified-latex/unified-latex-util-trim\";\n\n/**\n * Clean up any whitespace issues in an enumerate environment. In particular,\n *      * Remove any leading or ending whitespace\n *      * Ensure there is a par between occurrences of `\\item`\n *      * Ensure there is whitespace after each occurrence of `\\item` provided there is content there\n * `itemName` can be used to set what the \"item\" macro is called.\n *\n * This function attaches content following a `\\item` to the `\\item` macro with\n * `openMark` and `closeMark` set to empty. This allows hanging-indents to be rendered.\n */\nexport function cleanEnumerateBody(\n    ast: Ast.Node[],\n    itemName = \"item\"\n): Ast.Node[] {\n    let { segments, macros } = splitOnMacro(ast, itemName);\n    // Trim the content of each block, but make sure there is a space\n    // between each macro and the content. Since the first segment of content\n    // appears *before* any macro, don't add a space there.\n    for (let i = 0; i < segments.length; i++) {\n        const segment = segments[i];\n        if (i === 0) {\n            // The very first segment might be comment with leading whitespace. We don't want to trim that off\n            trimEnd(segment);\n        } else {\n            trim(segment);\n        }\n        // The very first segment comes before any `\\item` macros. It is either\n        // blank or contains comments (or is invalid LaTeX). We don't insert a space\n        // in this case.\n        if (segment.length > 0 && i > 0) {\n            segment.unshift({ type: \"whitespace\" });\n        }\n    }\n\n    let insertParbreakBefore: WeakSet<Ast.Node> = new WeakSet();\n\n    // We want a trailing indent for the `\\item` nodes. We will\n    // do this with a trick: we will add an argument to the index node\n    // with openMark=\" \" and closeMark=\"\"\n    let body: Ast.Node[] = macros.flatMap((node, i) => {\n        const segment = segments[i + 1];\n        const trailingComments = popTrailingComments(segment);\n        node.args = node.args || [];\n        node.args.push(arg(segment, { openMark: \"\", closeMark: \"\" }));\n        updateRenderInfo(node, { inParMode: true });\n\n        // The stream contains a mix of `\\item` macros and comments/parbreaks. We only\n        // want to insert parbreaks before `\\item` macros, so we record these for later.\n        if (i > 0 || segments[0]?.length > 0) {\n            insertParbreakBefore.add(node);\n        }\n\n        return [node, ...trailingComments];\n    });\n\n    // We want a parbreak between each `\\item` block and the preceding content.\n    // We've already logged the `\\item` macros in `insertParbreakBefore`.\n    body = body.flatMap((node) =>\n        insertParbreakBefore.has(node) ? [{ type: \"parbreak\" }, node] : node\n    );\n\n    body.unshift(...segments[0]);\n\n    // We have inserted parbreaks so some comments need to be told that there is a suffix parbreak\n    for (let i = 0; i < body.length - 1; i++) {\n        const node = body[i];\n        const nextNode = body[i + 1];\n        if (!match.parbreak(nextNode)) {\n            continue;\n        }\n        if (match.comment(node)) {\n            node.suffixParbreak = true;\n        }\n        // The heuristic for detecting an `item`-like node is that its last argument has no close mark.\n        // Regardless of what it is, if there is no close mark, when rendered we don't want two newlines to\n        // appear.\n        if (\n            match.macro(node) &&\n            node.args &&\n            node.args[node.args.length - 1].closeMark === \"\"\n        ) {\n            const args = node.args[node.args.length - 1].content;\n            const lastArg = args[args.length - 1];\n            if (match.comment(lastArg)) {\n                lastArg.suffixParbreak = true;\n            }\n        }\n    }\n\n    return body;\n}\n\n/**\n * Removes and returns any number of trailing comments/parbreaks from `nodes`.\n */\nfunction popTrailingComments(nodes: Ast.Node[]): Ast.Node[] {\n    let lastNodeIndex = lastSignificantNodeIndex(nodes, true);\n    if (\n        lastNodeIndex === nodes.length - 1 ||\n        (lastNodeIndex == null && nodes.length === 0)\n    ) {\n        return [];\n    }\n\n    // If `nodes` has a non-zero length and we didn't find a significant node, everything is comments!\n    if (lastNodeIndex == null) {\n        lastNodeIndex = -1;\n    }\n    return nodes.splice(lastNodeIndex + 1);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAsBA,SAAgB,mBACZ,KACA,WAAW,QACD;CACV,IAAI,EAAE,UAAU,YAAA,GAAA,wCAAA,cAAwB,KAAK,SAAS;AAItD,MAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;EACtC,MAAM,UAAU,SAAS;AACzB,MAAI,MAAM,EAEN,EAAA,GAAA,uCAAA,SAAQ,QAAQ;MAEhB,EAAA,GAAA,uCAAA,MAAK,QAAQ;AAKjB,MAAI,QAAQ,SAAS,KAAK,IAAI,EAC1B,SAAQ,QAAQ,EAAE,MAAM,cAAc,CAAC;;CAI/C,IAAI,uCAA0C,IAAI,SAAS;CAK3D,IAAI,OAAmB,OAAO,SAAS,MAAM,MAAM;EAC/C,MAAM,UAAU,SAAS,IAAI;EAC7B,MAAM,mBAAmB,oBAAoB,QAAQ;AACrD,OAAK,OAAO,KAAK,QAAQ,EAAE;AAC3B,OAAK,KAAK,MAAA,GAAA,qCAAA,KAAS,SAAS;GAAE,UAAU;GAAI,WAAW;GAAI,CAAC,CAAC;AAC7D,GAAA,GAAA,8CAAA,kBAAiB,MAAM,EAAE,WAAW,MAAM,CAAC;AAI3C,MAAI,IAAI,KAAK,SAAS,IAAI,SAAS,EAC/B,sBAAqB,IAAI,KAAK;AAGlC,SAAO,CAAC,MAAM,GAAG,iBAAiB;GACpC;AAIF,QAAO,KAAK,SAAS,SACjB,qBAAqB,IAAI,KAAK,GAAG,CAAC,EAAE,MAAM,YAAY,EAAE,KAAK,GAAG,KACnE;AAED,MAAK,QAAQ,GAAG,SAAS,GAAG;AAG5B,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,SAAS,GAAG,KAAK;EACtC,MAAM,OAAO,KAAK;EAClB,MAAM,WAAW,KAAK,IAAI;AAC1B,MAAI,CAAC,wCAAA,MAAM,SAAS,SAAS,CACzB;AAEJ,MAAI,wCAAA,MAAM,QAAQ,KAAK,CACnB,MAAK,iBAAiB;AAK1B,MACI,wCAAA,MAAM,MAAM,KAAK,IACjB,KAAK,QACL,KAAK,KAAK,KAAK,KAAK,SAAS,GAAG,cAAc,IAChD;GACE,MAAM,OAAO,KAAK,KAAK,KAAK,KAAK,SAAS,GAAG;GAC7C,MAAM,UAAU,KAAK,KAAK,SAAS;AACnC,OAAI,wCAAA,MAAM,QAAQ,QAAQ,CACtB,SAAQ,iBAAiB;;;AAKrC,QAAO;;;;;AAMX,SAAS,oBAAoB,OAA+B;CACxD,IAAI,iBAAA,GAAA,0CAAA,0BAAyC,OAAO,KAAK;AACzD,KACI,kBAAkB,MAAM,SAAS,KAChC,iBAAiB,QAAQ,MAAM,WAAW,EAE3C,QAAO,EAAE;AAIb,KAAI,iBAAiB,KACjB,iBAAgB;AAEpB,QAAO,MAAM,OAAO,gBAAgB,EAAE"}