|
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")
|
@@ -1861,7 +1866,7 @@ def csnames(group, names):
|
1861 | 1866 | + r"|\\(?:{})(?![A-Za-z])".format(
|
1862 | 1867 | "|".join(map(re.escape, tex2uni)))
|
1863 | 1868 | )("sym").leaveWhitespace()
|
1864 |
| - p.unknown_symbol = Regex(r"\\[A-Za-z]*")("name") |
| 1869 | + p.unknown_symbol = Regex(r"\\[A-Za-z]+")("name") |
1865 | 1870 |
|
1866 | 1871 | p.font = csnames("font", self._fontnames)
|
1867 | 1872 | p.start_group = Optional(r"\math" + oneOf(self._fontnames)("font")) + "{"
|
@@ -1921,6 +1926,11 @@ def csnames(group, names):
|
1921 | 1926 |
|
1922 | 1927 | p.text = cmd(r"\text", QuotedString('{', '\\', endQuoteChar="}"))
|
1923 | 1928 |
|
| 1929 | + p.substack = cmd(r"\substack", |
| 1930 | + nested_expr(opener="{", closer="}", |
| 1931 | + content=Group(OneOrMore(p.token)) + |
| 1932 | + ZeroOrMore(Literal("\\\\").suppress()))("parts")) |
| 1933 | + |
1924 | 1934 | p.subsuper = (
|
1925 | 1935 | (Optional(p.placeable)("nucleus")
|
1926 | 1936 | + OneOrMore(oneOf(["_", "^"]) - p.placeable)("subsuper")
|
@@ -1959,6 +1969,7 @@ def csnames(group, names):
|
1959 | 1969 | | p.overline
|
1960 | 1970 | | p.text
|
1961 | 1971 | | p.boldsymbol
|
| 1972 | + | p.substack |
1962 | 1973 | )
|
1963 | 1974 |
|
1964 | 1975 | p.auto_delim <<= (
|
@@ -2633,3 +2644,25 @@ def boldsymbol(self, s, loc, toks):
|
2633 | 2644 | self.pop_state()
|
2634 | 2645 |
|
2635 | 2646 | return Hlist(hlist)
|
| 2647 | + |
| 2648 | + def substack(self, s, loc, toks): |
| 2649 | + parts = toks["parts"] |
| 2650 | + state = self.get_state() |
| 2651 | + thickness = state.get_current_underline_thickness() |
| 2652 | + vlist = [] |
| 2653 | + |
| 2654 | + hlist = [Hlist(k) for k in parts[0]] |
| 2655 | + max_width = max(map(lambda c: c.width, hlist)) |
| 2656 | + |
| 2657 | + for sub in hlist: |
| 2658 | + cp = HCentered([sub]) |
| 2659 | + cp.hpack(max_width, 'exactly') |
| 2660 | + vlist.append(cp) |
| 2661 | + |
| 2662 | + vlist = [val for pair in zip(vlist, |
| 2663 | + [Vbox(0, thickness * 2)] * |
| 2664 | + len(vlist)) for val in pair] |
| 2665 | + del vlist[-1] |
| 2666 | + vlt = Vlist(vlist) |
| 2667 | + result = [Hlist([vlt])] |
| 2668 | + return result |
0 commit comments