2

MWE:

\documentclass{article}

\begin{document}

\ExplSyntaxOn \cs_set_eq:NN __examzh_symbols_old_frac:nn \frac \RenewDocumentCommand { \frac } { m m } { __examzh_symbols_old_frac:nn {#1}{#2} } \ExplSyntaxOff

$\frac{1}{2}$

\end{document}

I wanted to redefine the \frac for "improvement". But I found that when I wanted to "copy" a \frac by \cs_set_eq:NN, it seemed that \cs_set_eq:NN failed and I didn't know why.

MWE

Then I used \NewCommandCopy and it worked:

\documentclass{article}

\begin{document}

\ExplSyntaxOn % \cs_set_eq:NN __examzh_symbols_old_frac:nn \frac \NewCommandCopy { \oldfrac } { \frac } \RenewDocumentCommand { \frac } { m m } { % __examzh_symbols_old_frac:nn {#1}{#2} \oldfrac {#1}{#2} } \ExplSyntaxOff

$\frac{1}{2}$

\end{document}

Could you tell me what's wrong with the method of \cs_set_eq:NN?

enter image description here

xdyy
  • 591
  • 3
    \frac is a robust command, that means it has an specific internal structure. A simple \let (or \cs_set_eq:NN) can't properly copy this structure. That's why \NewDocumentCopy exists. – Ulrike Fischer Jul 18 '22 at 15:30
  • Or rather, \NewCommandCopy. :-) FWIW, letltxmacro would also work here, AFAIK. – frougon Jul 18 '22 at 15:42
  • Thanks for much! @Ulrike Fischer and frougon – xdyy Jul 18 '22 at 15:59

1 Answers1

3
% ltmath.dtx
\DeclareRobustCommand\frac[2]{{\begingroup#1\endgroup\over#2}}

will define two, not one, new macros: \frac and \frac␣.

\def\frac{\protect\frac␣}
\long\def\frac␣#1#2{{\begingroup #1\endgroup \over #2}}

This way, \frac is automatically protected, hence in LaTeX2e's term, robust. See also What is the difference between Fragile and Robust commands? When and why do we need \protect?.

Thus you need some "deep" copy commands compared to shallow copy ones.

  • deep copy: \NewCommandCopy since LaTeX2e 2020-10-01 or \LetLtxMacro from letltxmacro package.
  • shallow copy: primitive \let or the l3 function \cs_set_eq:NN
    \cs_new_protected:Npn \cs_set_eq:NN #1 { \tex_let:D #1 =~ }
    
muzimuzhi Z
  • 26,474