为什么不能在 \if... \fi 组中使用括号?

为什么不能在 \if... \fi 组中使用括号?

我开始使用\newif在 LaTeX 类定义中,最终停止在文章之间携带所有定义和导入。

由于我尝试定义选项,因此我最终定义了很多开关。有一件事我不明白,为什么这样做有效:

\if@myswitch
   \renewcommand{\myquietcommand}[1]{{}}
\fi

但这不行:

\if@myswitch{
   \renewcommand{\myquietcommand}[1]{{}}
}\fi

我确信这与 LaTeX 解析文档的方式有关,但我想知道如何产生等效效果(为我的编辑器提供“if 宏块”内包含的内容的缩进提示)。

答案1

你可以把括号组放在原始条件语句中,但它没有特殊的语法含义。相反,它只是以与条件语句之外相同的方式形成一个组。因此,当

\if@myswitch{
   \renewcommand{\myquietcommand}[1]{{}}
}\fi

展开,并假设\if@myswitch为真,我们最终得到

{
  \renewcommand{\myquietcommand}[1]{{}}
}

这将启动一个组,插入一个空格(在 之后{),执行\renewcommand,插入另一个空格(在 之后{{}}),然后关闭该组。组的结束意味着 的定义\myquietcommand恢复到组打开之前的定义。

如果你使用 TeX 条件 ( \if@...),则仅使用括号组一个额外的组。\IfFileExists相反,LaTeX 条件语句(例如)则在括号组中采用两个参数。

答案2

LaTeX 最大的秘密之一是

{\ifnum0=`}\fi

与其兄弟姐妹配对

\ifnum0=`{\fi}

但也可以发现

\iftrue{\else}\fi
\iffalse{\else}\fi

这些都是完全合法的 TeX 构造。{\ifnum0=`}\fi\iftrue{\else}\fi展开时都会产生一个左括号。 的 TeXnical 原因{\ifnum0=`}\fi相当复杂;我将描述 的一种可能用法\iftrue{\else}\fi

假设您想逐步构建一个带支撑的标记列表,但该列表应由带支撑的子列表组成。

\def\initlist#1{%
  \def#1{\iftrue{\else}\fi}
}
\def\addtolist#1#2{%
  \listappend#1{\unexpanded{#2}}%
}
\def\addbreaktolist#1{%
  \listappend#1{%
    \iffalse{\else}\fi\iftrue{\else}\fi
  }%
}
\def\finishlist#1{%
  \listappend#1{%
    \iffalse{\else}\fi
  }%
  \edef#1{#1}%
}

\def\listappend#1#2{%
  \expandafter\def\expandafter#1\expandafter{#1#2}%
}

\initlist\foo

\addtolist\foo{abc}
\addtolist\foo{def}
\addbreaktolist\foo
\addtolist\foo{ghi}
\finishlist\foo

\show\foo

(这个有\unexpanded那个可以省去)。

终端上的结果是

> \foo=macro:
->{abcdef}{ghi}.

在任何时候都不会出现不平衡的括号,并且标记列表会按预期出现,\edef这要归功于最终摆脱\iftrue\iffalse,只留下所需的括号。


上面的例子是干什么的?它的目的是表明,对于 TeX 来说,条件和括号是完全独立的。TeX 条件不依赖括号来界定真假文本。一般形式为

<if><test><true text>\else<false text>\fi

其中<if>代表原始条件之一(并且\if@myswitch\iftrue\iffalse),由与 TeX 尝试通过扩展发现的特定(对于并且为空)<test>相关的适当标记组成。和可以是几乎任意的标记列表;如上例所示,它们可以包含括号。<if>\iftrue\iffalse<test><true text><false text>

当然,人们必须对 TeX 如何匹配\else\fi初始有信心<if>,但这已经在其他地方描述过了。

那么你的例子起什么作用?

假设\if@myswitch返回“true”,

\if@myswitch{
   \renewcommand{\myquietcommand}[1]{{}}
}\fi

会离开

{ \renewcommand{\myquietcommand}[1]{{}} }\fi

在主输入流上(带有空格,这可能相关)。\fi展开后将消失。否则它只会留下\fi

\renewcommand像上面的“真实”案例那样在群体中做某事只是一种什么都不做的复杂方式。

相关内容