Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default arguments support #24 #62

Open
wants to merge 25 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ee4c8e5
feat: Attach default arguments to AST
theseanl Dec 31, 2023
58077cd
feat: Support default arguments for embellishments
theseanl Jan 2, 2024
76d88c1
test: add macro with default argument case in CLI test, make it work on
theseanl Jan 2, 2024
48c30a7
chore: remove an obsolete snapshot
theseanl Jan 3, 2024
c07f7b8
Merge branch 'main' into default-arguments
theseanl Jan 5, 2024
af91693
[WIP] fix 'until' behavior, support multi-token stop
theseanl Jan 17, 2024
0c3e598
build: Switch to nodejs export conditions from TS project references
theseanl Jan 20, 2024
da0e74c
Merge branch 'main' into ditch-ts-project-references
theseanl Jan 20, 2024
b69517b
build: use _bundle export condition on esm bundle as well
theseanl Jan 20, 2024
9035e2a
chore: make prettier format json
theseanl Jan 20, 2024
768a308
build: set forceConsistentCasingInFileNames
theseanl Jan 20, 2024
191c53c
Merge branch 'ditch-ts-project-references' into default-arguments
theseanl Jan 20, 2024
2067555
feat: support multi-stop token in 'until', macro delimiters
theseanl Jan 20, 2024
6cb5599
refactor: move default argument logic to expandMacros
theseanl Jan 21, 2024
20976aa
feat: Support default arguments referencing other arguments
theseanl Jan 21, 2024
21a1733
chore: revert early return in gobble-single-argument.ts
theseanl Jan 21, 2024
bd1f972
feat: default argument support for \newcommand
theseanl Jan 22, 2024
7d12d13
chore: simplify codes
theseanl Jan 22, 2024
af5e25d
build: use import instead of _bundle
theseanl Jan 22, 2024
8de3294
Merge branch 'ditch-ts-project-references' into default-arguments
theseanl Jan 24, 2024
d63b24e
chore: fix cli test, regenerate package lock
theseanl Jan 24, 2024
dcb22be
Merge branch 'main' into default-arguments
theseanl Jan 24, 2024
916e10f
chore: minor change as per reviews
theseanl Jan 24, 2024
38a18e2
Merge branch 'main' into default-arguments
theseanl Jan 29, 2024
6b9e249
fix: optional argument without default value
theseanl Jan 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7,612 changes: 4,193 additions & 3,419 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"devDependencies": {
"@types/node": "^20.5.9",
"@types/prettier": "^2.7.3",
"@typescript-eslint/eslint-plugin": "^6.16.0",
"esbuild": "^0.19.2",
"esbuild-runner": "^2.2.2",
"lerna": "^7.2.0",
Expand Down
2 changes: 2 additions & 0 deletions packages/unified-latex-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@
"homepage": "https://github.com/siefkenj/unified-latex#readme",
"private": true,
"devDependencies": {
"@types/cross-spawn": "^6.0.6",
"cross-spawn": "^7.0.3",
"source-map-support": "^0.5.21"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ hi $\\\\x fooArg$ and baz!
"
`;

exports[`unified-latex-cli > can expand macro 3`] = `
"% Expand via> tests/needs-expanding.tex --stats -e \\"\\\\\\\\newcommand{foo}[1]{FOO(#1)}\\" -e '{name: \\"bar\\", body: \\"baz\\"}'
hi FOO(fooArg) and baz!
"
`;

exports[`unified-latex-cli > can expand macros defined in document 1`] = `
"\\\\newcommand{\\\\foo}[1]{$BAR #1$}
\\\\DeclareDocumentCommand{\\\\baz}{m}{\\\\foo{xxx} .#1.}
Expand Down
220 changes: 143 additions & 77 deletions packages/unified-latex-cli/tests/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import "../../test-common";
import { exec as _exec } from "node:child_process";
import * as fsLegacy from "node:fs";
import * as path from "node:path";
import spawn from "cross-spawn";

const exec = util.promisify(_exec);

Expand All @@ -18,87 +19,152 @@ console.log = (...args) => {
const exePath = path.resolve(__dirname, "../dist/unified-latex-cli.mjs");
const examplesPath = path.resolve(__dirname, "examples");

describe("unified-latex-cli", () => {
let stdout: string, stderr: string;
it("executable exists", async () => {
expect(fsLegacy.existsSync(exePath)).toBeTruthy();
});
it("can execute without error", async () => {
let { stdout, stderr } = await exec(`node ${exePath} -h`);
expect(stdout).toBeTruthy();
});
it("can format document", async () => {
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/needs-fixing.tex`
);
expect(stdout).toMatchSnapshot();
});
it("can expand macro", async () => {
{
describe(
"unified-latex-cli",
() => {
let stdout: string, stderr: string;
it("executable exists", async () => {
expect(fsLegacy.existsSync(exePath)).toBeTruthy();
});
it("can execute without error", async () => {
let { stdout, stderr } = await exec(`node ${exePath} -h`);
expect(stdout).toBeTruthy();
});
it("can format document", async () => {
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/needs-expanding.tex -e '\\newcommand{foo}[1]{FOO(#1)}' -e '{name: "bar", body: "baz"}'`
`node ${exePath} ${examplesPath}/needs-fixing.tex`
);
expect(stdout).toMatchSnapshot();
}
{
// Make sure we don't lose spaces in math mode
});
it("can expand macro", async () => {
{
let stdout = await executeCommand(`node`, [
exePath,
`${examplesPath}/needs-expanding.tex`,
`-e`,
"\\newcommand{foo}[1]{FOO(#1)}",
`-e`,
'{name: "bar", body: "baz"}',
]);
expect(stdout).toMatchSnapshot();
}
{
// Make sure we don't lose spaces in math mode
let stdout = await executeCommand(`node`, [
exePath,
`${examplesPath}/needs-expanding.tex`,
`-e`,
"\\newcommand{foo}[1]{$\\x #1$}",
`-e`,
'{name: "bar", body: "baz"}',
]);
expect(stdout).toMatchSnapshot();
}
{
let stdout = await executeCommand(`node`, [
exePath,
`${examplesPath}/needs-expanding.tex`,
`-e`,
"\\newcommand{foo}[1]{FOO(#1)}",
`-e`,
'{name: "bar", signature: "O{baz}", body: "#1"}',
]);
expect(stdout).toMatchSnapshot();
}
});
it("can expand macros defined in document", async () => {
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/needs-expanding.tex -e '\\newcommand{foo}[1]{$\\x #1$}' -e '{name: "bar", body: "baz"}'`
`node ${exePath} ${examplesPath}/has-definition.tex --stats-json`
);
expect(stdout).toMatchSnapshot();
}
});
it("can expand macros defined in document", async () => {
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/has-definition.tex --stats-json`
);
const { newcommands } = JSON.parse(stdout) as {
newcommands: { name: string }[];
};
const newcommandNames = newcommands.map((c) => c.name);
expect(newcommandNames).toEqual(["foo", "baz"]);
const { newcommands } = JSON.parse(stdout) as {
newcommands: { name: string }[];
};
const newcommandNames = newcommands.map((c) => c.name);
expect(newcommandNames).toEqual(["foo", "baz"]);

{
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/has-definition.tex --expand-document-macro foo --expand-document-macro baz`
);
expect(stdout).toMatchSnapshot();
}
});
it("can override default macros", async () => {
{
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/has-existing-definition.tex`
);
expect(stdout).toMatchSnapshot();
}
{
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/has-existing-definition.tex -e '\\newcommand{mathbb}{\\mathbb}'`
);
expect(stdout).toMatchSnapshot();
}
{
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/has-existing-definition.tex -e '\\newcommand{mathbb}[2]{\\mathbb{#1}{#2}}'`
);
expect(stdout).toMatchSnapshot();
}
});
it("can convert to html", async () => {
{
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/simple.tex --html`
);
expect(stdout).toMatchSnapshot();
}
});
it("can convert to markdown", async () => {
{
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/simple.tex --markdown`
);
expect(stdout).toMatchSnapshot();
}
{
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/has-definition.tex --expand-document-macro foo --expand-document-macro baz`
);
expect(stdout).toMatchSnapshot();
}
});
it("can override default macros", async () => {
{
let stdout = await executeCommand(`node`, [
exePath,
`${examplesPath}/has-existing-definition.tex`,
]);
expect(stdout).toMatchSnapshot();
}
{
let stdout = await executeCommand(`node`, [
exePath,
`${examplesPath}/has-existing-definition.tex`,
`-e`,
"\\newcommand{mathbb}{\\mathbb}",
]);
expect(stdout).toMatchSnapshot();
}
{
let stdout = await executeCommand(`node`, [
exePath,
`${examplesPath}/has-existing-definition.tex`,
`-e`,
"\\newcommand{mathbb}[2]{\\mathbb{#1}{#2}}",
]);
expect(stdout).toMatchSnapshot();
}
});
it("can convert to html", async () => {
{
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/simple.tex --html`
);
expect(stdout).toMatchSnapshot();
}
});
it("can convert to markdown", async () => {
{
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/simple.tex --markdown`
);
expect(stdout).toMatchSnapshot();
}
});
},
{
timeout: 60 * 1000,
}
);

/**
* Run commands with arguments using "cross-spawn", which correctly escapes arguments
* so that end results are the same across different shells.
*/
async function executeCommand(executablePath: string, args: string[]) {
return new Promise((resolve, reject) => {
const childProcess = spawn(executablePath, args, { stdio: "pipe" });

let stdoutData = "";

// Listen for stdout data
childProcess.stdout!.on("data", (data) => {
stdoutData += data.toString();
});

// Listen for errors
childProcess.on("error", (err) => {
reject(err);
});

// Listen for process completion
childProcess.on("close", (code) => {
if (code === 0) {
resolve(stdoutData);
} else {
reject(new Error(`Child process exited with code ${code}`));
}
});
});
});
}
2 changes: 1 addition & 1 deletion packages/unified-latex-to-hast/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export * from "./libs/convert-to-html";
* import { printRaw } from "@unified-latex/unified-latex-util-print-raw";
* import { unifiedLatexToHast } from "@unified-latex/unified-latex-to-hast";
* import { unifiedLatexFromString } from "@unified-latex/unified-latex-util-parse";
* import { getArgsContent } from "@unified-latex/unified-latex-util-arguments";
* import { getArgsContent } from "@unified-latex/unified-latex-util-arguments";
*
* const convert = (value) =>
* unified()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,5 +178,5 @@ export const environmentReplacements: Record<
content: env.content,
attributes: { className: "environment quote" },
});
}
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,20 @@ describe("unified-latex-to-mdast:convert-to-markdown", () => {
`### My Section\n\nHi there\n\nAnd here $x^{2}$ math\n`
);
});

it("display math converts to $$...$$", () => {
let ast = unified()
.use(unifiedLatexFromString)
.parse("my\\[math\\]yay!");
markdown = convertToMarkdown(ast);
expect(markdown).toEqual(
`my\n\n\`\`\`math\nmath\n\`\`\`\n\nyay!\n`
);
expect(markdown).toEqual(`my\n\n\`\`\`math\nmath\n\`\`\`\n\nyay!\n`);
});

it("math isn't mangled when it is rendered", () => {
let ast = unified()
.use(unifiedLatexFromString)
.parse("$\\sum_x^{y} x+Y$");
markdown = convertToMarkdown(ast);
expect(markdown).toEqual(
`$\\sum_{x}^{y}x+Y$\n`
);
expect(markdown).toEqual(`$\\sum_{x}^{y}x+Y$\n`);
});
});