我想将一个宏传递给一个showgrid
键。该宏可以稍后重新定义。其可能值为top
、bottom
、false
、true
。
以下 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}