我正在努力解决LaTeX 初学者指南作者:Stefan Kottwitz。我被难住了:
\documentclass{article}
\newcommand{\keyword}[2][\bfseries]{{#1#2}}
\begin{document}
\keyword{Grouping} by curly braces limits the
\keyword{scope} of \keyword[\itshape]{declarations}.
\end{document}
输出结果将“Groupings”和“scope”加粗,而“declarations”则加斜体。我不明白这种语法。我隐约知道这\bfseries
是“默认”的,并\itshape
特意用“declarations”来代替,但我不明白 Kottwitz 的解释:
我们再看一下代码中加粗标记的行。通过使用
[\bfseries]
,我们引入了一个可选参数。我们用 来引用它#1
。它的默认值是\bfseries
。由于我们这次使用了声明,因此我们添加了一对括号以确保只有关键字受到声明的影响。在文档的后面,我们给出了[\itshape]
,\keyword
将默认格式更改为斜体。
我可以就此处发生的事情征询第二意见/解释吗?
答案1
语法\newcommand
没有可选参数如下:
\newcommand{<name>}[<args>]{ <code> }
其中<args>
是参数的数量(范围从 1 到 9)。在<code>
定义的部分中,每个参数都用一个#
符号标记:因此第一个参数是,#1
第二个参数是,#2
等等。因此,如果我们创建一个\reverseconcat
具有三个强制参数的宏并将它们以相反的顺序连接起来,我们将按如下方式定义它:
\newcommand{\reverseconcat}[3]{#3#2#1} % version 1
我们将按如下方式使用它:
\reverseconcat{A}{B}{C}
输出“CBA”
现在假设我们希望命令使输出变为粗体。为此,我们需要添加\bfseries
代码。假设我们这样做:
\newcommand{\reverseconcat}[3]{\bfseries#3#2#1} % version 2
但是,如果我们将相同的参数传递给此命令,就会遇到一个问题:代码部分就像我们刚刚\bfseries CBA
在文档中输入一样,并且由于是一个开关,它将使所有后续文本变为粗体,这不是我们想要的。因此,在这种情况下,我们需要通过在代码部分周围添加括号来\bfseries
限制范围。\bfseries
\newcommand{\reverseconcat}[3]{{\bfseries#3#2#1}} % version 3
现在,当我们将相同的参数传递给此命令时,就好像我们{\bfseries CBA}
在我们的文档中输入了内容一样,这正是我们想要的。
现在假设我们希望命令有一个可选参数。根据定义,可选参数是总是指定的参数#1
(即第一个参数)。但是,由于即使用户省略了第一个参数,命令仍然具有第一个参数,因此我们仍然需要为其提供一个值。因此命令的语法发生了变化:
\newcommand{<name>}[<args>][<first argument value>]{<code>}
现在让我们让反向连接宏接受一个可选参数,该参数指定如何格式化反转的文本。在这种情况下,我们的新宏将接受四参数(假设我们仍然想要我们最初的 3 个参数。)
因此我们的新命令如下所示:
\newcommand{\reverseconcat}[4][\bfseries]{{#1#4#3#2}}
此宏的行为与上面的版本 3 完全相同,因此\reverseconcat{A}{B}{C}
将输出“篮球联赛“。但是请注意,由于我们添加了可选参数,因此用于反转部分的数字是不同的:它们从 开始,#2
因为#1
是可选参数。
但是,我们的新命令允许我们为第一个参数指定不同的值,因此,如果我们不希望文本变为粗体,我们可以通过将\itshape
其变为斜体:
\reverseconcat[\itshape]{A}{B}{C}
这将产生“篮球联赛“
正如 Przemysław Scherwentke 在他的回答中所说,你实际上可以将任何内容传递给这个命令,而不仅仅是格式化命令,所以,例如,如果你忘记了\
on \itshape
:
\reverseconcat[itshape]{A}{B}{C}
输出将是“itshapeCBA”
最后这个例子表明,期望用户将一个命令传递给另一个命令可能不是最好的主意,因为您希望上面的示例产生错误而不是产生不正确的输出。但在这里解决这个问题会让我们走得太远。
答案2
这里有两个独立的事情,我认为同时处理它们可能会造成混乱。第一件事是可选参数第二件事是用于限定范围的括号。
可选参数
当你定义一个命令时
\newcommand\isgreat[2]{#1 thinks #2 is great.}
你在定义周围加上{
和。然后出现的就会像你期望的那样被替换:}
\isgreat
\isgreat{John}{Stack Exchange} He uses it every day.
John 认为 Stack Exchange 很棒。他每天都会使用它。
如果你这样写:
\newcommand\isgreat[2][John]{#1 thinks #2 is great.}
那么第一个参数是可选的。如果你不给它,它默认为John
\isgreat{LaTeX}
约翰认为 LaTeX 很棒。
如果你做给它,你必须把它放在方括号中。
\isgreat[Gary]{LaTeX}
Gary 认为 LaTeX 很棒。
用于限定范围的括号
当您书写时\bfseries
,就像单击 Microsoft Word 中的“粗体”工具栏按钮一样——从那时起您键入的所有内容都将变为粗体。
John thinks LaTeX is \bfseries great. He uses it every day.
John 认为 LaTeX 是太棒了。他每天都用它。
为了将粗体限制在文本的特定部分,可以将其括在括号中。
John thinks LaTeX is {\bfseries great}. He uses it every day.
John 认为 LaTeX 是伟大的。他每天都用它。
最后
在 Stefan 的例子中,LaTeX 取代了
\keyword{Grouping} by curly braces
和
{\bfseries Grouping} by curly braces
您知道为什么需要额外的花括号吗\newcommand
?一对花括号用于提供定义,另一对花括号用于限制命令的范围\bfseries
。
答案3
\newcommand{\keyword}[2][\bfseries]{{#1#2}}
是一个具有 2 个参数和一个可选参数的宏。如果未指定,\bfseries
则将其作为第一个参数。如果您写入,例如,\keyword[AAA]{declarations}
您将获得AAAdeclarations
罗马字体。
答案4
我认为令人费解的部分,正如在约翰的回答,是这句话
由于我们这次使用了声明,所以我们添加了一对括号以确保只有关键字受到声明的影响。
引用声明可能会与与宣言一个新的命令。
相反,它指的是\newcommand
内容的扩展不会自动限定范围,并且在使用\bfseries
和其他声明的特定情况下,您必须自己处理范围,通过让最后一个参数newcommand
限定范围:{#1#2}
而不是#1#2
也许从不同的例子开始会有所帮助:
\documentclass{article}
\newcommand{\dummy}[2][0]{#2^#1}
\begin{document}
the default is $\dummy{A}$ but you can switch to $\dummy[2]{A}$
\end{document}