|
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") |
8000
@@ -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 | p.auto_delim <<= ( |
@@ -2637,3 +2648,25 @@ def boldsymbol(self, s, loc, toks): |
2637 | 2648 | self.pop_state() |
2638 | 2649 |
|
2639 | 2650 | return Hlist(hlist) |
| 2651 | + |
| 2652 | + def substack(self, s, loc, toks): |
| 2653 | + parts = toks["parts"] |
| 2654 | + state = self.get_state() |
| 2655 | + thickness = state.get_current_underline_thickness() |
| 2656 | + vlist = [] |
| 2657 | + |
| 2658 | + hlist = [Hlist(k) for k in parts[0]] |
| 2659 | + max_width = max(map(lambda c: c.width, hlist)) |
| 2660 | + |
| 2661 | + for sub in hlist: |
| 2662 | + cp = HCentered([sub]) |
| 2663 | + cp.hpack(max_width, 'exactly') |
| 2664 | + vlist.append(cp) |
| 2665 | + |
| 2666 | + vlist = [val for pair in zip(vlist, |
| 2667 | + [Vbox(0, thickness * 2)] * |
| 2668 | + len(vlist)) for val in pair] |
| 2669 | + del vlist[-1] |
| 2670 | + vlt = Vlist(vlist) |
| 2671 | + result = [Hlist([vlt])] |
| 2672 | + return result |
0 commit comments