我正在使用 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]
,所以每当你使用\textbftt
TeX 时,它都会期望找到确切地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
”的例子,所以我建议您坚持这样做,除非您确定自己在做什么。