summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex')
-rw-r--r--Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex970
1 files changed, 970 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex
new file mode 100644
index 00000000000..3d69d34b73c
--- /dev/null
+++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex
@@ -0,0 +1,970 @@
+% Copyright 2007 Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+% This file parses/evaluates a decimal expression.
+%
+% Version 1.414213 29/9/2007
+
+% \pgfmathparse, \pgfmathqparse
+%
+% Evaluates a decimal expression.
+%
+% #1 - the expression.
+%
+% returns
+%
+% x = the result as a dimension.
+%
+% E.g.
+% \pgfmathparse{3pt*2cm+1.5}
+% \pgfmathqparse{3pt*2cm+1.5pt}
+%
+% Every number in \pgfmathqparse *must*
+% specify a unit.
+%
+\newif\ifpgfmath@quickparse
+
+\def\pgfmathparse{%
+ \pgfmath@quickparsefalse%
+ \pgfmathparse@}
+
+\def\pgfmathqparse{%
+ \pgfmath@quickparsetrue%
+ \pgfmathparse@}
+
+\def\pgfmath@calcreal#1{#1}%
+\def\pgfmath@calcminof#1#2{min(#1,#2)}%
+\def\pgfmath@calcmaxof#1#2{max(#1,#2)}%
+\def\pgfmath@calcratio#1#2{#1/#2}%
+
+\def\pgfmathparse@#1{%
+ \begingroup%
+ % Reinstall correct font, so that dimensions like 1em are correct
+ \pgfmath@selectfont%
+ \let\real\pgfmath@calcreal%
+ \let\minof\pgfmath@calcminof%
+ \let\maxof\pgfmath@calcmaxof%
+ \let\ratio\pgfmath@calcratio%
+ \edef\pgfmath@temp{#1}%
+ \pgfmath@resetparsingparameters%
+ \global\pgfmathunitsdeclaredfalse%
+ \ifpgfmath@quickparse%
+ \let\pgfmath@parseoperand\pgfmath@quickparseoperand%
+ \else%
+ \let\pgfmath@parseoperand\pgfmath@parseoperand%
+ \fi%
+ \let\pgfmath@parsepostgroup\pgfmath@parseoperator%
+ \expandafter\pgfmath@parse@\pgfmath@temp @@@@@@@@@@@\pgfmath@empty}
+
+
+% \pgfmath@resetparsingparameters
+%
+% Reset the stack at the begining of the parse/group.
+%
+\def\pgfmath@resetparsingparameters{%
+ \pgfmath@stack{\pgfmath@empty\pgfmath@empty\pgfmath@empty\pgfmath@empty}%
+ \def\pgfmath@stacknextoperator{\pgfmath@empty}% Will not work with \let
+}
+% \pgfmath@parse@
+%
+% Start parsing. Expect one of
+% 1) the end of the parse
+% 2) the start of a group
+% 3) a (possible) operand.
+%
+\def\pgfmath@parse@#1{%
+ \def\pgfmath@token{}%
+ \ifx#1@%
+ \let\pgfmath@parsenext\pgfmath@endparse%
+ \else%
+ \ifx#1(%
+ \let\pgfmath@parsenext\pgfmath@startparsegroup%
+ \else%
+ \edef\pgfmath@token{#1}%
+ \let\pgfmath@parsenext\pgfmath@parseoperand%
+ \fi\fi%
+ \pgfmath@parsenext%
+}
+
+% If no TeX units are declared *at any point* in the parse
+% the result is scaled by \pgfmathresultunitscale.
+\newif\ifpgfmathunitsdeclared
+\def\pgfmathsetresultunitscale#1{\def\pgfmathresultunitscale{#1}}
+\def\pgfmathresultunitscale{1}
+
+% \pgfmath@endparse
+%
+% Everything stops here.
+%
+\def\pgfmath@endparse#1\pgfmath@empty{%
+ \pgfmath@processalloperations%
+ \pgfmath@stackpop{\pgfmathresult}%
+ \begingroup%
+ \ifpgfmathunitsdeclared%
+ \pgfmath@x1pt\relax%
+ \else%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \pgfmath@x\pgfmathresultunitscale pt\relax\pgfmath@%
+ \fi%
+ \expandafter\pgfmath@x\pgfmathresult\pgfmath@x%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+ \pgfmath@smuggleone{\pgfmathresult}%
+ \endgroup%
+ \ignorespaces%
+}
+
+% \pgfmath@startparsegroup
+%
+% When opening ( is scanned start a new group.
+%
+\def\pgfmath@startparsegroup{%
+ \begingroup%
+ \let\pgfmath@parsepostgroup\pgfmath@parseoperator%
+ \pgfmath@resetparsingparameters%
+ \pgfmath@parse@}
+
+% \pgfmath@endparsegroup
+%
+% When closing ) is scanned, processes all waiting
+% operations (within the group) and close the group.
+%
+\def\pgfmath@endparsegroup{%
+ \pgfmath@processalloperations%
+ \pgfmath@stackpop{\pgfmathresult}%
+ \expandafter\pgfmath@x\pgfmathresult pt\relax%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+ \pgfmath@parsepostgroup%
+}
+
+% \pgfmath@parseoperator
+%
+% An operator is expected here.
+% Or the end of the parse or parse group.
+%
+\def\pgfmath@parseoperator#1{%
+ \def\pgfmath@token{}%
+ % Push the operand in \pgfmathresult on to the stack.
+ \expandafter\pgfmath@stackpushoperand\expandafter{\pgfmathresult}%
+ \ifx#1@%
+ \let\pgfmath@parsenext\pgfmath@endparse%
+ \else%
+ \ifx#1+%
+ \let\pgfmath@parsenext\pgfmath@parseadd%
+ \else%
+ \ifx#1-%
+ \let\pgfmath@parsenext\pgfmath@parsesubtract%
+ \else%
+ \ifx#1*%
+ \let\pgfmath@parsenext\pgfmath@parsemultiply%
+ \else%
+ \ifx#1/%
+ \let\pgfmath@parsenext\pgfmath@parsedivide%
+ \else
+ \ifx#1)%
+ \let\pgfmath@parsenext\pgfmath@endparsegroup%
+ \else%
+ \ifx#1r%
+ \let\pgfmath@parsenext\pgfmath@parseradians%
+ \else%
+ \ifx#1>%
+ \let\pgfmath@parsenext\pgfmath@parsegreaterthan%
+ \else%
+ \ifx#1<%
+ \let\pgfmath@parsenext\pgfmath@parselessthan%
+ \else%
+ \if#1=%
+ \let\pgfmath@parsenext\pgfmath@parseequalto%
+ \else%
+ \if#1^%
+ \let\pgfmath@parsenext\pgfmath@parsepower%
+ \else%
+ \pgfmath@error{Unknown operator `#1'}%
+ \let\pgfmath@parsenext\relax%
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi%
+ \pgfmath@parsenext%
+}
+
+% Use a \toks register as a stack.
+\newtoks\pgfmath@stack
+
+% \pgfmath@stackpushoperator
+%
+% Push an operator (actually its macro e.g., \pgfmathadd@)
+% on to the stack. And keep track of it using the macro
+% \pgfmath@stacknextoperator.
+%
+\def\pgfmath@stackpushoperator#1{%
+ \edef\pgfmath@temp{\noexpand#1\the\pgfmath@stack}%
+ \expandafter\pgfmath@stack\expandafter{\pgfmath@temp}%
+ \def\pgfmath@stacknextoperator{#1}}% <- Must \def. Cannot \let.
+
+% \pgfmath@stackpushoperand
+%
+% Push an operand (i.e. a number) on the stack. It is
+% put within a TeX group to make popping a lot simpler.
+%
+\def\pgfmath@stackpushoperand#1{%
+ \edef\pgfmath@temp{{#1}\the\pgfmath@stack}%
+ \expandafter\pgfmath@stack\expandafter{\pgfmath@temp}%
+}
+
+% \pgfmath@stackpeek
+%
+% Peek (i.e. without removal) at the top of the stack.
+%
+\def\pgfmath@stackpeek{\expandafter\pgfmath@stackpeek@\the\pgfmath@stack\pgfmath@}
+\def\pgfmath@stackpeek@#1#2\pgfmath@{#1}%
+
+% \pgfmath@stackpop
+%
+% Pop (i.e. remove) the top of the stack into #1.
+%
+\def\pgfmath@stackpop#1{\expandafter\pgfmath@stackpop@\expandafter#1\the\pgfmath@stack\pgfmath@}
+\def\pgfmath@stackpop@#1#2#3\pgfmath@{\edef#1{#2}\pgfmath@stack{#3}}%
+
+% \pgfmath@stackpopoperation
+%
+% Remove and perform an operation from the stack.
+%
+\def\pgfmath@stackpopoperation{%
+ \expandafter\pgfmath@stackpopoperation@\the\pgfmath@stack\pgfmath@%
+}
+\def\pgfmath@stackpopoperation@#1#2#3#4#5\pgfmath@{%
+ \ifx\pgfmath@empty#1\relax%
+ \pgfmath@stack{\pgfmath@empty\pgfmath@empty\pgfmath@empty\pgfmath@empty}%
+ \else%
+ \ifx\pgfmath@empty#2\relax%
+ \pgfmath@stack{{#1}\pgfmath@empty\pgfmath@empty\pgfmath@empty\pgfmath@empty}%
+ \else%
+ #2{#3}{#1}%
+ \pgfmath@stack{#4#5}%
+ \expandafter\pgfmath@stackpushoperand\expandafter{\pgfmathresult}%
+ \fi\fi%
+ \def\pgfmath@stacknextoperator{#4}}
+
+% \pgfmath@processalloperations
+%
+% Process all operation in the stack. The
+% overall result is at the top of the stack.
+%
+\def\pgfmath@processalloperations{%
+ \expandafter\pgfmath@in@\pgfmath@stacknextoperator{\pgfmath@empty}%
+ \ifpgfmath@in@%
+ \let\pgfmath@processnext\relax%
+ \else%
+ \pgfmath@stackpopoperation%
+ \let\pgfmath@processnext\pgfmath@processalloperations%
+ \fi%
+ \pgfmath@processnext}
+
+% \pgfmath@processoperationsuntil
+%
+% Process operations in the stack, until the specified
+% operation/s is/are encountered. The overall result is
+% at the top of the stack.
+%
+\def\pgfmath@processoperationsuntil#1{%
+ \expandafter\pgfmath@in@\pgfmath@stacknextoperator{#1\pgfmath@empty}%
+ \ifpgfmath@in@%
+ \let\pgfmath@processnext\pgfmath@processoperationsuntil@end%
+ \else%
+ \pgfmath@stackpopoperation%
+ \let\pgfmath@processnext\pgfmath@processoperationsuntil%
+ \fi%
+ \pgfmath@processnext{#1}}
+\def\pgfmath@processoperationsuntil@end#1{}
+
+
+% OK. Now the operators are parsed.
+% These correspond to the + - / * ^ < > = operators and r (postfix) function.
+%
+\def\pgfmath@parseadd{%
+ % If no operator has been assigned (i.e. + is the first operator scanned),
+ % do nothing, except add addition to the stack.
+ \ifx\pgfmath@stacknextoperator\pgfmath@empty%
+ \else%
+ % Empty the process stack up to any inequalities.
+ \pgfmath@processoperationsuntil{\pgfmathequalto@\pgfmathlessthan@\pgfmathgreaterthan@}%
+ \fi%
+ \pgfmath@stackpushoperator{\pgfmathadd@}%
+ \pgfmath@parse@}
+
+\def\pgfmath@parsesubtract{%
+ % If no operator has been assigned (i.e. - is the first operator scanned),
+ % do nothing, except add subtract to the stack.
+ \ifx\pgfmath@stacknextoperator\pgfmath@empty%
+ \else%
+ % Empty the process stack up to any inequalities.
+ \pgfmath@processoperationsuntil{\pgfmathequalto@\pgfmathlessthan@\pgfmathgreaterthan@}%
+ \fi%
+ \pgfmath@stackpushoperator{\pgfmathsubtract@}%
+ \pgfmath@parse@}
+
+\def\pgfmath@parsemultiply{%
+ % If no operator has been assigned (i.e. * is the first operator scanned),
+ % do nothing, except push multiply onto the stack.
+ \ifx\pgfmath@stacknextoperator\pgfmath@empty%
+ \else%
+ % Process all operations up to inequalites or addition/subtraction
+ \pgfmath@processoperationsuntil{\pgfmathequalto@\pgfmathlessthan@\pgfmathgreaterthan@%
+ \pgfmathadd@\pgfmathsubtract@}%
+ \fi%
+ \pgfmath@stackpushoperator{\pgfmathmultiply@}%
+ \pgfmath@parse@}
+
+\def\pgfmath@parsedivide{%
+ % If no operator has been assigned (i.e. / is the first operator scanned),
+ % do nothing, except push divide onto the stack.
+ \ifx\pgfmath@stacknextoperator\pgfmath@empty%
+ \else%
+ % Process all operations up to inequalites or addition/subtraction
+ \pgfmath@processoperationsuntil{\pgfmathequalto@\pgfmathlessthan@\pgfmathgreaterthan@%
+ \pgfmathadd@\pgfmathsubtract@}%
+ \fi%
+ \pgfmath@stackpushoperator{\pgfmathdivide@}%
+ \pgfmath@parse@}
+
+\def\pgfmath@parsegreaterthan{%
+ % On scanning an equality/inequality operator everything up to
+ % (but not including) the operator is evaluated...
+ \pgfmath@processalloperations%
+ % ...and the operation pushed onto the stack.
+ \pgfmath@stackpushoperator{\pgfmathgreaterthan@}%
+ \pgfmath@parse@}
+
+\def\pgfmath@parselessthan{%
+ \pgfmath@processalloperations%
+ \pgfmath@stackpushoperator{\pgfmathlessthan@}%
+ \pgfmath@parse@}
+
+\def\pgfmath@parseequalto={%
+ \pgfmath@processalloperations%
+ \pgfmath@stackpushoperator{\pgfmathequalto@}%
+ \pgfmath@parse@}
+
+\def\pgfmath@parsepower{%
+ % Easy, just push power onto the stack.
+ \pgfmath@stackpushoperator{\pgfmathpow@}%
+ \pgfmath@parse@}
+
+\def\pgfmath@parseradians{%
+ % r is a post-fix function...
+ \ifx\pgfmath@primaryoperation\pgfmath@empty%
+ \else%
+ \pgfmath@processoperationsuntil{\pgfmathequalto@\pgfmathlessthan@\pgfmathgreaterthan@%
+ \pgfmathadd@\pgfmathsubtract@}%
+ \fi%
+ \pgfmath@stackpop{\pgfmath@temp}%
+ \pgfmathdeg@{\pgfmath@temp}%
+ % ...so processing returns to \pgfmath@parseoperator
+ \pgfmath@parseoperator}
+
+\newcount\c@pgfmath@parsecounta
+\newcount\c@pgfmath@parsecountb
+\newcount\c@pgfmath@parsecountc
+\newdimen\pgfmath@parsex
+
+% \pgfmath@quickparseoperand
+%
+% An operand can *only* be a dimension.
+%
+\def\pgfmath@quickparseoperand{%
+ \afterassignment\pgfmath@quickparseoperand@%
+ \pgfmath@parsex\pgfmath@token}
+\def\pgfmath@quickparseoperand@{%
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@parsex}}%
+ \pgfmath@parseoperator%
+}
+
+% \pgfmath@parseoperand
+%
+% An operand can be an ASCII number (with or without dimensions, with
+% or without a decimal point), a TeX register (count, dimen or skip,
+% which may have expanded with \the), or a function e.g. sin(X).
+%
+% It is assumed that after \edef-ing, the only unexpanded tokens are registers.
+%
+\def\pgfmath@parseoperand{%
+ \def\pgfmath@sign{}%
+ \expandafter\pgfmath@parseoperandsign\pgfmath@token}
+\def\pgfmath@parseoperandsign#1{%
+ \pgfmath@in@#1{-+}%
+ \ifpgfmath@in@
+ % Gobble multiple signs.
+ \edef\pgfmath@sign{\pgfmath@sign#1}%
+ \expandafter\pgfmath@parseoperandsign%
+ \else%
+ \expandafter\pgfmath@parsenumberorfunction\expandafter#1%
+ \fi%
+}
+
+\newif\ifpgfmath@dimen@
+
+\def\pgfmath@ifregisterdimen@#1\pgfmath@{%
+ \pgfmath@in@{p}{#1}%
+ \ifpgfmath@in@%
+ \pgfmath@dimen@true%
+ \else%
+ \pgfmath@dimen@false%
+ \fi}
+
+\def\pgfmath@parsenumberorfunction#1{%
+ \let\pgfmath@parsenext\pgfmath@parsenumberorfunction@simple%
+ \ifx#1\wd\let\pgfmath@parsenext\pgfmath@boxdimen\fi%
+ \ifx#1\ht\let\pgfmath@parsenext\pgfmath@boxdimen\fi%
+ \ifx#1\dp\let\pgfmath@parsenext\pgfmath@boxdimen\fi%
+ \pgfmath@parsenext#1%
+}
+
+\def\pgfmath@boxdimen#1#2{%
+ \pgfmath@parsex=\pgfmath@sign#1#2%
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@parsex}}%
+ \global\pgfmathunitsdeclaredtrue% a dimension has units
+ \pgfmath@parseoperator%
+}
+
+\def\pgfmath@parsenumberorfunction@simple#1{%
+ \expandafter\ifcat#1\relax%
+ % So, a TeX register.
+ \afterassignment\pgfmath@ifregisterdimen@%
+ \pgfmath@parsex\pgfmath@sign#1pt\relax\pgfmath@%
+ \ifpgfmath@dimen@%
+ % A dimension! So stop scanning operand here.
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@parsex}}%
+ \global\pgfmathunitsdeclaredtrue% a dimension has units
+ \def\pgfmath@temp{}%
+ \let\pgfmath@parsenext\pgfmath@parseoperator%
+ \else%
+ % A count! Expand it, but carry on as usual as it might
+ % be immediately followed by a dimension.
+ \ifdim\pgfmath@parsex<0pt\relax%
+ \edef\pgfmath@sign{\pgfmath@sign-}%
+ \pgfmath@parsex-\pgfmath@parsex%
+ \fi%
+ \edef\pgfmath@temp{\pgfmath@tonumber{\pgfmath@parsex}}%
+ \let\pgfmath@parsenext\pgfmath@parsenumberorfunction@%
+ \fi%
+ \else%
+ % Could be a number or a function...?
+ \edef\pgfmath@temp{#1}%
+ \let\pgfmath@parsenext\pgfmath@parsenumberorfunction@%
+ \fi%
+ \expandafter\pgfmath@parsenext\pgfmath@temp%
+}%
+
+\def\pgfmath@parsenumberorfunction@#1{%
+ \ifx#1(% It might be a group e.g. -(1+2)...
+ \let\pgfmath@parsenext\pgfmath@parseoperandgroup%
+ \else%
+ \pgfmath@in@{#1}{.0123456789}%
+ \ifpgfmath@in@% ... or a number...
+ \let\pgfmath@parsenext\pgfmath@parsenumber%
+ \else% ... or a function.
+ \let\pgfmath@parsenext\pgfmath@parsefunction%
+ \fi%
+ \fi%
+ \pgfmath@parsenext#1%
+}%
+
+\def\pgfmath@parseoperandgroup({%
+ \let\pgfmath@postparsegroup\pgfmath@@parseoperandgroup%
+ \pgfmath@startparsegroup%
+}
+
+\def\pgfmath@@parseoperandgroup{%
+ \let\pgfmath@postparsegroup\pgfmath@parseoperator%
+ \edef\pgfmathresult{\pgfmath@sign\pgfmathresult}%
+ \pgfmath@parseoperator%
+}
+
+\def\pgfmath@parsenumber{%
+ % Consider the number 3.14159
+ % 3 is parsed by assignment to a, then '.' is absorbed and 14159
+ % parsed by assignement to b (actually b=114159, see below).
+ \c@pgfmath@parsecountc0\relax%
+ \afterassignment\pgfmath@parsedecimalpoint%
+ \c@pgfmath@parsecounta0}
+
+\def\pgfmath@parsedecimalpoint#1{%
+ \ifx#1.% Is there a decimal point? If not, see if there are any units.
+ \let\pgfmath@parsenext\pgfmath@parsemantissa%
+ \else%
+ \c@pgfmath@parsecountb10\relax% The first digit of b is gobbled (see below).
+ \let\pgfmath@parsenext\pgfmath@parseunits%
+ \fi%
+ \pgfmath@parsenext#1}
+
+
+
+% We would like to assign the following number (which is the mantisse)
+% to a number. However, for a very long mantisse as in 3.141592653589793238462643
+% this will fail since the number becomes too large.
+%
+% Because of this, we have to do some ``magic'': We scan 9 tokens and
+% then do an assignment with a guard after 9 tokens so that the
+% assigment cannot fail.
+%
+\def\pgfmath@parsemantissa.#1#2#3#4#5#6#7#8#9{%
+ \afterassignment\pgfmath@checkforguard%
+ % Consider the number: 2.005
+ % 2 is assigned to a, but b will be assigned 5, which is *not right*.
+ % So using 1 here hereresults in b=1005. The first digit is then
+ % gobbled later, when expanded with \the.
+ \c@pgfmath@parsecountb1#1#2#3#4#5#6#7#8#9\relax}%
+
+\def\pgfmath@checkforguard{%
+ \pgfmath@ifnextchar\relax%
+ {%
+ % Ok, this is a looong mantisse. Start gobbling all following
+ % numbers
+ \pgfmath@gobblemantisse%
+ }%
+ {%
+ \pgfmath@removeguard%
+ }%
+}
+
+\def\pgfmath@gobblemantisse\relax#1#2#3#4#5#6#7#8#9{%
+ \afterassignment\pgfmath@checkforguard%
+ \c@pgfmath@parsecountc0#1#2#3#4#5#6#7#8#9\relax% these digits are ignored
+}
+
+\def\pgfmath@removeguard#1\relax{\pgfmath@parseunits#1}
+
+
+\def\pgfmath@parseunits#1{%
+ % Here the extra first digit in b is gobbled.
+ \edef\pgfmath@resulttemp{%
+ \pgfmath@sign\the\c@pgfmath@parsecounta.\expandafter\pgfmath@gobbleone\the\c@pgfmath@parsecountb}%
+ % Check whether #1 is a \dp, \wd, or \ht
+ \let\pgfmath@parsenext=\pgfmath@parseunits@simple%
+ \ifx#1\wd\let\pgfmath@parsenext=\pgfmath@parseunits@boxdimen\fi%
+ \ifx#1\ht\let\pgfmath@parsenext=\pgfmath@parseunits@boxdimen\fi%
+ \ifx#1\dp\let\pgfmath@parsenext=\pgfmath@parseunits@boxdimen\fi%
+ \pgfmath@parsenext#1%
+}
+
+\def\pgfmath@parseunits@boxdimen#1#2{%
+ \pgfmath@parsex=\pgfmath@sign#1#2%
+ \pgfmath@parsex\pgfmath@resulttemp\pgfmath@parsex%
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@parsex}}%
+ \global\pgfmathunitsdeclaredtrue% a dimension has units
+ \pgfmath@parseoperator%
+}
+
+\def\pgfmath@parseunits@simple#1{%
+ % Now check if #1 is actually a register.
+ \ifcat#1\relax%
+ \afterassignment\pgfmath@ifregisterdimen@%
+ \pgfmath@parsex#1pt\relax\pgfmath@%
+ \pgfmath@parsex\pgfmath@resulttemp\pgfmath@parsex%
+ \ifpgfmath@dimen@% If it's a dimen stop scanning operand here.
+ \global\pgfmathunitsdeclaredtrue% a dimension has units
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@parsex}}%
+ \let\pgfmath@parsenext\pgfmath@parseoperator%
+ \else
+ \edef\pgfmath@resulttemp{\pgfmath@tonumber{\pgfmath@parsex}}%
+ \let\pgfmath@parsenext\pgfmath@parseunits@%
+ \fi%
+ \expandafter\pgfmath@parsenext%
+ \else%
+ \expandafter\pgfmath@parseunits@\expandafter#1%
+ \fi}
+
+\def\pgfmath@parseunits@#1#2{%
+ % Check if #1 is an operator, or the character `@' indicating the end of the parse.
+ \pgfmath@in@#1{@+-*/^r<>=()}%
+ \ifpgfmath@in@%
+ \edef\pgfmath@tokens{#1#2}%
+ \edef\pgfmathresult{\pgfmath@resulttemp}%
+ \let\pgfmath@parsenext\pgfmath@parseoperator%
+ \else%
+ \pgfmath@in@#1{Ee}% e+0X
+ \ifpgfmath@in@%
+ % Oh no! It might be and em or an ex...
+ \pgfmath@in@#2{mx}%
+ \ifpgfmath@in@%
+ \global\pgfmathunitsdeclaredtrue%
+ \pgfmath@parsex\pgfmath@resulttemp#1#2\relax%
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@parsex}}%
+ \edef\pgfmath@tokens{}%
+ \let\pgfmath@parsenext\pgfmath@parseoperator%
+ \else%
+ \edef\pgfmath@tokens{#2}%
+ \let\pgfmath@parsenext\pgfmath@parsescientific%
+ \fi%
+ \else
+ % Anything else *should* be a TeX unit.
+ \global\pgfmathunitsdeclaredtrue%
+ \pgfmath@parsex\pgfmath@resulttemp#1#2\relax%
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@parsex}}%
+ \edef\pgfmath@tokens{}%
+ \let\pgfmath@parsenext\pgfmath@parseoperator%
+ \fi\fi%
+ \expandafter\pgfmath@parsenext\pgfmath@tokens%
+}
+
+% Parse 'Scientific' notation in the form xEyy
+%
+\def\pgfmath@parsescientific{%
+ \afterassignment\pgfmath@parsescientific@%
+ \c@pgfmath@parsecounta}
+
+\def\pgfmath@parsescientific@{%
+ \edef\pgfmath@parsesci@temp{\pgfmath@resulttemp\the\c@pgfmath@parsecountc}%
+ \expandafter\pgfmathscientific\expandafter{\pgfmath@parsesci@temp}%
+ {\the\c@pgfmath@parsecounta}%
+ \edef\pgfmath@resulttemp{\pgfmathresult}%
+ \pgfmath@parseunits@}
+
+% Functions parsed (not calculated) here are:
+%
+% round(X) 'half-up' rounding.
+% floor(X) floor function.
+% ciel(X) ceiling function.
+% abs(X) absolute function.
+%
+% exp(X) e^X (0 <= X <~= 9.7).
+% ln(X) logarithm of X.
+% pow(X,Y) X^Y,
+%
+% sin(X) sine function.
+% cos(X) cosine function.
+% tan(X) tan function.
+% asin(X) arcsine of X (in radians) -1 <= X <= 1
+% acos(X) arccosine of X (in radians) -1 <= X <= 1
+% atan(X) arctangent of X (in radians) -1 <= X <= 1
+% veclen(X,Y) the length Z where Z^2 = X^2 + Y^2
+% mod(X,Y) X modulo Y
+% max(X,Y) the maximum of X or Y
+% min(X,Y) the minimum of X or Y
+%
+% NB veclen, mod, max, and min *cannot* be nested.
+%
+% deg(X) converts X to degrees (X in radians)
+% rad(X) converts X to radians (X in degrees)
+%
+% rnd generate pseudo-random number X (0 <= X <= 1).
+% rand generate pseudo-random number X (1 <= X <= -1).
+% sqrt(X) square root.
+%
+% pi the constant PI.
+
+\def\pgfmath@parsefunction{%
+ \def\pgfmath@parsedfunctionname{}%
+ \futurelet\pgfmath@parsetoken\pgfmath@parsefunction@@}
+\def\pgfmath@parsefunction@@#1{%
+ \pgfmath@in@#1{()@+-*/^<>=}% A function name ends with one of these...
+ \ifpgfmath@in@%
+ \let\pgfmath@parsefunctionnext\pgfmath@parsefunction@end%
+ \else%
+ \ifx\pgfmath@parsetoken\pgfmath@sptoken% ...or a space.
+ \let\pgfmath@parsefunctionnext\pgfmath@parsefunction@end%
+ \else%
+ \let\pgfmath@parsefunctionnext\pgfmath@parsefunction@continue%
+ \fi\fi%
+ \pgfmath@parsefunctionnext#1}
+
+\def\pgfmath@parsefunction@end#1{%
+ \expandafter\ifx\csname pgfmath@parsefunction@\pgfmath@parsedfunctionname\endcsname\relax%
+ \pgfmath@reportunknownfunction%
+ \let\pgfmath@parsefunctionnext\relax%
+ \else%
+ \let\pgfmath@parsefunctionnext\pgfmath@executeparsefunction@%
+ \fi%
+ \pgfmath@parsefunctionnext#1}
+
+\def\pgfmath@parsefunction@continue#1{%
+ \edef\pgfmath@parsedfunctionname{\pgfmath@parsedfunctionname#1}%
+ \futurelet\pgfmath@parsetoken\pgfmath@parsefunction@@}
+
+\def\pgfmath@executeparsefunction@{\csname pgfmath@parsefunction@\pgfmath@parsedfunctionname\endcsname}
+
+
+\def\pgfmath@reportunknownfunction{%
+ \pgfmath@error{Unknown function `\pgfmath@parsedfunctionname'}{}%
+}
+
+% \pgfmath@postfunction
+%
+% In scanning a function e.g. sin(40), we subvert the normal parsing
+% group mechanism by messing around with \pgfmath@parsepostgroup, so
+% that after scanning ), the parser doesn't scan for an operator, but
+% returns to the macros scanning the function.
+% Here the mechanism is restored, and the value of the function is
+% stored along with the approprate sign, which was saved earlier.
+%
+\def\pgfmath@postfunction{%
+ \let\pgfmath@parsepostgroup\pgfmath@parseoperator%
+ \edef\pgfmathresult{\pgfmath@sign\pgfmathresult}%
+ \pgfmath@parseoperator}
+
+
+% \pgfmath@parsefunction@abs
+%
+\def\pgfmath@parsefunction@abs{%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@abs@%
+ \expandafter\pgfmath@parse@}
+\def\pgfmath@parsefunction@abs@{%
+ \expandafter\pgfmathabs@\expandafter{\pgfmathresult}%
+ \pgfmath@postfunction%
+}
+
+% \pgfmath@parsefunction@sqrt
+%
+\def\pgfmath@parsefunction@sqrt{%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@sqrt@%
+ \expandafter\pgfmath@parse@}
+\def\pgfmath@parsefunction@sqrt@{%
+ \expandafter\pgfmathsqrt@\expandafter{\pgfmathresult}%
+ \pgfmath@postfunction%
+}
+
+% \pgfmath@parsefunction@round
+%
+\def\pgfmath@parsefunction@round{%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@round@%
+ \expandafter\pgfmath@parse@}
+\def\pgfmath@parsefunction@round@{%
+ \expandafter\pgfmathround@\expandafter{\pgfmathresult}%
+ \pgfmath@postfunction%
+}
+
+% \pgfmath@parsefunction@floor
+%
+\def\pgfmath@parsefunction@floor{%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@floor@%
+ \expandafter\pgfmath@parse@}
+\def\pgfmath@parsefunction@floor@{%
+ \expandafter\pgfmathfloor@\expandafter{\pgfmathresult}%
+ \pgfmath@postfunction%
+}
+
+% \pgfmath@parsefunction@ceil
+%
+\def\pgfmath@parsefunction@ceil{%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@ceil@%
+ \expandafter\pgfmath@parse@}
+\def\pgfmath@parsefunction@ceil@{%
+ \expandafter\pgfmathceil@\expandafter{\pgfmathresult}%
+ \pgfmath@postfunction%
+}
+
+% \pgfmath@parsefunction@sin
+%
+\def\pgfmath@parsefunction@sin{%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@sin@%
+ \expandafter\pgfmath@parse@}
+\def\pgfmath@parsefunction@sin@{%
+ \expandafter\pgfmathsin@\expandafter{\pgfmathresult}%
+ \pgfmath@postfunction%
+}
+
+% \pgfmath@parsefunction@cos
+%
+\def\pgfmath@parsefunction@cos{%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@cos@%
+ \expandafter\pgfmath@parse@}
+\def\pgfmath@parsefunction@cos@{%
+ \expandafter\pgfmathcos@\expandafter{\pgfmathresult}%
+ \pgfmath@postfunction%
+}
+
+% \pgfmath@parsefunction@asin
+%
+\def\pgfmath@parsefunction@asin{%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@asin@%
+ \expandafter\pgfmath@parse@}
+\def\pgfmath@parsefunction@asin@{%
+ \expandafter\pgfmathasin@\expandafter{\pgfmathresult}%
+ \pgfmath@postfunction%
+}
+
+% \pgfmath@parsefunction@acos
+%
+\def\pgfmath@parsefunction@acos{%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@acos@%
+ \expandafter\pgfmath@parse@}
+\def\pgfmath@parsefunction@acos@{%
+ \expandafter\pgfmathacos@\expandafter{\pgfmathresult}%
+ \pgfmath@postfunction}
+
+% \pgfmath@parsefunction@atan
+%
+\def\pgfmath@parsefunction@atan{%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@atan@%
+ \expandafter\pgfmath@parse@}
+\def\pgfmath@parsefunction@atan@{%
+ \expandafter\pgfmathatan@\expandafter{\pgfmathresult}%
+ \pgfmath@postfunction%
+}
+
+% \pgfmath@parsefunction@tan
+%
+\def\pgfmath@parsefunction@tan{%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@tan@%
+ \expandafter\pgfmath@parse@}
+\def\pgfmath@parsefunction@tan@{%
+ \expandafter\pgfmathtan@\expandafter{\pgfmathresult}%
+ \pgfmath@postfunction%
+}
+
+% \pgfmath@parsefunction@cot
+%
+\def\pgfmath@parsefunction@cot{%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@cot@%
+ \expandafter\pgfmath@parse@}
+\def\pgfmath@parsefunction@cot@{%
+ \expandafter\pgfmathcot@\expandafter{\pgfmathresult}%
+ \pgfmath@postfunction%
+}
+
+% \pgfmath@parsefunction@sec
+%
+\def\pgfmath@parsefunction@sec{%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@sec@%
+ \expandafter\pgfmath@parse@}
+\def\pgfmath@parsefunction@sec@{%
+ \expandafter\pgfmathsec@\expandafter{\pgfmathresult}%
+ \pgfmath@postfunction%
+}
+
+% \pgfmath@parsefunction@cosec
+%
+\def\pgfmath@parsefunction@cosec{%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@cosec@%
+ \expandafter\pgfmath@parse@}
+\def\pgfmath@parsefunction@cosec@{%
+ \expandafter\pgfmathcosec@\expandafter{\pgfmathresult}%
+ \pgfmath@postfunction%
+}
+
+% \pgfmath@parsefunction@rad
+%
+\def\pgfmath@parsefunction@rad{%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@rad@%
+ \pgfmath@parse@}
+\def\pgfmath@parsefunction@rad@{%
+ \expandafter\pgfmathrad@\expandafter{\pgfmathresult}%
+ \pgfmath@postfunction}%
+
+% \pgfmath@parsefunction@rad
+%
+\def\pgfmath@parsefunction@deg{%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@deg@%
+ \expandafter\pgfmath@parse@}
+\def\pgfmath@parsefunction@deg@{%
+ \expandafter\pgfmathdeg@\expandafter{\pgfmathresult}%
+ \pgfmath@postfunction}%
+
+% \pgfmath@parsefunction@rnd
+%
+\def\pgfmath@parsefunction@rnd{%
+ \expandafter\pgfmathrnd%
+ \expandafter\pgfmath@postfunction}
+
+% \pgfmath@parsefunction@rand
+%
+\def\pgfmath@parsefunction@rand{%
+ \expandafter\pgfmathrand%
+ \expandafter\pgfmath@postfunction}%
+
+% \pgfmath@parsefunction@exp
+%
+\def\pgfmath@parsefunction@exp{%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@exp@%
+ \expandafter\pgfmath@parse@}
+\def\pgfmath@parsefunction@exp@{%
+ \expandafter\pgfmathexp@\expandafter{\pgfmathresult}%
+ \pgfmath@postfunction%
+}
+
+% \pgfmath@parsefunction@ln
+%
+\def\pgfmath@parsefunction@ln{%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@ln@%
+ \expandafter\pgfmath@parse@}
+\def\pgfmath@parsefunction@ln@{%
+ \expandafter\pgfmathln@\expandafter{\pgfmathresult}%
+ \pgfmath@postfunction%
+}
+
+% \pgfmath@parsefunction@pi
+%
+\def\pgfmath@parsefunction@pi{%
+ \pgfmathpi%
+ \pgfmath@postfunction%
+}
+
+% \pgfmath@parsefunction@veclen
+%
+\def\pgfmath@parsefunction@veclen{%
+ \expandafter\pgfmath@parsefunction@veclen@}
+\def\pgfmath@parsefunction@veclen@(#1,{%
+ \pgfmathparse@{#1}\edef\pgfmath@firstoperand{\pgfmathresult}%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@veclen@@
+ \pgfmath@startparsegroup}
+\def\pgfmath@parsefunction@veclen@@{%
+ \edef\pgfmath@secondoperand{\pgfmathresult}%
+ \pgfmathveclen@{\pgfmath@firstoperand}{\pgfmath@secondoperand}%
+ \pgfmath@postfunction}
+
+% \pgfmath@parsefunction@mod
+%
+\def\pgfmath@parsefunction@mod{%
+ \expandafter\pgfmath@parsefunction@mod@}
+\def\pgfmath@parsefunction@mod@(#1,{%
+ \pgfmathparse@{#1}\edef\pgfmath@firstoperand{\pgfmathresult}%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@mod@@
+ \pgfmath@startparsegroup}
+\def\pgfmath@parsefunction@mod@@{%
+ \edef\pgfmath@secondoperand{\pgfmathresult}%
+ \pgfmathmod@{\pgfmath@firstoperand}{\pgfmath@secondoperand}%
+ \pgfmath@postfunction}
+
+% \pgfmath@parsefunction@max
+%
+\def\pgfmath@parsefunction@max{%
+ \expandafter\pgfmath@parsefunction@max@}
+\def\pgfmath@parsefunction@max@(#1,{%
+ \pgfmathparse@{#1}\edef\pgfmath@firstoperand{\pgfmathresult}%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@max@@
+ \pgfmath@startparsegroup}
+\def\pgfmath@parsefunction@max@@{%
+ \edef\pgfmath@secondoperand{\pgfmathresult}%
+ \pgfmathmax@{\pgfmath@firstoperand}{\pgfmath@secondoperand}%
+ \pgfmath@postfunction}
+
+% \pgfmath@parsefunction@min
+%
+\def\pgfmath@parsefunction@min{%
+ \expandafter\pgfmath@parsefunction@min@}
+\def\pgfmath@parsefunction@min@(#1,{%
+ \pgfmathparse@{#1}\edef\pgfmath@firstoperand{\pgfmathresult}%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@min@@
+ \pgfmath@startparsegroup}
+\def\pgfmath@parsefunction@min@@{%
+ \edef\pgfmath@secondoperand{\pgfmathresult}%
+ \pgfmathmin@{\pgfmath@firstoperand}{\pgfmath@secondoperand}%
+ \pgfmath@postfunction}
+
+% \pgfmath@parsefunction@pow
+%
+\def\pgfmath@parsefunction@pow{%
+ \expandafter\pgfmath@parsefunction@pow@}
+\def\pgfmath@parsefunction@pow@(#1,{%
+ \pgfmathparse@{#1}\edef\pgfmath@firstoperand{\pgfmathresult}%
+ \let\pgfmath@parsepostgroup\pgfmath@parsefunction@pow@@
+ \pgfmath@startparsegroup}
+\def\pgfmath@parsefunction@pow@@{%
+ \edef\pgfmath@secondoperand{\pgfmathresult}%
+ \pgfmathpow@{\pgfmath@firstoperand}{\pgfmath@secondoperand}%
+ \pgfmath@postfunction} \ No newline at end of file