{"version":3,"file":"index.cjs","sources":["../libs/trim.ts","../libs/unified-latex-trim-environment-contents.ts","../libs/unified-latex-trim-root.ts","../libs/has-whitespace-equivalent.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"],"names":["match","unifiedLatexTrimEnvironmentContents","visit","unifiedLatexTrimRoot"],"mappings":"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"}