Skip to content

Commit

Permalink
Merge branch 'master' into screenshotter-diff
Browse files Browse the repository at this point in the history
  • Loading branch information
kohler committed Jul 5, 2017
2 parents 518336d + 1704d3b commit b3aa1b4
Show file tree
Hide file tree
Showing 57 changed files with 2,221 additions and 2,129 deletions.
3 changes: 2 additions & 1 deletion .babelrc
@@ -1,6 +1,7 @@
{
"presets": ["es2015"],
"plugins": [
"transform-runtime"
"transform-runtime",
"transform-class-properties"
]
}
3 changes: 2 additions & 1 deletion .eslintrc
@@ -1,4 +1,5 @@
{
"parser": "babel-eslint",
"rules": {
"arrow-spacing": 2,
"brace-style": [2, "1tbs", { "allowSingleLine": true }],
Expand All @@ -14,7 +15,7 @@
"indent": [2, 4, {"SwitchCase": 1}],
"keyword-spacing": 2,
"linebreak-style": [2, "unix"],
"max-len": [2, 80, 4, { "ignoreUrls": true, "ignorePattern": "\\brequire\\([\"']|eslint-disable" }],
"max-len": [2, 84, 4, { "ignoreUrls": true, "ignorePattern": "\\brequire\\([\"']|eslint-disable" }],
"no-alert": 2,
"no-array-constructor": 2,
"no-console": 2,
Expand Down
10 changes: 8 additions & 2 deletions CONTRIBUTING.md
Expand Up @@ -90,12 +90,18 @@ If you add a feature that is dependent on the final output looking the way you
created it, add a screenshot test. See
[ss_data.yaml](test/screenshotter/ss_data.yaml).

You can use our
[texcmp](https://github.com/Khan/KaTeX/tree/master/dockers/texcmp) tool
to compare the outputs of a screenshot test as generated by KaTeX and LaTeX.
It's often useful to attach the resulting "visual diff" to your pull request
with a new feature.

#### Testing in other browsers

KaTeX supports all major browsers, including IE 8 and newer. Unfortunately, it
KaTeX supports all major browsers, including IE 9 and newer. Unfortunately, it
is hard to test new changes in many browsers. If you can, please test your
changes in as many browsers as possible. In particular, if you make CSS changes,
try to test in IE 8, using [modern.ie](http://modern.ie) VMs.
try to test in IE 9, using [modern.ie](http://modern.ie) VMs.

## Style guide

Expand Down
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -9,7 +9,7 @@ KaTeX is a fast, easy-to-use JavaScript library for TeX math rendering on the we
* **Self contained:** KaTeX has no dependencies and can easily be bundled with your website resources.
* **Server side rendering:** KaTeX produces the same output regardless of browser or environment, so you can pre-render expressions using Node.js and send them as plain HTML.

KaTeX supports all major browsers, including Chrome, Safari, Firefox, Opera, and IE 8 - IE 11. A list of supported commands can be found on the [wiki](https://github.com/Khan/KaTeX/wiki/Function-Support-in-KaTeX).
KaTeX supports all major browsers, including Chrome, Safari, Firefox, Opera, Edge, and IE 9 - IE 11. A list of supported commands can be found on the [wiki](https://github.com/Khan/KaTeX/wiki/Function-Support-in-KaTeX).

## Usage

Expand Down
4 changes: 4 additions & 0 deletions contrib/auto-render/README.md
Expand Up @@ -26,6 +26,10 @@ before the close body tag:
```

See [index.html](index.html) for an example.
(To run this example from a clone of the repository, run `make serve`
in the root KaTeX directory, and then visit
http://0.0.0.0:7936/contrib/auto-render/index.html
with your web browser.)

If you prefer to have all your setup inside the html `<head>`,
you can use the following script there
Expand Down
4 changes: 4 additions & 0 deletions contrib/auto-render/index.html
@@ -1,4 +1,8 @@
<!DOCTYPE html>
<!--To run this example from a clone of the repository, run `make serve`
in the root KaTeX directory and then visit with your web browser:
http://0.0.0.0:7936/contrib/auto-render/index.html
-->
<html>
<head>
<meta charset="UTF-8">
Expand Down
41 changes: 32 additions & 9 deletions dockers/Screenshotter/screenshotter.js
Expand Up @@ -67,6 +67,10 @@ const opts = require("nomnom")
abbr: "x",
help: "Comma-separated list of test cases to exclude",
})
.option("reload", {
flag: true,
help: "Reload page for each test",
})
.option("verify", {
flag: true,
help: "Check whether screenshot matches current file content",
Expand Down Expand Up @@ -236,6 +240,7 @@ function tryConnect() {
// Build the web driver

let driver;
let driverReady = false;
function buildDriver() {
const builder = new selenium.Builder().forBrowser(opts.browser);
const ffProfile = new firefox.Profile();
Expand Down Expand Up @@ -301,7 +306,7 @@ function findHostIP() {
}
if (katexIP !== "*any*" || katexURL) {
if (!katexURL) {
katexURL = "http://" + katexIP + ":" + katexPort + "/babel/";
katexURL = "http://" + katexIP + ":" + katexPort + "/";
console.log("KaTeX URL is " + katexURL);
}
process.nextTick(takeScreenshots);
Expand All @@ -313,7 +318,7 @@ function findHostIP() {
app.get("/ss-connect.js", function(req, res, next) {
if (!katexURL) {
katexIP = req.query.ip;
katexURL = "http://" + katexIP + ":" + katexPort + "/babel/";
katexURL = "http://" + katexIP + ":" + katexPort + "/";
console.log("KaTeX URL is " + katexURL);
process.nextTick(takeScreenshots);
}
Expand Down Expand Up @@ -382,11 +387,27 @@ function takeScreenshot(key) {
}

const url = katexURL + "test/screenshotter/test.html?" + itm.query;
driver.get(url);
if (opts.wait) {
browserSideWait(1000 * opts.wait);
driver.call(loadMath);

function loadMath() {
if (!opts.reload && driverReady) {
driver.executeAsyncScript(
"var callback = arguments[arguments.length - 1]; " +
"handle_search_string(" +
JSON.stringify("?" + itm.query) + ", callback);")
.then(waitThenScreenshot);
} else {
driver.get(url).then(waitThenScreenshot);
}
}

function waitThenScreenshot() {
driverReady = true;
if (opts.wait) {
browserSideWait(1000 * opts.wait);
}
driver.takeScreenshot().then(haveScreenshot).then(oneDone, check);
}
driver.takeScreenshot().then(haveScreenshot).then(oneDone, check);

function haveScreenshot(img) {
img = imageDimensions(img);
Expand Down Expand Up @@ -424,9 +445,11 @@ function takeScreenshot(key) {
}
} else {
console.log("error " + key);
driver.get(url);
browserSideWait(500 * retry);
return driver.takeScreenshot().then(haveScreenshot);
browserSideWait(300 * retry);
if (retry > 1) {
driverReady = false; // reload fully
}
return driver.call(loadMath);
}
} else {
console.log("* ok " + key);
Expand Down
10 changes: 5 additions & 5 deletions katex.js
Expand Up @@ -7,12 +7,12 @@
* errors in the expression, or errors in javascript handling.
*/

const ParseError = require("./src/ParseError");
const Settings = require("./src/Settings");
import ParseError from "./src/ParseError";
import Settings from "./src/Settings";

const buildTree = require("./src/buildTree");
const parseTree = require("./src/parseTree");
const utils = require("./src/utils");
import buildTree from "./src/buildTree";
import parseTree from "./src/parseTree";
import utils from "./src/utils";

/**
* Parse and build an expression, and place that expression in the DOM node
Expand Down
3 changes: 3 additions & 0 deletions package.json
Expand Up @@ -15,8 +15,11 @@
],
"license": "MIT",
"devDependencies": {
"babel-eslint": "^7.2.0",
"babel-plugin-transform-class-properties": "^6.23.0",
"babel-plugin-transform-runtime": "^6.15.0",
"babel-preset-es2015": "^6.18.0",
"babel-register": "^6.24.0",
"babelify": "^7.3.0",
"browserify": "^13.3.0",
"clean-css": "^3.4.23",
Expand Down
41 changes: 17 additions & 24 deletions server.js
Expand Up @@ -15,7 +15,7 @@ if (require.main === module) {
":date[iso] :method :url HTTP/:http-version - :status"));
}

function serveBrowserified(file, standaloneName, doBabelify) {
function serveBrowserified(file, standaloneName) {
return function(req, res, next) {
let files;
if (Array.isArray(file)) {
Expand All @@ -26,10 +26,9 @@ function serveBrowserified(file, standaloneName, doBabelify) {
files = [path.join(__dirname, file)];
}

const options = {};
if (doBabelify) {
options.transform = [babelify];
}
const options = {
transform: [babelify],
};
if (standaloneName) {
options.standalone = standaloneName;
}
Expand All @@ -46,30 +45,24 @@ function serveBrowserified(file, standaloneName, doBabelify) {
};
}

function twoBrowserified(url, file, standaloneName) {
app.get(url, serveBrowserified(file, standaloneName, false));
app.get("/babel" + url, serveBrowserified(file, standaloneName, true));
}

function twoUse(url, handler) {
app.use(url, handler);
app.use("/babel" + url, handler);
function browserified(url, file, standaloneName) {
app.get(url, serveBrowserified(file, standaloneName));
}

function twoStatic(url, file) {
twoUse(url, express.static(path.join(__dirname, file)));
function getStatic(url, file) {
app.use(url, express.static(path.join(__dirname, file)));
}

twoBrowserified("/katex.js", "katex", "katex");
twoUse("/test/jasmine", express.static(path.dirname(
browserified("/katex.js", "katex", "katex");
app.use("/test/jasmine", express.static(path.dirname(
require.resolve("jasmine-core/lib/jasmine-core/jasmine.js"))));
twoBrowserified("/test/katex-spec.js", "test/*[Ss]pec.js");
twoBrowserified(
browserified("/test/katex-spec.js", "test/*[Ss]pec.js");
browserified(
"/contrib/auto-render/auto-render.js",
"contrib/auto-render/auto-render",
"renderMathInElement");

twoUse("/katex.css", function(req, res, next) {
app.use("/katex.css", function(req, res, next) {
const lessfile = path.join(__dirname, "static", "katex.less");
fs.readFile(lessfile, {encoding: "utf8"}, function(err, data) {
if (err) {
Expand All @@ -93,10 +86,10 @@ twoUse("/katex.css", function(req, res, next) {
});
});

twoStatic("", "static");
twoStatic("", "build");
twoStatic("/test", "test");
twoStatic("/contrib", "contrib");
getStatic("", "static");
getStatic("", "build");
getStatic("/test", "test");
getStatic("/contrib", "contrib");

app.use(function(err, req, res, next) {
console.error(err.stack);
Expand Down
95 changes: 50 additions & 45 deletions src/Lexer.js
Expand Up @@ -11,15 +11,8 @@
* kinds.
*/

const matchAt = require("match-at");

const ParseError = require("./ParseError");

// The main lexer class
function Lexer(input) {
this.input = input;
this.pos = 0;
}
import matchAt from "match-at";
import ParseError from "./ParseError";

/**
* The resulting token returned from `lex`.
Expand All @@ -40,26 +33,28 @@ function Lexer(input) {
* @param {number=} end the end offset, zero-based exclusive
* @param {Lexer=} lexer the lexer which in turn holds the input string
*/
function Token(text, start, end, lexer) {
this.text = text;
this.start = start;
this.end = end;
this.lexer = lexer;
}
class Token {
constructor(text, start, end, lexer) {
this.text = text;
this.start = start;
this.end = end;
this.lexer = lexer;
}

/**
* Given a pair of tokens (this and endToken), compute a “Token” encompassing
* the whole input range enclosed by these two.
*
* @param {Token} endToken last token of the range, inclusive
* @param {string} text the text of the newly constructed token
*/
Token.prototype.range = function(endToken, text) {
if (endToken.lexer !== this.lexer) {
return new Token(text); // sorry, no position information available
/**
* Given a pair of tokens (this and endToken), compute a “Token” encompassing
* the whole input range enclosed by these two.
*
* @param {Token} endToken last token of the range, inclusive
* @param {string} text the text of the newly constructed token
*/
range(endToken, text) {
if (endToken.lexer !== this.lexer) {
return new Token(text); // sorry, no position information available
}
return new Token(text, this.start, endToken.end, this.lexer);
}
return new Token(text, this.start, endToken.end, this.lexer);
};
}

/* The following tokenRegex
* - matches typical whitespace (but not NBSP etc.) using its first group
Expand All @@ -84,26 +79,36 @@ const tokenRegex = new RegExp(
")"
);

/**
* This function lexes a single token.
/*
* Main Lexer class
*/
Lexer.prototype.lex = function() {
const input = this.input;
const pos = this.pos;
if (pos === input.length) {
return new Token("EOF", pos, pos, this);
class Lexer {
constructor(input) {
this.input = input;
this.pos = 0;
}
const match = matchAt(tokenRegex, input, pos);
if (match === null) {
throw new ParseError(
"Unexpected character: '" + input[pos] + "'",
new Token(input[pos], pos, pos + 1, this));

/**
* This function lexes a single token.
*/
lex() {
const input = this.input;
const pos = this.pos;
if (pos === input.length) {
return new Token("EOF", pos, pos, this);
}
const match = matchAt(tokenRegex, input, pos);
if (match === null) {
throw new ParseError(
"Unexpected character: '" + input[pos] + "'",
new Token(input[pos], pos, pos + 1, this));
}
const text = match[2] || " ";
const start = this.pos;
this.pos += match[0].length;
const end = this.pos;
return new Token(text, start, end, this);
}
const text = match[2] || " ";
const start = this.pos;
this.pos += match[0].length;
const end = this.pos;
return new Token(text, start, end, this);
};
}

module.exports = Lexer;

0 comments on commit b3aa1b4

Please sign in to comment.