The Problem
There are several packages I would like to write which require me to redefine the \newcommand
(\renewcommand
, etc.) command so I can track or change the commands that authors subsequently define. But I have no idea how to go about it. My naive attempts so far have failed. Probably because I am still very weak at the TeX level.
I'm surprised that I couldn't find more than vague hints towards this concept. It feels like such an obvious thing to do.
Motivation
A simple usecase, and the first package I plan write, is to ensure the following: that using \newcommand
to define a command - say: \cmd
- that has already been defined does not immediately generate an error. \cmd
would simply be in a state of conflict. Subsequently trying to expand \cmd
would then generate an error (since it's ambiguous which of the two definitions you want).
The conflict could be resolved by subsequently redefining \cmd
using \renewcommand
, after which \cmd
can once again safely be expanded. Example:
\newcommand{\cmd}{FIRST} %
\cmd % outputs FIRST
\newcommand{\cmd}{SECOND} % no problem yet
\cmd % error: expanding ambiguous command
\renewcommand{\cmd}{THIRD} %
\cmd % outputs THIRD
This could, for example, be used to mediate conflicts between packages (that use \newcommand
). Of course, this concept is still quite weak (for example, what to do if two packages independently use \renewcommand
on the same command?). But it is enough to serve as a usecase for my question.
After I learn more about this, I plan to exercise more fine-grained control.
Pseudo Code Solution
It feels like I have to do something like this (ignoring the optional argument for now):
\let\old@newcommand\newcommand
\MetaRenewCommand{\newcommand}{
\ifdefined#1
\old@newcommand{#1}{
\PackageError{lazyfail}{Expanding ambiguous command \protect #1}
}
\else
\old@newcommand{#1}{#3}
\fi
}
Of course, there are many things wrong with this code. There is no \MetaRenewCommand
and I still have to handle the optional argument of \newcommand
.
So, how do I start? It feels like it must be possible, as \newcommand
and friends are not primitives of LaTeX, but defined in terms of lower level commands.
Further Motivation
Here's another use-case I have in mind for this. When including a package, I would like to ignore all commands it provides except for a small list which I specify:
\usepackagefor[\Lightning]{marvosym}
Here I am loading the marvosym
package, but only to use \Ligntning
. I choose this example because the marvosym
\CheckedBox
command conflicts with the one in the llncs
class.
I already routinely specify the commands I plan to use a package for with a comment, but it would be nice to actually enforce that.
\providecommand
provides your "no problem yet" requirement... but not generating an error upon subsequent usage.\newcommand
(if you just want to force the issue, you use\def
in a package). I'm not sure I see what you are really up to: if two packages define\foo
, then trouble will ensue, hence the existence of\newcommand
to warn about this and allow some action to be taken. (That said, at a technical level this is doable, certainly as an exercise.)