From 6bb62b11b4eadf8039fa98b75e642e6fe47da2fd Mon Sep 17 00:00:00 2001 From: Eddie Kohler Date: Wed, 23 Nov 2016 08:52:10 -0500 Subject: [PATCH] Support \mathop, \mathrel, \mathbin, \mathpunct, etc. class commands. These commands set their arguments in a given TeX math class. Use the existing "op" type for \mathop (to support \limits); introduce a new "mclass" type for the other classes. Fixes #482. Tests borrowed from #485 (cbreeden). --- src/buildHTML.js | 11 +++ src/buildMathML.js | 11 ++- src/functions.js | 78 ++++++++++-------- test/screenshotter/images/MathAtom-chrome.png | Bin 0 -> 7736 bytes .../screenshotter/images/MathAtom-firefox.png | Bin 0 -> 7720 bytes .../screenshotter/images/MathAtom2-chrome.png | Bin 0 -> 7893 bytes .../images/MathAtom2-firefox.png | Bin 0 -> 7846 bytes test/screenshotter/ss_data.yaml | 2 + 8 files changed, 65 insertions(+), 37 deletions(-) create mode 100644 test/screenshotter/images/MathAtom-chrome.png create mode 100644 test/screenshotter/images/MathAtom-firefox.png create mode 100644 test/screenshotter/images/MathAtom2-chrome.png create mode 100644 test/screenshotter/images/MathAtom2-firefox.png diff --git a/src/buildHTML.js b/src/buildHTML.js index d30bbde..253b0eb 100644 --- a/src/buildHTML.js +++ b/src/buildHTML.js @@ -786,6 +786,11 @@ groupTypes.op = function(group, options) { // The slant of the symbol is just its italic correction. slant = base.italic; + } else if (group.value.value) { + // If this is a list, compose that list. + var inner = buildExpression(group.value.value, options, true); + + base = makeSpan(["mop"], inner, options); } else { // Otherwise, this is a text operator. Build the text from the // operator's name. @@ -1399,6 +1404,12 @@ groupTypes.phantom = function(group, options) { return new buildCommon.makeFragment(elements); }; +groupTypes.mclass = function(group, options) { + var elements = buildExpression(group.value.value, options, true); + + return makeSpan([group.value.mclass], elements, options); +}; + /** * buildGroup is the function that takes a group and calls the correct groupType * function for it. It also handles the interaction of size and style changes diff --git a/src/buildMathML.js b/src/buildMathML.js index 5b10fac..11a088f 100644 --- a/src/buildMathML.js +++ b/src/buildMathML.js @@ -316,7 +316,7 @@ groupTypes.spacing = function(group) { return node; }; -groupTypes.op = function(group) { +groupTypes.op = function(group, options) { var node; // TODO(emily): handle big operators using the `largeop` attribute @@ -325,6 +325,10 @@ groupTypes.op = function(group) { // This is a symbol. Just add the symbol. node = new mathMLTree.MathNode( "mo", [makeText(group.value.body, group.mode)]); + } else if (group.value.value) { + // This is an operator with children. Add them. + node = new mathMLTree.MathNode( + "mo", buildExpression(group.value.value, options)); } else { // This is a text operator. Add all of the characters from the // operator's name. @@ -475,6 +479,11 @@ groupTypes.phantom = function(group, options) { return new mathMLTree.MathNode("mphantom", inner); }; +groupTypes.mclass = function(group, options) { + var inner = buildExpression(group.value.value, options); + return new mathMLTree.MathNode("mstyle", inner); +}; + /** * Takes a list of nodes, builds them, and returns a list of the generated * MathML nodes. A little simpler than the HTML version because we don't do any diff --git a/src/functions.js b/src/functions.js index dc8a392..deaf4f7 100644 --- a/src/functions.js +++ b/src/functions.js @@ -100,6 +100,16 @@ function defineFunction(names, props, handler) { } } +// Since the corresponding buildHTML/buildMathML function expects a +// list of elements, we normalize for different kinds of arguments +var ordargument = function(arg) { + if (arg.type === "ordgroup") { + return arg.value; + } else { + return [arg]; + } +}; + // A normal square root defineFunction("\\sqrt", { numArgs: 1, @@ -121,19 +131,9 @@ defineFunction("\\text", { greediness: 2, }, function(context, args) { var body = args[0]; - // Since the corresponding buildHTML/buildMathML function expects a - // list of elements, we normalize for different kinds of arguments - // TODO(emily): maybe this should be done somewhere else - var inner; - if (body.type === "ordgroup") { - inner = body.value; - } else { - inner = [body]; - } - return { type: "text", - body: inner, + body: ordargument(body), }; }); @@ -146,18 +146,10 @@ defineFunction("\\color", { }, function(context, args) { var color = args[0]; var body = args[1]; - // Normalize the different kinds of bodies (see \text above) - var inner; - if (body.type === "ordgroup") { - inner = body.value; - } else { - inner = [body]; - } - return { type: "color", color: color.value, - value: inner, + value: ordargument(body), }; }); @@ -223,16 +215,24 @@ defineFunction("\\phantom", { numArgs: 1, }, function(context, args) { var body = args[0]; - var inner; - if (body.type === "ordgroup") { - inner = body.value; - } else { - inner = [body]; - } - return { type: "phantom", - value: inner, + value: ordargument(body), + }; +}); + +// Math class commands except \mathop +defineFunction([ + "\\mathord", "\\mathbin", "\\mathrel", "\\mathopen", + "\\mathclose", "\\mathpunct", "\\mathinner", +], { + numArgs: 1, +}, function(context, args) { + var body = args[0]; + return { + type: "mclass", + mclass: "m" + context.funcName.substr(5), + value: ordargument(body), }; }); @@ -298,17 +298,10 @@ defineFunction([ greediness: 3, }, function(context, args) { var body = args[0]; - var atoms; - if (body.type === "ordgroup") { - atoms = body.value; - } else { - atoms = [body]; - } - return { type: "color", color: "katex-" + context.funcName.slice(1), - value: atoms, + value: ordargument(body), }; }); @@ -378,6 +371,19 @@ defineFunction([ }; }); +// \mathop class command +defineFunction("\\mathop", { + numArgs: 1, +}, function(context, args) { + var body = args[0]; + return { + type: "op", + limits: false, + symbol: false, + value: ordargument(body), + }; +}); + // Fractions defineFunction([ "\\dfrac", "\\frac", "\\tfrac", diff --git a/test/screenshotter/images/MathAtom-chrome.png b/test/screenshotter/images/MathAtom-chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..175c72a74bda2bba51c82e6c350ffdd14df96590 GIT binary patch literal 7736 zcmeHLSy+?Tx?TYkC(vC{RD`sfwx~=hlZX&)i_}^MiyA>BB1I4cEC>i8gK`ARAlVq|U@WW~NMj!y@$gyvZoV->f;S+utOwg%*Lbdp_ zPxx&<@nQ8>pGKIN6&7{wJMLJ#x*D_1#{6^J4aM1CQg;>L+JmrTL!T!;xbfhNbM1cw zJ#@$n7;{v_Z;1UWdf_vJ)tNRf97!D`*h)oL26hJw*K?$6&0E{~{22U2bq%*TXV79309-H75QF98vr72HL0%4aDV2)s)+YYxKl&p) zoPP^Mw6h|`;qJ8$YuhP_qJOvK4l!#ls2FF>5@pG;zB;^Flk*{DQHq>tXmQoQXg4fB z?M-O(S`El`YseQG-OR$rR5Ct7Vvzd9M%A(zvmF8rI*aD$!cLNoHiXhx@cunUaOrx= z*z1OBWZq1}9bhfs7-yO0leF$wD(@Cta6)ffUpc@^dWAf>H1=Acoy~JMsz$53gz0&x zD|~k+1>W@&06Y#EunnJ#4*1EB2{5duj6qA9G{WZKTy>7eS^(G?#bANFWm;(xJ)N%= z-9DYm`{5J785%fs4YomqJ!%#O!_8tY&c|Ax6}*le{y|H-;UrsJ5A%Rd)GHnCr%EGZ z$oLXo6YcpDv$AGFiWJUAif0fMSm@ads)t+KKHMEl&=7qQUPsi~)ogvzob6!%uIlTR zS}rY!Yw{Q*6|8G1V-t`xUEr7GQ8wR87E~rk4K{$oE}sEzRbu!%n(5`pF&)xT_R6V| ziJ$>F=4;TIN+Vuwn?oR~g`z;oR6O3jIjnrd$b zQfR@g>o6k$Fqv*}xMggFw^yR$BiW3o$fOj-@}|eYZ_^}JZTZv$Vuc$EkOaWE(%@2} zmeu4)m>{*ez#V&{*OKc@oORv;9cwZmNxKS^nr#MQBejhWrgRwV*Xp;v0MPfL{POO` zA_9A$XkQK^O0U!grgcjqGQ{`ymmC4$JZlZPuC?`1&D3W0patw|Wfs`QIW99~8>yDl zOLu`=U{51%fH?d3)&H)z&Cls>YnslXr5bDlWT`h?3XySz9mq^o)0m3t$2D|u9mkIG z{@3GQ`V?JLj)eQ(+Z!UE?Cn64wBvuKX;d=Im2q}{aLPmO9X;UZsy9wfSW=77C)0;; zq_+Q=E47)96jSigL&qPB>6{$)4l^^2VtPm@MQ&N%-nBD85`qGM>_qi6Wh~W&ay2y6 zlFH?}9Z#+lrbqe?G(Bq~cHZ09mZIP$fuPh6?SmyIfSmaWh(4q6(cML2RRTH1E$?!* z(oa$!FY3B$jrF_YXVhv%6ZvK8};Fp#R7#@Taq=)~a=BP0H}5a3K22WwP zNS1P4h4&&i!V?nKko5&#n8jY0hC|75jT!K_2MyS$7(P9rLWUH$#0G!dZ+T8S#9B(Y z1fB#oKKi(yx!yQXHBt%H5h~1uzixfpZ}4g$xGZ4m-ejOlJP3XNjv`*+=p_Y}bT|0+vr5*}ryrIyGR%j+Hmed}q;J?BHyTZAIkgwCuZNTL$FCb& z9C&-nGEi!cmrw4yJY4(XT?d-D@Wz&OAW6!re1}&_`SRx_?s&W4)@FyU8?SX@ENc&U z#MJJuxd~3UtEeasb7<~w%k}&Ao@bNG((GGjpS>z{!D>E-Oz^$=MsoF8T5#NpFKks= zI*p3rj#u7yin^bhEPhz!<0fekR*Rkl)Gx}X`r}@#G7ak49)4u{I~nMq;#lRk4?a?7 zeqXSEBA28M?YGw5M2NzIa373Lp4UNI?5B)1MqwMf^#R$Z|4(qHC2r#0zR*CaiP!C& zEf?A|`z)iPqPh=GKS@)T)uQ+;^+^7S@}m+-0Y)+4Pa!Br`o6e1eX1dn+i>YFWhWrp z_5BO%x-8EyHs{9W9)LBa35fXE4r*{4T`u{;JBFoG>b5a$5)u+(i3=yk(|V_esDe=` z;y_V%R(cmIn`T{DYHv;&OydV$e0PGP0f3W78T#j6-FJfIkjgQ7%f7CkZ;xZjP6?1D z)mi?}OB42_smb?Y52;kle5Zq|X=6=UXs&yrgxh#7Me3|_d&$h>MWeL?A6WKHpS^&3-`>eN|}IFQ&UrZCqHcP(WzqE zCE1TG?Swr;&a3jJ1TU7NHNzb*)tTMB&M`vf^)N!16fPfe6nyGb(;SE=aJQ8Py%M9Jcf0Vy$HM}y_ z;Y?K4Qxc{=-rY@aT*X2NQ%98$3U=|yoY+;-b7^R8>DLbZO-TX*P3~(qFY30BPrd|F zC#-Q(FOy*qzr^X6HZ>`m-`%$6nk-+ia{^iDzEWU8;i+`Q1)1~#I6Edt>lAe<|s zUfZ+qmz76vg}y%U+di?Ho#QfghW?-kg13NUYIDY~p~;uxF-nV-O%6A_;YLwyQ=a)A zocet(ADuG!z?0*Zy{$K)A2Rj6uvP4IBeT`UJI^#&&hQyY-rn8?8yynF17#DG#ephi z=wmv3uq5SAK!jof`FXQd9$XkcQk#rG zEqCZo_bzl+%#74euEo`!KT^QSw+Z+mrN#HaoByiWxgC(#U2+5B>FEq3v(t3TR@E4u zlbU^6_O0Tt&Au~&_cNy+yDjWzAywy}0bcKhb>8+L`J(C@*cmPw~iGQRNP9fy=1oBGbo zld}vH-Ms?mqM!b~-P8A)8uvB;hr>kll=fMBg#J6*t{6u7GQtfU&E9r`ZeHXXe^H%# zBE{=bK>bBYN9PO&vYN5S!g!gLwgfNT9k0%^XP!xES-;gTXt)A$7mU?_4KWhPH}-&3 z5$19DankQ8b1$q^__#n-6-M_^o>G10X<6q4jTd+PF}78k3w`2j$m^rv5Tc#0jxiJ@ zi;DN7OXasu5*FnnPeVJ1zCP1Z`gBd1RVpOc347$3Dbp{dr6b2|C}Fu1j=>WNDn6EO zen|cP4u?eE?r_n>mO5(=cI?=3x;juH%=kV!I@+{Y)>+_?RWfT&Qggy;_-%L<8KwUn zbpcY&JG=W^VR51?ffP0)%veQ!aNv@DwwX&!gxbi3S4(oBeN7iny?t;@x( z7@})gN@(nC8~y>RnKy-sA)LL45)%<|02U_ebud9O=$YXpXljyUudtOg7`5tZ{8P~^up}P$xzRWOwFC+-v3>Rb5{=h>|`i*4-{K3cwz=VN1cc@H)?xkB&1yTg$E+iw5NrgYN6b2K+dF`l+D zkEo@MPvqlbl85WUIQNOce{ZmNPRitRxnpg3T58vEOu{+(kMNqd`6e~zK3luTVJ~zz z1Bu`_;)ZcyVQftNF^UJ_yCmdh^n{epIBSv2PZ)C2i3FMcEerY`O5(q@ifu#o-7Gg+UQ&QG$5XkIg zg>mwp8@oN35>eZffmTIEGV8^Ih-L1fxL8`ST@a6B&uX3AuO7DtY}6A8*mZ_}^-`}U zIZ$V;ImbvOs2BptNPT$!J`qGI1QfQRMXM1YW2ve0?ok}pDcdkQbZ&tj5}2p3seMjP zPNqRuj+}VFCu$^jDG&>pyRE@G*w_7WRl`uATjE8|EK2zF>uM-V-Mg!b`cl~g5B*`m zf}tr*+vw3e@$AJND;GyclRO??)&>ph9_{;IzBUeMi3`IP;~qidM!DK|%$B0w?O*u> z3hfll%=vP&q-hk|l)gDK^f~qcb-#bKKZ7rg$TuiZmtIk&F54X=dM;HJJ74U)mnU05 zL+4SPG&a&I&cJ9xdeNxc(BWwV043~%Sr(PGv`FBg z&$nl8slWK@{@##hULJG*dd4J;v#(PSt%$=a->WIFtQ6KTqz7fK^XVJWV^FG5`m2ks zz5Uq~m-@lmg@3ZyZm`4{79lbTdSSrNhXeW3<$o1!tbxOtf5PEY_~yDYxss5TW>^8j z3Nx&*;))`ysNsqluBhRP8m_3}iW>euQA5Nq-3|M!flRD}B>~4geZHyr>imuW0N{E4 AQ2+n{ literal 0 HcmV?d00001 diff --git a/test/screenshotter/images/MathAtom-firefox.png b/test/screenshotter/images/MathAtom-firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..d451d16cc8a5c66efd4b2b9c00ca4163b5f24582 GIT binary patch literal 7720 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 Ai~s-t literal 0 HcmV?d00001 diff --git a/test/screenshotter/images/MathAtom2-firefox.png b/test/screenshotter/images/MathAtom2-firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..cc0b69629c87e3e9e81aa72ffb58aff39d544d3b GIT binary patch literal 7846 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 literal 0 HcmV?d00001 diff --git a/test/screenshotter/ss_data.yaml b/test/screenshotter/ss_data.yaml index 6c5cd88..6c596c9 100644 --- a/test/screenshotter/ss_data.yaml +++ b/test/screenshotter/ss_data.yaml @@ -79,6 +79,8 @@ LeftRightStyleSizing: | LimitControls: | \displaystyle\int\limits_2^3 3x^2\,dx + \sum\nolimits^n_{i=1}i + \textstyle\int\limits_x^y z +MathAtom: a\mathrel{\mathop{=}\limits^{\blue ?}}b +MathAtom2: \mathop{\overline\mathrm{lim}}\limits_{x\to\infty}f(x) MathDefaultFonts: Ax2k\breve{a}\omega\Omega\imath+\KaTeX MathBb: \mathbb{Ax2k\breve{a}\omega\Omega\imath+\KaTeX} MathBf: \mathbf{Ax2k\breve{a}\omega\Omega\imath+\KaTeX}