const path = require('path'); var katex = require(path.join(__dirname,"third_party/katex/katex.js")) options = require(path.join(__dirname,"third_party/katex/src/Options.js")) var readline = require('readline'); var rl = readline.createInterface({ input: process.stdin, output: process.stdout, terminal: false }); rl.on('line', function(line){ a = line if (line[0] == "%") { line = line.substr(1, line.length - 1); } // line = line.split('%')[0]; line = line.split('\\~').join(' '); for (var i = 0; i < 300; i++) { line = line.replace(/\\>/, " "); // line = line.replace('$', ' '); line = line.replace(/\\label{.*?}/, ""); } if (line.indexOf("matrix") == -1 && line.indexOf("cases")==-1 && line.indexOf("array")==-1 && line.indexOf("begin")==-1) { for (var i = 0; i < 300; i++) { line = line.replace(/\\\\/, "\\,"); } } line = line + " " // global_str is tokenized version (build in parser.js) // norm_str is normalized version build by renderer below. try { if (process.argv[2] == "tokenize") { var tree = katex.__parse(line, {}); console.log(global_str.replace(/\\label { .*? }/, "")); } else { for (var i = 0; i < 300; ++i) { line = line.replace(/{\\rm/, "\\mathrm{"); line = line.replace(/{ \\rm/, "\\mathrm{"); line = line.replace(/\\rm{/, "\\mathrm{"); } var tree = katex.__parse(line, {}); buildExpression(tree, new options({})); for (var i = 0; i < 300; ++i) { norm_str = norm_str.replace('SSSSSS', '$'); norm_str = norm_str.replace(' S S S S S S', '$'); } console.log(norm_str.replace(/\\label { .*? }/, "")); } } catch (e) { console.error(line); console.error(norm_str); console.error(e); console.log(""); } global_str = "" norm_str = "" }) // This is a LaTeX AST to LaTeX Renderer (modified version of KaTeX AST-> MathML). norm_str = "" var groupTypes = {}; groupTypes.mathord = function(group, options) { if (options.font == "mathrm"){ for (i = 0; i < group.value.length; ++i ) { if (group.value[i] == " ") { norm_str = norm_str + group.value[i] + "\; "; } else { norm_str = norm_str + group.value[i] + " "; } } } else { norm_str = norm_str + group.value + " "; } }; groupTypes.textord = function(group, options) { norm_str = norm_str + group.value + " "; }; groupTypes.bin = function(group) { norm_str = norm_str + group.value + " "; }; groupTypes.rel = function(group) { norm_str = norm_str + group.value + " "; }; groupTypes.open = function(group) { norm_str = norm_str + group.value + " "; }; groupTypes.close = function(group) { norm_str = norm_str + group.value + " "; }; groupTypes.inner = function(group) { norm_str = norm_str + group.value + " "; }; groupTypes.punct = function(group) { norm_str = norm_str + group.value + " "; }; groupTypes.ordgroup = function(group, options) { norm_str = norm_str + "{ "; buildExpression(group.value, options); norm_str = norm_str + "} "; }; groupTypes.text = function(group, options) { norm_str = norm_str + "\\mathrm { "; buildExpression(group.value.body, options); norm_str = norm_str + "} "; }; groupTypes.color = function(group, options) { var inner = buildExpression(group.value.value, options); var node = new mathMLTree.MathNode("mstyle", inner); node.setAttribute("mathcolor", group.value.color); return node; }; groupTypes.supsub = function(group, options) { buildGroup(group.value.base, options); if (group.value.sub) { norm_str = norm_str + "_ "; if (group.value.sub.type != 'ordgroup') { norm_str = norm_str + " { "; buildGroup(group.value.sub, options); norm_str = norm_str + "} "; } else { buildGroup(group.value.sub, options); } } if (group.value.sup) { norm_str = norm_str + "^ "; if (group.value.sup.type != 'ordgroup') { norm_str = norm_str + " { "; buildGroup(group.value.sup, options); norm_str = norm_str + "} "; } else { buildGroup(group.value.sup, options); } } }; groupTypes.genfrac = function(group, options) { if (!group.value.hasBarLine) { norm_str = norm_str + "\\binom "; } else { norm_str = norm_str + "\\frac "; } buildGroup(group.value.numer, options); buildGroup(group.value.denom, options); }; groupTypes.array = function(group, options) { norm_str = norm_str + "\\begin{" + group.value.style + "} "; if (group.value.style == "array" || group.value.style == "tabular" || group.value.style == "tabularx") { norm_str = norm_str + "{ "; if (group.value.cols) { group.value.cols.map(function(start) { if (start) { if (start.type == "align") { norm_str = norm_str + start.align + " "; } else if (start.type == "separator") { norm_str = norm_str + start.separator + " "; } } }); } else { group.value.body[0].map(function(start) { norm_str = norm_str + "c "; } ); } norm_str = norm_str + "} "; } group.value.body.map(function(row) { if (row.length > 1 || row[0].value.length > 0) { if (row[0].value[0] && row[0].value[0].value == "\\hline") { norm_str = norm_str + "\\hline "; row[0].value = row[0].value.slice(1); } out = row.map(function(cell) { buildGroup(cell, options); norm_str = norm_str + "& "; }); norm_str = norm_str.substring(0, norm_str.length-2) + "\\\\ "; } }); norm_str = norm_str + "\\end{" + group.value.style + "} "; }; groupTypes.sqrt = function(group, options) { var node; if (group.value.index) { norm_str = norm_str + "\\sqrt [ " + group.value.index + " ] "; buildGroup(group.value.body, options); } else { norm_str = norm_str + "\\sqrt "; buildGroup(group.value.body, options); } }; groupTypes.leftright = function(group, options) { norm_str = norm_str + "\\left" + group.value.left + " "; buildExpression(group.value.body, options); norm_str = norm_str + "\\right" + group.value.right + " "; }; groupTypes.accent = function(group, options) { if (group.value.base.type != 'ordgroup') { norm_str = norm_str + group.value.accent + " { "; buildGroup(group.value.base, options); norm_str = norm_str + "} "; } else { norm_str = norm_str + group.value.accent + " "; buildGroup(group.value.base, options); } }; groupTypes.spacing = function(group) { var node; if (group.value == " ") { norm_str = norm_str + "~ "; } else { norm_str = norm_str + group.value + " "; } return node; }; groupTypes.op = function(group) { var node; // TODO(emily): handle big operators using the `largeop` attribute if (group.value.symbol) { // This is a symbol. Just add the symbol. norm_str = norm_str + group.value.body + " "; } else { if (group.value.limits == false) { norm_str = norm_str + "\\\operatorname { "; } else { norm_str = norm_str + "\\\operatorname* { "; } for (i = 1; i < group.value.body.length; ++i ) { norm_str = norm_str + group.value.body[i] + " "; } norm_str = norm_str + "} "; } }; groupTypes.katex = function(group) { var node = new mathMLTree.MathNode( "mtext", [new mathMLTree.TextNode("KaTeX")]); return node; }; groupTypes.font = function(group, options) { var font = group.value.font; if (font == "mbox" || font == "hbox") { font = "mathrm"; } norm_str = norm_str + "\\" + font + " "; buildGroup(group.value.body, options.withFont(font)); }; groupTypes.delimsizing = function(group) { var children = []; norm_str = norm_str + group.value.funcName + " " + group.value.value + " "; }; groupTypes.styling = function(group, options) { norm_str = norm_str + " " + group.value.original + " "; buildExpression(group.value.value, options); }; groupTypes.sizing = function(group, options) { if (group.value.original == "\\rm") { norm_str = norm_str + "\\mathrm { "; buildExpression(group.value.value, options.withFont("mathrm")); norm_str = norm_str + "} "; } else { norm_str = norm_str + " " + group.value.original + " "; buildExpression(group.value.value, options); } }; groupTypes.overline = function(group, options) { norm_str = norm_str + "\\overline { "; buildGroup(group.value.body, options); norm_str = norm_str + "} "; norm_str = norm_str; }; groupTypes.underline = function(group, options) { norm_str = norm_str + "\\underline { "; buildGroup(group.value.body, options); norm_str = norm_str + "} "; norm_str = norm_str; }; groupTypes.rule = function(group) { norm_str = norm_str + "\\rule { "+group.value.width.number+" "+group.value.width.unit+" } { "+group.value.height.number+" "+group.value.height.unit+ " } "; }; groupTypes.llap = function(group, options) { norm_str = norm_str + "\\llap "; buildGroup(group.value.body, options); }; groupTypes.rlap = function(group, options) { norm_str = norm_str + "\\rlap "; buildGroup(group.value.body, options); }; groupTypes.phantom = function(group, options, prev) { norm_str = norm_str + "\\phantom { "; buildExpression(group.value.value, options); norm_str = norm_str + "} "; }; /** * Takes a list of nodes, builds them, and returns a list of the generated * MathML nodes. A little simpler than the HTML version because we don't do any * previous-node handling. */ var buildExpression = function(expression, options) { var groups = []; for (var i = 0; i < expression.length; i++) { var group = expression[i]; buildGroup(group, options); } // console.log(norm_str); // return groups; }; /** * Takes a group from the parser and calls the appropriate groupTypes function * on it to produce a MathML node. */ var buildGroup = function(group, options) { if (groupTypes[group.type]) { groupTypes[group.type](group, options); } else { throw new ParseError( "Got group of unknown type: '" + group.type + "'"); } };