如何将宏作为键的值传递?

如何将宏作为键的值传递?

我想将一个宏传递给一个showgrid键。该宏可以稍后重新定义。其可能值为topbottomfalsetrue

以下 MWE 产生空白页。如何修复?

\documentclass[border=12pt,pstricks]{standalone}
\usepackage{pstricks}

\def\status{true}

\begin{document}

\begin{pspicture}[showgrid=\status](3,3)
\end{pspicture}

\end{document}

答案1

原因在于键的定义。键的值未展开,导致测试失败。您可以使用以下重新定义:

\makeatletter
\define@key[psset]{pstricks}{showgrid}[b]{\expandafter\pst@@showgrid#1\@nil}
\makeatother

上面的扩展只能起作用一次。要扩展键的值,您可以使用:

\makeatletter
\define@key[psset]{pstricks}{showgrid}[b]{\begingroup\edef\x{\endgroup\noexpand\pst@@showgrid#1\noexpand\@nil}\x}
\makeatother

这里是例子:

\documentclass[border=12pt,pstricks]{standalone}
\usepackage{pstricks}

\def\status{true}
\makeatletter
\define@key[psset]{pstricks}{showgrid}[b]{\expandafter\pst@@showgrid#1\@nil}
\makeatother

\begin{document}
\def\status{true}
\begin{pspicture}[showgrid=\status](3,3)
\end{pspicture}

\end{document}

答案2

不同于鍵盤, 这键值包没有提供扩展键值的规定\setkeys。但是,Marco Daniel 的解决方案针对特定键,因此不适用于其他键,即使在 pstricks 中也不适用。这是一个通用解决方案,我改编自键盘阅读器适合现有代码的包键值。这个想法是使用指针来指示用户想要(全部或部分)扩展某个键的值的愿望。

\documentclass{article}
\usepackage{pstricks}

\makeatletter
\def\XKV@s@tkeys#1#2{%
  \XKV@sp@deflist\XKV@na{#2}%
  \XKV@for@n{#1}\CurrentOption{%
    \XKV@expandvalueasneeded
    \expandafter\XKV@s@tk@ys\CurrentOption==\@nil
  }%
}
\def\XKV@expandvalueasneeded{%
  \begingroup
  \def\reserved@a##1##2\@nil##3{%
    \def\reserved@a####1##1####2####3\@nil{%
      \ifx\@nnil####2\else
        \edef\CurrentOption{##3=####2{##2}}%
      \fi
    }%
    \reserved@a
    \expanded\@iden\expandonce{\unexpanded\expandafter}%
    ##1\@nnil\@nil
  }%
  \def\reserved@b##1=##2=##3\@nil{%
    \if\relax\detokenize{##2}\relax\else
      \reserved@a##2\@nil{##1}%
    \fi
  }%
  \expandafter\reserved@b\CurrentOption==\@nil
  \edef\x{\endgroup\edef\noexpand\CurrentOption
    {\noexpand\unexpanded{\unexpanded\expandafter{\CurrentOption}}}}\x
}
\makeatother

\begin{document}
\def\status{true}
\def\sstatus{\status}

\newpsstyle{gridstyle}{subgriddiv=2}
\begin{pspicture}[showgrid=\expandonce{\status}](-1,0)(2,2)
%\begin{pspicture}[showgrid=\expanded{\sstatus}](-1,0)(2,2)
\end{pspicture}

\end{document}

在这个网站上,我看到有人尝试使用定义为宏的键。所以这里有一个解决方案,甚至可以接受宏作为键。

\documentclass{article}
\usepackage{pstricks}

\makeatletter
\def\XKV@g@tkeyname#1=#2\@nil#3{%
  \XKV@ifcmd{#1}\savevalue#3{%
    \XKV@rkvtrue\XKV@sgfalse
  }{%
    \XKV@ifcmd{#1}\gsavevalue#3{%
      \XKV@rkvtrue\XKV@sgtrue
    }{%
      \XKV@rkvfalse\XKV@sgfalse
    }%
  }%
  \expandafter\XKV@ifcmd\expandafter{#3}\xkvexpanded#3{%
    \edef#3{#3}%
  }{%
     \expandafter\XKV@ifcmd\expandafter{#3}\xkvexpandonce#3{%
       \edef#3{\unexpanded\expandafter{#3}}%
     }{}%
  }%
}
\def\XKV@s@tkeys#1#2{%
  \XKV@sp@deflist\XKV@na{#2}%
  \XKV@for@n{#1}\CurrentOption{%
    \begingroup
    \@tempcnta\z@
    \XKV@expandkvasneeded
    \edef\x{\endgroup\edef\noexpand\CurrentOption
      {\noexpand\unexpanded{\unexpanded\expandafter{\CurrentOption}}}}\x
    \expandafter\XKV@s@tk@ys\CurrentOption==\@nil
  }%
}
\def\XKV@expandkvasneeded{%
  \def\reserved@a##1##2\@nil##3{%
    \def\reserved@a####1##1####2####3\@nil{%
      \ifx\@nnil####2\else
        \ifnum\@tempcnta=\z@
          \edef\CurrentOption{####2{##2}=\unexpanded{##3}}%
        \else
          \edef\CurrentOption{##3=####2{##2}}%
        \fi
      \fi
    }%
    \reserved@a
    \xkvexpanded\@iden\xkvexpandonce{\unexpanded\expandafter}##1\@nnil\@nil
  }%
  \def\reserved@b##1=##2=##3\@nil{%
    \ifnum\@tempcnta=\z@
      \reserved@a##1\@nil{##2}%
    \else
      \if\relax\detokenize{##2}\relax\else
        \reserved@a##2\@nil{##1}%
      \fi
    \fi
  }%
  \expandafter\reserved@b\CurrentOption==\@nil
  \ifnum\@tempcnta=\@ne\else
    \@tempcnta\@ne
    \expandafter\XKV@expandkvasneeded
  \fi
}
\let\xkvexpanded\relax
\let\xkvexpandonce\relax
\makeatother

\begin{document}
\def\status{true}
\def\sstatus{\status}
\def\showgrid{showgrid}

\newpsstyle{gridstyle}{subgriddiv=2}
\begin{pspicture}[\xkvexpanded{\showgrid}=\xkvexpandonce{\status}](-1,0)(2,2)
%\begin{pspicture}[showgrid=\xkvexpanded{\sstatus}](-1,0)(2,2)
\end{pspicture}
\end{document}

相关内容