这不是我第一次尝试创建新命令却失败了。我发现有些东西不起作用(出现“未定义的控制序列”或其他错误)。
使用 quote-endquote 参数。
\newcommand{\mytest}[1]{ \quote #1 \endquote }
使用
\verb
带参数的命令\newcommand{\mytest}[1]{ \verb+#1+ }
使用
begin{lstlisting}
环境:\newcommand{\mytest}[1]{ \begin{lstlisting} #1 \end{lstlisting} }
您知道我可以在哪里找到一份详尽的清单,列出我能做什么\newcommand
和不能做什么吗?甚至更好的是,为什么?
答案1
很难说你能用 做什么\newcommand
,因为可能性(确实)是无限的。
我可以谈谈你的两个例子,指出你所犯的错误。
在第一个定义中,你使用\quote
和\endquote
,这是一个错误;\quote
是 LaTeX 在找到时执行的命令\begin{quote}
,但这种情况发生了开团后作为 的副作用。当 LaTeX 发现 时,\begin
该组通常会被 关闭,从而自动撤消由 执行的参数设置。\end
\end{quote}
\quote
根据你的定义,\mytest{something}
你会发现线宽是永久改变并且左缩进将永远持续下去。相反,可以安全地说
\newenvironment{myenv}{\quote}{\endquote}
因为分组将由\begin{myenv}
和提供\end{myenv}
。
的主要特点是什么\newcommand
?我们来看一个简单的例子:
\newcommand{\foo}[1]{?#1!}
现在,如果你输入\foo{xyz}
,它与输入
?xyz!
因为当 TeX 扫描时,\foo
它知道必须找到一个参数(\foo
如果不是,则为之后的第一个标记{
,或者直到匹配的整个标记列表)并用指令中指定的替换文本}
进行替换,其中用 表示。\foo<argument>
\newcommand
<argument>
#1
您最多可以有九个参数(甚至没有参数)。它所做的就是这种“替换”。有了合适的定义,再加上条件结构,您甚至可以定义递归宏,但这太长了,无法描述。“用户定义”的大部分只是用于标记逻辑单元的简单(或稍微复杂)替换。
TeX 不会扫描命令后面的内容,直到它有到。因此,在执行时\foo
,它不会越过参数,也不会在参数内扩展任何宏,直到宏替换结束。因此在
\foo{\baz{x}}
TeX 将会看到
?\baz{x}!
之后它将首先进行处理?
,然后\baz{x}
就好像这些内容从一开始就存在于输入中,但会在第二个示例中显示出细微的差别。
打字上的不同之处\foo{\baz{x}}
在于?\baz{x}!
TeX 已经拥有标记化 \baz{x}
。
该\verb
命令通过改变所有特殊字符的含义来工作。它通过延迟吸收要逐字排版的文本来实现这一点,并且这将在一组中进行;所以
\verb+\baz{x}+
将执行以下步骤
- 开一个小组(通过提供
{
) - 开始以等宽字体排版
- 将所有特殊字符的含义更改为“可打印”
- 定义
+
为}
(组结束标记) - 继续排版你发现的一切
- 尾随
+
将撤消所有特殊设置
该描述并不完整,但足以满足我们的目的;还有其他与理解整体情况无关的技术细节。
当你定义时会发生什么
\newcommand{\foo}[1]{\verb+#1+}
就像你提议的那样?当 TeX 看到\foo{\baz{x}}
它时,它知道它必须扫描参数并将其标记化。因此参数是四个代币(我用 • 隔开)
\baz • { • x • }
并且 的含义不会发生任何变化\
,{
并且}
无法再执行。更糟糕的是,+
应该改变其含义以成为组结束标记的 无法修改,因为它在定义时已被标记化。因此,LaTeX 有一个保护机制,不允许\verb
成为命令的参数,因为如果您在这样的地方使用它,可能会发生任何类型的邪恶:更改特殊字符的含义而无法撤消设置会让您陷入无路可逃的境地。
有解决方法吗?有,请参阅如何将 \verb 命令放入 \textbf{} 块内?,但首先要问自己,是否真的需要在命令参数中逐字逐句地说明。