新命令:什么事不能做?

新命令:什么事不能做?

这不是我第一次尝试创建新命令却失败了。我发现有些东西不起作用(出现“未定义的控制序列”或其他错误)。

  • 使用 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}+

将执行以下步骤

  1. 开一个小组(通过提供{
  2. 开始以等宽字体排版
  3. 将所有特殊字符的含义更改为“可打印”
  4. 定义+}(组结束标记)
  5. 继续排版你发现的一切
  6. 尾随+将撤消所有特殊设置

该描述并不完整,但足以满足我们的目的;还有其他与理解整体情况无关的技术细节。

当你定义时会发生什么

\newcommand{\foo}[1]{\verb+#1+}

就像你提议的那样?当 TeX 看到\foo{\baz{x}}它时,它知道它必须扫描参数并将其标记化。因此参数是四个代币(我用 • 隔开)

\baz • { • x • }

并且 的含义不会发生任何变化\{并且}无法再执行。更糟糕的是,+应该改变其含义以成为组结束标记的 无法修改,因为它在定义时已被标记化。因此,LaTeX 有一个保护机制,不允许\verb成为命令的参数,因为如果您在这样的地方使用它,可能会发生任何类型的邪恶:更改特殊字符的含义而无法撤消设置会让您陷入无路可逃的境地。

有解决方法吗?有,请参阅如何将 \verb 命令放入 \t​​extbf{} 块内?,但首先要问自己,是否真的需要在命令参数中逐字逐句地说明。

相关内容