{"version":3,"file":"index.cjs","names":[],"sources":["../libs/trim.ts","../libs/unified-latex-trim-environment-contents.ts","../libs/unified-latex-trim-root.ts","../libs/has-whitespace-equivalent.ts","../index.ts"],"sourcesContent":["import * as Ast from \"@unified-latex/unified-latex-types\";\nimport { match } from \"@unified-latex/unified-latex-util-match\";\n\n/**\n * Trims whitespace and parbreaks from the start and end\n * of an array. The number of trimmed nodes is returned.\n * Special care is taken to preserve comments, though any whitespace\n * before the first comment(s) or after the last comment(s) is trimmed.\n */\nexport function trim(nodes: Ast.Node[]): {\n    trimmedStart: number;\n    trimmedEnd: number;\n} {\n    if (!Array.isArray(nodes)) {\n        console.warn(\"Trying to trim a non-array ast\", nodes);\n        return nodes;\n    }\n\n    const { trimmedStart } = trimStart(nodes);\n    const { trimmedEnd } = trimEnd(nodes);\n\n    return { trimmedStart, trimmedEnd };\n}\n\n/**\n * Trim whitespace and parbreaks from the left of an array.\n */\nexport function trimStart(nodes: Ast.Node[]): { trimmedStart: number } {\n    const { start } = amountOfLeadingAndTrailingWhitespace(nodes);\n\n    nodes.splice(0, start);\n\n    // If there are comments at the start, they might have leading whitespace.\n    // This leading whitespace should be trimmed\n    for (const leadingToken of nodes) {\n        if (!match.comment(leadingToken)) {\n            break;\n        }\n        if (leadingToken.leadingWhitespace || leadingToken.sameline) {\n            leadingToken.leadingWhitespace = false;\n        }\n        // Special care must be taken. If the comment was on the same line as a\n        // parskip, it will no longer be on the same line after the trimming.\n        // Thus, we must modify the comment.\n        if (start > 0 && leadingToken.sameline) {\n            leadingToken.sameline = false;\n        }\n    }\n\n    return { trimmedStart: start };\n}\n\n/**\n * Trim whitespace and parbreaks from the right of an array.\n */\nexport function trimEnd(nodes: Ast.Node[]): { trimmedEnd: number } {\n    const { end } = amountOfLeadingAndTrailingWhitespace(nodes);\n\n    nodes.splice(nodes.length - end, end);\n\n    // Trim off any spaces belonging to trailing comments\n    for (let i = nodes.length - 1; i >= 0; i--) {\n        const trailingToken = nodes[i];\n        if (!match.comment(trailingToken)) {\n            break;\n        }\n\n        // Any parbreaks have been trimmed, so there is no suffix parbreak here!\n        delete trailingToken.suffixParbreak;\n\n        // We don't trim spaces before trailing same-line comments. This is a stylistic choice\n        // so that\n        // `foo %xxx` does not become `foo%xxx`.\n        // The latter is strictly \"correct\" for a trim function, but it is prettier to format\n        // code preserving the space before the sameline comment\n        if (\n            match.comment(trailingToken) &&\n            trailingToken.leadingWhitespace &&\n            !trailingToken.sameline\n        ) {\n            trailingToken.leadingWhitespace = false;\n        }\n    }\n\n    return { trimmedEnd: end };\n}\n\n/**\n * Returns the number of whitespace/parbreak nodes at the start and end of an array.\n */\nfunction amountOfLeadingAndTrailingWhitespace(ast: Ast.Node[]): {\n    start: number;\n    end: number;\n} {\n    let start = 0;\n    let end = 0;\n    for (const node of ast) {\n        if (match.whitespace(node) || match.parbreak(node)) {\n            start++;\n        } else {\n            break;\n        }\n    }\n\n    if (start === ast.length) {\n        return { start, end: 0 };\n    }\n\n    // Find the padding on the right\n    for (let i = ast.length - 1; i >= 0; i--) {\n        const node = ast[i];\n        if (match.whitespace(node) || match.parbreak(node)) {\n            end++;\n        } else {\n            break;\n        }\n    }\n\n    return { start, end };\n}\n","import type { Plugin } from \"unified\";\nimport * as Ast from \"@unified-latex/unified-latex-types\";\nimport { match } from \"@unified-latex/unified-latex-util-match\";\nimport { visit } from \"@unified-latex/unified-latex-util-visit\";\nimport { trim, trimEnd, trimStart } from \"./trim\";\n\ntype PluginOptions = void;\n\n/**\n * Unified plugin to trim the whitespace from the start/end of any environments, including\n * math environments.\n */\nexport const unifiedLatexTrimEnvironmentContents: Plugin<\n    PluginOptions[],\n    Ast.Root,\n    Ast.Root\n> = function unifiedLatexTrimEnvironmentContents() {\n    return (tree) => {\n        visit(tree, (node) => {\n            if (!(match.math(node) || match.anyEnvironment(node))) {\n                return;\n            }\n\n            // If the first thing in the environment is a sameline comment,\n            // we actually want to start trimming *after* it.\n            let firstNode = node.content[0];\n            if (match.comment(firstNode) && firstNode.sameline) {\n                firstNode.suffixParbreak = false;\n                trimEnd(node.content);\n\n                // We play a nasty trick here. This call to `trimStart`\n                // will actually modify `node.content` if `node.content.slice(1)` starts\n                // with a comment that has leading whitespace (it will remove that whitespace).\n                // However, it won't remove any elements from `node.content`; we need\n                // to do that ourselves.\n                const { trimmedStart } = trimStart(node.content.slice(1));\n                node.content.splice(1, trimmedStart);\n            } else {\n                trim(node.content);\n            }\n        });\n    };\n};\n","import type { Plugin } from \"unified\";\nimport * as Ast from \"@unified-latex/unified-latex-types\";\nimport { trim } from \"./trim\";\n\ntype PluginOptions = void;\n\n/**\n * Unified plugin to trim the whitespace from the start/end of the root element.\n */\nexport const unifiedLatexTrimRoot: Plugin<PluginOptions[], Ast.Root, Ast.Root> =\n    function unifiedLatexTrimRoot() {\n        return (tree) => {\n            trim(tree.content);\n        };\n    };\n","import * as Ast from \"@unified-latex/unified-latex-types\";\nimport { match } from \"@unified-latex/unified-latex-util-match\";\n\n/**\n * Returns whether the array has whitespace at the start/end. Comments with `leadingWhitespace === true`\n * are counted as whitespace. Other comments are ignored.\n */\nexport function hasWhitespaceEquivalent(nodes: Ast.Node[]): {\n    start: boolean;\n    end: boolean;\n} {\n    let start = false;\n    let end = false;\n    for (let i = 0; i < nodes.length; i++) {\n        const node = nodes[i];\n        if (match.comment(node)) {\n            // A comment with leading whitespace will render with leading whitespace,\n            // so if we encounter one, we should consider ourselves to have leading whitespace.\n            if (node.leadingWhitespace) {\n                start = true;\n                break;\n            }\n            continue;\n        }\n        if (match.whitespace(node)) {\n            start = true;\n        }\n        break;\n    }\n    for (let j = nodes.length - 1; j >= 0; j--) {\n        const node = nodes[j];\n        if (match.comment(node)) {\n            if (node.leadingWhitespace) {\n                end = true;\n                break;\n            }\n            continue;\n        }\n        if (match.whitespace(node)) {\n            end = true;\n        }\n        break;\n    }\n    return { start, end };\n}\n","export * from \"./libs/trim\";\nexport * from \"./libs/unified-latex-trim-environment-contents\";\nexport * from \"./libs/unified-latex-trim-root\";\nexport * from \"./libs/has-whitespace-equivalent\";\n\n// NOTE: The docstring comment must be the last item in the index.ts file!\n/**\n * ## What is this?\n *\n * Functions to help modify a `unified-latex` Abstract Syntax Tree (AST).\n *\n * ## When should I use this?\n *\n * If you want to remove whitespace from the ends of an array of nodes.\n *\n * Note that whitespace can come from a `Ast.Whitespace` node or from an\n * `Ast.Comment` node that has leading whitespace. These functions take care\n * to deal with both situations.\n */\n"],"mappings":"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"}