mathoid-texvcjs
Version:
A TeX/LaTeX validator for MediaWiki.
492 lines (487 loc) • 25 kB
JavaScript
'use strict';
var assert = require('assert');
var texvcjs = require('../');
// set this variable to the path to your texvccheck binary for additional
// sanity-checking against the ocaml texvccheck.
var TEXVCBINARY = 0; // "../../Math/texvccheck/texvccheck";
var tryocaml = function (input, output, done, fixDoubleSpacing) {
if (!TEXVCBINARY) { return done(); }
var cp = require('child_process');
cp.execFile(TEXVCBINARY, [input], { encoding: 'utf8' }, function (err, stdout, stderr) {
if (err) { return done(err); }
if (stderr) { return done(stderr); }
if (fixDoubleSpacing) { stdout = stdout.replace(/ {2}/g, ' '); }
assert.equal(stdout, '+' + output);
done();
});
};
var DELIMITERS1 =
[ '(', ')', '[', ']', '\\{', '\\}', '|' ];
var DELIMITERS2 =
('\\backslash\\downarrow\\Downarrow\\langle\\lbrace\\lceil\\lfloor' +
'\\llcorner\\lrcorner\\rangle\\rbrace\\rceil\\rfloor\\rightleftharpoons' +
'\\twoheadleftarrow\\twoheadrightarrow\\ulcorner\\uparrow\\Uparrow' +
'\\updownarrow\\Updownarrow\\urcorner\\Vert\\vert\\lbrack\\rbrack')
.split(/\\/).slice(1).map(function (f) { return '\\' + f; });
var DELIMITERS3 =
('\\darr\\dArr\\Darr\\lang\\rang\\uarr\\uArr\\Uarr')
.split(/\\/).slice(1).map(function (f) { return '\\' + f; });
describe('Comprehensive test cases', function () {
var testcases = {
'Box functions': {
input:
'\\text {-0-9a-zA-Z+*,=():/;?.!\'` \x80-\xFF} ' +
'\\mbox {-0-9a-zA-Z+*,=():/;?.!\'` \x80-\xFF} ' +
'\\hbox {-0-9a-zA-Z+*,=():/;?.!\'` \x80-\xFF} ' +
'\\vbox {-0-9a-zA-Z+*,=():/;?.!\'` \x80-\xFF} ',
output:
'{\\text{-0-9a-zA-Z+*,=():/;?.!\'` \x80-\xFF}}' +
'{\\mbox{-0-9a-zA-Z+*,=():/;?.!\'` \x80-\xFF}}' +
'{\\hbox{-0-9a-zA-Z+*,=():/;?.!\'` \x80-\xFF}}' +
'{\\vbox{-0-9a-zA-Z+*,=():/;?.!\'` \x80-\xFF}}'
},
'Box functions (2)': {
input: '{\\text{ABC}}{\\mbox{ABC}}{\\hbox{ABC}}{\\vbox{ABC}}',
skipOcaml: true /* extra braces in ocaml version */
},
'LaTeX functions': {
input:
'\\arccos \\arcsin \\arctan \\arg \\cosh \\cos \\cot \\coth ' +
'\\csc \\deg \\det \\dim \\exp \\gcd \\hom \\inf \\ker \\lg ' +
'\\lim \\liminf \\limsup \\ln \\log \\max \\min \\Pr \\sec ' +
'\\sin \\sinh \\sup \\tan \\tanh '
},
'Mediawiki functions': {
input:
'\\arccot\\arcsec\\arccsc\\sgn\\sen',
output:
'\\operatorname {arccot} \\operatorname {arcsec} ' +
'\\operatorname {arccsc} \\operatorname {sgn} ' +
'\\operatorname {sen} '
},
'Literals (1)': {
input:
'\\aleph \\alpha \\amalg \\And \\angle \\approx ' +
'\\approxeq \\ast \\asymp \\backepsilon \\backprime ' +
'\\backsim \\backsimeq \\barwedge \\Bbbk \\because \\beta ' +
'\\beth \\between \\bigcap \\bigcirc \\bigcup \\bigodot ' +
'\\bigoplus \\bigotimes \\bigsqcup \\bigstar ' +
'\\bigtriangledown \\bigtriangleup \\biguplus \\bigvee ' +
'\\bigwedge \\blacklozenge \\blacksquare \\blacktriangle ' +
'\\blacktriangledown \\blacktriangleleft \\blacktriangleright ' +
'\\bot \\bowtie \\Box \\boxdot \\boxminus \\boxplus ' +
'\\boxtimes \\bullet \\bumpeq \\Bumpeq \\cap \\Cap \\cdot ' +
'\\cdots \\centerdot \\checkmark \\chi \\circ \\circeq ' +
'\\circlearrowleft \\circlearrowright \\circledast ' +
'\\circledcirc \\circleddash \\circledS \\clubsuit \\colon ' +
'\\complement \\cong \\coprod \\cup \\Cup ' +
'\\curlyeqprec \\curlyeqsucc \\curlyvee \\curlywedge ' +
'\\curvearrowleft \\curvearrowright \\dagger \\daleth ' +
'\\dashv \\ddagger \\ddots \\delta \\Delta ' +
'\\diagdown \\diagup \\diamond \\Diamond \\diamondsuit ' +
'\\digamma \\displaystyle \\div \\divideontimes \\doteq ' +
'\\doteqdot \\dotplus \\dots \\dotsb \\dotsc \\dotsi \\dotsm ' +
'\\dotso \\doublebarwedge \\downdownarrows \\downharpoonleft ' +
'\\downharpoonright \\ell \\emptyset \\epsilon \\eqcirc ' +
'\\eqsim \\eqslantgtr \\eqslantless \\equiv \\eta \\eth ' +
'\\exists \\fallingdotseq \\Finv \\flat \\forall \\frown ' +
'\\Game \\gamma \\Gamma \\geq \\geqq \\geqslant \\gets \\gg ' +
'\\ggg \\gimel \\gnapprox \\gneq \\gneqq \\gnsim \\gtrapprox ' +
'\\gtrdot \\gtreqless \\gtreqqless \\gtrless \\gtrsim ' +
'\\gvertneqq \\hbar \\heartsuit \\hookleftarrow ' +
'\\hookrightarrow \\hslash \\iff \\iiiint \\iiint \\iint ' +
'\\Im \\imath \\implies \\in \\infty \\injlim \\int ' +
'\\intercal \\iota \\jmath \\kappa \\lambda \\Lambda \\land ' +
'\\ldots \\leftarrow \\Leftarrow \\leftarrowtail ' +
'\\leftharpoondown \\leftharpoonup \\leftleftarrows ' +
'\\leftrightarrow \\Leftrightarrow \\leftrightarrows ' +
'\\leftrightharpoons \\leftrightsquigarrow \\leftthreetimes ' +
'\\leq \\leqq \\leqslant \\lessapprox \\lessdot ' +
'\\lesseqgtr \\lesseqqgtr \\lessgtr \\lesssim \\limits \\ll ' +
'\\Lleftarrow \\lll \\lnapprox \\lneq \\lneqq \\lnot \\lnsim ' +
'\\longleftarrow \\Longleftarrow \\longleftrightarrow ' +
'\\Longleftrightarrow \\longmapsto \\longrightarrow ' +
'\\Longrightarrow \\looparrowleft \\looparrowright \\lor ' +
'\\lozenge \\Lsh \\ltimes \\lVert \\lvertneqq \\mapsto ' +
'\\measuredangle \\mho \\mid \\mod \\models \\mp \\mu ' +
'\\multimap \\nabla \\natural \\ncong \\nearrow \\neg \\neq ' +
'\\nexists \\ngeq \\ngeqq \\ngeqslant \\ngtr \\ni ' +
'\\nleftarrow \\nLeftarrow \\nleftrightarrow ' +
'\\nLeftrightarrow \\nleq \\nleqq \\nleqslant \\nless \\nmid ' +
'\\nolimits \\not \\notin \\nparallel \\nprec \\npreceq ' +
'\\nrightarrow \\nRightarrow \\nshortmid \\nshortparallel ' +
'\\nsim \\nsubseteq \\nsubseteqq \\nsucc \\nsucceq ' +
'\\nsupseteq \\nsupseteqq \\ntriangleleft \\ntrianglelefteq ' +
'\\ntriangleright \\ntrianglerighteq \\nu \\nvdash \\nVdash ' +
'\\nvDash \\nVDash \\nwarrow \\odot \\oint \\omega \\Omega ' +
'\\ominus \\oplus \\oslash \\otimes ' +
'\\P \\parallel \\partial ' +
'\\perp \\phi \\Phi \\pi \\Pi \\pitchfork \\pm \\prec ' +
'\\precapprox \\preccurlyeq \\preceq \\precnapprox ' +
'\\precneqq \\precnsim \\precsim \\prime \\prod \\projlim ' +
'\\propto \\psi \\Psi \\qquad \\quad \\Re \\rho \\rightarrow ' +
'\\Rightarrow \\rightarrowtail \\rightharpoondown ' +
'\\rightharpoonup \\rightleftarrows \\rightrightarrows ' +
'\\rightsquigarrow \\rightthreetimes \\risingdotseq ' +
'\\Rrightarrow \\Rsh \\rtimes \\rVert \\S ' +
'\\scriptscriptstyle \\scriptstyle \\searrow \\setminus ' +
'\\sharp \\shortmid \\shortparallel \\sigma \\Sigma \\sim ' +
'\\simeq \\smallfrown \\smallsetminus \\smallsmile \\smile ' +
'\\spadesuit \\sphericalangle \\sqcap \\sqcup \\sqsubset ' +
'\\sqsubseteq \\sqsupset \\sqsupseteq \\square \\star ' +
'\\subset \\Subset \\subseteq \\subseteqq \\subsetneq ' +
'\\subsetneqq \\succ \\succapprox \\succcurlyeq \\succeq ' +
'\\succnapprox \\succneqq \\succnsim \\succsim \\sum ' +
'\\supset \\Supset \\supseteq \\supseteqq \\supsetneq ' +
'\\supsetneqq \\surd \\swarrow \\tau \\textstyle ' +
'\\therefore \\theta \\Theta ' +
'\\thickapprox \\thicksim \\times \\to \\top \\triangle ' +
'\\triangledown \\triangleleft \\trianglelefteq \\triangleq ' +
'\\triangleright \\trianglerighteq ' +
'\\upharpoonleft \\upharpoonright \\uplus \\upsilon ' +
'\\Upsilon \\upuparrows \\varDelta \\varepsilon \\varGamma ' +
'\\varinjlim \\varkappa \\varLambda \\varliminf \\varlimsup ' +
'\\varnothing \\varOmega \\varphi \\varPhi \\varpi \\varPhi ' +
'\\varprojlim \\varpropto \\varrho \\varsigma \\varSigma ' +
'\\varsubsetneq \\varsubsetneqq \\varsupsetneq ' +
'\\varsupsetneqq \\vartheta \\varTheta \\vartriangle ' +
'\\vartriangleleft \\vartriangleright \\varUpsilon \\varXi ' +
'\\vdash \\Vdash \\vDash \\vdots \\vee ' +
'\\veebar \\vline \\Vvdash \\wedge ' +
'\\wp \\wr \\xi \\Xi \\zeta '
},
'Literals (2)': {
input:
'\\AA\\Coppa\\coppa\\Digamma\\euro\\geneuro\\geneuronarrow' +
'\\geneurowide\\Koppa\\koppa\\officialeuro\\Sampi\\sampi' +
'\\Stigma\\stigma\\textvisiblespace\\varstigma',
output:
'\\mbox{\\AA} \\mbox{\\Coppa} \\mbox{\\coppa} ' +
'\\mbox{\\Digamma} \\mbox{\\euro} \\mbox{\\geneuro} ' +
'\\mbox{\\geneuronarrow} \\mbox{\\geneurowide} ' +
'\\mbox{\\Koppa} \\mbox{\\koppa} \\mbox{\\officialeuro} ' +
'\\mbox{\\Sampi} \\mbox{\\sampi} \\mbox{\\Stigma} ' +
'\\mbox{\\stigma} \\mbox{\\textvisiblespace} ' +
'\\mbox{\\varstigma} '
},
'Literals (2\')': {
/* We can parse what we emit (but the ocaml version can't) */
input:
'\\mbox{\\AA} \\mbox{\\Coppa} \\mbox{\\coppa} ' +
'\\mbox{\\Digamma} \\mbox{\\euro} \\mbox{\\geneuro} ' +
'\\mbox{\\geneuronarrow} \\mbox{\\geneurowide} ' +
'\\mbox{\\Koppa} \\mbox{\\koppa} \\mbox{\\officialeuro} ' +
'\\mbox{\\Sampi} \\mbox{\\sampi} \\mbox{\\Stigma} ' +
'\\mbox{\\stigma} \\mbox{\\textvisiblespace} ' +
'\\mbox{\\varstigma} ',
skipOcaml: true
},
'Literals (2) MJ': {
usemathrm: true,
input:
'\\AA\\Coppa\\coppa\\Digamma\\euro\\geneuro\\geneuronarrow' +
'\\geneurowide\\Koppa\\koppa\\officialeuro\\Sampi\\sampi' +
'\\Stigma\\stigma\\textvisiblespace\\varstigma',
output:
'\\mathrm {\\AA} \\mathrm {\\Coppa} \\mathrm {\\coppa} ' +
'\\mathrm {\\Digamma} \\mathrm {\\euro} \\mathrm {\\geneuro} ' +
'\\mathrm {\\geneuronarrow} \\mathrm {\\geneurowide} ' +
'\\mathrm {\\Koppa} \\mathrm {\\koppa} \\mathrm {\\officialeuro} ' +
'\\mathrm {\\Sampi} \\mathrm {\\sampi} \\mathrm {\\Stigma} ' +
'\\mathrm {\\stigma} \\mathrm {\\textvisiblespace} ' +
'\\mathrm {\\varstigma} '
},
'Literals (2\') MJ': {
usemathrm: true,
/* We can parse what we emit (but the ocaml version can't) */
input:
'\\mathrm {\\AA} \\mathrm {\\Coppa} \\mathrm {\\coppa} ' +
'\\mathrm {\\Digamma} \\mathrm {\\euro} \\mathrm {\\geneuro} ' +
'\\mathrm {\\geneuronarrow} \\mathrm {\\geneurowide} ' +
'\\mathrm {\\Koppa} \\mathrm {\\koppa} \\mathrm {\\officialeuro} ' +
'\\mathrm {\\Sampi} \\mathrm {\\sampi} \\mathrm {\\Stigma} ' +
'\\mathrm {\\stigma} \\mathrm {\\textvisiblespace} ' +
'\\mathrm {\\varstigma} ',
skipOcaml: true
},
'Literals (3)': {
oldtexvc: true,
input:
'\\C\\H\\N\\Q\\R\\Z\\alef\\alefsym\\Alpha\\and\\ang\\Beta' +
'\\bull\\Chi\\clubs\\cnums\\Complex\\Dagger\\diamonds\\Doteq' +
'\\doublecap\\doublecup\\empty\\Epsilon\\Eta\\exist\\ge' +
'\\gggtr\\hArr\\harr\\Harr\\hearts\\image\\infin\\Iota\\isin' +
'\\Kappa\\larr\\Larr\\lArr\\le\\lrarr\\Lrarr\\lrArr\\Mu' +
'\\natnums\\ne\\Nu\\O\\omicron\\Omicron\\or\\part\\plusmn' +
'\\rarr\\Rarr\\rArr\\real\\reals\\Reals\\restriction\\Rho' +
'\\sdot\\sect\\spades\\sub\\sube\\supe\\Tau\\thetasym' +
'\\varcoppa\\weierp\\Zeta',
output:
'\\mathbb {C} \\mathbb {H} \\mathbb {N} \\mathbb {Q} ' +
'\\mathbb {R} \\mathbb {Z} \\aleph \\aleph \\mathrm {A} ' +
'\\land \\angle \\mathrm {B} \\bullet \\mathrm {X} ' +
'\\clubsuit \\mathbb {C} \\mathbb {C} \\ddagger ' +
'\\diamondsuit \\doteqdot \\Cap \\Cup \\emptyset ' +
'\\mathrm {E} \\mathrm {H} \\exists \\geq \\ggg ' +
'\\Leftrightarrow \\leftrightarrow \\Leftrightarrow ' +
'\\heartsuit \\Im \\infty \\mathrm {I} \\in \\mathrm {K} ' +
'\\leftarrow \\Leftarrow \\Leftarrow \\leq ' +
'\\leftrightarrow \\Leftrightarrow \\Leftrightarrow ' +
'\\mathrm {M} \\mathbb {N} \\neq \\mathrm {N} \\emptyset ' +
'oO\\lor \\partial \\pm ' +
'\\rightarrow \\Rightarrow \\Rightarrow \\Re \\mathbb {R} ' +
'\\mathbb {R} \\upharpoonright \\mathrm {P} \\cdot ' +
'\\S \\spadesuit \\subset \\subseteq \\supseteq ' +
'\\mathrm {T} \\vartheta \\mbox{\\coppa} \\wp \\mathrm {Z} '
},
Big: (function () {
var BIGS = ('\\big\\Big\\bigg\\Bigg\\biggl\\Biggl\\biggr\\Biggr' +
'\\bigl\\Bigl\\bigr\\Bigr').split(/\\/).slice(1);
var DELIMITERS = DELIMITERS1.concat(DELIMITERS2)
.concat(['\\darr', '\\uarr']);
var input = BIGS.map(function (b) {
return DELIMITERS.map(function (d) {
return '\\' + b + d;
}).join('');
}).join('');
var output = BIGS.map(function (b) {
return DELIMITERS.map(function (d) {
if (d === '\\darr') { d = '\\downarrow'; }
if (d === '\\uarr') { d = '\\uparrow'; }
if (d.charAt(0) === '\\' && d.length > 2) { d = d + ' '; }
return '{\\' + b + ' ' + d + '}';
}).join('');
}).join('');
return { input: input, output: output };
}()),
'Delimiters (1)': {
input: DELIMITERS1.join('') + DELIMITERS2.join(' ') + ' '
},
'Delimiters (2)': {
input:
'\\darr\\dArr\\Darr\\lang\\rang\\uarr\\uArr\\Uarr',
output:
'\\downarrow \\Downarrow \\Downarrow \\langle \\rangle ' +
'\\uparrow \\Uparrow \\Uparrow '
},
'Delimiters (3)': {
input:
'\\left' + DELIMITERS1.join('\\left') +
'\\right' + DELIMITERS1.slice().reverse().join('\\right')
},
'Delimiters (4)': {
input:
'\\left' + DELIMITERS2.join(' \\left') +
' \\right' + DELIMITERS2.slice().reverse().join(' \\right') + ' '
},
'Delimiters (5)': {
input:
'\\left\\darr \\left\\dArr \\left\\Darr \\left\\lang ' +
'\\right\\rang \\right\\uarr \\right\\uArr \\right\\Uarr ',
output:
'\\left\\downarrow \\left\\Downarrow \\left\\Downarrow ' +
'\\left\\langle \\right\\rangle ' +
'\\right\\uparrow \\right\\Uparrow \\right\\Uparrow '
},
FUN_AR1: {
input:
'\\acute{A}\\bar{A}\\bcancel{A}\\bmod{A}\\boldsymbol{A}' +
'\\breve{A}\\cancel{A}\\check{A}\\ddot{A}\\dot{A}\\emph{A}' +
'\\grave{A}\\hat{A}\\hphantom{A}\\mathbb{A}\\mathbf{A}' +
'\\mathcal{A}\\mathclose{A}\\mathfrak{A}\\mathit{A}' +
'\\mathop{A}\\mathopen{A}\\mathord{A}\\mathpunct{A}' +
'\\mathrm{A}\\mathsf{A}\\mathtt{A}' +
'\\operatorname{A}\\overleftarrow{A}\\overleftrightarrow{A}' +
'\\overline{A}\\overrightarrow{A}\\phantom{A}\\pmod{A}\\sqrt{A}' +
'\\textbf{A}\\textit{A}\\textrm{A}\\textsf{A}\\texttt{A}' +
'\\tilde{A}\\underline{A}\\vec{A}\\vphantom{A}\\widehat{A}' +
'\\widetilde{A}\\xcancel{A}',
output:
'{\\acute {A}}{\\bar {A}}{\\bcancel {A}}{\\bmod {A}}' +
'{\\boldsymbol {A}}{\\breve {A}}{\\cancel {A}}{\\check {A}}' +
'{\\ddot {A}}{\\dot {A}}{\\emph {A}}{\\grave {A}}{\\hat {A}}' +
'{\\hphantom {A}}\\mathbb {A} \\mathbf {A} {\\mathcal {A}}' +
'{\\mathclose {A}}{\\mathfrak {A}}{\\mathit {A}}' +
'\\mathop {A} {\\mathopen {A}}{\\mathord {A}}' +
'{\\mathpunct {A}}\\mathrm {A} {\\mathsf {A}}' +
'{\\mathtt {A}}\\operatorname {A} {\\overleftarrow {A}}' +
'{\\overleftrightarrow {A}}{\\overline {A}}' +
'{\\overrightarrow {A}}{\\phantom {A}}{\\pmod {A}}{\\sqrt {A}}' +
'{\\textbf {A}}{\\textit {A}}{\\textrm {A}}{\\textsf {A}}' +
'{\\texttt {A}}{\\tilde {A}}{\\underline {A}}{\\vec {A}}' +
'{\\vphantom {A}}{\\widehat {A}}{\\widetilde {A}}{\\xcancel {A}}',
skipOcaml: 'double spacing and extra braces'
},
'FUN_AR1 (2)': {
oldtexvc: true,
input: '\\Bbb{foo}\\bold{bar}',
output: '{\\mathbb {foo}}{\\mathbf {bar}}',
skipOcaml: 'double spacing',
skipReparse: 'spacing'
},
'FUN_AR1NB (1)': {
input: '\\operatorname {sin} ',
skipOcaml: 'missing space'
},
'FUN_AR1NB (2)': {
input: '\\mathbb {A} \\mathbf {B} \\mathrm {C} ',
skipOcaml: 'extra braces'
},
'FUN_AR1NB (3)': {
input: '\\overbrace {A} _{b}^{c}\\underbrace {C} _{d}^{e}',
skipOcaml: 'ocaml bug'
},
'FUN_AR1NB (4)': {
input: '\\xleftarrow{A}\\xrightarrow{A}',
output: '\\xleftarrow {A} \\xrightarrow {A} '
},
'FUN_AR1NB (5)': {
input: '\\mathrel{A}\\mathbin{A}',
output: '\\mathrel {A} \\mathbin {A} '
},
FUN_AR1OPT: {
input:
'\\sqrt{2}\\sqrt[3]{2}' +
'\\xleftarrow{above}\\xleftarrow[below]{above}' +
'\\xrightarrow{above}\\xrightarrow[below]{above}',
output:
'{\\sqrt {2}}{\\sqrt[{3}]{2}}' +
'\\xleftarrow {above} {\\xleftarrow[{below}]{above}}' +
'\\xrightarrow {above} {\\xrightarrow[{below}]{above}}',
skipOcaml: 'spacing'
},
FUN_AR2: {
input:
'\\binom{A}{B}\\cancelto{A}{B}\\cfrac{A}{B}\\dbinom{A}{B}' +
'\\dfrac{A}{B}\\frac{A}{B}\\overset{A}{B}\\stackrel{A}{B}' +
'\\tbinom{A}{B}\\tfrac{A}{B}\\underset{A}{B}',
output:
'{\\binom {A}{B}}{\\cancelto {A}{B}}{\\cfrac {A}{B}}' +
'{\\dbinom {A}{B}}{\\dfrac {A}{B}}{\\frac {A}{B}}' +
'{\\overset {A}{B}}{\\stackrel {A}{B}}{\\tbinom {A}{B}}' +
'{\\tfrac {A}{B}}{\\underset {A}{B}}',
skipOcaml: 'double spacing'
},
FUN_AR2nb: {
input: '\\sideset{_\\dagger^*}{_\\dagger^*}\\prod',
output: '\\sideset {_{\\dagger }^{*}}{_{\\dagger }^{*}}\\prod '
},
'FUN_INFIX (1)': {
input: '\\left({a\\atop 1}{b\\atop m}{c\\atop n}\\right)',
output: '\\left({a \\atop 1}{b \\atop m}{c \\atop n}\\right)'
},
'FUN_INFIX (2)': {
input: '{1\\,0\\choose0\\,1}',
output: '{1\\,0 \\choose 0\\,1}'
},
'FUN_INFIX (3)': {
input: '{a\\over b}',
output: '{a \\over b}'
},
'FUN_INFIX (4)': {
input: 'a\\over b',
output: '{a \\over b}'
},
DECLh: {
input: '{abc \\rm def \\it ghi \\cal jkl \\bf mno}',
output: '{abc{\\rm {def{\\it {ghi{\\cal {jkl{\\bf {mno}}}}}}}}}'
},
litsq_zq: {
input: ']^2',
output: ']^{2}'
},
'Matrices (1)': (function () {
var ENV =
['matrix', 'pmatrix', 'bmatrix', 'Bmatrix', 'vmatrix', 'Vmatrix',
'array', 'align', 'alignat', 'smallmatrix', 'cases'];
var arg = function (env) {
switch (env) {
case 'array': return '{|c||c|}';
case 'alignedat': case 'alignat': return '{3}';
default: return '';
}
};
return {
input: ENV.map(function (env) {
return '\\begin{' + env + '}' + arg(env) + ' a & b \\\\\\hline c & d \\end{' + env + '}';
}).join(''),
output: ENV.map(function (env) {
if (env === 'align') { env = 'aligned'; }
if (env === 'alignat') { env = 'alignedat'; }
return '{\\begin{' + env + '}' + arg(env) + 'a&b\\\\\\hline c&d\\end{' + env + '}}';
}).join('')
};
}()),
'Matrices (2)': {
input: '{\\begin{array}{|c|}\\hline {\\!n\\!}\\\\\\hline \\end{array}}'
},
'Matrices (3)': {
input: '\\begin{alignedat} { 3 } a & b & c \\end{alignedat}',
output: '{\\begin{alignedat}{3}a&b&c\\end{alignedat}}'
},
'Color (1)': {
input: '\\definecolor {mycolor}{rgb}{0.1,.2,0.}\\color {mycolor}'
},
'Color (2)': {
input:
'\\color {blue}\\color [named]{blue}\\color [gray]{0.5}' +
'\\color [rgb]{0,1,0}\\color [cmyk]{1,0,0,0}'
},
'Color (3)': {
input:
'\\pagecolor {blue}\\pagecolor [named]{blue}' +
'\\pagecolor [gray]{0.5}\\pagecolor [rgb]{0,1,0}' +
'\\pagecolor [cmyk]{1,0,0,0}'
},
'Color (4)': {
input:
'\\definecolor{mycolor}{rgb}{0.1,.2,0.}\\color[CMYK]{0,1,0,1}',
output:
'\\definecolor {mycolor}{rgb}{0.1,.2,0.}\\color [cmyk]{0,1,0,1}'
},
'Color (5)': {
input:
'\\definecolor{mycolor}{RGB}{255,102,51}' +
'\\pagecolor [RGB]{51,102,255}',
output:
'\\definecolor {mycolor}{rgb}{1,0.4,0.2}' +
'\\pagecolor [rgb]{0.2,0.4,1}'
},
Unicode: {
input: '{\\mbox{💩\uD83D\uDCA9}}'
}
};
Object.keys(testcases).forEach(function (title) {
describe(title, function () {
var tc = testcases[title];
tc.output = tc.output || tc.input;
if (!tc.skipJs) {
it('output should be correct', function () {
var result = texvcjs.check(tc.input, { debug: true, usemathrm: tc.usemathrm, oldtexvc: tc.oldtexvc });
assert.equal(result.status, '+');
assert.equal(result.output, tc.output);
});
}
if (!tc.skipReparse) {
// verify that the output doesn't change if we feed it
// through again.
it('should parse its own output', function () {
var result1 = texvcjs.check(tc.output, { debug: true });
var result2 = texvcjs.check(result1.output, { debug: true });
assert.equal(result2.status, '+');
assert.equal(result2.output, result1.output);
});
}
if (!tc.skipOcaml) {
it('should match ocaml output', function (done) {
tryocaml(tc.input, tc.output, done);
});
}
if (tc.skipOcaml === 'double spacing') {
it('should match ocaml output (except for spacing)', function (done) {
tryocaml(tc.input, tc.output, done, true);
});
}
});
});
});