diff --git a/CHANGELOG.md b/CHANGELOG.md index 397119ea..005f119a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### v1.7.1 - Types fix for `@unified-latex/unified-latex-types` +- Fixed AST when expanding `\sysdelim` macros for rendering `\systeme{}` macros with KaTeX ### v1.7.0 diff --git a/packages/unified-latex-prettier/libs/printer/printer.ts b/packages/unified-latex-prettier/libs/printer/printer.ts index 95ca2ddd..25eeb45e 100644 --- a/packages/unified-latex-prettier/libs/printer/printer.ts +++ b/packages/unified-latex-prettier/libs/printer/printer.ts @@ -84,7 +84,20 @@ export function printLatexAst( case "whitespace": return line; default: - console.warn("Printing unknown type", node); + console.warn(`Printing unknown type ${readableType(node)}`, node); return printRaw(node); } } + +/** + * Get a printable type for an object. + */ +function readableType(obj: any): string { + if (obj == null) { + return "null"; + } + if (Array.isArray(obj)) { + return "array"; + } + return typeof obj; +} diff --git a/packages/unified-latex-to-hast/libs/pre-html-subs/katex-subs.ts b/packages/unified-latex-to-hast/libs/pre-html-subs/katex-subs.ts index 2c673e35..67e1d91f 100644 --- a/packages/unified-latex-to-hast/libs/pre-html-subs/katex-subs.ts +++ b/packages/unified-latex-to-hast/libs/pre-html-subs/katex-subs.ts @@ -28,11 +28,17 @@ export const katexSpecificMacroReplacements: Record< }); // If we have information about the sysdelims, then apply them - if (node._renderInfo?.sysdelims) { - const [frontDelim, backDelim]: [Ast.Node, Ast.Node] = node + if (node?._renderInfo?.sysdelims) { + const [frontDelim, backDelim]: [Ast.Node[], Ast.Node[]] = node ._renderInfo?.sysdelims as any; - return [LEFT, frontDelim, ret, RIGHT, backDelim]; + return [ + LEFT, + ...(frontDelim || []), + ret, + RIGHT, + ...(backDelim || []), + ]; } return [LEFT, DEFAULT_LEFT_DELIM, ret, RIGHT, DEFAULT_RIGHT_DELIM]; diff --git a/packages/unified-latex-to-hast/tests/katex-subs.test.ts b/packages/unified-latex-to-hast/tests/katex-subs.test.ts new file mode 100644 index 00000000..f02529c8 --- /dev/null +++ b/packages/unified-latex-to-hast/tests/katex-subs.test.ts @@ -0,0 +1,132 @@ +import { describe, it, expect } from "vitest"; +import util from "util"; +import { parse } from "@unified-latex/unified-latex-util-parse"; +import { replaceNode } from "@unified-latex/unified-latex-util-replace"; +import { + attachNeededRenderInfo, + katexSpecificMacroReplacements, +} from "../libs/pre-html-subs/katex-subs"; +import { match } from "@unified-latex/unified-latex-util-match"; +import { Macro, Node } from "@unified-latex/unified-latex-types/index"; +import { trimRenderInfo } from "@unified-latex/unified-latex-util-render-info"; + +// Make console.log pretty-print by default +const origLog = console.log; +console.log = (...args) => { + origLog(...args.map((x) => util.inspect(x, false, 10, true))); +}; + +describe("unified-latex-to-hast:katex-subs", () => { + it("can expand systeme", () => { + const parsed = trimRenderInfo( + parse("$\\sysdelim{[}{.}x=\\systeme{a&b\\\\x&y}$") + ); + const isKatexMacro = match.createMacroMatcher( + katexSpecificMacroReplacements + ); + attachNeededRenderInfo(parsed); + replaceNode(parsed, (node: Macro) => { + if (isKatexMacro(node)) { + return katexSpecificMacroReplacements[node.content](node); + } + }); + + //trimRenderInfo(parsed); + + expect(parsed).toEqual({ + content: [ + { + content: [ + { + content: "x", + type: "string", + }, + { + content: "=", + type: "string", + }, + { + content: "left", + type: "macro", + }, + { + content: "[", + type: "string", + }, + { + args: [ + { + closeMark: "}", + content: [ + { + content: "r", + type: "string", + }, + ], + openMark: "{", + type: "argument", + }, + ], + content: [ + { + content: "a", + type: "string", + }, + { + content: "&", + type: "string", + }, + { + content: "b", + type: "string", + }, + { + args: [ + { + closeMark: "", + content: [], + openMark: "", + type: "argument", + }, + { + closeMark: "", + content: [], + openMark: "", + type: "argument", + }, + ], + content: "\\", + type: "macro", + }, + { + content: "x", + type: "string", + }, + { + content: "&", + type: "string", + }, + { + content: "y", + type: "string", + }, + ], + env: "array", + type: "environment", + }, + { + content: "right", + type: "macro", + }, + { + content: ".", + type: "string", + }, + ], + type: "inlinemath", + }, + ], + type: "root", + }); + }); +}); diff --git a/packages/unified-latex-types/libs/info-specs.ts b/packages/unified-latex-types/libs/info-specs.ts index 6957f313..40de5a82 100644 --- a/packages/unified-latex-types/libs/info-specs.ts +++ b/packages/unified-latex-types/libs/info-specs.ts @@ -123,6 +123,10 @@ export type MacroInfo = { * @type {boolean} */ tikzPathCommand?: boolean; + /** + * If `\sysdelims` is present, this contains the global information about the delimiters. + */ + sysdelims?: (Ast.Node[] | null)[]; }; /** * The macro signature as an xparse argument specification string. diff --git a/packages/unified-latex-types/vite.config.ts b/packages/unified-latex-types/vite.config.ts index 7cee3987..afbabc90 100644 --- a/packages/unified-latex-types/vite.config.ts +++ b/packages/unified-latex-types/vite.config.ts @@ -16,7 +16,7 @@ export default defineConfig(({ mode }) => { const plugins = mode === "commonjs" ? [] - : [dts({ rollupTypes: true }), packageReadmeAndPackageJson()]; + : [dts({ rollupTypes: false }), packageReadmeAndPackageJson()]; console.log(`Building in mode: ${mode}.\n`); return {