From 6bd127aa996b6bec72ab4c3191103bea59a45602 Mon Sep 17 00:00:00 2001 From: Aitik Gupta Date: Mon, 28 Dec 2020 23:23:52 +0530 Subject: [PATCH 1/3] Added support for overset/underset --- lib/matplotlib/_mathtext.py | 66 +++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/lib/matplotlib/_mathtext.py b/lib/matplotlib/_mathtext.py index 45e51f53984d..3a8c13b1403d 100644 --- a/lib/matplotlib/_mathtext.py +++ b/lib/matplotlib/_mathtext.py @@ -2035,6 +2035,7 @@ def __init__(self): p.non_math = Forward() p.operatorname = Forward() p.overline = Forward() + p.overset = Forward() p.placeable = Forward() p.rbrace = Forward() p.rbracket = Forward() @@ -2053,6 +2054,7 @@ def __init__(self): p.symbol = Forward() p.symbol_name = Forward() p.token = Forward() + p.underset = Forward() p.unknown_symbol = Forward() # Set names on everything -- very useful for debugging @@ -2169,6 +2171,18 @@ def __init__(self): - (p.required_group | Error("Expected \\overline{value}")) ) + p.overset <<= Group( + Suppress(Literal(r"\overset")) + - ((p.simple_group + p.simple_group) + | Error("Expected \\overset{body}{annotation}")) + ) + + p.underset <<= Group( + Suppress(Literal(r"\underset")) + - ((p.simple_group + p.simple_group) + | Error("Expected \\underset{body}{annotation}")) + ) + p.unknown_symbol <<= Combine(p.bslash + Regex("[A-Za-z]*")) p.operatorname <<= Group( @@ -2190,6 +2204,8 @@ def __init__(self): | p.dfrac | p.binom | p.genfrac + | p.overset + | p.underset | p.sqrt | p.overline | p.operatorname @@ -2842,6 +2858,38 @@ def binom(self, s, loc, toks): return self._genfrac('(', ')', 0.0, self._MathStyle.TEXTSTYLE, num, den) + def _genset(self, state, body, annotation, overunder): + thickness = state.font_output.get_underline_thickness( + state.font, state.fontsize, state.dpi) + + body.shrink() + + cbody = HCentered([body]) + cannotation = HCentered([annotation]) + width = max(cbody.width, cannotation.width) + cbody.hpack(width, 'exactly') + cannotation.hpack(width, 'exactly') + + vgap = thickness * 3 + if overunder == "under": + vlist = Vlist([cannotation, # annotation + Vbox(0, vgap), # space + cbody # body + ]) + # Shift so the annotation sits in the same vertical position + shift_amount = cannotation.depth + cbody.height + vgap + + vlist.shift_amount = shift_amount + else: + vlist = Vlist([cbody, # body + Vbox(0, vgap), # space + cannotation # annotation + ]) + + # To add horizontal gap between symbols: wrap the Vlist into + # an Hlist and extend it with an Hbox(0, horizontal_gap) + return vlist + def sqrt(self, s, loc, toks): (root, body), = toks state = self.get_state() @@ -2902,6 +2950,24 @@ def overline(self, s, loc, toks): hlist = Hlist([rightside]) return [hlist] + def overset(self, s, loc, toks): + assert len(toks) == 1 + assert len(toks[0]) == 2 + + state = self.get_state() + body, annotation = toks[0] + + return self._genset(state, body, annotation, overunder="over") + + def underset(self, s, loc, toks): + assert len(toks) == 1 + assert len(toks[0]) == 2 + + state = self.get_state() + body, annotation = toks[0] + + return self._genset(state, body, annotation, overunder="under") + def _auto_sized_delimiter(self, front, middle, back): state = self.get_state() if len(middle): From 4ce7efcf5cb0c9812535718bb569259ad43098bf Mon Sep 17 00:00:00 2001 From: Aitik Gupta Date: Mon, 18 Jan 2021 08:37:20 +0530 Subject: [PATCH 2/3] Added test for overset/underset --- lib/matplotlib/tests/test_mathtext.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/matplotlib/tests/test_mathtext.py b/lib/matplotlib/tests/test_mathtext.py index 9bd6ca7366dc..16ac7c7bacbd 100644 --- a/lib/matplotlib/tests/test_mathtext.py +++ b/lib/matplotlib/tests/test_mathtext.py @@ -115,6 +115,7 @@ # images. lightweight_math_tests = [ r'$\sqrt[ab]{123}$', # github issue #8665 + r'$x \overset{f}{\rightarrow} \overset{f}{x} \underset{xx}{ff} \overset{xx}{ff} \underset{f}{x} \underset{f}{\leftarrow} x$', # github issue #18241 ] digits = "0123456789" @@ -246,6 +247,8 @@ def test_fontinfo(): (r'$\left($', r'Expected "\right"'), (r'$\dfrac$', r'Expected \dfrac{num}{den}'), (r'$\dfrac{}{}$', r'Expected \dfrac{num}{den}'), + (r'$\overset$', r'Expected \overset{body}{annotation}'), + (r'$\underset$', r'Expected \underset{body}{annotation}'), ], ids=[ 'hspace without value', @@ -266,6 +269,8 @@ def test_fontinfo(): 'unclosed parentheses without sizing', 'dfrac without parameters', 'dfrac with empty parameters', + 'overset without parameters', + 'underset without parameters', ] ) def test_mathtext_exceptions(math, msg): From 542ba9b242537e456c310557cab4e498b7ceaa46 Mon Sep 17 00:00:00 2001 From: Aitik Gupta Date: Mon, 18 Jan 2021 08:38:02 +0530 Subject: [PATCH 3/3] Added test baseline image --- .../test_mathtext/mathtext1_dejavusans_01.png | Bin 0 -> 2147 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 lib/matplotlib/tests/baseline_images/test_mathtext/mathtext1_dejavusans_01.png diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext1_dejavusans_01.png b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext1_dejavusans_01.png new file mode 100644 index 0000000000000000000000000000000000000000..f303fe49e2818959fbf35fe3e30e14a4ba26aaca GIT binary patch literal 2147 zcmb_ddpy&7AO8(ysir!WI<7^Bl)26hHRLE;D`H5B5oUC8+2%AE(*3yQk|iW@Fmi9^ z605Z2Hn%ayLJ7-dNsdjWJYTQ#yq^D_znU8-ili<$s@21sz2z+R8&vg)JG_Zg4P; zXG*y+2y)+L27c_j2AcN1-VMyhn|=mS+x`dVSK|v`w!#&nnz)x`WtNtfzs$D^`!;dP#Ul3DbR zNLN?a);XDOY50Cs^YbU1oRSghmOACa5KOpGuUlcjm=37Cm+u3WqmEhNHEhCpIG_0c@UzUBG8so*`SPA)D zF0r(<)Po&#HzFe9@i!>HEZ&+S4@G4i4yilS#^<|TxKKLTnaNBWn%{sxw7s7%YHal6 z@pv9J=QHl#zn_+wsamOQ6XaV6yC;|BP*_z}H6GsJ>g1H$+uNHjNZhkyLvdBrXK@~a z+5V?Q#F-JW2%A9_D?WhwvM0|TMVUO7eUNU#Vng0>pv^x%NF@C!d+;e<>!F&}(e((0 z=qbY}k%w>mkVrHU-hc`oIaoLR@s^}=0ERVCyQWYO!wDYM->SrV_)sgCtzzgUsPt{2 zE-!@|oT)uQ5%UuUHO{HW2wr5YeXHs0;ZeM1{q_%1iOB7r1hZz)N(>14FwxG8kj`eb zwY5>_Mlk*)lD@8PK!=nzGr)6E)IwGEK`+T zk2hr+5)(yF#a%gQ#Lec&<)xltMinj9GYJ6Qi7Q~UX>Yg|DRz+vDC#g78hhJzci)ke zI*K^a_|-kr0RE1f%|2yBuGQpHSB|xPB;)JftpcGi^T`u4ie!jg+tF}Nh^+R0E;l1} zpMK<-gl8f_(z-hO3-(TRb#<9nUbc!26~56%?OL-B!P)ujA8~OBU1C$v%9+{_pN>jx zZS5l|i~BH`;iu6nR+Du6(W4zT7etRmzO1;(Ca=Z_e>H@?%Z%{@^5mLL7=*1{=$-WR zf|?q0S2wqyt_K*)(6MU>wO@@U2X~s1UW*rwU+OF?L#|E|g+jHpw%!gLF(fv9;KivF zmy}coC9#qB7xnb?x&cLLD?b?YMz2!OhVYKim1qf;QL`X-OCuL{D-~eHri&c*)DO!UNJ1Uq7JI<&>{Ww;mA^Im1wm0vF{eaa30_=Yt!d8XiSMfWiXJ=hboyr&*8rq$hpfi#q zAG5O5*JU5W9ZuDCJVqiFu*%EPqugjTjYcC$Xa6Dr0`>~kG&IbKO_8@nPZJUnNc=2| z0ZF9*@CnSGFl|Mu-O($<0R1~V}4FtBbqjhAKoRRV%-$n-W^!jFQ$_`WH#;E|`e40_=-<9Pof z+Uk3y;WYd;^baXFYys&o@d^s{&_R*6@r5+npaeNozE-x?t_0zlGoTnk3wYe~C zD4k9ZB9ps8Tm8esrB@Y|ft~#4cc;(cunC44Cq<^zZLJa-YtPj95_NCqto;6TlDwu z7d(3wBb^(~sQ`If-mlZ*Ey`piY_@BOTdA|7V-k({_{F=5Ge~Atb+zm1(