pstricks 参数内的宏

pstricks 参数内的宏

我想创建一个命令,以便轻松地将彩色图片转换为黑白图片。为此,我想将\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见下文)。对于更复杂的命令,这并不那么容易。这就是为什么您可能需要考虑切换到 TiZ,风格可以轻松完成所有这些。

\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}

在此处输入图片描述

相关内容