如何解析没有 keyval 的可选参数?

如何解析没有 keyval 的可选参数?

当前实现仅支持使用可选参数中的指定数字进行舍入。

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

客观的:

我想让\const它的行为如下。如果我们调用

  • \const[4,r]{...}{...},后面会用到round4位数字。
  • \const[4,t]{...}{...},后面会用到trunc4位数字。
  • \const[c]{...}{...},它将用来clip修剪所有尾随零

欢迎任何改进代码的想法!

答案1

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

产生一个日志

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

\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

答案2

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

在此处输入图片描述

类似的空洞论点\const[]{...也是可能的。

这里与键/值语法相同:

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

在此处输入图片描述

相关内容