From fb403fa9eb4f907087a127ea02f6f0c3de02ab92 Mon Sep 17 00:00:00 2001 From: Martin von Gagern Date: Wed, 15 Jul 2015 16:50:47 +0200 Subject: [PATCH] Switch Screenshotter data from JSON to YAML Escaping TeX in JSON as query strings is a pain: you have to double all the \\, you have to escape the & and the #, you can't easily include line breaks for readability, and so on. YAML solves most of these problems for most of the situations. Now each test case can be structured, while simple test cases only consist of a line of verbatim TeX code, with no escaping. The most troublesome items remaining are lines starting in { since in YAML these would denote inline mapping types. We use block notation for these. --- dockers/Screenshotter/screenshotter.js | 10 ++- dockers/texcmp/texcmp.js | 31 +++----- package.json | 3 +- test/screenshotter/ss_data.js | 23 ++++++ test/screenshotter/ss_data.json | 41 ----------- test/screenshotter/ss_data.yaml | 97 ++++++++++++++++++++++++++ test/screenshotter/test.html | 4 +- 7 files changed, 137 insertions(+), 72 deletions(-) create mode 100644 test/screenshotter/ss_data.js delete mode 100644 test/screenshotter/ss_data.json create mode 100644 test/screenshotter/ss_data.yaml diff --git a/dockers/Screenshotter/screenshotter.js b/dockers/Screenshotter/screenshotter.js index 5789bb168..29cbd663a 100644 --- a/dockers/Screenshotter/screenshotter.js +++ b/dockers/Screenshotter/screenshotter.js @@ -8,7 +8,7 @@ var net = require("net"); var selenium = require("selenium-webdriver"); var app = require("../../server"); -var data = require("../../test/screenshotter/ss_data.json"); +var data = require("../../test/screenshotter/ss_data"); var dstDir = path.normalize( path.join(__dirname, "..", "..", "test", "screenshotter", "images")); @@ -130,8 +130,6 @@ if (seleniumURL) { console.log("Selenium driver in local session"); } -var toStrip = "http://localhost:7936/"; // remove this from testcase URLs - process.nextTick(startServer); var attempts = 0; @@ -248,12 +246,12 @@ function takeScreenshots() { } function takeScreenshot(key) { - var url = data[key]; - if (!url) { + var itm = data[key]; + if (!itm) { console.error("Test case " + key + " not known!"); return; } - url = katexURL + url.substr(toStrip.length); + var url = katexURL + "test/screenshotter/test.html?" + itm.query; driver.get(url); driver.takeScreenshot().then(function haveScreenshot(img) { img = imageDimensions(img); diff --git a/dockers/texcmp/texcmp.js b/dockers/texcmp/texcmp.js index f5aac1c0f..5872fd661 100644 --- a/dockers/texcmp/texcmp.js +++ b/dockers/texcmp/texcmp.js @@ -1,6 +1,5 @@ "use strict"; -var querystring = require("querystring"); var childProcess = require("child_process"); var fs = require("fs"); var path = require("path"); @@ -16,18 +15,12 @@ var readFile = Q.denodeify(fs.readFile); var writeFile = Q.denodeify(fs.writeFile); var mkdir = Q.denodeify(fs.mkdir); -// ignore some tests, since they contain commands not supported by LaTeX -var blacklist = { - Colors: "Color handling differs", - DeepFontSizing: "\\Huge inside \\dfrac doesn't work for some reason", - KaTeX: "Custom command, doesn't exist in LaTeX" -}; var todo; if (process.argv.length > 2) { todo = process.argv.slice(2); } else { todo = Object.keys(data).filter(function(key) { - return !blacklist[key]; + return !data[key].nolatex; }); } @@ -63,22 +56,16 @@ Q.all([ // Process a single test case: rasterize, then create diff function processTestCase(key) { - if (blacklist[key]) { - return; + var itm = data[key]; + var tex = "$" + itm.tex + "$"; + if (itm.display) { + tex = "\\[" + itm.tex + "\\]"; } - var url = data[key]; - var query = url.replace(/^.*?\?/, ""); // extract query string - query = query.replace(/\+/g, "%2B"); // plus doesn't mean space here - query = querystring.parse(query); - var tex = "$" + query.m + "$"; - if (query.display) { - tex = "$$" + query.m + "$$"; + if (itm.pre) { + tex = itm.pre.replace("
", "\\\\") + tex; } - if (query.pre) { - tex = query.pre.replace("
", "\\\\") + tex; - } - if (query.post) { - tex = tex + query.post.replace("
", "\\\\"); + if (itm.post) { + tex = tex + itm.post.replace("
", "\\\\"); } tex = template.replace(/\$.*\$/, tex.replace(/\$/g, "$$$$")); var texFile = path.join(tmpDir, key + ".tex"); diff --git a/package.json b/package.json index f4ac836cb..0f880e5d8 100644 --- a/package.json +++ b/package.json @@ -18,10 +18,11 @@ "clean-css": "~2.2.15", "express": "~3.3.3", "jasmine-node": "2.0.0-beta4", + "js-yaml": "^3.3.1", "jshint": "^2.5.6", "less": "~1.7.5", - "selenium-webdriver": "^2.46.1", "nomnom": "^1.8.1", + "selenium-webdriver": "^2.46.1", "uglify-js": "~2.4.15" }, "bin": "cli.js", diff --git a/test/screenshotter/ss_data.js b/test/screenshotter/ss_data.js new file mode 100644 index 000000000..829f15949 --- /dev/null +++ b/test/screenshotter/ss_data.js @@ -0,0 +1,23 @@ +/** + * Parse and polish the screenshotter data in ss_data.yaml. + * + * This module is responsible for reading the file ss_data.yaml, + * unify syntactic variations (like string vs. dict as test case body) + * and provide common functionality (like a query string encoded version). + * The export of this module is simply a dictionary of test cases. + */ + +var fs = require("fs"); +var jsyaml = require("js-yaml"); +var querystring = require("querystring"); + +var dict = fs.readFileSync(require.resolve("./ss_data.yaml")); +dict = jsyaml.safeLoad(dict); +for (var key in dict) { + var itm = dict[key]; + if (typeof itm === "string") { + itm = dict[key] = { tex: itm }; + } + itm.query = querystring.stringify(itm); +} +module.exports = dict; diff --git a/test/screenshotter/ss_data.json b/test/screenshotter/ss_data.json deleted file mode 100644 index deaf70c4c..000000000 --- a/test/screenshotter/ss_data.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "Accents": "http://localhost:7936/test/screenshotter/test.html?m=\\vec{A}\\vec{x}\\vec x^2\\vec{x}_2^2\\vec{A}^2\\vec{xA}^2", - "Arrays": "http://localhost:7936/test/screenshotter/test.html?m=\\left(\\begin{array}{rlc}1%262%263\\\\1+1%262+1%263+1\\cr1\\over2%26\\scriptstyle 1/2%26\\frac12\\\\[1ex]\\begin{pmatrix}x\\\\y\\end{pmatrix}%260%26\\begin{vmatrix}a%26b\\\\c%26d\\end{vmatrix}\\end{array}\\right]", - "ArrayType": "http://localhost:7936/test/screenshotter/test.html?m=1\\begin{array}{c}2\\\\3\\end{array}4", - "Baseline": "http://localhost:7936/test/screenshotter/test.html?m=a+b-c\\cdot d/e", - "BasicTest": "http://localhost:7936/test/screenshotter/test.html?m=a", - "BinomTest": "http://localhost:7936/test/screenshotter/test.html?m=\\dbinom{a}{b}\\tbinom{a}{b}^{\\binom{a}{b}+17}", - "Cases": "http://localhost:7936/test/screenshotter/test.html?m=f(a,b)=\\begin{cases}a+1%26\\text{if }b\\text{ is odd}\\\\a%26\\text{if }b=0\\\\a-1%26\\text{otherwise}\\end{cases}", - "Colors": "http://localhost:7936/test/screenshotter/test.html?m=\\blue{a}\\color{%230f0}{b}\\color{red}{c}", - "DeepFontSizing": "http://localhost:7936/test/screenshotter/test.html?m=a^{\\big| x^{\\big(}}_{\\Big\\uparrow} + i^{i^{\\Huge x}_y}_{\\Huge z} + \\dfrac{\\Huge x}{y}", - "DelimiterSizing": "http://localhost:7936/test/screenshotter/test.html?m=\\bigl\\uparrow\\Bigl\\downarrow\\biggl\\updownarrow\\Biggl\\Uparrow\\Biggr\\Downarrow\\biggr\\langle\\Bigr\\}\\bigr\\rfloor", - "DisplayMode": "http://localhost:7936/test/screenshotter/test.html?m=\\sum_{i=0}^\\infty \\frac{1}{i}&pre=pre&post=post&display=1", - "DisplayStyle": "http://localhost:7936/test/screenshotter/test.html?m={\\displaystyle\\sqrt{x}}{\\sqrt{x}}{\\displaystyle \\frac12}{\\frac12}{\\displaystyle x^1_2}{x^1_2}", - "Exponents": "http://localhost:7936/test/screenshotter/test.html?m=a^{a^a_a}_{a^a_a}", - "FractionTest": "http://localhost:7936/test/screenshotter/test.html?m=\\dfrac{a}{b}\\frac{a}{b}\\tfrac{a}{b}\\;-\\dfrac12\\;1\\tfrac12", - "Functions": "http://localhost:7936/test/screenshotter/test.html?m=\\sin\\cos\\tan\\ln\\log", - "GreekLetters": "http://localhost:7936/test/screenshotter/test.html?m=\\alpha\\beta\\gamma\\omega", - "KaTeX": "http://localhost:7936/test/screenshotter/test.html?m=\\KaTeX", - "Lap": "http://localhost:7936/test/screenshotter/test.html?m=ab\\llap{f}cd\\rlap{g}h", - "LeftRight": "http://localhost:7936/test/screenshotter/test.html?m=\\left( x^2 \\right) \\left\\{ x^{x^{x^{x^x}}} \\right.", - "LeftRightListStyling": "http://localhost:7936/test/screenshotter/test.html?m=a+\\left(x+y\\right)-x", - "LeftRightStyleSizing": "http://localhost:7936/test/screenshotter/test.html?m=+\\left\\{\\rule{0.1em}{1em}\\right.x^{+\\left\\{\\rule{0.1em}{1em}\\right.x^{+\\left\\{\\rule{0.1em}{1em}\\right.}}", - "NestedFractions": "http://localhost:7936/test/screenshotter/test.html?m=\\dfrac{\\frac{a}{b}}{\\frac{c}{d}}\\dfrac{\\dfrac{a}{b}}{\\dfrac{c}{d}}\\frac{\\frac{a}{b}}{\\frac{c}{d}}", - "NullDelimiterInteraction": "http://localhost:7936/test/screenshotter/test.html?m=a \\bigl. + 2 \\quad \\left. + a \\right)", - "OpLimits": "http://localhost:7936/test/screenshotter/test.html?m={\\sin_2^2 \\lim_2^2 \\int_2^2 \\sum_2^2}{\\displaystyle \\lim_2^2 \\int_2^2 \\intop_2^2 \\sum_2^2}", - "Overline": "http://localhost:7936/test/screenshotter/test.html?m=\\overline{x}\\overline{x}\\overline{x^{x^{x^x}}} \\blue{\\overline{y}}", - "Phantom": "http://localhost:7936/test/screenshotter/test.html?m=\\dfrac{1+\\phantom{x^{\\blue{2}}} = x}{1+x^{\\blue{2}} = x}", - "PrimeSpacing": "http://localhost:7936/test/screenshotter/test.html?m=f'+f_2'+f^{f'}", - "RlapBug": "http://localhost:7936/test/screenshotter/test.html?m=\\frac{\\rlap{x}}{2}", - "Rule": "http://localhost:7936/test/screenshotter/test.html?m=\\rule{1em}{0.5em}\\rule{1ex}{2ex}\\rule{1em}{1ex}\\rule{1em}{0.431ex}", - "SizingBaseline": "http://localhost:7936/test/screenshotter/test.html?m={\\tiny a+b}a+b{\\Huge a+b}&pre=x&post=M", - "Sizing": "http://localhost:7936/test/screenshotter/test.html?m={\\Huge x}{\\LARGE y}{\\normalsize z}{\\scriptsize w}", - "Spacing": "http://localhost:7936/test/screenshotter/test.html?m=^3+[-1][1-1]1=1(=1)\\lvert a\\rvert~b", - "Sqrt": "http://localhost:7936/test/screenshotter/test.html?m=\\sqrt{\\sqrt{\\sqrt{x}}}_{\\sqrt{\\sqrt{x}}}^{\\sqrt{\\sqrt{\\sqrt{x}}}^{\\sqrt{\\sqrt{\\sqrt{x}}}}}", - "SqrtRoot": "http://localhost:7936/test/screenshotter/test.html?m=1+\\sqrt[3]{2}+\\sqrt[1923^234]{2^{2^{2^{2^{2^{2^{2^{2^{2^{2^{2^2}}}}}}}}}}}", - "SupSubCharacterBox": "http://localhost:7936/test/screenshotter/test.html?m=a_2f_2{f}_2{aa}_2{af}_2", - "SupSubHorizSpacing": "http://localhost:7936/test/screenshotter/test.html?m=x^{x^{x}}\\Big|x_{x_{x_{x_{x}}}}\\bigg|x^{x^{x_{x_{x_{x_{x}}}}}}\\bigg|", - "SupSubOffsets": "http://localhost:7936/test/screenshotter/test.html?m=\\displaystyle \\int_{2+3}x f^{2+3}+3\\lim_{2+3+4+5}f", - "Text": "http://localhost:7936/test/screenshotter/test.html?m=\\frac{a}{b}\\text{c~ {ab} \\ e}+fg", - "VerticalSpacing": "http://localhost:7936/test/screenshotter/test.html?pre=potato
blah&post=
moo&m=x^{\\Huge y}z" -} diff --git a/test/screenshotter/ss_data.yaml b/test/screenshotter/ss_data.yaml new file mode 100644 index 000000000..a51bba16d --- /dev/null +++ b/test/screenshotter/ss_data.yaml @@ -0,0 +1,97 @@ +# List of test cases for which we create screenshots and other documents. +# Each value in the top level dictionary is either a string or a dict +# which may contain the following keys: +# - tex: the KaTeX input string +# - pre: some HTML to insert before the KaTeX content +# - post: some HTML to insert after the KaTeX content +# - display: set this to 1 in order to use display style +# +# Note that YAML will treat a value starting in { as a flow mapping. +# To avoid that, either enclose the value in '…' or use a block scalar style, +# writing | (or >) as the first symbol of the value and then continuing +# on the next line. See http://www.yaml.org/ for syntax details. + +Accents: \vec{A}\vec{x}\vec x^2\vec{x}_2^2\vec{A}^2\vec{xA}^2 +Arrays: | + \left(\begin{array}{rlc} + 1&2&3\\ + 1+1&2+1&3+1\cr1\over2&\scriptstyle 1/2&\frac12\\[1ex] + \begin{pmatrix}x\\y\end{pmatrix}&0&\begin{vmatrix}a&b\\c&d\end{vmatrix} + \end{array}\right] +ArrayType: 1\begin{array}{c}2\\3\end{array}4 +Baseline: a+b-c\cdot d/e +BasicTest: a +BinomTest: \dbinom{a}{b}\tbinom{a}{b}^{\binom{a}{b}+17} +Cases: | + f(a,b)=\begin{cases} + a+1&\text{if }b\text{ is odd} \\ + a&\text{if }b=0 \\ + a-1&\text{otherwise} + \end{cases} +Colors: + tex: \blue{a}\color{#0f0}{b}\color{red}{c} + nolatex: different syntax and different scope +DeepFontSizing: + tex: | + a^{\big| x^{\big(}}_{\Big\uparrow} + + i^{i^{\Huge x}_y}_{\Huge z} + + \dfrac{\Huge x}{y} + nolatex: \Huge inside \dfrac doesn't work, needs an extra {…} +DelimiterSizing: | + \bigl\uparrow\Bigl\downarrow\biggl\updownarrow + \Biggl\Uparrow\Biggr\Downarrow\biggr\langle\Bigr\}\bigr\rfloor +DisplayMode: + tex: \sum_{i=0}^\infty \frac{1}{i} + pre: pre + post: post + display: 1 +DisplayStyle: | + {\displaystyle\sqrt{x}}{\sqrt{x}} + {\displaystyle \frac12}{\frac12}{\displaystyle x^1_2}{x^1_2} +Exponents: a^{a^a_a}_{a^a_a} +FractionTest: \dfrac{a}{b}\frac{a}{b}\tfrac{a}{b}\;-\dfrac12\;1\tfrac12 +Functions: \sin\cos\tan\ln\log +GreekLetters: \alpha\beta\gamma\omega +KaTeX: + tex: \KaTeX + nolatex: There is no LaTeX command for this (yet) +Lap: ab\llap{f}cd\rlap{g}h +LeftRight: \left( x^2 \right) \left\{ x^{x^{x^{x^x}}} \right. +LeftRightListStyling: a+\left(x+y\right)-x +LeftRightStyleSizing: | + +\left\{\rule{0.1em}{1em}\right. + x^{+\left\{\rule{0.1em}{1em}\right. + x^{+\left\{\rule{0.1em}{1em}\right.}} +NestedFractions: | + \dfrac{\frac{a}{b}}{\frac{c}{d}}\dfrac{\dfrac{a}{b}} + {\dfrac{c}{d}}\frac{\frac{a}{b}}{\frac{c}{d}} +NullDelimiterInteraction: a \bigl. + 2 \quad \left. + a \right) +OpLimits: | + {\sin_2^2 \lim_2^2 \int_2^2 \sum_2^2} + {\displaystyle \lim_2^2 \int_2^2 \intop_2^2 \sum_2^2} +Overline: \overline{x}\overline{x}\overline{x^{x^{x^x}}} \blue{\overline{y}} +Phantom: \dfrac{1+\phantom{x^{\blue{2}}} = x}{1+x^{\blue{2}} = x} +PrimeSpacing: f'+f_2'+f^{f'} +RlapBug: \frac{\rlap{x}}{2} +Rule: \rule{1em}{0.5em}\rule{1ex}{2ex}\rule{1em}{1ex}\rule{1em}{0.431ex} +SizingBaseline: + tex: '{\tiny a+b}a+b{\Huge a+b}' + pre: x + post: M +Sizing: | + {\Huge x}{\LARGE y}{\normalsize z}{\scriptsize w} +Spacing: ^3+[-1][1-1]1=1(=1)\lvert a\rvert~b +Sqrt: | + \sqrt{\sqrt{\sqrt{x}}}_{\sqrt{\sqrt{x}}}^{\sqrt{\sqrt{\sqrt{x}}} + ^{\sqrt{\sqrt{\sqrt{x}}}}} +SqrtRoot: | + 1+\sqrt[3]{2}+\sqrt[1923^234]{2^{2^{2^{2^{2^{2^{2^{2^{2^{2^{2^2}}}}}}}}}}} +SupSubCharacterBox: a_2f_2{f}_2{aa}_2{af}_2 +SupSubHorizSpacing: | + x^{x^{x}}\Big|x_{x_{x_{x_{x}}}}\bigg|x^{x^{x_{x_{x_{x_{x}}}}}}\bigg| +SupSubOffsets: \displaystyle \int_{2+3}x f^{2+3}+3\lim_{2+3+4+5}f +Text: \frac{a}{b}\text{c~ {ab} \ e}+fg +VerticalSpacing: + pre: potato
blah + tex: x^{\Huge y}z + post:
moo diff --git a/test/screenshotter/test.html b/test/screenshotter/test.html index f03df4d73..67ff556f6 100644 --- a/test/screenshotter/test.html +++ b/test/screenshotter/test.html @@ -1,7 +1,7 @@ - Huxley test + Screenshotter test