Switch from nomnom to commander (#1496)

* Switch from nomnom to commander

* Fix #1489
* --macro repeatable option replaced with single --macros option with ";"
  separator (until https://github.com/tj/commander.js/issues/674)
* Add missing --max-expand option
* Replace expired --unicode-text-in-math-mode option with --strict
  (https://github.com/Khan/KaTeX/issues/1483#issuecomment-405108291)
* Add instructions for how to run in the opening comments
* Clean up option doc strings

* Implement @ylemkimon's comments

* Fix try/const bug

* Fix use of --selenium-ip

It was a quirk that --seleniumIP worked.  --help lists --selenium-ip.

* Implement comments, restore --macro repeatable argument

* Cleanup

* Restore 0 default for maxExpand

* Fix more comments from @ylemkimon

* npm run dist -> npm run build

In preparation for #1500

* Fix line length error
This commit is contained in:
Erik Demaine
2018-07-23 13:16:45 -04:00
committed by GitHub
parent cbd3afd738
commit 9fe5e221e5
6 changed files with 131 additions and 1657 deletions

View File

@@ -21,7 +21,7 @@ defaults: &defaults
- run: - run:
name: Verify screenshots and generate diffs and new screenshots name: Verify screenshots and generate diffs and new screenshots
command: node dockers/Screenshotter/screenshotter.js --seleniumIP localhost -b $CIRCLE_JOB --verify --diff --new command: node dockers/Screenshotter/screenshotter.js --selenium-ip localhost -b $CIRCLE_JOB --verify --diff --new
- store_artifacts: - store_artifacts:
path: test/screenshotter/new path: test/screenshotter/new

160
cli.js
View File

@@ -1,103 +1,67 @@
#!/usr/bin/env node #!/usr/bin/env node
// Simple CLI for KaTeX. // Simple CLI for KaTeX.
// Reads TeX from stdin, outputs HTML to stdout. // Reads TeX from stdin, outputs HTML to stdout.
// To run this from the repository, you must first build KaTeX by running
// `npm install` and `npm run build`.
/* eslint no-console:0 */ /* eslint no-console:0 */
const katex = require("./"); let katex;
try {
katex = require("./");
} catch (e) {
console.error(
"KaTeX could not import, likely because dist/katex.js is missing.");
console.error("Please run 'npm install' and 'npm run build' before running");
console.error("cli.js from the KaTeX repository.");
console.error();
throw e;
}
const {version} = require("./package.json");
const fs = require("fs"); const fs = require("fs");
const options = require("nomnom") const options = require("commander")
.option("displayMode", { .version(version)
full: "display-mode", .option("-d, --display-mode",
abbr: "d", "Render math in display mode, which puts the math in display style " +
flag: true, "(so \\int and \\sum are large, for example), and centers the math " +
default: false, "on the page on its own line.")
help: "If true the math will be rendered in display " + .option("-t, --no-throw-on-error",
"mode, which will put the math in display style " + "Render errors (in the color given by --error-color) instead of " +
"(so \\int and \\sum are large, for example), and " + "throwing a ParseError exception when encountering an error.")
"will center the math on the page on its own line.", .option("-c, --error-color <color>",
}) "A color string given in the format 'rgb' or 'rrggbb' (no #). " +
.option("throwOnError", { "This option determines the color of errors rendered by the -t option.",
full: "no-throw-on-error", "#cc0000",
abbr: "t", (color) => "#" + color)
flag: true, .option("-b, --color-is-text-color",
default: true, "Makes \\color behave like LaTeX's 2-argument \\textcolor, " +
transform: function(t) { "instead of LaTeX's one-argument \\color mode change.")
return !t; .option("-S, --strict",
}, "Turn on strict / LaTeX faithfulness mode, which throws an error " +
help: "If true, KaTeX will throw a ParseError when it " + "if the input uses features that are not supported by LaTeX")
"encounters an unsupported command. If false, KaTeX " + .option("-s, --max-size <n>",
"will render the unsupported command as text in the " + "If non-zero, all user-specified sizes, e.g. in " +
"color given by errorColor.", "\\rule{500em}{500em}, will be capped to maxSize ems. " +
}) "Otherwise, elements and spaces can be arbitrarily large",
.option("errorColor", { 0, parseInt)
full: "error-color", .option("-e, --max-expand <n>",
abbr: "c", "Limit the number of macro expansions to the specified number, to " +
metavar: "color", "prevent e.g. infinite macro loops. If set to Infinity, the macro " +
default: "#cc0000", "expander will try to fully expand as in LaTeX.",
transform: function(color) { (n) => (n === "Infinity" ? Infinity : parseInt(n)))
return "#" + color; .option("-m, --macro <def>",
}, "Define custom macro of the form '\\foo:expansion' (use multiple -m " +
help: "A color string given in the format 'rgb' or 'rrggbb'. " + "arguments for multiple macros).",
"This option determines the color which unsupported " + (def, defs) => {
"commands are rendered in.", defs.push(def);
}) return defs;
.option("colorIsTextColor", { }, [])
full: "color-is-text-color", .option("-f, --macro-file <path>",
abbr: "b", "Read macro definitions, one per line, from the given file.")
flag: true, .option("-i, --input <path>", "Read LaTeX input from the given file.")
default: false, .option("-o, --output <path>", "Write html output to the given file.")
help: "Makes \\color behave like LaTeX's 2-argument \\textcolor, " + .parse(process.argv);
"instead of LaTeX's one-argument \\color mode change.",
})
.option("unicodeTextInMathMode", {
full: "unicode-text-in-math-mode",
abbr: "u",
flag: true,
default: false,
help: "Add support for unicode text characters in math mode.",
})
.option("maxSize", {
full: "max-size",
abbr: "s",
metavar: "size",
default: 0,
help: "If non-zero, all user-specified sizes, e.g. in " +
"\\rule{500em}{500em}, will be capped to maxSize ems. " +
"Otherwise, elements and spaces can be arbitrarily large",
})
.option("macros", {
full: "macro",
abbr: "m",
metavar: "macro:expansion",
list: true,
default: [],
help: "A custom macro. Each macro is a property with a name " +
"like \\name which maps to a string that " +
"describes the expansion of the macro.",
})
.option("macroFile", {
full: "macro-file",
abbr: "f",
metavar: "path",
default: null,
help: "Read macro definitions from the given file.",
})
.option("inputFile", {
full: "input",
abbr: "i",
metavar: "path",
default: null,
help: "Read LaTeX input from the given file.",
})
.option("outputFile", {
full: "output",
abbr: "o",
metavar: "path",
default: null,
help: "Write html output to the given file.",
})
.parse();
function readMacros() { function readMacros() {
@@ -114,7 +78,7 @@ function readMacros() {
function splitMacros(macroStrings) { function splitMacros(macroStrings) {
// Override macros from macro file (if any) // Override macros from macro file (if any)
// with macros from command line (if any) // with macros from command line (if any)
macroStrings = macroStrings.concat(options.macros); macroStrings = macroStrings.concat(options.macro);
const macros = {}; const macros = {};
@@ -132,8 +96,8 @@ function splitMacros(macroStrings) {
function readInput() { function readInput() {
let input = ""; let input = "";
if (options.inputFile) { if (options.input) {
fs.readFile(options.inputFile, "utf-8", function(err, data) { fs.readFile(options.input, "utf-8", function(err, data) {
if (err) {throw err;} if (err) {throw err;}
input = data.toString(); input = data.toString();
writeOutput(input); writeOutput(input);
@@ -152,8 +116,8 @@ function readInput() {
function writeOutput(input) { function writeOutput(input) {
const output = katex.renderToString(input, options) + "\n"; const output = katex.renderToString(input, options) + "\n";
if (options.outputFile) { if (options.output) {
fs.writeFile(options.outputFile, output, function(err) { fs.writeFile(options.output, output, function(err) {
if (err) { if (err) {
return console.log(err); return console.log(err);
} }

View File

@@ -27,74 +27,33 @@ const newDir = path.normalize(
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// Process command line arguments // Process command line arguments
const opts = require("nomnom") const opts = require("commander")
.option("browser", { .option("-b, --browser <firefox|chrome>",
abbr: "b", "Name of the browser to use", "firefox")
"default": "firefox", .option("-c, --container <id>",
help: "Name of the browser to use", "Name or ID of a running docker container to contact")
}) .option("--selenium-url <url>", "Full URL of the Selenium web driver")
.option("container", { .option("--selenium-ip <ip>", "IP address of the Selenium web driver")
abbr: "c", .option("--selenium-port <n>",
type: "string", "Port number of the Selenium web driver", 4444, parseInt)
help: "Name or ID of a running docker container to contact", .option("--katex-url <url>", "Full URL of the KaTeX development server")
}) .option("--katex-ip <ip>", "IP address of the KaTeX development server")
.option("seleniumURL", { .option("--katex-port <n>",
full: "selenium-url", "Port number of the KaTeX development server", parseInt)
help: "Full URL of the Selenium web driver", .option("-i, --include <tests>",
}) "Comma-separated list of test cases to process")
.option("seleniumIP", { .option("-x, --exclude <tests>",
full: "selenium-ip", "Comma-separated list of test cases to exclude")
help: "IP address of the Selenium web driver", .option("--reload", "Reload page for each test")
}) .option("--verify", "Check whether screenshot matches current file content")
.option("seleniumPort", { .option("--diff", "With `--verify`, produce image diffs when match fails")
full: "selenium-port", .option("--new",
"default": 4444, "With `--verify`, generate new screenshots when match fails")
help: "Port number of the Selenium web driver", .option("--attempts <n>",
}) "Retry this many times before reporting failure", 5, parseInt)
.option("katexURL", { .option("--wait <secs>",
full: "katex-url", "Wait this many seconds between page load and screenshot", parseFloat)
help: "Full URL of the KaTeX development server", .parse(process.argv);
})
.option("katexIP", {
full: "katex-ip",
help: "Full URL of the KaTeX development server",
})
.option("katexPort", {
full: "katex-port",
help: "Port number of the KaTeX development server",
})
.option("include", {
abbr: "i",
help: "Comma-separated list of test cases to process",
})
.option("exclude", {
abbr: "x",
help: "Comma-separated list of test cases to exclude",
})
.option("reload", {
flag: true,
help: "Reload page for each test",
})
.option("verify", {
flag: true,
help: "Check whether screenshot matches current file content",
})
.option("diff", {
flag: true,
help: "With `--verify`, produce image diffs when match fails",
})
.option("new", {
flag: true,
help: "With `--verify`, generate new screenshots when match fails",
})
.option("attempts", {
help: "Retry this many times before reporting failure",
"default": 5,
})
.option("wait", {
help: "Wait this many seconds between page load and screenshot",
})
.parse();
let listOfCases; let listOfCases;
if (opts.include) { if (opts.include) {
@@ -109,11 +68,11 @@ if (opts.exclude) {
}); });
} }
let seleniumURL = opts.seleniumURL; let seleniumURL = opts.seleniumUrl;
let seleniumIP = opts.seleniumIP; let seleniumIP = opts.seleniumIp;
let seleniumPort = opts.seleniumPort; let seleniumPort = opts.seleniumPort;
let katexURL = opts.katexURL; let katexURL = opts.katexUrl;
let katexIP = opts.katexIP; let katexIP = opts.katexIp;
let katexPort = opts.katexPort; let katexPort = opts.katexPort;
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////

1511
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -81,7 +81,7 @@
"dist:zip": "cd dist && tar czf ../katex.tar.gz * && zip -rq ../katex.zip *" "dist:zip": "cd dist && tar czf ../katex.tar.gz * && zip -rq ../katex.zip *"
}, },
"dependencies": { "dependencies": {
"nomnom": "^1.8.1" "commander": "^2.16.0"
}, },
"husky": { "husky": {
"hooks": { "hooks": {

View File

@@ -4,12 +4,10 @@
const fs = require("fs"); const fs = require("fs");
const childProcess = require("child_process"); const childProcess = require("child_process");
const opts = require("nomnom") const opts = require("commander")
.option("spacing", { .option("-s, --spacing",
flag: true, "Print mismatches involving spacing commands")
help: "Print mismatches involving spacing commands", .parse(process.argv);
})
.parse();
const symbols = require("../src/symbols"); const symbols = require("../src/symbols");
const keys = Object.keys(symbols.math); const keys = Object.keys(symbols.math);