我想创建一个命令,以便轻松地将彩色图片转换为黑白图片。为此,我想将\newif \ifBlackAndWhite
和 宏一起使用\myCommand
,这样如果\ifBlackAndWhitetrue
,那么
\begin{pspicture}(0,0)(2,2)
\pscircle[\myCommand, linewidth=1mm](1,1){0.5}
\end{pspicture}
变成
\begin{pspicture}(0,0)(2,2)
\pscircle[fillstyle=none, linewidth=1mm](1,1){0.5}
\end{pspicture}
如果\ifBlackAndWhitefalse
,那么就变成
\begin{pspicture}(0,0)(2,2)
\pscircle[fillstyle=solid, fillcolor=red, linewidth=1mm](1,1){0.5}
\end{pspicture}
是否可以定义这样的宏? 下面是一个简单的模板...
\documentclass{article}
\usepackage{pstricks}
\newcommand{\myCommand}{...}
\newif\ifBlackAndWhite \BlackAndWhitefalse
\ifBlackAndWhite
\renewcommand{\myCommand}{...}
\fi
\begin{document}
\begin{pspicture}(0,0)(2,2)
\pscircle[fillstyle=none, linewidth=1mm](1,1){0.5}
\end{pspicture}
\begin{pspicture}(0,0)(2,2)
\pscircle[fillstyle=solid, fillcolor=red, linewidth=1mm](1,1){0.5}
\end{pspicture}
\begin{pspicture}(0,0)(2,2)
\pscircle[\myCommand, linewidth=1mm](1,1){0.5}
\end{pspicture}
\end{document}
答案1
您需要更改扩展顺序。对于简单的命令,例如\pscircle
您可以定义为您执行此操作的变体(\ePScircle
见下文)。对于更复杂的命令,这并不那么容易。这就是为什么您可能需要考虑切换到 Ti钾Z,风格可以轻松完成所有这些。
\documentclass{article}
\usepackage{pstricks}
\newif\ifBlackAndWhite
\BlackAndWhitefalse
\newcommand\myCommand{\ifBlackAndWhite
fillstyle=none%
\else
fillstyle=solid,fillcolor=red%
\fi}
\def\ePScircle[#1](#2)#3{\expanded{\noexpand\pscircle[#1](#2){#3}}}
\begin{document}
\begin{pspicture}(0,0)(2,2)
\pscircle[fillstyle=none, linewidth=1mm](1,1){0.5}
\end{pspicture}
\begin{pspicture}(0,0)(2,2)
\pscircle[fillstyle=solid, fillcolor=red, linewidth=1mm](1,1){0.5}
\end{pspicture}
\BlackAndWhitetrue
\begin{pspicture}(0,0)(2,2)
\expanded{\noexpand\pscircle[\myCommand, linewidth=1mm](1,1){0.5}}
\end{pspicture}
\BlackAndWhitefalse
\begin{pspicture}(0,0)(2,2)
\expanded{\noexpand\pscircle[\myCommand, linewidth=1mm](1,1){0.5}}
\end{pspicture}
\BlackAndWhitetrue
\begin{pspicture}(0,0)(2,2)
\ePScircle[\myCommand, linewidth=1mm](1,1){0.5}
\end{pspicture}
\BlackAndWhitefalse
\begin{pspicture}(0,0)(2,2)
\ePScircle[\myCommand, linewidth=1mm](1,1){0.5}
\end{pspicture}
\end{document}
答案2
传递给任何 PStricks 对象的可选参数未展开。您可以重新定义捕获可选参数的宏 - \pst@@object
- 以使用\edef
而不是常规的\def
:
\makeatletter
\def\pst@@object#1[#2]{%
\edef\pst@par{#2}% Changed from \def to \edef
\@ifnextchar+{\@nameuse{#1@i}}{\@nameuse{#1@i}}%
}
\makeatother
更优雅一点的可能是使用etoolbox
修补:
\usepackage{etoolbox}
\makeatletter
% \patchcmd{<cmd>}{<search>}{<replace>}{<success>}{<failure>}
\patchcmd{\pst@@object}% <cmd>
{\def}% <search>
{\edef}% <replace>
{}{}% <success><failure>
\makeatother
An\edef
将扩展参数一次,这在大多数情况下可能就足够了。
\documentclass{article}
\usepackage{pstricks}
\usepackage{etoolbox}
\makeatletter
% \patchcmd{<cmd>}{<search>}{<replace>}{<success>}{<failure>}
\patchcmd{\pst@@object}% <cmd>
{\def}% <search>
{\edef}% <replace>
{}{}% <success><failure>
\makeatother
\newcommand{\myCommand}{fillstyle=solid, fillcolor=red}
\newif\ifBlackAndWhite \BlackAndWhitefalse
\ifBlackAndWhite
\renewcommand{\myCommand}{fillstyle=none}
\fi
\begin{document}
\begin{pspicture}(0,0)(2,2)
\pscircle[fillstyle=none, linewidth=1mm](1,1){0.5}
\end{pspicture}
\begin{pspicture}(0,0)(2,2)
\pscircle[fillstyle=solid, fillcolor=red, linewidth=1mm](1,1){0.5}
\end{pspicture}
\begin{pspicture}(0,0)(2,2)
\pscircle[\myCommand, linewidth=1mm](1,1){0.5}
\end{pspicture}
\end{document}
下面是输出\BlackAndWhitetrue
:
答案3
您可以定义自己的密钥。
\documentclass{article}
\usepackage{pstricks}
\makeatletter % switch the commented lines for changing the meaning of the key
\define@key[psset]{pstricks}{myfill}[]{\setkeys+[psset]{pstricks}{fillstyle=none}}
%\define@key[psset]{pstricks}{myfill}[]{\setkeys+[psset]{pstricks}{fillstyle=solid,fillcolor=red}}
\makeatother
\begin{document}
\begin{pspicture}(0,0)(2,2)
\pscircle[fillstyle=none, linewidth=1mm](1,1){0.5}
\end{pspicture}
\begin{pspicture}(0,0)(2,2)
\pscircle[fillstyle=solid, fillcolor=red, linewidth=1mm](1,1){0.5}
\end{pspicture}
\begin{pspicture}(0,0)(2,2)
\pscircle[myfill, linewidth=1mm](1,1){0.5}
\end{pspicture}
\end{document}
切换评论后:
答案4
这是user232027 的解决方案用\protected@edef\@tempa{...}
代替\expanded{...}
。
我提出它只是因为旧的 TeX 引擎没有\expanded
。
尽管如此,我还是更喜欢user232027 的解决方案因为我的变体的一个缺点是您需要在可选参数内加倍哈希值。
(我不知道可选参数是否\pscircle
可以包含哈希。)
不像user232027 的解决方案所有参数都已扩展,我的变体仅扩展可选参数(如果存在)。
\documentclass{article}
\usepackage{pstricks}
\newif\ifBlackAndWhite
\BlackAndWhitefalse
\makeatletter
\newcommand\myCommand{%
\ifBlackAndWhite\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{fillstyle=none}{fillstyle=solid,fillcolor=red}%
}
\newcommand\ePScircle{\@ifnextchar[{\ePScircleOpt}{\pscircle}}%
\newcommand\ePScircleOpt[1][]{%
{\protected@edef\@tempa{#1}\expandafter}%
\expandafter\pscircle\expandafter[\expandafter{\@tempa}]%
}%
\makeatother
\begin{document}
\begin{pspicture}(0,0)(2,2)
\pscircle[fillstyle=none, linewidth=1mm](1,1){0.5}
\end{pspicture}
\begin{pspicture}(0,0)(2,2)
\pscircle[fillstyle=solid, fillcolor=red, linewidth=1mm](1,1){0.5}
\end{pspicture}
\BlackAndWhitetrue
\begin{pspicture}(0,0)(2,2)
\expanded{\noexpand\pscircle[\myCommand, linewidth=1mm](1,1){0.5}}
\end{pspicture}
\BlackAndWhitefalse
\begin{pspicture}(0,0)(2,2)
\expanded{\noexpand\pscircle[\myCommand, linewidth=1mm](1,1){0.5}}
\end{pspicture}
\BlackAndWhitetrue
\begin{pspicture}(0,0)(2,2)
\ePScircle[\myCommand, linewidth=1mm](1,1){0.5}
\end{pspicture}
\BlackAndWhitefalse
\begin{pspicture}(0,0)(2,2)
\ePScircle[\myCommand, linewidth=1mm](1,1){0.5}
\end{pspicture}
\end{document}
与 egreg 的方法类似您可以定义一个评估-switch 的键\ifBlackAndWhite
:
\documentclass{article}
\usepackage{pstricks}
\makeatletter
\newif\ifBlackAndWhite
\BlackAndWhitefalse
\define@key[psset]{pstricks}{myfill}[]{%
\ifBlackAndWhite\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\setkeys+[psset]{pstricks}{fillstyle=none}}%
{\setkeys+[psset]{pstricks}{fillstyle=solid,fillcolor=red}}%
}%
\makeatother
\begin{document}
\BlackAndWhitefalse
\begin{pspicture}(0,0)(2,2)
\pscircle[myfill, linewidth=1mm](1,1){0.5}
\end{pspicture}
\BlackAndWhitetrue
\begin{pspicture}(0,0)(2,2)
\pscircle[myfill, linewidth=1mm](1,1){0.5}
\end{pspicture}
\end{document}