{"version":3,"file":"index.cjs","names":[],"sources":["../libs/match.ts","../index.ts"],"sourcesContent":["import * as Ast from \"@unified-latex/unified-latex-types\";\nimport {\n    EnvInfo,\n    MacroInfo,\n    MacroInfoRecord,\n} from \"@unified-latex/unified-latex-types\";\nimport { printRaw } from \"@unified-latex/unified-latex-util-print-raw\";\n\n/**\n * Creates a macro matching function that uses a `SpecialMacroSpec` or list of macros\n * and generates a hash for quick lookup.\n */\nfunction createMacroMatcher<S extends string>(\n    macros: Ast.Macro[] | S[] | Record<S, unknown>\n) {\n    // We first make sure we have a record type with keys being the macro's contents\n    const macrosHash: Record<string, unknown> = Array.isArray(macros)\n        ? macros.length > 0\n            ? typeof macros[0] === \"string\"\n                ? Object.fromEntries(\n                      macros.map((macro) => {\n                          if (typeof macro !== \"string\") {\n                              throw new Error(\"Wrong branch of map function\");\n                          }\n                          return [macro, {}] as [string, MacroInfo];\n                      })\n                  )\n                : Object.fromEntries(\n                      macros.map((macro) => {\n                          if (typeof macro === \"string\") {\n                              throw new Error(\"Wrong branch of map function\");\n                          }\n                          if (macro.escapeToken != null) {\n                              return [\n                                  macro.content,\n                                  { escapeToken: macro.escapeToken },\n                              ] as [string, MacroInfo];\n                          }\n                          return [macro.content, {}] as [string, MacroInfo];\n                      })\n                  )\n            : {}\n        : macros;\n\n    return function matchAgainstMacros(node: any | Ast.Macro) {\n        if (node == null || node.type !== \"macro\") {\n            return false;\n        }\n        // At this point we have a macro type\n        const spec = macrosHash[node.content];\n        if (!spec) {\n            return false;\n        }\n\n        if (typeof spec === \"object\" && \"escapeToken\" in spec) {\n            return (\n                (spec as MacroInfoRecord).escapeToken == null ||\n                (spec as MacroInfoRecord).escapeToken === node.escapeToken\n            );\n        }\n        return true;\n    } as Ast.TypeGuard<Ast.Macro & { content: S }>;\n}\n\n/**\n * Creates a macro matching function that uses a `SpecialMacroSpec` or list of macros\n * and generates a hash for quick lookup.\n */\nfunction createEnvironmentMatcher(macros: string[] | Record<string, unknown>) {\n    // We first make sure we have a record type with keys being the macro's contents\n    const environmentsHash = Array.isArray(macros)\n        ? Object.fromEntries(\n              macros.map((str) => {\n                  return [str, {}] as [string, EnvInfo];\n              })\n          )\n        : macros;\n\n    return function matchAgainstEnvironments(node: any | Ast.Environment) {\n        if (!match.anyEnvironment(node)) {\n            return false;\n        }\n        // At this point we have an environment type\n        const envName = printRaw(node.env);\n        const spec = environmentsHash[envName];\n        if (!spec) {\n            return false;\n        }\n\n        return true;\n    } as Ast.TypeGuard<Ast.Environment>;\n}\n\n/**\n * Functions to match different types of nodes.\n */\nexport const match = {\n    macro(node: any, macroName?: string): node is Ast.Macro {\n        if (node == null) {\n            return false;\n        }\n        return (\n            node.type === \"macro\" &&\n            (macroName == null || node.content === macroName)\n        );\n    },\n    anyMacro(node: any): node is Ast.Macro {\n        return match.macro(node);\n    },\n    environment(node: any, envName?: string): node is Ast.Environment {\n        if (node == null) {\n            return false;\n        }\n        return (\n            (node.type === \"environment\" || node.type === \"mathenv\") &&\n            (envName == null || printRaw(node.env) === envName)\n        );\n    },\n    anyEnvironment(node: any): node is Ast.Environment {\n        return match.environment(node);\n    },\n    comment(node: any): node is Ast.Comment {\n        if (node == null) {\n            return false;\n        }\n        return node.type === \"comment\";\n    },\n    parbreak(node: any): node is Ast.Parbreak {\n        if (node == null) {\n            return false;\n        }\n        return node.type === \"parbreak\";\n    },\n    whitespace(node: any): node is Ast.Whitespace {\n        if (node == null) {\n            return false;\n        }\n        return node.type === \"whitespace\";\n    },\n    /**\n     * Matches whitespace or a comment with leading whitespace.\n     */\n    whitespaceLike(\n        node: any\n    ): node is Ast.Whitespace | (Ast.Comment & { leadingWhitespace: true }) {\n        if (node == null) {\n            return false;\n        }\n        return (\n            node.type === \"whitespace\" ||\n            (node.type === \"whitespace\" && node.leadingWhitespace === true)\n        );\n    },\n    string(node: any, value?: string): node is Ast.String {\n        if (node == null) {\n            return false;\n        }\n        return (\n            node.type === \"string\" && (value == null || node.content === value)\n        );\n    },\n    anyString(node: any): node is Ast.String {\n        return match.string(node);\n    },\n    group(node: any): node is Ast.Group {\n        if (node == null) {\n            return false;\n        }\n        return node.type === \"group\";\n    },\n    argument(node: any): node is Ast.Argument {\n        if (node == null) {\n            return false;\n        }\n        return node.type === \"argument\";\n    },\n    blankArgument(node: any): boolean {\n        if (!match.argument(node)) {\n            return false;\n        }\n        return (\n            node.openMark === \"\" &&\n            node.closeMark === \"\" &&\n            node.content.length === 0\n        );\n    },\n    math(node: any): node is Ast.DisplayMath | Ast.InlineMath {\n        if (node == null) {\n            return false;\n        }\n        return node.type === \"displaymath\" || node.type === \"inlinemath\";\n    },\n    createMacroMatcher,\n    createEnvironmentMatcher,\n};\n\nexport const {\n    anyEnvironment,\n    anyMacro,\n    anyString,\n    argument,\n    blankArgument,\n    comment,\n    environment,\n    group,\n    macro,\n    math,\n    parbreak,\n    string,\n    whitespace,\n} = match;\n","export * from \"./libs/match\";\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 match different `Ast.Node` types in a `unified-latex` Abstract Syntax Tree (AST).\n *\n * ## When should I use this?\n *\n * If you need a type-guard to ensure a node is of a certain type; for example, during a call to `unified-latex-until-visit`.\n */\n"],"mappings":"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"}