1 | #!/usr/bin/env node
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | let katex;
|
10 | try {
|
11 | katex = require("./");
|
12 | } catch (e) {
|
13 | console.error(
|
14 | "KaTeX could not import, likely because dist/katex.js is missing.");
|
15 | console.error("Please run 'yarn' and 'yarn build' before running");
|
16 | console.error("cli.js from the KaTeX repository.");
|
17 | console.error();
|
18 | throw e;
|
19 | }
|
20 | const {version} = require("./package.json");
|
21 | const fs = require("fs");
|
22 |
|
23 | const program = require("commander")
|
24 | .version(version)
|
25 | .option("-d, --display-mode",
|
26 | "Render math in display mode, which puts the math in display style " +
|
27 | "(so \\int and \\sum are large, for example), and centers the math " +
|
28 | "on the page on its own line.")
|
29 | .option("--leqno",
|
30 | "Render display math in leqno style (left-justified tags).")
|
31 | .option("--fleqn",
|
32 | "Render display math flush left.")
|
33 | .option("-t, --no-throw-on-error",
|
34 | "Render errors (in the color given by --error-color) instead of " +
|
35 | "throwing a ParseError exception when encountering an error.")
|
36 | .option("-c, --error-color <color>",
|
37 | "A color string given in the format 'rgb' or 'rrggbb' (no #). " +
|
38 | "This option determines the color of errors rendered by the -t option.",
|
39 | "#cc0000",
|
40 | (color) => "#" + color)
|
41 | .option("-b, --color-is-text-color",
|
42 | "Makes \\color behave like LaTeX's 2-argument \\textcolor, " +
|
43 | "instead of LaTeX's one-argument \\color mode change.")
|
44 | .option("-S, --strict",
|
45 | "Turn on strict / LaTeX faithfulness mode, which throws an error " +
|
46 | "if the input uses features that are not supported by LaTeX")
|
47 | .option("-s, --max-size <n>",
|
48 | "If non-zero, all user-specified sizes, e.g. in " +
|
49 | "\\rule{500em}{500em}, will be capped to maxSize ems. " +
|
50 | "Otherwise, elements and spaces can be arbitrarily large",
|
51 | Infinity, parseInt)
|
52 | .option("-e, --max-expand <n>",
|
53 | "Limit the number of macro expansions to the specified number, to " +
|
54 | "prevent e.g. infinite macro loops. If set to Infinity, the macro " +
|
55 | "expander will try to fully expand as in LaTeX.",
|
56 | (n) => (n === "Infinity" ? Infinity : parseInt(n)))
|
57 | .option("-m, --macro <def>",
|
58 | "Define custom macro of the form '\\foo:expansion' (use multiple -m " +
|
59 | "arguments for multiple macros).",
|
60 | (def, defs) => {
|
61 | defs.push(def);
|
62 | return defs;
|
63 | }, [])
|
64 | .option("-f, --macro-file <path>",
|
65 | "Read macro definitions, one per line, from the given file.")
|
66 | .option("-i, --input <path>", "Read LaTeX input from the given file.")
|
67 | .option("-o, --output <path>", "Write html output to the given file.");
|
68 |
|
69 | if (require.main !== module) {
|
70 | module.exports = program;
|
71 | return;
|
72 | }
|
73 |
|
74 | const options = program.parse(process.argv);
|
75 |
|
76 | function readMacros() {
|
77 | if (options.macroFile) {
|
78 | fs.readFile(options.macroFile, "utf-8", function(err, data) {
|
79 | if (err) {throw err;}
|
80 | splitMacros(data.toString().split('\n'));
|
81 | });
|
82 | } else {
|
83 | splitMacros([]);
|
84 | }
|
85 | }
|
86 |
|
87 | function splitMacros(macroStrings) {
|
88 |
|
89 |
|
90 | macroStrings = macroStrings.concat(options.macro);
|
91 |
|
92 | const macros = {};
|
93 |
|
94 | for (const m of macroStrings) {
|
95 | const i = m.search(":");
|
96 | if (i !== -1) {
|
97 | macros[m.substring(0, i).trim()] = m.substring(i + 1).trim();
|
98 | }
|
99 | }
|
100 |
|
101 | options.macros = macros;
|
102 | readInput();
|
103 | }
|
104 |
|
105 | function readInput() {
|
106 | let input = "";
|
107 |
|
108 | if (options.input) {
|
109 | fs.readFile(options.input, "utf-8", function(err, data) {
|
110 | if (err) {throw err;}
|
111 | input = data.toString();
|
112 | writeOutput(input);
|
113 | });
|
114 | } else {
|
115 | process.stdin.on("data", function(chunk) {
|
116 | input += chunk.toString();
|
117 | });
|
118 |
|
119 | process.stdin.on("end", function() {
|
120 | writeOutput(input);
|
121 | });
|
122 | }
|
123 | }
|
124 |
|
125 | function writeOutput(input) {
|
126 | const output = katex.renderToString(input, options) + "\n";
|
127 |
|
128 | if (options.output) {
|
129 | fs.writeFile(options.output, output, function(err) {
|
130 | if (err) {
|
131 | return console.log(err);
|
132 | }
|
133 | });
|
134 | } else {
|
135 | console.log(output);
|
136 | }
|
137 | }
|
138 |
|
139 | readMacros();
|