定义名称取决于条件的宏

定义名称取决于条件的宏

我尝试了以下三种方法aaa为名称取决于条件的宏赋予值(这里是)。

只有第三个有效。但是,该值aaa必须写入两次。如果该值很长,这会很烦人。

还有更好的办法吗?

代码:

\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}

答案1

TeXbook,第 20 章:定义(也称为宏)说:

  • 条件。当\if...被展开时,TeX 会尽可能地向前读取以确定条件是真还是假;如果为假,它会向前跳过(跟踪\if...\fi嵌套),直到找到\else\or\fi来结束跳过的文本。同样,当\else\or\fi被展开时,TeX 会读取到任何应该跳过的文本的末尾。条件的“展开”为空。(条件总是减少消化过程后期阶段看到的标记数量,而宏通常会增加标记数量。)
% 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

虽然这个答案的目的是展示带有 \if..\else..\fi表达式的扩展步骤,这更表明了一个教学目标,但擦拭埃格尔在我看来,最好地展示如何在实践中实际处理事情。

答案2

有条件地做\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}

在此处输入图片描述

另一方面,如果这是包代码,并且命令名称依赖于某些开关,例如\ifpackage@foo,您可以执行

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

答案3

我会在其中使用\csname ...\endcsname配对和条件:\if

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

您的实验很糟糕,因为\if条件评估了条件但没有关闭整个构造,即\else在启动\fi时保持不变。\def

相关内容