12

Did something change related to \ne recenetly?

The MWE below in TeXLive 2018 yields the expected output

enter image description here

but with TeXLive 2019 (with all packages up to date as of today) I get

Argument of \ne  has an extra }.

Code

\documentclass{article}
\usepackage{mathtools}
\usepackage{xparse}

\let\OldNe\ne

\RenewDocumentCommand{\ne}{o}{%
    \mathrel{\OldNe}
}

\begin{document}
$a \ne b$
\end{document}
  • 3
    \ne is now \protect\ne<space>, so you need to use the letltxmacro package and \LetLtxMacro\OldNe\ne – Phelype Oleinik Nov 12 '19 at 1:45
  • @PhelypeOleinik: Thanks. Works great. Please post a answer. – Peter Grill Nov 12 '19 at 1:50
15

With the last LaTeX release (October 2019) a lot of commands which are not usually supposed to expand were made robust, so \ne, which usually was \not=, now expands to \protect\ne␣ (\ne␣ is \csname ne \endcsname).

With \let\OldNe\ne, when your command does \mathrel{\OldNe}, \OldNe expands to \protect\ne␣, and now \ne␣ is a macro delimited by a ], but a } is found before that, so TeX raises the Argument of \ne has an extra } (note the extra space in the error message).


Usually, this would have worked, because \ne␣ would expand to \not=. However, xparse uses the command \ne␣ as a temporary macro to grab the arguments of \ne so that in case you forget a } somewhere, the error message will show you something meaningful:

Runaway argument?
[oops 
! Paragraph ended before \ne  was complete.
<to be read again> 
                   \par

(see that the error occurred while grabbing the argument of \ne␣) rather than expose some xparse internal that doesn't give a clue about the source of the error:

Runaway argument?
[oops 
! Paragraph ended before \__xparse_grab_delimited_argument_of_some_macro:w was complete.
<to be read again> 
                   \par

To work around the issue, for the time being, load the letltxmacro and use \LetLtxMacro\OldNe\ne instead of \let\OldNe\ne. \LetLtxMacro takes care of the fact that \ne is now protected. The 2020-10-01 release, the LaTeX kernel will feature a brand new \NewCommandCopy, which can be used the same way as \LetLtxMacro to copy commands without worrying about their definition.

| improve this answer | |
  • 3
    Is there a document which list the commands that were changed? – Peter Grill Nov 12 '19 at 3:00
  • 3
    @PeterGrill Not officially, as far as I know. We have the history of commits in the LaTeX2e repo (github.com/latex3/latex2e), but not officially compiled into a list. That's a good idea, though, we should probably have one. I'll let you know if one comes to exist. – Phelype Oleinik Nov 12 '19 at 3:22
  • 1
    Why is the protected version delimited by a ]? – siracusa Nov 12 '19 at 5:48
  • @siracusa I think that is a response to what ever it is the OP is doing, Peter is making a macro that takes an optional arg. – daleif Nov 12 '19 at 8:35
  • @siracusa to be honest I don't know yet. I'm traveling until tomorrow, so my debugging powers are limited. I thought it weird too, since (from the very little I know of xparse's internals) there should not be a \ne<space> nor a ]-delimited macro. I'll investigate when I can. – Phelype Oleinik Nov 12 '19 at 8:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.