mirror of
https://github.com/borbann-platform/end-of-semester-report.git
synced 2025-12-20 06:44:05 +01:00
1 line
15 KiB
Plaintext
1 line
15 KiB
Plaintext
{"version":3,"file":"index.cjs","sources":["../libs/list-math-children.ts","../libs/visit.ts"],"sourcesContent":["import * as Ast from \"@unified-latex/unified-latex-types\";\nimport { match } from \"@unified-latex/unified-latex-util-match\";\n\n/**\n * List all props of the current node that should be processed\n * in math mode or not in math mode. If math mode is not specified in the node's render\n * info, empty lists are returned.\n *\n * For example `\\text{foo}` will report that `args` should *not* be processed in math mode,\n * since it's contents should always be processed in text mode.\n */\nexport function listMathChildren(node: Ast.Ast): {\n enter: string[];\n leave: string[];\n} {\n const NULL_RETURN = { enter: [], leave: [] };\n if (Array.isArray(node)) {\n return NULL_RETURN;\n }\n if (match.math(node)) {\n // When we enter a math environment, our content is always\n // considered math mode\n return { enter: [\"content\"], leave: [] };\n }\n\n const renderInfo: { inMathMode?: boolean } = node._renderInfo || {};\n if (renderInfo.inMathMode == null) {\n return NULL_RETURN;\n }\n if (match.macro(node)) {\n if (renderInfo.inMathMode === true) {\n return { enter: [\"args\"], leave: [] };\n } else if (renderInfo.inMathMode === false) {\n return { enter: [], leave: [\"args\"] };\n }\n }\n if (match.environment(node)) {\n if (renderInfo.inMathMode === true) {\n return { enter: [\"content\"], leave: [] };\n } else {\n return { enter: [], leave: [\"content\"] };\n }\n }\n return NULL_RETURN;\n}\n","import * as Ast from \"@unified-latex/unified-latex-types\";\nimport { listMathChildren } from \"./list-math-children\";\n\nexport type VisitorContext = {\n /**\n * Whether the node is being processed in math mode.\n *\n * This happens when the node is a director or indirect child\n * of a math environment (e.g. `$abc$`), but not when an environment\n * re-establishes text mode (e.g. `$\\text{abc}$`)\n */\n inMathMode?: boolean;\n /**\n * Whether the node has any ancestor that is processed in math mode.\n */\n hasMathModeAncestor?: boolean;\n};\n\ntype GetGuard<T> = T extends (x: any, ...y: any[]) => x is infer R ? R : never;\n/**\n * Gets the type that a type-guard function is guarding. If\n * the guard type cannot be determined, the input type is returned.\n */\ntype GuardTypeOf<T extends (x: any, ...y: any[]) => boolean> =\n GetGuard<T> extends never\n ? T extends (x: infer A) => any\n ? A\n : never\n : GetGuard<T>;\n\n/**\n * Extracts the guard type from the `test` function provided in a\n * `VisitOptions` argument.\n */\ntype GuardFromOptions<\n Opts extends VisitOptions,\n PossibleTypes = Ast.Ast\n> = Opts extends {\n test: infer R;\n}\n ? R extends (x: any, ...y: any[]) => boolean\n ? // A guard like `typeof Array.isArray` will return `any[]` as the type.\n // This type cannot be narrowed, so instead we use it to pick from\n // the set of all possible types.\n Extract<PossibleTypes, GuardTypeOf<R>>\n : PossibleTypes\n : PossibleTypes;\n\n/**\n * Narrow the type `T` based on the `VisitOptions` supplied. If `{includeArrays: false}`\n * is specified in the `VisitOptions`, then arrays are excluded from `T`.\n */\ntype NarrowArraysBasedOnOptions<T, Opts extends VisitOptions> = Opts extends {\n includeArrays: infer A;\n}\n ? A extends true\n ? T\n : Exclude<T, any[]>\n : Exclude<T, any[]>;\n\n/**\n * Get the type of the parameter to the `Visitor` function based on the\n * `VisitOptions` that are supplied.\n */\ntype VisitorTypeFromOptions<Opts extends VisitOptions> =\n NarrowArraysBasedOnOptions<GuardFromOptions<Opts>, Opts>;\n\n/**\n * Continue traversing as normal\n */\nexport const CONTINUE = Symbol(\"continue\");\n/**\n * Do not traverse this node’s children\n */\nexport const SKIP = Symbol(\"skip\");\n/**\n * Stop traversing immediately\n */\nexport const EXIT = Symbol(\"exit\");\n\ntype Action = typeof CONTINUE | typeof SKIP | typeof EXIT;\ntype Index = number;\ntype ActionTuple = [Action] | [typeof SKIP, Index] | [typeof CONTINUE, Index];\n\n/**\n * A visitor takes a `node`, `key`, `index`, and ...\n *\n * @param key - The key of the parent that we were accessed through.\n */\ntype Visitor<T> = (\n node: T,\n info: VisitInfo\n) => null | undefined | Action | Index | ActionTuple | void;\ntype Visitors<T> = { enter?: Visitor<T>; leave?: Visitor<T> };\n\ntype VisitOptions = {\n startingContext?: VisitorContext;\n /**\n * Type guard for types that are passed to the `visitor` function.\n */\n test?: (node: Ast.Ast, info: VisitInfo) => boolean;\n /**\n * Whether arrays will be sent to the `visitor` function. If falsy,\n * only nodes will be past to `visitor`.\n */\n includeArrays?: boolean;\n};\n\nconst DEFAULT_CONTEXT: VisitorContext = {\n inMathMode: false,\n hasMathModeAncestor: false,\n};\n\nexport type VisitInfo = {\n /**\n * If the element was accessed via an attribute, the attribute key is specified.\n */\n readonly key: string | undefined;\n /**\n * If the element was accessed in an array, the index is specified.\n */\n readonly index: number | undefined;\n /**\n * A list of ancestor nodes, `[parent, grandparent, great-grandparent, ...]`\n */\n readonly parents: (Ast.Node | Ast.Argument)[];\n /**\n * If the element was accessed in an array, the array that it is part of.\n */\n readonly containingArray: (Ast.Node | Ast.Argument)[] | undefined;\n /**\n * The LaTeX context of the current match.\n */\n readonly context: VisitorContext;\n};\n\n/**\n * Visit children of tree which pass a test\n *\n * @param {Node} tree Abstract syntax tree to walk\n * @param {Visitor|Visitors} [visitor] Function to run for each node\n */\nexport function visit<Opts extends VisitOptions>(\n tree: Ast.Ast,\n visitor:\n | Visitor<VisitorTypeFromOptions<Opts>>\n | Visitors<VisitorTypeFromOptions<Opts>>,\n options?: Opts\n) {\n const {\n startingContext = DEFAULT_CONTEXT,\n test = () => true,\n includeArrays = false,\n } = options || {};\n let enter: Visitor<VisitorTypeFromOptions<Opts>> | undefined;\n let leave: Visitor<VisitorTypeFromOptions<Opts>> | undefined;\n\n if (typeof visitor === \"function\") {\n enter = visitor;\n } else if (visitor && typeof visitor === \"object\") {\n enter = visitor.enter;\n leave = visitor.leave;\n }\n\n walk(tree, {\n key: undefined,\n index: undefined,\n parents: [],\n containingArray: undefined,\n context: { ...startingContext },\n });\n\n /**\n * @param {Node} node\n * @param {string?} key\n * @param {number?} index\n * @param {Array.<Node>} parents\n */\n function walk(\n node: Ast.Ast,\n { key, index, parents, context, containingArray }: VisitInfo\n ): ActionTuple {\n const nodePassesTest = includeArrays\n ? test(node, { key, index, parents, context, containingArray })\n : !Array.isArray(node) &&\n test(node, { key, index, parents, context, containingArray });\n\n const result: ActionTuple =\n enter && nodePassesTest\n ? toResult(\n enter(node as any, {\n key,\n index,\n parents,\n context,\n containingArray,\n })\n )\n : [CONTINUE];\n\n if (result[0] === EXIT) {\n return result;\n }\n\n if (result[0] === SKIP) {\n return leave && nodePassesTest\n ? toResult(\n leave(node as any, {\n key,\n index,\n parents,\n context,\n containingArray,\n })\n )\n : result;\n }\n\n if (Array.isArray(node)) {\n // The `value` array might be modified in place as we traverse it, so\n // we use a traditional for loop.\n for (let index = 0; index > -1 && index < node.length; index++) {\n const item = node[index];\n const result = walk(item, {\n key,\n index,\n parents,\n context,\n containingArray: node,\n });\n if (result[0] === EXIT) {\n return result;\n }\n if (typeof result[1] === \"number\") {\n // The for loop will increment i every pass. However,\n // if an index was returned, that's where we want to start next time.\n index = result[1] - 1;\n }\n }\n } else {\n // We don't want to recursively apply to the `content`\n // of all types (e.g., comments and macros), so specify\n // a blacklist.\n let childProps: (\"content\" | \"args\")[] = [\"content\", \"args\"];\n switch (node.type) {\n case \"macro\":\n childProps = [\"args\"];\n break;\n case \"comment\":\n case \"string\":\n case \"verb\":\n case \"verbatim\":\n childProps = [];\n break;\n default:\n break;\n }\n\n const mathModeProps = listMathChildren(node);\n for (const key of childProps) {\n const value = node[key as keyof typeof node] as\n | Ast.Ast\n | undefined;\n const grandparents = [node].concat(parents);\n\n if (value == null) {\n continue;\n }\n\n // We may switch in/out of math mode as we pass to node[key]\n const newContext = { ...context };\n if (mathModeProps.enter.includes(key)) {\n newContext.inMathMode = true;\n newContext.hasMathModeAncestor = true;\n } else if (mathModeProps.leave.includes(key)) {\n newContext.inMathMode = false;\n }\n\n const result = walk(value, {\n key,\n index: undefined,\n parents: grandparents,\n context: newContext,\n containingArray: undefined,\n });\n if (result[0] === EXIT) {\n return result;\n }\n }\n }\n\n return leave && nodePassesTest\n ? toResult(\n leave(node as any, {\n key,\n index,\n parents,\n context,\n containingArray,\n })\n )\n : result;\n }\n}\n\n/**\n * Ensures a result is an `ActionTuple`s\n */\nfunction toResult(\n value: null | undefined | void | Action | Index | ActionTuple\n): ActionTuple {\n if (value == null) {\n return [CONTINUE];\n }\n\n if (Array.isArray(value)) {\n return value;\n }\n\n if (typeof value === \"number\") {\n return [CONTINUE, value];\n }\n\n return [value];\n}\n"],"names":["match","index","result","key"],"mappings":"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"} |