Actual outcome
mathtext.Parser.parse raises a ValueError.
Expected outcome
The documentation states the following:
Radicals can be produced with the \sqrt[]{} command ... Any base can (optionally) be provided inside square brackets. Note that the base must be a simple expression, and can not contain layout commands such as fractions or sub/superscripts
In fact, it seems that only a (signed) integer literal is allowed. From mathtext.Parser.__init__:
It would be convenient if other bases were allowed. If that change cannot be made (or in the meantime), I think the documentation should be updated.
Matplotlib version
Operating System: Debian 9.0
Matplotlib Version: 2.0.0
Python Version: 3.5.3
I believe I installed Python from the python3.5 package in the stretch repository and Matplotlib from the python3-matplotlib package in the stretch repository, but I'm not sure.
diff --git i/lib/matplotlib/mathtext.py w/lib/matplotlib/mathtext.py
index ef7b8768f..c49a23ab1 100644
--- i/lib/matplotlib/mathtext.py+++ w/lib/matplotlib/mathtext.py@@ -2495,7 +2495,7 @@ class Parser(object):
p.sqrt <<= Group(
Suppress(Literal(r"\sqrt"))
- - ((Optional(p.lbracket + p.int_literal + p.rbracket, default=None)+ - ((Optional(p.lbracket + p.token + p.rbracket, default=None)
+ p.required_group)
| Error("Expected \\sqrt{value}"))
)
@@ -3231,7 +3231,7 @@ class Parser(object):
if root is None:
root = Box(check.width * 0.5, 0., 0.)
else:
- root = Hlist([Char(x, state) for x in root])+ root = Hlist([root])
root.shrink()
root.shrink()
makes $sqrt[{abc}]{123}$ work, but the extra braces in the brackets are needed. Unfortunately I haven't figured out how to make it work without the extra braces...
OK, so the problem was that square brackets are actually not special most of the time, other than when parsing delimiters around the root base (and that's generically true in TeX as well, e.g. \sqrt[[]{a} just puts [ in the base position). So we need to explicitly exclude them (otherwise the parser just keeps chewing until the end when looking for the end of the base); looks like the following patch works:
diff --git i/lib/matplotlib/_mathtext.py w/lib/matplotlib/_mathtext.py
index dd0305d4b..0e858574c 100644
--- i/lib/matplotlib/_mathtext.py+++ w/lib/matplotlib/_mathtext.py@@ -2158,7 +2158,8 @@ class Parser:
p.sqrt <<= Group(
Suppress(Literal(r"\sqrt"))
- - ((Optional(p.lbracket + p.int_literal + p.rbracket, default=None)+ - ((Group(Optional(+ p.lbracket + OneOrMore(~p.rbracket + p.token) + p.rbracket))
+ p.required_group)
| Error("Expected \\sqrt{value}"))
)
@@ -2864,10 +2865,10 @@ class Parser:
# Add the root and shift it upward so it is above the tick.
# The value of 0.6 is a hard-coded hack ;)
- if root is None:+ if not root:
root = Box(check.width * 0.5, 0., 0.)
else:
- root = Hlist([Char(x, state) for x in root])+ root = Hlist(root)
root.shrink()
root.shrink()
As always, brownie points for whoever turns this into a PR.
Activity
anntzer commented on Mar 25, 2019
So
makes $sqrt[{abc}]{123}$ work, but the extra braces in the brackets are needed. Unfortunately I haven't figured out how to make it work without the extra braces...
anntzer commented on Nov 30, 2020
OK, so the problem was that square brackets are actually not special most of the time, other than when parsing delimiters around the root base (and that's generically true in TeX as well, e.g. \sqrt[[]{a} just puts [ in the base position). So we need to explicitly exclude them (otherwise the parser just keeps chewing until the end when looking for the end of the base); looks like the following patch works:
As always, brownie points for whoever turns this into a PR.
anntzer commented on Jan 16, 2021
Implemented in #19261, so the brownie mostly goes to @timhoffm but I'll keep a bit of it for myself (yum yum).