嵌套命令时的参数非法

嵌套命令时的参数非法

当我尝试定义包含另一个先前定义的命令的命令时,我总是收到非法参数错误。我知道您必须小心处理嵌套定义,但我没想到我会这样做。以下是 MWE:

\documentclass{memoir}

\usepackage{xstring,xparse,xspace}

\NewDocumentCommand{}{\pfc}{Preface~\StrGobbleLeft{#1}{1}\xspace}

\NewDocumentCommand{\D}{ o }{%
\IfNoValueTF{#1} {%
\emph{D}\xspace}{%
    \IfBeginWith{#1}%
    {p}{\emph{D} \pfc}{%
        \IfStrEqCase{#1}{%
            {f}{\emph{Daybreak}\xspace}%
            {g}{\emph{Morgenröte}\xspace}%
            }%
            [\emph{D}~#1\xspace]%
        }%
    }%
}

\begin{document}

\D[p1]

我期望的是以下情况:

前言 1

但我只是得到了非法参数错误。大概是因为我不想使用 ##1,因为我没有在宏中更新命令。如果我只是将 \pfc 的内容而不是命令放入 \D 命令中,那么它就可以工作,但我不想这样做。

有任何想法吗?

答案1

您将其定义为不带参数但在定义中使用过的命令,#1因此会出现错误,就像使用\newcommand或 一样\def

要将外部命令的参数传递给您,\pfc您需要将其定义\pfc为一个带有一个参数的宏,然后\pfc{#1}在第二个定义中使用它来传递该参数。

所以

\NewDocumentCommand{\pfc}{m}{... #1 ...}

....

 ....\pfc{#1}

基本上,当 TeX 看到一个宏带有一个参数时,它会从输入流中删除它\foo{aaa},并将其替换为替换为的替换文本。这是这样做的\foo\foo{aaa}\foo#1aaa第一的,那么 TeX 开始处理替换文本时会忘记所有关于 的内容\foo。因此,当它看到\pfc你的定义并展开它时,#1与顶级命令的参数的所有关联都会被忘记。

答案2

的定义中有一个明显的错误\pfc,但它本身似乎并不是一个真正有用的命令。

通过充分使用,您可以获得更简单的实现expl3

\documentclass{memoir}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\usepackage{xparse,xspace}

\ExplSyntaxOn
\NewDocumentCommand{\D}{ o }
 {
  \IfNoValueTF{#1}
   {% No optional argument: just print D
    \emph{D}\xspace
   }
   {% Optional argument: pass control to an inner function
    \rowthorn_D:n { #1 }
   }
 }

\cs_new:Npn \rowthorn_D:n #1
 {% Check what's the first token in the optional argument
  \str_case_x:nnF { \tl_head:n { #1 } }
   {% if it's `p', remove it and print the rest
    {p}{\emph{D}\nobreakspace Preface\nobreakspace\tl_tail:n { #1 }}
   }
   {% otherwise, if it's f or g ...
    \str_case:nnF { #1 }
     {
      {f}{\emph{Daybreak}}% it's `f': print Daybreak
      {g}{\emph{Morgenr\"ote}}% it's `g': print Morgenröte
     }
     {\emph{D}\nobreakspace#1}% otherwise print the whole argument
   }
 }
\ExplSyntaxOff

\begin{document}

\D[p1] xyz

\D[f] xyz

\D xyz

\D[g] xyz

\D[ff] xyz

\end{document}

请注意,\xspace仅在“没有可选参数”的情况下才需要(如果有的话)。

在此处输入图片描述

相关内容