1

I am trying to define some macros in which I need an "if" which test contains an argument of the macro. The issue arises when this argument is \vec{<arg>} and the amsmath package is loaded. Here is a minimal working example:

\documentclass{article}
\begin{document}
$\if\vec{x}\empty true\else false\fi$
\end{document}

and here is a minimal non-working example:

\documentclass{article}
\usepackage{amsmath}
\begin{document}
$\if\vec{x}\empty true\else false\fi$
\end{document}

I would be happy to understand what causes the errors in the definition of vec by the amsmath package, and how to fix it.

To give you more information, I create the macro:

\newcommand*\ifpresent[2]{\expandafter\if#1\empty\else#2\fi}

and I want

$\ifpresent{\ifpresent{x}{a}}{b}$

to write "b", and

$\ifpresent{\ifpresent{}{a}}{b}$

to write nothing.

I also tried:

\newcommand*\ifpresent[2]{\expandafter\ifx#1\empty\else#2\fi}

but in this case

$\ifpresent{\ifpresent{x}{a}}{b}$

gives me the "Extra \else" and "extra \fi" errors.

What I want then is to define macros like

\newcommand\foo[1]{\ifpresent{#1}{foo#1}}

and

\newcommand\bar[1]{\ifpresent{#1}{bar#1}}

such that

\foo{\bar{}}

gives nothing and

\foo{\bar{yeah}}

gives "foobaryeah"

  • Welcome to TeX.SX! TeX's \if is rather different from what C programmers would expect; it's not really clear what a use case of your \ifpresent macro should do. – egreg Mar 19 '14 at 13:16
  • Well, what I want is to define macros like \newcommand\foo[1]{\ifpresent{#1}{foo#1}} and \newcommand\bar[1]{\ifpresent{#1}{bar#1}} such that \foo{\bar{}} gives nothing and \foo{\bar{yeah}} gives "foobaryeah" – Val Mar 19 '14 at 13:19
  • Can you also clarify what you mean with the first sentence of your post? Moreover, it is more important that you explain what the conditional itself should check for. (For an empty argument? This one is really easy with a trick by @HeikoOberdiek: \if\relax\detokenize{#1}\relax <true>\else <false>\fi) – Ruben Mar 19 '14 at 13:19
  • Sorry, but I can't understand. – egreg Mar 19 '14 at 13:23
  • Indeed, @Ruben I want to test for emptyness of the argument. The issue with \if\relax\detokenize{#1}\relax <true>\else <false>\fi is that \ifpresent{\ifpresent{}{a}}{b} generates "b" instead of nothing. – Val Mar 19 '14 at 13:31
4

I don't really understand what you're looking for. Surely \if is not the good tool, because of its rules: \if will expand what follows until finding two unexpandable tokens that then it compares.

Possibly this is a realization of your needs:

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\doifnonblank}{mm}
 {
  \val_doifnonblank:fn { #1 } { #2 }
 }

\cs_new:Npn \val_doifnonblank:nn #1 #2
 {
  \tl_if_blank:nF { #1 } { #2 }
 }

\cs_generate_variant:Nn \val_doifnonblank:nn { f }
\ExplSyntaxOff

\newcommand{\foo}[1]{\doifnonblank{#1}{foo#1}}

\begin{document}

X\foo{}X

X\foo{x}X

X\foo{\doifnonblank{}{x}}X

X\foo{\doifnonblank{x}{y}}X

\end{document}
| improve this answer | |
  • Yes ! That is what I wanted. Thank you. I don't really understand the code here, but I will try to. It seems to be "latex3". Isn't it possible with latex2e ? – Val Mar 19 '14 at 13:39
  • @Val Yes, it's LaTeX3 and it would be possible also in legacy LaTeX; why bother? ;-) – egreg Mar 19 '14 at 15:15
2
 \if\vec{

expands \vec until it gets two non expandable tokens and then tests those tokens to see if they have the same character code. I suspect that isn't what you want to test. I'd suggest a replacement but it isn't clear what you do want to test at that point/

| improve this answer | |
  • Indeed that is not what I want. I want to test if \vec{x} and empty produce the same thing. In this case they don't. I edited my question to explain what I want to do. – Val Mar 19 '14 at 13:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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