1

I tried the following three ways to give value(here is aaa) to a macro whose name depends on a condition.

Only the third one works. However, the value aaa has to be written twice. If the value is very long, this would be very annoying.

Any better way?

Code:

\documentclass[a4paper]{article}
\usepackage{}
\usepackage{geometry}
\geometry{showframe}
\geometry{left=1cm,right=1cm,top=1cm,bottom=1cm}
\parindent0pt
\begin{document}
Method 1:
% \expandafter\def\ifnum 5>4 \aaa\else\bbb\fi{aaa}
% \aaa
Method 2:
% \ifnum 5>4\def\aaa\else\def\bbb\fi{aaa}
% \aaa
Method 3:
\ifnum 5>4\def\aaa{aaa}\else\def\bbb{aaa}\fi
\aaa
\end{document}
lyl
  • 2,727

3 Answers3

5

Conditionally do \newcommand.

\documentclass{article}

\makeatletter \newcommand{\conditionalnewcommand}[3]{% % #1 = test, #2 = name for true, #3 = name for false #1\relax \expandafter@firstoftwo \else \expandafter@secondoftwo \fi {\newcommand#2}{\newcommand#3}% } \makeatother

\conditionalnewcommand{\ifnum5>4}{\aaa}{\bbb}{this is aaa} \conditionalnewcommand{\ifnum3>4}{\aaa}{\bbb}{this is bbb}

\begin{document}

\aaa

\bbb

\end{document}

enter image description here

On the other hand, if this is package code and the command name depends on some switch, say \ifpackage@foo, you can do

\newcommand\package@command{whatever}
\@onlypreamble\package@command
\ifpackage@foo
  \@ifdefinable{\aaa}{\let\aaa\package@command}
\else
  \@ifdefinable{\bbb}{\let\bbb\package@command}
\fi

egreg
  • 1,121,712
  • Many thanks @egreg! And what's the meaning of @firstoftwo and @sencondoftwo? And where do they come from? – lyl Feb 20 '22 at 12:48
  • 1
    @lyl You can find the description on the site: https://tex.stackexchange.com/q/21262/4427 – egreg Feb 20 '22 at 17:21
4

I would use \csname ...\endcsname pair and \if conditional inside them:

\expandafter \def \csname \ifnum 4>5 aaa\else bbb\fi \endcsname {...}

Your experiments are bad because the \if conditional evaluates the condition but does not closes whole construction, i.e. \else and \fi remains when \def started.

wipet
  • 74,238
2

TeXbook, Chapter 20: Definitions (also called Macros) says:

  • Conditionals. When an \if... is expanded, TeX reads ahead as far as necessary to determine whether the condition is true or false; and if false, it skips ahead (keeping track of \if...\fi nesting) until finding the \else, \or, or \fi that ends the skipped text. Similarly, when \else, \or, or \fi is expanded, TeX reads to the end of any text that ought to be skipped. The "expansion" of a conditional is empty. (Conditionals always reduce the number of tokens that are seen by later stages of the digestive process, while macros usually increase the number of tokens.)
% Here toplevel-expansion of \ifnum ends before the 1st token of the true-branch/\if..-branch.
% \expandafter..\expandafter in the true-branch/\if..-branch is used to make the entire \else..\fi-branch go away:

\ifnum 5>4 \expandafter\def\expandafter\aaa\else \expandafter\def\expandafter\bbb\fi{aaa}%

\expandafter\show\ifnum 5>4 \aaa\else\bbb\fi

% Here toplevel-expansion of \ifnum ends before the 1st token of the false-branch/\else..-branch. % \expandafter..\expandafter in the false-branch/\else..-branch is used to make the token \fi go away:

\ifnum 5>5 \expandafter\def\expandafter\aaa\else \expandafter\def\expandafter\bbb\fi{aaa}%

\expandafter\show\ifnum 5>5 \aaa\else\bbb\fi

\csname bye\endcsname \stop


While this answer is intended to exhibit expansion-steps with \if..\else..\fi-expressions, which rather indicates a didactic objective, the answers of wipet and egreg, imho, show best how to actually handle things in practice.

Ulrich Diez
  • 28,770