6

Is it possible to amend to a macro without storing the original one in a tmp variable?

Approach is similar to this one here: Redefine macro in terms of old one. But without the OldMacro

I came up with something using groups, but doesn't work.

\def\abc{abc} 
\begingroup\let\orgabc\abc\def\abc{\orgabc\endgroup def}


EDIT: It's indeed partially working. But not to my expectations.
\documentclass{article}

\def\abc{abc}
\begingroup\let\orgabc\abc\def\abc{\orgabc\endgroup def}

\begin{document}
  \abc
\end{document}

Output: abcdef (Works, as expected)

\documentclass{article}

\def\abc{abc}
\begingroup\let\orgabc\abc\def\abc{\orgabc\endgroup def}

\begin{document}
  \abc
  \abcorg
\end{document}

Output: Error: undefined control sequence (Works as desired, because \abcorg is not defined)

\documentclass{article}

\def\abc{abc}
\begingroup\let\orgabc\abc\def\abc{\orgabc\endgroup def}

\begin{document}
  \orgabc
\end{document}

Output: abc (Why is \orgabc defined here?)


EDIT: The redefinition somehow clashes with the titlesec package. I opened a new question here
Simon
  • 93
  • Welcome to TeX.SX! You can have a look at our starter guide to familiarize yourself further with our format. – TeXnician Feb 28 '17 at 07:24
  • What is your goal? For me it prints abcdef. – TeXnician Feb 28 '17 at 07:27
  • 1
    In LaTeX there is \g@addto@macro, so \g@addto@\abc{foo}\abc expands to abcfoo then –  Feb 28 '17 at 07:29
  • Thank you for your answers! I now understand the power of the MWE. It does indeed work in a MWE, but doesn't in my main document. I will edit my question. – Simon Feb 28 '17 at 07:34
  • 1
    Ooops, I meant \g@addto@macro\abc{foo} above... –  Feb 28 '17 at 07:36
  • Well, effectively you use a temp 'variable' anyway –  Feb 28 '17 at 08:11
  • Yes, but I don't want the tmp token to be defined outside the redefinition. How is this handled by \g@addto@macro\abc{foo}? – Simon Feb 28 '17 at 08:14
  • @Simon: both the original macro as well as the addto - content are stored in a temp token register and the original macro is redefined with \xdef ... all a in group, so the temp token is volatile actually, but the crucial point is the expansion such that the temp token 'releases' its value –  Feb 28 '17 at 08:18
  • This answer shows how \g@addto@macro is implemented. – TonioElGringo Feb 28 '17 at 08:18
  • With this approach the changes to \abc are only valid for its first use; thereafter it reverts to its previous definition. Is that the desired behavior? – Guho Feb 28 '17 at 08:46

2 Answers2

6

This of course cannot work, because it will leave the effect of \begingroup hanging until you call \abc, which will probably happen in undesirable places (see your other question).

To me it seems you want to do

\def\abc{abc}
\expandafter\def\expandafter\abc\expandafter{\abc def}

but this is clumsy and limited to only allow appending.

Without reinventing the wheel, you can use etoolbox:

\documentclass{article}
\usepackage{etoolbox}

\newcommand{\abc}{abc}

\begin{document}

The macro \verb|\abc| expands to ``\abc''.

\appto\abc{def}

The macro \verb|\abc| expands to ``\abc''.

\preto\abc{X}\appto\abc{X}

The macro \verb|\abc| expands to ``\abc''.

\end{document}

This will print

The macro \abc expands to “abc”.
The macro \abc expands to “abcdef”.
The macro \abc expands to “XabcdefX”.

egreg
  • 1,121,712
5

Reorganized and corrected my answer

The cause why \orgabc is still available is that the group is actually never closed, it causes warnings about semi groups.

Now, egreg has used \expandafter\def\.... already.

It is possible to use \xdef\foo{\foo other stuff} to use a shorter version.

As a third variant, apply \g@addto@macro from the LaTeX kernel, which stores everything expanded in a token first and redefines the macro with \xdef, in order to expand the token.

\documentclass{article}



\def\abc{abc}
\def\abcother{abc}
\def\abcyetanother{abc}
\expandafter\def\expandafter\abc\expandafter{\abc\ defappended which works}

\xdef\abcother{\abcother\ defappended works as well}

\makeatletter
\g@addto@macro\abcyetanother{\ and here again}

\makeatother


\begin{document}
First version: \abc

Second version:  \abcother

Third version: \abcyetanother
\end{document}

enter image description here