Turn var into const or let

This commit is contained in:
Martin von Gagern 2017-01-07 02:25:50 +01:00 committed by Kevin Barabash
parent 9b565a6375
commit bd9db332d2
33 changed files with 1308 additions and 1318 deletions

View File

@ -35,6 +35,7 @@
"no-unreachable": 2,
"no-unused-vars": [2, {"args": "none", "varsIgnorePattern": "^_*$"}],
"no-useless-call": 2,
"no-var": 2,
"no-with": 2,
"one-var": [2, "never"],
"prefer-const": 2,
@ -52,9 +53,6 @@
// We've decided explicitly not to care about this.
"arrow-parens": 0,
// ---------------------------------------
// Stuff that's disabled for now, but maybe shouldn't be.
// disabled because KaTeX doesn't use ES6
"no-var": 0,
// TODO(csilvers): enable these if/when community agrees on it.
"prefer-arrow-callback": 0,
"object-curly-spacing": [0, "always"],

10
cli.js
View File

@ -3,11 +3,11 @@
// Reads TeX from stdin, outputs HTML to stdout.
/* eslint no-console:0 */
var katex = require("./");
var input = "";
const katex = require("./");
let input = "";
// Skip the first two args, which are just "node" and "cli.js"
var args = process.argv.slice(2);
const args = process.argv.slice(2);
if (args.indexOf("--help") !== -1) {
console.log(process.argv[0] + " " + process.argv[1] +
@ -26,7 +26,7 @@ process.stdin.on("data", function(chunk) {
});
process.stdin.on("end", function() {
var options = { displayMode: args.indexOf("--display-mode") !== -1 };
var output = katex.renderToString(input, options);
const options = { displayMode: args.indexOf("--display-mode") !== -1 };
const output = katex.renderToString(input, options);
console.log(output);
});

View File

@ -4,21 +4,21 @@
/* global it: false */
/* global describe: false */
var splitAtDelimiters = require("./splitAtDelimiters");
const splitAtDelimiters = require("./splitAtDelimiters");
beforeEach(function() {
jasmine.addMatchers({
toSplitInto: function() {
return {
compare: function(actual, left, right, result) {
var message = {
const message = {
pass: true,
message: "'" + actual + "' split correctly",
};
var startData = [{type: "text", data: actual}];
const startData = [{type: "text", data: actual}];
var split =
const split =
splitAtDelimiters(startData, left, right, false);
if (split.length !== result.length) {
@ -30,12 +30,12 @@ beforeEach(function() {
return message;
}
for (var i = 0; i < split.length; i++) {
var real = split[i];
var correct = result[i];
for (let i = 0; i < split.length; i++) {
const real = split[i];
const correct = result[i];
var good = true;
var diff;
let good = true;
let diff;
if (real.type !== correct.type) {
good = false;
@ -189,7 +189,7 @@ describe("A delimiter splitter", function() {
});
it("remembers which delimiters are display-mode", function() {
var startData = [{type: "text", data: "hello ( world ) boo"}];
const startData = [{type: "text", data: "hello ( world ) boo"}];
expect(splitAtDelimiters(startData, "(", ")", true)).toEqual(
[
@ -201,7 +201,7 @@ describe("A delimiter splitter", function() {
});
it("works with more than one start datum", function() {
var startData = [
const startData = [
{type: "text", data: "hello ( world ) boo"},
{type: "math", data: "math", rawData: "(math)", display: true},
{type: "text", data: "hello ( world ) boo"},
@ -222,7 +222,7 @@ describe("A delimiter splitter", function() {
});
it("doesn't do splitting inside of math nodes", function() {
var startData = [
const startData = [
{type: "text", data: "hello ( world ) boo"},
{type: "math", data: "hello ( world ) boo",
rawData: "(hello ( world ) boo)", display: true},

View File

@ -1,12 +1,12 @@
/* eslint no-console:0 */
/* global katex */
var splitAtDelimiters = require("./splitAtDelimiters");
const splitAtDelimiters = require("./splitAtDelimiters");
var splitWithDelimiters = function(text, delimiters) {
var data = [{type: "text", data: text}];
for (var i = 0; i < delimiters.length; i++) {
var delimiter = delimiters[i];
const splitWithDelimiters = function(text, delimiters) {
let data = [{type: "text", data: text}];
for (let i = 0; i < delimiters.length; i++) {
const delimiter = delimiters[i];
data = splitAtDelimiters(
data, delimiter.left, delimiter.right,
delimiter.display || false);
@ -14,17 +14,17 @@ var splitWithDelimiters = function(text, delimiters) {
return data;
};
var renderMathInText = function(text, delimiters) {
var data = splitWithDelimiters(text, delimiters);
const renderMathInText = function(text, delimiters) {
const data = splitWithDelimiters(text, delimiters);
var fragment = document.createDocumentFragment();
const fragment = document.createDocumentFragment();
for (var i = 0; i < data.length; i++) {
for (let i = 0; i < data.length; i++) {
if (data[i].type === "text") {
fragment.appendChild(document.createTextNode(data[i].data));
} else {
var span = document.createElement("span");
var math = data[i].data;
const span = document.createElement("span");
const math = data[i].data;
try {
katex.render(math, span, {
displayMode: data[i].display,
@ -48,17 +48,17 @@ var renderMathInText = function(text, delimiters) {
return fragment;
};
var renderElem = function(elem, delimiters, ignoredTags) {
for (var i = 0; i < elem.childNodes.length; i++) {
var childNode = elem.childNodes[i];
const renderElem = function(elem, delimiters, ignoredTags) {
for (let i = 0; i < elem.childNodes.length; i++) {
const childNode = elem.childNodes[i];
if (childNode.nodeType === 3) {
// Text node
var frag = renderMathInText(childNode.textContent, delimiters);
const frag = renderMathInText(childNode.textContent, delimiters);
i += frag.childNodes.length - 1;
elem.replaceChild(frag, childNode);
} else if (childNode.nodeType === 1) {
// Element node
var shouldRender = ignoredTags.indexOf(
const shouldRender = ignoredTags.indexOf(
childNode.nodeName.toLowerCase()) === -1;
if (shouldRender) {
@ -69,7 +69,7 @@ var renderElem = function(elem, delimiters, ignoredTags) {
}
};
var defaultOptions = {
const defaultOptions = {
delimiters: [
{left: "$$", right: "$$", display: true},
{left: "\\[", right: "\\]", display: true},
@ -83,11 +83,12 @@ var defaultOptions = {
],
};
var extend = function(obj) {
const extend = function(obj) {
// Adapted from underscore.js' `_.extend`. See LICENSE.txt for license.
var source;
var prop;
for (var i = 1, length = arguments.length; i < length; i++) {
let source;
let prop;
const length = arguments.length;
for (let i = 1; i < length; i++) {
source = arguments[i];
for (prop in source) {
if (Object.prototype.hasOwnProperty.call(source, prop)) {
@ -98,7 +99,7 @@ var extend = function(obj) {
return obj;
};
var renderMathInElement = function(elem, options) {
const renderMathInElement = function(elem, options) {
if (!elem) {
throw new Error("No element provided to render");
}

View File

@ -1,14 +1,14 @@
/* eslint no-constant-condition:0 */
var findEndOfMath = function(delimiter, text, startIndex) {
const findEndOfMath = function(delimiter, text, startIndex) {
// Adapted from
// https://github.com/Khan/perseus/blob/master/src/perseus-markdown.jsx
var index = startIndex;
var braceLevel = 0;
let index = startIndex;
let braceLevel = 0;
var delimLength = delimiter.length;
const delimLength = delimiter.length;
while (index < text.length) {
var character = text[index];
const character = text[index];
if (braceLevel <= 0 &&
text.slice(index, index + delimLength) === delimiter) {
@ -27,16 +27,16 @@ var findEndOfMath = function(delimiter, text, startIndex) {
return -1;
};
var splitAtDelimiters = function(startData, leftDelim, rightDelim, display) {
var finalData = [];
const splitAtDelimiters = function(startData, leftDelim, rightDelim, display) {
const finalData = [];
for (var i = 0; i < startData.length; i++) {
for (let i = 0; i < startData.length; i++) {
if (startData[i].type === "text") {
var text = startData[i].data;
const text = startData[i].data;
var lookingForLeft = true;
var currIndex = 0;
var nextIndex;
let lookingForLeft = true;
let currIndex = 0;
let nextIndex;
nextIndex = text.indexOf(leftDelim);
if (nextIndex !== -1) {

View File

@ -1,27 +1,27 @@
/* eslint no-console:0, prefer-spread:0 */
"use strict";
var childProcess = require("child_process");
var fs = require("fs");
var http = require("http");
var jspngopt = require("jspngopt");
var net = require("net");
var os = require("os");
var pako = require("pako");
var path = require("path");
var selenium = require("selenium-webdriver");
var firefox = require("selenium-webdriver/firefox");
const childProcess = require("child_process");
const fs = require("fs");
const http = require("http");
const jspngopt = require("jspngopt");
const net = require("net");
const os = require("os");
const pako = require("pako");
const path = require("path");
const selenium = require("selenium-webdriver");
const firefox = require("selenium-webdriver/firefox");
var app = require("../../server");
var data = require("../../test/screenshotter/ss_data");
const app = require("../../server");
const data = require("../../test/screenshotter/ss_data");
var dstDir = path.normalize(
const dstDir = path.normalize(
path.join(__dirname, "..", "..", "test", "screenshotter", "images"));
//////////////////////////////////////////////////////////////////////
// Process command line arguments
var opts = require("nomnom")
const opts = require("nomnom")
.option("browser", {
abbr: "b",
"default": "firefox",
@ -74,25 +74,25 @@ var opts = require("nomnom")
})
.parse();
var listOfCases;
let listOfCases;
if (opts.include) {
listOfCases = opts.include.split(",");
} else {
listOfCases = Object.keys(data);
}
if (opts.exclude) {
var exclude = opts.exclude.split(",");
const exclude = opts.exclude.split(",");
listOfCases = listOfCases.filter(function(key) {
return exclude.indexOf(key) === -1;
});
}
var seleniumURL = opts.seleniumURL;
var seleniumIP = opts.seleniumIP;
var seleniumPort = opts.seleniumPort;
var katexURL = opts.katexURL;
var katexIP = opts.katexIP;
var katexPort = opts.katexPort;
let seleniumURL = opts.seleniumURL;
let seleniumIP = opts.seleniumIP;
let seleniumPort = opts.seleniumPort;
let katexURL = opts.katexURL;
let katexIP = opts.katexIP;
let katexPort = opts.katexPort;
//////////////////////////////////////////////////////////////////////
// Work out connection to selenium docker container
@ -107,15 +107,15 @@ function check(err) {
}
function cmd() {
var args = Array.prototype.slice.call(arguments);
var cmd = args.shift();
const args = Array.prototype.slice.call(arguments);
const cmd = args.shift();
return childProcess.execFileSync(
cmd, args, { encoding: "utf-8" }).replace(/\n$/, "");
}
function guessDockerIPs() {
if (process.env.DOCKER_MACHINE_NAME) {
var machine = process.env.DOCKER_MACHINE_NAME;
const machine = process.env.DOCKER_MACHINE_NAME;
seleniumIP = seleniumIP || cmd("docker-machine", "ip", machine);
katexIP = katexIP || cmd("docker-machine", "ssh", machine,
"echo ${SSH_CONNECTION%% *}");
@ -124,7 +124,7 @@ function guessDockerIPs() {
try {
// When using boot2docker, seleniumIP and katexIP are distinct.
seleniumIP = seleniumIP || cmd("boot2docker", "ip");
var config = cmd("boot2docker", "config");
let config = cmd("boot2docker", "config");
config = (/^HostIP = "(.*)"$/m).exec(config);
if (!config) {
console.error("Failed to find HostIP");
@ -142,7 +142,7 @@ function guessDockerIPs() {
return;
}
// Native Docker on Linux or remote Docker daemon or similar
var gatewayIP = cmd("docker", "inspect",
const gatewayIP = cmd("docker", "inspect",
"-f", "{{.NetworkSettings.Gateway}}", opts.container);
seleniumIP = seleniumIP || gatewayIP;
katexIP = katexIP || gatewayIP;
@ -165,22 +165,22 @@ if (seleniumURL) {
}
process.nextTick(startServer);
var attempts = 0;
let attempts = 0;
//////////////////////////////////////////////////////////////////////
// Start up development server
var devServer = null;
var minPort = 32768;
var maxPort = 61000;
let devServer = null;
const minPort = 32768;
const maxPort = 61000;
function startServer() {
if (katexURL || katexPort) {
process.nextTick(tryConnect);
return;
}
var port = Math.floor(Math.random() * (maxPort - minPort)) + minPort;
var server = http.createServer(app).listen(port);
const port = Math.floor(Math.random() * (maxPort - minPort)) + minPort;
const server = http.createServer(app).listen(port);
server.once("listening", function() {
devServer = server;
katexPort = port;
@ -206,7 +206,7 @@ function tryConnect() {
process.nextTick(buildDriver);
return;
}
var sock = net.connect({
const sock = net.connect({
host: seleniumIP,
port: +seleniumPort,
});
@ -225,21 +225,21 @@ function tryConnect() {
//////////////////////////////////////////////////////////////////////
// Build the web driver
var driver;
let driver;
function buildDriver() {
var builder = new selenium.Builder().forBrowser(opts.browser);
var ffProfile = new firefox.Profile();
const builder = new selenium.Builder().forBrowser(opts.browser);
const ffProfile = new firefox.Profile();
ffProfile.setPreference(
"browser.startup.homepage_override.mstone", "ignore");
ffProfile.setPreference("browser.startup.page", 0);
var ffOptions = new firefox.Options().setProfile(ffProfile);
const ffOptions = new firefox.Options().setProfile(ffProfile);
builder.setFirefoxOptions(ffOptions);
if (seleniumURL) {
builder.usingServer(seleniumURL);
}
driver = builder.build();
driver.manage().timeouts().setScriptTimeout(3000).then(function() {
var html = '<!DOCTYPE html>' +
let html = '<!DOCTYPE html>' +
'<html><head><style type="text/css">html,body{' +
'width:100%;height:100%;margin:0;padding:0;overflow:hidden;' +
'}</style></head><body><p>Test</p></body></html>';
@ -253,15 +253,15 @@ function buildDriver() {
//////////////////////////////////////////////////////////////////////
// Set the screen size
var targetW = 1024;
var targetH = 768;
const targetW = 1024;
const targetH = 768;
function setSize(reqW, reqH) {
return driver.manage().window().setSize(reqW, reqH).then(function() {
return driver.takeScreenshot();
}).then(function(img) {
img = imageDimensions(img);
var actualW = img.width;
var actualH = img.height;
const actualW = img.width;
const actualH = img.height;
if (actualW === targetW && actualH === targetH) {
findHostIP();
return;
@ -274,7 +274,7 @@ function setSize(reqW, reqH) {
}
function imageDimensions(img) {
var buf = new Buffer(img, "base64");
const buf = new Buffer(img, "base64");
return {
buf: buf,
width: buf.readUInt32BE(16),
@ -312,13 +312,13 @@ function findHostIP() {
});
// Next, enumerate all network addresses
var ips = [];
var devs = os.networkInterfaces();
for (var dev in devs) {
const ips = [];
const devs = os.networkInterfaces();
for (const dev in devs) {
if (devs.hasOwnProperty(dev)) {
var addrs = devs[dev];
for (var i = 0; i < addrs.length; ++i) {
var addr = addrs[i].address;
const addrs = devs[dev];
for (let i = 0; i < addrs.length; ++i) {
let addr = addrs[i].address;
if (/:/.test(addr)) {
addr = "[" + addr + "]";
}
@ -329,7 +329,7 @@ function findHostIP() {
console.log("Looking for host IP among " + ips.join(", "));
// Load a data: URI document which attempts to contact each of these IPs
var html = "<!doctype html>\n<html><body>\n";
let html = "<!doctype html>\n<html><body>\n";
html += ips.map(function(ip) {
return '<script src="http://' + ip + ':' + katexPort +
'/ss-connect.js?ip=' + encodeURIComponent(ip) +
@ -343,17 +343,17 @@ function findHostIP() {
//////////////////////////////////////////////////////////////////////
// Take the screenshots
var countdown = listOfCases.length;
let countdown = listOfCases.length;
var exitStatus = 0;
var listOfFailed = [];
let exitStatus = 0;
const listOfFailed = [];
function takeScreenshots() {
listOfCases.forEach(takeScreenshot);
}
function takeScreenshot(key) {
var itm = data[key];
const itm = data[key];
if (!itm) {
console.error("Test case " + key + " not known!");
listOfFailed.push(key);
@ -364,14 +364,14 @@ function takeScreenshot(key) {
return;
}
var file = path.join(dstDir, key + "-" + opts.browser + ".png");
var retry = 0;
var loadExpected = null;
let file = path.join(dstDir, key + "-" + opts.browser + ".png");
let retry = 0;
let loadExpected = null;
if (opts.verify) {
loadExpected = promisify(fs.readFile, file);
}
var url = katexURL + "test/screenshotter/test.html?" + itm.query;
const url = katexURL + "test/screenshotter/test.html?" + itm.query;
driver.get(url);
if (opts.wait) {
browserSideWait(1000 * opts.wait);
@ -398,10 +398,10 @@ function takeScreenshot(key) {
loadExpected = promisify(fs.readFile, file);
}
}
var opt = new jspngopt.Optimizer({
const opt = new jspngopt.Optimizer({
pako: pako,
});
var buf = opt.bufferSync(img.buf);
const buf = opt.bufferSync(img.buf);
if (loadExpected) {
return loadExpected.then(function(expected) {
if (!buf.equals(expected)) {
@ -451,8 +451,8 @@ function browserSideWait(milliseconds) {
// Second and later arguments are passed to the function named in the
// first argument, and a callback is added as last argument.
function promisify(f) {
var args = Array.prototype.slice.call(arguments, 1);
var deferred = new selenium.promise.Deferred();
const args = Array.prototype.slice.call(arguments, 1);
const deferred = new selenium.promise.Deferred();
args.push(function(err, val) {
if (err) {
deferred.reject(err);

View File

@ -2,22 +2,22 @@
/* eslint-disable no-console */
"use strict";
var childProcess = require("child_process");
var fs = require("fs");
var path = require("path");
var Q = require("q"); // To debug, pass Q_DEBUG=1 in the environment
var pngparse = require("pngparse");
var fft = require("ndarray-fft");
var ndarray = require("ndarray-fft/node_modules/ndarray");
const childProcess = require("child_process");
const fs = require("fs");
const path = require("path");
const Q = require("q"); // To debug, pass Q_DEBUG=1 in the environment
const pngparse = require("pngparse");
const fft = require("ndarray-fft");
const ndarray = require("ndarray-fft/node_modules/ndarray");
var data = require("../../test/screenshotter/ss_data");
const data = require("../../test/screenshotter/ss_data");
// Adapt node functions to Q promises
var readFile = Q.denodeify(fs.readFile);
var writeFile = Q.denodeify(fs.writeFile);
var mkdir = Q.denodeify(fs.mkdir);
const readFile = Q.denodeify(fs.readFile);
const writeFile = Q.denodeify(fs.writeFile);
const mkdir = Q.denodeify(fs.mkdir);
var todo;
let todo;
if (process.argv.length > 2) {
todo = process.argv.slice(2);
} else {
@ -27,23 +27,23 @@ if (process.argv.length > 2) {
}
// Dimensions used when we do the FFT-based alignment computation
var alignWidth = 2048; // should be at least twice the width resp. height
var alignHeight = 2048; // of the screenshots, and a power of two.
const alignWidth = 2048; // should be at least twice the width resp. height
const alignHeight = 2048; // of the screenshots, and a power of two.
// Compute required resolution to match test.html. 16px default font,
// scaled to 4em in test.html, and to 1.21em in katex.css. Corresponding
// LaTeX font size is 10pt. There are 72.27pt per inch.
var pxPerEm = 16 * 4 * 1.21;
var pxPerPt = pxPerEm / 10;
var dpi = pxPerPt * 72.27;
const pxPerEm = 16 * 4 * 1.21;
const pxPerPt = pxPerEm / 10;
const dpi = pxPerPt * 72.27;
var tmpDir = "/tmp/texcmp";
var ssDir = path.normalize(
const tmpDir = "/tmp/texcmp";
const ssDir = path.normalize(
path.join(__dirname, "..", "..", "test", "screenshotter"));
var imagesDir = path.join(ssDir, "images");
var teximgDir = path.join(ssDir, "tex");
var diffDir = path.join(ssDir, "diff");
var template;
const imagesDir = path.join(ssDir, "images");
const teximgDir = path.join(ssDir, "tex");
const diffDir = path.join(ssDir, "diff");
let template;
Q.all([
readFile(path.join(ssDir, "test.tex"), "utf-8"),
@ -58,8 +58,8 @@ Q.all([
// Process a single test case: rasterize, then create diff
function processTestCase(key) {
var itm = data[key];
var tex = "$" + itm.tex + "$";
const itm = data[key];
let tex = "$" + itm.tex + "$";
if (itm.display) {
tex = "\\[" + itm.tex + "\\]";
}
@ -70,14 +70,14 @@ function processTestCase(key) {
tex = tex + itm.post.replace("<br>", "\\\\");
}
tex = template.replace(/\$.*\$/, tex.replace(/\$/g, "$$$$"));
var texFile = path.join(tmpDir, key + ".tex");
var pdfFile = path.join(tmpDir, key + ".pdf");
var pngFile = path.join(teximgDir, key + "-pdflatex.png");
var browserFile = path.join(imagesDir, key + "-firefox.png");
var diffFile = path.join(diffDir, key + ".png");
const texFile = path.join(tmpDir, key + ".tex");
const pdfFile = path.join(tmpDir, key + ".pdf");
const pngFile = path.join(teximgDir, key + "-pdflatex.png");
const browserFile = path.join(imagesDir, key + "-firefox.png");
const diffFile = path.join(diffDir, key + ".png");
// Step 1: write key.tex file
var fftLatex = writeFile(texFile, tex).then(function() {
const fftLatex = writeFile(texFile, tex).then(function() {
// Step 2: call "pdflatex key" to create key.pdf
return execFile("pdflatex", [
"-interaction", "nonstopmode", key,
@ -95,24 +95,24 @@ function processTestCase(key) {
return readPNG(pngFile).then(fftImage);
});
// Step 5: apply FFT to reference image as well
var fftBrowser = readPNG(browserFile).then(fftImage);
const fftBrowser = readPNG(browserFile).then(fftImage);
return Q.all([fftBrowser, fftLatex]).spread(function(browser, latex) {
// Now we have the FFT result from both
// Step 6: find alignment which maximizes overlap.
// This uses a FFT-based correlation computation.
var x;
var y;
var real = createMatrix();
var imag = createMatrix();
let x;
let y;
const real = createMatrix();
const imag = createMatrix();
// Step 6a: (real + i*imag) = latex * conjugate(browser)
for (y = 0; y < alignHeight; ++y) {
for (x = 0; x < alignWidth; ++x) {
var br = browser.real.get(y, x);
var bi = browser.imag.get(y, x);
var lr = latex.real.get(y, x);
var li = latex.imag.get(y, x);
const br = browser.real.get(y, x);
const bi = browser.imag.get(y, x);
const lr = latex.real.get(y, x);
const li = latex.imag.get(y, x);
real.set(y, x, br * lr + bi * li);
imag.set(y, x, br * li - bi * lr);
}
@ -122,14 +122,14 @@ function processTestCase(key) {
fft(-1, real, imag);
// Step 6c: find position where the (squared) absolute value is maximal
var offsetX = 0;
var offsetY = 0;
var maxSquaredNorm = -1; // any result is greater than initial value
let offsetX = 0;
let offsetY = 0;
let maxSquaredNorm = -1; // any result is greater than initial value
for (y = 0; y < alignHeight; ++y) {
for (x = 0; x < alignWidth; ++x) {
var or = real.get(y, x);
var oi = imag.get(y, x);
var squaredNorm = or * or + oi * oi;
const or = real.get(y, x);
const oi = imag.get(y, x);
const squaredNorm = or * or + oi * oi;
if (maxSquaredNorm < squaredNorm) {
maxSquaredNorm = squaredNorm;
offsetX = x;
@ -148,12 +148,12 @@ function processTestCase(key) {
console.log("Positioned " + key + ": " + offsetX + ", " + offsetY);
// Step 7: use these offsets to compute difference illustration
var bx = Math.max(offsetX, 0); // browser left padding
var by = Math.max(offsetY, 0); // browser top padding
var lx = Math.max(-offsetX, 0); // latex left padding
var ly = Math.max(-offsetY, 0); // latex top padding
var uw = Math.max(browser.width + bx, latex.width + lx); // union width
var uh = Math.max(browser.height + by, latex.height + ly); // u. height
const bx = Math.max(offsetX, 0); // browser left padding
const by = Math.max(offsetY, 0); // browser top padding
const lx = Math.max(-offsetX, 0); // latex left padding
const ly = Math.max(-offsetY, 0); // latex top padding
const uw = Math.max(browser.width + bx, latex.width + lx); // union w.
const uh = Math.max(browser.height + by, latex.height + ly); // u. h.
return execFile("convert", [
// First image: latex rendering, converted to grayscale and padded
"(", pngFile, "-grayscale", "Rec709Luminance",
@ -187,7 +187,7 @@ function ensureDir(dir) {
// Execute a given command, and return a promise to its output.
// Don't denodeify here, since fail branch needs access to stderr.
function execFile(cmd, args, opts) {
var deferred = Q.defer();
const deferred = Q.defer();
childProcess.execFile(cmd, args, opts, function(err, stdout, stderr) {
if (err) {
console.error("Error executing " + cmd + " " + args.join(" "));
@ -204,9 +204,9 @@ function execFile(cmd, args, opts) {
// Read given file and parse it as a PNG file.
function readPNG(file) {
var deferred = Q.defer();
var onerror = deferred.reject.bind(deferred);
var stream = fs.createReadStream(file);
const deferred = Q.defer();
const onerror = deferred.reject.bind(deferred);
const stream = fs.createReadStream(file);
stream.on("error", onerror);
pngparse.parseStream(stream, function(err, image) {
if (err) {
@ -221,20 +221,19 @@ function readPNG(file) {
// Take a parsed image data structure and apply FFT transformation to it
function fftImage(image) {
var real = createMatrix();
var imag = createMatrix();
var idx = 0;
var nchan = image.channels;
var alphachan = 1 - (nchan % 2);
var colorchan = nchan - alphachan;
for (var y = 0; y < image.height; ++y) {
for (var x = 0; x < image.width; ++x) {
var c;
var v = 0;
for (c = 0; c < colorchan; ++c) {
const real = createMatrix();
const imag = createMatrix();
let idx = 0;
const nchan = image.channels;
const alphachan = 1 - (nchan % 2);
const colorchan = nchan - alphachan;
for (let y = 0; y < image.height; ++y) {
for (let x = 0; x < image.width; ++x) {
let v = 0;
for (let c = 0; c < colorchan; ++c) {
v += 255 - image.data[idx++];
}
for (c = 0; c < alphachan; ++c) {
for (let c = 0; c < alphachan; ++c) {
v += image.data[idx++];
}
real.set(y, x, v);
@ -251,6 +250,6 @@ function fftImage(image) {
// Create a new matrix of preconfigured dimensions, initialized to zero
function createMatrix() {
var array = new Float64Array(alignWidth * alignHeight);
const array = new Float64Array(alignWidth * alignHeight);
return new ndarray(array, [alignWidth, alignHeight]);
}

View File

@ -7,24 +7,24 @@
* errors in the expression, or errors in javascript handling.
*/
var ParseError = require("./src/ParseError");
var Settings = require("./src/Settings");
const ParseError = require("./src/ParseError");
const Settings = require("./src/Settings");
var buildTree = require("./src/buildTree");
var parseTree = require("./src/parseTree");
var utils = require("./src/utils");
const buildTree = require("./src/buildTree");
const parseTree = require("./src/parseTree");
const utils = require("./src/utils");
/**
* Parse and build an expression, and place that expression in the DOM node
* given.
*/
var render = function(expression, baseNode, options) {
let render = function(expression, baseNode, options) {
utils.clearNode(baseNode);
var settings = new Settings(options);
const settings = new Settings(options);
var tree = parseTree(expression, settings);
var node = buildTree(tree, expression, settings).toNode();
const tree = parseTree(expression, settings);
const node = buildTree(tree, expression, settings).toNode();
baseNode.appendChild(node);
};
@ -46,18 +46,18 @@ if (typeof document !== "undefined") {
/**
* Parse and build an expression, and return the markup for that.
*/
var renderToString = function(expression, options) {
var settings = new Settings(options);
const renderToString = function(expression, options) {
const settings = new Settings(options);
var tree = parseTree(expression, settings);
const tree = parseTree(expression, settings);
return buildTree(tree, expression, settings).toMarkup();
};
/**
* Parse an expression and return the parse tree.
*/
var generateParseTree = function(expression, options) {
var settings = new Settings(options);
const generateParseTree = function(expression, options) {
const settings = new Settings(options);
return parseTree(expression, settings);
};

View File

@ -1,14 +1,14 @@
/* eslint no-console:0 */
var fs = require("fs");
var path = require("path");
const fs = require("fs");
const path = require("path");
var babelify = require("babelify");
var browserify = require("browserify");
var express = require("express");
var glob = require("glob");
var less = require("less");
const babelify = require("babelify");
const browserify = require("browserify");
const express = require("express");
const glob = require("glob");
const less = require("less");
var app = express();
const app = express();
if (require.main === module) {
app.use(require("morgan")(
@ -17,7 +17,7 @@ if (require.main === module) {
var serveBrowserified = function(file, standaloneName) {
return function(req, res, next) {
var files;
let files;
if (Array.isArray(file)) {
files = file.map(function(f) { return path.join(__dirname, f); });
} else if (file.indexOf("*") !== -1) {
@ -26,16 +26,16 @@ var serveBrowserified = function(file, standaloneName) {
files = [path.join(__dirname, file)];
}
var options = {
const options = {
transform: [babelify]
};
if (standaloneName) {
options.standalone = standaloneName;
}
var b = browserify(files, options);
var stream = b.bundle();
const b = browserify(files, options);
const stream = b.bundle();
var body = "";
let body = "";
stream.on("data", function(s) { body += s; });
stream.on("error", function(e) { next(e); });
stream.on("end", function() {
@ -59,7 +59,7 @@ app.get("/contrib/auto-render/auto-render.js",
"renderMathInElement"));
app.get("/katex.css", function(req, res, next) {
var lessfile = path.join(__dirname, "static", "katex.less");
const lessfile = path.join(__dirname, "static", "katex.less");
fs.readFile(lessfile, {encoding: "utf8"}, function(err, data) {
if (err) {
next(err);

View File

@ -11,9 +11,9 @@
* kinds.
*/
var matchAt = require("match-at");
const matchAt = require("match-at");
var ParseError = require("./ParseError");
const ParseError = require("./ParseError");
// The main lexer class
function Lexer(input) {
@ -76,7 +76,7 @@ Token.prototype.range = function(endToken, text) {
* If there is no matching function or symbol definition, the Parser will
* still reject the input.
*/
var tokenRegex = new RegExp(
const tokenRegex = new RegExp(
"([ \r\n\t]+)|" + // whitespace
"([!-\\[\\]-\u2027\u202A-\uD7FF\uF900-\uFFFF]" + // single codepoint
"|[\uD800-\uDBFF][\uDC00-\uDFFF]" + // surrogate pair
@ -88,21 +88,21 @@ var tokenRegex = new RegExp(
* This function lexes a single token.
*/
Lexer.prototype.lex = function() {
var input = this.input;
var pos = this.pos;
const input = this.input;
const pos = this.pos;
if (pos === input.length) {
return new Token("EOF", pos, pos, this);
}
var match = matchAt(tokenRegex, input, pos);
const match = matchAt(tokenRegex, input, pos);
if (match === null) {
throw new ParseError(
"Unexpected character: '" + input[pos] + "'",
new Token(input[pos], pos, pos + 1, this));
}
var text = match[2] || " ";
var start = this.pos;
const text = match[2] || " ";
const start = this.pos;
this.pos += match[0].length;
var end = this.pos;
const end = this.pos;
return new Token(text, start, end, this);
};

View File

@ -3,7 +3,7 @@
* until only non-macro tokens remain.
*/
var Lexer = require("./Lexer");
const Lexer = require("./Lexer");
function MacroExpander(input, macros) {
this.lexer = new Lexer(input);
@ -20,16 +20,16 @@ MacroExpander.prototype.nextToken = function() {
if (this.stack.length === 0) {
this.stack.push(this.lexer.lex());
}
var topToken = this.stack.pop();
var name = topToken.text;
const topToken = this.stack.pop();
const name = topToken.text;
if (!(name.charAt(0) === "\\" && this.macros.hasOwnProperty(name))) {
return topToken;
}
var expansion = this.macros[name];
let expansion = this.macros[name];
if (typeof expansion === "string") {
var bodyLexer = new Lexer(expansion);
const bodyLexer = new Lexer(expansion);
expansion = [];
var tok = bodyLexer.lex();
let tok = bodyLexer.lex();
while (tok.text !== "EOF") {
expansion.push(tok);
tok = bodyLexer.lex();
@ -43,7 +43,7 @@ MacroExpander.prototype.nextToken = function() {
MacroExpander.prototype.get = function(ignoreSpace) {
this.discardedWhiteSpace = [];
var token = this.nextToken();
let token = this.nextToken();
if (ignoreSpace) {
while (token.text === " ") {
this.discardedWhiteSpace.push(token);

View File

@ -39,7 +39,7 @@ function Options(data) {
* from "extension" will be copied to the new options object.
*/
Options.prototype.extend = function(extension) {
var data = {
const data = {
style: this.style,
size: this.size,
color: this.color,
@ -49,7 +49,7 @@ Options.prototype.extend = function(extension) {
font: this.font,
};
for (var key in extension) {
for (const key in extension) {
if (extension.hasOwnProperty(key)) {
data[key] = extension[key];
}
@ -115,7 +115,7 @@ Options.prototype.reset = function() {
* A map of color names to CSS colors.
* TODO(emily): Remove this when we have real macros
*/
var colorMap = {
const colorMap = {
"katex-blue": "#6495ed",
"katex-orange": "#ffa500",
"katex-pink": "#ff00af",

View File

@ -10,15 +10,15 @@
* @param {(Token|ParseNode)=} token An object providing position information
*/
function ParseError(message, token) {
var error = "KaTeX parse error: " + message;
var start;
var end;
let error = "KaTeX parse error: " + message;
let start;
let end;
if (token && token.lexer && token.start <= token.end) {
// If we have the input and a position, make the error a bit fancier
// Get the input
var input = token.lexer.input;
const input = token.lexer.input;
// Prepend some information
start = token.start;
@ -30,16 +30,16 @@ function ParseError(message, token) {
}
// Underline token in question using combining underscores
var underlined = input.slice(start, end).replace(/[^]/g, "$&\u0332");
const underlined = input.slice(start, end).replace(/[^]/g, "$&\u0332");
// Extract some context from the input and add it to the error
var left;
let left;
if (start > 15) {
left = "…" + input.slice(start - 15, start);
} else {
left = input.slice(0, start);
}
var right;
let right;
if (end + 15 < input.length) {
right = input.slice(end, end + 15) + "…";
} else {
@ -50,7 +50,7 @@ function ParseError(message, token) {
// Some hackery to make ParseError a prototype of Error
// See http://stackoverflow.com/a/8460753
var self = new Error(error);
const self = new Error(error);
self.name = "ParseError";
self.__proto__ = ParseError.prototype;

View File

@ -1,13 +1,13 @@
/* eslint no-constant-condition:0 */
var functions = require("./functions");
var environments = require("./environments");
var MacroExpander = require("./MacroExpander");
var symbols = require("./symbols");
var utils = require("./utils");
var cjkRegex = require("./unicodeRegexes").cjkRegex;
const functions = require("./functions");
const environments = require("./environments");
const MacroExpander = require("./MacroExpander");
const symbols = require("./symbols");
const utils = require("./utils");
const cjkRegex = require("./unicodeRegexes").cjkRegex;
var parseData = require("./parseData");
var ParseError = require("./ParseError");
const parseData = require("./parseData");
const ParseError = require("./ParseError");
/**
* This file contains the parser used to parse out a TeX expression from the
@ -56,7 +56,7 @@ function Parser(input, settings) {
this.leftrightDepth = 0;
}
var ParseNode = parseData.ParseNode;
const ParseNode = parseData.ParseNode;
/**
* An initial function (without its arguments), or an argument to a function.
@ -111,7 +111,7 @@ Parser.prototype.parse = function() {
// Try to parse the input
this.mode = "math";
this.consume();
var parse = this.parseInput();
const parse = this.parseInput();
return parse;
};
@ -120,13 +120,13 @@ Parser.prototype.parse = function() {
*/
Parser.prototype.parseInput = function() {
// Parse an expression
var expression = this.parseExpression(false);
const expression = this.parseExpression(false);
// If we succeeded, make sure there's an EOF at the end
this.expect("EOF", false);
return expression;
};
var endOfExpression = ["}", "\\end", "\\right", "&", "\\\\", "\\cr"];
const endOfExpression = ["}", "\\end", "\\right", "&", "\\\\", "\\cr"];
/**
* Parses an "expression", which is a list of atoms.
@ -142,11 +142,11 @@ var endOfExpression = ["}", "\\end", "\\right", "&", "\\\\", "\\cr"];
* @return {ParseNode}
*/
Parser.prototype.parseExpression = function(breakOnInfix, breakOnTokenText) {
var body = [];
const body = [];
// Keep adding atoms to the body until we can't parse any more atoms (either
// we reached the end, a }, or a \right)
while (true) {
var lex = this.nextToken;
const lex = this.nextToken;
if (endOfExpression.indexOf(lex.text) !== -1) {
break;
}
@ -156,10 +156,10 @@ Parser.prototype.parseExpression = function(breakOnInfix, breakOnTokenText) {
if (breakOnInfix && functions[lex.text] && functions[lex.text].infix) {
break;
}
var atom = this.parseAtom();
const atom = this.parseAtom();
if (!atom) {
if (!this.settings.throwOnError && lex.text[0] === "\\") {
var errorNode = this.handleUnsupportedCmd();
const errorNode = this.handleUnsupportedCmd();
body.push(errorNode);
continue;
}
@ -181,11 +181,11 @@ Parser.prototype.parseExpression = function(breakOnInfix, breakOnTokenText) {
* @returns {Array}
*/
Parser.prototype.handleInfixNodes = function(body) {
var overIndex = -1;
var funcName;
let overIndex = -1;
let funcName;
for (var i = 0; i < body.length; i++) {
var node = body[i];
for (let i = 0; i < body.length; i++) {
const node = body[i];
if (node.type === "infix") {
if (overIndex !== -1) {
throw new ParseError(
@ -198,11 +198,11 @@ Parser.prototype.handleInfixNodes = function(body) {
}
if (overIndex !== -1) {
var numerNode;
var denomNode;
let numerNode;
let denomNode;
var numerBody = body.slice(0, overIndex);
var denomBody = body.slice(overIndex + 1);
const numerBody = body.slice(0, overIndex);
const denomBody = body.slice(overIndex + 1);
if (numerBody.length === 1 && numerBody[0].type === "ordgroup") {
numerNode = numerBody[0];
@ -216,7 +216,7 @@ Parser.prototype.handleInfixNodes = function(body) {
denomNode = new ParseNode("ordgroup", denomBody, this.mode);
}
var value = this.callFunction(
const value = this.callFunction(
funcName, [numerNode, denomNode], null);
return [new ParseNode(value.type, value, this.mode)];
} else {
@ -225,16 +225,16 @@ Parser.prototype.handleInfixNodes = function(body) {
};
// The greediness of a superscript or subscript
var SUPSUB_GREEDINESS = 1;
const SUPSUB_GREEDINESS = 1;
/**
* Handle a subscript or superscript with nice errors.
*/
Parser.prototype.handleSupSubscript = function(name) {
var symbolToken = this.nextToken;
var symbol = symbolToken.text;
const symbolToken = this.nextToken;
const symbol = symbolToken.text;
this.consume();
var group = this.parseGroup();
const group = this.parseGroup();
if (!group) {
if (!this.settings.throwOnError && this.nextToken.text[0] === "\\") {
@ -248,7 +248,7 @@ Parser.prototype.handleSupSubscript = function(name) {
} else if (group.isFunction) {
// ^ and _ have a greediness, so handle interactions with functions'
// greediness
var funcGreediness = functions[group.result].greediness;
const funcGreediness = functions[group.result].greediness;
if (funcGreediness > SUPSUB_GREEDINESS) {
return this.parseFunction(group);
} else {
@ -266,14 +266,14 @@ Parser.prototype.handleSupSubscript = function(name) {
* contained within a color node whose color is determined by errorColor
*/
Parser.prototype.handleUnsupportedCmd = function() {
var text = this.nextToken.text;
var textordArray = [];
const text = this.nextToken.text;
const textordArray = [];
for (var i = 0; i < text.length; i++) {
for (let i = 0; i < text.length; i++) {
textordArray.push(new ParseNode("textord", text[i], "text"));
}
var textNode = new ParseNode(
const textNode = new ParseNode(
"text",
{
body: textordArray,
@ -281,7 +281,7 @@ Parser.prototype.handleUnsupportedCmd = function() {
},
this.mode);
var colorNode = new ParseNode(
const colorNode = new ParseNode(
"color",
{
color: this.settings.errorColor,
@ -302,7 +302,7 @@ Parser.prototype.handleUnsupportedCmd = function() {
Parser.prototype.parseAtom = function() {
// The body of an atom is an implicit group, so that things like
// \left(x\right)^2 work correctly.
var base = this.parseImplicitGroup();
const base = this.parseImplicitGroup();
// In text mode, we don't have superscripts or subscripts
if (this.mode === "text") {
@ -311,11 +311,11 @@ Parser.prototype.parseAtom = function() {
// Note that base may be empty (i.e. null) at this point.
var superscript;
var subscript;
let superscript;
let subscript;
while (true) {
// Lex the first token
var lex = this.nextToken;
const lex = this.nextToken;
if (lex.text === "\\limits" || lex.text === "\\nolimits") {
// We got a limit control
@ -324,7 +324,7 @@ Parser.prototype.parseAtom = function() {
"Limit controls must follow a math operator",
lex);
} else {
var limits = lex.text === "\\limits";
const limits = lex.text === "\\limits";
base.value.limits = limits;
base.value.alwaysHandleSupSub = true;
}
@ -343,10 +343,10 @@ Parser.prototype.parseAtom = function() {
subscript = this.handleSupSubscript("subscript");
} else if (lex.text === "'") {
// We got a prime
var prime = new ParseNode("textord", "\\prime", this.mode);
const prime = new ParseNode("textord", "\\prime", this.mode);
// Many primes can be grouped together, so we handle this here
var primes = [prime];
const primes = [prime];
this.consume();
// Keep lexing tokens until we get something that's not a prime
while (this.nextToken.text === "'") {
@ -376,13 +376,13 @@ Parser.prototype.parseAtom = function() {
};
// A list of the size-changing functions, for use in parseImplicitGroup
var sizeFuncs = [
const sizeFuncs = [
"\\tiny", "\\scriptsize", "\\footnotesize", "\\small", "\\normalsize",
"\\large", "\\Large", "\\LARGE", "\\huge", "\\Huge",
];
// A list of the style-changing functions, for use in parseImplicitGroup
var styleFuncs = [
const styleFuncs = [
"\\displaystyle", "\\textstyle", "\\scriptstyle", "\\scriptscriptstyle",
];
@ -398,27 +398,26 @@ var styleFuncs = [
* @return {?ParseNode}
*/
Parser.prototype.parseImplicitGroup = function() {
var start = this.parseSymbol();
const start = this.parseSymbol();
if (start == null) {
// If we didn't get anything we handle, fall back to parseFunction
return this.parseFunction();
}
var func = start.result;
var body;
const func = start.result;
if (func === "\\left") {
// If we see a left:
// Parse the entire left function (including the delimiter)
var left = this.parseFunction(start);
const left = this.parseFunction(start);
// Parse out the implicit body
++this.leftrightDepth;
body = this.parseExpression(false);
const body = this.parseExpression(false);
--this.leftrightDepth;
// Check the next token
this.expect("\\right", false);
var right = this.parseFunction();
const right = this.parseFunction();
return new ParseNode("leftright", {
body: body,
left: left.value.value,
@ -426,26 +425,26 @@ Parser.prototype.parseImplicitGroup = function() {
}, this.mode);
} else if (func === "\\begin") {
// begin...end is similar to left...right
var begin = this.parseFunction(start);
var envName = begin.value.name;
const begin = this.parseFunction(start);
const envName = begin.value.name;
if (!environments.hasOwnProperty(envName)) {
throw new ParseError(
"No such environment: " + envName, begin.value.nameGroup);
}
// Build the environment object. Arguments and other information will
// be made available to the begin and end methods using properties.
var env = environments[envName];
var args = this.parseArguments("\\begin{" + envName + "}", env);
var context = {
const env = environments[envName];
const args = this.parseArguments("\\begin{" + envName + "}", env);
const context = {
mode: this.mode,
envName: envName,
parser: this,
positions: args.pop(),
};
var result = env.handler(context, args);
const result = env.handler(context, args);
this.expect("\\end", false);
var endNameToken = this.nextToken;
var end = this.parseFunction();
const endNameToken = this.nextToken;
const end = this.parseFunction();
if (end.value.name !== envName) {
throw new ParseError(
"Mismatch: \\begin{" + envName + "} matched " +
@ -456,7 +455,7 @@ Parser.prototype.parseImplicitGroup = function() {
return result;
} else if (utils.contains(sizeFuncs, func)) {
// If we see a sizing function, parse out the implict body
body = this.parseExpression(false);
const body = this.parseExpression(false);
return new ParseNode("sizing", {
// Figure out what size to use based on the list of functions above
size: "size" + (utils.indexOf(sizeFuncs, func) + 1),
@ -464,7 +463,7 @@ Parser.prototype.parseImplicitGroup = function() {
}, this.mode);
} else if (utils.contains(styleFuncs, func)) {
// If we see a styling function, parse out the implict body
body = this.parseExpression(true);
const body = this.parseExpression(true);
return new ParseNode("styling", {
// Figure out what style to use by pulling out the style from
// the function name
@ -492,17 +491,17 @@ Parser.prototype.parseFunction = function(baseGroup) {
if (baseGroup) {
if (baseGroup.isFunction) {
var func = baseGroup.result;
var funcData = functions[func];
const func = baseGroup.result;
const funcData = functions[func];
if (this.mode === "text" && !funcData.allowedInText) {
throw new ParseError(
"Can't use function '" + func + "' in text mode",
baseGroup.token);
}
var args = this.parseArguments(func, funcData);
var token = baseGroup.token;
var result = this.callFunction(func, args, args.pop(), token);
const args = this.parseArguments(func, funcData);
const token = baseGroup.token;
const result = this.callFunction(func, args, args.pop(), token);
return new ParseNode(result.type, result, this.mode);
} else {
return baseGroup.result;
@ -516,7 +515,7 @@ Parser.prototype.parseFunction = function(baseGroup) {
* Call a function handler with a suitable context and arguments.
*/
Parser.prototype.callFunction = function(name, args, positions, token) {
var context = {
const context = {
funcName: name,
parser: this,
positions: positions,
@ -533,19 +532,19 @@ Parser.prototype.callFunction = function(name, args, positions, token) {
* @return the array of arguments, with the list of positions as last element
*/
Parser.prototype.parseArguments = function(func, funcData) {
var totalArgs = funcData.numArgs + funcData.numOptionalArgs;
const totalArgs = funcData.numArgs + funcData.numOptionalArgs;
if (totalArgs === 0) {
return [[this.pos]];
}
var baseGreediness = funcData.greediness;
var positions = [this.pos];
var args = [];
const baseGreediness = funcData.greediness;
const positions = [this.pos];
const args = [];
for (var i = 0; i < totalArgs; i++) {
var nextToken = this.nextToken;
var argType = funcData.argTypes && funcData.argTypes[i];
var arg;
for (let i = 0; i < totalArgs; i++) {
const nextToken = this.nextToken;
const argType = funcData.argTypes && funcData.argTypes[i];
let arg;
if (i < funcData.numOptionalArgs) {
if (argType) {
arg = this.parseGroupOfType(argType, true);
@ -575,9 +574,9 @@ Parser.prototype.parseArguments = function(func, funcData) {
}
}
}
var argNode;
let argNode;
if (arg.isFunction) {
var argGreediness =
const argGreediness =
functions[arg.result].greediness;
if (argGreediness > baseGreediness) {
argNode = this.parseFunction(arg);
@ -605,7 +604,7 @@ Parser.prototype.parseArguments = function(func, funcData) {
* @return {?ParseFuncOrArgument}
*/
Parser.prototype.parseGroupOfType = function(innerMode, optional) {
var outerMode = this.mode;
const outerMode = this.mode;
// Handle `original` argTypes
if (innerMode === "original") {
innerMode = outerMode;
@ -628,7 +627,7 @@ Parser.prototype.parseGroupOfType = function(innerMode, optional) {
}
// By the time we get here, innerMode is one of "text" or "math".
// We switch the mode of the parser, recurse, then restore the old mode.
var res = this.parseGroup(optional);
const res = this.parseGroup(optional);
this.switchMode(outerMode);
return res;
};
@ -644,12 +643,12 @@ Parser.prototype.parseStringGroup = function(modeName, optional) {
if (optional && this.nextToken.text !== "[") {
return null;
}
var outerMode = this.mode;
const outerMode = this.mode;
this.mode = "text";
this.expect(optional ? "[" : "{");
var str = "";
var firstToken = this.nextToken;
var lastToken = firstToken;
let str = "";
const firstToken = this.nextToken;
let lastToken = firstToken;
while (this.nextToken.text !== (optional ? "]" : "}")) {
if (this.nextToken.text === "EOF") {
throw new ParseError(
@ -674,11 +673,11 @@ Parser.prototype.parseStringGroup = function(modeName, optional) {
* @param {string} modeName Used to describe the mode in error messages
*/
Parser.prototype.parseRegexGroup = function(regex, modeName) {
var outerMode = this.mode;
const outerMode = this.mode;
this.mode = "text";
var firstToken = this.nextToken;
var lastToken = firstToken;
var str = "";
const firstToken = this.nextToken;
let lastToken = firstToken;
let str = "";
while (this.nextToken.text !== "EOF"
&& regex.test(str + this.nextToken.text)) {
lastToken = this.nextToken;
@ -698,11 +697,11 @@ Parser.prototype.parseRegexGroup = function(regex, modeName) {
* Parses a color description.
*/
Parser.prototype.parseColorGroup = function(optional) {
var res = this.parseStringGroup("color", optional);
const res = this.parseStringGroup("color", optional);
if (!res) {
return null;
}
var match = (/^(#[a-z0-9]+|[a-z]+)$/i).exec(res.text);
const match = (/^(#[a-z0-9]+|[a-z]+)$/i).exec(res.text);
if (!match) {
throw new ParseError("Invalid color: '" + res.text + "'", res);
}
@ -715,7 +714,7 @@ Parser.prototype.parseColorGroup = function(optional) {
* Parses a size specification, consisting of magnitude and unit.
*/
Parser.prototype.parseSizeGroup = function(optional) {
var res;
let res;
if (!optional && this.nextToken.text !== "{") {
res = this.parseRegexGroup(
/^[-+]? *(?:$|\d+|\d+\.\d*|\.\d*) *[a-z]{0,2}$/, "size");
@ -725,11 +724,11 @@ Parser.prototype.parseSizeGroup = function(optional) {
if (!res) {
return null;
}
var match = (/([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/).exec(res.text);
const match = (/([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/).exec(res.text);
if (!match) {
throw new ParseError("Invalid size: '" + res.text + "'", res);
}
var data = {
const data = {
number: +(match[1] + match[2]), // sign + magnitude, cast to number
unit: match[3],
};
@ -753,13 +752,13 @@ Parser.prototype.parseSizeGroup = function(optional) {
* @return {?ParseFuncOrArgument}
*/
Parser.prototype.parseGroup = function(optional) {
var firstToken = this.nextToken;
const firstToken = this.nextToken;
// Try to parse an open brace
if (this.nextToken.text === (optional ? "[" : "{")) {
// If we get a brace, parse an expression
this.consume();
var expression = this.parseExpression(false, optional ? "]" : null);
var lastToken = this.nextToken;
const expression = this.parseExpression(false, optional ? "]" : null);
const lastToken = this.nextToken;
// Make sure we get a close brace
this.expect(optional ? "]" : "}");
if (this.mode === "text") {
@ -786,11 +785,10 @@ Parser.prototype.parseGroup = function(optional) {
* list will be moified in place
*/
Parser.prototype.formLigatures = function(group) {
var i;
var n = group.length - 1;
for (i = 0; i < n; ++i) {
var a = group[i];
var v = a.value;
let n = group.length - 1;
for (let i = 0; i < n; ++i) {
const a = group[i];
const v = a.value;
if (v === "-" && group[i + 1].value === "-") {
if (i + 1 < n && group[i + 2].value === "-") {
group.splice(i, 3, new ParseNode(
@ -817,7 +815,7 @@ Parser.prototype.formLigatures = function(group) {
* @return {?ParseFuncOrArgument}
*/
Parser.prototype.parseSymbol = function() {
var nucleus = this.nextToken;
const nucleus = this.nextToken;
if (functions[nucleus.text]) {
this.consume();

View File

@ -6,18 +6,17 @@
* information about them.
*/
var sigmas = require("./fontMetrics.js").sigmas;
const sigmas = require("./fontMetrics.js").sigmas;
var metrics = [{}, {}, {}];
var i;
for (var key in sigmas) {
const metrics = [{}, {}, {}];
for (const key in sigmas) {
if (sigmas.hasOwnProperty(key)) {
for (i = 0; i < 3; i++) {
for (let i = 0; i < 3; i++) {
metrics[i][key] = sigmas[key][i];
}
}
}
for (i = 0; i < 3; i++) {
for (let i = 0; i < 3; i++) {
metrics[i].emPerEx = sigmas.xHeight[i] / sigmas.quad[i];
}
@ -95,17 +94,17 @@ Style.prototype.isTight = function() {
};
// IDs of the different styles
var D = 0;
var Dc = 1;
var T = 2;
var Tc = 3;
var S = 4;
var Sc = 5;
var SS = 6;
var SSc = 7;
const D = 0;
const Dc = 1;
const T = 2;
const Tc = 3;
const S = 4;
const Sc = 5;
const SS = 6;
const SSc = 7;
// String names for the different sizes
var sizeNames = [
const sizeNames = [
"displaystyle textstyle",
"textstyle",
"scriptstyle",
@ -113,7 +112,7 @@ var sizeNames = [
];
// Reset names for the different sizes
var resetNames = [
const resetNames = [
"reset-textstyle",
"reset-textstyle",
"reset-scriptstyle",
@ -121,7 +120,7 @@ var resetNames = [
];
// Instances of the different styles
var styles = [
const styles = [
new Style(D, 0, 1.0, false),
new Style(Dc, 0, 1.0, true),
new Style(T, 1, 1.0, false),
@ -133,11 +132,11 @@ var styles = [
];
// Lookup tables for switching from one style to another
var sup = [S, Sc, S, Sc, SS, SSc, SS, SSc];
var sub = [Sc, Sc, Sc, Sc, SSc, SSc, SSc, SSc];
var fracNum = [T, Tc, S, Sc, SS, SSc, SS, SSc];
var fracDen = [Tc, Tc, Sc, Sc, SSc, SSc, SSc, SSc];
var cramp = [Dc, Dc, Tc, Tc, Sc, Sc, SSc, SSc];
const sup = [S, Sc, S, Sc, SS, SSc, SS, SSc];
const sub = [Sc, Sc, Sc, Sc, SSc, SSc, SSc, SSc];
const fracNum = [T, Tc, S, Sc, SS, SSc, SS, SSc];
const fracDen = [Tc, Tc, Sc, Sc, SSc, SSc, SSc, SSc];
const cramp = [Dc, Dc, Tc, Tc, Sc, Sc, SSc, SSc];
// We only export some of the styles. Also, we don't export the `Style` class so
// no more styles can be generated.

View File

@ -4,12 +4,12 @@
* different kinds of domTree nodes in a consistent manner.
*/
var domTree = require("./domTree");
var fontMetrics = require("./fontMetrics");
var symbols = require("./symbols");
var utils = require("./utils");
const domTree = require("./domTree");
const fontMetrics = require("./fontMetrics");
const symbols = require("./symbols");
const utils = require("./utils");
var greekCapitals = [
const greekCapitals = [
"\\Gamma",
"\\Delta",
"\\Theta",
@ -24,7 +24,7 @@ var greekCapitals = [
];
// The following have to be loaded from Main-Italic font, using class mainit
var mainitLetters = [
const mainitLetters = [
"\u0131", // dotless i, \imath
"\u0237", // dotless j, \jmath
"\u00a3", // \pounds
@ -39,17 +39,17 @@ var mainitLetters = [
* TODO: add a separate argument for math class (e.g. `mop`, `mbin`), which
* should if present come first in `classes`.
*/
var makeSymbol = function(value, fontFamily, mode, options, classes) {
const makeSymbol = function(value, fontFamily, mode, options, classes) {
// Replace the value with its replaced value from symbol.js
if (symbols[mode][value] && symbols[mode][value].replace) {
value = symbols[mode][value].replace;
}
var metrics = fontMetrics.getCharacterMetrics(value, fontFamily);
const metrics = fontMetrics.getCharacterMetrics(value, fontFamily);
var symbolNode;
let symbolNode;
if (metrics) {
var italic = metrics.italic;
let italic = metrics.italic;
if (mode === "text") {
italic = 0;
}
@ -80,7 +80,7 @@ var makeSymbol = function(value, fontFamily, mode, options, classes) {
* Makes a symbol in Main-Regular or AMS-Regular.
* Used for rel, bin, open, close, inner, and punct.
*/
var mathsym = function(value, mode, options, classes) {
const mathsym = function(value, mode, options, classes) {
// Decide what font to render the symbol in by its entry in the symbols
// table.
// Have a special case for when the value = \ because the \ is used as a
@ -98,7 +98,7 @@ var mathsym = function(value, mode, options, classes) {
/**
* Makes a symbol in the default font for mathords and textords.
*/
var mathDefault = function(value, mode, options, classes, type) {
const mathDefault = function(value, mode, options, classes, type) {
if (type === "mathord") {
return mathit(value, mode, options, classes);
} else if (type === "textord") {
@ -112,7 +112,7 @@ var mathDefault = function(value, mode, options, classes, type) {
/**
* Makes a symbol in the italic math font.
*/
var mathit = function(value, mode, options, classes) {
const mathit = function(value, mode, options, classes) {
if (/[0-9]/.test(value.charAt(0)) ||
// glyphs for \imath and \jmath do not exist in Math-Italic so we
// need to use Main-Italic instead
@ -129,21 +129,21 @@ var mathit = function(value, mode, options, classes) {
/**
* Makes either a mathord or textord in the correct font and color.
*/
var makeOrd = function(group, options, type) {
var mode = group.mode;
var value = group.value;
const makeOrd = function(group, options, type) {
const mode = group.mode;
let value = group.value;
if (symbols[mode][value] && symbols[mode][value].replace) {
value = symbols[mode][value].replace;
}
var classes = ["mord"];
const classes = ["mord"];
var font = options.font;
const font = options.font;
if (font) {
if (font === "mathit" || utils.contains(mainitLetters, value)) {
return mathit(value, mode, options, classes);
} else {
var fontName = fontMap[font].fontName;
const fontName = fontMap[font].fontName;
if (fontMetrics.getCharacterMetrics(value, fontName)) {
return makeSymbol(
value, fontName, mode, options, classes.concat([font]));
@ -160,13 +160,13 @@ var makeOrd = function(group, options, type) {
* Calculate the height, depth, and maxFontSize of an element based on its
* children.
*/
var sizeElementFromChildren = function(elem) {
var height = 0;
var depth = 0;
var maxFontSize = 0;
const sizeElementFromChildren = function(elem) {
let height = 0;
let depth = 0;
let maxFontSize = 0;
if (elem.children) {
for (var i = 0; i < elem.children.length; i++) {
for (let i = 0; i < elem.children.length; i++) {
if (elem.children[i].height > height) {
height = elem.children[i].height;
}
@ -192,8 +192,8 @@ var sizeElementFromChildren = function(elem) {
* TODO: add a separate argument for math class (e.g. `mop`, `mbin`), which
* should if present come first in `classes`.
*/
var makeSpan = function(classes, children, options) {
var span = new domTree.span(classes, children, options);
const makeSpan = function(classes, children, options) {
const span = new domTree.span(classes, children, options);
sizeElementFromChildren(span);
@ -204,7 +204,7 @@ var makeSpan = function(classes, children, options) {
* Prepends the given children to the given span, updating height, depth, and
* maxFontSize.
*/
var prependChildren = function(span, children) {
const prependChildren = function(span, children) {
span.children = children.concat(span.children);
sizeElementFromChildren(span);
@ -213,8 +213,8 @@ var prependChildren = function(span, children) {
/**
* Makes a document fragment with the given list of children.
*/
var makeFragment = function(children) {
var fragment = new domTree.documentFragment(children);
const makeFragment = function(children) {
const fragment = new domTree.documentFragment(children);
sizeElementFromChildren(fragment);
@ -226,12 +226,12 @@ var makeFragment = function(children) {
* element has the same max font size. To do this, we create a zero-width space
* with the correct font size.
*/
var makeFontSizer = function(options, fontSize) {
var fontSizeInner = makeSpan([], [new domTree.symbolNode("\u200b")]);
const makeFontSizer = function(options, fontSize) {
const fontSizeInner = makeSpan([], [new domTree.symbolNode("\u200b")]);
fontSizeInner.style.fontSize =
(fontSize / options.style.sizeMultiplier) + "em";
var fontSizer = makeSpan(
const fontSizer = makeSpan(
["fontsize-ensurer", "reset-" + options.size, "size5"],
[fontSizeInner]);
@ -277,12 +277,12 @@ var makeFontSizer = function(options, fontSize) {
* - options: An Options object
*
*/
var makeVList = function(children, positionType, positionData, options) {
var depth;
var currPos;
var i;
const makeVList = function(children, positionType, positionData, options) {
let depth;
let currPos;
let i;
if (positionType === "individualShift") {
var oldChildren = children;
const oldChildren = children;
children = [oldChildren[0]];
// Add in kerns to the list of children to get each element to be
@ -290,9 +290,9 @@ var makeVList = function(children, positionType, positionData, options) {
depth = -oldChildren[0].shift - oldChildren[0].elem.depth;
currPos = depth;
for (i = 1; i < oldChildren.length; i++) {
var diff = -oldChildren[i].shift - currPos -
const diff = -oldChildren[i].shift - currPos -
oldChildren[i].elem.depth;
var size = diff -
const size = diff -
(oldChildren[i - 1].elem.height +
oldChildren[i - 1].elem.depth);
@ -304,7 +304,7 @@ var makeVList = function(children, positionType, positionData, options) {
} else if (positionType === "top") {
// We always start at the bottom, so calculate the bottom by adding up
// all the sizes
var bottom = positionData;
let bottom = positionData;
for (i = 0; i < children.length; i++) {
if (children[i].type === "kern") {
bottom -= children[i].size;
@ -324,27 +324,27 @@ var makeVList = function(children, positionType, positionData, options) {
}
// Make the fontSizer
var maxFontSize = 0;
let maxFontSize = 0;
for (i = 0; i < children.length; i++) {
if (children[i].type === "elem") {
maxFontSize = Math.max(maxFontSize, children[i].elem.maxFontSize);
}
}
var fontSizer = makeFontSizer(options, maxFontSize);
const fontSizer = makeFontSizer(options, maxFontSize);
// Create a new list of actual children at the correct offsets
var realChildren = [];
const realChildren = [];
currPos = depth;
for (i = 0; i < children.length; i++) {
if (children[i].type === "kern") {
currPos += children[i].size;
} else {
var child = children[i].elem;
const child = children[i].elem;
var shift = -child.depth - currPos;
const shift = -child.depth - currPos;
currPos += child.height + child.depth;
var childWrap = makeSpan([], [fontSizer, child]);
const childWrap = makeSpan([], [fontSizer, child]);
childWrap.height -= shift;
childWrap.depth += shift;
childWrap.style.top = shift + "em";
@ -355,11 +355,11 @@ var makeVList = function(children, positionType, positionData, options) {
// Add in an element at the end with no offset to fix the calculation of
// baselines in some browsers (namely IE, sometimes safari)
var baselineFix = makeSpan(
const baselineFix = makeSpan(
["baseline-fix"], [fontSizer, new domTree.symbolNode("\u200b")]);
realChildren.push(baselineFix);
var vlist = makeSpan(["vlist"], realChildren);
const vlist = makeSpan(["vlist"], realChildren);
// Fix the final height and depth, in case there were kerns at the ends
// since the makeSpan calculation won't take that in to account.
vlist.height = Math.max(currPos, vlist.height);
@ -368,7 +368,7 @@ var makeVList = function(children, positionType, positionData, options) {
};
// A table of size -> font size for the different sizing functions
var sizingMultiplier = {
const sizingMultiplier = {
size1: 0.5,
size2: 0.7,
size3: 0.8,
@ -383,7 +383,7 @@ var sizingMultiplier = {
// A map of spacing functions to their attributes, like size and corresponding
// CSS class
var spacingFunctions = {
const spacingFunctions = {
"\\qquad": {
size: "2em",
className: "qquad",
@ -420,7 +420,7 @@ var spacingFunctions = {
* - fontName: the "style" parameter to fontMetrics.getCharacterMetrics
*/
// A map between tex font commands an MathML mathvariant attribute values
var fontMap = {
const fontMap = {
// styles
"mathbf": {
variant: "bold",

File diff suppressed because it is too large Load Diff

View File

@ -4,21 +4,21 @@
* parser.
*/
var buildCommon = require("./buildCommon");
var fontMetrics = require("./fontMetrics");
var mathMLTree = require("./mathMLTree");
var ParseError = require("./ParseError");
var symbols = require("./symbols");
var utils = require("./utils");
const buildCommon = require("./buildCommon");
const fontMetrics = require("./fontMetrics");
const mathMLTree = require("./mathMLTree");
const ParseError = require("./ParseError");
const symbols = require("./symbols");
const utils = require("./utils");
var makeSpan = buildCommon.makeSpan;
var fontMap = buildCommon.fontMap;
const makeSpan = buildCommon.makeSpan;
const fontMap = buildCommon.fontMap;
/**
* Takes a symbol and converts it into a MathML text node after performing
* optional replacement from symbols.js.
*/
var makeText = function(text, mode) {
const makeText = function(text, mode) {
if (symbols[mode][text] && symbols[mode][text].replace) {
text = symbols[mode][text].replace;
}
@ -29,18 +29,18 @@ var makeText = function(text, mode) {
/**
* Returns the math variant as a string or null if none is required.
*/
var getVariant = function(group, options) {
var font = options.font;
const getVariant = function(group, options) {
const font = options.font;
if (!font) {
return null;
}
var mode = group.mode;
const mode = group.mode;
if (font === "mathit") {
return "italic";
}
var value = group.value;
let value = group.value;
if (utils.contains(["\\imath", "\\jmath"], value)) {
return null;
}
@ -49,7 +49,7 @@ var getVariant = function(group, options) {
value = symbols[mode][value].replace;
}
var fontName = fontMap[font].fontName;
const fontName = fontMap[font].fontName;
if (fontMetrics.getCharacterMetrics(value, fontName)) {
return fontMap[options.font].variant;
}
@ -61,14 +61,14 @@ var getVariant = function(group, options) {
* Functions for handling the different types of groups found in the parse
* tree. Each function should take a parse group and return a MathML node.
*/
var groupTypes = {};
const groupTypes = {};
groupTypes.mathord = function(group, options) {
var node = new mathMLTree.MathNode(
const node = new mathMLTree.MathNode(
"mi",
[makeText(group.value, group.mode)]);
var variant = getVariant(group, options);
const variant = getVariant(group, options);
if (variant) {
node.setAttribute("mathvariant", variant);
}
@ -76,11 +76,11 @@ groupTypes.mathord = function(group, options) {
};
groupTypes.textord = function(group, options) {
var text = makeText(group.value, group.mode);
const text = makeText(group.value, group.mode);
var variant = getVariant(group, options) || "normal";
const variant = getVariant(group, options) || "normal";
var node;
let node;
if (/[0-9]/.test(group.value)) {
// TODO(kevinb) merge adjacent <mn> nodes
// do it as a post processing step
@ -97,42 +97,42 @@ groupTypes.textord = function(group, options) {
};
groupTypes.bin = function(group) {
var node = new mathMLTree.MathNode(
const node = new mathMLTree.MathNode(
"mo", [makeText(group.value, group.mode)]);
return node;
};
groupTypes.rel = function(group) {
var node = new mathMLTree.MathNode(
const node = new mathMLTree.MathNode(
"mo", [makeText(group.value, group.mode)]);
return node;
};
groupTypes.open = function(group) {
var node = new mathMLTree.MathNode(
const node = new mathMLTree.MathNode(
"mo", [makeText(group.value, group.mode)]);
return node;
};
groupTypes.close = function(group) {
var node = new mathMLTree.MathNode(
const node = new mathMLTree.MathNode(
"mo", [makeText(group.value, group.mode)]);
return node;
};
groupTypes.inner = function(group) {
var node = new mathMLTree.MathNode(
const node = new mathMLTree.MathNode(
"mo", [makeText(group.value, group.mode)]);
return node;
};
groupTypes.punct = function(group) {
var node = new mathMLTree.MathNode(
const node = new mathMLTree.MathNode(
"mo", [makeText(group.value, group.mode)]);
node.setAttribute("separator", "true");
@ -141,25 +141,25 @@ groupTypes.punct = function(group) {
};
groupTypes.ordgroup = function(group, options) {
var inner = buildExpression(group.value, options);
const inner = buildExpression(group.value, options);
var node = new mathMLTree.MathNode("mrow", inner);
const node = new mathMLTree.MathNode("mrow", inner);
return node;
};
groupTypes.text = function(group, options) {
var inner = buildExpression(group.value.body, options);
const inner = buildExpression(group.value.body, options);
var node = new mathMLTree.MathNode("mtext", inner);
const node = new mathMLTree.MathNode("mtext", inner);
return node;
};
groupTypes.color = function(group, options) {
var inner = buildExpression(group.value.value, options);
const inner = buildExpression(group.value.value, options);
var node = new mathMLTree.MathNode("mstyle", inner);
const node = new mathMLTree.MathNode("mstyle", inner);
node.setAttribute("mathcolor", group.value.color);
@ -167,7 +167,7 @@ groupTypes.color = function(group, options) {
};
groupTypes.supsub = function(group, options) {
var children = [buildGroup(group.value.base, options)];
const children = [buildGroup(group.value.base, options)];
if (group.value.sub) {
children.push(buildGroup(group.value.sub, options));
@ -177,7 +177,7 @@ groupTypes.supsub = function(group, options) {
children.push(buildGroup(group.value.sup, options));
}
var nodeType;
let nodeType;
if (!group.value.sub) {
nodeType = "msup";
} else if (!group.value.sup) {
@ -186,13 +186,13 @@ groupTypes.supsub = function(group, options) {
nodeType = "msubsup";
}
var node = new mathMLTree.MathNode(nodeType, children);
const node = new mathMLTree.MathNode(nodeType, children);
return node;
};
groupTypes.genfrac = function(group, options) {
var node = new mathMLTree.MathNode(
const node = new mathMLTree.MathNode(
"mfrac",
[
buildGroup(group.value.numer, options),
@ -204,10 +204,10 @@ groupTypes.genfrac = function(group, options) {
}
if (group.value.leftDelim != null || group.value.rightDelim != null) {
var withDelims = [];
const withDelims = [];
if (group.value.leftDelim != null) {
var leftOp = new mathMLTree.MathNode(
const leftOp = new mathMLTree.MathNode(
"mo", [new mathMLTree.TextNode(group.value.leftDelim)]);
leftOp.setAttribute("fence", "true");
@ -218,7 +218,7 @@ groupTypes.genfrac = function(group, options) {
withDelims.push(node);
if (group.value.rightDelim != null) {
var rightOp = new mathMLTree.MathNode(
const rightOp = new mathMLTree.MathNode(
"mo", [new mathMLTree.TextNode(group.value.rightDelim)]);
rightOp.setAttribute("fence", "true");
@ -226,7 +226,7 @@ groupTypes.genfrac = function(group, options) {
withDelims.push(rightOp);
}
var outerNode = new mathMLTree.MathNode("mrow", withDelims);
const outerNode = new mathMLTree.MathNode("mrow", withDelims);
return outerNode;
}
@ -246,7 +246,7 @@ groupTypes.array = function(group, options) {
};
groupTypes.sqrt = function(group, options) {
var node;
let node;
if (group.value.index) {
node = new mathMLTree.MathNode(
"mroot", [
@ -262,10 +262,10 @@ groupTypes.sqrt = function(group, options) {
};
groupTypes.leftright = function(group, options) {
var inner = buildExpression(group.value.body, options);
const inner = buildExpression(group.value.body, options);
if (group.value.left !== ".") {
var leftNode = new mathMLTree.MathNode(
const leftNode = new mathMLTree.MathNode(
"mo", [makeText(group.value.left, group.mode)]);
leftNode.setAttribute("fence", "true");
@ -274,7 +274,7 @@ groupTypes.leftright = function(group, options) {
}
if (group.value.right !== ".") {
var rightNode = new mathMLTree.MathNode(
const rightNode = new mathMLTree.MathNode(
"mo", [makeText(group.value.right, group.mode)]);
rightNode.setAttribute("fence", "true");
@ -282,23 +282,23 @@ groupTypes.leftright = function(group, options) {
inner.push(rightNode);
}
var outerNode = new mathMLTree.MathNode("mrow", inner);
const outerNode = new mathMLTree.MathNode("mrow", inner);
return outerNode;
};
groupTypes.middle = function(group, options) {
var middleNode = new mathMLTree.MathNode(
const middleNode = new mathMLTree.MathNode(
"mo", [makeText(group.value.middle, group.mode)]);
middleNode.setAttribute("fence", "true");
return middleNode;
};
groupTypes.accent = function(group, options) {
var accentNode = new mathMLTree.MathNode(
const accentNode = new mathMLTree.MathNode(
"mo", [makeText(group.value.accent, group.mode)]);
var node = new mathMLTree.MathNode(
const node = new mathMLTree.MathNode(
"mover",
[buildGroup(group.value.base, options), accentNode]);
@ -308,7 +308,7 @@ groupTypes.accent = function(group, options) {
};
groupTypes.spacing = function(group) {
var node;
let node;
if (group.value === "\\ " || group.value === "\\space" ||
group.value === " " || group.value === "~") {
@ -325,7 +325,7 @@ groupTypes.spacing = function(group) {
};
groupTypes.op = function(group, options) {
var node;
let node;
// TODO(emily): handle big operators using the `largeop` attribute
@ -350,7 +350,7 @@ groupTypes.op = function(group, options) {
};
groupTypes.mod = function(group, options) {
var inner = [];
let inner = [];
if (group.value.modType === "pod" || group.value.modType === "pmod") {
inner.push(new mathMLTree.MathNode(
@ -361,7 +361,7 @@ groupTypes.mod = function(group, options) {
"mo", [makeText("mod", group.mode)]));
}
if (group.value.value) {
var space = new mathMLTree.MathNode("mspace");
const space = new mathMLTree.MathNode("mspace");
space.setAttribute("width", "0.333333em");
inner.push(space);
inner = inner.concat(buildExpression(group.value.value, options));
@ -375,25 +375,25 @@ groupTypes.mod = function(group, options) {
};
groupTypes.katex = function(group) {
var node = new mathMLTree.MathNode(
const node = new mathMLTree.MathNode(
"mtext", [new mathMLTree.TextNode("KaTeX")]);
return node;
};
groupTypes.font = function(group, options) {
var font = group.value.font;
const font = group.value.font;
return buildGroup(group.value.body, options.withFont(font));
};
groupTypes.delimsizing = function(group) {
var children = [];
const children = [];
if (group.value.value !== ".") {
children.push(makeText(group.value.value, group.mode));
}
var node = new mathMLTree.MathNode("mo", children);
const node = new mathMLTree.MathNode("mo", children);
if (group.value.mclass === "mopen" ||
group.value.mclass === "mclose") {
@ -410,18 +410,18 @@ groupTypes.delimsizing = function(group) {
};
groupTypes.styling = function(group, options) {
var inner = buildExpression(group.value.value, options);
const inner = buildExpression(group.value.value, options);
var node = new mathMLTree.MathNode("mstyle", inner);
const node = new mathMLTree.MathNode("mstyle", inner);
var styleAttributes = {
const styleAttributes = {
"display": ["0", "true"],
"text": ["0", "false"],
"script": ["1", "false"],
"scriptscript": ["2", "false"],
};
var attr = styleAttributes[group.value.style];
const attr = styleAttributes[group.value.style];
node.setAttribute("scriptlevel", attr[0]);
node.setAttribute("displaystyle", attr[1]);
@ -430,9 +430,9 @@ groupTypes.styling = function(group, options) {
};
groupTypes.sizing = function(group, options) {
var inner = buildExpression(group.value.value, options);
const inner = buildExpression(group.value.value, options);
var node = new mathMLTree.MathNode("mstyle", inner);
const node = new mathMLTree.MathNode("mstyle", inner);
// TODO(emily): This doesn't produce the correct size for nested size
// changes, because we don't keep state of what style we're currently
@ -446,11 +446,11 @@ groupTypes.sizing = function(group, options) {
};
groupTypes.overline = function(group, options) {
var operator = new mathMLTree.MathNode(
const operator = new mathMLTree.MathNode(
"mo", [new mathMLTree.TextNode("\u203e")]);
operator.setAttribute("stretchy", "true");
var node = new mathMLTree.MathNode(
const node = new mathMLTree.MathNode(
"mover",
[buildGroup(group.value.body, options), operator]);
node.setAttribute("accent", "true");
@ -459,11 +459,11 @@ groupTypes.overline = function(group, options) {
};
groupTypes.underline = function(group, options) {
var operator = new mathMLTree.MathNode(
const operator = new mathMLTree.MathNode(
"mo", [new mathMLTree.TextNode("\u203e")]);
operator.setAttribute("stretchy", "true");
var node = new mathMLTree.MathNode(
const node = new mathMLTree.MathNode(
"munder",
[buildGroup(group.value.body, options), operator]);
node.setAttribute("accentunder", "true");
@ -474,20 +474,20 @@ groupTypes.underline = function(group, options) {
groupTypes.rule = function(group) {
// TODO(emily): Figure out if there's an actual way to draw black boxes
// in MathML.
var node = new mathMLTree.MathNode("mrow");
const node = new mathMLTree.MathNode("mrow");
return node;
};
groupTypes.kern = function(group) {
// TODO(kevin): Figure out if there's a way to add space in MathML
var node = new mathMLTree.MathNode("mrow");
const node = new mathMLTree.MathNode("mrow");
return node;
};
groupTypes.llap = function(group, options) {
var node = new mathMLTree.MathNode(
const node = new mathMLTree.MathNode(
"mpadded", [buildGroup(group.value.body, options)]);
node.setAttribute("lspace", "-1width");
@ -497,7 +497,7 @@ groupTypes.llap = function(group, options) {
};
groupTypes.rlap = function(group, options) {
var node = new mathMLTree.MathNode(
const node = new mathMLTree.MathNode(
"mpadded", [buildGroup(group.value.body, options)]);
node.setAttribute("width", "0px");
@ -506,12 +506,12 @@ groupTypes.rlap = function(group, options) {
};
groupTypes.phantom = function(group, options) {
var inner = buildExpression(group.value.value, options);
const inner = buildExpression(group.value.value, options);
return new mathMLTree.MathNode("mphantom", inner);
};
groupTypes.mclass = function(group, options) {
var inner = buildExpression(group.value.value, options);
const inner = buildExpression(group.value.value, options);
return new mathMLTree.MathNode("mstyle", inner);
};
@ -520,10 +520,10 @@ groupTypes.mclass = function(group, options) {
* 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];
const buildExpression = function(expression, options) {
const groups = [];
for (let i = 0; i < expression.length; i++) {
const group = expression[i];
groups.push(buildGroup(group, options));
}
return groups;
@ -533,7 +533,7 @@ var buildExpression = function(expression, options) {
* Takes a group from the parser and calls the appropriate groupTypes function
* on it to produce a MathML node.
*/
var buildGroup = function(group, options) {
const buildGroup = function(group, options) {
if (!group) {
return new mathMLTree.MathNode("mrow");
}
@ -555,23 +555,23 @@ var buildGroup = function(group, options) {
* Note that we actually return a domTree element with a `<math>` inside it so
* we can do appropriate styling.
*/
var buildMathML = function(tree, texExpression, options) {
var expression = buildExpression(tree, options);
const buildMathML = function(tree, texExpression, options) {
const expression = buildExpression(tree, options);
// Wrap up the expression in an mrow so it is presented in the semantics
// tag correctly.
var wrapper = new mathMLTree.MathNode("mrow", expression);
const wrapper = new mathMLTree.MathNode("mrow", expression);
// Build a TeX annotation of the source
var annotation = new mathMLTree.MathNode(
const annotation = new mathMLTree.MathNode(
"annotation", [new mathMLTree.TextNode(texExpression)]);
annotation.setAttribute("encoding", "application/x-tex");
var semantics = new mathMLTree.MathNode(
const semantics = new mathMLTree.MathNode(
"semantics", [wrapper, annotation]);
var math = new mathMLTree.MathNode("math", [semantics]);
const math = new mathMLTree.MathNode("math", [semantics]);
// You can't style <math> nodes, so we wrap the node in a span.
return makeSpan(["katex-mathml"], [math]);

View File

@ -1,32 +1,32 @@
var buildHTML = require("./buildHTML");
var buildMathML = require("./buildMathML");
var buildCommon = require("./buildCommon");
var Options = require("./Options");
var Settings = require("./Settings");
var Style = require("./Style");
const buildHTML = require("./buildHTML");
const buildMathML = require("./buildMathML");
const buildCommon = require("./buildCommon");
const Options = require("./Options");
const Settings = require("./Settings");
const Style = require("./Style");
var makeSpan = buildCommon.makeSpan;
const makeSpan = buildCommon.makeSpan;
var buildTree = function(tree, expression, settings) {
const buildTree = function(tree, expression, settings) {
settings = settings || new Settings({});
var startStyle = Style.TEXT;
let startStyle = Style.TEXT;
if (settings.displayMode) {
startStyle = Style.DISPLAY;
}
// Setup the default options
var options = new Options({
const options = new Options({
style: startStyle,
size: "size5",
});
// `buildHTML` sometimes messes with the parse tree (like turning bins ->
// ords), so we build the MathML version first.
var mathMLNode = buildMathML(tree, expression, options);
var htmlNode = buildHTML(tree, options);
const mathMLNode = buildMathML(tree, expression, options);
const htmlNode = buildHTML(tree, options);
var katexNode = makeSpan(["katex"], [
const katexNode = makeSpan(["katex"], [
mathMLNode, htmlNode,
]);

View File

@ -20,21 +20,21 @@
* used in `\left` and `\right`.
*/
var ParseError = require("./ParseError");
var Style = require("./Style");
const ParseError = require("./ParseError");
const Style = require("./Style");
var buildCommon = require("./buildCommon");
var fontMetrics = require("./fontMetrics");
var symbols = require("./symbols");
var utils = require("./utils");
const buildCommon = require("./buildCommon");
const fontMetrics = require("./fontMetrics");
const symbols = require("./symbols");
const utils = require("./utils");
var makeSpan = buildCommon.makeSpan;
const makeSpan = buildCommon.makeSpan;
/**
* Get the metrics for a given symbol and font, after transformation (i.e.
* after following replacement from symbols.js)
*/
var getMetrics = function(symbol, font) {
const getMetrics = function(symbol, font) {
if (symbols.math[symbol] && symbols.math[symbol].replace) {
return fontMetrics.getCharacterMetrics(
symbols.math[symbol].replace, font);
@ -47,7 +47,7 @@ var getMetrics = function(symbol, font) {
/**
* Builds a symbol in the given font size (note size is an integer)
*/
var mathrmSize = function(value, size, mode, options) {
const mathrmSize = function(value, size, mode, options) {
return buildCommon.makeSymbol(value, "Size" + size + "-Regular",
mode, options);
};
@ -56,13 +56,13 @@ var mathrmSize = function(value, size, mode, options) {
* Puts a delimiter span in a given style, and adds appropriate height, depth,
* and maxFontSizes.
*/
var styleWrap = function(delim, toStyle, options, classes) {
const styleWrap = function(delim, toStyle, options, classes) {
classes = classes || [];
var span = makeSpan(
const span = makeSpan(
classes.concat(["style-wrap", options.style.reset(), toStyle.cls()]),
[delim], options);
var multiplier = toStyle.sizeMultiplier / options.style.sizeMultiplier;
const multiplier = toStyle.sizeMultiplier / options.style.sizeMultiplier;
span.height *= multiplier;
span.depth *= multiplier;
@ -76,13 +76,13 @@ var styleWrap = function(delim, toStyle, options, classes) {
* font, but is restyled to either be in textstyle, scriptstyle, or
* scriptscriptstyle.
*/
var makeSmallDelim = function(delim, style, center, options, mode, classes) {
var text = buildCommon.makeSymbol(delim, "Main-Regular", mode, options);
const makeSmallDelim = function(delim, style, center, options, mode, classes) {
const text = buildCommon.makeSymbol(delim, "Main-Regular", mode, options);
var span = styleWrap(text, style, options, classes);
const span = styleWrap(text, style, options, classes);
if (center) {
var shift =
const shift =
(1 - options.style.sizeMultiplier / style.sizeMultiplier) *
options.style.metrics.axisHeight;
@ -98,15 +98,15 @@ var makeSmallDelim = function(delim, style, center, options, mode, classes) {
* Makes a large delimiter. This is a delimiter that comes in the Size1, Size2,
* Size3, or Size4 fonts. It is always rendered in textstyle.
*/
var makeLargeDelim = function(delim, size, center, options, mode, classes) {
var inner = mathrmSize(delim, size, mode, options);
const makeLargeDelim = function(delim, size, center, options, mode, classes) {
const inner = mathrmSize(delim, size, mode, options);
var span = styleWrap(
const span = styleWrap(
makeSpan(["delimsizing", "size" + size], [inner], options),
Style.TEXT, options, classes);
if (center) {
var shift = (1 - options.style.sizeMultiplier) *
const shift = (1 - options.style.sizeMultiplier) *
options.style.metrics.axisHeight;
span.style.top = shift + "em";
@ -121,8 +121,8 @@ var makeLargeDelim = function(delim, size, center, options, mode, classes) {
* Make an inner span with the given offset and in the given font. This is used
* in `makeStackedDelim` to make the stacking pieces for the delimiter.
*/
var makeInner = function(symbol, font, mode) {
var sizeClass;
const makeInner = function(symbol, font, mode) {
let sizeClass;
// Apply the correct CSS class to choose the right font.
if (font === "Size1-Regular") {
sizeClass = "delim-size1";
@ -130,7 +130,7 @@ var makeInner = function(symbol, font, mode) {
sizeClass = "delim-size4";
}
var inner = makeSpan(
const inner = makeSpan(
["delimsizinginner", sizeClass],
[makeSpan([], [buildCommon.makeSymbol(symbol, font, mode)])]);
@ -143,18 +143,18 @@ var makeInner = function(symbol, font, mode) {
* Make a stacked delimiter out of a given delimiter, with the total height at
* least `heightTotal`. This routine is mentioned on page 442 of the TeXbook.
*/
var makeStackedDelim = function(delim, heightTotal, center, options, mode,
const makeStackedDelim = function(delim, heightTotal, center, options, mode,
classes) {
// There are four parts, the top, an optional middle, a repeated part, and a
// bottom.
var top;
var middle;
var repeat;
var bottom;
let top;
let middle;
let repeat;
let bottom;
top = repeat = bottom = delim;
middle = null;
// Also keep track of what font the delimiters are in
var font = "Size1-Regular";
let font = "Size1-Regular";
// We set the parts and font based on the symbol. Note that we use
// '\u23d0' instead of '|' and '\u2016' instead of '\\|' for the
@ -251,65 +251,64 @@ var makeStackedDelim = function(delim, heightTotal, center, options, mode,
}
// Get the metrics of the four sections
var topMetrics = getMetrics(top, font);
var topHeightTotal = topMetrics.height + topMetrics.depth;
var repeatMetrics = getMetrics(repeat, font);
var repeatHeightTotal = repeatMetrics.height + repeatMetrics.depth;
var bottomMetrics = getMetrics(bottom, font);
var bottomHeightTotal = bottomMetrics.height + bottomMetrics.depth;
var middleHeightTotal = 0;
var middleFactor = 1;
const topMetrics = getMetrics(top, font);
const topHeightTotal = topMetrics.height + topMetrics.depth;
const repeatMetrics = getMetrics(repeat, font);
const repeatHeightTotal = repeatMetrics.height + repeatMetrics.depth;
const bottomMetrics = getMetrics(bottom, font);
const bottomHeightTotal = bottomMetrics.height + bottomMetrics.depth;
let middleHeightTotal = 0;
let middleFactor = 1;
if (middle !== null) {
var middleMetrics = getMetrics(middle, font);
const middleMetrics = getMetrics(middle, font);
middleHeightTotal = middleMetrics.height + middleMetrics.depth;
middleFactor = 2; // repeat symmetrically above and below middle
}
// Calcuate the minimal height that the delimiter can have.
// It is at least the size of the top, bottom, and optional middle combined.
var minHeight = topHeightTotal + bottomHeightTotal + middleHeightTotal;
const minHeight = topHeightTotal + bottomHeightTotal + middleHeightTotal;
// Compute the number of copies of the repeat symbol we will need
var repeatCount = Math.ceil(
const repeatCount = Math.ceil(
(heightTotal - minHeight) / (middleFactor * repeatHeightTotal));
// Compute the total height of the delimiter including all the symbols
var realHeightTotal =
const realHeightTotal =
minHeight + repeatCount * middleFactor * repeatHeightTotal;
// The center of the delimiter is placed at the center of the axis. Note
// that in this context, "center" means that the delimiter should be
// centered around the axis in the current style, while normally it is
// centered around the axis in textstyle.
var axisHeight = options.style.metrics.axisHeight;
let axisHeight = options.style.metrics.axisHeight;
if (center) {
axisHeight *= options.style.sizeMultiplier;
}
// Calculate the depth
var depth = realHeightTotal / 2 - axisHeight;
const depth = realHeightTotal / 2 - axisHeight;
// Now, we start building the pieces that will go into the vlist
// Keep a list of the inner pieces
var inners = [];
const inners = [];
// Add the bottom symbol
inners.push(makeInner(bottom, font, mode));
var i;
if (middle === null) {
// Add that many symbols
for (i = 0; i < repeatCount; i++) {
for (let i = 0; i < repeatCount; i++) {
inners.push(makeInner(repeat, font, mode));
}
} else {
// When there is a middle bit, we need the middle part and two repeated
// sections
for (i = 0; i < repeatCount; i++) {
for (let i = 0; i < repeatCount; i++) {
inners.push(makeInner(repeat, font, mode));
}
inners.push(makeInner(middle, font, mode));
for (i = 0; i < repeatCount; i++) {
for (let i = 0; i < repeatCount; i++) {
inners.push(makeInner(repeat, font, mode));
}
}
@ -318,7 +317,7 @@ var makeStackedDelim = function(delim, heightTotal, center, options, mode,
inners.push(makeInner(top, font, mode));
// Finally, build the vlist
var inner = buildCommon.makeVList(inners, "bottom", depth, options);
const inner = buildCommon.makeVList(inners, "bottom", depth, options);
return styleWrap(
makeSpan(["delimsizing", "mult"], [inner], options),
@ -327,7 +326,7 @@ var makeStackedDelim = function(delim, heightTotal, center, options, mode,
// There are three kinds of delimiters, delimiters that stack when they become
// too large
var stackLargeDelimiters = [
const stackLargeDelimiters = [
"(", ")", "[", "\\lbrack", "]", "\\rbrack",
"\\{", "\\lbrace", "\\}", "\\rbrace",
"\\lfloor", "\\rfloor", "\\lceil", "\\rceil",
@ -335,7 +334,7 @@ var stackLargeDelimiters = [
];
// delimiters that always stack
var stackAlwaysDelimiters = [
const stackAlwaysDelimiters = [
"\\uparrow", "\\downarrow", "\\updownarrow",
"\\Uparrow", "\\Downarrow", "\\Updownarrow",
"|", "\\|", "\\vert", "\\Vert",
@ -344,19 +343,19 @@ var stackAlwaysDelimiters = [
];
// and delimiters that never stack
var stackNeverDelimiters = [
const stackNeverDelimiters = [
"<", ">", "\\langle", "\\rangle", "/", "\\backslash", "\\lt", "\\gt",
];
// Metrics of the different sizes. Found by looking at TeX's output of
// $\bigl| // \Bigl| \biggl| \Biggl| \showlists$
// Used to create stacked delimiters of appropriate sizes in makeSizedDelim.
var sizeToMaxHeight = [0, 1.2, 1.8, 2.4, 3.0];
const sizeToMaxHeight = [0, 1.2, 1.8, 2.4, 3.0];
/**
* Used to create a delimiter of a specific size, where `size` is 1, 2, 3, or 4.
*/
var makeSizedDelim = function(delim, size, options, mode, classes) {
const makeSizedDelim = function(delim, size, options, mode, classes) {
// < and > turn into \langle and \rangle in delimiters
if (delim === "<" || delim === "\\lt") {
delim = "\\langle";
@ -389,7 +388,7 @@ var makeSizedDelim = function(delim, size, options, mode, classes) {
*/
// Delimiters that never stack try small delimiters and large delimiters only
var stackNeverDelimiterSequence = [
const stackNeverDelimiterSequence = [
{type: "small", style: Style.SCRIPTSCRIPT},
{type: "small", style: Style.SCRIPT},
{type: "small", style: Style.TEXT},
@ -400,7 +399,7 @@ var stackNeverDelimiterSequence = [
];
// Delimiters that always stack try the small delimiters first, then stack
var stackAlwaysDelimiterSequence = [
const stackAlwaysDelimiterSequence = [
{type: "small", style: Style.SCRIPTSCRIPT},
{type: "small", style: Style.SCRIPT},
{type: "small", style: Style.TEXT},
@ -409,7 +408,7 @@ var stackAlwaysDelimiterSequence = [
// Delimiters that stack when large try the small and then large delimiters, and
// stack afterwards
var stackLargeDelimiterSequence = [
const stackLargeDelimiterSequence = [
{type: "small", style: Style.SCRIPTSCRIPT},
{type: "small", style: Style.SCRIPT},
{type: "small", style: Style.TEXT},
@ -423,7 +422,7 @@ var stackLargeDelimiterSequence = [
/**
* Get the font used in a delimiter based on what kind of delimiter it is.
*/
var delimTypeToFont = function(type) {
const delimTypeToFont = function(type) {
if (type.type === "small") {
return "Main-Regular";
} else if (type.type === "large") {
@ -437,20 +436,20 @@ var delimTypeToFont = function(type) {
* Traverse a sequence of types of delimiters to decide what kind of delimiter
* should be used to create a delimiter of the given height+depth.
*/
var traverseSequence = function(delim, height, sequence, options) {
const traverseSequence = function(delim, height, sequence, options) {
// Here, we choose the index we should start at in the sequences. In smaller
// sizes (which correspond to larger numbers in style.size) we start earlier
// in the sequence. Thus, scriptscript starts at index 3-3=0, script starts
// at index 3-2=1, text starts at 3-1=2, and display starts at min(2,3-0)=2
var start = Math.min(2, 3 - options.style.size);
for (var i = start; i < sequence.length; i++) {
const start = Math.min(2, 3 - options.style.size);
for (let i = start; i < sequence.length; i++) {
if (sequence[i].type === "stack") {
// This is always the last delimiter, so we just break the loop now.
break;
}
var metrics = getMetrics(delim, delimTypeToFont(sequence[i]));
var heightDepth = metrics.height + metrics.depth;
const metrics = getMetrics(delim, delimTypeToFont(sequence[i]));
let heightDepth = metrics.height + metrics.depth;
// Small delimiters are scaled down versions of the same font, so we
// account for the style change size.
@ -473,7 +472,7 @@ var traverseSequence = function(delim, height, sequence, options) {
* Make a delimiter of a given height+depth, with optional centering. Here, we
* traverse the sequences, and create a delimiter that the sequence tells us to.
*/
var makeCustomSizedDelim = function(delim, height, center, options, mode,
const makeCustomSizedDelim = function(delim, height, center, options, mode,
classes) {
if (delim === "<" || delim === "\\lt") {
delim = "\\langle";
@ -482,7 +481,7 @@ var makeCustomSizedDelim = function(delim, height, center, options, mode,
}
// Decide what sequence to use
var sequence;
let sequence;
if (utils.contains(stackNeverDelimiters, delim)) {
sequence = stackNeverDelimiterSequence;
} else if (utils.contains(stackLargeDelimiters, delim)) {
@ -492,7 +491,7 @@ var makeCustomSizedDelim = function(delim, height, center, options, mode,
}
// Look through the sequence
var delimType = traverseSequence(delim, height, sequence, options);
const delimType = traverseSequence(delim, height, sequence, options);
// Depending on the sequence element we decided on, call the appropriate
// function.
@ -511,20 +510,20 @@ var makeCustomSizedDelim = function(delim, height, center, options, mode,
* Make a delimiter for use with `\left` and `\right`, given a height and depth
* of an expression that the delimiters surround.
*/
var makeLeftRightDelim = function(delim, height, depth, options, mode,
const makeLeftRightDelim = function(delim, height, depth, options, mode,
classes) {
// We always center \left/\right delimiters, so the axis is always shifted
var axisHeight =
const axisHeight =
options.style.metrics.axisHeight * options.style.sizeMultiplier;
// Taken from TeX source, tex.web, function make_left_right
var delimiterFactor = 901;
var delimiterExtend = 5.0 / fontMetrics.metrics.ptPerEm;
const delimiterFactor = 901;
const delimiterExtend = 5.0 / fontMetrics.metrics.ptPerEm;
var maxDistFromAxis = Math.max(
const maxDistFromAxis = Math.max(
height - axisHeight, depth + axisHeight);
var totalHeight = Math.max(
const totalHeight = Math.max(
// In real TeX, calculations are done using integral values which are
// 65536 per pt, or 655360 per em. So, the division here truncates in
// TeX but doesn't here, producing different results. If we wanted to

View File

@ -7,16 +7,16 @@
*
* Similar functions for working with MathML nodes exist in mathMLTree.js.
*/
var unicodeRegexes = require("./unicodeRegexes");
var utils = require("./utils");
const unicodeRegexes = require("./unicodeRegexes");
const utils = require("./utils");
/**
* Create an HTML className based on a list of classes. In addition to joining
* with spaces, we also remove null or empty classes.
*/
var createClass = function(classes) {
const createClass = function(classes) {
classes = classes.slice();
for (var i = classes.length - 1; i >= 0; i--) {
for (let i = classes.length - 1; i >= 0; i--) {
if (!classes[i]) {
classes.splice(i, 1);
}
@ -65,27 +65,27 @@ span.prototype.tryCombine = function(sibling) {
* Convert the span into an HTML node
*/
span.prototype.toNode = function() {
var span = document.createElement("span");
const span = document.createElement("span");
// Apply the class
span.className = createClass(this.classes);
// Apply inline styles
for (var style in this.style) {
for (const style in this.style) {
if (Object.prototype.hasOwnProperty.call(this.style, style)) {
span.style[style] = this.style[style];
}
}
// Apply attributes
for (var attr in this.attributes) {
for (const attr in this.attributes) {
if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
span.setAttribute(attr, this.attributes[attr]);
}
}
// Append the children, also as HTML nodes
for (var i = 0; i < this.children.length; i++) {
for (let i = 0; i < this.children.length; i++) {
span.appendChild(this.children[i].toNode());
}
@ -96,7 +96,7 @@ span.prototype.toNode = function() {
* Convert the span into an HTML markup string
*/
span.prototype.toMarkup = function() {
var markup = "<span";
let markup = "<span";
// Add the class
if (this.classes.length) {
@ -105,10 +105,10 @@ span.prototype.toMarkup = function() {
markup += "\"";
}
var styles = "";
let styles = "";
// Add the styles, after hyphenation
for (var style in this.style) {
for (const style in this.style) {
if (this.style.hasOwnProperty(style)) {
styles += utils.hyphenate(style) + ":" + this.style[style] + ";";
}
@ -119,7 +119,7 @@ span.prototype.toMarkup = function() {
}
// Add the attributes
for (var attr in this.attributes) {
for (const attr in this.attributes) {
if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
markup += " " + attr + "=\"";
markup += utils.escape(this.attributes[attr]);
@ -130,7 +130,7 @@ span.prototype.toMarkup = function() {
markup += ">";
// Add the markup of the children, also as markup
for (var i = 0; i < this.children.length; i++) {
for (let i = 0; i < this.children.length; i++) {
markup += this.children[i].toMarkup();
}
@ -157,10 +157,10 @@ function documentFragment(children) {
*/
documentFragment.prototype.toNode = function() {
// Create a fragment
var frag = document.createDocumentFragment();
const frag = document.createDocumentFragment();
// Append the children
for (var i = 0; i < this.children.length; i++) {
for (let i = 0; i < this.children.length; i++) {
frag.appendChild(this.children[i].toNode());
}
@ -171,17 +171,17 @@ documentFragment.prototype.toNode = function() {
* Convert the fragment into HTML markup
*/
documentFragment.prototype.toMarkup = function() {
var markup = "";
let markup = "";
// Simply concatenate the markup for the children together
for (var i = 0; i < this.children.length; i++) {
for (let i = 0; i < this.children.length; i++) {
markup += this.children[i].toMarkup();
}
return markup;
};
var iCombinations = {
const iCombinations = {
'î': '\u0131\u0302',
'ï': '\u0131\u0308',
'í': '\u0131\u0301',
@ -233,13 +233,13 @@ symbolNode.prototype.tryCombine = function(sibling) {
|| this.maxFontSize !== sibling.maxFontSize) {
return false;
}
for (var style in this.style) {
for (const style in this.style) {
if (this.style.hasOwnProperty(style)
&& this.style[style] !== sibling.style[style]) {
return false;
}
}
for (style in sibling.style) {
for (const style in sibling.style) {
if (sibling.style.hasOwnProperty(style)
&& this.style[style] !== sibling.style[style]) {
return false;
@ -257,8 +257,8 @@ symbolNode.prototype.tryCombine = function(sibling) {
* created if it is needed.
*/
symbolNode.prototype.toNode = function() {
var node = document.createTextNode(this.value);
var span = null;
const node = document.createTextNode(this.value);
let span = null;
if (this.italic > 0) {
span = document.createElement("span");
@ -270,7 +270,7 @@ symbolNode.prototype.toNode = function() {
span.className = createClass(this.classes);
}
for (var style in this.style) {
for (const style in this.style) {
if (this.style.hasOwnProperty(style)) {
span = span || document.createElement("span");
span.style[style] = this.style[style];
@ -291,9 +291,9 @@ symbolNode.prototype.toNode = function() {
symbolNode.prototype.toMarkup = function() {
// TODO(alpert): More duplication than I'd like from
// span.prototype.toMarkup and symbolNode.prototype.toNode...
var needsSpan = false;
let needsSpan = false;
var markup = "<span";
let markup = "<span";
if (this.classes.length) {
needsSpan = true;
@ -302,12 +302,12 @@ symbolNode.prototype.toMarkup = function() {
markup += "\"";
}
var styles = "";
let styles = "";
if (this.italic > 0) {
styles += "margin-right:" + this.italic + "em;";
}
for (var style in this.style) {
for (const style in this.style) {
if (this.style.hasOwnProperty(style)) {
styles += utils.hyphenate(style) + ":" + this.style[style] + ";";
}
@ -318,7 +318,7 @@ symbolNode.prototype.toMarkup = function() {
markup += " style=\"" + utils.escape(styles) + "\"";
}
var escaped = utils.escape(this.value);
const escaped = utils.escape(this.value);
if (needsSpan) {
markup += ">";
markup += escaped;

View File

@ -1,9 +1,9 @@
/* eslint no-constant-condition:0 */
var parseData = require("./parseData");
var ParseError = require("./ParseError");
var Style = require("./Style");
const parseData = require("./parseData");
const ParseError = require("./ParseError");
const Style = require("./Style");
var ParseNode = parseData.ParseNode;
const ParseNode = parseData.ParseNode;
/**
* Parse the body of the environment, with rows delimited by \\ and
@ -11,19 +11,19 @@ var ParseNode = parseData.ParseNode;
* with one group per cell.
*/
function parseArray(parser, result) {
var row = [];
var body = [row];
var rowGaps = [];
let row = [];
const body = [row];
const rowGaps = [];
while (true) {
var cell = parser.parseExpression(false, null);
const cell = parser.parseExpression(false, null);
row.push(new ParseNode("ordgroup", cell, parser.mode));
var next = parser.nextToken.text;
const next = parser.nextToken.text;
if (next === "&") {
parser.consume();
} else if (next === "\\end") {
break;
} else if (next === "\\\\" || next === "\\cr") {
var cr = parser.parseFunction();
const cr = parser.parseFunction();
rowGaps.push(cr.value.size);
row = [];
body.push(row);
@ -69,7 +69,7 @@ function defineEnvironment(names, props, handler) {
props = { numArgs: props };
}
// Set default values of environments
var data = {
const data = {
numArgs: props.numArgs || 0,
argTypes: props.argTypes,
greediness: 1,
@ -77,7 +77,7 @@ function defineEnvironment(names, props, handler) {
numOptionalArgs: props.numOptionalArgs || 0,
handler: handler,
};
for (var i = 0; i < names.length; ++i) {
for (let i = 0; i < names.length; ++i) {
module.exports[names[i]] = data;
}
}
@ -87,10 +87,10 @@ function defineEnvironment(names, props, handler) {
defineEnvironment("array", {
numArgs: 1,
}, function(context, args) {
var colalign = args[0];
let colalign = args[0];
colalign = colalign.value.map ? colalign.value : [colalign];
var cols = colalign.map(function(node) {
var ca = node.value;
const cols = colalign.map(function(node) {
const ca = node.value;
if ("lcr".indexOf(ca) !== -1) {
return {
type: "align",
@ -106,7 +106,7 @@ defineEnvironment("array", {
"Unknown column alignment: " + node.value,
node);
});
var res = {
let res = {
type: "array",
cols: cols,
hskipBeforeAndAfter: true, // \@preamble in lttab.dtx
@ -126,7 +126,7 @@ defineEnvironment([
"Vmatrix",
], {
}, function(context) {
var delimiters = {
const delimiters = {
"matrix": null,
"pmatrix": ["(", ")"],
"bmatrix": ["[", "]"],
@ -134,7 +134,7 @@ defineEnvironment([
"vmatrix": ["|", "|"],
"Vmatrix": ["\\Vert", "\\Vert"],
}[context.envName];
var res = {
let res = {
type: "array",
hskipBeforeAndAfter: false, // \hskip -\arraycolsep in amsmath
};
@ -154,7 +154,7 @@ defineEnvironment([
// \left\{\begin{array}{@{}l@{\quad}l@{}} … \end{array}\right.
defineEnvironment("cases", {
}, function(context) {
var res = {
let res = {
type: "array",
arraystretch: 1.2,
cols: [{
@ -188,25 +188,24 @@ defineEnvironment("cases", {
// so that \strut@ is the same as \strut.
defineEnvironment("aligned", {
}, function(context) {
var res = {
let res = {
type: "array",
cols: [],
};
res = parseArray(context.parser, res);
var emptyGroup = new ParseNode("ordgroup", [], context.mode);
var numCols = 0;
const emptyGroup = new ParseNode("ordgroup", [], context.mode);
let numCols = 0;
res.value.body.forEach(function(row) {
var i;
for (i = 1; i < row.length; i += 2) {
for (let i = 1; i < row.length; i += 2) {
row[i].value.unshift(emptyGroup);
}
if (numCols < row.length) {
numCols = row.length;
}
});
for (var i = 0; i < numCols; ++i) {
var align = "r";
var pregap = 0;
for (let i = 0; i < numCols; ++i) {
let align = "r";
let pregap = 0;
if (i % 2 === 1) {
align = "l";
} else if (i > 0) {

View File

@ -1,7 +1,7 @@
/* eslint no-unused-vars:0 */
var Style = require("./Style");
var cjkRegex = require("./unicodeRegexes").cjkRegex;
const Style = require("./Style");
const cjkRegex = require("./unicodeRegexes").cjkRegex;
/**
* This file contains metrics regarding fonts and individual symbols. The sigma
@ -32,7 +32,7 @@ var cjkRegex = require("./unicodeRegexes").cjkRegex;
//
// The output of each of these commands is quite lengthy. The only part we
// care about is the FONTDIMEN section. Each value is measured in EMs.
var sigmas = {
const sigmas = {
slant: [0.250, 0.250, 0.250], // sigma1
space: [0.000, 0.000, 0.000], // sigma2
stretch: [0.000, 0.000, 0.000], // sigma3
@ -62,34 +62,34 @@ var sigmas = {
// \showthe\fontdimenX\a
// where X is the corresponding variable number. These correspond to the font
// parameters of the extension fonts (family 3). See the TeXbook, page 441.
var xi1 = 0;
var xi2 = 0;
var xi3 = 0;
var xi4 = 0;
var xi5 = 0.431;
var xi6 = 1;
var xi7 = 0;
var xi8 = 0.04;
var xi9 = 0.111;
var xi10 = 0.166;
var xi11 = 0.2;
var xi12 = 0.6;
var xi13 = 0.1;
const xi1 = 0;
const xi2 = 0;
const xi3 = 0;
const xi4 = 0;
const xi5 = 0.431;
const xi6 = 1;
const xi7 = 0;
const xi8 = 0.04;
const xi9 = 0.111;
const xi10 = 0.166;
const xi11 = 0.2;
const xi12 = 0.6;
const xi13 = 0.1;
// This value determines how large a pt is, for metrics which are defined in
// terms of pts.
// This value is also used in katex.less; if you change it make sure the values
// match.
var ptPerEm = 10.0;
const ptPerEm = 10.0;
// The space between adjacent `|` columns in an array definition. From
// `\showthe\doublerulesep` in LaTeX.
var doubleRuleSep = 2.0 / ptPerEm;
const doubleRuleSep = 2.0 / ptPerEm;
/**
* This is just a mapping from common names to real metrics
*/
var metrics = {
const metrics = {
defaultRuleThickness: xi8,
bigOpSpacing1: xi9,
bigOpSpacing2: xi10,
@ -104,7 +104,7 @@ var metrics = {
// metrics, including height, depth, italic correction, and skew (kern from the
// character to the corresponding \skewchar)
// This map is generated via `make metrics`. It should not be changed manually.
var metricMap = require("./fontMetricsData");
const metricMap = require("./fontMetricsData");
// These are very rough approximations. We default to Times New Roman which
// should have Latin-1 and Cyrillic characters, but may not depending on the
@ -113,7 +113,7 @@ var metricMap = require("./fontMetricsData");
// descenders we prefer approximations with ascenders, primarily to prevent
// the fraction bar or root line from intersecting the glyph.
// TODO(kevinb) allow union of multiple glyph metrics for better accuracy.
var extraCharacterMap = {
const extraCharacterMap = {
// Latin-1
'À': 'A',
'Á': 'A',
@ -252,14 +252,14 @@ var extraCharacterMap = {
* Note: the `width` property may be undefined if fontMetricsData.js wasn't
* built using `Make extended_metrics`.
*/
var getCharacterMetrics = function(character, style) {
var ch = character.charCodeAt(0);
const getCharacterMetrics = function(character, style) {
let ch = character.charCodeAt(0);
if (character[0] in extraCharacterMap) {
ch = extraCharacterMap[character[0]].charCodeAt(0);
} else if (cjkRegex.test(character[0])) {
ch = 'M'.charCodeAt(0);
}
var metrics = metricMap[style][ch];
const metrics = metricMap[style][ch];
if (metrics) {
return {
depth: metrics[0],

View File

@ -1,7 +1,7 @@
var utils = require("./utils");
var ParseError = require("./ParseError");
var parseData = require("./parseData");
var ParseNode = parseData.ParseNode;
const utils = require("./utils");
const ParseError = require("./ParseError");
const parseData = require("./parseData");
const ParseNode = parseData.ParseNode;
/* This file contains a list of functions that we parse, identified by
* the calls to defineFunction.
@ -88,7 +88,7 @@ function defineFunction(names, props, handler) {
props = { numArgs: props };
}
// Set default values of functions
var data = {
const data = {
numArgs: props.numArgs,
argTypes: props.argTypes,
greediness: (props.greediness === undefined) ? 1 : props.greediness,
@ -97,14 +97,14 @@ function defineFunction(names, props, handler) {
infix: !!props.infix,
handler: handler,
};
for (var i = 0; i < names.length; ++i) {
for (let i = 0; i < names.length; ++i) {
module.exports[names[i]] = data;
}
}
// Since the corresponding buildHTML/buildMathML function expects a
// list of elements, we normalize for different kinds of arguments
var ordargument = function(arg) {
const ordargument = function(arg) {
if (arg.type === "ordgroup") {
return arg.value;
} else {
@ -117,8 +117,8 @@ defineFunction("\\sqrt", {
numArgs: 1,
numOptionalArgs: 1,
}, function(context, args) {
var index = args[0];
var body = args[1];
const index = args[0];
const body = args[1];
return {
type: "sqrt",
body: body,
@ -127,7 +127,7 @@ defineFunction("\\sqrt", {
});
// Non-mathy text, possibly in a font
var textFunctionStyles = {
const textFunctionStyles = {
"\\text": undefined, "\\textrm": "mathrm", "\\textsf": "mathsf",
"\\texttt": "mathtt", "\\textnormal": "mathrm", "\\textbf": "mathbf",
"\\textit": "textit",
@ -142,7 +142,7 @@ defineFunction([
greediness: 2,
allowedInText: true,
}, function(context, args) {
var body = args[0];
const body = args[0];
return {
type: "text",
body: ordargument(body),
@ -157,8 +157,8 @@ defineFunction("\\color", {
greediness: 3,
argTypes: ["color", "original"],
}, function(context, args) {
var color = args[0];
var body = args[1];
const color = args[0];
const body = args[1];
return {
type: "color",
color: color.value,
@ -170,7 +170,7 @@ defineFunction("\\color", {
defineFunction("\\overline", {
numArgs: 1,
}, function(context, args) {
var body = args[0];
const body = args[0];
return {
type: "overline",
body: body,
@ -181,7 +181,7 @@ defineFunction("\\overline", {
defineFunction("\\underline", {
numArgs: 1,
}, function(context, args) {
var body = args[0];
const body = args[0];
return {
type: "underline",
body: body,
@ -194,9 +194,9 @@ defineFunction("\\rule", {
numOptionalArgs: 1,
argTypes: ["size", "size", "size"],
}, function(context, args) {
var shift = args[0];
var width = args[1];
var height = args[2];
const shift = args[0];
const width = args[1];
const height = args[2];
return {
type: "rule",
shift: shift && shift.value,
@ -229,7 +229,7 @@ defineFunction("\\KaTeX", {
defineFunction("\\phantom", {
numArgs: 1,
}, function(context, args) {
var body = args[0];
const body = args[0];
return {
type: "phantom",
value: ordargument(body),
@ -243,7 +243,7 @@ defineFunction([
], {
numArgs: 1,
}, function(context, args) {
var body = args[0];
const body = args[0];
return {
type: "mclass",
mclass: "m" + context.funcName.substr(5),
@ -255,10 +255,10 @@ defineFunction([
defineFunction("\\stackrel", {
numArgs: 2,
}, function(context, args) {
var top = args[0];
var bottom = args[1];
const top = args[0];
const bottom = args[1];
var bottomop = new ParseNode("op", {
const bottomop = new ParseNode("op", {
type: "op",
limits: true,
alwaysHandleSupSub: true,
@ -266,7 +266,7 @@ defineFunction("\\stackrel", {
value: ordargument(bottom),
}, bottom.mode);
var supsub = new ParseNode("supsub", {
const supsub = new ParseNode("supsub", {
base: bottomop,
sup: top,
sub: null,
@ -293,7 +293,7 @@ defineFunction("\\bmod", {
defineFunction(["\\pod", "\\pmod", "\\mod"], {
numArgs: 1,
}, function(context, args) {
var body = args[0];
const body = args[0];
return {
type: "mod",
modType: context.funcName.substr(1),
@ -302,7 +302,7 @@ defineFunction(["\\pod", "\\pmod", "\\mod"], {
});
// Extra data needed for the delimiter handler down below
var delimiterSizes = {
const delimiterSizes = {
"\\bigl" : {mclass: "mopen", size: 1},
"\\Bigl" : {mclass: "mopen", size: 2},
"\\biggl": {mclass: "mopen", size: 3},
@ -321,7 +321,7 @@ var delimiterSizes = {
"\\Bigg" : {mclass: "mord", size: 4},
};
var delimiters = [
const delimiters = [
"(", ")", "[", "\\lbrack", "]", "\\rbrack",
"\\{", "\\lbrace", "\\}", "\\rbrace",
"\\lfloor", "\\rfloor", "\\lceil", "\\rceil",
@ -336,7 +336,7 @@ var delimiters = [
".",
];
var fontAliases = {
const fontAliases = {
"\\Bbb": "\\mathbb",
"\\bold": "\\mathbf",
"\\frak": "\\mathfrak",
@ -362,7 +362,7 @@ defineFunction([
allowedInText: true,
greediness: 3,
}, function(context, args) {
var body = args[0];
const body = args[0];
return {
type: "color",
color: "katex-" + context.funcName.slice(1),
@ -440,7 +440,7 @@ defineFunction([
defineFunction("\\mathop", {
numArgs: 1,
}, function(context, args) {
var body = args[0];
const body = args[0];
return {
type: "op",
limits: false,
@ -458,12 +458,12 @@ defineFunction([
numArgs: 2,
greediness: 2,
}, function(context, args) {
var numer = args[0];
var denom = args[1];
var hasBarLine;
var leftDelim = null;
var rightDelim = null;
var size = "auto";
const numer = args[0];
const denom = args[1];
let hasBarLine;
let leftDelim = null;
let rightDelim = null;
let size = "auto";
switch (context.funcName) {
case "\\dfrac":
@ -512,7 +512,7 @@ defineFunction(["\\llap", "\\rlap"], {
numArgs: 1,
allowedInText: true,
}, function(context, args) {
var body = args[0];
const body = args[0];
return {
type: context.funcName.slice(1),
body: body,
@ -520,7 +520,7 @@ defineFunction(["\\llap", "\\rlap"], {
});
// Delimiter functions
var checkDelimiter = function(delim, context) {
const checkDelimiter = function(delim, context) {
if (utils.contains(delimiters, delim.value)) {
return delim;
} else {
@ -538,7 +538,7 @@ defineFunction([
], {
numArgs: 1,
}, function(context, args) {
var delim = checkDelimiter(args[0], context);
const delim = checkDelimiter(args[0], context);
return {
type: "delimsizing",
@ -553,7 +553,7 @@ defineFunction([
], {
numArgs: 1,
}, function(context, args) {
var delim = checkDelimiter(args[0], context);
const delim = checkDelimiter(args[0], context);
// \left and \right are caught somewhere in Parser.js, which is
// why this data doesn't match what is in buildHTML.
@ -566,7 +566,7 @@ defineFunction([
defineFunction("\\middle", {
numArgs: 1,
}, function(context, args) {
var delim = checkDelimiter(args[0], context);
const delim = checkDelimiter(args[0], context);
if (!context.parser.leftrightDepth) {
throw new ParseError("\\middle without preceding \\left", delim);
}
@ -604,8 +604,8 @@ defineFunction([
numArgs: 1,
greediness: 2,
}, function(context, args) {
var body = args[0];
var func = context.funcName;
const body = args[0];
let func = context.funcName;
if (func in fontAliases) {
func = fontAliases[func];
}
@ -625,7 +625,7 @@ defineFunction([
], {
numArgs: 1,
}, function(context, args) {
var base = args[0];
const base = args[0];
return {
type: "accent",
accent: context.funcName,
@ -638,7 +638,7 @@ defineFunction(["\\over", "\\choose", "\\atop"], {
numArgs: 0,
infix: true,
}, function(context) {
var replaceWith;
let replaceWith;
switch (context.funcName) {
case "\\over":
replaceWith = "\\frac";
@ -665,7 +665,7 @@ defineFunction(["\\\\", "\\cr"], {
numOptionalArgs: 1,
argTypes: ["size"],
}, function(context, args) {
var size = args[0];
const size = args[0];
return {
type: "cr",
size: size,
@ -677,12 +677,12 @@ defineFunction(["\\begin", "\\end"], {
numArgs: 1,
argTypes: ["text"],
}, function(context, args) {
var nameGroup = args[0];
const nameGroup = args[0];
if (nameGroup.type !== "ordgroup") {
throw new ParseError("Invalid environment name", nameGroup);
}
var name = "";
for (var i = 0; i < nameGroup.value.length; ++i) {
let name = "";
for (let i = 0; i < nameGroup.value.length; ++i) {
name += nameGroup.value[i].value;
}
return {

View File

@ -8,7 +8,7 @@
* domTree.js, creating namespaced DOM nodes and HTML text markup respectively.
*/
var utils = require("./utils");
const utils = require("./utils");
/**
* This node represents a general purpose MathML node of any type. The
@ -33,16 +33,16 @@ MathNode.prototype.setAttribute = function(name, value) {
* Converts the math node into a MathML-namespaced DOM element.
*/
MathNode.prototype.toNode = function() {
var node = document.createElementNS(
const node = document.createElementNS(
"http://www.w3.org/1998/Math/MathML", this.type);
for (var attr in this.attributes) {
for (const attr in this.attributes) {
if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
node.setAttribute(attr, this.attributes[attr]);
}
}
for (var i = 0; i < this.children.length; i++) {
for (let i = 0; i < this.children.length; i++) {
node.appendChild(this.children[i].toNode());
}
@ -53,10 +53,10 @@ MathNode.prototype.toNode = function() {
* Converts the math node into an HTML markup string.
*/
MathNode.prototype.toMarkup = function() {
var markup = "<" + this.type;
let markup = "<" + this.type;
// Add the attributes
for (var attr in this.attributes) {
for (const attr in this.attributes) {
if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
markup += " " + attr + "=\"";
markup += utils.escape(this.attributes[attr]);
@ -66,7 +66,7 @@ MathNode.prototype.toMarkup = function() {
markup += ">";
for (var i = 0; i < this.children.length; i++) {
for (let i = 0; i < this.children.length; i++) {
markup += this.children[i].toMarkup();
}

View File

@ -3,16 +3,16 @@
* TODO(emily): Remove this
*/
var Parser = require("./Parser");
const Parser = require("./Parser");
/**
* Parses an expression using a Parser, then returns the parsed result.
*/
var parseTree = function(toParse, settings) {
const parseTree = function(toParse, settings) {
if (!(typeof toParse === 'string' || toParse instanceof String)) {
throw new TypeError('KaTeX can only parse string typed expression');
}
var parser = new Parser(toParse, settings);
const parser = new Parser(toParse, settings);
return parser.parse();
};

View File

@ -33,25 +33,25 @@ function defineSymbol(mode, font, group, replace, name) {
// This helps minify the code, and also spotting typos using jshint.
// modes:
var math = "math";
var text = "text";
const math = "math";
const text = "text";
// fonts:
var main = "main";
var ams = "ams";
const main = "main";
const ams = "ams";
// groups:
var accent = "accent";
var bin = "bin";
var close = "close";
var inner = "inner";
var mathord = "mathord";
var op = "op";
var open = "open";
var punct = "punct";
var rel = "rel";
var spacing = "spacing";
var textord = "textord";
const accent = "accent";
const bin = "bin";
const close = "close";
const inner = "inner";
const mathord = "mathord";
const op = "op";
const open = "open";
const punct = "punct";
const rel = "rel";
const spacing = "spacing";
const textord = "textord";
// Now comes the symbol table
@ -616,50 +616,48 @@ defineSymbol(text, main, spacing, "\u00a0", " ");
defineSymbol(text, main, spacing, "\u00a0", "~");
// There are lots of symbols which are the same, so we add them in afterwards.
var i;
var ch;
// All of these are textords in math mode
var mathTextSymbols = "0123456789/@.\"";
for (i = 0; i < mathTextSymbols.length; i++) {
ch = mathTextSymbols.charAt(i);
const mathTextSymbols = "0123456789/@.\"";
for (let i = 0; i < mathTextSymbols.length; i++) {
const ch = mathTextSymbols.charAt(i);
defineSymbol(math, main, textord, ch, ch);
}
// All of these are textords in text mode
var textSymbols = "0123456789!@*()-=+[]\";:?/.,";
for (i = 0; i < textSymbols.length; i++) {
ch = textSymbols.charAt(i);
const textSymbols = "0123456789!@*()-=+[]\";:?/.,";
for (let i = 0; i < textSymbols.length; i++) {
const ch = textSymbols.charAt(i);
defineSymbol(text, main, textord, ch, ch);
}
// All of these are textords in text mode, and mathords in math mode
var letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (i = 0; i < letters.length; i++) {
ch = letters.charAt(i);
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (let i = 0; i < letters.length; i++) {
const ch = letters.charAt(i);
defineSymbol(math, main, mathord, ch, ch);
defineSymbol(text, main, textord, ch, ch);
}
// Latin-1 letters
for (i = 0x00C0; i <= 0x00D6; i++) {
ch = String.fromCharCode(i);
for (let i = 0x00C0; i <= 0x00D6; i++) {
const ch = String.fromCharCode(i);
defineSymbol(text, main, textord, ch, ch);
}
for (i = 0x00D8; i <= 0x00F6; i++) {
ch = String.fromCharCode(i);
for (let i = 0x00D8; i <= 0x00F6; i++) {
const ch = String.fromCharCode(i);
defineSymbol(text, main, textord, ch, ch);
}
for (i = 0x00F8; i <= 0x00FF; i++) {
ch = String.fromCharCode(i);
for (let i = 0x00F8; i <= 0x00FF; i++) {
const ch = String.fromCharCode(i);
defineSymbol(text, main, textord, ch, ch);
}
// Cyrillic
for (i = 0x0410; i <= 0x044F; i++) {
ch = String.fromCharCode(i);
for (let i = 0x0410; i <= 0x044F; i++) {
const ch = String.fromCharCode(i);
defineSymbol(text, main, textord, ch, ch);
}

View File

@ -1,4 +1,4 @@
var hangulRegex = /[\uAC00-\uD7AF]/;
const hangulRegex = /[\uAC00-\uD7AF]/;
// This regex combines
// - Hiragana: [\u3040-\u309F]
@ -6,7 +6,7 @@ var hangulRegex = /[\uAC00-\uD7AF]/;
// - CJK ideograms: [\u4E00-\u9FAF]
// - Hangul syllables: [\uAC00-\uD7AF]
// Notably missing are halfwidth Katakana and Romanji glyphs.
var cjkRegex =
const cjkRegex =
/[\u3040-\u309F]|[\u30A0-\u30FF]|[\u4E00-\u9FAF]|[\uAC00-\uD7AF]/;
module.exports = {

View File

@ -7,17 +7,16 @@
* Provide an `indexOf` function which works in IE8, but defers to native if
* possible.
*/
var nativeIndexOf = Array.prototype.indexOf;
var indexOf = function(list, elem) {
const nativeIndexOf = Array.prototype.indexOf;
const indexOf = function(list, elem) {
if (list == null) {
return -1;
}
if (nativeIndexOf && list.indexOf === nativeIndexOf) {
return list.indexOf(elem);
}
var i = 0;
var l = list.length;
for (; i < l; i++) {
const l = list.length;
for (let i = 0; i < l; i++) {
if (list[i] === elem) {
return i;
}
@ -28,25 +27,25 @@ var indexOf = function(list, elem) {
/**
* Return whether an element is contained in a list
*/
var contains = function(list, elem) {
const contains = function(list, elem) {
return indexOf(list, elem) !== -1;
};
/**
* Provide a default value if a setting is undefined
*/
var deflt = function(setting, defaultIfUndefined) {
const deflt = function(setting, defaultIfUndefined) {
return setting === undefined ? defaultIfUndefined : setting;
};
// hyphenate and escape adapted from Facebook's React under Apache 2 license
var uppercase = /([A-Z])/g;
var hyphenate = function(str) {
const uppercase = /([A-Z])/g;
const hyphenate = function(str) {
return str.replace(uppercase, "-$1").toLowerCase();
};
var ESCAPE_LOOKUP = {
const ESCAPE_LOOKUP = {
"&": "&amp;",
">": "&gt;",
"<": "&lt;",
@ -54,7 +53,7 @@ var ESCAPE_LOOKUP = {
"'": "&#x27;",
};
var ESCAPE_REGEX = /[&><"']/g;
const ESCAPE_REGEX = /[&><"']/g;
function escaper(match) {
return ESCAPE_LOOKUP[match];
@ -74,9 +73,9 @@ function escape(text) {
* A function to set the text content of a DOM element in all supported
* browsers. Note that we don't define this if there is no document.
*/
var setTextContent;
let setTextContent;
if (typeof document !== "undefined") {
var testNode = document.createElement("span");
const testNode = document.createElement("span");
if ("textContent" in testNode) {
setTextContent = function(node, text) {
node.textContent = text;

View File

@ -4,15 +4,15 @@
/* global it: false */
/* global describe: false */
var parseTree = require("../src/parseTree");
var Settings = require("../src/Settings");
const parseTree = require("../src/parseTree");
const Settings = require("../src/Settings");
var defaultSettings = new Settings({});
const defaultSettings = new Settings({});
beforeEach(function() {
jasmine.addMatchers({
toFailWithParseError: function(util, customEqualityTesters) {
var prefix = "KaTeX parse error: ";
const prefix = "KaTeX parse error: ";
return {
compare: function(actual, expected) {
try {
@ -28,8 +28,8 @@ beforeEach(function() {
message: "'" + actual + "' parsed with error",
};
}
var msg = e.message;
var exp = prefix + expected;
const msg = e.message;
const exp = prefix + expected;
if (msg === exp) {
return {
pass: true,

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,20 @@
/* eslint no-console:0 */
"use strict";
var fs = require("fs");
var childProcess = require("child_process");
const fs = require("fs");
const childProcess = require("child_process");
var opts = require("nomnom")
const opts = require("nomnom")
.option("spacing", {
flag: true,
help: "Print mismatches involving spacing commands",
})
.parse();
var symbols = require("../src/symbols");
var keys = Object.keys(symbols.math);
const symbols = require("../src/symbols");
const keys = Object.keys(symbols.math);
keys.sort();
var types = [
const types = [
"mathord", "op", "bin", "rel", "open", "close", "punct", "inner",
"spacing", "accent", "textord",
];
@ -22,22 +22,22 @@ var types = [
process.nextTick(writeTexFile);
function writeTexFile() {
var tex = fs.createWriteStream("symgroups.tex");
const tex = fs.createWriteStream("symgroups.tex");
tex.on("finish", typeset);
tex.write("\\documentclass{article}\n" +
"\\usepackage{textcomp,amsmath,amssymb,gensymb}\n" +
"\\begin{document}\n" +
"\\showboxbreadth=\\maxdimen\\showboxdepth=\\maxdimen\n\n");
keys.forEach(function(key, idx) {
var sym = symbols.math[key];
var type = types.indexOf(sym.group) + 1;
const sym = symbols.math[key];
const type = types.indexOf(sym.group) + 1;
tex.write("$" + idx + "+" + key + "+" + type + "\\showlists$\n\n");
});
tex.end("\\end{document}\n");
}
function typeset() {
var proc = childProcess.spawn(
const proc = childProcess.spawn(
"pdflatex", ["--interaction=nonstopmode", "symgroups"],
{stdio: "ignore"});
proc.on("exit", function(code, signal) {
@ -76,29 +76,29 @@ function typeset() {
*/
// Extract individual blocks, from switch to math mode up to switch back.
var reMM = /^### math mode entered.*\n([^]*?)###/mg;
const reMM = /^### math mode entered.*\n([^]*?)###/mg;
// Identify the parts separated by the plus signs
var reParts = /([^]*^\.\\fam0 \+\n)([^]+)(\\mathbin\n\.+\\fam0 \+[^]*)/m;
const reParts = /([^]*^\.\\fam0 \+\n)([^]+)(\\mathbin\n\.+\\fam0 \+[^]*)/m;
// Variation of the above in case we have nothing between the plus signs
var reEmpty = /^\.\\fam0 \+\n\\mathbin\n\.\\fam0 \+/m;
const reEmpty = /^\.\\fam0 \+\n\\mathbin\n\.\\fam0 \+/m;
// Match any printed digit in the first or last of these parts
var reDigit = /^\.\\fam0 ([0-9])/mg;
const reDigit = /^\.\\fam0 ([0-9])/mg;
// Match the atom type, i.e. "\mathrel" in the above example
var reAtom = /\\([a-z]+)/;
const reAtom = /\\([a-z]+)/;
function evaluate(err, log) {
if (err) {
throw err;
}
var match;
var nextIndex = 0;
let match;
let nextIndex = 0;
while ((match = reMM.exec(log)) !== null) {
var list = match[1];
const list = match[1];
match = reParts.exec(list);
if (!match) {
match = reEmpty.exec(list);
@ -113,9 +113,9 @@ function evaluate(err, log) {
console.error(list);
process.exit(2);
}
var idx = extractDigits(match[1]);
var atom = match[2];
var katexType = types[extractDigits(match[3]) - 1] || "???";
const idx = extractDigits(match[1]);
const atom = match[2];
const katexType = types[extractDigits(match[3]) - 1] || "???";
match = reAtom.exec(atom);
if (!match) {
console.error("Failed to find atom type");
@ -123,7 +123,7 @@ function evaluate(err, log) {
console.error(list);
process.exit(3);
}
var latexType = match[1];
const latexType = match[1];
if (katexType !== latexType && "math" + katexType !== latexType &&
(katexType !== "textord" || latexType !== "mathord") &&
(katexType !== "spacing" || opts.spacing)) {
@ -145,8 +145,8 @@ function evaluate(err, log) {
}
function extractDigits(str) {
var match;
var res = "";
let match;
let res = "";
while ((match = reDigit.exec(str)) !== null) {
res += match[1];
}

View File

@ -4,13 +4,13 @@
/* global expect: false */
/* global it: false */
/* global describe: false */
var ParseError = require("../src/ParseError");
var parseTree = require("../src/parseTree");
var Settings = require("../src/Settings");
const ParseError = require("../src/ParseError");
const parseTree = require("../src/parseTree");
const Settings = require("../src/Settings");
var defaultSettings = new Settings({});
const defaultSettings = new Settings({});
var parseAndSetResult = function(expr, result, settings) {
const parseAndSetResult = function(expr, result, settings) {
try {
return parseTree(expr, settings || defaultSettings);
} catch (e) {
@ -32,9 +32,9 @@ describe("unicode", function() {
toParse: function() {
return {
compare: function(actual, settings) {
var usedSettings = settings ? settings : defaultSettings;
const usedSettings = settings ? settings : defaultSettings;
var result = {
const result = {
pass: true,
message: "'" + actual + "' succeeded parsing",
};
@ -47,9 +47,9 @@ describe("unicode", function() {
toNotParse: function() {
return {
compare: function(actual, settings) {
var usedSettings = settings ? settings : defaultSettings;
const usedSettings = settings ? settings : defaultSettings;
var result = {
const result = {
pass: false,
message: "Expected '" + actual + "' to fail " +
"parsing, but it succeeded",