How can I avoid this regex error when attempting to use texdef?

When I try to use `texdef`, I get the following error, even though `texdef` is just the same as it was when TeX Live 2016 was frozen and, indeed, just the same as it has been for several years, since it is dated 2011-2012. Why am I now getting an error and what can I do about it?

``````texdef --help
Unescaped left brace in regex is illegal here in regex; marked by <-- HERE in m/^\\\@protected\@testopt { <-- HERE ?\\.*? }? *(\\\\.*?) / at /usr/local/texlive/bin/texdef line 391.
``````

I seem to remember it issued a complaint before, but it still worked. However, I'm not certain of this.

• I get `Unescaped left brace in regex is deprecated, passed through in regex; marked by <-- HERE in m/^\\\@protected\@testopt { <-- HERE ?\\.*? }? *(\\\\.*?) / at /usr/local/texlive/2017/bin/x86_64-cygwin/texdef line 391` so presumably you have a newer perl where it is illegal rather than just deprecated. The source of texdef needs to be updated (I'm not sure if that's still Martin maintaining it or if it's maintained directly in texlive now) Jun 28, 2017 at 11:35
• I've been pushing Martin to fix it for some months. Jun 28, 2017 at 11:58
• @DavidCarlisle Ah, yes. That's the complaint I used to get, I think, when it still works. I'm using a distro which tends to get new versions quickly, so I'm sure you are right about `perl`. I have version 5.26.0.
– cfr
Jun 28, 2017 at 12:00
• @egreg Any hope with this? When I update TeX Live, it overwrites my corrections. And I can't be the only one with the problem now. (See Sigur's comment below David's answer.) Is there somewhere I can report this as a bug? Or ...? (I thought I'd already reported it, though, by email.)
– cfr
Aug 20, 2017 at 23:49
• The lastest version of `texdef` fixes this problem now. Apr 9, 2018 at 11:01

the perl code needs to be updated at the points indicated (lines 391 and lines 394 to use `\{` and `\}` not `{` and `}`

``````    elsif (\$macrodef =~ /^\\\@protected\@testopt \{?\\.*? \}? *(\\\\.*?) /) {
unshift @cmds, \$1;
}
elsif (\$macrodef =~ /^\\\@testopt \{?(\\.*?) \}?/) {
``````

This should be reported as a bug in texdef

• Thanks! I've emailed MS, but I'm now using `texdef-cfr`, which works fine. (I figure from egreg's comment, a fix might be a while coming.)
– cfr
Jun 28, 2017 at 12:11
• Which version of Perl do you have, just out of curiosity?
– cfr
Jun 28, 2017 at 12:12
• @cfr `This is perl 5, version 22, subversion 3 (v5.22.3) built for cygwin-thread-multi` Jun 28, 2017 at 13:36
• @cfr It's GPL'ed code so I just fixed my copy in place while testing the above. Jun 28, 2017 at 13:37
• Good idea. Thanks. I was thinking it would get overwritten, but that doesn't really matter in this case.
– cfr
Jun 28, 2017 at 22:12

Do not use this solution if you install TeX Live using packages distributed by a Linux distro, you are a Windows user or doing so requires root privileges and you are not sure what you're doing.

This is merely David's answer in the form of a patch for easy application, since it seems that this is not likely to get updated any time soon and updating TeX Live overwrites corrections to the original file.

``````--- 2017/texmf-dist/scripts/texdef/texdef.pl.orig       2016-11-25 18:32:54.000000000 +0000
+++ 2017/texmf-dist/scripts/texdef/texdef.pl    2017-08-27 22:49:49.052819126 +0100
@@ -388,10 +388,10 @@
my \$protectedmacro = \$2;
unshift @cmds, \$protectedmacro;
}
-        elsif (\$macrodef =~ /^\\\@protected\@testopt {?\\.*? }? *(\\\\.*?) /) {
+        elsif (\$macrodef =~ /^\\\@protected\@testopt \{?\\.*? \}? *(\\\\.*?) /) {
unshift @cmds, \$1;
}
-        elsif (\$macrodef =~ /^\\\@testopt {?(\\.*?) }?/) {
+        elsif (\$macrodef =~ /^\\\@testopt \{?(\\.*?) \}?/) {
unshift @cmds, \$1;
}
}
@@ -679,7 +679,7 @@
| (?:new|renew|provide)robustcmd\s* \*? \s* {? \s* \\  # etoolbox definitions
| (?:new(?:box|count|dimen|if|insert|read|skip|muskip|toks|write)) \s* \\ # TeX registers etc.
| (?:char|count|dimen|mathchar|skip|toks)def \s* \\  # TeX chardefs etc.
-            | \@namedef{?                                        # Definition by name only
+            | \@namedef\{?                                        # Definition by name only
| Declare[a-zA-z]+ \s* \*? \s* {? \s* \\             # Declare... definitions
| declare[a-zA-z]+ \s* \*? \s* {? \s* \\             # declare... definitions
)
``````

Save the file as, say, `texdef.patch`.

Assuming that you installed TeX Live from upstream on a Unix-ish system in the default location, so that `texdef.pl` is located at `/usr/local/texlive/2017/texmf-dist/scripts/texdef/texdef.pl`, put the patch file in `/usr/local/texlive` by navigating to the directory where you saved the file.

``````mv texdef.patch /usr/local/texlive
``````

Then apply the patch using

``````cd /usr/local/texlive
patch -b -p0 <texdef.patch
``````

If you installed TeX Live with root privileges, you'll need to `su` or use `sudo`. If you installed as yourself, you won't need anything. If you installed as, say, the `texlive` user (as explained in my instructions for installing as an unprivileged user with no access to your own home), you'll need to `su texlive`.

The `-b` flag tells `patch` to backup the file before patching and `patch` will not touch a file unless it can find a good match for the search text. So this should be relatively safe. At worst, it should simply fail to do anything. However, anything you do as root is only as safe as you make it, so I wouldn't do this as root unless you are confident you won't do anything too catastrophic.

• Great. One suggestion: Do not use this solution... could be moved to top of your answer. Aug 21, 2017 at 11:33
• @Sigur New version above catches another one.
– cfr
Aug 28, 2017 at 22:48