# Define a Macro via Macro if Given Macro is not defined

I want to define a macro if it is not already defined. I can do this inline as the example below shows. But I would like to have a macro to do this functionality for me. My attempt to make this work is DefineMacroIfUndefined, but not sure how to adjust it to make it work.

I have commented out the call to DefineMacroIfUndefined as this does not compile otherwise.

\documentclass{article}

\newcommand{\CheckIfCommandDefined}{
\ifdefined\MyNewCommand
MyNewCommand is defined.\par%
\else
MyNewCommand is not defined.\par%
\fi
}

% Define macro to the given value if not already defined
\newcommand{\DefineMacroIfUndefined}[2]{
% #1 is name of macro
% #2 is value to be assigned if this macros is not already defined.
\ifdefined\csname#1\endcsname
% Do nothing since it is already defined
\else
\newcommand{\csname#1\endcsname}{#2}
\fi
}

\begin{document}

% This works great.
\ifdefined\MyNewCommand
% Do nothing since it is already defined
\else
\newcommand{\MyNewCommand}{true}
\fi

\CheckIfCommandDefined
\let\MyNewCommand\undefined % Undefine \MyNewCommand

\CheckIfCommandDefined
% But want to be able to do the above thru a macro
%\DefineMacroIfUndefined{MyNewCommand}{true}
\CheckIfCommandDefined

\end{document}


You can simply use \providecommand instead of \newcommand. It has the same syntax but defines the macro only if it is not yet defined.

If you want to do it manual you need to use \expandafter before the \newcommand to make sure \csname ...\endcsname is expanded before it. In this case the { } should be simply dropped.

% Define macro to the given value if not already defined
\newcommand{\DefineMacroIfUndefined}[3][0]{%
% #1 is the optional argument
% #2 is name of macro
% #3 is value to be assigned if this macros is not already defined.
\ifcsname#2\endcsname
% Do nothing since it is already defined
\else
\expandafter\newcommand\csname#2\endcsname[#1]{#3}%
%or: \expandafter\newcommand\expandafter{\csname#2\endcsname}[#1]{#3}%
\fi
}

• This works nice. I assume the optional argument is the number of parameters for this macro. If so, how would I pass in what to do with the parameters? Use ##? Jun 2, 2011 at 5:05
• Sorry, I just saw your comment now. Single # should be fine here. Oct 23, 2011 at 9:23

The following are a full set of macros I use. It has full error checking and writes every thing to the log file!!! If you try to overwrite an existing command it will stop with an error.

It gives you three command \TestedNameLet, \TestedNameDef and \TestedNameRobustDef

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\makeatletter

% You will probably put this inside a package
\newcommand*\my@pkgname{mypackage}

\def\my@ifundefined#1{%-- Better than standard latex (eTex has better tests than this)
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname#1\endcsname\relax
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi}

\long\def\my@ifnamedefinable #1{%-- Test and write info to log
\edef\reserved@a{#1}%
\my@ifundefined\reserved@a
{\edef\reserved@b{\expandafter\@carcube \reserved@a xxx\@nil}%
\ifx \reserved@b\@qend \my@notdefinable\else
\ifx \reserved@a\@qrelax \my@notdefinable\else
\PackageInfo{\my@pkgname}{\@backslashchar\reserved@a\space created}%
\fi
\fi}%
\my@notdefinable}

\gdef\my@notdefinable{%-- Error message
\PackageError{\my@pkgname}{%
Command \@backslashchar\reserved@a\space
Or name \@backslashchar\@qend... illegal.%
}{%
If \@backslashchar\reserved@a\space is not important\MessageBreak
then \protect\let\@backslashchar\reserved@a%
=\protect\relax,\MessageBreak
else use a different \@backslashchar name.}}

%%% Base level commands %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand*{\my@namelet}[1]{\expandafter\let\csname #1\endcsname}
\newcommand*{\my@nameuse}[1]{\csname #1\endcsname}
\newcommand*{\my@namedef}[1]{\expandafter\def\csname #1\endcsname}
\newcommand*{\my@robustnamedef}[1]{%
\expandafter\edef\csname #1\endcsname{%
\noexpand\protect\my@nameuse{#1 }}%
\my@namedef{#1 }}

%%% These are the commands to use %%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand*{\TestedNameLet}[1]{%
\my@ifnamedefinable{#1}\my@namelet{#1}}

\newcommand*{\TestedNameDef}[1]{%
\my@ifnamedefinable{#1}\my@namedef{#1}}

\newcommand*{\TestedNameRobustDef}[1]{%
\my@ifnamedefinable{#1}\my@robustnamedef{#1}}

\makeatother
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


An example of the usage is:

\newcommand\CreateRef[2]{%
\TestedNameDef{#1Ref}##1{#2\ref{##1}}}


This can be used to create your own reference commands on the fly

\CreateRef{Fig}{Figure~}


Which will create a command \FigRef{lab} -> Figure~\ref{lab}

• I am not yet as well versed with LaTeX as I need to be and am wondering if there is an advantage to using this over Martin's suggestion, which I can actually understand. Jun 2, 2011 at 5:00
• @Peter Grill: Conceptualy, Martin's version is related to \providecommand which means that if the command allready exists the original command is used and the one you provided is ignored. My version is related to \newcommand which means if the command already exists TeX stops and throws an error. You then have to choose a new command name. Jun 2, 2011 at 7:37
• Thanks. As I get more proficient at LaTeX, I have a feeling I'll migrate over to your solution over time. Jun 2, 2011 at 8:23