下面的例子非常简单,只是为了以最简单的方式说明问题。
\documentclass{beamer}
\usepackage[nomessages]{fp}
% constants declarator
\def\LoadConstants{}% to load PostScript constants defined in the preamble
\newcommand\const[3][6]{%
\edef\temporary{trunc(#3}%
\expandafter\FPeval\csname#2\expandafter\endcsname
\expandafter{\temporary:#1)}%
\edef\LoadConstants{\LoadConstants
\noexpand\pstVerb{/#2 \csname#2\endcsname\space def}}%
\ignorespaces}
\usepackage{pstricks,multido}
\SpecialCoor
\usepackage[active,tightpage]{preview}
\PreviewEnvironment{pspicture}
\PreviewBorder=25pt\relax
\const{Side}{root(2,17)}% the square root of 17
\begin{document}
\begin{frame}
\begin{pspicture}(\Side,\Side)
\LoadConstants
\psframe(!Side dup)\pause
\multido{\i=0+30}{12}{%
\const{temp}{cos(\i*pi/180)}
\LoadConstants
\rput{\i}(!Side 2 div dup 2 copy temp mul add 3 1 roll \i\space sin mul add){\temp}\pause
}
\end{pspicture}
\end{frame}
\end{document}
背景:
- 我必须使用
beamer
文档类来利用覆盖来创建分步动画。 - 我还必须使用它
preview
来获得紧密的输出。 - 使用
beamer
和standalone
文档类别无法替代上述两个要求。 - 我必须同时在 TeX 世界和 PostScript 世界中定义常量。这些常量很可能由涉及三角学和对数的代数表达式定义。
- 如果可能的话,应该在序言中定义常量。
- 但
preview
会丢弃序言中定义的 PostScript 常量。这就是为什么\LoadConstants
必须在pspicture
环境中调用来处理此问题。 \LoadConstants
根据设计,应该只调用一次。- 然而,有时我需要在 内定义额外的常量
pspicture
。调用\LoadConstants
额外的常量会产生冗余,因为\LoadConstants
它是由 连接起来的字符串组成的\pstVerb
。 - 我主要使用
standalone
文档类,因此\LoadConstants
也可以在序言中调用。
目标:
- 我希望有一个
\const
足够智能的单一函数来检测它是在序言中还是内部调用pspicture
。 - 当
\const
在序言中调用时,它必须\LoadConstants
通过连接相应的来做好准备\pstVerb
。 - 但是当
\const
在里面调用时pspicture
,它只是\pstVerb
在该位置调用。笔记:请小心,因为\pstVerb
有一个尾随空格。 - 作为奖励,如果可以的话,请注入
\LoadConstants
到pspicture
环境中,这样我不需要\LoadConstants
首先调用。 - 欢迎任何改进代码的想法!
答案1
\documentclass{beamer}
\usepackage[nomessages]{fp}
% constants declarator
\def\LoadConstants{}% to load PostScript constants defined in the preamble
\newcommand\const[3][6]{%
\edef\temporary{trunc(#3}%
\expandafter\FPeval\csname#2\expandafter\endcsname
\expandafter{\temporary:#1)}%
\edef\LoadConstants{\LoadConstants
\noexpand\pstVerb{/#2 \csname#2\endcsname\space def}}}
\usepackage{pstricks,multido}
\SpecialCoor
\usepackage[active,tightpage]{preview}
\PreviewEnvironment{pspicture}
\PreviewBorder=25pt\relax
\makeatletter
\def\pst@@picture@i[#1]#2(#3,#4){%
\renewcommand\const[3][6]{%
\edef\temporary{trunc(##3}%
\expandafter\FPeval\csname##2\expandafter\endcsname\expandafter{\temporary:##1)}%
\pstVerb{/##2 \csname##2\endcsname\space def}\ignorespaces}%
\@ifnextchar(% ignore anything between [] and ()
{\pst@@@picture[#1](#3,#4)\LoadConstants}%
{\pst@@@picture[#1](0,0)(#3,#4)\LoadConstants}}
\makeatother
\const{Side}{root(2,17)}% the square root of 17
\begin{document}
\begin{frame}
\begin{pspicture}(\Side,\Side)
\psframe(!Side dup)\pause
\multido{\i=0+30}{12}{%
\const{temp}{cos(\i*pi/180)}
\rput{\i}(!Side 2 div dup 2 copy temp mul add 3 1 roll \i\space sin mul add){\temp}\pause
}
\end{pspicture}
\end{frame}
\end{document}