使用 \newcommand 所作的定义在一次使用后失效

使用 \newcommand 所作的定义在一次使用后失效

我正在使用 Overleaf。

我创建了一个简单的命令来组合\textbf\texttt

\newcommand{\textbftt}[1]{\textbf{\texttt{#1}}}

该定义位于文档前奏文件中。

\textbftt在文档的其他地方使用了该命令,例如textbftt{return}。它似乎工作正常。

但是,当我编辑使用 的文件时\textbftt(编辑与 的使用无关\textbftt),该命令不再起作用。文本既不显示bf也不显示tt

我还在页边空白处看到了一个错误标记(一个带有“x”的小红框)。附加的错误消息表明该命令的使用方式与其定义不一致。(如果一开始它工作正常,怎么会这样呢?)

更令人困惑的是,如果我对包含定义的文件进行多余的编辑,例如,在文件的某个地方添加一个额外的空格,该命令现在就可以正常工作 - 直到我再次编辑使用它的文件。(如果我使用\def而不是,也会发生同样的事情\newcommand。)

我发现自己对前奏文件进行了反复无意义的更改(例如,添加和删除多余的空格)以查看我的文档是什么样子。

对于可能发生的事情有什么想法吗?

对 prelude 文件的更改是否会迫使 Overleaf 重新读取该文件,从而重新读取定义?它在重新编译时不是总是这样做吗?

谢谢。

答案1

在您的文档中您有:

\def\textbftt[#1]{\textbf{\texttt{#1}}}

而你说的问题是:

\newcommand{\textbftt}[1]{\textbf{\texttt{#1}}}

首先,除非你真的,绝对地知道你在做什么,你应该在文档中使用\newcommand而不是。如果你仔细看,LaTeX 手册甚至没有解释 的用法,所以它(某种程度上)不属于系统(当然它可以工作,因为 LaTeX 在 TeX 之上运行,但它真的不应该在日常文档中使用)。\def\def\def是给“专家”用的!

现在,上述两个定义都是正确的,如果使用得当,它们都会起作用(什么会不起作用 :-)。然而,它们都定义了两个非常不同的命令!

\newcommand

我们先解决第二个问题,它比较“简单”。语法如下\newcommand

\newcommand{<command>}[<num args>][<default>]{<replacement text>}

其中[<num args>][<default>]都是可选的,但如果要使用后者,前者是必需的。<command>是命令名称,在您的例子中是\textbftt,您将其定义为带<num args>=1参数,没有可选参数(因为<default>没有给出),并且<replacement text>此命令的是\textbf{\texttt{#1}},其中#1是命令的第一个(也是唯一一个)参数,用括号({...})括起来。 这一切意味着当您使用该定义时:

\textbftt{<some text>}

TeX 将扩展\textbftt,用括号之间的内容(平衡!)替换#1中的:<replacement text>

\textbf{\texttt{<some text>}}

这正是你想要的。

\def

现在这个\def版本比较复杂。语法如下\def(稍微简化了一下):

\def<command><parameter text>{<replacement text>}

其中<command><replacement text>与 版本中的相同\newcommand。 正是<parameter text>欺骗了你,因为,嗯,这是最棘手的部分 :-)

可以是任意文本,但<parameter text>和 除外,它们最多可包含 9 个符号,后跟 1 到 9 的连续数字({}#IE, #1,,#2... #9---这些是“参数”)。<parameter text>除了参数之外,您在中使用的任何内容都必须匹配确切地当你使用 时<command>。在你的定义中\def\textbftt[#1]{\textbf{\texttt{#1}}}<parameter text>[#1],所以每当你使用\textbfttTeX 时,它都会期望找到确切地a [,后跟任意 (平衡--- 平衡对{...}) 的文本(可能为空),直到下一个]。如果 TeX 找不到其中任何一个,它会说Use of \textbftt doesn't match its definition

现在,知道您需要将文本括在里面[...]而不是{...}现在,您可以像以前版本中那样使用命令:

\textbftt[<some text>]

那么 TeX 将会扩展\textbftt

\textbf{\texttt{<some text>}}

您会得到相同的结果,但定义和用法不同。

问题

但是现在你说:“嘿,我可以用\textbftt[<some text>]代替\textbftt{<some text>}!”

是的,你可以。但你不应该。LaTeX 手册定义选修的参数应括在 中[...],而不是强制参数。违反此惯例会使命令的使用违反直觉,并且可能存在问题。

另一个问题是 TeX 知道是{...}“分隔符”,而[]只是两个字符,就像!和和,@一样……这意味着如果您需要使用其他[]您需要特殊保护以确保 TeX 做正确的事情。例如:

\textbftt[some [text] with square brackets]

将要不是做你想做的事。
它将扩展为:

\textbf{\texttt{some [text}} with square brackets]

最后,当然,\newcommand检查您尝试创建的命令是否已经存在,如果您要重新定义某些重要内容,则会引发错误。\def只需这样做,您就会注意到混乱何时发生。

如果您搜索此网站,您会看到大量“您应该使用\newcommand”的例子,所以我建议您坚持这样做,除非您确定自己在做什么。

相关内容