Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I'm looking for a LaTeX way to control macro expansion, contingent on some macro being defined or not. I'm looking for something like this (but then actually working):

\newcommand[1]{\checkfor}{
  \if\isdef\csname{#1}
  ... expand this if command exists ...
  \else
  ... expand this if command does not exist ...
  \fi
}

which can then be called using

\checkfor{CommandName}

(this example is, of course, useless. The actual code I want to use this kind of expansion in is a package that dynamically creates a large number of macros from an even larger set of possible macros, with default behaviour for "all macros". Since not "all" macros may exist, I need some way to test whether a macro was declared, before I can expand based on its value).

share|improve this question
    
Welcome to TeX.sx! Your question was migrated here from Stack Overflow. Please register on this site, too, and make sure that both accounts are associated with each other. That way you would be able to comment on or accept answers or edit your question. –  Werner Oct 4 '11 at 21:35
add comment

migrated from stackoverflow.com Oct 4 '11 at 21:22

This question came from our site for professional and enthusiast programmers.

4 Answers

up vote 11 down vote accepted

Is this what you are looking for:

\documentclass[12pt]{article}

\newcommand{\checkfor}[1]{%
  \ifcsname#1\endcsname%
    ... command '#1' exists ...%
  \else%
    ... command '#1' does not exist ...%
  \fi%
}

\begin{document}
\checkfor{CommandName}\par
\checkfor{section}
\end{document}
share|improve this answer
2  
Perhaps mention 'tail safe' approaches using \@firstoftwo/\@secondoftwo. –  Joseph Wright Oct 4 '11 at 21:31
1  
Could you expand on what 'tail safe' means or give a link? I'd like to learn more. –  Justin Bailey Oct 4 '11 at 21:44
    
@JosephWright: Sorry, but I don't know what 'tail safe' refers to. As a reference this question has a good discussion on: what do firstoftwo and secondoftwo do –  Peter Grill Oct 4 '11 at 23:19
1  
@PeterGrill Well, if the 'material to insert' needs to potentially use nested conditional, the leaving the \fi unclosed is not ideal (you get a token build up). There is also the case where the 'material' may need other arguments, which it won't 'see' with the \fi still there. In both of those cases, making the two branches into additional arguments of the macro and using \expandafter\@fitstoftwo/\expandafter\@secondoftwo in the branches is preferable. (Of course, for simple cases this is not required, but I'm assuming a general solution is needed.) –  Joseph Wright Oct 5 '11 at 6:00
    
For those who want to try this out; take care that {CommandName} is without the preceding \ backslash. –  Serge Stroobandt Jun 19 '13 at 8:48
add comment

The etoolbox provides two macros for this:

\ifdef{<control sequence>}{<true>}{<false>}
Expands to <true> if the <control sequence> is defined, and to <false> otherwise.
Note that control sequences will be considered as defined even if their meaning
is \relax. This command is a LaTeX wrapper for the e-TeX primitive \ifdefined.

\ifcsdef{<csname>}{<true>}{<false>}
Similar to \ifdef except that it takes a control sequence name as its first argument.
This command is a LaTeX wrapper for the e-TeX primitive \ifcsname.
share|improve this answer
add comment

The LaTeX kernel standard macro here is \@ifundefined, used as

\@ifundefined{foo}
  {%
    % \foo not defined
  }
  {%
    % \foo defined
  }%

The solution Peter has posted is better in most cases as it is 'expandable' and does not cause \foo to end up defined equal to \relax.

share|improve this answer
add comment

The package xifthen provides \ifundefined which apparently has slightly different semantics:

This test differs from \@ifundefined in that it takes a real command—and not a command name—as argument, and also in that command which is let equal to \relax is not considered undefined.

So what you are looking for can be implemented as:

\newcommand[1]{\checkfor}{
  \ifthenelse{\isundefined{#1}}{%
    % expand undefined
  }{%
    % expand defined
  }%
}
share|improve this answer
    
good information. –  Mike 'Pomax' Kamermans Sep 6 '13 at 17:04
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.