将选项从新命令传递到另一个命令(\includegraphics)

将选项从新命令传递到另一个命令(\includegraphics)

我正在制作一个\seal使用该\includegraphics函数的命令。该命令\seal有一些key=value自己的选项(colorbeamertrimz),它必须接受 的所有选项,\includegraphics以便直接将它们传递给它。我们可以使用\seal一个名为的图片,theimage如下所示:

\seal[width=2cm, color=red]{theimage}

调用:

\includegraphics[width=2cm]{theimage}

虽然我想使用中的所有选项\includegraphics,但以下代码可以很好地完成heightwidth选项。

% Declaring options for "seal"
\pgfkeys{
/seal/.is family, /seal,
% "seal" options
color/.estore in = \sealColor,
beamer/.estore in = \sealBeamer,
trimz/.estore in = \sealTrimz,
% "\includegraphics" options
height/.estore in = \sealHeight,
width/.estore in = \sealWidth,
}

% Declaring variables for the left side of "key=value"
\newcommand{\sealHeightL}{height}
\newcommand{\sealWidthL}{width}

% Declaring a command for storing the image
\newcommand{\theimage}{}

% Defining the \seal command
\newcommand{\seal}[2][]{%
    \pgfkeys{/seal, #1}%
    %
    % Makes the left side of "key=value" empty
    % if there's no value
    \ifthenelse{\equal{\sealHeight}{}}
        {\renewcommand{\sealHeightL}{}}
        {\renewcommand{\sealHeightL}{height}}%
    \ifthenelse{\equal{\sealWidth}{}}
        {\renewcommand{\sealWidthL}{}}
        {\renewcommand{\sealWidthL}{width}}%
    %
    % The \includegraphics command
    \renewcommand{\theimage}{\includegraphics[%
        \sealHeightL=\sealHeight,%
        \sealWidthL=\sealWidth,%
    ]{#2}%
    %
    % The other command (pay no attention to this)
    \othercommand{\sealColor}{\sealBeamer}{\sealTrimz}{\theimage}
}

此代码的基本思想是调用\seal[width=2cm, color=red]{theimage}\includegraphics[width=2cm, =]{theimage}然后\seal[color=red]{theimage}调用\includegraphics[=, =]{theimage}。这是可行的,因为 和 都\includegraphics[width=2cm, =]{theimage}不会\includegraphics[=, =]{theimage}产生错误消息。最后一个相当于调用\includegraphics[]{theimage}

现在,尽管此代码可以很好地完成工作,但是在调用时它会返回两个错误消息\seal[height=2cm]{theimage}

Undefined control sequence. \seal[height=2cm]{theimage}
Package keyval Error: undefined. \seal[height=2cm]{theimage}

当调用时\seal{theimage},它会返回重复两次的以下消息。

Undefined control sequence. \seal{theimage}
Package keyval Error: undefined. \seal{theimage}

我认为发生这种情况的原因与 相同\includegraphics[\empty = \empty,]{theimage},其中\newcommand{\empty}{},返回以下错误消息:

Package keyval Error: undefined. \includegraphics[\empty = \empty]{theimage}

使用\ifthenelse方括号内的命令\includegraphics似乎不起作用。似乎还必须=直接写在括号内,而不是写在括号内的命令内。我可以想到以下解决此问题的策略:

  1. 设计一种完全不同的方法将选项从 传递\seal\includegraphics。目前,我还不知道这种方法可能是什么。
  2. 让 LaTeX 知道这不是错误。由于我是 LaTeX 新手,我不知道该怎么做。我也觉得这不是一个合适的解决方案:如果出现错误消息,则一定是某些地方没有到位。这可能会对其他选项产生实际影响。但是,我愿意接受其他建议。
  3. 定义\seal它使用两个括号来表示key=value选项:一个用于它自己的选项,另一个用于表示\includegraphics选项。这样,它会将其中一个括号的整个字符串传递给\includegraphics。在这种情况下,我们将调用\seal[width=2cm][color=red]{theimage}而不是\seal[width=2cm, color=red]{theimage}。我认为这可能是最直接的解决方案。的第一个版本\seal是形式为的命令\seal[includegraphicsOptions]{colorValue}{beamerValue}{trimzValue}{theimage},它将整个includegraphicsOptions字符串传递给\includegraphics不返回任何错误。尽管如此,我不知道如何定义\seal它有两个括号,虽然我非常欢迎这样的解决方案,但我认为它有点不符合我的口味。(在这一点上,我更有可能被说服。)

但最终,我来这里是因为我不知道如何正确解决这个问题。我希望有人能提出解决方案。

笔记:我正在使用/需要的用于此命令的唯一包是和graphicx。(此外,这对于这个问题并不重要,并且可选地还有 类。)pgfkeysifthenelsetikzbeamer

附言:很抱歉我无法简短地回答这个问题。

答案1

您可以使用该.unknown功能:

\documentclass{article}
\usepackage{pgfkeys}

% Declaring options for "seal"
\pgfkeys{
  /seal/.is family, /seal,
  % "seal" options
  color/.estore in = \sealColor,
  beamer/.estore in = \sealBeamer,
  trimz/.estore in = \sealTrimz,
  .unknown/.code={%
    \edef\includegraphicssealoptions{\includegraphicssealoptions,\pgfkeyscurrentname=#1}%
  },
}

% Defining the \seal command
\newcommand{\seal}[2][]{%
  \def\includegraphicssealoptions{}%
  \pgfkeys{/seal,color=black,beamer=,trimz=,#1}%
  \edef\thesealimage{\noexpand\includegraphics[\includegraphicssealoptions]{#2}}%
  % The other command (pay no attention to this)
  \othercommand{\sealColor}{\sealBeamer}{\sealTrimz}{\thesealimage}
}

\newcommand{\othercommand}[4]{%
  \typeout{%
    sealColor=#1^^J%
    sealBeamer=#2^^J%
    sealTrimz=#3^^J%
    imagecommand=\unexpanded\expandafter{#4}%
  }%
}

\begin{document}

\seal[width=2cm, color=red]{theimage}

\seal[trimz=b,width=2cm,height=1cm,beamer=x,color=red]{theimage}

\end{document}

对于插入您发出的图像\thesealimage,我猜是\othercommand

根据示例中的定义,您可以获得

sealColor=red
sealBeamer=
sealTrimz=
imagecommand=\includegraphics [,width=2cm]{theimage}

sealColor=red
sealBeamer=x
sealTrimz=b
imagecommand=\includegraphics [,width=2cm,height=1cm]{theimage}

答案2

这对于 来说(几乎)微不足道expkv-cs。以下内容不定义您的临时宏,并且仅通过参数转发起作用(如果您需要\sealColor定义宏,您可以在\sealDO将它们传递给 之前进行定义\othercommand)。

以下使用\othercommand与@egreg相同的功能和相同的值(除了它不扩展图像命令的第一个标记,因为它已经是了\includegraphics):

\documentclass{article}

\usepackage{expkv-cs}

\newcommand\seal[2][]{\sealKV{#1}{#2}}
\ekvcSplitAndForward\sealKV\sealDO
  {
     color  = {} % #1
    ,beamer = {} % #2
    ,trimz  = {} % #3
    ,...         % #4 -- all unknown keys
  }
\newcommand\sealDO[5]
  {\othercommand{#1}{#2}{#3}{\includegraphics[#4]{#5}}}

\newcommand{\othercommand}[4]{%
  \typeout{%
    sealColor=#1^^J%
    sealBeamer=#2^^J%
    sealTrimz=#3^^J%
    imagecommand=\unexpanded{#4}%
  }%
}

\begin{document}

\seal[width=2cm, color=red]{theimage}

\seal[trimz=b,width=2cm,height=1cm,beamer=x,color=red]{theimage}

\end{document}

这将打印到终端:

sealColor=red
sealBeamer=
sealTrimz=
imagecommand=\includegraphics [, {width} = {2cm} ]{theimage}
sealColor=red
sealBeamer=x
sealTrimz=b
imagecommand=\includegraphics [, {width} = {2cm} , {height} = {1cm} ]{theimage}

相关内容