Is it possible to create a command which takes the name of a command c as an argument and redefines c (e.g. via renewcommand) in terms of itself but adds some new functionality?
In short, can we define a command x(c) whose effect is c := f (c) for some modification f such as \textcolor{blue}{...}.
Example use cases:
- Add colors to existing symbols throughout the whole document, potentially with varying color themes:
where\setColor{neg}{blue}\setColoris the commandxI ask for withf = \textcolor{blue}{...}: Whenever\negis used afterwards, it will be blue. Similarly, one could make symbols bold or italic. - Add a suffix or prefix:
where\newcommand{\hello}{hello} \addSuffix{hello}{ world}\addSuffixis the searched commandxand using\hellowould writehello world.
The clean way to do this would probably be by just introducing custom commands to wrap each command of interest but that requires to adapt my whole (potentially) large document to replace all usages of the previous command with a new one (e.g., \neg -> \coloredneg).
This answer proposes a solution based on \NewCommandCopy, which works well when we have to do this a single time but becomes cumbersome when we want to redefine multiple commands:
\NewCommandCopy{\oldhello}{\hello}
\renewcommand{\hello}{\hello{} world}
I was not able to wrap this pattern inside a command that is parameterized in the name of the command to redefine (\hello here). All I got working was:
\newcommand{\setColor}[2]{%
%%% Problem: Full inlining via \edef changes behavior. For example, it breaks ensuremath in #1.
\expandafter\edef\csname old#1\endcsname{\csname #1 \endcsname}
\expandafter\renewcommand\csname #1\endcsname{\textcolor{#2}{\csname old#1 \endcsname}}%
}
But this breaks for some commands (see comment).
Ideally, the command x in question would also be generic in the kind of modification f applied. Then x(f, c) would apply a given command f, which takes a single argument, to another command c to perform c := f(c). (Maybe we could even allow c to have parameters and do c(a, b, c, ...) := f(c(a, b, c, ...))?)
In a programming language sense, what I am looking for here might be some lightweight kind of aspects from aspect-oriented programming or features from feature-oriented programming, where some syntactical modification is applied to an existing implementation.


where\rbracc` is the colored version. This way you can also mix and match. – yannisl Mar 21 '24 at 09:13