# How do I prevent a command from being invoked by a user while not disabling it?

Let's say I'm working on a LaTeX document collaboratively with someone else. I have defined a bunch of command aliases (such as \true for \top and \false for \bot); their precise purpose doesn't matter for this TeX.SE question, but it's partly to make it easy for us to use "working macros" while fine-tuning things under the hood independently (e.g., there are different ways of representing the two boolean values in math and computer science, and perhaps I want to easily change this stylistic decision later on). Also, I think that some commands shouldn't be used by others (or me), because they might be outdated, dangerous, etc.

What is the most elegant way to prevent a command or a set of commands from being directly invoked by users? I understand that loaded packages might still rely on them, so a starter might be something like

\makeatletter
\let\hardtoinvoke@commandname\commandname
\renewcommand{\commandname}{}
\makeatother


after all packages are loaded (the @ ensures that users cannot easily invoke this macro). What caveats are there? What is the cleanest way of disabling some commands for "direct" use? For the sake of having an example, let's say we want to do this for a 0-argument macro such as \top as well as something with a more complicated argument structure such as \raisebox. Can one easily generalize this to some sort of very general \hidecommand command?

Update 1: Also, without the \let-line, the macro really will not be usable by others (is that right?).

Update 2: The \let-\def difference might actually make what I want impossible, because for \def, things will be looked up at the time of use, not the time of definition. Thus, loading any package that uses \def...\commandname... somewhere inside would have the consequence that I won't be able to disable \commandname without breaking things, is that right? I'm asking because there might be clever @-tricks (perhaps something that invokes an error message only if called outside of an @-environment), but I feel that a proper solution might not be easy.

-
Note that doing \let\new\old \def\old{..} will also affect already loaded macros from packages which use \old, because they will use the current definition of \old not the one which was active when the package macro was defined. –  Martin Scharrer Dec 30 '12 at 11:44
@MartinScharrer I see, so the \let-\def difference applies only to the first level of a macro definition (i.e., it is not recursive)? –  Lover of Structure Dec 30 '12 at 12:16
Have a look at tex.stackexchange.com/questions/258/…. –  Martin Scharrer Jan 5 at 8:07

Short answer: you can not do this.

Longer answer: It is not really possible to detect whether a macro such as \top is used directly in the file or via another macro. (If the syntax was something like \top@ or \top! then there would be possibilities of testing the catcode of the following character.

If a package has already defined say \TopOrBot as

\def\TopOrBot{\top/\bot}


Then whether you redefine \top before or after loading the package, \TopOrBot will use your new definition.

The only thing you can do is redefine not only \top bit also \TopOrBot and any other macro that references \top.

-
1. This formulation "whether a macro [...] is used directly in the file or via another macro" is what I was looking for; thanks! 2. Hmm, is there an (easy or hard) way to find out which other macros use a given macro (say, \top) in their definitions? –  Lover of Structure Dec 30 '12 at 12:28
grep "\\top" find . -name \*.sty :-) –  David Carlisle Dec 30 '12 at 12:33
@LoverofStructure You might want to look at for example what amsmath does with \over to stop people using it directly. As David says, this requires altering anywhere that uses it, which is fine if you have a 'clear' target (set of style files) but much more tricky if the macro is general and widely used. –  Joseph Wright Dec 30 '12 at 12:35

use

\def\setAllMyCommands{%
\def\foo{bar}%
...%
}
\AtBeginDocument{\setAllMyCommands}


Then all changes by an user will be overwritten with your original definitions. You cannot really hide a command for a user. If he searches for a definition he'll find it.

-
I wasn't worried about other users (intentionally or unintentionally) or myself (unintentionally) overwriting my definition of \true. The idea was that I want all my collaborators to only use \true while preventing them from using \top by redefining \top to something that gives me perhaps an explicit error message, while keeping \top accessible to earlier definitions of mine (such as \true itself of course) and also loaded packages. Of course the @-trick I'm proposing can't (without the \let-line) prevent others from using the macro. I just want to prevent accidental usage. –  Lover of Structure Dec 30 '12 at 9:31
\def\top{\marginpar{please use \string\true instead of \string\top} \true} maybe possible or a message with \typeout, or with \message, or .... if you really want to stop compilation. –  Herbert Dec 30 '12 at 9:35
Thanks. Just checking with you about my understanding of this: what you wrote will produce a message whenever \top is called (i.e. even if not by the user), so previously loaded packages that use \top will also cause this custom message, correct? –  Lover of Structure Jan 1 at 2:39
@LoverofStructure: that is correct –  Herbert Jan 1 at 9:17
Ah, good. So I'd probably include a string like "if user-invoked, [please use ...]" at the beginning of your message, and that would then be the best we can do. –  Lover of Structure Jan 1 at 11:14
show 1 more comment