![将选项从新命令传递到另一个命令(\includegraphics)](https://linux22.com/image/478455/%E5%B0%86%E9%80%89%E9%A1%B9%E4%BB%8E%E6%96%B0%E5%91%BD%E4%BB%A4%E4%BC%A0%E9%80%92%E5%88%B0%E5%8F%A6%E4%B8%80%E4%B8%AA%E5%91%BD%E4%BB%A4%EF%BC%88%5Cincludegraphics%EF%BC%89.png)
我正在制作一个\seal
使用该\includegraphics
函数的命令。该命令\seal
有一些key=value
自己的选项(color
、beamer
、trimz
),它必须接受 的所有选项,\includegraphics
以便直接将它们传递给它。我们可以使用\seal
一个名为的图片,theimage
如下所示:
\seal[width=2cm, color=red]{theimage}
调用:
\includegraphics[width=2cm]{theimage}
虽然我想使用中的所有选项\includegraphics
,但以下代码可以很好地完成height
和width
选项。
% 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
似乎不起作用。似乎还必须=
直接写在括号内,而不是写在括号内的命令内。我可以想到以下解决此问题的策略:
- 设计一种完全不同的方法将选项从 传递
\seal
到\includegraphics
。目前,我还不知道这种方法可能是什么。 - 让 LaTeX 知道这不是错误。由于我是 LaTeX 新手,我不知道该怎么做。我也觉得这不是一个合适的解决方案:如果出现错误消息,则一定是某些地方没有到位。这可能会对其他选项产生实际影响。但是,我愿意接受其他建议。
- 定义
\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
。(此外,这对于这个问题并不重要,并且可选地还有 类。)pgfkeys
ifthenelse
tikz
beamer
附言:很抱歉我无法简短地回答这个问题。
答案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}