Skip to content

Commit c711c45

Browse files
committed
Add overset and underset, symbol group
1 parent 59bfcfa commit c711c45

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
@@ -2858,6 +2876,40 @@ def binom(self, s, loc, toks):
28582876
return self._genfrac('(', ')', 0.0, self._MathStyle.TEXTSTYLE,
28592877
num, den)
28602878

2879+
def _genset(self, state, value, symbol, shift):
2880+
thickness = state.font_output.get_underline_thickness(
2881+
state.font, state.fontsize, state.dpi)
2882+
2883+
value.shrink()
2884+
2885+
cvalue = HCentered([value])
2886+
csymbol = HCentered([symbol])
2887+
width = max(cvalue.width, csymbol.width)
2888+
cvalue.hpack(width, 'exactly')
2889+
csymbol.hpack(width, 'exactly')
2890+
2891+
metrics = state.font_output.get_metrics(
2892+
state.font, mpl.rcParams['mathtext.default'],
2893+
r'\leftrightarrow', state.fontsize, state.dpi)
2894+
2895+
# Shift so the symbol sits in the same vertical position
2896+
shift_amount = csymbol.height/2 - (metrics.ymax + metrics.ymin)/2
2897+
if shift:
2898+
vlist = Vlist([csymbol, # value
2899+
cvalue # symbol
2900+
])
2901+
vlist.shift_amount = shift_amount + cvalue.height
2902+
else:
2903+
vlist = Vlist([cvalue, # value
2904+
Vbox(0, thickness * 1.5), # space
2905+
csymbol # symbol
2906+
])
2907+
vlist.shift_amount = shift_amount
2908+
2909+
hlist = [Hlist([vlist, Hbox(thickness * 2.)])]
2910+
2911+
return hlist
2912+
28612913
def sqrt(self, s, loc, toks):
28622914
root, body = toks[0]
28632915
state = self.get_state()
@@ -2921,6 +2973,30 @@ def overline(self, s, loc, toks):
29212973
hlist = Hlist([rightside])
29222974
return [hlist]
29232975

2976+
def overset(self, s, loc, toks):
2977+
assert len(toks) == 1
2978+
assert len(toks[0]) == 2
2979+
# Only one symbol
2980+
assert len(toks[0][1]) == 1
2981+
state = self.get_state()
2982+
2983+
value, symbol = toks[0]
2984+
symbol = symbol[0]
2985+
2986+
return self._genset(state, value, symbol, shift=False)
2987+
2988+
def underset(self, s, loc, toks):
2989+
assert len(toks) == 1
2990+
assert len(toks[0]) == 2
2991+
# Only one symbol
2992+
assert len(toks[0][1]) == 1
2993+
state = self.get_state()
2994+
2995+
value, symbol = toks[0]
2996+
symbol = symbol[0]
2997+
2998+
return self._genset(state, value, symbol, shift=True)
2999+
29243000
def _auto_sized_delimiter(self, front, middle, back):
29253001
state = self.get_state()
29263002
if len(middle):

0 commit comments

Comments
 (0)