Skip to content

Commit 5791c37

Browse files
committed
Add overset and underset, symbol group
1 parent 3798e5f commit 5791c37

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

lib/matplotlib/_mathtext.py

+76
Original file line numberDiff line numberDiff line change
@@ -2035,6 +2035,7 @@ def __init__(self):
20352035
p.non_math = Forward()
20362036
p.operatorname = Forward()
20372037
p.overline = Forward()
2038+
p.overset = Forward()
20382039
p.placeable = Forward()
20392040
p.rbrace = Forward()
20402041
p.rbracket = Forward()
@@ -2051,8 +2052,10 @@ def __init__(self):
20512052
p.subsuper = Forward()
20522053
p.subsuperop = Forward()
20532054
p.symbol = Forward()
2055+
p.symbol_group = Forward()
20542056
p.symbol_name = Forward()
20552057
p.token = Forward()
2058+
p.underset = Forward()
20562059
p.unknown_symbol = Forward()
20572060

20582061
# Set names on everything -- very useful for debugging
@@ -2109,6 +2112,7 @@ def __init__(self):
21092112
p.end_group <<= p.rbrace.copy()
21102113
p.simple_group <<= Group(p.lbrace + ZeroOrMore(p.token) + p.rbrace)
21112114
p.required_group <<= Group(p.lbrace + OneOrMore(p.token) + p.rbrace)
2115+
p.symbol_group <<= Group(p.lbrace + p.symbol + p.rbrace)
21122116
p.group <<= Group(
21132117
p.start_group + ZeroOrMore(p.token) + p.end_group
21142118
)
@@ -2168,6 +2172,18 @@ def __init__(self):
21682172
- (p.required_group | Error("Expected \\overline{value}"))
21692173
)
21702174

2175+
p.overset <<= Group(
2176+
Suppress(Literal(r"\overset"))
2177+
- ((p.required_group + p.symbol_group)
2178+
| Error("Expected \\overset{value}{symbol}"))
2179+
)
2180+
2181+
p.underset <<= Group(
2182+
Suppress(Literal(r"\underset"))
2183+
- ((p.required_group + p.symbol_group)
2184+
| Error("Expected \\underset{value}{symbol}"))
2185+
)
2186+
21712187
p.unknown_symbol <<= Combine(p.bslash + Regex("[A-Za-z]*"))
21722188

21732189
p.operatorname <<= Group(
@@ -2189,6 +2205,8 @@ def __init__(self):
21892205
| p.dfrac
21902206
| p.binom
21912207
| p.genfrac
2208+
| p.overset
2209+
| p.underset
21922210
| p.sqrt
21932211
| p.overline
21942212
| p.operatorname
@@ -2841,6 +2859,40 @@ def binom(self, s, loc, toks):
28412859
return self._genfrac('(', ')', 0.0, self._MathStyle.TEXTSTYLE,
28422860
num, den)
28432861

2862+
def _genset(self, state, value, symbol, shift):
2863+
thickness = state.font_output.get_underline_thickness(
2864+
state.font, state.fontsize, state.dpi)
2865+
2866+
value.shrink()
2867+
2868+
cvalue = HCentered([value])
2869+
csymbol = HCentered([symbol])
2870+
width = max(cvalue.width, csymbol.width)
2871+
cvalue.hpack(width, 'exactly')
2872+
csymbol.hpack(width, 'exactly')
2873+
2874+
metrics = state.font_output.get_metrics(
2875+
state.font, mpl.rcParams['mathtext.default'],
2876+
r'\leftrightarrow', state.fontsize, state.dpi)
2877+
2878+
# Shift so the symbol sits in the same vertical position
2879+
shift_amount = csymbol.height/2 - (metrics.ymax + metrics.ymin)/2
2880+
if shift:
2881+
vlist = Vlist([csymbol, # value
2882+
cvalue # symbol
2883+
])
2884+
vlist.shift_amount = shift_amount + cvalue.height
2885+
else:
2886+
vlist = Vlist([cvalue, # value
2887+
Vbox(0, thickness * 1.5), # space
2888+
csymbol # symbol
2889+
])
2890+
vlist.shift_amount = shift_amount
2891+
2892+
hlist = [Hlist([vlist, Hbox(thickness * 2.)])]
2893+
2894+
return hlist
2895+
28442896
def sqrt(self, s, loc, toks):
28452897
(root, body), = toks
28462898
state = self.get_state()
@@ -2901,6 +2953,30 @@ def overline(self, s, loc, toks):
29012953
hlist = Hlist([rightside])
29022954
return [hlist]
29032955

2956+
def overset(self, s, loc, toks):
2957+
assert len(toks) == 1
2958+
assert len(toks[0]) == 2
2959+
# Only one symbol
2960+
assert len(toks[0][1]) == 1
2961+
state = self.get_state()
2962+
2963+
value, symbol = toks[0]
2964+
symbol = symbol[0]
2965+
2966+
return self._genset(state, value, symbol, shift=False)
2967+
2968+
def underset(self, s, loc, toks):
2969+
assert len(toks) == 1
2970+
assert len(toks[0]) == 2
2971+
# Only one symbol
2972+
assert len(toks[0][1]) == 1
2973+
state = self.get_state()
2974+
2975+
value, symbol = toks[0]
2976+
symbol = symbol[0]
2977+
2978+
return self._genset(state, value, symbol, shift=True)
2979+
29042980
def _auto_sized_delimiter(self, front, middle, back):
29052981
state = self.get_state()
29062982
if len(middle):

0 commit comments

Comments
 (0)