|
18 | 18 | Empty, Forward, Literal, NotAny, oneOf, OneOrMore, Optional,
|
19 | 19 | ParseBaseException, ParseException, ParseExpression, ParseFatalException,
|
20 | 20 | ParserElement, ParseResults, QuotedString, Regex, StringEnd, ZeroOrMore,
|
21 |
| - pyparsing_common) |
| 21 | + pyparsing_common, Group) |
22 | 22 |
|
23 | 23 | import matplotlib as mpl
|
24 | 24 | from . import cbook
|
|
27 | 27 | from .font_manager import FontProperties, findfont, get_font
|
28 | 28 | from .ft2font import FT2Image, KERNING_DEFAULT
|
29 | 29 |
|
| 30 | +from pyparsing import __version_info__ as pyparsing_version |
| 31 | +if pyparsing_version < (3, 0): |
| 32 | + from pyparsing import nestedExpr as nested_expr |
| 33 | +else: |
| 34 | + from pyparsing import nested_expr |
30 | 35 |
|
31 | 36 | ParserElement.enablePackrat()
|
32 | 37 | _log = logging.getLogger("matplotlib.mathtext")
|
@@ -1865,7 +1870,7 @@ def csnames(group, names):
|
1865 | 1870 | + r"|\\(?:{})(?![A-Za-z])".format(
|
1866 | 1871 | "|".join(map(re.escape, tex2uni)))
|
1867 | 1872 | )("sym").leaveWhitespace()
|
1868 |
| - p.unknown_symbol = Regex(r"\\[A-Za-z]*")("name") |
| 1873 | + p.unknown_symbol = Regex(r"\\[A-Za-z]+")("name") |
1869 | 1874 |
|
1870 | 1875 | p.font = csnames("font", self._fontnames)
|
1871 | 1876 | p.start_group = Optional(r"\math" + oneOf(self._fontnames)("font")) + "{"
|
@@ -1925,6 +1930,11 @@ def csnames(group, names):
|
1925 | 1930 |
|
1926 | 1931 | p.text = cmd(r"\text", QuotedString('{', '\\', endQuoteChar="}"))
|
1927 | 1932 |
|
| 1933 | + p.substack = cmd(r"\substack", |
| 1934 | + nested_expr(opener="{", closer="}", |
| 1935 | + content=Group(OneOrMore(p.token)) + |
| 1936 | + ZeroOrMore(Literal("\\\\").suppress()))("parts")) |
| 1937 | + |
1928 | 1938 | p.subsuper = (
|
1929 | 1939 | (Optional(p.placeable)("nucleus")
|
1930 | 1940 | + OneOrMore(oneOf(["_", "^"]) - p.placeable)("subsuper")
|
@@ -1963,6 +1973,7 @@ def csnames(group, names):
|
1963 | 1973 | | p.overline
|
1964 | 1974 | | p.text
|
1965 | 1975 | | p.boldsymbol
|
| 1976 | + | p.substack |
1966 | 1977 | )
|
1967 | 1978 |
|
1968 | 1979 | mdelim = r"\middle" - (p.delim("mdelim") | Error("Expected a delimiter"))
|
@@ -2648,3 +2659,25 @@ def boldsymbol(self, s, loc, toks):
|
2648 | 2659 | self.pop_state()
|
2649 | 2660 |
|
2650 | 2661 | return Hlist(hlist)
|
| 2662 | + |
| 2663 | + def substack(self, s, loc, toks): |
| 2664 | + parts = toks["parts"] |
| 2665 | + state = self.get_state() |
| 2666 | + thickness = state.get_current_underline_thickness() |
| 2667 | + vlist = [] |
| 2668 | + |
| 2669 | + hlist = [Hlist(k) for k in parts[0]] |
| 2670 | + max_width = max(map(lambda c: c.width, hlist)) |
| 2671 | + |
| 2672 | + for sub in hlist: |
| 2673 | + cp = HCentered([sub]) |
| 2674 | + cp.hpack(max_width, 'exactly') |
| 2675 | + vlist.append(cp) |
| 2676 | + |
| 2677 | + vlist = [val for pair in zip(vlist, |
| 2678 | + [Vbox(0, thickness * 2)] * |
| 2679 | + len(vlist)) for val in pair] |
| 2680 | + del vlist[-1] |
| 2681 | + vlt = Vlist(vlist) |
| 2682 | + result = [Hlist([vlt])] |
| 2683 | + return result |
0 commit comments