如何实现一个常量声明宏来在前导码和 pspicture 中表现不同?

如何实现一个常量声明宏来在前导码和 pspicture 中表现不同?

下面的例子非常简单,只是为了以最简单的方式说明问题。

在此处输入图片描述

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

背景:

  1. 我必须使用beamer文档类来利用覆盖来创建分步动画。
  2. 我还必须使用它preview来获得紧密的输出。
  3. 使用beamerstandalone文档类别无法替代上述两个要求。
  4. 我必须同时在 TeX 世界和 PostScript 世界中定义常量。这些常量很可能由涉及三角学和对数的代数表达式定义。
  5. 如果可能的话,应该在序言中定义常量。
  6. preview会丢弃序言中定义的 PostScript 常量。这就是为什么\LoadConstants必须在pspicture环境中调用来处理此问题。
  7. \LoadConstants根据设计,应该只调用一次。
  8. 然而,有时我需要在 内定义额外的常量pspicture。调用\LoadConstants额外的常量会产生冗余,因为\LoadConstants它是由 连接起来的字符串组成的\pstVerb
  9. 我主要使用standalone文档类,因此\LoadConstants也可以在序言中调用。

目标:

  1. 我希望有一个\const足够智能的单一函数来检测它是在序言中还是内部调用pspicture
  2. \const在序言中调用时,它必须\LoadConstants通过连接相应的来做好准备\pstVerb
  3. 但是当\const在里面调用时pspicture,它只是\pstVerb在该位置调用。笔记:请小心,因为\pstVerb有一个尾随空格。
  4. 作为奖励,如果可以的话,请注入\LoadConstantspspicture环境中,这样我不需要\LoadConstants首先调用。
  5. 欢迎任何改进代码的想法!

答案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}

相关内容