将宏扩展为 \input 的参数会导致未定义的控制序列错误

将宏扩展为 \input 的参数会导致未定义的控制序列错误

我正在创建一个包,它定义了一个如下所示的命令:

\newcommand{\mycommand}[2]{
    \input{|"\mypackage@buildcommand{#1}{#2}"}
}

mypackage@buildcommand使用 ifthen 包,它定义了\equal。但是,当我\mycommand{x}{y}在使用我的包的 LaTeX 文档中使用时,我收到一个未定义的控制序列错误,引用\equal。当我的宏只是返回 buildcommand 的结果而不是将其传递给输入时,它可以正常工作并将命令输出到 LaTeX 文档,但这样\input它就不起作用了。

编辑
添加了使用ifthen的相关代码

\ifx\@empty\playtex@encoding
    \ifdefined\inputencodingname
        % Use inputenc encoding if defined
        \def\playtex@encoding{%
            % Treat utf8x as utf8
            \ifthenelse{\equal{\inputencodingname}{utf8x}}%
            {utf8}{\inputencodingname}%
        }
    \else
        \def\playtex@encoding{utf8}
    \fi
\fi

\newcommand{\playtex@buildcommand}[2]{%
    playtex-render \playtex@playerfile{} #1 #2 %
    --encoding=\playtex@encoding{} %
    \ifthenelse{\equal{\playtex@cache}{always}}{--cache}{%
    \ifthenelse{\equal{\playtex@cache}{never}}{--no-cache}{%
    \ifthenelse{\equal{\playtex@cache}{draft}}{%
        \ifdraft{--cache}{--no-cache}%
    }{{\errmessage{cache must be always, never, or draft}}}}}%
}

答案1

您需要使用可扩展测试,但事实\ifthenelse并非如此。此外,{}不应在该上下文中使用该测试来分隔宏名称,而\space应使用该测试。

我将命令改为echo仅用于测试目的。

\documentclass{article}
\usepackage{pdftexcmds}

\makeatletter
\newcommand{\ifequalstring}[2]{%
  \ifnum\pdf@strcmp{#1}{#2}=\z@
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}

\newcommand{\mycommand}[2]{%
  \input{|"\playtex@buildcommand{#1}{#2}"}%
}

\ifdefined\inputencodingname
  % Use inputenc encoding if defined
  \edef\playtex@encoding{%
    % Treat utf8x as utf8
    \ifequalstring{\inputencodingname}{utf8x}{utf8}{\inputencodingname}%
  }%
\else
  \def\playtex@encoding{utf8}%
\fi

\newcommand{\playtex@buildcommand}[2]{%
%  playtex-render \playtex@playerfile\space #1 #2 %
  echo \playtex@playerfile\space #1 #2 %
    --encoding=\playtex@encoding\space
    \ifequalstring{\playtex@cache}{always}
      {--cache}
      {%
       \ifequalstring{\playtex@cache}{never}
         {--no-cache}
         {%
          \ifequalstring{\playtex@cache}{draft}
            {\ifdraft{--cache}{--no-cache}}
            {\errmessage{cache must be always, never, or draft}}%
         }%
      }%
}
\makeatother

\begin{document}

\makeatletter % for testing
\def\playtex@playerfile{FILE}
\def\playtex@cache{always}
\makeatother

\texttt{\mycommand{A}{B}}

\end{document}

输出

FILE A B --encoding=utf8 --cache

答案2

我通过从宏中提取所有条件并使用条件定义不同的宏来使其工作。我为参数创建了一个 cachearg 宏--cache,在输入中我将所有“静态”宏放在一起。我还必须创建一个\playtex@space宏,设置为空格字符,因为\macro{}语法在上下文中不起作用\input,以阻止宏因某种原因吞噬其后的东西。在@DavidCarlisle 的评论中,我看到他使用了一个\@space似乎做同样事情的宏,但我尝试用它替换它\playtex@space\@space但它没有定义。不知道它是否应该是默认的。

整个过程相当丑陋和不灵活:例如,如果 inputenc 编码发生变化,我的包不会像宏中的条件那样自动更新。话虽如此,它还是有效的。感谢您的帮助。

相关内容