UNPKG

@unified-latex/unified-latex-util-trim

Version:

Functions for modifying a unified-latex AST

157 lines (156 loc) 4.53 kB
import { match } from "@unified-latex/unified-latex-util-match"; import { visit } from "@unified-latex/unified-latex-util-visit"; //#region libs/trim.ts /** * Trims whitespace and parbreaks from the start and end * of an array. The number of trimmed nodes is returned. * Special care is taken to preserve comments, though any whitespace * before the first comment(s) or after the last comment(s) is trimmed. */ function trim(nodes) { if (!Array.isArray(nodes)) { console.warn("Trying to trim a non-array ast", nodes); return nodes; } const { trimmedStart } = trimStart(nodes); const { trimmedEnd } = trimEnd(nodes); return { trimmedStart, trimmedEnd }; } /** * Trim whitespace and parbreaks from the left of an array. */ function trimStart(nodes) { const { start } = amountOfLeadingAndTrailingWhitespace(nodes); nodes.splice(0, start); for (const leadingToken of nodes) { if (!match.comment(leadingToken)) break; if (leadingToken.leadingWhitespace || leadingToken.sameline) leadingToken.leadingWhitespace = false; if (start > 0 && leadingToken.sameline) leadingToken.sameline = false; } return { trimmedStart: start }; } /** * Trim whitespace and parbreaks from the right of an array. */ function trimEnd(nodes) { const { end } = amountOfLeadingAndTrailingWhitespace(nodes); nodes.splice(nodes.length - end, end); for (let i = nodes.length - 1; i >= 0; i--) { const trailingToken = nodes[i]; if (!match.comment(trailingToken)) break; delete trailingToken.suffixParbreak; if (match.comment(trailingToken) && trailingToken.leadingWhitespace && !trailingToken.sameline) trailingToken.leadingWhitespace = false; } return { trimmedEnd: end }; } /** * Returns the number of whitespace/parbreak nodes at the start and end of an array. */ function amountOfLeadingAndTrailingWhitespace(ast) { let start = 0; let end = 0; for (const node of ast) if (match.whitespace(node) || match.parbreak(node)) start++; else break; if (start === ast.length) return { start, end: 0 }; for (let i = ast.length - 1; i >= 0; i--) { const node = ast[i]; if (match.whitespace(node) || match.parbreak(node)) end++; else break; } return { start, end }; } //#endregion //#region libs/unified-latex-trim-environment-contents.ts /** * Unified plugin to trim the whitespace from the start/end of any environments, including * math environments. */ var unifiedLatexTrimEnvironmentContents = function unifiedLatexTrimEnvironmentContents() { return (tree) => { visit(tree, (node) => { if (!(match.math(node) || match.anyEnvironment(node))) return; let firstNode = node.content[0]; if (match.comment(firstNode) && firstNode.sameline) { firstNode.suffixParbreak = false; trimEnd(node.content); const { trimmedStart } = trimStart(node.content.slice(1)); node.content.splice(1, trimmedStart); } else trim(node.content); }); }; }; //#endregion //#region libs/unified-latex-trim-root.ts /** * Unified plugin to trim the whitespace from the start/end of the root element. */ var unifiedLatexTrimRoot = function unifiedLatexTrimRoot() { return (tree) => { trim(tree.content); }; }; //#endregion //#region libs/has-whitespace-equivalent.ts /** * Returns whether the array has whitespace at the start/end. Comments with `leadingWhitespace === true` * are counted as whitespace. Other comments are ignored. */ function hasWhitespaceEquivalent(nodes) { let start = false; let end = false; for (let i = 0; i < nodes.length; i++) { const node = nodes[i]; if (match.comment(node)) { if (node.leadingWhitespace) { start = true; break; } continue; } if (match.whitespace(node)) start = true; break; } for (let j = nodes.length - 1; j >= 0; j--) { const node = nodes[j]; if (match.comment(node)) { if (node.leadingWhitespace) { end = true; break; } continue; } if (match.whitespace(node)) end = true; break; } return { start, end }; } //#endregion //#region index.ts /** * ## What is this? * * Functions to help modify a `unified-latex` Abstract Syntax Tree (AST). * * ## When should I use this? * * If you want to remove whitespace from the ends of an array of nodes. * * Note that whitespace can come from a `Ast.Whitespace` node or from an * `Ast.Comment` node that has leading whitespace. These functions take care * to deal with both situations. */ //#endregion export { hasWhitespaceEquivalent, trim, trimEnd, trimStart, unifiedLatexTrimEnvironmentContents, unifiedLatexTrimRoot }; //# sourceMappingURL=index.js.map