Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

The current implementation only supports rounding with the specified digits in the optional arguments.

\documentclass{beamer}
\usepackage{multido}
\usepackage{pstricks}
\usepackage[nomessages]{fp}

% \pstVerb concatenator
\def\LoadConstants{}

% Constant declarator invoked in the preamble
\newcommand\const[3][]{%
    \if\relax\detokenize{#1}\relax
        \edef\temporary{#3}%
    \else
        \edef\temporary{round(#3:#1)}%
    \fi
    \expandafter\FPeval\csname#2\expandafter\endcsname
        \expandafter{\expandafter{\temporary}}%
    \toks0=\expandafter{\LoadConstants\pstVerb}
    \edef\LoadConstants{\the\toks0 {/#2 \csname#2\endcsname\space def}}}

\makeatletter
\def\pst@@picture@i[#1]#2(#3,#4){%
% BEGIN - redefine \const for invocation inside pspicture
    \renewcommand\const[3][]{%
    \if\relax\detokenize{##1}\relax
        \edef\temporary{##3}%
    \else
        \edef\temporary{round(##3:##1)}%
    \fi
    \expandafter\FPeval\csname##2\expandafter\endcsname
        \expandafter{\expandafter{\temporary}}%
        \pstVerb{/##2 \csname##2\endcsname\space def}\ignorespaces}%
% END - redefine \const for invocation inside pspicture
    \@ifnextchar(% ignore anything between [] and ()
% BEGIN - inject \LoadConstants into pspicture
    {\pst@@@picture[#1](#3,#4)\LoadConstants}%
    {\pst@@@picture[#1](0,0)(#3,#4)\LoadConstants}%
% END - inject \LoadConstants into pspicture    
}
\makeatother

\usepackage[active,tightpage]{preview}
\PreviewEnvironment{pspicture}
\PreviewBorder=25pt\relax


\SpecialCoor
\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[5]{temp}{cos(\i*pi/180)}
        \rput{\i}(!Side 2 div dup dup \i\space PtoC 3 1 roll add 3 1 roll add){$\temp$}\pause
    }
\end{pspicture}
\end{frame}
\end{document}

Objective:

I want to make \const behave as follows. If we invoke

  • \const[4,r]{...}{...}, it will use round with 4 digits after .
  • \const[4,t]{...}{...}, it will use trunc with 4 digits after .
  • \const[c]{...}{...}, it will use clip to trim all trailing zeros

Any idea to improve the code is welcome!

share|improve this question
    
What will happen if the input is \const[3]{...}{...} –  Marco Daniel Apr 27 '13 at 11:02
    
@MarcoDaniel: It is not allowed. –  Who is crazy first Apr 27 '13 at 11:14
    
Then you want two optional arguments. If you use pstricks you already have available a key-value syntax; why not exploiting it? –  egreg Apr 27 '13 at 12:54
    
@egreg: I have not learnt it yet. :-) –  Who is crazy first Apr 27 '13 at 12:55

2 Answers 2

up vote 6 down vote accepted
\def\zzA#1,#2#3\relax#4{
\if t#2 trunc(#4:#1)%
\else\if r#2 round(#4:#1)%
\else clip(#4)%
\fi\fi}

% Constant declarator invoked in the preamble
\newcommand\const[3][]{%
    \if\relax\detokenize{#1}\relax
        \edef\temporary{#3}%
    \else
        \edef\temporary{\zzA#1,c\relax{#3}}%
\wlog{::\temporary}%
    \fi
    \expandafter\FPeval\csname#2\expandafter\endcsname
        \expandafter{\expandafter{\temporary}}%
    \toks0=\expandafter{\LoadConstants\pstVerb}
    \edef\LoadConstants{\the\toks0 {/#2 \csname#2\endcsname\space def}}}

produces a log of

::  trunc(root(2,17):4)
::  round(root(2,17):4)
:: clip(root(2,17))

from

\const{Side}{root(2,17)}% the square root of 17
\const[4,t]{Side}{root(2,17)}% the square root of 17
\const[4,r]{Side}{root(2,17)}% the square root of 17
\const[c]{Side}{root(2,17)}% the square root of 17
share|improve this answer
    
+1 I am trying to apply it. –  Who is crazy first Apr 27 '13 at 11:27
    
What is #3 for in \zzA? –  Who is crazy first Apr 27 '13 at 11:40
    
What does \const[4]{Side}{root(2,17)} do? It should throw an error. –  Who is crazy first Apr 27 '13 at 16:03
    
@Bugbusters errors are tricky as I'm inside the edef, so currently it checks for r and t and then teh \else clause for clip picks up everything else. You could test for clip explicitly and then have an else clause that did unknwnfunction(..) so that would then generate an error later but I'm not sure taht is better, as it would error in the Postscript rather than tex. –  David Carlisle Apr 27 '13 at 16:19
    
Error should be in TeX such that it automatically stops the next compilation with GhostScript. –  Who is crazy first Apr 27 '13 at 16:31
\documentclass{minimal}
\parindent=0pt    
\usepackage{pstricks}
\usepackage[nomessages]{fp}

\def\LoadConstants{}    
\makeatletter
\def\const{\@ifnextchar[\const@i{\const@i[r]}}
\def\const@i[#1]{\expandafter\const@ii#1,,\@nil}
\def\const@ii#1,#2,#3\@nil#4#5{%
  \if\relax\detokenize{#2}\relax 
    \if\relax\detokenize{#1}\relax \expandafter\const@iii\expandafter{#5}{#4}%
    \else
      \pst@isnum{#1}%
        {>>> Wrong Parameter '#1' \@namedef{#4}{}}
        {\ifx#1c \expandafter\const@iii\expandafter{clip(#5)}{#4}%
         \else   \expandafter\const@iii\expandafter{#5}{#4}%
         \fi}%
    \fi%
  \else%
    \ifx#2t  \expandafter\const@iii\expandafter{trunc(#5:#1)}{#4}%
    \else
      \ifx#2c\expandafter\const@iii\expandafter{clip(#5}{#4}%
      \else  \expandafter\const@iii\expandafter{round(#5:#1)}{#4}%
      \fi%
    \fi%
  \fi%
}
\def\const@iii#1#2{%
    \expandafter\FPeval\csname#2\expandafter\endcsname\expandafter{\expandafter{#1}}%
    \toks0=\expandafter{\LoadConstants\pstVerb}
    \edef\LoadConstants{\the\toks0 {/#2 \csname#2\endcsname\space def}}}
\makeatother

\begin{document}
\const{Side}{root(2,17)} \Side \\
\const[c]{Side}{root(2,17)} \Side \\
\const[4]{Side}{root(2,17)} \Side \\
\const[r]{Side}{root(2,17)} \Side\\
\const[6,r]{Side}{root(2,17)} \Side\\
\const[6,t]{Side}{root(2,17)} \Side
\end{document}

enter image description here

An empty argument like \const[]{... is also possible.

And here the same with the key/value syntax:

\documentclass{minimal}
\parindent=0pt
\usepackage{pstricks}
\usepackage[nomessages]{fp}

\def\LoadConstants{}
\makeatletter
\define@key[psset]{}{Roundtype}[round]{\expandafter\pst@@Roundtype#1\@nil}%
\def\pst@@Roundtype#1#2\@nil{%
  \ifx#1t \def\psk@Roundtype{trunc}%
    \else\ifx#1c \def\psk@Roundtype{clip}\else\def\psk@Roundtype{round}%
  \fi\fi}
\define@key[psset]{}{Decimals}[-1]{\pst@getint{#1}\psk@Decimals}%
\psset{Roundtype,Decimals}
\def\pst@RT@c{clip}

\def\const{\def\pst@par{}\pst@object{const}}
\def\const@i#1#2{%
  \use@par%
  \ifx\psk@Roundtype\pst@RT@c
    \expandafter\const@ii\expandafter{clip(#2)}{#1}
  \else
    \ifnum\psk@Decimals<1\relax
      \expandafter\const@ii\expandafter{#2}{#1}%
    \else
      \expandafter\const@ii\expandafter{\psk@Roundtype(#2:\psk@Decimals)}{#1}%
    \fi%
  \fi%
}

\def\const@ii#1#2{%
    \expandafter\FPeval\csname#2\expandafter\endcsname\expandafter{\expandafter{#1}}%
    \toks0=\expandafter{\LoadConstants\pstVerb}
    \edef\LoadConstants{\the\toks0 {/#2 \csname#2\endcsname\space def}}}
\makeatother

\begin{document}
\const{Side}{root(2,17)} \Side \\
\const[Roundtype=c]{Side}{root(2,17)} \Side \\
\const[Decimals=4]{Side}{root(2,17)} \Side \\
\const[Roundtype=r]{Side}{root(2,17)} \Side\\
\const[Decimals=6,Roundtype=r]{Side}{root(2,17)} \Side\\
\const[Decimals=6,Roundtype=t]{Side}{root(2,17)} \Side\\
\const[]{Side}{root(2,17)} \Side
\end{document}

enter image description here

share|improve this answer
    
Could you make the compilation in TeX phase terminated with an error message when invoking \const[4]{Side}{root(2,17)}? –  Who is crazy first Apr 27 '13 at 13:18
    
\@pstrickserr{Invalid argument!}\@ehpb –  Herbert Apr 27 '13 at 13:35
    
The key/value version behaves strange, for example: (1) \const{}{} should produce 18 digits after period. (2) \const[Roundtype=c,Decimals=4] does not make sense. –  Who is crazy first Apr 27 '13 at 13:42
    
then set the default to 18 digits. Where is the ptoblem?? I have no idea what makes sense or not. I do not use the fp package for that! –  Herbert Apr 27 '13 at 13:56
    
How to set the default to 18? I don't think it is possible because it will throw an error. Only 17 is the max when using trunc and round. –  Who is crazy first Apr 27 '13 at 15:11

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.