# unified-latex-util-replace ## What is this? Functions to help modify a `unified-latex` Abstract Syntax Tree (AST). ## When should I use this? If you want to recursively replace particular AST nodes. ## Install ```bash npm install @unified-latex/unified-latex-util-replace ``` This package contains both esm and commonjs exports. To explicitly access the esm export, import the `.js` file. To explicitly access the commonjs export, import the `.cjs` file. # Plugins ## `unifiedLatexReplaceStreamingCommands` Unified plugin to replace all found streaming commands with their argument-style equivalents. This only applies to sections of the tree with no math ancestor. ### Usage `unified().use(unifiedLatexReplaceStreamingCommands[, options])` #### options ```typescript PluginOptions ``` ### Type `Plugin` ```typescript function unifiedLatexReplaceStreamingCommands( options: PluginOptions ): (tree: Ast.Root) => void; ``` where ```typescript type PluginOptions = { replacers: Record< string, (content: Ast.Node[], streamingCommand: Ast.Macro) => Ast.Node | Ast.Node[] >; }; ``` # Functions ## `firstSignificantNode(nodes, parbreaksAreInsignificant)` Returns the first non-whitespace/non-comment node in `nodes`. If there is no such node, `null` is returned. ```typescript function firstSignificantNode( nodes: Ast.Node[], parbreaksAreInsignificant: Boolean ): Ast.Node; ``` **Parameters** | Param | Type | | :------------------------ | :----------- | | nodes | `Ast.Node[]` | | parbreaksAreInsignificant | `Boolean` | ## `firstSignificantNodeIndex(nodes, parbreaksAreInsignificant)` Returns the index of the first non-whitespace/non-comment node in `nodes`. If there is no such node, `null` is returned. ```typescript function firstSignificantNodeIndex( nodes: Ast.Node[], parbreaksAreInsignificant: Boolean ): number; ``` **Parameters** | Param | Type | | :------------------------ | :----------- | | nodes | `Ast.Node[]` | | parbreaksAreInsignificant | `Boolean` | ## `lastSignificantNode(nodes, parbreaksAreInsignificant)` Returns the last non-whitespace/non-comment node in `nodes`. If there is no such node, `null` is returned. ```typescript function lastSignificantNode( nodes: Ast.Node[], parbreaksAreInsignificant: Boolean ): Ast.Node; ``` **Parameters** | Param | Type | | :------------------------ | :----------- | | nodes | `Ast.Node[]` | | parbreaksAreInsignificant | `Boolean` | ## `lastSignificantNodeIndex(nodes, parbreaksAreInsignificant)` Returns the index of the last non-whitespace/non-comment node in `nodes`. If there is no such node, `null` is returned. ```typescript function lastSignificantNodeIndex( nodes: Ast.Node[], parbreaksAreInsignificant: Boolean ): number; ``` **Parameters** | Param | Type | | :------------------------ | :----------- | | nodes | `Ast.Node[]` | | parbreaksAreInsignificant | `Boolean` | ## `replaceNode(ast, visitor)` Recursively replace nodes in `ast`. The `visitor` function is called on each node. If `visitor` returns a node or an array of nodes, those nodes replace the node passed to `visitor`. If `null` is returned, the node is deleted. If `undefined` is returned, no replacement happens. ```typescript function replaceNode( ast: Ast.Ast, visitor: ( node: Ast.Node | Ast.Argument, info: VisitInfo ) => | Ast.Node | Ast.Argument | (Ast.Node | Ast.Argument)[] | null | undefined | void ): void; ``` **Parameters** | Param | Type | | :------ | :-------------------------------- | | ast | `Ast.Ast` | | visitor | Omitted | ## `replaceNodeDuringVisit(replacement, info)` Replaces the current node with `replacement`. It is assumed that the current node is in an array that is a child of a parent element. If this is not the case, the function will error. ```typescript function replaceNodeDuringVisit( replacement: Ast.Node | Ast.Argument | (Ast.Node | Ast.Argument)[], info: VisitInfo ): void; ``` **Parameters** | Param | Type | | :---------- | :-------------------------------- | | replacement | Omitted | | info | `VisitInfo` | where ```typescript type VisitInfo = { /** * If the element was accessed via an attribute, the attribute key is specified. */ readonly key: string | undefined; /** * If the element was accessed in an array, the index is specified. */ readonly index: number | undefined; /** * A list of ancestor nodes, `[parent, grandparent, great-grandparent, ...]` */ readonly parents: (Ast.Node | Ast.Argument)[]; /** * If the element was accessed in an array, the array that it is part of. */ readonly containingArray: (Ast.Node | Ast.Argument)[] | undefined; /** * The LaTeX context of the current match. */ readonly context: VisitorContext; }; ``` ## `replaceStreamingCommand(ast, isStreamingCommand, replacer, options)` Given a group or a node array, look for streaming commands (e.g., `\bfseries`) and replace them with the specified macro. The "arguments" of the streaming command are passed to `replacer` and the return value of `replacer` is inserted into the stream. By default, this command will split at parbreaks (since commands like `\textbf{...} do not accept parbreaks in their contents) and call `replacer\` multiple times, once per paragraph. Commands are also split at environments and at any macros listed in `macrosThatBreakPars`. ```typescript function replaceStreamingCommand( ast: Ast.Group | Ast.Node[], isStreamingCommand: (node: any) => node is Ast.Macro, replacer: ( content: Ast.Node[], streamingCommand: Ast.Macro ) => Ast.Node | Ast.Node[], options: { macrosThatBreakPars?: string[]; environmentsThatDontBreakPars?: string[]; } ): Ast.Node[]; ``` **Parameters** | Param | Type | | :----------------- | :-------------------------------- | | ast | `Ast.Group \| Ast.Node[]` | | isStreamingCommand | Omitted | | replacer | Omitted | | options | Omitted | ## `replaceStreamingCommandInGroup(group, isStreamingCommand, replacer, options)` Process streaming commands in a group. If needed, "escape" the group. For example, `{\bfseries xx}` -> `\textbf{xx}`, but `{foo \bfseries xx}` -> `{foo \textbf{xx}}`. ```typescript function replaceStreamingCommandInGroup( group: Ast.Group, isStreamingCommand: (node: any) => node is Ast.Macro, replacer: ( content: Ast.Node[], streamingCommand: Ast.Macro ) => Ast.Node | Ast.Node[], options: { macrosThatBreakPars?: string[]; environmentsThatDontBreakPars?: string[]; } ): Ast.Node[]; ``` **Parameters** | Param | Type | | :----------------- | :-------------------------------- | | group | `Ast.Group` | | isStreamingCommand | Omitted | | replacer | Omitted | | options | Omitted |