@unified-latex/unified-latex-util-trim
Version:
Functions for modifying a unified-latex AST
1 lines • 10.4 kB
Source Map (JSON)
{"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":";;;;;;;;;;AASA,SAAgB,KAAK,OAGnB;AACE,KAAI,CAAC,MAAM,QAAQ,MAAM,EAAE;AACvB,UAAQ,KAAK,kCAAkC,MAAM;AACrD,SAAO;;CAGX,MAAM,EAAE,iBAAiB,UAAU,MAAM;CACzC,MAAM,EAAE,eAAe,QAAQ,MAAM;AAErC,QAAO;EAAE;EAAc;EAAY;;;;;AAMvC,SAAgB,UAAU,OAA6C;CACnE,MAAM,EAAE,UAAU,qCAAqC,MAAM;AAE7D,OAAM,OAAO,GAAG,MAAM;AAItB,MAAK,MAAM,gBAAgB,OAAO;AAC9B,MAAI,CAAC,wCAAA,MAAM,QAAQ,aAAa,CAC5B;AAEJ,MAAI,aAAa,qBAAqB,aAAa,SAC/C,cAAa,oBAAoB;AAKrC,MAAI,QAAQ,KAAK,aAAa,SAC1B,cAAa,WAAW;;AAIhC,QAAO,EAAE,cAAc,OAAO;;;;;AAMlC,SAAgB,QAAQ,OAA2C;CAC/D,MAAM,EAAE,QAAQ,qCAAqC,MAAM;AAE3D,OAAM,OAAO,MAAM,SAAS,KAAK,IAAI;AAGrC,MAAK,IAAI,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK;EACxC,MAAM,gBAAgB,MAAM;AAC5B,MAAI,CAAC,wCAAA,MAAM,QAAQ,cAAc,CAC7B;AAIJ,SAAO,cAAc;AAOrB,MACI,wCAAA,MAAM,QAAQ,cAAc,IAC5B,cAAc,qBACd,CAAC,cAAc,SAEf,eAAc,oBAAoB;;AAI1C,QAAO,EAAE,YAAY,KAAK;;;;;AAM9B,SAAS,qCAAqC,KAG5C;CACE,IAAI,QAAQ;CACZ,IAAI,MAAM;AACV,MAAK,MAAM,QAAQ,IACf,KAAI,wCAAA,MAAM,WAAW,KAAK,IAAI,wCAAA,MAAM,SAAS,KAAK,CAC9C;KAEA;AAIR,KAAI,UAAU,IAAI,OACd,QAAO;EAAE;EAAO,KAAK;EAAG;AAI5B,MAAK,IAAI,IAAI,IAAI,SAAS,GAAG,KAAK,GAAG,KAAK;EACtC,MAAM,OAAO,IAAI;AACjB,MAAI,wCAAA,MAAM,WAAW,KAAK,IAAI,wCAAA,MAAM,SAAS,KAAK,CAC9C;MAEA;;AAIR,QAAO;EAAE;EAAO;EAAK;;;;;;;;AC1GzB,IAAa,sCAIT,SAAS,sCAAsC;AAC/C,SAAQ,SAAS;AACb,GAAA,GAAA,wCAAA,OAAM,OAAO,SAAS;AAClB,OAAI,EAAE,wCAAA,MAAM,KAAK,KAAK,IAAI,wCAAA,MAAM,eAAe,KAAK,EAChD;GAKJ,IAAI,YAAY,KAAK,QAAQ;AAC7B,OAAI,wCAAA,MAAM,QAAQ,UAAU,IAAI,UAAU,UAAU;AAChD,cAAU,iBAAiB;AAC3B,YAAQ,KAAK,QAAQ;IAOrB,MAAM,EAAE,iBAAiB,UAAU,KAAK,QAAQ,MAAM,EAAE,CAAC;AACzD,SAAK,QAAQ,OAAO,GAAG,aAAa;SAEpC,MAAK,KAAK,QAAQ;IAExB;;;;;;;;AC/BV,IAAa,uBACT,SAAS,uBAAuB;AAC5B,SAAQ,SAAS;AACb,OAAK,KAAK,QAAQ;;;;;;;;;ACL9B,SAAgB,wBAAwB,OAGtC;CACE,IAAI,QAAQ;CACZ,IAAI,MAAM;AACV,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACnC,MAAM,OAAO,MAAM;AACnB,MAAI,wCAAA,MAAM,QAAQ,KAAK,EAAE;AAGrB,OAAI,KAAK,mBAAmB;AACxB,YAAQ;AACR;;AAEJ;;AAEJ,MAAI,wCAAA,MAAM,WAAW,KAAK,CACtB,SAAQ;AAEZ;;AAEJ,MAAK,IAAI,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK;EACxC,MAAM,OAAO,MAAM;AACnB,MAAI,wCAAA,MAAM,QAAQ,KAAK,EAAE;AACrB,OAAI,KAAK,mBAAmB;AACxB,UAAM;AACN;;AAEJ;;AAEJ,MAAI,wCAAA,MAAM,WAAW,KAAK,CACtB,OAAM;AAEV;;AAEJ,QAAO;EAAE;EAAO;EAAK"}