From fec04614b82fafc2bbf82f68e6416abb1e236b78 Mon Sep 17 00:00:00 2001 From: Jmeas Date: Wed, 1 Oct 2014 18:46:00 -0400 Subject: [PATCH] Adds JSHint to the build system and tidies up code. --- .jshintrc | 67 ++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 7 +++-- package.json | 55 ++++++++++++++++++------------------- src/Lexer.js | 13 ++++----- src/Parser.js | 15 ++++++----- src/Style.js | 2 +- src/buildCommon.js | 14 +++++----- src/buildTree.js | 37 +++++++++++++------------ src/delimiter.js | 21 +++++---------- src/fontMetrics.js | 16 ++++++----- src/functions.js | 2 +- src/parseTree.js | 2 +- src/symbols.js | 8 +++--- src/utils.js | 2 +- 14 files changed, 165 insertions(+), 96 deletions(-) create mode 100644 .jshintrc diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 000000000..bc06ad14e --- /dev/null +++ b/.jshintrc @@ -0,0 +1,67 @@ +{ + "bitwise" : true, + "camelcase" : true, + "curly" : true, + "eqeqeq" : false, + "es3" : true, + "forin" : false, + "immed" : true, + "indent" : 4, + "latedef" : false, + "newcap" : true, + "noarg" : true, + "noempty" : true, + "nonbsp" : true, + "nonew" : true, + "plusplus" : false, + "quotmark" : "double", + "undef" : true, + "unused" : "vars", + "strict" : false, + "trailing" : true, + "maxparams" : 7, + "maxdepth" : 6, + + "asi" : false, + "boss" : false, + "debug" : false, + "eqnull" : true, + "esnext" : false, + "evil" : false, + "expr" : true, + "funcscope" : false, + "globalstrict" : false, + "iterator" : false, + "lastsemic" : false, + "laxbreak" : true, + "laxcomma" : false, + "loopfunc" : false, + "maxerr" : 50, + "multistr" : false, + "notypeof" : false, + "proto" : true, + "scripturl" : false, + "smarttabs" : false, + "shadow" : false, + "sub" : false, + "supernew" : false, + "validthis" : false, + "noyield" : false, + + "browser" : true, + "couch" : false, + "devel" : false, + "dojo" : false, + "jquery" : false, + "mootools" : false, + "node" : true, + "nonstandard" : false, + "prototypejs" : false, + "rhino" : false, + "worker" : false, + "wsh" : false, + "yui" : false, + "globals": { + "console": true + } +} diff --git a/Makefile b/Makefile index 9b6f34e59..2de8a003b 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,12 @@ -.PHONY: build setup copy serve clean metrics test zip -build: setup build/katex.min.js build/katex.min.css zip compress +.PHONY: build lint setup copy serve clean metrics test zip +build: setup lint build/katex.min.js build/katex.min.css zip compress setup: npm install +lint: katex.js $(wildcard src/*.js) + ./node_modules/.bin/jshint $^ + build/katex.js: katex.js $(wildcard src/*.js) ./node_modules/.bin/browserify $< --standalone katex > $@ diff --git a/package.json b/package.json index 4344ee912..93547a292 100644 --- a/package.json +++ b/package.json @@ -1,29 +1,30 @@ { - "name": "katex", - "version": "0.1.0", - "description": "Fast math!", - "main": "katex.js", - "repository": { - "type": "git", - "url": "git://github.com/Khan/KaTeX.git" - }, - "files": [ - "katex.js", - "cli.js", - "src/" - ], - "license": "MIT", - "devDependencies": { - "browserify": "~2.29.1", - "express": "~3.3.3", - "less": "~1.7.5", - "uglify-js": "~2.4.15", - "clean-css": "~2.2.15", - "huxley": "~0.8.1", - "jasmine-node": "git://github.com/mhevery/jasmine-node.git#Jasmine2.0" - }, - "bin": "cli.js", - "scripts": { - "test": "make test" - } + "name": "katex", + "version": "0.1.0", + "description": "Fast math!", + "main": "katex.js", + "repository": { + "type": "git", + "url": "git://github.com/Khan/KaTeX.git" + }, + "files": [ + "katex.js", + "cli.js", + "src/" + ], + "license": "MIT", + "devDependencies": { + "browserify": "~2.29.1", + "clean-css": "~2.2.15", + "express": "~3.3.3", + "huxley": "~0.8.1", + "jasmine-node": "git://github.com/mhevery/jasmine-node.git#Jasmine2.0", + "jshint": "^2.5.6", + "less": "~1.7.5", + "uglify-js": "~2.4.15" + }, + "bin": "cli.js", + "scripts": { + "test": "make lint test" + } } diff --git a/src/Lexer.js b/src/Lexer.js index 7e0c50999..6d0765cff 100644 --- a/src/Lexer.js +++ b/src/Lexer.js @@ -16,7 +16,7 @@ var ParseError = require("./ParseError"); // The main lexer class function Lexer(input) { this._input = input; -}; +} // The resulting token returned from `lex`. function Token(text, data, position) { @@ -35,7 +35,7 @@ var mathNormals = [ /^['\^_{}]/, // misc /^[(\[]/, // opens /^[)\]?!]/, // closes - /^~/, // spacing + /^~/ // spacing ]; // These are "normal" tokens like above, but should instead be parsed in text @@ -43,7 +43,7 @@ var mathNormals = [ var textNormals = [ /^[a-zA-Z0-9`!@*()-=+\[\]'";:?\/.,]/, // ords /^[{}]/, // grouping - /^~/, // spacing + /^~/ // spacing ]; // Regexes for matching whitespace @@ -61,15 +61,16 @@ var anyFunc = /^\\(?:[a-zA-Z]+|.)/; */ Lexer.prototype._innerLex = function(pos, normals, ignoreWhitespace) { var input = this._input.slice(pos); + var whitespace; if (ignoreWhitespace) { // Get rid of whitespace. - var whitespace = input.match(whitespaceRegex)[0]; + whitespace = input.match(whitespaceRegex)[0]; pos += whitespace.length; input = input.slice(whitespace.length); } else { // Do the funky concatenation of whitespace that happens in text mode. - var whitespace = input.match(whitespaceConcatRegex); + whitespace = input.match(whitespaceConcatRegex); if (whitespace !== null) { return new Token(" ", null, pos + whitespace[0].length); } @@ -100,7 +101,7 @@ Lexer.prototype._innerLex = function(pos, normals, ignoreWhitespace) { throw new ParseError("Unexpected character: '" + input[0] + "'", this, pos); -} +}; // A regex to match a CSS color (like #ffffff or BlueViolet) var cssColor = /^(#[a-z0-9]+|[a-z]+)/i; diff --git a/src/Parser.js b/src/Parser.js index 65bbf9caa..f23e7fd96 100644 --- a/src/Parser.js +++ b/src/Parser.js @@ -46,7 +46,7 @@ var ParseError = require("./ParseError"); function Parser(input) { // Make a new lexer this.lexer = new Lexer(input); -}; +} /** * The resulting parse tree nodes of the parse tree. @@ -260,18 +260,18 @@ Parser.prototype.parseAtom = function(pos, mode) { var superscript; var subscript; + var result; while (true) { // Lex the first token var lex = this.lexer.lex(currPos, mode); - var group; if (lex.text === "^") { // We got a superscript start if (superscript) { throw new ParseError( "Double superscript", this.lexer, currPos); } - var result = this.handleSupSubscript( + result = this.handleSupSubscript( lex.position, mode, lex.text, "superscript"); currPos = result.position; superscript = result.result; @@ -281,7 +281,7 @@ Parser.prototype.parseAtom = function(pos, mode) { throw new ParseError( "Double subscript", this.lexer, currPos); } - var result = this.handleSupSubscript( + result = this.handleSupSubscript( lex.position, mode, lex.text, "subscript"); currPos = result.position; subscript = result.result; @@ -352,13 +352,14 @@ Parser.prototype.parseImplicitGroup = function(pos, mode) { } var func = start.result.result; + var body; if (func === "\\left") { // If we see a left: // Parse the entire left function (including the delimiter) var left = this.parseFunction(pos, mode); // Parse out the implicit body - var body = this.parseExpression(left.position, mode, false, "}"); + body = this.parseExpression(left.position, mode, false, "}"); // Check the next token var rightLex = this.parseSymbol(body.position, mode); @@ -382,7 +383,7 @@ Parser.prototype.parseImplicitGroup = function(pos, mode) { return null; } else if (utils.contains(sizeFuncs, func)) { // If we see a sizing function, parse out the implict body - var body = this.parseExpression(start.result.position, mode, false, "}"); + body = this.parseExpression(start.result.position, mode, false, "}"); return new ParseResult( new ParseNode("sizing", { // Figure out what size to use based on the list of functions above @@ -392,7 +393,7 @@ Parser.prototype.parseImplicitGroup = function(pos, mode) { body.position); } else if (utils.contains(styleFuncs, func)) { // If we see a styling function, parse out the implict body - var body = this.parseExpression(start.result.position, mode, true, "}"); + body = this.parseExpression(start.result.position, mode, true, "}"); return new ParseResult( new ParseNode("styling", { // Figure out what style to use by pulling out the style from diff --git a/src/Style.js b/src/Style.js index c331d1f17..43d5e2609 100644 --- a/src/Style.js +++ b/src/Style.js @@ -94,7 +94,7 @@ var resetNames = [ "reset-textstyle", "reset-textstyle", "reset-scriptstyle", - "reset-scriptscriptstyle", + "reset-scriptscriptstyle" ]; // Instances of the different styles diff --git a/src/buildCommon.js b/src/buildCommon.js index 8d98656f0..f1ab53a35 100644 --- a/src/buildCommon.js +++ b/src/buildCommon.js @@ -173,6 +173,8 @@ var makeFontSizer = function(options, fontSize) { */ var makeVList = function(children, positionType, positionData, options) { var depth; + var currPos; + var i; if (positionType === "individualShift") { var oldChildren = children; children = [oldChildren[0]]; @@ -180,8 +182,8 @@ var makeVList = function(children, positionType, positionData, options) { // Add in kerns to the list of children to get each element to be // shifted to the correct specified shift depth = -oldChildren[0].shift - oldChildren[0].elem.depth; - var currPos = depth; - for (var i = 1; i < oldChildren.length; i++) { + currPos = depth; + for (i = 1; i < oldChildren.length; i++) { var diff = -oldChildren[i].shift - currPos - oldChildren[i].elem.depth; var size = diff - @@ -197,7 +199,7 @@ var makeVList = function(children, positionType, positionData, options) { // We always start at the bottom, so calculate the bottom by adding up // all the sizes var bottom = positionData; - for (var i = 0; i < children.length; i++) { + for (i = 0; i < children.length; i++) { if (children[i].type === "kern") { bottom -= children[i].size; } else { @@ -217,7 +219,7 @@ var makeVList = function(children, positionType, positionData, options) { // Make the fontSizer var maxFontSize = 0; - for (var i = 0; i < children.length; i++) { + for (i = 0; i < children.length; i++) { if (children[i].type === "elem") { maxFontSize = Math.max(maxFontSize, children[i].elem.maxFontSize); } @@ -226,8 +228,8 @@ var makeVList = function(children, positionType, positionData, options) { // Create a new list of actual children at the correct offsets var realChildren = []; - var currPos = depth; - for (var i = 0; i < children.length; i++) { + currPos = depth; + for (i = 0; i < children.length; i++) { if (children[i].type === "kern") { currPos += children[i].size; } else { diff --git a/src/buildTree.js b/src/buildTree.js index b249beacf..cbdf0525d 100644 --- a/src/buildTree.js +++ b/src/buildTree.js @@ -13,8 +13,6 @@ var buildCommon = require("./buildCommon"); var delimiter = require("./delimiter"); var domTree = require("./domTree"); var fontMetrics = require("./fontMetrics"); -var parseTree = require("./parseTree"); -var symbols = require("./symbols"); var utils = require("./utils"); var makeSpan = buildCommon.makeSpan; @@ -99,7 +97,7 @@ var getTypeOfGroup = function(group) { * handling them itself. */ var shouldHandleSupSub = function(group, options) { - if (group == null) { + if (!group) { return false; } else if (group.type === "op") { // Operators handle supsubs differently when they have limits @@ -118,7 +116,7 @@ var shouldHandleSupSub = function(group, options) { * a single element, we want to pull that out. */ var getBaseElem = function(group) { - if (group == null) { + if (!group) { return false; } else if (group.type === "ordgroup") { if (group.value.length === 1) { @@ -248,7 +246,6 @@ var groupTypes = { supsub: function(group, options, prev) { // Superscript and subscripts are handled in the TeXbook on page // 445-446, rules 18(a-f). - var baseGroup = group.value.base; // Here is where we defer to the inner group if it should handle // superscripts and subscripts itself. @@ -257,18 +254,19 @@ var groupTypes = { } var base = buildGroup(group.value.base, options.reset()); + var supmid, submid, sup, sub; if (group.value.sup) { - var sup = buildGroup(group.value.sup, + sup = buildGroup(group.value.sup, options.withStyle(options.style.sup())); - var supmid = makeSpan( + supmid = makeSpan( [options.style.reset(), options.style.sup().cls()], [sup]); } if (group.value.sub) { - var sub = buildGroup(group.value.sub, + sub = buildGroup(group.value.sub, options.withStyle(options.style.sub())); - var submid = makeSpan( + submid = makeSpan( [options.style.reset(), options.style.sub().cls()], [sub]); } @@ -384,7 +382,7 @@ var groupTypes = { var numerreset = makeSpan([fstyle.reset(), nstyle.cls()], [numer]); var denom = buildGroup(group.value.denom, options.withStyle(dstyle)); - var denomreset = makeSpan([fstyle.reset(), dstyle.cls()], [denom]) + var denomreset = makeSpan([fstyle.reset(), dstyle.cls()], [denom]); var ruleWidth = fontMetrics.metrics.defaultRuleThickness / options.style.sizeMultiplier; @@ -551,7 +549,7 @@ var groupTypes = { if (hasLimits) { // IE 8 clips \int if it is in a display: inline-block. We wrap it // in a new span so it is an inline, and works. - var base = makeSpan([], [base]); + base = makeSpan([], [base]); var supmid, supKern, submid, subKern; // We manually have to handle the superscripts and subscripts. This, @@ -581,9 +579,9 @@ var groupTypes = { // Build the final group as a vlist of the possible subscript, base, // and possible superscript. - var finalGroup; + var finalGroup, top, bottom; if (!supGroup) { - var top = base.height - baseShift; + top = base.height - baseShift; finalGroup = buildCommon.makeVList([ {type: "kern", size: fontMetrics.metrics.bigOpSpacing5}, @@ -598,7 +596,7 @@ var groupTypes = { // margin will shift by 1/2 that. finalGroup.children[0].style.marginLeft = -slant + "em"; } else if (!subGroup) { - var bottom = base.depth + baseShift; + bottom = base.depth + baseShift; finalGroup = buildCommon.makeVList([ {type: "elem", elem: base}, @@ -615,7 +613,7 @@ var groupTypes = { // subscript) but be safe. return base; } else { - var bottom = fontMetrics.metrics.bigOpSpacing5 + + bottom = fontMetrics.metrics.bigOpSpacing5 + submid.height + submid.depth + subKern + base.depth + baseShift; @@ -743,7 +741,7 @@ var groupTypes = { } // Shift the delimiter so that its top lines up with the top of the line - delimShift = -(inner.height + lineClearance + ruleWidth) + delim.height; + var delimShift = -(inner.height + lineClearance + ruleWidth) + delim.height; delim.style.top = delimShift + "em"; delim.height -= delimShift; delim.depth += delimShift; @@ -989,7 +987,7 @@ var groupTypes = { var accentBody = makeSpan(["accent-body", vecClass], [ makeSpan([], [accent])]); - var accentBody = buildCommon.makeVList([ + accentBody = buildCommon.makeVList([ {type: "elem", elem: body}, {type: "kern", size: -clearance}, {type: "elem", elem: accentBody} @@ -1047,11 +1045,12 @@ var buildGroup = function(group, options, prev) { if (groupTypes[group.type]) { // Call the groupTypes function var groupNode = groupTypes[group.type](group, options, prev); + var multiplier; // If the style changed between the parent and the current group, // account for the size difference if (options.style !== options.parentStyle) { - var multiplier = options.style.sizeMultiplier / + multiplier = options.style.sizeMultiplier / options.parentStyle.sizeMultiplier; groupNode.height *= multiplier; @@ -1061,7 +1060,7 @@ var buildGroup = function(group, options, prev) { // If the size changed between the parent and the current group, account // for that size difference. if (options.size !== options.parentSize) { - var multiplier = sizingMultiplier[options.size] / + multiplier = sizingMultiplier[options.size] / sizingMultiplier[options.parentSize]; groupNode.height *= multiplier; diff --git a/src/delimiter.js b/src/delimiter.js index d5179f402..a0e7f0c9b 100644 --- a/src/delimiter.js +++ b/src/delimiter.js @@ -20,14 +20,11 @@ * used in `\left` and `\right`. */ -var Options = require("./Options"); var ParseError = require("./ParseError"); var Style = require("./Style"); var buildCommon = require("./buildCommon"); -var domTree = require("./domTree"); var fontMetrics = require("./fontMetrics"); -var parseTree = require("./parseTree"); var symbols = require("./symbols"); var utils = require("./utils"); @@ -38,9 +35,9 @@ var makeSpan = buildCommon.makeSpan; * after following replacement from symbols.js) */ var getMetrics = function(symbol, font) { - if (symbols["math"][symbol] && symbols["math"][symbol].replace) { + if (symbols.math[symbol] && symbols.math[symbol].replace) { return fontMetrics.getCharacterMetrics( - symbols["math"][symbol].replace, font); + symbols.math[symbol].replace, font); } else { return fontMetrics.getCharacterMetrics( symbol, font); @@ -172,8 +169,6 @@ var makeStackedDelim = function(delim, heightTotal, center, options, mode) { top = "\\Uparrow"; repeat = "\u2016"; bottom = "\\Downarrow"; - } else if (delim === "|" || delim === "\\vert") { - } else if (delim === "\\|" || delim === "\\Vert") { } else if (delim === "[" || delim === "\\lbrack") { top = "\u23a1"; repeat = "\u23a2"; @@ -267,8 +262,7 @@ var makeStackedDelim = function(delim, heightTotal, center, options, mode) { if (center) { axisHeight *= options.style.sizeMultiplier; } - // Calculate the height and depth - var height = realHeightTotal / 2 + axisHeight; + // Calculate the depth var depth = realHeightTotal / 2 - axisHeight; // Now, we start building the pieces that will go into the vlist @@ -279,13 +273,14 @@ var makeStackedDelim = function(delim, heightTotal, center, options, mode) { // Add the bottom symbol inners.push(makeInner(bottom, font, mode)); + var i; if (middle === null) { // Calculate the number of repeated symbols we need var repeatHeight = realHeightTotal - topHeightTotal - bottomHeightTotal; var symbolCount = Math.ceil(repeatHeight / repeatHeightTotal); // Add that many symbols - for (var i = 0; i < symbolCount; i++) { + for (i = 0; i < symbolCount; i++) { inners.push(makeInner(repeat, font, mode)); } } else { @@ -304,7 +299,7 @@ var makeStackedDelim = function(delim, heightTotal, center, options, mode) { Math.ceil(bottomRepeatHeight / repeatHeightTotal); // Add the top repeated part - for (var i = 0; i < topSymbolCount; i++) { + for (i = 0; i < topSymbolCount; i++) { inners.push(makeInner(repeat, font, mode)); } @@ -312,7 +307,7 @@ var makeStackedDelim = function(delim, heightTotal, center, options, mode) { inners.push(makeInner(middle, font, mode)); // Add the bottom repeated part - for (var i = 0; i < bottomSymbolCount; i++) { + for (i = 0; i < bottomSymbolCount; i++) { inners.push(makeInner(repeat, font, mode)); } } @@ -365,8 +360,6 @@ var makeSizedDelim = function(delim, size, options, mode) { delim = "\\rangle"; } - var retDelim; - // Sized delimiters are never centered. if (utils.contains(stackLargeDelimiters, delim) || utils.contains(stackNeverDelimiters, delim)) { diff --git a/src/fontMetrics.js b/src/fontMetrics.js index d6c55efff..17888107d 100644 --- a/src/fontMetrics.js +++ b/src/fontMetrics.js @@ -1,3 +1,5 @@ +/* jshint unused:false */ + /** * This file contains metrics regarding fonts and individual symbols. The sigma * and xi variables, as well as the metricMap map contain data extracted from @@ -45,15 +47,15 @@ var xi1 = 0; var xi2 = 0; var xi3 = 0; var xi4 = 0; -var xi5 = .431; +var xi5 = 0.431; var xi6 = 1; var xi7 = 0; -var xi8 = .04; -var xi9 = .111; -var xi10 = .166; -var xi11 = .2; -var xi12 = .6; -var xi13 = .1; +var xi8 = 0.04; +var xi9 = 0.111; +var xi10 = 0.166; +var xi11 = 0.2; +var xi12 = 0.6; +var xi13 = 0.1; // This value determines how large a pt is, for metrics which are defined in // terms of pts. diff --git a/src/functions.js b/src/functions.js index 7a659dc92..d51d38b4d 100644 --- a/src/functions.js +++ b/src/functions.js @@ -172,7 +172,7 @@ var functions = { return { type: "infix", replaceWith: "\\frac" - } + }; } } }; diff --git a/src/parseTree.js b/src/parseTree.js index aeb5247ce..a778e2c4d 100644 --- a/src/parseTree.js +++ b/src/parseTree.js @@ -12,6 +12,6 @@ var parseTree = function(toParse) { var parser = new Parser(toParse); return parser.parse(); -} +}; module.exports = parseTree; diff --git a/src/symbols.js b/src/symbols.js index dd4fa53df..6c94d1f1c 100644 --- a/src/symbols.js +++ b/src/symbols.js @@ -973,7 +973,7 @@ var symbols = { var mathTextSymbols = "0123456789/@.\""; for (var i = 0; i < mathTextSymbols.length; i++) { var ch = mathTextSymbols.charAt(i); - symbols["math"][ch] = { + symbols.math[ch] = { font: "main", group: "textord" }; @@ -983,7 +983,7 @@ for (var i = 0; i < mathTextSymbols.length; i++) { var textSymbols = "0123456789`!@*()-=+[]'\";:?/.,"; for (var i = 0; i < textSymbols.length; i++) { var ch = textSymbols.charAt(i); - symbols["text"][ch] = { + symbols.text[ch] = { font: "main", group: "textord" }; @@ -993,11 +993,11 @@ for (var i = 0; i < textSymbols.length; i++) { var letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; for (var i = 0; i < letters.length; i++) { var ch = letters.charAt(i); - symbols["math"][ch] = { + symbols.math[ch] = { font: "main", group: "mathord" }; - symbols["text"][ch] = { + symbols.text[ch] = { font: "main", group: "textord" }; diff --git a/src/utils.js b/src/utils.js index 09974113a..9b9bf7112 100644 --- a/src/utils.js +++ b/src/utils.js @@ -59,7 +59,7 @@ function escaper(match) { * @return {string} An escaped string. */ function escape(text) { - return ('' + text).replace(ESCAPE_REGEX, escaper); + return ("" + text).replace(ESCAPE_REGEX, escaper); } /**