From f41811b55dfce3a5f59b953b68457b0aa5491baf Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sat, 9 Aug 2008 23:39:38 +0000 Subject: pgfplots update (10aug08) git-svn-id: svn://tug.org/texlive/trunk@10222 c570f23f-e606-0410-a88d-b1316a301751 --- .../pgfplotsoldpgfsupp_loader.code.tex | 12 + .../pgfplotsoldpgfsupp_misc.code.tex | 174 ++ .../pgfplotsoldpgfsupp_pgfkeysfiltered.code.tex | 928 ++++++++ ...plotsoldpgfsupp_pgflibraryplothandlers.code.tex | 922 ++++++++ .../pgfplotsoldpgfsupp_pgfmathfloat.code.tex | 2322 ++++++++++++++++++++ 5 files changed, 4358 insertions(+) create mode 100644 Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_loader.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_misc.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfkeysfiltered.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgflibraryplothandlers.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfmathfloat.code.tex (limited to 'Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib') diff --git a/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_loader.code.tex b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_loader.code.tex new file mode 100644 index 00000000000..ce780e866b2 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_loader.code.tex @@ -0,0 +1,12 @@ +%-------------------------------------------------- +% \pgfutil@ifundefined{pgfmathfloattosci} +% {}% +% {\endinput}% +%-------------------------------------------------- +\pgfkeysifdefined{/pgf/number format/@dec sep mark}{\endinput}{} + +\immediate\write16{Package pgfplots: loading complementary code for your PGF version...} +\input pgfplotsoldpgfsupp_misc.code.tex +\input pgfplotsoldpgfsupp_pgfkeysfiltered.code.tex +\input pgfplotsoldpgfsupp_pgfmathfloat.code.tex +\input pgfplotsoldpgfsupp_pgflibraryplothandlers.code.tex diff --git a/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_misc.code.tex b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_misc.code.tex new file mode 100644 index 00000000000..def32476da4 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_misc.code.tex @@ -0,0 +1,174 @@ + +% ====================================================== +% compatibility with PGF 2.0 +\def\pgfkeysaddvalue#1#2#3{% + {% + \toks0{#2}% + \pgfkeysifdefined{#1} + {\pgfkeys@temptoks\expandafter\expandafter\expandafter{\csname pgfk@#1\endcsname}}% + {\pgfkeys@temptoks{}}% + \toks1{#3}% + \xdef\pgfkeys@global@temp{\the\toks0 \the\pgfkeys@temptoks \the\toks1}% believe or don't: the spaces are important + }% + \pgfkeyslet{#1}\pgfkeys@global@temp% +} + +\def\pgfkeys@try{% + \pgfkeysifdefined{\pgfkeyscurrentpath/.@cmd}% + {% + \pgfkeysgetvalue{\pgfkeyscurrentpath/.@cmd}{\pgfkeys@code}% + \ifx\pgfkeyscurrentvalue\pgfkeysnovalue@text% Hmm... no value + \pgfkeysifdefined{\pgfkeyscurrentpath/.@def}% + {\pgfkeysgetvalue{\pgfkeyscurrentpath/.@def}{\pgfkeyscurrentvalue}} + {}% no default, so leave it + \fi% + \let\pgfkeyscurrentkey=\pgfkeyscurrentpath% make sure that \pgfkeys@code doesn't know about 'try'. Important for .is choice + % FIXME: maybe there are more things like that - also adjust currentname!? + \expandafter\pgfkeys@code\pgfkeyscurrentvalue\pgfeov% + \pgfkeyssuccesstrue% + }% + {% + \pgfkeysifdefined{\pgfkeyscurrentpath}% + {% + \ifx\pgfkeyscurrentvalue\pgfkeysnovalue@text% + \pgfkeysvalueof{\pgfkeyscurrentpath}% + \else% + \pgfkeyslet{\pgfkeyscurrentpath}\pgfkeyscurrentvalue% + \fi% + \pgfkeyssuccesstrue% + }% + {\pgfkeyssuccessfalse}% + }% +} +% ====================================================== + + +% pgfutil@loop (from plain.tex) + +\def\pgfutil@loop#1\pgfutil@repeat{\def\pgfutil@body{#1}\pgfutil@iterate} +\def\pgfutil@iterate{\pgfutil@body \let\pgfutil@next\pgfutil@iterate \else\let\pgfutil@next\relax\fi \pgfutil@next} +\let\pgfutil@repeat=\fi % this makes \loop...\if...\repeat skippable + +\def\pgfqpointxy#1#2{% + \pgf@x=#1\pgf@xx% + \advance\pgf@x by #2\pgf@yx% + \pgf@y=#1\pgf@xy% + \advance\pgf@y by #2\pgf@yy} +\def\pgfqpointxyz#1#2#3{% + \pgf@x=#1\pgf@xx% + \advance\pgf@x by #2\pgf@yx% + \advance\pgf@x by #3\pgf@zx% + \pgf@y=#1\pgf@xy% + \advance\pgf@y by #2\pgf@yy% + \advance\pgf@y by #3\pgf@zy} +\def\pgfcoordinate#1#2{% + \edef\pgf@temp{#1}% + \ifx\pgf@temp\pgfutil@empty% do nothing + \else% + \pgf@process{\pgfpointtransformed{#2}}% + \expandafter\gdef\csname pgf@sh@ns@#1\endcsname{coordinate}% + \expandafter\xdef\csname pgf@sh@np@#1\endcsname{% + \noexpand\def\noexpand\centerpoint{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + } + \expandafter\gdef\csname pgf@sh@nt@#1\endcsname{{1}{0}{0}{1}{0pt}{0pt}}% + \expandafter\global\expandafter\let\csname pgf@sh@ma@#1\endcsname\pgfutil@empty% + \expandafter\gdef\csname pgf@sh@pi@#1\endcsname{\pgfpictureid}% + \fi% +} +% ====================================================== + +\def\pgfutilensuremath#1{% + \ifmmode#1\else$#1$\fi +} + +\tikzoption{ybar}[]{\let\tikz@plot@handler=\pgfplothandlerybar} +\tikzoption{xbar}[]{\let\tikz@plot@handler=\pgfplothandlerxbar} +\tikzoption{ybar interval}[]{\let\tikz@plot@handler=\pgfplothandlerybarinterval} +\tikzoption{xbar interval}[]{\let\tikz@plot@handler=\pgfplothandlerxbarinterval} +\tikzoption{const plot}[]{\let\tikz@plot@handler=\pgfplothandlerconstantlineto} +\tikzoption{const plot mark left}[]{\let\tikz@plot@handler=\pgfplothandlerconstantlineto} +\tikzoption{const plot mark right}[]{\let\tikz@plot@handler=\pgfplothandlerconstantlinetomarkright} +\tikzoption{jump mark right}[]{\let\tikz@plot@handler=\pgfplothandlerjumpmarkright} +\tikzoption{jump mark left}[]{\let\tikz@plot@handler=\pgfplothandlerjumpmarkleft} + +% the 'every mark' style is new: +\tikzset{ + every mark/.style={}, + mark options/.style={% + every mark/.style={#1}% + }} +\def\tikz@@@plot{% + \def\pgfplotlastpoint{\pgfpointorigin}% + \tikz@plot@handler% + \tikz@plot@data% + \global\let\tikz@@@temp=\pgfplotlastpoint% + \ifx\tikz@plot@mark\pgfutil@empty% + \else% + % Marks are drawn after the path. + \setbox\tikz@figbox=\hbox{% + \unhbox\tikz@figbox% + \hbox{{% + \pgfinterruptpath% + \pgfscope% + \let\tikz@options=\pgfutil@empty% + \let\tikz@transform=\pgfutil@empty% + \tikzset{every mark}% + \tikz@options% + \ifx\tikz@mark@list\pgfutil@empty% + \pgfplothandlermark{\tikz@transform\pgfuseplotmark{\tikz@plot@mark}}% + \else + \pgfplothandlermarklisted{\tikz@transform\pgfuseplotmark{\tikz@plot@mark}}{\tikz@mark@list}% + \fi + \tikz@plot@data% + \endpgfscope + \endpgfinterruptpath% + }}% + }% + \fi% + \global\setbox\tikz@tempbox=\copy\tikz@figbox% + %\global\let\tikz@after@path@smuggle=\tikz@after@path + \endgroup% + \setbox\tikz@figbox=\box\tikz@tempbox% + \tikz@make@last@position{\tikz@@@temp}% + %\expandafter\tikz@scan@next@command\tikz@after@path@smuggle% + \tikz@scan@next@command% +} + + + + +% ====================================================== + + +\newif\ifpgfmathcomparison + +% Assigns \pgfmathresult to 1.0 if #1 ~= #1. +% +% It will also set the boolean \ifpgfmathcomparison accordingly +% (globally). +\def\pgfmathapproxequalto#1#2{% + \edef\pgfmath@marshal{% + \noexpand\pgfmathparse{#2} + \noexpand\let\noexpand\pgfmath@arg\noexpand\pgfmathresult% + \noexpand\pgfmathparse{#1}% + }% + \pgfmath@marshal% + \pgfmathapproxequalto@{\pgfmathresult}{\pgfmath@arg}} +\def\pgfmathapproxequalto@#1#2{% + \begingroup% + \pgfmath@x#1pt% + \pgfmath@y#2pt% + \advance\pgfmath@x-\pgfmath@y% + \ifdim\pgfmath@x<0pt + \multiply\pgfmath@x by-1 + \fi + \ifdim\pgfmath@x<0.0001pt\relax% + \def\pgfmathresult{1.0}% + \global\pgfmathcomparisontrue + \else% + \def\pgfmathresult{0.0}% + \global\pgfmathcomparisonfalse + \fi% + \pgfmath@smuggleone\pgfmathresult + \endgroup% +} diff --git a/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfkeysfiltered.code.tex b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfkeysfiltered.code.tex new file mode 100644 index 00000000000..ed490784564 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfkeysfiltered.code.tex @@ -0,0 +1,928 @@ +% Copyright 2008 by Christian Feuersaenger +% +% 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 contains additions to pgfkeys.code.tex (loaded +% automatically at the end of pgfkeys.code.tex) +% +% Improvements: +% +% - option filtering +% you provide +% - a boolean predicate +% - a "filter handler" which will be invoked for non-matching options, +% - a key=value list as usual. +% The filter sets only matching options and invokes the handler for +% unmatching ones. +% +% - Fast family support as in xkeyval. +% - A key like /my tree/my option can be associated with /my family +% - You can efficiently set keys which belong to a set of "active" +% families. +% Remaining options can be collected into a macro. + +% WARNING: +% this file overwrites +% \pgfkeys@addpath +% \pgfkeys@nevermind +% +% all other features are 'additive' + + +% these implementations will be switched dynamically with their +% filtered versions (in \pgfkeys@install@filter@and@invoke) +\let\pgfkeys@orig@case@one=\pgfkeys@case@one +\let\pgfkeys@orig@@set=\pgfkeys@@set +\let\pgfkeys@orig@@qset=\pgfkeys@@qset +\let\pgfkeys@orig@try=\pgfkeys@try +\let\pgfkeys@orig@unknown=\pgfkeys@unknown + +\newif\ifpgfkeysfilteringisactive +\newif\ifpgfkeysfiltercontinue +\let\pgfkeys@key@predicate=\pgfkeys@empty +\let\pgfkeys@filtered@handler=\pgfkeys@empty +\newtoks\pgfkeys@tmptoks + +% Performs 'filtered' key settings. +% +% For every option for which the path prefixing has already been done, +% the current key filter predicate will be invoked. If the predicate +% returns true, pgfkeys will process this key in the normal manner. +% If not, a key filter handler will be invoked. +% +% The *predicate* and *handler* semantics are as follows: +% PRECONDITION: +% 1. The variables +% \pgfkeyscurrentkey (full path including name) +% \pgfkeyscurrentkeyRAW (the current key as it has been +% found in the key=value list +% without path modification) +% \pgfkeyscurrentvalue +% are all set. If the current key is a handler variable, +% \pgfkeyscurrentname +% and +% \pgfkeyscurrentpath +% are also set. +% 2. The type of option has already been checked, that means +% case (1) whether '.@cmd' exists +% case (2) whether the key as such has its value +% case (3) it is a handler like '.code', '.cd' or whatever. +% case (0) it is unknown. +% The actual case number (0-3) will be provided as contents +% of the macro +% \pgfkeyscasenumber. +% Please note that unknown options will be processed with +% the usual '.unknown' handlers unless the key filter takes +% control over unknown options as well. +% +% POSTCONDITION: +% the predicate sets +% \pgfkeysfiltercontinuetrue +% or +% \pgfkeysfiltercontinuefalse +% (the boolean \ifpgfkeysfiltercontinue). +% Depending on this 'if', option processing will be continued or +% skipped. +% +% The handler can do anything with the option, for example collect +% unmatched ones. +% +% ATTENTION: \pgfkeysfiltered can't be nested (yet). Use the +% \pgfkeyspredicateAND if you need multiple predicates at once. +% Nesting would produce unexpected results because the current filter +% state can't be stored/restored without TeX-groups, therefor it is +% disabled. +% +% ATTENTION: you can't filter error messages. +% +% REMARK: In case (3), the macros \pgfkeyscurrentpath and +% \pgfkeyscurrentname have already been computed, you do not need to +% invoke \pgfkeyssplitpath. In any other case, neither path nor name +% are required for the options processing - if you need them for +% predicates/handlers, you need to compute them by hand. +% +% +% Example: +% \def\unmatched{} +% \pgfkeys{/pgf/key filters/is descendant of/.install key filter=/my group} +% \pgfkeys{/pgf/key filter handlers/append filtered to/.install key filter handler=\unmatched} +% \pgfkeysfiltered% +% {/my group/option 1=value 1,/tikz/option 2=value 2} +% -> +% will set '/my group/option 1' as usual, but '/tikz/option 2' will not +% be set. Instead, it will be appended to '\unmatched' such that +% \unmatched = {/tikz/option 2=value2} +% after the operation. +% +% Arguments: +% #1: key-value list. +\def\pgfkeysfiltered{% + % produce + % '{}' + % each expanded exactly one time into the register: + \expandafter\pgfkeysfiltered@@install\expandafter{\pgfkeysdefaultpath}% +} + +% #1: old value of default path. +% #2: key-value-list. +\def\pgfkeysfiltered@@install#1#2{% + \pgfkeys@install@filter@and@invoke{% + \let\pgfkeysdefaultpath\pgfkeys@root% + \pgfkeys@parse#2,\pgfkeys@mainstop% + \def\pgfkeysdefaultpath{#1}% + }% +} + +% Assuming that macro #1 contains a key=value list, this command +% performs an \pgfkeysalso command for the content of macro #1. +% +% It can be used in conjunction with +% - \pgfkeysfiltered and +% - \pgfkeysappendfilterednamestomacro: +% the first pass fill only process options matching the filter, then, +% a \pgfkeysalsofrom can be used at a later time to set the remaining +% options. +% +% Example: +% \pgfkeys{/my group/.cd,/utils/exec=\pgfkeysalsofrom\filtered} +\def\pgfkeysalsofrom#1{% + \expandafter\pgfkeysalso\expandafter{#1}% +} + +% The same as \pgfkeysalsofrom, but it invokes \pgfkeysalsofiltered. +\def\pgfkeysalsofilteredfrom#1{% + \expandafter\pgfkeysalsofiltered\expandafter{#1}% +} + +% #1 = options +\long\def\pgfkeysalsofiltered#1{% + \pgfkeys@install@filter@and@invoke{\pgfkeysalso{#1}}% +}% + +% The same like \pgfkeysfiltered, but with quick search path setting. +% +% #1: default path +% #2: key-value-pairs +\def\pgfqkeysfiltered#1{% + \expandafter\pgfqkeysfiltered@@install\expandafter{\pgfkeysdefaultpath}{#1}% +} + +% #1: old value of default path. +% #2: default path +% #3: key-value-list. +\def\pgfqkeysfiltered@@install#1#2#3{% + \pgfkeys@install@filter@and@invoke{% + \def\pgfkeysdefaultpath{#2/}\pgfkeys@parse#3,\pgfkeys@mainstop\def\pgfkeysdefaultpath{#1}% + }% +} + +% Family management +% +% The family code provides the following features: +% 1. every key can be associated with 0 or 1 'family'. +% 2. Families are a loose association which are independend of the key +% hierarchy. +% For example, /my tree/key1 can belong to family /tikz. +% +% 3. It is possible to "activate" or "deactivate" single families. +% Furthermore, it is possible to set only keys which belong to +% active families (using \pgfkeysfiltered). +% 4. Runtime complexities: +% If you have N options and you only want to process K active +% families, the runtime is O( N + K ): +% - activate every family O(K) +% - use \pgfkeyshasactivefamily as filter predicate O(N) +% - deactivate every family O(K) + + +% Activates family #1. +% +% #1 maybe a macro. +\def\pgfkeysactivatefamily#1{% + \pgfkeysiffamilydefined + {#1}% + {\csname pgfk@#1/familyactivetrue\endcsname}% + {\pgfkeysvalueof{/errors/family unknown/.@cmd}{#1}\pgfeov}% +%\message{[ACTIVATING FAMILY #1]}% +} + +% Deactivates family #1. +% +% #1 maybe a macro. +\def\pgfkeysdeactivatefamily#1{ + \pgfkeysiffamilydefined + {#1}% + {\csname pgfk@#1/familyactivefalse\endcsname}% + {\pgfkeysvalueof{/errors/family unknown/.@cmd}{#1}\pgfeov}% +%\message{[DEACTIVATING FAMILY #1]}% +} + +% Activates all families in the comma separated list #1. +% +% It will also generate code for deactivation of all those families +% into the command #2. +% +% #1: a comma-separated list of fully qualified family names. +% #2: a command which will be filled with a deactivate-all command. +\def\pgfkeysactivatefamilies#1#2{% + \pgfkeyssavekeyfilterstateto\pgfkeys@cur@state + \expandafter\pgfkeysactivatefamilies@impl\expandafter{\pgfkeys@cur@state}{#1}{#2}% +} +% #1: commands needed to restore the old filtering state +% #2: family name list +% #3: macro name for de-activate command +\def\pgfkeysactivatefamilies@impl#1#2#3{% + \pgfkeysinstallkeyfilter{/pgf/key filters/false}{}% + \let#3=\pgfkeys@empty% + \def\pgfkeys@filtered@handler{\pgfkeys@family@activate@handler{#3}}% + \pgfkeysalsofiltered{#2}% + #1% +} + +\def\pgfkeys@family@activate@handler#1{% + \pgfkeysactivatefamily{\pgfkeyscurrentkey}% + % produce + % '\pgfkeysdeactivatefamily{' '}' + \pgfkeys@tmptoks=\expandafter\expandafter\expandafter{\expandafter#1\expandafter\pgfkeysdeactivatefamily\expandafter{\pgfkeyscurrentkey}}% + \edef#1{\the\pgfkeys@tmptoks}% +} + +% If for testing whether a family exists. +% +% #1 = fully qualified family name +% #2 = if-case +% #3 = else-case +% +% Description: +% +% If the family exists, #2 will be executed. Otherwise, #3 will be +% called. +\long\def\pgfkeysiffamilydefined#1#2#3{\pgfkeys@ifcsname ifpgfk@#1/familyactive\endcsname#2\else#3\fi} + +% Sets the TeX boolean +% \ifpgfkeysfiltercontinue := ( family #1 is active ) +% +% Argument: +% #1 the family name. Maybe a macro. +\def\pgfkeysisfamilyactive#1{% + \pgfkeysiffamilydefined{#1}{% + \expandafter\let\expandafter\ifpgfkeysfiltercontinue\csname ifpgfk@#1/familyactive\endcsname + }{% + \pgfkeysvalueof{/errors/family unknown/.@cmd}{#1}\pgfeov% + \expandafter\expandafter\expandafter\let\csname ifpgfkeysfiltercontinue\endcsname\csname iffalse\endcsname + }% +}% + +% Retrieve the family of full key #1 into macro #2. +% +% Will set the TeX boolean \ifpgfkeyssuccess to whether the full key +% really has a family. +% +% The family for any key is stored in the sub-key #1/family. +% +% Parameters: +% #1: the full key name for which the family is requested. Maybe a +% macro. +% #2: a macro name which will be filled with the result. +\def\pgfkeysgetfamily#1#2{% + \pgfkeysifdefined{#1/family}{\pgfkeysgetvalue{#1/family}{#2}\pgfkeyssuccesstrue}{\pgfkeyssuccessfalse}% +} + + + +% Sets \ifpgfkeysfiltercontinue to true iff the current key belongs to +% the /errors tree. +\long\def\pgfkeys@cur@is@descendant@of@errors{% + \expandafter\pgfkeys@cur@is@descendant@of@errors@impl\pgfkeyscurrentkey/errors\pgf@@eov +}% +\long\def\pgfkeys@cur@is@descendant@of@errors@impl#1/errors#2\pgf@@eov{% + \def\pgfkeyspred@TMP{#1}% + \ifx\pgfkeyspred@TMP\pgfkeys@empty +%\message{[SPECIAL CHECK] '\pgfkeyscurrentkey' is descendant of '/errors': TRUE.}% + \pgfkeysfiltercontinuetrue + \else +%\message{[SPECIAL CHECK] '\pgfkeyscurrentkey' is descendant of '/errors': FALSE.}% + \pgfkeysfiltercontinuefalse + \fi +}% + +% \pgfkeysinterruptkeyfilter +% ... +% \endpgfkeysinterruptkeyfilter +% temporarily interrupts key filtering and enables it in +% \endpgfkeysinterruptkeyfilter. +% +% If key filtering it not active, this has no effect at all. +% +% REMARK: +% \pgfkeysinterruptkeyfilter...\endpgfkeysinterruptkeyfilter does NOT +% introduce a \TeX-group. +\def\pgfkeysinterruptkeyfilter{% + \ifpgfkeysfilteringisactive + \let\pgfkeys@case@one=\pgfkeys@orig@case@one + \let\pgfkeys@try=\pgfkeys@orig@try + \let\pgfkeys@unknown=\pgfkeys@orig@unknown + \fi +} + +\def\endpgfkeysinterruptkeyfilter{% + \ifpgfkeysfilteringisactive + \let\pgfkeys@case@one=\pgfkeys@case@one@filtered + \let\pgfkeys@try=\pgfkeys@try@filtered + \let\pgfkeys@unknown=\pgfkeys@unknown@filtered + \fi +} + +% Activates families #1, calls \pgfkeysfiltered and deactivates the +% families afterwards. +% +% REMARK: you need to install a family-based key filter predicate +% manually to benefit from the activated families! +% +% #1: comma separated family list +% #2: key-value pairs +% +% @see \pgfkeysactivatefamiliesandfilteroptions +\def\pgfkeysactivatefamiliesandfilteroptions#1#2{% + \pgfkeysactivatefamilies{#1}{\pgfkeys@family@deactivation}% + \pgfkeysfiltered{#2}% + \pgfkeys@family@deactivation +} + +% The "quick" variant of \pgfkeysactivatefamiliesandfilteroptions: it +% also assigns a default path. +% +% #1: comma separated family list +% #2: default path +% #3: key-value pairs +\def\pgfqkeysactivatefamiliesandfilteroptions#1#2#3{% + \pgfkeysactivatefamilies{#1}{\pgfkeys@family@deactivation}% + \pgfqkeysfiltered{#2}{#3}% + \pgfkeys@family@deactivation +} + +% Public version of split path: +\def\pgfkeyssplitpath{\pgfkeys@split@path}% + + +% The same as \pgfkeysactivatefamiliesandfilteroptions but just for +% ONE family. +% +% #1: family (maybe a macro) +% #2: key-value pairs +\def\pgfkeysactivatesinglefamilyandfilteroptions#1#2{% + \pgfkeysactivatefamily{#1}% + \pgfkeysfiltered{#2}% + \pgfkeysdeactivatefamily{#1}% +} + +% The "quick" variant of \pgfkeysactivatesinglefamilyandfilteroptions +% +% #1: family (maybe a macro) +% #2: default path +% #3: key-value pairs +\def\pgfqkeysactivatesinglefamilyandfilteroptions#1#2#3{% + \pgfkeysactivatefamily{#1}% + \pgfqkeysfiltered{#2}{#3}% + \pgfkeysdeactivatefamily{#1}% +} + +% Installs the key filter '#1' with argument '#2'. +% This is equivalent to +% \pgfkeys{#1/.install key filter=#2} +% +% The current values of the key filter handler is stored into the public +% macros +% \pgfkeyscurrentkeyfilter +% and +% \pgfkeyscurrentkeyfilterargs +% +% #1: a full key name; may be a macro +% #2: optional arguments for the key. If the key expects more than one +% argument, supply '{{first}{second}}' +\def\pgfkeysinstallkeyfilter#1#2{% + \pgfkeysifdefined{#1/.@cmd}{% + \edef\pgfkeyscurrentkeyfilter{#1}% + \def\pgfkeyscurrentkeyfilterargs{#2}% + \pgfkeysgetvalue{#1/.@cmd}{\pgfkeys@key@predicate@}% + \def\pgfkeys@key@predicate{\pgfkeys@key@predicate@#2\pgfeov}% + }{% + \pgfkeysvalueof{/errors/no such key filter/.@cmd}{#1}{#2}\pgfeov% + }% +} + +% Installs the key filter handler '#1' with argument '#2'. +% This is equivalent to +% \pgfkeys{#1/.install key filter handler=#2} +% +% The current values of the key filter handler is stored into the public +% macros +% \pgfkeyscurrentkeyfilterhandler +% and +% \pgfkeyscurrentkeyfilterhandlerargs +% +% #1: a full key name; may be a macro +% #2: optional arguments for the handler. If the handler expects more than one +% argument, supply '{{first}{second}}' +\def\pgfkeysinstallkeyfilterhandler#1#2{% + \pgfkeysifdefined{#1/.@cmd}{% + \edef\pgfkeyscurrentkeyfilterhandler{#1}% + \def\pgfkeyscurrentkeyfilterhandlerargs{#2}% + \pgfkeysgetvalue{#1/.@cmd}{\pgfkeys@filtered@handler@}% + \def\pgfkeys@filtered@handler{\pgfkeys@filtered@handler@#2\pgfeov}% + }{% + \pgfkeysvalueof{/errors/no such key filter handler/.@cmd}{#1}{#2}\pgfeov% + }% +} + +% Creates a macro which contains commands to re-activate the current +% key filter and key filter handler. It can be used to temporarily +% switch the key filter. +\def\pgfkeyssavekeyfilterstateto#1{% + % produce the string + % \pgfkeysinstallkeyfilter{...}{...} + % \pgfkeysinstallkeyfilterhandler{...}{...} + % where each argument is expanded once + % FIXME: Do the same with less overhead! + \pgfkeys@tmptoks={\pgfkeysinstallkeyfilter}% + \pgfkeys@tmptoks=\expandafter\expandafter\expandafter{\expandafter\the\expandafter\pgfkeys@tmptoks\expandafter{\pgfkeyscurrentkeyfilter}}% + \pgfkeys@tmptoks=\expandafter\expandafter\expandafter{\expandafter\the\expandafter\pgfkeys@tmptoks\expandafter{\pgfkeyscurrentkeyfilterargs}\pgfkeysinstallkeyfilterhandler}% + \pgfkeys@tmptoks=\expandafter\expandafter\expandafter{\expandafter\the\expandafter\pgfkeys@tmptoks\expandafter{\pgfkeyscurrentkeyfilterhandler}}% + \pgfkeys@tmptoks=\expandafter\expandafter\expandafter{\expandafter\the\expandafter\pgfkeys@tmptoks\expandafter{\pgfkeyscurrentkeyfilterhandlerargs}}% + \edef#1{% + \the\pgfkeys@tmptoks + }% +} + + +\pgfkeys{% + /errors/family unknown/.code=\pgfkeys@error{% + Sorry, I do not know family '#1' and can't work with any assoicated family handling. Perhaps you misspelled it?}, + /errors/no such key filter/.code 2 args=\pgfkeys@error{Sorry, there is no such key filter '#1'.}, + /errors/no such key filter handler/.code 2 args=\pgfkeys@error{Sorry, there is no such key filter handler '#1'.}, + % HANDLERS: + % + % .is family should + % 1. '.cd' into the families' path, + % 2. define booleans to activate/deactive the family + % (see \pgfkeysisfamilyactive) + % 3. make sure that \pgfkeyshasactivefamily returns true for + % the family itsself. + /handlers/.is family/.append code={% + %\newif is an \outer macro in plain tex, so this here is not portable: + %\expandafter\newif\csname if\pgfkeyscurrentpath/familyactive\endcsname + \edef\pgfkeyspred@TMP{pgfk@\pgfkeyscurrentpath/familyactive}% + \expandafter\pgfkeys@non@outer@newif\expandafter{\pgfkeyspred@TMP}% + \edef\pgfkeyspred@TMP{\pgfkeyscurrentpath/.belongs to family=\pgfkeyscurrentpath}% + \expandafter\pgfkeysalso\expandafter{\pgfkeyspred@TMP}% + },% + /handlers/.activate family/.code=\pgfkeysactivatefamily{\pgfkeyscurrentpath}, + /handlers/.deactivate family/.code=\pgfkeysdeactivatefamily{\pgfkeyscurrentpath}, + /handlers/.belongs to family/.code={% + \pgfkeysiffamilydefined{#1}{% + \pgfkeyssetvalue{\pgfkeyscurrentpath/family}{#1}% + }{% + \pgfkeysalso{/errors/family unknown=#1}% + }% + },% + % + % + % An addition to the '.try' and '.retry' handlers: + % + % It is the same as '.retry', but if the option is still unknown, the + % usual handlers for unknown keys will be invoked. + /handlers/.lastretry/.code={% + \ifpgfkeyssuccess\else + \pgfkeys@try + \ifpgfkeyssuccess\else + % discard the '.lastretry' suffix: + \edef\pgfkeyscurrentkey{\pgfkeyscurrentpath}% + \pgfkeys@split@path% + \pgfkeys@unknown + \fi + \fi + }, + % + % + /handlers/.install key filter/.code={% + \pgfkeysinstallkeyfilter{\pgfkeyscurrentpath}{#1}% + },% + /handlers/.install key filter handler/.code={% + \pgfkeysinstallkeyfilterhandler{\pgfkeyscurrentpath}{#1}% + },% + % + % + % KEY FILTER HANDLERS: + % + /pgf/key filter handlers/append filtered to/.code={% + % Produce + % '={' '}' + % where both, the key and the value are expanded just ONCE: + \pgfkeys@tmptoks=\expandafter\expandafter\expandafter{\expandafter\pgfkeyscurrentkeyRAW\expandafter=\expandafter{\pgfkeyscurrentvalue}}% + \ifx#1\pgfkeys@empty + \else + % Produce ',' '={' '}' + \pgfkeys@tmptoks=\expandafter\expandafter\expandafter{\expandafter#1\expandafter,\the\pgfkeys@tmptoks}% + \fi + \edef#1{\the\pgfkeys@tmptoks}% + },% + /pgf/key filter handlers/ignore/.code={}, + /pgf/key filter handlers/ignore/.install key filter handler, + /pgf/key filter handlers/log/.code={% + \immediate\write16{LOG: the option '\pgfkeyscurrentkey' (was originally '\pgfkeyscurrentkeyRAW') (case \pgfkeyscasenumber) has not been processed due to pgfkeysfiltered.}% + }, + % + % + % KEY FILTER PREDICATES: + % + % Returns true iff the currently processed key belongs to an active family. + % A family is active if it has been activated before. + /pgf/key filters/active families/.code={% + \ifnum\pgfkeyscasenumber=0 + % unknown options shall be processed with the + % unknown-handlers. + \pgfkeysfiltercontinuetrue + \else + \ifnum\pgfkeyscasenumber=3 + \pgfkeysgetfamily\pgfkeyscurrentpath\pgfkeyspred@TMP + \else + \pgfkeysgetfamily\pgfkeyscurrentkey\pgfkeyspred@TMP + \fi + \ifpgfkeyssuccess + \pgfkeysisfamilyactive{\pgfkeyspred@TMP}% + \else% Ok, it does not belong to any family. + \pgfkeysfiltercontinuefalse + \fi + \fi + },% + % + % + % + % This filter works as follows: + % 1. if the current key belongs to a family: + % return whether its family is active, + % 2. if the current key does NOT belong to a family: + % return the result of criterion '#1', + % 3. the current key is unknown: + % return the result of criterion '#2'. + % + % Arguments: + % #1: the predicate which will be invoked in case 2. + % It will be invoked with the current case number as argument. + % #2: the predicate which will be invoked in case 3 with + % the current case number as argument. + /pgf/key filters/active families or no family/.code 2 args={% + \ifnum\pgfkeyscasenumber=0 + \pgfkeysevalkeyfilterwith{#2}% + \else + \ifnum\pgfkeyscasenumber=3 + \pgfkeysgetfamily\pgfkeyscurrentpath\pgfkeyspred@TMP + \else + \pgfkeysgetfamily\pgfkeyscurrentkey\pgfkeyspred@TMP + \fi + \ifpgfkeyssuccess + \pgfkeysisfamilyactive{\pgfkeyspred@TMP}% + \else% Ok, it does not belong to any family. + \pgfkeysevalkeyfilterwith{#1}% + \fi + \fi + }, + /pgf/key filters/active families or no family DEBUG/.code 2 args={% + \ifnum\pgfkeyscasenumber=0 + \immediate\write16{[pgfkeyshasactivefamilyornofamily(\pgfkeyscurrentkey, \pgfkeyscasenumber) invoking unknown handler '#2']}% + \pgfkeysevalkeyfilterwith{#2}% + \else + \ifnum\pgfkeyscasenumber=3 + \pgfkeysgetfamily\pgfkeyscurrentpath\pgfkeyspred@TMP + \else + \pgfkeysgetfamily\pgfkeyscurrentkey\pgfkeyspred@TMP + \fi + \ifpgfkeyssuccess + \pgfkeysisfamilyactive{\pgfkeyspred@TMP}% + \ifpgfkeysfiltercontinue + \immediate\write16{[pgfkeyshasactivefamilyornofamily(\pgfkeyscurrentkey, \pgfkeyscasenumber) family is ACTIVE]}% + \else + \immediate\write16{[pgfkeyshasactivefamilyornofamily(\pgfkeyscurrentkey, \pgfkeyscasenumber) family is NOT active.]}% + \fi + \else% Ok, it does not belong to any family. + \immediate\write16{[pgfkeyshasactivefamilyornofamily(\pgfkeyscurrentkey, \pgfkeyscasenumber) invoking has-no-family-handler '#1']}% + \pgfkeysevalkeyfilterwith{#1}% + \fi + \fi + }, + % + % Processes only options which are childs of #1. + % Example: + % is descendant of/.install key filter=/foo + % will be true for + % /foo/bar/x=y + % /foo/.cd + % /foo/bar/.style=... + % but not for + % /bar/foo/... + /pgf/key filters/is descendant of/.code={% + \ifnum\pgfkeyscasenumber=0 +%\message{'\pgfkeyscurrentkey' (case \pgfkeyscasenumber) is UNKNOWN. Calling unknown handler.}% + % unknown options shall be processed with the + % unknown-handlers. + \pgfkeysfiltercontinuetrue + \else + % string prefix comparison: + \long\def\pgfkeysisdescendantof@impl##1#1##2\pgf@@eov{% + \def\pgfkeyspred@TMP{##1}% + \ifx\pgfkeyspred@TMP\pgfkeys@empty +%\message{'\pgfkeyscurrentkey' (case \pgfkeyscasenumber) is descendant of '#1': TRUE.}% + \pgfkeysfiltercontinuetrue + \else +%\message{'\pgfkeyscurrentkey' (case \pgfkeyscasenumber) is descendant of '#1': FALSE.}% + \pgfkeysfiltercontinuefalse + \fi + }% + \expandafter\pgfkeysisdescendantof@impl\pgfkeyscurrentkey#1\pgf@@eov + \fi + },% + % + % + % + % Returns true if the currently processed full key equals #2. + /pgf/key filters/equals/.code={% + \ifnum\pgfkeyscasenumber=0 + % Unknown option: + \pgfkeysfiltercontinuetrue + \else + \def\pgfkeyspred@TMP{#1}% + \ifx\pgfkeyscurrentkey\pgfkeyspred@TMP + \pgfkeysfiltercontinuetrue + \else + \pgfkeysfiltercontinuefalse + \fi + \fi + },% + % + % + % Argument #1 can be any other (evaluated) filter predicate, its logical return + % value will be inverted. + % Example: + % not/.install key filter={is descendend of=/tikz} + % will install a key filter which evaluates 'is descendant of' with argument '/tikz' and returns the logical negation of the result. + /pgf/key filters/not/.code={% + \pgfkeysevalkeyfilterwith{#1}% + \ifpgfkeysfiltercontinue + \pgfkeysfiltercontinuefalse + \else + \pgfkeysfiltercontinuetrue + \fi + },% + /pgf/key filters/and/.code 2 args={% + \pgfkeysevalkeyfilterwith{#1}% + \ifpgfkeysfiltercontinue + \pgfkeysevalkeyfilterwith{#2}% + \fi + },% + /pgf/key filters/or/.code 2 args={% + \pgfkeysevalkeyfilterwith{#1}% + \ifpgfkeysfiltercontinue + \else + \pgfkeysevalkeyfilterwith{#2}% + \fi + },% + /pgf/key filters/true/.code={\pgfkeysfiltercontinuetrue},% + /pgf/key filters/true/.install key filter, + /pgf/key filters/false/.code={\pgfkeysfiltercontinuefalse},% + % + % Returns false if the current key is unknown, which avoids calling + % the unknown handlers. + /pgf/key filters/defined/.code={% + \ifnum\pgfkeyscasenumber=0 + \pgfkeysfiltercontinuefalse + \else + \pgfkeysfiltercontinuetrue + \fi + }, +}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Private IMPLEMENTATION +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +% This command does THE SAME work as \pgfkeys@case@one, +% but it applies filtering whenever it identified the type of an +% option. +\def\pgfkeys@case@one@filtered{% + \pgfkeys@cur@is@descendant@of@errors + \ifpgfkeysfiltercontinue + \pgfkeys@orig@case@one + \else + \pgfkeysfiltercontinuetrue + \pgfkeysifdefined{\pgfkeyscurrentkey/.@cmd}{% + % CASE ONE: a command option + \def\pgfkeyscasenumber{1}% + \pgfkeys@key@predicate% + \ifpgfkeysfiltercontinue +%\message{PROCESSING KEY \pgfkeyscurrentkey!}% + \pgfkeysgetvalue{\pgfkeyscurrentkey/.@cmd}{\pgfkeys@code}% + \expandafter\pgfkeys@code\pgfkeyscurrentvalue\pgfeov + \else +%\message{FILTEReD OUT KEY \pgfkeyscurrentkey!}% + \pgfkeys@filtered@handler% + \fi + }{% + % CASE TWO: a normal value option + \pgfkeysifdefined{\pgfkeyscurrentkey}{% + \def\pgfkeyscasenumber{2}% + \pgfkeys@key@predicate% + \ifpgfkeysfiltercontinue +%\message{PROCESSING KEY \pgfkeyscurrentkey!}% + \pgfkeys@case@two@extern + \else +%\message{FILTEReD OUT KEY \pgfkeyscurrentkey!}% + \pgfkeys@filtered@handler% + \fi + }{% + \pgfkeys@split@path + % CASE THREE: a handler + \pgfkeysifdefined{/handlers/\pgfkeyscurrentname/.@cmd}{% + \def\pgfkeyscasenumber{3}% + \pgfkeys@key@predicate% + \ifpgfkeysfiltercontinue +%\message{PROCESSING KEY \pgfkeyscurrentkey!}% + \pgfkeysgetvalue{/handlers/\pgfkeyscurrentname/.@cmd}{\pgfkeys@code}% + \expandafter\pgfkeys@code\pgfkeyscurrentvalue\pgfeov + \else +%\message{FILTERED OUT KEY \pgfkeyscurrentkey!}% + \pgfkeys@filtered@handler% + \fi + }{% + \pgfkeys@unknown + }% + }% + }% + \fi +}% + +\def\pgfkeys@unknown@filtered{% + % CASE ZERO: an unknown option. + \def\pgfkeyscasenumber{0}% + \pgfkeys@key@predicate% + \ifpgfkeysfiltercontinue +%\message{PROCESSING KEY \pgfkeyscurrentkey!}% + % start normal 'unknown' handlers: + \pgfkeys@orig@unknown + \else +%\message{FILTEReD OUT KEY \pgfkeyscurrentkey!}% + \pgfkeys@filtered@handler% + \fi +} + +% Does the same as \pgfkeys@try, but it also invokes the key filters. +\def\pgfkeys@try@filtered{% + \ifpgfkeysfiltercontinue + \pgfkeys@orig@try + \else + \pgfkeysfiltercontinuetrue + \pgfkeysifdefined{\pgfkeyscurrentpath/.@cmd}% + {% + % CASE ONE: a command option + \def\pgfkeyscasenumber{1}% + \pgfkeys@key@predicate% + \ifpgfkeysfiltercontinue + \pgfkeysgetvalue{\pgfkeyscurrentkey/.@cmd}{\pgfkeys@code}% + \ifx\pgfkeyscurrentvalue\pgfkeysnovalue@text% Hmm... no value + \pgfkeysifdefined{\pgfkeyscurrentpath/.@def}% + {\pgfkeysgetvalue{\pgfkeyscurrentpath/.@def}{\pgfkeyscurrentvalue}} + {}% no default, so leave it + \fi% + \expandafter\pgfkeys@code\pgfkeyscurrentvalue\pgfeov% + \else + \pgfkeys@filtered@handler% + \fi + \pgfkeyssuccesstrue% + }% + {% + \pgfkeysifdefined{\pgfkeyscurrentpath}% + {% CASE TWO: a normal value option + \def\pgfkeyscasenumber{2}% + \pgfkeys@key@predicate% + \ifpgfkeysfiltercontinue + \ifx\pgfkeyscurrentvalue\pgfkeysnovalue@text% + \pgfkeysvalueof{\pgfkeyscurrentpath}% + \else% + \pgfkeyslet{\pgfkeyscurrentpath}\pgfkeyscurrentvalue% + \fi% + \else + \pgfkeys@filtered@handler% + \fi + \pgfkeyssuccesstrue% + }% + {\pgfkeyssuccessfalse}% + }% + \fi +} + + +% #1 the code to invoke after init and before cleanup +\def\pgfkeys@install@filter@and@invoke#1{% + \ifpgfkeysfilteringisactive + \pgfkeys@error{Sorry, nested calls to key filtering routines are not allowed. (reason: It is not possible to properly restore the previous filtering state after returning from the nested call)}% + \fi + \pgfkeysfilteringisactivetrue + \let\pgfkeys@case@one=\pgfkeys@case@one@filtered + \let\pgfkeys@try=\pgfkeys@try@filtered + \let\pgfkeys@unknown=\pgfkeys@unknown@filtered + #1% + \let\pgfkeys@case@one=\pgfkeys@orig@case@one + \let\pgfkeys@try=\pgfkeys@orig@try + \let\pgfkeys@unknown=\pgfkeys@orig@unknown + \pgfkeysfilteringisactivefalse +} + + +%-------------------------------------------------- +% \def\pgfkeys@eval@key@filter@subroutine@case@one{% +% \pgfkeysifdefined{\pgfkeyscurrentkey/.@cmd}{% +% \pgfkeysgetvalue{\pgfkeyscurrentkey/.@cmd}{\pgfkeys@code}% +% \let\pgfkeyspred@TMP=\pgfkeyscurrentvalue +% \pgfkeys@eval@key@filter@subroutine@restorestate +% \expandafter\pgfkeys@code\pgfkeyspred@TMP\pgfeov +% }{% +% \pgfkeysvalueof{/errors/no such key filter/.@cmd}\pgfkeyscurrentkey\pgfkeyscurrentvalue\pgfeov% +% }% +% } +% % THIS VERSION IS TOO SLOW. See below. +% \def\pgfkeysevalkeyfilterwith#1{% +% \edef\pgfkeys@eval@key@filter@subroutine@restorestate{% +% \noexpand\def\noexpand\pgfkeyscurrentkey{\pgfkeyscurrentkey}% +% \noexpand\def\noexpand\pgfkeyscurrentkeyRAW{\pgfkeyscurrentkeyRAW}% +% \noexpand\def\noexpand\pgfkeyscurrentname{\pgfkeyscurrentname}% +% \noexpand\def\noexpand\pgfkeyscurrentvalue{\pgfkeyscurrentvalue}% +% \noexpand\pgfkeys@pathtoks={\pgfkeyscurrentpath}% +% }% +% \pgfkeysinterruptkeyfilter +% \let\pgfkeys@case@one=\pgfkeys@eval@key@filter@subroutine@case@one +% \pgfkeysalso{#1}% +% \endpgfkeysinterruptkeyfilter% this here also restored \pgfkeys@case@one. +% \pgfkeys@eval@key@filter@subroutine@restorestate +% }% +%-------------------------------------------------- + + +% Evaluates a key filter '#1'. Example: +% \pgfkeysevalkeyfilterwith{/pgf/key filters/equals=/tikz} +% +% \pgfkeysevalkeyfilterwith works only if key filtering is +% active. +% +% The argument '#1' MUST be a FULL KEY. +% +% The implementation employs a subset of the \pgfkeysalso code. +\def\pgfkeysevalkeyfilterwith#1{% + \pgfkeys@eval@key@filter@subroutine@unpack#1=\pgfkeysnovalue=\pgfkeys@stop +}% +\def\pgfkeys@eval@key@filter@subroutine@unpack#1=#2=#3\pgfkeys@stop{% + \pgfkeys@spdef\pgfkeyspred@TMP{#1}% + \edef\pgfkeyspred@TMP{\pgfkeyspred@TMP}% + \pgfkeys@spdef\pgfkeyspred@TMPB{#2}% TMPB=value + \ifx\pgfkeyspred@TMPB\pgfkeysnovalue@text% Hmm... no value + \pgfkeysifdefined{\pgfkeyspred@TMP/.@def}% + {\pgfkeysgetvalue{\pgfkeyspred@TMP/.@def}{\pgfkeyspred@TMPB}} + {}% no default, so leave it + \fi% + \ifx\pgfkeyspred@TMPB\pgfkeysvaluerequired% + \pgfkeysvalueof{/errors/value required/.@cmd}\pgfkeyspred@TMP\pgfkeyspred@TMPB\pgfeov% + \else% + \pgfkeysifdefined{\pgfkeyspred@TMP/.@cmd}{% + \pgfkeysgetvalue{\pgfkeyspred@TMP/.@cmd}{\pgfkeys@code}% + \expandafter\pgfkeys@code\pgfkeyspred@TMPB\pgfeov + }{% + \pgfkeysvalueof{/errors/no such key filter/.@cmd}\pgfkeyspred@TMP\pgfkeyspred@TMPB\pgfeov% + }% + \fi% +} + + +\def\pgfkeys@nevermind#1\relax{\let\pgfkeyscurrentkeyRAW=\pgfkeyscurrentkey} +\def\pgfkeys@addpath#1\relax{\def\pgfkeyscurrentkeyRAW{#1}% old @addpath: + \edef\pgfkeyscurrentkey{\pgfkeysdefaultpath#1}% +} + +\def\pgfkeys@non@outer@newif@#1#2{% + \expandafter\edef\csname #2true\endcsname{\noexpand\let\noexpand#1=\noexpand\iftrue}% + \expandafter\edef\csname #2false\endcsname{\noexpand\let\noexpand#1=\noexpand\iffalse}% + \csname #2false\endcsname +}% + +% For latex and context, this here has the same effect as a \newif +% applied to 'if#1'. For plain tex, it has also the same effect, but +% it is not an \outer macro as the plain-tex \newif. +\def\pgfkeys@non@outer@newif#1{% + \expandafter\pgfkeys@non@outer@newif@\csname if#1\endcsname{#1}% +} +\endinput diff --git a/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgflibraryplothandlers.code.tex b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgflibraryplothandlers.code.tex new file mode 100644 index 00000000000..0d120a8b722 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgflibraryplothandlers.code.tex @@ -0,0 +1,922 @@ +% Copyright 2006 by Till Tantau +% +% 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. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgfplots/pgfplots/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgflibraryplothandlers.code.tex,v 1.3 2008/06/07 17:08:33 ludewich Exp $ + +\newif\ifpgf@plot@started + + +% This handler converts each plot stream command into a curveto +% command, except for the first, which is converted to the previously +% specified action. +% +% Example: +% +% \pgfpathmoveto{\pgfpointorigin} +% \pgfsetlinetofirstplotpoint +% \pgfplothandlercurveto +% \pgfplotxyfile{mytable} + +\def\pgfplothandlercurveto{% + \def\pgf@plotstreamstart{% + \global\let\pgf@plotstreampoint=\pgf@plot@curveto@handler@initial% + \global\let\pgf@plotstreamspecial=\pgfutil@gobble% + \global\let\pgf@plotstreamend=\pgf@plot@curveto@handler@finish% + \global\pgf@plot@startedfalse% + }% +} + +\def\pgf@plot@curveto@handler@initial#1{% + \pgf@process{#1}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@plot@first@action{\pgfqpoint{\pgf@xa}{\pgf@ya}}% + \xdef\pgf@plot@curveto@first{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}% + \global\let\pgf@plot@curveto@first@support=\pgf@plot@curveto@first% + \global\let\pgf@plotstreampoint=\pgf@plot@curveto@handler@second% +} + +\def\pgf@plot@curveto@handler@second#1{% + \pgf@process{#1}% + \xdef\pgf@plot@curveto@second{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \global\let\pgf@plotstreampoint=\pgf@plot@curveto@handler@third% + \global\pgf@plot@startedtrue% +} + +\def\pgf@plot@curveto@handler@third#1{% + \pgf@process{#1}% + \xdef\pgf@plot@curveto@current{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + % compute difference vector: + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@process{\pgf@plot@curveto@first} + \advance\pgf@xa by-\pgf@x% + \advance\pgf@ya by-\pgf@y% + % compute support directions: + \pgf@xa=\pgf@plottension\pgf@xa% + \pgf@ya=\pgf@plottension\pgf@ya% + % first marshal: + \pgf@process{\pgf@plot@curveto@second}% + \pgf@xb=\pgf@x% + \pgf@yb=\pgf@y% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + \advance\pgf@xb by-\pgf@xa% + \advance\pgf@yb by-\pgf@ya% + \advance\pgf@xc by\pgf@xa% + \advance\pgf@yc by\pgf@ya% + \edef\pgf@marshal{\noexpand\pgfpathcurveto{\noexpand\pgf@plot@curveto@first@support}% + {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}{\noexpand\pgf@plot@curveto@second}}% + {\pgf@marshal}% + % Prepare next: + \global\let\pgf@plot@curveto@first=\pgf@plot@curveto@second% + \global\let\pgf@plot@curveto@second=\pgf@plot@curveto@current% + \xdef\pgf@plot@curveto@first@support{\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}% +} + +\def\pgf@plot@curveto@handler@finish{% + \ifpgf@plot@started% + \pgfpathcurveto{\pgf@plot@curveto@first@support}{\pgf@plot@curveto@second}{\pgf@plot@curveto@second}% + \fi% +} + + +% This commands sets the tension for smoothing of plots. +% +% #1 = tension of curves. A value of 1 will yield a circle when the +% control points are at quarters of a circle. A smaller value +% will result in a tighter curve. Default is 0.5. +% +% Example: +% +% \pgfsetplottension{0.2} + +\def\pgfsetplottension#1{% + \pgf@x=#1pt\relax% + \pgf@x=0.2775\pgf@x\relax% + \edef\pgf@plottension{\pgf@sys@tonumber\pgf@x}} +\pgfsetplottension{0.5} + + +% This handler converts the plot stream command into a curveto +% command that is closed using a closepath. +% +% Example: +% +% \pgfpathmoveto{\pgfpointorigin} +% \pgfplothandlerclosedcurve +% \pgfplotxyfile{mytable} + +\def\pgfplothandlerclosedcurve{% + \def\pgf@plotstreamstart{% + \global\let\pgf@plotstreampoint=\pgf@plot@closedcurve@handler@initial% + \global\let\pgf@plotstreamspecial=\pgfutil@gobble% + \global\let\pgf@plotstreamend=\pgf@plot@closedcurve@handler@finish% + }% +} + +\def\pgf@plot@closedcurve@handler@initial#1{% + \pgf@process{#1}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \xdef\pgf@plot@closedcurve@initial{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}% + \global\let\pgf@plotstreampoint=\pgf@plot@closedcurve@handler@second% + \global\pgf@plot@startedfalse% +} + +\def\pgf@plot@closedcurve@handler@second#1{% + \pgf@process{#1}% + \xdef\pgf@plot@closedcurve@after@initial{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + {\pgfpathmoveto{}}% + \global\let\pgf@plotstreampoint=\pgf@plot@closedcurve@handler@third% +} + +\def\pgf@plot@closedcurve@handler@third#1{% + \global\pgf@plot@startedtrue% + \pgf@process{#1}% + \xdef\pgf@plot@closedcurve@current{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + % compute difference vector: + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@process{\pgf@plot@closedcurve@initial} + \advance\pgf@xa by-\pgf@x% + \advance\pgf@ya by-\pgf@y% + % compute support directions: + \pgf@xa=\pgf@plottension\pgf@xa% + \pgf@ya=\pgf@plottension\pgf@ya% + % first marshal: + \pgf@process{\pgf@plot@closedcurve@after@initial}% + \pgf@xb=\pgf@x% + \pgf@yb=\pgf@y% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + \advance\pgf@xb by-\pgf@xa% + \advance\pgf@yb by-\pgf@ya% + \advance\pgf@xc by\pgf@xa% + \advance\pgf@yc by\pgf@ya% + \global\let\pgf@plot@closedcurve@first=\pgf@plot@closedcurve@after@initial% + \global\let\pgf@plot@closedcurve@second=\pgf@plot@closedcurve@current% + \xdef\pgf@plot@closedcurve@after@initial@presupport{\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}% + \xdef\pgf@plot@closedcurve@first@support{\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}% + \global\let\pgf@plotstreampoint=\pgf@plot@closedcurve@handler@fourth% +} + +\def\pgf@plot@closedcurve@handler@fourth#1{% + \pgf@process{#1}% + \xdef\pgf@plot@closedcurve@current{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + % compute difference vector: + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@process{\pgf@plot@closedcurve@first} + \advance\pgf@xa by-\pgf@x% + \advance\pgf@ya by-\pgf@y% + % compute support directions: + \pgf@xa=\pgf@plottension\pgf@xa% + \pgf@ya=\pgf@plottension\pgf@ya% + % first marshal: + \pgf@process{\pgf@plot@closedcurve@second}% + \pgf@xb=\pgf@x% + \pgf@yb=\pgf@y% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + \advance\pgf@xb by-\pgf@xa% + \advance\pgf@yb by-\pgf@ya% + \advance\pgf@xc by\pgf@xa% + \advance\pgf@yc by\pgf@ya% + \edef\pgf@marshal{\noexpand\pgfpathcurveto{\noexpand\pgf@plot@closedcurve@first@support}% + {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}{\noexpand\pgf@plot@closedcurve@second}}% + {\pgf@marshal}% + % Prepare next: + \global\let\pgf@plot@closedcurve@first=\pgf@plot@closedcurve@second% + \global\let\pgf@plot@closedcurve@second=\pgf@plot@closedcurve@current% + \xdef\pgf@plot@closedcurve@first@support{\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}% +} + +\def\pgf@plot@closedcurve@handler@finish{% + \ifpgf@plot@started + % + % first, draw line from 2nd last to last: + % + \pgf@process{\pgf@plot@closedcurve@initial}% + % compute difference vector: + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@process{\pgf@plot@closedcurve@first}% + \advance\pgf@xa by-\pgf@x% + \advance\pgf@ya by-\pgf@y% + % compute support directions: + \pgf@xa=\pgf@plottension\pgf@xa% + \pgf@ya=\pgf@plottension\pgf@ya% + % first marshal: + \pgf@process{\pgf@plot@closedcurve@second}% + \pgf@xb=\pgf@x% + \pgf@yb=\pgf@y% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + \advance\pgf@xb by-\pgf@xa% + \advance\pgf@yb by-\pgf@ya% + \advance\pgf@xc by\pgf@xa% + \advance\pgf@yc by\pgf@ya% + \edef\pgf@marshal{\noexpand\pgfpathcurveto{\noexpand\pgf@plot@closedcurve@first@support}% + {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}{\noexpand\pgf@plot@closedcurve@second}}% + {\pgf@marshal}% + \xdef\pgf@plot@closedcurve@first@support{\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}% + % + % second, draw line from last point to start: + % + \pgf@process{\pgf@plot@closedcurve@after@initial}% + % compute difference vector: + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@process{\pgf@plot@closedcurve@second}% + \advance\pgf@xa by-\pgf@x% + \advance\pgf@ya by-\pgf@y% + % compute support directions: + \pgf@xa=\pgf@plottension\pgf@xa% + \pgf@ya=\pgf@plottension\pgf@ya% + % first marshal: + \pgf@process{\pgf@plot@closedcurve@initial}% + \pgf@xb=\pgf@x% + \pgf@yb=\pgf@y% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + \advance\pgf@xb by-\pgf@xa% + \advance\pgf@yb by-\pgf@ya% + \advance\pgf@xc by\pgf@xa% + \advance\pgf@yc by\pgf@ya% + \edef\pgf@marshal{\noexpand\pgfpathcurveto{\noexpand\pgf@plot@closedcurve@first@support}% + {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}{\noexpand\pgf@plot@closedcurve@initial}}% + {\pgf@marshal}% + % + % third, draw line from first to second point: + % + \edef\pgf@marshal{\noexpand\pgfpathcurveto{\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}% + {\noexpand\pgf@plot@closedcurve@after@initial@presupport}{\noexpand\pgf@plot@closedcurve@after@initial}}% + {\pgf@marshal}% + \pgfpathclose% + \fi% +} + + + + + +% This handler converts each point in a stream into a line from the +% $y$-axis to the given points coordinate, resulting in a +% ``comb.'' +% +% Example: +% +% \pgfplothandlerxcomb +% \pgfplotxyfile{mytable} + +\def\pgfplothandlerxcomb{% + \def\pgf@plotstreamstart{% + \global\let\pgf@plotstreampoint=\pgf@plot@xcomb@handler% + \global\let\pgf@plotstreamspecial=\pgfutil@gobble% + \global\let\pgf@plotstreamend=\pgfplotxzerolevelstreamend% + \pgfplotxzerolevelstreamstart + }% +} + +\def\pgf@plot@xcomb@handler#1{% + \pgf@process{#1}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \begingroup + \pgfplotxzerolevelstreamnext + \endgroup + \pgf@yb=\pgf@x + \pgfpathmoveto{\pgfqpoint{\pgf@yb}{\pgf@ya}}% + \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@ya}}% +} + + +% This handler converts each point in a stream into a line from the +% $x$-axis straight up to the given points coordinate, resulting in a +% ``comb.'' +% +% Example: +% +% \pgfplothandlerycomb +% \pgfplotxyfile{mytable} + +\def\pgfplothandlerycomb{% + \def\pgf@plotstreamstart{% + \global\let\pgf@plotstreampoint=\pgf@plot@ycomb@handler% + \global\let\pgf@plotstreamspecial=\pgfutil@gobble% + \global\let\pgf@plotstreamend=\pgfplotyzerolevelstreamend% + \pgfplotyzerolevelstreamstart + }% +} + +\def\pgf@plot@ycomb@handler#1{% + \pgf@process{#1}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \begingroup + \pgfplotyzerolevelstreamnext + \endgroup + \pgf@yb=\pgf@x + \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@yb}}% + \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@ya}}% +} + +% PGF Bar or comb plots usually draw something from zero to the current plot's coordinate. +% +% The 'zero' offset can be changed using an input stream. +% +% There are two such streams which can be configured independently. +% The first one returns "zeros" for coordinate x, the second one +% returns "zeros" for coordinate y. +% +% \pgfplotxzerolevelstreamstart +% \pgfplotxzerolevelstreamnext % assigns \pgf@x globally +% \pgfplotxzerolevelstreamnext +% \pgfplotxzerolevelstreamnext +% \pgfplotxzerolevelstreamend +% +% and +% \pgfplotyzerolevelstreamstart +% \pgfplotyzerolevelstreamnext % assigns \pgf@x globally +% \pgfplotyzerolevelstreamend +% +\def\pgfplotxzerolevelstreamstart{\pgf@plotxzerolevelstreamstart}% +\def\pgfplotxzerolevelstreamend{\pgf@plotxzerolevelstreamend}% +\def\pgfplotxzerolevelstreamnext{\pgf@plotxzerolevelstreamnext} +\def\pgfplotyzerolevelstreamstart{\pgf@plotyzerolevelstreamstart}% +\def\pgfplotyzerolevelstreamend{\pgf@plotyzerolevelstreamend}% +\def\pgfplotyzerolevelstreamnext{\pgf@plotyzerolevelstreamnext} + +% This zero level stream always returns '#1' (a dimension). +\def\pgfplotxzerolevelstreamconstant#1{% + \edef\pgfplotxzerolevelstreamconstant@val{#1}% + \def\pgf@plotxzerolevelstreamstart{% + \global\let\pgf@plotxzerolevelstreamend=\relax + \gdef\pgf@plotxzerolevelstreamnext{\global\pgf@x=\pgfplotxzerolevelstreamconstant@val\relax}% + }% +}% +\pgfplotxzerolevelstreamconstant{0pt}% + +% This zero level stream always returns '#1'. +\def\pgfplotyzerolevelstreamconstant#1{% + \edef\pgfplotyzerolevelstreamconstant@val{#1}% + \def\pgf@plotyzerolevelstreamstart{% + \global\let\pgf@plotyzerolevelstreamend=\relax + \gdef\pgf@plotyzerolevelstreamnext{\global\pgf@x=\pgfplotyzerolevelstreamconstant@val\relax}% + }% +}% +\pgfplotyzerolevelstreamconstant{0pt}% + +\def\pgfplotbarwidth{\pgfkeysvalueof{/pgf/bar width}} + +\pgfqkeys{/pgf}{% + bar width/.initial=10pt, + bar shift/.initial=0pt, + bar interval width/.initial=1, + bar interval shift/.initial=0.5, +} + +% This handler places a rectangle at each point in the plot stream, a +% rectangle which touches the x-axis at one end and the current point +% at the other end: +% --(X)-- +% | | +% | | +% | | +% --(0)-- +% Example: +% +% \pgfplothandlerybar +% \pgfplotxyfile{mytable} +\def\pgfplothandlerybar{% + \def\pgf@plotstreamstart{% + \global\let\pgf@plotstreampoint=\pgf@plot@ybar@handler% + \global\let\pgf@plotstreamspecial=\pgfutil@gobble% + \global\let\pgf@plotstreamend=\pgfplotyzerolevelstreamend% + \pgfmathparse{\pgfplotbarwidth}% + \xdef\pgfplotbarwidth@{\pgfmathresult pt}% + \pgfmathparse{\pgfkeysvalueof{/pgf/bar shift}}% + \xdef\pgfplotbarshift@{\pgfmathresult pt}% + \pgfplotyzerolevelstreamstart + }% +} + +\def\pgf@plot@ybar@handler#1{% + \pgf@process{#1}% + \pgf@ya=\pgf@y + \expandafter\pgf@xb\pgfplotbarwidth@\relax + \pgf@xc=\pgf@x + \advance\pgf@xc by-.5\pgf@xb + \advance\pgf@xc by\pgfplotbarshift@\relax + \begingroup + \pgfplotyzerolevelstreamnext + \endgroup + \pgf@yb=\pgf@x + \advance\pgf@ya by-\pgf@yb + \pgfpathrectangle + {\pgfqpoint{\pgf@xc}{\pgf@yb}}% + {\pgfqpoint{\pgf@xb}{\pgf@ya}}% +} + +% This handler places a rectangle at each point in the plot stream, a +% rectangle which touches the y-axis at one end and the current point +% at the other end: +% --------- +% | | +% (0) (X) +% | | +% --------- +% Example: +% +% \pgfplothandlerxbar +% \pgfplotxyfile{mytable} +\def\pgfplothandlerxbar{% + \def\pgf@plotstreamstart{% + \global\let\pgf@plotstreampoint=\pgf@plot@xbar@handler% + \global\let\pgf@plotstreamspecial=\pgfutil@gobble% + \global\let\pgf@plotstreamend=\pgfplotxzerolevelstreamend% + \pgfmathparse{\pgfplotbarwidth}% + \xdef\pgfplotbarwidth@{\pgfmathresult pt}% + \pgfmathparse{\pgfkeysvalueof{/pgf/bar shift}}% + \xdef\pgfplotbarshift@{\pgfmathresult pt}% + \pgfplotxzerolevelstreamstart + }% +} + +\def\pgf@plot@xbar@handler#1{% + \pgf@process{#1}% + \pgf@ya=\pgf@x + \expandafter\pgf@xb\pgfplotbarwidth@\relax + \pgf@xc=\pgf@y + \advance\pgf@xc by-.5\pgf@xb + \advance\pgf@xc by\pgfplotbarshift@\relax + \begingroup + \pgfplotxzerolevelstreamnext + \endgroup + \pgf@yb=\pgf@x + \advance\pgf@ya by-\pgf@yb + \pgfpathrectangle + {\pgfqpoint{\pgf@yb}{\pgf@xc}}% + {\pgfqpoint{\pgf@ya}{\pgf@xb}}% +} + +% This handler is a variant of \pgfplothandlerybar which works with +% intervals instead of points. +% +% Bars are drawn between successive input coordinates and the width is +% determined relatively to the interval length. +% +% It looks like this: +% +% |---| |-----| +% | | | | +% | | | | +% | | | | +% (X)------(X)-----------(X) +% +% where (X) denotes the x-axis offsets of input coordinates. +% +% In more detail, if (x_i,y_i) and (x_{i+1},y_{i+1}) denote successive +% input coordinates, the bar will be placed above the +% interval [x_i,x_{i+1}], centered at +% +% x_i + \pgfkeysvalueof{/pgf/bar interval shift} * (x_{i+1} - x_i) +% +% with width +% +% \pgfkeysvalueof{/pgf/bar interval width} * (x_{i+1} - x_i). +% +% If you have N+1 input points, you will get N bars (one for each +% interval). The y_i value of the last bar will be ignored. +% +% Example: +% +% \pgfplothandlerybarinterval +% \pgfplotxyfile{mytable} +\def\pgfplothandlerybarinterval{% + \def\pgf@plotstreamstart{% + \global\let\pgf@plotstreampoint=\pgf@plot@ybarinterval@handler@first% + \global\let\pgf@plotstreamspecial=\pgfutil@gobble% + \global\let\pgf@plotstreamend=\pgfplotyzerolevelstreamend% + \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval width}}% + \xdef\pgfplotbarintervalwidth@{\pgfmathresult}% + \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval shift}}% + \xdef\pgfplotbarintervalshift@{\pgfmathresult}% + \pgfplotyzerolevelstreamstart + }% +} + +\def\pgf@plot@ybarinterval@handler@first#1{% + \pgf@process{#1}% + \xdef\pgf@plot@barinterval@intervalstart{\the\pgf@x}% + \xdef\pgf@plot@barinterval@bar{\the\pgf@y}% + \global\let\pgf@plotstreampoint=\pgf@plot@ybarinterval@handler% +} +\def\pgf@plot@ybarinterval@handler#1{% + \pgf@process{#1}% + \pgf@ya=\pgf@plot@barinterval@bar + \xdef\pgf@plot@barinterval@bar{\the\pgf@y}% + \pgf@xc=\pgf@plot@barinterval@intervalstart\relax + \xdef\pgf@plot@barinterval@intervalstart{\the\pgf@x}% + \pgf@xb=\pgf@x + \advance\pgf@xb by-\pgf@xc + \advance\pgf@xc by\pgfplotbarintervalshift@\pgf@xb + \pgf@xb=\pgfplotbarintervalwidth@\pgf@xb + \advance\pgf@xc by-.5\pgf@xb% center + \begingroup + \pgfplotyzerolevelstreamnext + \endgroup + \pgf@yb=\pgf@x + \advance\pgf@ya by-\pgf@yb + \pgfpathrectangle + {\pgfqpoint{\pgf@xc}{\pgf@yb}}% + {\pgfqpoint{\pgf@xb}{\pgf@ya}}% +} + +% Like \pgfplothandlerybarinterval but for xbar. +\def\pgfplothandlerxbarinterval{% + \def\pgf@plotstreamstart{% + \global\let\pgf@plotstreampoint=\pgf@plot@xbarinterval@handler@first% + \global\let\pgf@plotstreamspecial=\pgfutil@gobble% + \global\let\pgf@plotstreamend=\pgfplotxzerolevelstreamend% + \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval width}}% + \xdef\pgfplotbarintervalwidth@{\pgfmathresult}% + \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval shift}}% + \xdef\pgfplotbarintervalshift@{\pgfmathresult}% + \pgfplotxzerolevelstreamstart + }% +} + +\def\pgf@plot@xbarinterval@handler@first#1{% + \pgf@process{#1}% + \xdef\pgf@plot@barinterval@intervalstart{\the\pgf@y}% + \xdef\pgf@plot@barinterval@bar{\the\pgf@x}% + \global\let\pgf@plotstreampoint=\pgf@plot@xbarinterval@handler% +} +\def\pgf@plot@xbarinterval@handler#1{% + \pgf@process{#1}% + \pgf@ya=\pgf@plot@barinterval@bar + \xdef\pgf@plot@barinterval@bar{\the\pgf@x}% + \pgf@xc=\pgf@plot@barinterval@intervalstart\relax + \xdef\pgf@plot@barinterval@intervalstart{\the\pgf@y}% + \pgf@xb=\pgf@y + \advance\pgf@xb by-\pgf@xc + \advance\pgf@xc by\pgfplotbarintervalshift@\pgf@xb + \pgf@xb=\pgfplotbarintervalwidth@\pgf@xb + \advance\pgf@xc by-.5\pgf@xb% center + \begingroup + \pgfplotxzerolevelstreamnext + \endgroup + \pgf@yb=\pgf@x + \advance\pgf@ya by-\pgf@yb + \pgfpathrectangle + {\pgfqpoint{\pgf@yb}{\pgf@xc}}% + {\pgfqpoint{\pgf@ya}{\pgf@xb}}% +} + + +% This handler is very similar to \pgfplothandlerlineto, but it +% produces CONSTANT connected pieces of the form +% +% x +% | +% x--- | +% | x---- +% x-| +% +% Example: +% +% \pgfplothandlerconstantlineto +% \pgfplotxyfile{mytable} +\def\pgfplothandlerconstantlineto{% + \def\pgf@plotstreamstart{% + \global\let\pgf@plotstreampoint=\pgf@plot@const@line@handler% + \global\let\pgf@plotstreamspecial=\pgfutil@gobble% + \global\let\pgf@plotstreamend=\relax% + }% +} +\def\pgf@plot@const@line@handler#1{% + \pgf@plot@first@action{#1}% + \xdef\pgf@plot@const@line@handler@last{\the\pgf@y}% + \global\let\pgf@plotstreampoint=\pgf@plot@const@line@handler@@% +} +\def\pgf@plot@const@line@handler@@#1{% + \pgf@process{#1}% + \pgf@xa=\pgf@x + \pgf@ya=\pgf@y + \expandafter\pgf@yb\pgf@plot@const@line@handler@last + \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}% + \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@ya}}% + \xdef\pgf@plot@const@line@handler@last{\the\pgf@ya}% +} + +% A variant of \pgfplothandlerconstantlineto which places its mark on +% the right line ends. +% +% |---x +% ---x | +% |--x +% x +% +% Example: +% +% \pgfplothandlerconstantlinetomarkright +% \pgfplotxyfile{mytable} +\def\pgfplothandlerconstantlinetomarkright{% + \def\pgf@plotstreamstart{% + \global\let\pgf@plotstreampoint=\pgf@plot@const@line@mark@right@handler% + \global\let\pgf@plotstreamspecial=\pgfutil@gobble% + \global\let\pgf@plotstreamend=\relax% + }% +} +\def\pgf@plot@const@line@mark@right@handler#1{% + \pgf@plot@first@action{#1}% + \xdef\pgf@plot@const@line@handler@last{\the\pgf@x}% + \global\let\pgf@plotstreampoint=\pgf@plot@const@line@mark@right@handler@@% +} +\def\pgf@plot@const@line@mark@right@handler@@#1{% + \pgf@process{#1}% + \pgf@xa=\pgf@x + \pgf@ya=\pgf@y + \expandafter\pgf@yb\pgf@plot@const@line@handler@last + \pgfpathlineto{\pgfqpoint{\pgf@yb}{\pgf@ya}}% + \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@ya}}% + \xdef\pgf@plot@const@line@handler@last{\the\pgf@xa}% +} + +% This handler is in fact a variant of \pgfplothandlerconstantlineto, +% but it does not draw vertical lines. It produces a sequence of +% line-to and move-to operations such that plot marks are placed at +% each right end: +% +% ---x +% ---x +% ---x +% --x +% +% Example: +% +% \pgfplothandlerjumpmarkright +% \pgfplotxyfile{mytable} +\def\pgfplothandlerjumpmarkright{% + \def\pgf@plotstreamstart{% + \global\let\pgf@plotstreampoint=\pgf@plot@jumpmarkright@handler% + \global\let\pgf@plotstreamspecial=\pgfutil@gobble% + \global\let\pgf@plotstreamend=\relax% + }% +} +\def\pgf@plot@jumpmarkright@handler#1{% + \pgf@plot@first@action{#1}% + \xdef\pgf@plot@const@line@handler@last{\the\pgf@x}% + \global\let\pgf@plotstreampoint=\pgf@plot@jumpmarkright@handler@@% +} +\def\pgf@plot@jumpmarkright@handler@@#1{% + \pgf@process{#1}% + \pgf@xa=\pgf@x + \pgf@ya=\pgf@y + \expandafter\pgf@yb\pgf@plot@const@line@handler@last + \pgfpathmoveto{\pgfqpoint{\pgf@yb}{\pgf@ya}}% + \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@ya}}% + \xdef\pgf@plot@const@line@handler@last{\the\pgf@xa}% +} + +% This handler is in fact a variant of \pgfplothandlerconstantlineto, +% but it does not draw vertical lines. It produces a sequence of +% line-to and move-to operations such that plot marks are placed at +% each left end: +% +% x--- +% x--- +% x--- +% x-- +% +% Example: +% +% \pgfplothandlerjumpmarkleft +% \pgfplotxyfile{mytable} +\def\pgfplothandlerjumpmarkleft{% + \def\pgf@plotstreamstart{% + \global\let\pgf@plotstreampoint=\pgf@plot@jumpmarkleft@handler% + \global\let\pgf@plotstreamspecial=\pgfutil@gobble% + \global\let\pgf@plotstreamend=\relax% + }% +} +\def\pgf@plot@jumpmarkleft@handler#1{% + \pgf@plot@first@action{#1}% + \xdef\pgf@plot@const@line@handler@last{\the\pgf@y}% + \global\let\pgf@plotstreampoint=\pgf@plot@jumpmarkleft@handler@@% +} +\def\pgf@plot@jumpmarkleft@handler@@#1{% + \pgf@process{#1}% + \pgf@xa=\pgf@x + \pgf@ya=\pgf@y + \expandafter\pgf@yb\pgf@plot@const@line@handler@last + \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}% + \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}% + \xdef\pgf@plot@const@line@handler@last{\the\pgf@ya}% +} + + + +% This handler converts each point in a stream into a line from the +% origin to the point's coordinate, resulting in a ``star''. +% +% Example: +% +% \pgfplothandlerpolarcomb +% \pgfplotxyfile{mytable} + +\def\pgfplothandlerpolarcomb{% + \def\pgf@plotstreamstart{% + \global\let\pgf@plotstreampoint=\pgf@plot@polarcomb@handler% + \global\let\pgf@plotstreamspecial=\pgfutil@gobble% + \global\let\pgf@plotstreamend=\relax% + }% +} + +\def\pgf@plot@polarcomb@handler#1{% + \pgf@process{#1}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgfpathmoveto{\pgfpointorigin}% + \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@ya}}% +} + + + + +% This handler draws a given mark at each point. +% +% #1 = some code to be executed at each point (with the coordinate +% system translated to that point). +% Typically, this code will be \pgfuseplotmark{whatever}. +% +% Example: +% +% \pgfplothandlermark{\pgfuseplotmark{*}} +% \pgfplotxyfile{mytable} + +\def\pgfplothandlermark#1{% + \pgf@plothandlermark{% + \ifnum\pgf@plot@mark@count<\pgf@plot@mark@repeat\relax% + \else% + \global\pgf@plot@mark@count=0\relax% + #1% + \fi% + }% +} + +\newcount\pgf@plot@mark@count +\def\pgf@plot@mark@phase{0} + +\def\pgf@plothandlermark#1{% + \def\pgf@plot@mark{#1}% + \def\pgf@plotstreamstart{% + \global\pgf@plot@mark@count=\pgf@plot@mark@repeat\relax% + \global\advance\pgf@plot@mark@count by-\pgf@plot@mark@phase\relax% + \global\let\pgf@plotstreampoint=\pgf@plot@mark@handler% + \global\let\pgf@plotstreamspecial=\pgfutil@gobble% + \global\let\pgf@plotstreamend=\relax% + }% +} + +\def\pgf@plot@mark@handler#1{% + \global\advance\pgf@plot@mark@count by1\relax% + {\pgftransformshift{#1}\pgf@plot@mark}% +} + + +% Set the repeat count for marks. For example, if 3 is given as a +% value, only every third point will get a mark. +% +% #1 = repeat count +% +% Example: +% +% \pgfsetplotmarkrepeat{2} + +\def\pgfsetplotmarkrepeat#1{\def\pgf@plot@mark@repeat{#1}} +\pgfsetplotmarkrepeat{1} + + +% Set the phase for marks. For example, if 3 is the repeat and 3 is +% the phase, already the first point will be marked. +% +% #1 = the index of the first point that should be marked. +% +% Example: +% +% \pgfsetplotmarkphase{3} + +\def\pgfsetplotmarkphase#1{\def\pgf@plot@mark@phase{#1}} +\pgfsetplotmarkphase{1} + + + +% This handler draws a given mark at those points whose number is +% given in the (pgffor-like) list. +% +% #1 = some code to be executed at each point (with the coordinate +% system translated to that point). +% Typically, this code will be \pgfuseplotmark{whatever}. +% #2 = list of positions like "1,2,4,...,9,10" +% +% Example: +% +% \pgfplothandlermarklisted{\pgfuseplotmark{*}}{1,2,4,...,9} +% \pgfplotxyfile{mytable} + +\def\pgfplothandlermarklisted#1#2{% + \let\pgf@plot@mark@list=\pgfutil@empty% + \edef\pgf@marshal{\noexpand\foreach\noexpand\pgf@temp in{#2}} + \pgf@marshal{\xdef\pgf@plot@mark@list{\pgf@plot@mark@list(\pgf@temp)}}% + \pgf@plothandlermark{% + \edef\pgf@marshal{\noexpand\pgfutil@in@{(\the\pgf@plot@mark@count)}{\pgf@plot@mark@list}}% + \pgf@marshal% + \ifpgfutil@in@#1\fi}% +} + + +% Define a new plot mark for use with \pgfplotmark. +% +% #1 = a plot mark mnemonic +% #2 = code for drawing the mark +% +% Example: +% +% \pgfdeclareplotmark{*}{\pgfpathcircle{\pgfpointorigin}{2pt}\pgfusepathqfill} + +\def\pgfdeclareplotmark#1#2{\expandafter\def\csname pgf@plot@mark@#1\endcsname{#2}} + + +% Set the size of plot marks. For circles, this will be the radius, +% for other shapes it should be about half the width/height. +% +% Example: +% +% \pgfsetplotmarksize{1pt} + +\def\pgfsetplotmarksize#1{\pgfmathsetlength\pgfplotmarksize{#1}} + +\newdimen\pgfplotmarksize +\pgfplotmarksize=2pt + + +% Insert a plot mark's code at the origin. +% +% #1 = plot mark mnemonic +% +% Example: +% +% \pgfuseplotmark{*} + +\def\pgfuseplotmark#1{\csname pgf@plot@mark@#1\endcsname} + + +% A stroke-filled circle mark + +\pgfdeclareplotmark{*} +{% + \pgfpathcircle{\pgfpointorigin}{\pgfplotmarksize} + \pgfusepathqfillstroke +} + + +% A plus-sign like mark + +\pgfdeclareplotmark{+} +{% + \pgfpathmoveto{\pgfqpoint{-\pgfplotmarksize}{0pt}} + \pgfpathlineto{\pgfqpoint{\pgfplotmarksize}{0pt}} + \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}} + \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}} + \pgfusepathqstroke +} + + +% An x-shaped mark + +\pgfdeclareplotmark{x} +{% + \pgfpathmoveto{\pgfqpoint{-.70710678\pgfplotmarksize}{-.70710678\pgfplotmarksize}} + \pgfpathlineto{\pgfqpoint{.70710678\pgfplotmarksize}{.70710678\pgfplotmarksize}} + \pgfpathmoveto{\pgfqpoint{-.70710678\pgfplotmarksize}{.70710678\pgfplotmarksize}} + \pgfpathlineto{\pgfqpoint{.70710678\pgfplotmarksize}{-.70710678\pgfplotmarksize}} + \pgfusepathqstroke +} + +% See pgflibraryplotmarks for more plot marks + + + + + + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfmathfloat.code.tex b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfmathfloat.code.tex new file mode 100644 index 00000000000..e199d44f811 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfmathfloat.code.tex @@ -0,0 +1,2322 @@ +% Copyright 2008 by Christian Feuersaenger +% +% 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 contains methods for basic floating point arithmetics, rounding +% to arbitrary precision and number pretty printing. +% +% Version 0.9.4 2008/03/18 + +\global\newif\ifpgfmathfloatcomparison +\newif\ifpgfmathfloatroundhasperiod +\newif\ifpgfmathprintnumberskipzeroperiod + + +% used internally in grouped macros: +\toksdef\pgfmathfloat@tmptoks=1 +\newif\ifpgfmathfloat@fixed@digits@after@period +\newif\ifpgfmathfloatroundmayneedrenormalize +\toksdef\pgfmathfloat@a@Mtok=0 + +%% WARNING: avoid conflicting register names! +\let\pgfmathfloat@a@S=\c@pgf@counta +\let\pgfmathfloat@a@M=\pgf@xa +\let\pgfmathfloat@a@E=\c@pgf@countb +\let\pgfmathfloat@b@S=\c@pgf@countc +\let\pgfmathfloat@b@M=\pgf@xb +\let\pgfmathfloat@b@E=\c@pgf@countd + +% can be changed with options. +\def\pgfmathfloat@round@precision{2} + +\gdef\pgfmathfloat@glob@TMP{} + + +% Computes a normalised floating point representation for #1 of the +% form +% [FLAGS] MANTISSE EXPONENT +% meaning +% [+-]X.XXXXXXX*10^C +% where +% X.XXXXXX is a mantisse with first number != 0, C is an integer and +% FLAGS contains the sign and some other special cases. +% +% This method does NOT use TeX Registers to represent the numbers! The +% computation is COMPLETELY STRING BASED. +% This allows numbers such at 10000000 or 5.23e-10 to be represented +% properly, although TeX-registers would produce overflow/underflow +% errors in these cases. +% +% It is to be used to compute logs, because log(X*10^Y) = log(X) + log(10)*Y +% +% Arguments: +% #1: an arbitrary number which shall be parsed. Maybe a macro. +% Examples: +% [+-]XXXXX.XXXXXX +% [+-]XXXXX.XXXXXXeXXXX +% [+-]0.0000XXXXXX +% [+-]0.0000XXXXXXeXXXX +% [+-]inf +% nan +% Maybe a macro containing such a number. +% +% Return value: +% \pgfmathresult will be \def'ed to +% FLAGS MANTISSE 'e' EXPONENT +% where +% FLAGS is a number in [0-5] where +% 0 == '0' (the number is +- 0.0), +% 1 == '+', +% 2 == '-', +% 3 == 'not a number' +% 4 == '+ infinity' +% 5 == '- infinity' +% +% MANTISSE is a normalised number 1 <= M < 10. It always contains a +% period and at least one digit after the period. +% +% EXPONENT is an integer value. +% +% Example: +% \pgfmathfloatparsenumber{1} +% -> \pgfmathresult = 11.0e0 +% \pgfmathfloatparsenumber{141.212} +% -> \pgfmathresult = 11.41212e2 +\def\pgfmathfloatparsenumber#1{% + \begingroup + \edef\pgfmathresult{#1}% + \expandafter\pgfmathfloatparsenumber@impl\pgfmathresult\pgfmathfloat@EOI + \ifpgfmathfloatparsenumberpendingperiod + \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok.0}% + \fi + \edef\pgfmathresult{% + \the\pgfmathfloat@a@S\the\pgfmathfloat@a@Mtok e\the\pgfmathfloat@a@E}% + \pgfmath@smuggleone\pgfmathresult + \endgroup +} + +% The same as \pgfmathfloatparsenumber, but does not perform sanity checking. +\def\pgfmathfloatqparsenumber#1{% + \begingroup + \let\pgfmathfloatparsenumber@sanitize@digit=\relax + \edef\pgfmathresult{#1}% + \expandafter\pgfmathfloatparsenumber@impl\pgfmathresult\pgfmathfloat@EOI + \ifpgfmathfloatparsenumberpendingperiod + \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok.0}% + \fi + \edef\pgfmathresult{% + \the\pgfmathfloat@a@S\the\pgfmathfloat@a@Mtok e\the\pgfmathfloat@a@E}% + \pgfmath@smuggleone\pgfmathresult + \endgroup +} + + +% decomposes a lowlevel floating point representation into flags, +% mantisse and exponent. +% +% #4: integer register for the flags. +% #5: dimen registers for the mantisse. +% #6: integer register for the exponent. +\def\pgfmathfloat@decompose#1#2e#3\relax#4#5#6{% + #4=#1\relax + #5=#2pt% + #6=#3\relax% +} +% overloaded, #5 needs to be a token register for the mantisse. +\def\pgfmathfloat@decompose@tok#1#2e#3\relax#4#5#6{% + #4=#1\relax + #5={#2}% + #6=#3\relax% +} +% overloaded, returns only ONE of the three components into #4: +\def\pgfmathfloat@decompose@F#1#2e#3\relax#4{#4=#1\relax}% +\def\pgfmathfloat@decompose@M#1#2e#3\relax#4{#4=#2pt}% +\def\pgfmathfloat@decompose@Mtok#1#2e#3\relax#4{#4={#2}}% +\def\pgfmathfloat@decompose@E#1#2e#3\relax#4{#4=#3\relax}% + +% Takes a floating point number #1 as input and writes flags to macro +% #2, mantisse to macro #3 and exponent to macro #4. +\def\pgfmathfloattomacro#1#2#3#4{% + \begingroup + \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E + \xdef\pgfmathfloat@glob@TMP{% + \noexpand\def\noexpand#2{\the\pgfmathfloat@a@S}% + \noexpand\def\noexpand#3{\the\pgfmathfloat@a@Mtok}% + \noexpand\def\noexpand#4{\the\pgfmathfloat@a@E}% + }% + \endgroup + \pgfmathfloat@glob@TMP +} + +% Takes a floating point number #1 as input and writes flags to count +% register #2, mantisse to dimen register #3 and exponent to count +% register #4. +\def\pgfmathfloattoregisters#1#2#3#4{% + \expandafter\pgfmathfloat@decompose#1\relax{#2}{#3}{#4}% +} + +% the same, but writes the mantisse into a token register. +\def\pgfmathfloattoregisterstok#1#2#3#4{% + \expandafter\pgfmathfloat@decompose@tok#1\relax{#2}{#3}{#4}% +} + +% Extracts the flags of #1 into the count register #2. +\def\pgfmathfloatgetflags#1#2{% + \expandafter\pgfmathfloat@decompose@F#1\relax{#2}% +} +% Extracts the mantisse of #1 into the dimen register #2. +\def\pgfmathfloatgetmantisse#1#2{% + \expandafter\pgfmathfloat@decompose@M#1\relax{#2}% +} +% Extracts the mantisse of #1 into the token register #2. +\def\pgfmathfloatgetmantissetok#1#2{% + \expandafter\pgfmathfloat@decompose@Mtok#1\relax{#2}% +} +% Extracts the exponent of #1 into the count register #2. +\def\pgfmathfloatgetexponent#1#2{% + \expandafter\pgfmathfloat@decompose@E#1\relax{#2}% +} + +% Defines \pgfmathresult as the floating point number encoded by +% the flags #1, mantisse #2 and exponent #3. +% +% All arguments are characters and will be expanded using '\edef'. +\def\pgfmathfloatcreate#1#2#3{% + \edef\pgfmathresult{#1#2e#3}% +}% + + +% Compares #1 with #2 and sets \pgfmathresult either to 1.0 or 0.0. +% +% It also sets the boolean \ifpgfmathfloatcomparison (globally. +\def\pgfmathfloatlessthan@#1#2{% +%\def\pgfmathfloatlessthan#1#2#3\and#4#5#6{% + \global\pgfmathfloatcomparisonfalse + \begingroup + \expandafter\pgfmathfloat@decompose#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@M\pgfmathfloat@a@E + \expandafter\pgfmathfloat@decompose#2\relax\pgfmathfloat@b@S\pgfmathfloat@b@M\pgfmathfloat@b@E + \ifcase\pgfmathfloat@a@S + % x = 0 -> (x y >0) + \ifnum1=\pgfmathfloat@b@S + \global\pgfmathfloatcomparisontrue + \fi + \or + % x > 0 -> (x ( y > 0 && |x| < |y|) ) + \ifnum1=\pgfmathfloat@b@S + % y>0: + \pgfmathfloatlessthan@positive + \fi + \or + % x < 0 -> (x (y >= 0 || |x| > |y|) ) + \ifnum2=\pgfmathfloat@b@S + % 'y<0': + \pgfmathfloatgreaterthan@positive + \else + \global\pgfmathfloatcomparisontrue + \fi + \else + \pgfmath@error{Sorry, 'pgfmathfloatlessthan@{#1}{#2}' not yet supported.}% + \fi + \endgroup + \ifpgfmathfloatcomparison + \def\pgfmathresult{1.0}% + \else + \def\pgfmathresult{0.0}% + \fi +} +\let\pgfmathfloatlessthan=\pgfmathfloatlessthan@ + +% compares \pgfmathfloat@a@[SME] < \pgfmathfloat@b@[SME] +\def\pgfmathfloatlessthan@positive{% + \ifnum\pgfmathfloat@a@E<\pgfmathfloat@b@E + \global\pgfmathfloatcomparisontrue + \else + \ifnum\pgfmathfloat@a@E=\pgfmathfloat@b@E + \ifdim\pgfmathfloat@a@M<\pgfmathfloat@b@M + \global\pgfmathfloatcomparisontrue + \fi + \fi + \fi +} + +% compares \pgfmathfloat@a@[SME] > \pgfmathfloat@b@[SME] +\def\pgfmathfloatgreaterthan@positive{% + \ifnum\pgfmathfloat@a@E>\pgfmathfloat@b@E + \global\pgfmathfloatcomparisontrue + \else + \ifnum\pgfmathfloat@a@E=\pgfmathfloat@b@E + \ifdim\pgfmathfloat@a@M>\pgfmathfloat@b@M + \global\pgfmathfloatcomparisontrue + \fi + \fi + \fi +} + + +\def\pgfmathfloatmax@#1#2{% + \pgfmathfloatlessthan{#1}{#2}% + \ifpgfmathfloatcomparison + \edef\pgfmathresult{#2}% + \else + \edef\pgfmathresult{#1}% + \fi +} +\let\pgfmathfloatmax=\pgfmathfloatmax@ + +\def\pgfmathfloatmin@#1#2{% + \pgfmathfloatlessthan{#1}{#2}% + \ifpgfmathfloatcomparison + \edef\pgfmathresult{#1}% + \else + \edef\pgfmathresult{#2}% + \fi +} +\let\pgfmathfloatmin=\pgfmathfloatmin@ + +% Renormalizes #1 to extended precision mantisse, meaning +% 100 <= m < 1000 +% instead of 1 <= m < 10. +% +% The 'extended precision' means we have higher accuracy when we apply pgfmath operations to mantisses. +% +% The input argument is expected to be a normalized floating point number; the output argument is a non-normalized floating point number (well, normalized to extended precision). +% +% The operation is supposed to be very fast. +\def\pgfmathfloattoextentedprecision#1{% + \begingroup + \pgfmathfloattoextentedprecision@a{#1}% + \pgfmathfloatcreate{\pgfmathfloat@a@S}{\pgfmathresult}{\pgfmathfloat@a@E}% + \pgfmath@smuggleone\pgfmathresult + \endgroup +}% + +\def\pgfmathfloattoextentedprecision@@zero#1\pgfmathfloat@EOI{% + \edef\pgfmathresult{#1}% +}% +\def\pgfmathfloattoextentedprecision@@one#1.#2#3\pgfmathfloat@EOI{% + \edef\pgfmathresult{#1#2.#3}% +}% +\def\pgfmathfloattoextentedprecision@@two#1.#2#3#4\pgfmathfloat@EOI{% + \edef\pgfmathresult{#1#2#3.#4}% +}% + +% Sets extended precision to 10^#1. +% +% The default is 10^2, which means mantissas in extended precision are +% normalised to 100 <= m < 1000. +% +% The case 10^1 means they are normalised to 10 <= m < 100 and 10^0 +% deactivates extended precision. +% +% #1 is the exponent, #1 = 0,1 or 2. +% +% This setting applies to \pgfmathfloattoextentedprecision. +\def\pgfmathfloatsetextprecision#1{% + \ifcase#1\relax + \let\pgfmathfloattoextentedprecision@@=\pgfmathfloattoextentedprecision@@zero + \def\pgfmathfloatextprec@shift{0}% + \or + \let\pgfmathfloattoextentedprecision@@=\pgfmathfloattoextentedprecision@@one + \def\pgfmathfloatextprec@shift{1}% + \else + \let\pgfmathfloattoextentedprecision@@=\pgfmathfloattoextentedprecision@@two + \def\pgfmathfloatextprec@shift{2}% + \fi +}% +\pgfmathfloatsetextprecision{2}% + +% Does the same work as \pgfmathfloattoextentedprecision, but this one here fills the +% registers \pgfmathfloat@a@S and \pgfmathfloat@a@E with the flags and (renormalized) exponent. +% It destroys the content of \pgfmathfloat@a@Mtok. +\def\pgfmathfloattoextentedprecision@a#1{% + \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E + \ifnum\pgfmathfloat@a@S<3 + \advance\pgfmathfloat@a@E by-\pgfmathfloatextprec@shift\relax% compensate for shift + \expandafter\pgfmathfloattoextentedprecision@@\the\pgfmathfloat@a@Mtok 00\pgfmathfloat@EOI + \else + \edef\pgfmathresult{#1}% + \fi +}% + + +% Similar to \pgfmathfloattoextentedprecision@a, this one here fills the '@b' registers. +\def\pgfmathfloattoextentedprecision@b#1{% + \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@b@S\pgfmathfloat@a@Mtok\pgfmathfloat@b@E + \ifnum\pgfmathfloat@b@S<3 + \advance\pgfmathfloat@b@E by-\pgfmathfloatextprec@shift\relax + \expandafter\pgfmathfloattoextentedprecision@@\the\pgfmathfloat@a@Mtok 00\pgfmathfloat@EOI + \else + \edef\pgfmathresult{#1}% + \fi +}% + +% Addition of two floating point numbers using 8 significant digits. +\def\pgfmathfloatadd@#1#2{% + \begingroup + % + % renormalize argument to 100 <= m < 1000 for extended accuracy: + \pgfmathfloattoextentedprecision@a{#1}% + \let\pgfmathfloat@arga=\pgfmathresult + % + \pgfmathfloattoextentedprecision@b{#2}% + \let\pgfmathfloat@argb=\pgfmathresult + % + \pgfmathfloatcomparisontrue% re-use this boolean here to handle special cases. + \ifcase\pgfmathfloat@a@S + \edef\pgfmathresult{#2}% + \pgfmathfloatcomparisonfalse + \or + \or + \edef\pgfmathfloat@arga{-\pgfmathfloat@arga}% + \else + \pgfmathfloatcomparisonfalse + \pgfmathfloatcreate{\the\pgfmathfloat@a@S}{0.0}{0}% + \fi + \ifcase\pgfmathfloat@b@S + \edef\pgfmathresult{#1}% + \pgfmathfloatcomparisonfalse + \or + \or + \edef\pgfmathfloat@argb{-\pgfmathfloat@argb}% + \else + \pgfmathfloatcomparisonfalse + \pgfmathfloatcreate{\the\pgfmathfloat@b@S}{0.0}{0}% + \fi + \ifpgfmathfloatcomparison + % Shift lesser mantisse to fit the larger one: + \ifnum\pgfmathfloat@a@E<\pgfmathfloat@b@E + \pgfmathfloatadd@shift{\pgfmathfloat@arga}{\pgfmathfloat@a@E}{\pgfmathfloat@b@E}% + \else + \pgfmathfloatadd@shift{\pgfmathfloat@argb}{\pgfmathfloat@b@E}{\pgfmathfloat@a@E}% + \fi + % add them! + \pgfmathadd@{\pgfmathfloat@arga}{\pgfmathfloat@argb}% + % renormalize sum. This is the only part were an expensive routine comes into play: + \edef\pgfmathresult{\pgfmathresult e\the\pgfmathfloat@a@E}% + \expandafter\pgfmathfloatqparsenumber\expandafter{\pgfmathresult}% + \fi + \pgfmath@smuggleone\pgfmathresult + \endgroup +}% + + +% #1=mantisse which needs to be shifted (with smaller exponent) +% #2=smaller exponent +% #3=larger exponent +% +% ATTENTION: this helper method DESTROYS contents of \pgfmathfloat@a@S. +\def\pgfmathfloatadd@shift#1#2#3{% + \pgf@xa=#1 pt% + \pgfmathfloat@a@S=#3\relax + \advance\pgfmathfloat@a@S by-#2\relax + \ifcase\pgfmathfloat@a@S + \or + \divide\pgf@xa by10\relax + \or + \divide\pgf@xa by100\relax + \or + \divide\pgf@xa by1000\relax + \or + \divide\pgf@xa by10000\relax + \or + \divide\pgf@xa by10000\relax + \divide\pgf@xa by10\relax + \or + \divide\pgf@xa by10000\relax + \divide\pgf@xa by100\relax + \or + \divide\pgf@xa by10000\relax + \divide\pgf@xa by1000\relax + \or + \divide\pgf@xa by10000\relax + \divide\pgf@xa by10000\relax + \else + \pgf@xa=0pt% + \fi + #2=#3\relax + \edef#1{\pgf@sys@tonumber\pgf@xa}% +} + +\let\pgfmathfloatadd=\pgfmathfloatadd@ + + +% Subtracts two floating point numbers. +\def\pgfmathfloatsubtract@#1#2{% + \begingroup + \expandafter\pgfmathfloat@decompose@tok#2\relax\pgfmathfloat@b@S\pgfmathfloat@a@Mtok\pgfmathfloat@b@E + \ifcase\pgfmathfloat@b@S + \edef\pgfmathresult{#1}% + \or + \pgfmathfloatcreate{2}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@b@E}% + \let\pgfmathfloatsub@arg=\pgfmathresult + \pgfmathfloatadd@{#1}{\pgfmathfloatsub@arg}% + \or + \pgfmathfloatcreate{1}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@b@E}% + \let\pgfmathfloatsub@arg=\pgfmathresult + \pgfmathfloatadd@{#1}{\pgfmathfloatsub@arg}% + \else + \pgfmathfloatcreate{\the\pgfmathfloat@b@S}{0.0}{0}% + \fi + \pgfmath@smuggleone\pgfmathresult + \endgroup +}% + +\let\pgfmathfloatsubtract=\pgfmathfloatsubtract@ + +% Scales a floating point number #1 with a fixed point number #2 using pgfmathmultiply. +% +% Use this method if #2 is small number. +\def\pgfmathfloatmultiplyfixed@#1#2{% + \begingroup + % + % renormalize argument to 100 <= m < 1000 for extended accuracy: + \pgfmathfloattoextentedprecision@a{#1}% + \let\pgfmathfloat@arga=\pgfmathresult + % + \pgfmathfloatcomparisontrue% re-use this boolean here to handle special cases. + \ifcase\pgfmathfloat@a@S + \edef\pgfmathresult{#1}% + \pgfmathfloatcomparisonfalse + \or + \or + \edef\pgfmathfloat@arga{-\pgfmathfloat@arga}% + \else + \pgfmathfloatcomparisonfalse + \pgfmathfloatcreate{\the\pgfmathfloat@a@S}{0.0}{0}% + \fi + \ifpgfmathfloatcomparison + \pgfmathmultiply@{\pgfmathfloat@arga}{#2}% + % renormalize product. This is the only part were an expensive routine comes into play: + \edef\pgfmathresult{\pgfmathresult e\the\pgfmathfloat@a@E}% + \expandafter\pgfmathfloatqparsenumber\expandafter{\pgfmathresult}% + \fi + \pgfmath@smuggleone\pgfmathresult + \endgroup +}% + +\let\pgfmathfloatmultiplyfixed=\pgfmathfloatmultiplyfixed@ + + +\def\pgfmathfloatmultiply@#1#2{% + \begingroup + \pgfmathfloatsetextprecision{1}% + \pgfmathfloattoextentedprecision@a{#1}% + \let\pgfmathfloat@arga=\pgfmathresult + % + \pgfmathfloattoextentedprecision@b{#2}% + \let\pgfmathfloat@argb=\pgfmathresult + % + \pgfmathfloatcomparisontrue% re-use this boolean here to handle special cases. + \ifcase\pgfmathfloat@a@S + % 0 + \pgfmathfloatcreate{0}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or% + + \ifcase\pgfmathfloat@b@S + \pgfmathfloatcreate{0}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \def\pgfmathresult@S{1}% + \or + \def\pgfmathresult@S{2}% + \else + \expandafter\pgfmathfloatcreate\the\pgfmathfloat@b@S{0.0}{0}% + \pgfmathfloatcomparisonfalse + \fi + \or% - + \ifcase\pgfmathfloat@b@S + \pgfmathfloatcreate{0}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \def\pgfmathresult@S{2}% + \or + \def\pgfmathresult@S{1}% + \or + \pgfmathfloatcreate{3}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{5}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{4}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \fi + \or% nan + \pgfmathfloatcreate{3}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or% +infty + \ifcase\pgfmathfloat@b@S + \pgfmathfloatcreate{0}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{4}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{5}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{3}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{4}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{5}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \fi + \or% -infty + \ifcase\pgfmathfloat@b@S + \pgfmathfloatcreate{0}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{5}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{4}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{3}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{5}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{4}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \fi + \fi + \ifpgfmathfloatcomparison + \pgfmathmultiply@{\pgfmathfloat@arga}{\pgfmathfloat@argb}% + \advance\pgfmathfloat@a@E by\pgfmathfloat@b@E + % renormalize sum. This is the only part were an expensive routine comes into play: + \edef\pgfmathresult{\pgfmathresult e\the\pgfmathfloat@a@E}% + \expandafter\pgfmathfloatqparsenumber\expandafter{\pgfmathresult}% + \expandafter\pgfmathfloat@decompose@tok\pgfmathresult\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E + \pgfmathfloatcreate{\pgfmathresult@S}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@a@E}% + \fi + \pgfmath@smuggleone\pgfmathresult + \endgroup +}% +\let\pgfmathfloatmultiply=\pgfmathfloatmultiply@ + +\def\pgfmathfloatdivide@#1#2{% + \begingroup + \pgfmathfloatsetextprecision{1}% + \pgfmathfloattoextentedprecision@a{#1}% + \let\pgfmathfloat@arga=\pgfmathresult + % + \pgfmathfloattoextentedprecision@b{#2}% + \let\pgfmathfloat@argb=\pgfmathresult + % + \pgfmathfloatcomparisontrue% re-use this boolean here to handle special cases. + \ifcase\pgfmathfloat@a@S + % 0 + \pgfmathfloatcreate{0}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or% + + \ifcase\pgfmathfloat@b@S + \pgfmathfloatcreate{4}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \def\pgfmathresult@S{1}% + \or + \def\pgfmathresult@S{2}% + \or + \pgfmathfloatcreate{3}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \else + \pgfmathfloatcreate{0}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \fi + \or% - + \ifcase\pgfmathfloat@b@S + \pgfmathfloatcreate{5}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \def\pgfmathresult@S{2}% + \or + \def\pgfmathresult@S{1}% + \or + \pgfmathfloatcreate{3}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \else + \pgfmathfloatcreate{0}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \fi + \or% nan + \pgfmathfloatcreate{3}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or% +infty + \ifcase\pgfmathfloat@b@S + \pgfmathfloatcreate{4}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{4}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{5}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{3}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{4}{0.0}{0}% what is inf/inf ? + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{5}{0.0}{0}% or inf/-inf ? + \pgfmathfloatcomparisonfalse + \fi + \or% -infty + \ifcase\pgfmathfloat@b@S + \pgfmathfloatcreate{5}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{5}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{4}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{3}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{5}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \or + \pgfmathfloatcreate{4}{0.0}{0}% + \pgfmathfloatcomparisonfalse + \fi + \fi + \ifpgfmathfloatcomparison + \pgfmathdivide@{\pgfmathfloat@arga}{\pgfmathfloat@argb}% + \advance\pgfmathfloat@a@E by-\pgfmathfloat@b@E + % renormalize sum. This is the only part were an expensive routine comes into play: + \edef\pgfmathresult{\pgfmathresult e\the\pgfmathfloat@a@E}% + \expandafter\pgfmathfloatqparsenumber\expandafter{\pgfmathresult}% + \expandafter\pgfmathfloat@decompose@tok\pgfmathresult\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E + \pgfmathfloatcreate{\pgfmathresult@S}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@a@E}% + \fi + \pgfmath@smuggleone\pgfmathresult + \endgroup +}% +\let\pgfmathfloatdivide=\pgfmathfloatdivide@ + +% Converts a composed floating point representation to fixed point. +% +% Example: +% \pgfmathfloattofixed{142e1} +% -> \pgfmathresult = 42.0 +\def\pgfmathfloattofixed@#1{% + \begingroup + \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E + \ifcase\pgfmathfloat@a@S + \def\pgfmathresult{0.0}% + \or + \expandafter\pgfmathfloattofixed@impl\the\pgfmathfloat@a@Mtok\relax + \or + \expandafter\pgfmathfloattofixed@impl\the\pgfmathfloat@a@Mtok\relax + \edef\pgfmathresult{-\pgfmathresult}% + \or\def\pgfmathresult{nan}% + \or\def\pgfmathresult{inf}% + \or\def\pgfmathresult{-inf}% + \fi + \pgfmath@smuggleone\pgfmathresult + \endgroup +} +\let\pgfmathfloattofixed=\pgfmathfloattofixed@ + +% Converts a floating point number to scientific format 1.234e5. +% +% This operation is very fast. +\def\pgfmathfloattosci@#1{% + \begingroup + \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E + \ifcase\pgfmathfloat@a@S + \def\pgfmathresult{0.0e0}% + \or + \edef\pgfmathresult{\the\pgfmathfloat@a@Mtok e\the\pgfmathfloat@a@E}% + \or + \edef\pgfmathresult{-\the\pgfmathfloat@a@Mtok e\the\pgfmathfloat@a@E}% + \or\def\pgfmathresult{nan}% + \or\def\pgfmathresult{inf}% + \or\def\pgfmathresult{-inf}% + \fi + \pgfmath@smuggleone\pgfmathresult + \endgroup +}% +\let\pgfmathfloattosci=\pgfmathfloattosci@ + +% Divides or multiplies the input number by 10^#4 using an arithmetic +% left/right shift. +% +% Input: +% #1 a normalised floating point number. +% #2 a positive or negative integer number denoting the shift. +% +% Example: +% \pgfmathfloatshift{11e3}{4}% +% -> pgfmathresult = 11e7 +\def\pgfmathfloatshift@#1#2{% + \begingroup + \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E + \expandafter\advance\expandafter\pgfmathfloat@a@E#2\relax + \edef\pgfmathresult{\the\pgfmathfloat@a@S\the\pgfmathfloat@a@Mtok e\the\pgfmathfloat@a@E}% + \pgfmath@smuggleone\pgfmathresult + \endgroup +} +\let\pgfmathfloatshift=\pgfmathfloatshift@ + +% Computes a good guess for log(X.XXXX) where the input number should +% be between 0 < x < 10. +% +% If it is not in this range, the returned value will be bad. +% +% For use in the newton implementation of log(x). Please note that we +% first compute a normalized floating point representation of x, and +% the mantisse is always between 0 and 10. +\def\pgfmathlog@smaller@ten@newton@startval#1.#2\to#3{% + \ifcase#1 + \pgfmath@error{pgfmathlog@newton: INTERNAL ERROR: should not happen! + [\#1=0 should have been caught before!]}% + \or#3=0.530628pt + \or#3=0.993pt + \or#3=1.308pt + \or#3=1.5pt + \or#3=1.71pt + \or#3=1.872pt + \or#3=2.01pt + \or#3=2.145pt + \or#3=2.24pt + \fi +} + +% FIXME : eliminate \pgfmathlog@invoke@expanded ? + +% Expands #2 using \edef and invokes #1 with the resulting string. +% +% Example: +% \pgfmath@y=7.9pt +% \pgfmathlog@invoke@expanded\pgfmathexp@{{\pgf@sys@tonumber{\pgfmath@y}}}% +% will invoke +% \pgfmathexp@{7.9} +\def\pgfmathlog@invoke@expanded#1#2{% + \edef\pgfmath@resulttemp{#2}% + \expandafter#1\pgfmath@resulttemp +} + +% This implementation of log(X) is done with a newton method applied to x-exp(y) = 0. +% The implementation \pgfmathexp is used for exp(y). +% +% see \pgfmathlog@ +\def\pgfmathlog@newton#1{% + \pgfmathfloatparsenumber{#1}% + \pgfmathlog@newton@float{\pgfmathresult}% +} + +% the same as \pgfmathlog@newton, but this one takes a floating point number as input. +\def\pgfmathlog@newton@float#1{% + \begingroup% + % compute #1 = M*10^E with normalised mantisse M = [+-]*[1-9].XXXXX + \expandafter\pgfmathfloat@decompose#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@M\pgfmathfloat@a@E + \let\pgfmathlog@loopcount=\pgfmathfloat@b@S% this counter is not used here... use it as loop counter. + % + \ifnum\pgfmathfloat@a@S=1 + % Now, compute log(#1) = log(M) + E*log(10) + \expandafter\pgfmathlog@smaller@ten@newton@startval\the\pgfmathfloat@a@M.\to\pgfmathfloat@b@M + \pgfmathlog@loopcount=0 + \pgfutil@loop + \ifnum\pgfmathlog@loopcount<3 + \pgfmathlog@invoke@expanded\pgfmathexp@{{\pgf@sys@tonumber{\pgfmathfloat@b@M}}}% + \let\pgfmathlog@tmp=\pgfmathresult + \pgfmathlog@invoke@expanded\pgfmathdivide@{{\pgf@sys@tonumber{\pgfmathfloat@a@M}}{\pgfmathlog@tmp}}% + \expandafter\pgfmath@ya\pgfmathresult pt + \advance\pgfmathfloat@b@M by\pgfmath@ya + \advance\pgfmathfloat@b@M by-1pt + \advance\pgfmathlog@loopcount by1 + \pgfutil@repeat + \pgfmathfloat@a@M=2.302585pt% = log(10) + \multiply\expandafter\pgfmathfloat@a@M\pgfmathfloat@a@E + \advance\pgfmathfloat@b@M by\pgfmathfloat@a@M + \edef\pgfmathresult{\pgf@sys@tonumber{\pgfmathfloat@b@M}}% + \else + \let\pgfmathresult=\pgfutil@empty% + \fi + \pgfmath@smuggleone\pgfmathresult + \endgroup% +} + +% Computes log(x) into \pgfmathresult. +% +% REMARK +% This method does NOT use TeX Registers to represent the numbers! The +% computation is COMPLETELY STRING BASED. +% This allows numbers such at 10000000 or 5.23e-10 to be represented +% properly, although TeX-registers would produce overflow/underflow +% errors in these cases. +% +% The natural logarithm is computed using log(X*10^Y) = log(X) + log(10)*Y +\let\pgfmathlog@=\pgfmathlog@newton + +\let\pgfmathlog@float=\pgfmathlog@newton@float + +% Public interface method. This is expected to use \pgfmathparse but +% it DOESN'T do that. \pgfmathparse naturally can't handle numbers +% which exceed TeX's numerical capabilities. However, exponentials are +% typically either too large or too small for TeX. +% +% @see \pgfmathnormalisedfloatingpoint for how we parse arguments. +% @see \pgfmathlog@ +\let\pgfmathlog=\pgfmathlog@newton + +% Rounds a fixed point number #1 to \pgfmathfloat@round@precision digits precision and returns +% the result into \pgfmathresult. +% +% Any trailing zeros after the period are discarded. +% See \pgfmathroundtozerofill if you want trailing zeros and fixed +% width. +% +% This method is PURELY text based and can work with arbirtrary +% precision (well, limited to TeX's stack size and integer size). +% +% Examples: +% \pgfmathroundto{1} +% -> \pgfmathresult = '1' +% +% \pgfmathroundto{19999.9996} +% -> \pgfmathresult = '20000' +% +% Arguments: +% #1 may be either a number or a macro expanding to a number. +% +% SIDE EFFECT: the global variable \ifpgfmathfloatroundhasperiod will be set. +\def\pgfmathroundto#1{% + \pgfmathfloatroundhasperiodtrue + \begingroup + \pgfmathfloat@fixed@digits@after@periodfalse + \pgfmathroundto@impl{#1}% + \pgfmath@smuggleone\pgfmathresult + \endgroup +} + + +% Overloaded method. +% +% This variant always uses a FIXED number behind the period and fills +% in zeros if necessary. +% Examples: +% \pgfmathroundtozerofill{1} +% -> \pgfmathresult = '1.00' +% +% \pgfmathroundtozerofill{19999.9996} +% -> \pgfmathresult = '20000.00' +% +% SIDE EFFECT: the global variable \ifpgfmathfloatroundhasperiod will be set. +\def\pgfmathroundtozerofill#1{% + \pgfmathfloatroundhasperiodtrue + \begingroup + \pgfmathfloat@fixed@digits@after@periodtrue + \pgfmathroundto@impl{#1}% + \pgfmath@smuggleone\pgfmathresult + \endgroup +} + +% see \pgfmathprintnumber@fixed@style for docs +\def\pgfmathprintnumber@fixed@styleDEFAULT#1#2#3e#4\relax{% + \begingroup + \pgfkeysgetvalue{/pgf/number format/set decimal separator}\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP + \pgfkeysgetvalue{/pgf/number format/@dec sep mark}\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP@MARK + \pgfkeysgetvalue{/pgf/number format/set thousands separator}\pgfmathprintnumber@fixed@styleDEFAULT@THOUSAND@SEP + \c@pgf@counta=#4\relax + \def\pgfmathresult{}% + \ifpgfmathfloatroundhasperiod + \expandafter\pgfmathprintnumber@fixed@styleDEFAULT@impl@period#1\pgfmathfloat@EOI + \else + \expandafter\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod#1\pgfmathfloat@EOI\pgfmathfloat@EOI\pgfmathfloat@EOI% + \begingroup + \toks0=\expandafter{\pgfmathresult}% + \toks1=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP@MARK}% + \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 }% + \endgroup + \let\pgfmathresult=\pgfmathfloat@glob@TMP + \fi + \pgfmath@smuggleone\pgfmathresult + \endgroup +} +\def\pgfmathprintnumber@fixed@styleDEFAULT@impl@period#1.#2\pgfmathfloat@EOI{% + \ifpgfmathprintnumberskipzeroperiod + \def\pgfmathfloat@loc@TMPb{#1}% + \ifx\pgfmathfloatparsenumber@tok@ZERO\pgfmathfloat@loc@TMPb + \else + \def\pgfmathfloat@loc@TMPc{-0}% + \ifx\pgfmathfloat@loc@TMPc\pgfmathfloat@loc@TMPb + \def\pgfmathresult{-}% + \else + \def\pgfmathfloat@loc@TMPc{+0}% + \ifx\pgfmathfloat@loc@TMPc\pgfmathfloat@loc@TMPb + \def\pgfmathresult{+}% + \else + \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod#1\pgfmathfloat@EOI\pgfmathfloat@EOI\pgfmathfloat@EOI + \fi + \fi + \fi + \else + \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod#1\pgfmathfloat@EOI\pgfmathfloat@EOI\pgfmathfloat@EOI + \fi + \begingroup + \toks0=\expandafter{\pgfmathresult}% + \toks1=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP@MARK}% + \toks2=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP #2}% + \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 \the\toks2 }% + \endgroup + \let\pgfmathresult=\pgfmathfloat@glob@TMP +}% +\def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod{% + \ifx\pgfmathprintnumber@fixed@styleDEFAULT@THOUSAND@SEP\pgfutil@empty + \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{% + \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printall}% + \else + \ifnum\c@pgf@counta<0\relax + \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{% + \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printall}% + \else + \advance\c@pgf@counta by1% counta:= total number of digits, N. + \c@pgf@countb=\c@pgf@counta + \divide\c@pgf@countb by3% countb := N DIV 3 + \c@pgf@countc=\c@pgf@countb + \multiply\c@pgf@countc by3 + \advance\c@pgf@counta by-\c@pgf@countc% now counta := N MOD 3 + \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{% + \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printsign + }% + \fi + \fi + \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT +} +\def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printsign#1{% + \def\pgfmathfloat@loc@TMPb{#1}% + \ifx\pgfmathfloat@loc@TMPb\pgfmathfloatparsenumber@tok@MINUS + \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult #1}% + \let\pgfmathfloat@loc@TMPb=\pgfutil@empty + \else + \ifx\pgfmathfloat@loc@TMPb\pgfmathfloatparsenumber@tok@PLUS + \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult #1}% + \let\pgfmathfloat@loc@TMPb=\pgfutil@empty + \else + \ifpgfmathprintnumber@showpositive + \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult +}% + \fi + \fi + \fi + \ifnum\c@pgf@counta>0 + \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{% + \expandafter\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printtrailingdigits\pgfmathfloat@loc@TMPb + }% + \else + \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{% + \expandafter\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@counteverythird\pgfmathfloat@loc@TMPb + }% + \fi + \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT +} +\def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printtrailingdigits#1#2{% + \ifcase\c@pgf@counta + \or + \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult #1}% + \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{% + \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@counteverythird#2% + }% + \or + \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult #1#2}% + \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{% + \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@counteverythird% + }% + \fi + \ifnum\c@pgf@countb>0\relax + \begingroup + \toks0=\expandafter{\pgfmathresult}% + \toks1=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@THOUSAND@SEP}% + \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 }% + \endgroup + \let\pgfmathresult=\pgfmathfloat@glob@TMP + \fi + \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT +} +\def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@counteverythird#1#2#3{% + \ifnum\c@pgf@countb>0\relax + \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult #1#2#3}% + \advance\c@pgf@countb by-1 + \ifnum\c@pgf@countb>0\relax + \begingroup + \toks0=\expandafter{\pgfmathresult}% + \toks1=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@THOUSAND@SEP}% + \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 }% + \endgroup + \let\pgfmathresult=\pgfmathfloat@glob@TMP + \fi + \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{% + \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@counteverythird% + }% + \else + % in thise case, #1#2#3 are expected to be + % \pgfmathfloat@EOI\pgfmathfloat@EOI\pgfmathfloat@EOI + %-------------------------------------------------- + % \def\pgfmathfloat@loc@TMPb{\pgfmathfloat@EOI\pgfmathfloat@EOI\pgfmathfloat@EOI}% + % \def\pgfmathfloat@loc@TMPc{#1#2#3}% + % \ifx\pgfmathfloat@loc@TMPc\pgfmathfloat@loc@TMPb + % \else + % \pgfmath@error{INTERNAL ERROR in fixed style - The input sequence did not terminate as expected; which indicates a wrong exponent argument provided to \string\pgfmathprintnumber@fixed@style}% + % \fi + %-------------------------------------------------- + \let\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT=\relax + \fi + \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT +} +\def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printall#1{% + \def\pgfmathfloat@loc@TMPb{#1}% + \let\pgfmathfloat@loc@TMPc=\pgfutil@empty + \ifx\pgfmathfloat@loc@TMPb\pgfmathfloatparsenumber@tok@MINUS + \else + \ifx\pgfmathfloat@loc@TMPb\pgfmathfloatparsenumber@tok@PLUS + \else + \ifpgfmathprintnumber@showpositive + \def\pgfmathfloat@loc@TMPc{+}% + \fi + \fi + \fi + \expandafter\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printall@\pgfmathfloat@loc@TMPc#1% +} +\def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printall@#1\pgfmathfloat@EOI\pgfmathfloat@EOI\pgfmathfloat@EOI{% + \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult #1}% +}% + +% #1 maybe a macro +\def\pgfmathprintnumber@fixed@stylePERIOD#1#2#3e#4\relax{% + \def\pgfmathresult{#1}% +} + +% #1 maybe a macro +\def\pgfmathprintnumber@fixed@styleCOMMA#1#2#3e#4\relax{% + \ifpgfmathfloatroundhasperiod + \expandafter\pgfmathprintnumber@fixed@styleCOMMA@impl#1\pgfmathfloat@EOI + \else + \def\pgfmathresult{#1}% + \fi +} +\def\pgfmathprintnumber@fixed@styleCOMMA@impl#1.#2\pgfmathfloat@EOI{\def\pgfmathresult{#1{,}#2}} + +% The default style to display fixed point numbers. +% +% It does not apply numerics, but it is responsable to typeset the +% rounded number. +% It can access the \ifpgfmathfloatroundhasperiod boolean. +% +% Arguments: +% #1#2#3e#4\relax + +% Input: +% #1 the fixed point number to be displayed (maybe a macro). +% #2#3e#4: the (possibly unformatted) floating point representation which belongs to #1. +% It is used to determine sign and exponent. +\let\pgfmathprintnumber@fixed@style=\pgfmathprintnumber@fixed@styleDEFAULT + + +% Rounds a normalized floating point number to \pgfmathfloat@round@precision +% digits precision and writes the result to \pgfmathresult. +% +% This method uses \pgfmathroundto for the mantisse. +% +% @see pgfmathfloatroundzerofill +% +% SIDE EFFECT: the global variable \ifpgfmathfloatroundhasperiod will be set to +% whether the final mantisse #5 has a period or not. +\def\pgfmathfloatround#1{% + \pgfmathfloatroundhasperiodtrue + \begingroup + \pgfmathfloat@fixed@digits@after@periodfalse + \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E + \pgfmathfloatround@impl + \pgfmath@smuggleone\pgfmathresult + \endgroup +} + +% Overload. +% +% This method uses a fixed width for the mantisse and fills in zeros +% if necessary. +% +% This method uses \pgfmathroundtozerofill for the mantisse. +% +% SIDE EFFECT: the global variable \ifpgfmathfloatroundhasperiod will be set to +% whether the final mantisse #5 has a period or not. +\def\pgfmathfloatroundzerofill#1{% + \pgfmathfloatroundhasperiodtrue + \begingroup + \pgfmathfloat@fixed@digits@after@periodtrue + \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E + \pgfmathfloatround@impl + \pgfmath@smuggleone\pgfmathresult + \endgroup +} + +\newif\ifpgfmathfloatround@allow@empty@mantisse +\def\pgfmathfloatround@mantisse@ONE{1.0}% + +% #1: sign +% #2: mantisse +% #3: exponent +% #4: CODE to display if the mantisse is drawn. +% #5: CODE to display if the mantisse is NOT draw. (unused) +% #6: CODE to display the exponent. +\def\pgfmathfloatrounddisplaystyle@shared@impl#1#2e#3\relax#4#5#6{% + \pgfkeysgetvalue{/pgf/number format/@sci exponent mark}\pgfmathfloatrounddisplaystyle@e@mark + \ifcase#1\relax + \pgfmathprintnumber@fixed@style{#2}#1#2e0\relax% + \expandafter\pgfmathfloatrounddisplaystyle@shared@impl@\expandafter{\pgfmathresult}{#4#6}% + \or\pgfmathprintnumber@fixed@style{#2}#1#2e0\relax% + \expandafter\pgfmathfloatrounddisplaystyle@shared@impl@\expandafter{\pgfmathresult}{#4#6}% + \or\pgfmathprintnumber@fixed@style{-#2}#1#2e0\relax% + \expandafter\pgfmathfloatrounddisplaystyle@shared@impl@\expandafter{\pgfmathresult}{#4#6}% + \or + \pgfmathfloatrounddisplaystyle@shared@impl@{NaN}{}% + \or + \ifpgfmathprintnumber@showpositive + \pgfmathfloatrounddisplaystyle@shared@impl@{+\infty}{}% + \else + \pgfmathfloatrounddisplaystyle@shared@impl@{\infty}{}% + \fi + \or + \pgfmathfloatrounddisplaystyle@shared@impl@{-\infty}{}% + \fi +} + +% #1: the part before the exponent code +% #2: the part for the exponent code. +\def\pgfmathfloatrounddisplaystyle@shared@impl@#1#2{% + {\toks0={#1}% + \toks1=\expandafter{\pgfmathfloatrounddisplaystyle@e@mark #2}% + \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 }% + }% + \let\pgfmathresult=\pgfmathfloat@glob@TMP +}% + +\def\pgfmathfloatrounddisplaystyle@std#1#2e#3\relax{% + \pgfmathfloatrounddisplaystyle@shared@impl#1#2e#3\relax{\cdot}{}{10^{#3}}% +} +\def\pgfmathfloatrounddisplaystyle@subscript#1#2e#3\relax{% + \pgfmathfloatrounddisplaystyle@shared@impl#1#2e#3\relax{}{1}{_{#3}}% +} +\def\pgfmathfloatrounddisplaystyle@e#1#2e#3\relax{% + \ifnum#3<0\relax + {\count0=#3\relax + \multiply\count0 by-1 + \xdef\pgfmathfloat@glob@TMP{e{-}\the\count0}% + }% + \let\pgfmathresult=\pgfmathfloat@glob@TMP + \else + \def\pgfmathresult{e{+}#3}% + \fi + \def\pgfmathfloat@loc@TMPb{\pgfmathfloatrounddisplaystyle@shared@impl#1#2e#3\relax{}{1}}% + \expandafter\pgfmathfloat@loc@TMPb\expandafter{\pgfmathresult}% +} +\def\pgfmathfloatrounddisplaystyle@E#1#2e#3\relax{% + \ifnum#3<0\relax + {\count0=#3\relax + \multiply\count0 by-1 + \xdef\pgfmathfloat@glob@TMP{E{-}\the\count0}% + }% + \let\pgfmathresult=\pgfmathfloat@glob@TMP + \else + \def\pgfmathresult{E{+}#3}% + \fi + \def\pgfmathfloat@loc@TMPb{\pgfmathfloatrounddisplaystyle@shared@impl#1#2e#3\relax{}{1}}% + \expandafter\pgfmathfloat@loc@TMPb\expandafter{\pgfmathresult}% +} + +% A macro which takes three arguments, sign, mantisse and exponent and +% expands to the final TeX-representation for that floating point +% number. +% +% PRECONDITION: +% the floating point number has already been rounded properly and +% the mantisse has been rounded correcty. +% +% #1: SIGN +% #2: MANTISSE +% #3: EXPONENT +\let\pgfmathfloatrounddisplaystyle=\pgfmathfloatrounddisplaystyle@std +\newif\ifpgfmathfloat@usezerofill@sci +\newif\ifpgfmathfloat@usezerofill@fixed +\newif\ifpgfmathprintnumber@assumemathmode +\newif\ifpgfmathprintnumber@showpositive + +\pgfkeys{% + /pgf/number format/.is family, + /pgf/number format, + fixed/.code= \pgfmath@set@number@printer{pgfmathprintnumber@FIXED}, + sci/.code= \pgfmath@set@number@printer{pgfmathprintnumber@SCI}, + std/.code= \pgfmath@set@number@printer{pgfmathprintnumber@STD}, + int detect/.code= \pgfmath@set@number@printer{pgfmathprintnumber@INT@DETECT}, + int trunc/.code= \pgfmath@set@number@printer{pgfmathprintnumber@INT@TRUNC}, + assume math mode/.is if=pgfmathprintnumber@assumemathmode, + assume math mode/.default=true, + fixed zerofill/.is if= pgfmathfloat@usezerofill@fixed, + fixed zerofill/.default=true, + sci zerofill/.is if= pgfmathfloat@usezerofill@sci, + sci zerofill/.default=true, + zerofill/.style= {/pgf/number format/fixed zerofill=#1,/pgf/number format/sci zerofill=#1}, + zerofill/.default= true, + precision/.store in= \pgfmathfloat@round@precision, + fixed default/.code= {\let\pgfmathprintnumber@fixed@style=\pgfmathprintnumber@fixed@styleDEFAULT}, + set decimal separator/.initial=, + dec sep/.style={/pgf/number format/set decimal separator=#1}, + @dec sep mark/.initial=, + @sci exponent mark/.initial=, + set thousands separator/.initial=, + 1000 sep/.style={/pgf/number format/set thousands separator=#1}, + use period/.style= {/pgf/number format/set decimal separator={.},/pgf/number format/set thousands separator={{{,}}}}, + use comma/.style= {/pgf/number format/set decimal separator={{{,}}},/pgf/number format/set thousands separator={.}}, + showpos/.is if=pgfmathprintnumber@showpositive, + showpos/.default=true, + print sign/.is if=pgfmathprintnumber@showpositive, + print sign/.default=true, + skip 0./.is if=pgfmathprintnumberskipzeroperiod, + skip 0./.default=true, + skip 0.= false, + use period, + sci 10^e/.code= {\let\pgfmathfloatrounddisplaystyle=\pgfmathfloatrounddisplaystyle@std}, + sci 10e/.code= {\let\pgfmathfloatrounddisplaystyle=\pgfmathfloatrounddisplaystyle@std}, + sci e/.code= {\let\pgfmathfloatrounddisplaystyle=\pgfmathfloatrounddisplaystyle@e}, + sci E/.code= {\let\pgfmathfloatrounddisplaystyle=\pgfmathfloatrounddisplaystyle@E}, + sci subscript/.code= {\let\pgfmathfloatrounddisplaystyle=\pgfmathfloatrounddisplaystyle@subscript}, +% sci may skip mantisse/.is if=pgfmathfloatround@allow@empty@mantisse, +% sci may skip mantisse/.default=true, +} + + + +\def\pgfmathprintnumber@STD#1{% + % parse the input: + \pgfmathfloatparsenumber{#1}% + \expandafter\pgfmathprintnumber@STD@issci\pgfmathresult\relax +} + +\def\pgfmathprintnumber@STD@issci#1#2e#3\relax{% + \expandafter\ifnum#1<3 + \expandafter\ifnum#3>4 + \pgfmathprintnumber@SCI@issci#1#2e#3\relax% + \else + \begingroup + \c@pgf@counta=\pgfmathfloat@round@precision\relax + \divide\c@pgf@counta by-2\relax + \ifnum#3<\c@pgf@counta + \pgfmathprintnumber@SCI@issci#1#2e#3\relax% + \else + \pgfmathprintnumber@FIXED@issci#1#2e#3\relax% + \fi + \pgfmath@smuggleone\pgfmathresult + \endgroup + \fi + \else% nan or inf: + \pgfmathfloatrounddisplaystyle#1#2e#3\relax% + \fi +} + + +\def\pgfmathprintnumber@INT@TRUNC#1{% + \pgfmathfloatparsenumber{#1}% + \expandafter\pgfmathprintnumber@INT@TRUNC@issci\pgfmathresult\relax +} + +\def\pgfmathprintnumber@INT@TRUNC@impl#1.#2\relax#3#4e#5\relax{% + \pgfmathfloatroundhasperiodfalse + \pgfmathprintnumber@fixed@style{#1}#3#4e#5\relax% +} +\def\pgfmathprintnumber@INT@TRUNC@issci#1#2e#3\relax{% + \ifnum#1<3\relax + \pgfmathfloattofixed{#1#2e#3}% + \expandafter\pgfmathprintnumber@INT@TRUNC@impl\pgfmathresult\relax#1#2e#3\relax + \else + \pgfmathfloatrounddisplaystyle#1#2e#3\relax% + \fi +} + + +\def\pgfmathprintnumber@INT@DETECT#1{% + \pgfmathfloatparsenumber{#1}% + \expandafter\pgfmathprintnumber@INT@DETECT@issci\pgfmathresult\relax +} + +\def\pgfmathprintnumber@INT@DETECT@issci#1#2e#3\relax{% + \begingroup + \ifnum#1<3\relax + \pgfmathfloattofixed{#1#2e#3}% + \def\pgfmathfloat@round@precision{6}% + \expandafter\pgfmathroundto\expandafter{\pgfmathresult}% + \ifpgfmathfloatroundhasperiod + \pgfmathprintnumber@SCI@issci#1#2e#3\relax + \else + \expandafter\pgfmathprintnumber@fixed@style\expandafter{\pgfmathresult}#1#2e#3\relax + \fi + \else + \pgfmathfloatrounddisplaystyle#1#2e#3\relax% + \fi + \pgfmath@smuggleone\pgfmathresult + \endgroup +} + +\def\pgfmathprintnumber@FIXED#1{% + \pgfmathfloatparsenumber{#1}% + \expandafter\pgfmathprintnumber@FIXED@issci\pgfmathresult\relax +} + +\def\pgfmathprintnumber@FIXED@issci#1#2e#3\relax{% + \begingroup + \ifnum#1<3 + \pgfmathfloattofixed{#1#2e#3}% + \ifpgfmathfloat@usezerofill@fixed + \expandafter\pgfmathroundtozerofill\expandafter{\pgfmathresult}% + \else + \expandafter\pgfmathroundto\expandafter{\pgfmathresult}% + \fi + \ifpgfmathfloatroundmayneedrenormalize + \pgfmathfloat@a@E=#3\relax + \advance\pgfmathfloat@a@E by1 + \edef\pgfmathfloat@loc@TMPb{\noexpand\pgfmathprintnumber@fixed@style{\pgfmathresult}#1#2e\the\pgfmathfloat@a@E}% + \pgfmathfloat@loc@TMPb\relax% + \else + \expandafter\pgfmathprintnumber@fixed@style\expandafter{\pgfmathresult}#1#2e#3\relax% + \fi + \else% nan or inf: + \pgfmathfloatrounddisplaystyle#1#2e#3\relax% + \fi + \pgfmath@smuggleone\pgfmathresult + \endgroup +} + + +\def\pgfmathprintnumber@SCI#1{% + \pgfmathfloatparsenumber{#1}% + \expandafter\pgfmathprintnumber@SCI@issci\pgfmathresult\relax +} + +\def\pgfmathprintnumber@SCI@issci#1#2e#3\relax{% + \ifpgfmathfloat@usezerofill@sci + \pgfmathfloatroundzerofill{#1#2e#3}% + \else + \pgfmathfloatround{#1#2e#3}% + \fi + \expandafter\pgfmathfloatrounddisplaystyle\pgfmathresult\relax +} + +% Prints argument #1 using the current pretty printer environment (all +% variables in /pgf/number format). +% +% You may specify optional arguments with \pgfmathprintnumber[...]. +\def\pgfmathprintnumber{% + \pgfutil@ifnextchar[% + {\pgfmathprintnumber@OPT}% + {\pgfmathprintnumber@noopt}% +} + +\def\pgfmathprintnumber@noopt#1{% + \pgfmathprintnumber@{#1}% + \ifpgfmathprintnumber@assumemathmode + \else + \pgfutilensuremath{\pgfmathresult}% + \fi +}% +\def\pgfmathprintnumber@OPT[#1]#2{% + \begingroup + \pgfqkeys{/pgf/number format}{#1}% + \pgfmathprintnumber@{#2}% + \ifpgfmathprintnumber@assumemathmode + \else + \pgfutilensuremath{\pgfmathresult}% + \fi + \endgroup +}% + +% As \pgfmathprintnumber, but it produces its output into the second +% argument. +\def\pgfmathprintnumberto{% + \pgfutil@ifnextchar[% + {\pgfmathprintnumberto@OPT}% + {\pgfmathprintnumberto@noopt}% +} + +\def\pgfmathprintnumberto@noopt#1#2{% + \begingroup + \pgfmathprintnumber@{#1}% + \ifpgfmathprintnumber@assumemathmode + \global\let\pgfmathfloat@glob@TMP=\pgfmathresult + \else + \toks0=\expandafter{\pgfmathresult}% + \xdef\pgfmathfloat@glob@TMP{\noexpand\pgfutilensuremath{\the\toks0 }}% + \fi + \endgroup + \let#2=\pgfmathfloat@glob@TMP +}% +\def\pgfmathprintnumberto@OPT[#1]#2#3{% + \begingroup + \pgfqkeys{/pgf/number format}{#1}% + \pgfmathprintnumber@{#2}% + \ifpgfmathprintnumber@assumemathmode + \global\let\pgfmathfloat@glob@TMP=\pgfmathresult + \else + \toks0=\expandafter{\pgfmathresult}% + \xdef\pgfmathfloat@glob@TMP{\noexpand\pgfutilensuremath{\the\toks0 }}% + \fi + \endgroup + \let#3=\pgfmathfloat@glob@TMP +}% + + +% Changes the current number pretty printer to #1. +% +% #1 is the macro base name for the pretty print routine, without the +% leading '\'. +\def\pgfmath@set@number@printer#1{% + \expandafter\let\expandafter\pgfmathprintnumber@\csname #1\endcsname + \expandafter\let\expandafter\pgfmathprintnumber@issci\csname #1@issci\endcsname +} + +\pgfmath@set@number@printer{pgfmathprintnumber@STD} +%\pgfmath@set@number@printer{pgfmathprintnumber@FIXED} +%\pgfmath@set@number@printer{pgfmathprintnumber@FIXED@ZEROFILL} +%\pgfmath@set@number@printer{pgfmathprintnumber@SCI@ZEROFILL} +%\pgfmath@set@number@printer{pgfmathprintnumber@SCI} + +%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% IMPL +% +%%%%%%%%%%%%%%%%%%%%%%%%%% + +% equals only itsself when compared with \ifx: +\def\pgfmathfloat@EOI{\pgfmathfloat@EOI}% + +% Re-use counters internally. +% +% They are always grouped and only used inside of the rounding +% routines. +\let\c@pgfmathroundto@prec=\pgfmathfloat@b@S% ATTENTION: DOUBLE-USED REGISTERS! +\let\c@pgfmathroundto@offsetbehindperiod=\pgfmathfloat@b@E +\newcount\c@pgfmathroundto@lastzeros + +\newif\ifpgfmathround@impl@PREPERIOD@is@negative@zero + +% PRECONDITION: +% \ifpgfmathfloatroundhasperiod=\iftrue holds outside of the +% current TeX group. +% +% POSTCONDITION: +% \ifpgfmathfloatroundhasperiod will be set correctly AFTER the +% current TeX group. +% \ifpgfmathfloatroundmayneedrenormalize will be set globally +\def\pgfmathroundto@impl#1{% + \global\pgfmathfloatroundmayneedrenormalizefalse + \pgfmathfloat@tmptoks={}% + \let\pgfmathround@next=\pgfutil@empty + \let\pgfmathround@cur=\pgfutil@empty + \let\pgfmathresult=\pgfutil@empty + \edef\pgfmathround@input{#1}% + \expandafter\c@pgfmathroundto@prec\pgfmathfloat@round@precision\relax + \c@pgfmathroundto@lastzeros=0 + \c@pgfmathroundto@offsetbehindperiod=-1 % means: no period found so far + \pgfmathround@impl@PREPERIOD@is@negative@zerotrue + \expandafter\pgfmathroundto@impl@ITERATE@NODOT@firstcall\pgfmathround@input\pgfmathfloat@EOI +} + +% \pgfmathroundto implementation in WORDS: +% +% coarse idea: +% 1. collect all digits/sign BEFORE the first period in REVERSE order +% 2. then, collect UP TO \prec digits after the period in REVERSE order +% Steps 1. and 2. lead to the digit [sign] sequence +% "x_{-p} x_{-p+1} ... x_{-2} x_{-1} '.' x_0 ... x_r" +% where 'r' is the total number of digits. The integer 'p' denotes the +% ACTUALLY collected number of digits behind the period. +% +% Let 'k' be the desired precision. +% +% Please note that pgfmathroundto rounds the mantisse, that means |abs(x)|. +% +% There are exactly TWO cases: +% 1. The case with p<=k and x_{-p-1} = end of input. +% 2. The case with p=k and x_{-p-1} is a further, next character. +% +% Then, for case 1.): +% discard any unused zeros at the tail of our number (possibly +% including the period) +% +% and in case 2.) +% if NEXT DIGIT < 5: +% do exactly the same as in case 1.) above and discard any +% following digits. +% else +% let q := -p +% while(x_q = 9 and q<=r ) +% if q>=0 +% set x_q = '0' +% else +% discard digit x_q='9' +% fi +% ++q +% if q=0 +% discard the period +% fi +% end while +% if q = r+1 +% insert a '1' +% else +% set x_q = x_q + 1 +% fi +% fi +% +% All these loops have been implemented in spaghetti-code below. +% Sorry, I fear its hard to understand. In principle, everything is +% realised using more or less finite state machines (with some number +% counting logic). +% +% Some comments: +% - The token register \pgfmathfloat@tmptoks is used to accumulate the REVERSED input number. +% - \pgfmathfloat@EOI always denotes 'END OF INPUT'. +% - in the second stage, we need to reverse \pgfmathfloat@tmptoks. +% This is -again- done with \pgfmathfloat@tmptoks. + +\def\pgfmathroundto@impl@discard@period#1.#2\pgfmathfloat@EOI{% + \pgfmathfloatroundhasperiodfalse + \aftergroup\pgfmathfloatroundhasperiodfalse + \def\pgfmathresult{#1}% +} + +\def\pgfmathroundto@impl@gobble@rest@and@start#1\pgfmathfloat@EOI{% + \pgfmathroundto@impl@start +} +\def\pgfmathroundto@impl@gobble@and@start\pgfmathfloat@EOI{% + \pgfmathroundto@impl@start +} +\def\pgfmathroundto@impl@gobble\pgfmathfloat@EOI{}% +\def\pgfmathroundto@impl@gobble@rest#1\pgfmathfloat@EOI{}% + +% This method will be invoked as soon as the first step, the reverse +% collection of up to PREC digits after the period, has finished. +\def\pgfmathroundto@impl@start{% + \ifx\pgfmathround@next\pgfutil@empty + \ifnum\c@pgfmathroundto@offsetbehindperiod<0 + % no period found. + \ifpgfmathfloat@fixed@digits@after@period + \ifnum\c@pgfmathroundto@prec=0\relax + \pgfmathfloatroundhasperiodfalse + \aftergroup\pgfmathfloatroundhasperiodfalse + \edef\pgfmathresult{\pgfmathround@input}% + \else + \pgfmathfloat@tmptoks=\expandafter{\pgfmathround@input.}% + \c@pgfmathroundto@offsetbehindperiod=\c@pgfmathroundto@prec + \pgfmathroundto@impl@append@zeros + \edef\pgfmathresult{\the\pgfmathfloat@tmptoks}% + \fi + \else + \pgfmathfloatroundhasperiodfalse + \aftergroup\pgfmathfloatroundhasperiodfalse + \edef\pgfmathresult{\pgfmathround@input}% + \fi + \else + %\ifnum\c@pgfmathroundto@offsetbehindperiod>\c@pgfmathroundto@prec + % \pgfmath@error{Internal logic error in pgfmathroundto at [I] - should not have happened!?}% + %\fi + \pgfmathroundto@impl@finish@with@truncation + \fi + \else + %\ifnum\c@pgfmathroundto@offsetbehindperiod=\c@pgfmathroundto@prec + %\else + % \pgfmath@error{Internal logic error in pgfmathroundto at [II] - should not have happened!? I have offsetbehindperiod=\the\c@pgfmathroundto@offsetbehindperiod and prec = \the\c@pgfmathroundto@prec}% + %\fi + \expandafter\ifnum\pgfmathround@next<5\relax + \pgfmathroundto@impl@finish@with@truncation + \else + \multiply\c@pgfmathroundto@offsetbehindperiod by-1 + \expandafter\pgfmathroundto@impl@ADD@ONE\the\pgfmathfloat@tmptoks\pgfmathfloat@EOI + \fi + \fi +} + +% takes the current input and decides whether trailing zeros shall be +% discarded or more zeros need to be filled in. +\def\pgfmathroundto@impl@finish@with@truncation{% + \ifpgfmathfloat@fixed@digits@after@period + \expandafter\pgfmathroundto@impl@REVERSE\the\pgfmathfloat@tmptoks\pgfmathfloat@EOI + \ifnum\c@pgfmathroundto@lastzeros=\c@pgfmathroundto@offsetbehindperiod + \ifpgfmathround@impl@PREPERIOD@is@negative@zero + % write '0.0000' instead of '-0.0000': + \expandafter\pgfmathroundto@impl@discard@minus\the\pgfmathfloat@tmptoks\pgfmathfloat@EOI + \fi + \fi + \ifnum\c@pgfmathroundto@prec=0\relax + \expandafter\pgfmathroundto@impl@discard@period\the\pgfmathfloat@tmptoks\pgfmathfloat@EOI + \else + \advance\c@pgfmathroundto@prec by-\c@pgfmathroundto@offsetbehindperiod + \c@pgfmathroundto@offsetbehindperiod=\c@pgfmathroundto@prec + \pgfmathroundto@impl@append@zeros + \edef\pgfmathresult{\the\pgfmathfloat@tmptoks}% + \fi + \else + \pgfmathroundto@impl@discard@suffix@zeros + \fi +} + +\def\pgfmathroundto@impl@discard@minus-#1\pgfmathfloat@EOI{\pgfmathfloat@tmptoks={#1}}% + +% appends \c@pgfmathroundto@offsetbehindperiod zeros at the end of \pgfmathfloat@tmptoks. +\def\pgfmathroundto@impl@append@zeros{% + \ifnum\c@pgfmathroundto@offsetbehindperiod>0 + \pgfmathfloat@tmptoks=\expandafter{\the\pgfmathfloat@tmptoks0}% + \advance\c@pgfmathroundto@offsetbehindperiod by-1 + \pgfmathroundto@impl@append@zeros + \fi +} + +\def\pgfmathroundto@impl@ADD@ONE{% + \pgfmathfloat@tmptoks={}% no longer needed because its old value will be read from input + \pgfmathroundto@impl@ADD@ONE@ITERATE +} +\def\pgfmathroundto@impl@ADD@ONE@ITERATE{% + \pgfutil@ifnextchar\pgfmathfloat@EOI{% + \global\pgfmathfloatroundmayneedrenormalizetrue + \edef\pgfmathresult{1\the\pgfmathfloat@tmptoks}% + \pgfmathroundto@impl@gobble + }{% + \pgfutil@ifnextchar.{% + \ifnum\c@pgfmathroundto@prec=0 + % silently discard period in special case precision=0 + \def\pgfmathround@nextcmd{\pgfmathroundto@impl@ADD@ONE@ITERATE@gobble@dot}% + \else + \def\pgfmathround@nextcmd{\pgfmathroundto@impl@ADD@ONE@NEXT@COLLECT}% + \fi + \pgfmathround@nextcmd + }{% + \pgfutil@ifnextchar+{% + \global\pgfmathfloatroundmayneedrenormalizetrue + \edef\pgfmathresult{1\the\pgfmathfloat@tmptoks}% + \pgfmathroundto@impl@gobble@rest + }{% + \pgfutil@ifnextchar-{% + \global\pgfmathfloatroundmayneedrenormalizetrue + \edef\pgfmathresult{-1\the\pgfmathfloat@tmptoks}% + \pgfmathroundto@impl@gobble@rest + }{% + \pgfmathroundto@impl@ADD@ONE@NEXT + }% + }% + }% + }% +} + +\def\pgfmathroundto@impl@ADD@ONE@ITERATE@gobble@dot.{% + \pgfmathfloatroundhasperiodfalse + \aftergroup\pgfmathfloatroundhasperiodfalse + \pgfmathroundto@impl@ADD@ONE@ITERATE +} + +\def\pgfmathroundto@impl@ADD@ONE@NEXT@COLLECT#1{% + \pgfmathfloat@tmptoks=\expandafter{\expandafter#1\the\pgfmathfloat@tmptoks}% + \pgfmathroundto@impl@ADD@ONE@ITERATE +} +\def\pgfmathroundto@impl@ADD@ONE@NEXT#1{% + \ifnum#1=9 + \ifnum\c@pgfmathroundto@offsetbehindperiod<0 + \ifpgfmathfloat@fixed@digits@after@period + \pgfmathfloat@tmptoks=\expandafter{\expandafter0\the\pgfmathfloat@tmptoks}% + \else + % silently DROP digit + \fi + \else + \pgfmathfloat@tmptoks=\expandafter{\expandafter0\the\pgfmathfloat@tmptoks}% + \fi + \advance\c@pgfmathroundto@offsetbehindperiod by1 + \ifnum\c@pgfmathroundto@offsetbehindperiod=0 + \ifpgfmathfloat@fixed@digits@after@period + \def\pgfmathround@nextcmd{\pgfmathroundto@impl@ADD@ONE@ITERATE}% + \else + \def\pgfmathround@nextcmd{\pgfmathroundto@impl@ADD@ONE@ITERATE@gobble@dot}% + \fi + \else + \def\pgfmathround@nextcmd{\pgfmathroundto@impl@ADD@ONE@ITERATE}% + \fi + \else + % re-use this counter: + \c@pgfmathroundto@lastzeros=#1 + \advance\c@pgfmathroundto@lastzeros by1 + \edef\pgfmathresult{\the\c@pgfmathroundto@lastzeros\the\pgfmathfloat@tmptoks}% + \pgfmathfloat@tmptoks=\expandafter{\pgfmathresult}% + \def\pgfmathround@nextcmd{\pgfmathroundto@impl@REVERSE@ITERATE}% + \fi + \pgfmathround@nextcmd +} + + +\def\pgfmathroundto@impl@discard@suffix@zeros{% + \ifnum\c@pgfmathroundto@lastzeros=\c@pgfmathroundto@offsetbehindperiod + \ifpgfmathround@impl@PREPERIOD@is@negative@zero + \pgfmathfloatroundhasperiodfalse + \aftergroup\pgfmathfloatroundhasperiodfalse + \def\pgfmathresult{0}% write '0' instead of '-0' + \else + \expandafter\pgfmathroundto@impl@discard@period\pgfmathround@input\pgfmathfloat@EOI + \fi + \else + \ifnum\c@pgfmathroundto@lastzeros=0 + \expandafter\pgfmathroundto@impl@REVERSE\the\pgfmathfloat@tmptoks\pgfmathfloat@EOI + \else + \expandafter\pgfmathroundto@impl@discard@suffix@zeros@ITERATE\the\pgfmathfloat@tmptoks\pgfmathfloat@EOI + \fi + \fi +} + +% PRECONDITION: +% \c@pgfmathroundto@lastzeros > 0 +\def\pgfmathroundto@impl@discard@suffix@zeros@ITERATE#1{% + \advance\c@pgfmathroundto@lastzeros by-1 + \ifnum\c@pgfmathroundto@lastzeros=0 + \def\pgfmathround@nextcmd{\pgfmathroundto@impl@REVERSE}% + \else + \def\pgfmathround@nextcmd{\pgfmathroundto@impl@discard@suffix@zeros@ITERATE}% + \fi + \pgfmathround@nextcmd +} + +% Usage: +% \pgfmathroundto@impl@REVERSE#1\pgfmathfloat@EOI +% -> writes #1 reversed into \pgfmathfloat@tmptoks +\def\pgfmathroundto@impl@REVERSE{% + \pgfmathfloat@tmptoks={}% + \pgfmathroundto@impl@REVERSE@ITERATE +} + +\def\pgfmathroundto@impl@REVERSE@ITERATE{% + \pgfutil@ifnextchar\pgfmathfloat@EOI{% + \edef\pgfmathresult{\the\pgfmathfloat@tmptoks}% + \pgfmathroundto@impl@gobble + }{% + \pgfmathroundto@impl@REVERSE@NEXT + }% +} + +\def\pgfmathroundto@impl@REVERSE@NEXT#1{% + \pgfmathfloat@tmptoks=\expandafter{\expandafter#1\the\pgfmathfloat@tmptoks}% + \pgfmathroundto@impl@REVERSE@ITERATE +} + +\def\pgfmathroundto@impl@BEGIN@DOT.{% + \pgfmathfloat@tmptoks=\expandafter{\expandafter.\the\pgfmathfloat@tmptoks}% + \c@pgfmathroundto@offsetbehindperiod=0 + \pgfmathroundto@impl@ITERATE@DOT +} +\def\pgfmathroundto@impl@ITERATE@DOT{% + \pgfutil@ifnextchar\pgfmathfloat@EOI{% + % finished. + \pgfmathroundto@impl@gobble@and@start + }{% + \pgfmathroundto@impl@NEXT@DOT + }% +} +\def\pgfmathroundto@impl@NEXT@DOT#1{% + \ifnum\c@pgfmathroundto@offsetbehindperiod=\c@pgfmathroundto@prec + \def\pgfmathround@next{#1}% + \def\pgfmathround@nextcmd{\pgfmathroundto@impl@gobble@rest@and@start}% + \else + \advance\c@pgfmathroundto@offsetbehindperiod by1 + \ifnum#1=0 + \advance\c@pgfmathroundto@lastzeros by1 + \else + \c@pgfmathroundto@lastzeros=0 + \fi + \pgfmathfloat@tmptoks=\expandafter{\expandafter#1\the\pgfmathfloat@tmptoks}% + \def\pgfmathround@nextcmd{\pgfmathroundto@impl@ITERATE@DOT}% + \fi + \pgfmathround@nextcmd +}% + +% in contrast to pgfmathroundto@impl@ITERATE@NODOT, this method here +% checks also for signs +\def\pgfmathroundto@impl@ITERATE@NODOT@firstcall#1{% + \def\pgfmathround@cur{#1}% + \ifx\pgfmathround@cur\pgfmathfloat@EOI + \pgfmathround@impl@PREPERIOD@is@negative@zerofalse + \def\pgfmathround@nextcmd{\pgfmathroundto@impl@start}% + \else + \ifx\pgfmathround@cur\pgfmathfloatparsenumber@tok@PERIOD + \pgfmathround@impl@PREPERIOD@is@negative@zerofalse + \def\pgfmathround@nextcmd{\pgfmathroundto@impl@BEGIN@DOT.}% + \else + \ifx\pgfmathround@cur\pgfmathfloatparsenumber@tok@MINUS + \else + \pgfmathround@impl@PREPERIOD@is@negative@zerofalse + \fi + \pgfmathfloat@tmptoks=\expandafter{\expandafter#1\the\pgfmathfloat@tmptoks}% + \def\pgfmathround@nextcmd{\pgfmathroundto@impl@ITERATE@NODOT}% + \fi + \fi + \pgfmathround@nextcmd +} + +\def\pgfmathroundto@impl@ITERATE@NODOT#1{% + \def\pgfmathround@cur{#1}% + \ifx\pgfmathround@cur\pgfmathfloat@EOI + \def\pgfmathround@nextcmd{\pgfmathroundto@impl@start}% + \else + \ifx\pgfmathround@cur\pgfmathfloatparsenumber@tok@PERIOD + \def\pgfmathround@nextcmd{\pgfmathroundto@impl@BEGIN@DOT.}% + \else + \ifx\pgfmathround@cur\pgfmathfloatparsenumber@tok@ZERO + \else + \pgfmathround@impl@PREPERIOD@is@negative@zerofalse + \fi + \pgfmathfloat@tmptoks=\expandafter{\expandafter#1\the\pgfmathfloat@tmptoks}% + \def\pgfmathround@nextcmd{\pgfmathroundto@impl@ITERATE@NODOT}% + \fi + \fi + \pgfmathround@nextcmd +} + +%-------------------------------------------- +% END of pgfmathroundto implementation. +%-------------------------------------------- + + +% flags, mantisse and exponent has already been stored into +% \pgfmathfloat@a@* [using ...@Mtok] +% +% PRECONDITION: +% \ifpgfmathfloatroundhasperiod = \iftrue outside of the current +% group +% +% POSTCONDITION: +% \ifpgfmathfloatroundhasperiod will be set after the current TeX +% group. +\def\pgfmathfloatround@impl{% + \expandafter\pgfmathroundto@impl\expandafter{\the\pgfmathfloat@a@Mtok}% + \ifpgfmathfloatroundmayneedrenormalize + \ifpgfmathfloatroundhasperiod + \expandafter\pgfmathfloatround@impl@renormalize\pgfmathresult\pgfmathfloat@EOI% + \else + \expandafter\pgfmathfloatround@impl@renormalize\pgfmathresult.\pgfmathfloat@EOI% + \fi + \advance\pgfmathfloat@a@E by1 + \fi + \edef\pgfmathresult{\the\pgfmathfloat@a@S\pgfmathresult e\the\pgfmathfloat@a@E}% +} + +\def\pgfmathfloatround@impl@renormalize#1#2.#3\pgfmathfloat@EOI{% + \pgfmathroundto@impl{#1.#2#3}% +} + + + + + +% ATTENTION: this thing REQUIRES a period in the mantisse! +% collects everything into \pgfmathresult +\def\pgfmathfloattofixed@impl#1.#2\relax{% + \ifnum\pgfmathfloat@a@E<0 + \pgfmathfloat@a@Mtok={0.}% + \pgfutil@loop + \ifnum\pgfmathfloat@a@E<-1 + \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok 0}% + \advance\pgfmathfloat@a@E by1 + \pgfutil@repeat + \def\pgfmathfloat@loc@TMPb{#2}% + \def\pgfmathfloat@loc@TMPc{0}% + \ifx\pgfmathfloat@loc@TMPb\pgfmathfloat@loc@TMPc + \edef\pgfmathresult{\the\pgfmathfloat@a@Mtok #1}% + \else + \edef\pgfmathresult{\the\pgfmathfloat@a@Mtok #1#2}% + \fi + \else + \ifnum\pgfmathfloat@a@E=0% + \edef\pgfmathresult{#1.#2}% + \else + \pgfmathfloat@a@Mtok={#1}% + \pgfmathfloattofixed@impl@collectmantisse#2\count\pgfmathfloat@a@E + \edef\pgfmathresult{\the\pgfmathfloat@a@Mtok}% + \fi + \fi +} + +\def\pgfmathfloattofixed@impl@collectmantisse#1#2\count#3{% + \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok #1}% + \advance\pgfmathfloat@a@E by-1% + \def\pgfmathfloat@loc@TMPb{#2}% + \ifx\pgfmathfloat@loc@TMPb\pgfutil@empty + \pgfutil@loop + \ifnum\pgfmathfloat@a@E>0% + \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok 0}% + \advance\pgfmathfloat@a@E by-1% + \pgfutil@repeat + \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok .0}% + \else + \ifnum\pgfmathfloat@a@E=0 + \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok .#2}% + \else + \pgfmathfloattofixed@impl@collectmantisse#2\count#3% + \fi + \fi +} + + +% ============================================ +% +% +% \pgfmathfloatparsenumber implementation +% +% +% ============================================ + + +% accepted parser tokens: +\def\pgfmathfloatparsenumber@tok@ONE{1} +\def\pgfmathfloatparsenumber@tok@TWO{2} +\def\pgfmathfloatparsenumber@tok@THREE{3} +\def\pgfmathfloatparsenumber@tok@FOUR{4} +\def\pgfmathfloatparsenumber@tok@FIVE{5} +\def\pgfmathfloatparsenumber@tok@SIX{6} +\def\pgfmathfloatparsenumber@tok@SEVEN{7} +\def\pgfmathfloatparsenumber@tok@EIGHT{8} +\def\pgfmathfloatparsenumber@tok@NINE{9} +\def\pgfmathfloatparsenumber@tok@ZERO{0} +\def\pgfmathfloatparsenumber@tok@e{e} +\def\pgfmathfloatparsenumber@tok@E{E} +\def\pgfmathfloatparsenumber@tok@PLUS{+} +\def\pgfmathfloatparsenumber@tok@MINUS{-} +\def\pgfmathfloatparsenumber@tok@n{n} +\def\pgfmathfloatparsenumber@tok@N{N} +\def\pgfmathfloatparsenumber@tok@i{i} +\def\pgfmathfloatparsenumber@tok@I{I} +\def\pgfmathfloatparsenumber@tok@PERIOD{.} + +\newif\ifpgfmathfloatparsenumberpendingperiod + +% Starts a finite-start-machine parser to read a number. +% +% It assigns \pgfmathfloat@a@S, \pgfmathfloat@a@Mtok, \pgfmathfloat@a@E. +\def\pgfmathfloatparsenumber@impl#1{% + \pgfmathfloatparsenumberpendingperiodfalse + \pgfmathfloat@tmptoks={}% this register is used to collect PENDING ZEROS + \pgfmathfloat@a@E=0 + % start parsing: check for sign: + \def\pgfmathfloatparsenumber@curtok{#1}% + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@PLUS + \pgfmathfloat@a@S=1\relax% + \def\pgfmathfloatparsenumber@NEXT{\pgfmathfloatparsenumber@impl@init}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@MINUS + \pgfmathfloat@a@S=2\relax% + \def\pgfmathfloatparsenumber@NEXT{\pgfmathfloatparsenumber@impl@init}% + \else + \pgfmathfloat@a@S=1\relax% + \def\pgfmathfloatparsenumber@NEXT{\pgfmathfloatparsenumber@impl@init#1}% + \fi + \fi + \pgfmathfloatparsenumber@NEXT +} + +\def\pgfmathfloatparsenumber@sanitize@digit{% + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@ONE + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@TWO + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@THREE + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@FOUR + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@FIVE + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@SIX + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@SEVEN + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@EIGHT + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@NINE + \else + \def\pgfmathfloatparsenumber@NEXT{\expandafter\pgfmathfloatparsenumber@impl@error\pgfmathfloatparsenumber@curtok}% + \fi\fi\fi\fi\fi\fi\fi\fi\fi +} + +% FROM: checksign. +% +\def\pgfmathfloatparsenumber@impl@init#1{% + \def\pgfmathfloatparsenumber@curtok{#1}% + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@n + \def\pgfmathfloatparsenumber@NEXT{\pgfmathfloatparsenumber@impl@readnan}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@i + \def\pgfmathfloatparsenumber@NEXT{\pgfmathfloatparsenumber@impl@readinf}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@ZERO + \def\pgfmathfloatparsenumber@NEXT{\pgfmathfloatparsenumber@impl@leadingzero}% + \else + \def\pgfmathfloatparsenumber@NEXT{% + \pgfmathfloat@a@Mtok={#1}% + \pgfmathfloatparsenumberpendingperiodtrue + \pgfmathfloatparsenumber@impl@positiveexp}% + \pgfmathfloatparsenumber@sanitize@digit + \fi + \fi + \fi + \pgfmathfloatparsenumber@NEXT +} + +\def\pgfmathfloatparsenumber@impl@error#1\pgfmathfloat@EOI{% + \begingroup + \pgfmathfloat@a@Mtok={#1}% + \pgfmath@error{Could not read input number, sorry. The unreadable part was near '\the\pgfmathfloat@a@Mtok'.}% + \endgroup +}% + +\def\pgfmathfloatparsenumber@impl@finish#1\pgfmathfloat@EOI{} + +\def\pgfmathfloatparsenumber@impl@readnan an{% + \pgfmathfloat@a@S=3\relax% + \pgfmathfloat@a@Mtok={0.0}% + \pgfmathfloat@a@E=0% + \pgfmathfloatparsenumber@impl@finish +} +\def\pgfmathfloatparsenumber@impl@readinf nf{% + \ifnum\pgfmathfloat@a@S=1 + \pgfmathfloat@a@S=4\relax% + \pgfmathfloat@a@Mtok={0.0}% + \else + \pgfmathfloat@a@S=5\relax% + \pgfmathfloat@a@Mtok={0.0}% + \fi + \pgfmathfloat@a@E=0% + \pgfmathfloatparsenumber@impl@finish +} +\def\pgfmathfloatparsenumber@impl@leadingzero#1{% + \def\pgfmathfloatparsenumber@curtok{#1}% + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@ZERO + \def\pgfmathfloatparsenumber@NEXT{% + \pgfmathfloatparsenumber@impl@leadingzero}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@PERIOD + \def\pgfmathfloatparsenumber@NEXT{% + \pgfmathfloat@a@E=-1 + \pgfmathfloatparsenumber@impl@leadingzero@foundperiod}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@e + \def\pgfmathfloatparsenumber@NEXT{% + \pgfmathfloat@a@S=0\relax% + \pgfmathfloat@a@Mtok={0.0}% + \pgfmathfloat@a@E=0% + \pgfmathfloatparsenumber@impl@readexponent}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@E + \def\pgfmathfloatparsenumber@NEXT{% + \pgfmathfloat@a@S=0\relax% + \pgfmathfloat@a@Mtok={0.0}% + \pgfmathfloat@a@E=0% + \pgfmathfloatparsenumber@impl@readexponent}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloat@EOI + \def\pgfmathfloatparsenumber@NEXT{% + \pgfmathfloat@a@S=0\relax% + \pgfmathfloat@a@Mtok={0.0}% + \pgfmathfloat@a@E=0% + }% + \else + \def\pgfmathfloatparsenumber@NEXT{% + \pgfmathfloat@a@Mtok={#1}% + \pgfmathfloatparsenumberpendingperiodtrue + \pgfmathfloatparsenumber@impl@positiveexp}% + \pgfmathfloatparsenumber@sanitize@digit + \fi\fi\fi + \fi + \fi + \pgfmathfloatparsenumber@NEXT +} + +\def\pgfmathfloatparsenumber@impl@leadingzero@foundperiod#1{% + \def\pgfmathfloatparsenumber@curtok{#1}% + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@ZERO + \def\pgfmathfloatparsenumber@NEXT{% + \advance\pgfmathfloat@a@E by-1 + \pgfmathfloatparsenumber@impl@leadingzero@foundperiod}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@e + \def\pgfmathfloatparsenumber@NEXT{% + \pgfmathfloat@a@S=0\relax% + \pgfmathfloat@a@Mtok={0.0}% + \pgfmathfloat@a@E=0% + \pgfmathfloatparsenumber@impl@readexponent}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@E + \def\pgfmathfloatparsenumber@NEXT{% + \pgfmathfloat@a@S=0\relax% + \pgfmathfloat@a@Mtok={0.0}% + \pgfmathfloat@a@E=0% + \pgfmathfloatparsenumber@impl@readexponent}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloat@EOI + \def\pgfmathfloatparsenumber@NEXT{% + \pgfmathfloat@a@S=0\relax% + \pgfmathfloat@a@Mtok={0.0}% + \pgfmathfloat@a@E=0% + }% + \else + \def\pgfmathfloatparsenumber@NEXT{% + \pgfmathfloat@a@Mtok={#1}% + \pgfmathfloatparsenumberpendingperiodtrue + \pgfmathfloatparsenumber@impl@finish@number@after@period}% + \pgfmathfloatparsenumber@sanitize@digit + \fi\fi\fi + \fi + \pgfmathfloatparsenumber@NEXT +} + + +\def\pgfmathfloatparsenumber@impl@positiveexp#1{% + \def\pgfmathfloatparsenumber@curtok{#1}% + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@ZERO + \def\pgfmathfloatparsenumber@NEXT{% + \advance\pgfmathfloat@a@E by1 + \pgfmathfloat@tmptoks=\expandafter{\the\pgfmathfloat@tmptoks0}% + \pgfmathfloatparsenumber@impl@pendingzeros@positiveexp}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@PERIOD + \def\pgfmathfloatparsenumber@NEXT{\pgfmathfloatparsenumber@impl@finish@number@after@period}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@e + \def\pgfmathfloatparsenumber@NEXT{\pgfmathfloatparsenumber@impl@readexponent}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@E + \def\pgfmathfloatparsenumber@NEXT{\pgfmathfloatparsenumber@impl@readexponent}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloat@EOI + \def\pgfmathfloatparsenumber@NEXT{}% + \else + \def\pgfmathfloatparsenumber@NEXT{% + \advance\pgfmathfloat@a@E by1 + \ifpgfmathfloatparsenumberpendingperiod + \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok.}% + \pgfmathfloatparsenumberpendingperiodfalse + \fi + \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok#1}% + \pgfmathfloatparsenumber@impl@positiveexp}% + \pgfmathfloatparsenumber@sanitize@digit + \fi\fi\fi + \fi + \fi + \pgfmathfloatparsenumber@NEXT +} + +\def\pgfmathfloatparsenumber@impl@readexponent#1\pgfmathfloat@EOI{% + \advance\pgfmathfloat@a@E by#1\relax +} + +\def\pgfmathfloatparsenumber@impl@pendingzeros@positiveexp#1{% + \def\pgfmathfloatparsenumber@curtok{#1}% + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@ZERO + \def\pgfmathfloatparsenumber@NEXT{% + \pgfmathfloat@tmptoks=\expandafter{\the\pgfmathfloat@tmptoks0}% + \advance\pgfmathfloat@a@E by1 + \pgfmathfloatparsenumber@impl@pendingzeros@positiveexp}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@PERIOD + \def\pgfmathfloatparsenumber@NEXT{\pgfmathfloatparsenumber@impl@finish@number@after@period}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@e + \def\pgfmathfloatparsenumber@NEXT{\pgfmathfloatparsenumber@impl@readexponent}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@E + \def\pgfmathfloatparsenumber@NEXT{\pgfmathfloatparsenumber@impl@readexponent}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloat@EOI + \def\pgfmathfloatparsenumber@NEXT{}% + \else + \def\pgfmathfloatparsenumber@NEXT{% + \advance\pgfmathfloat@a@E by1 + \ifpgfmathfloatparsenumberpendingperiod + \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok.}% + \pgfmathfloatparsenumberpendingperiodfalse + \fi + \pgfmathfloat@a@Mtok=\expandafter\expandafter\expandafter{\expandafter\the\expandafter\pgfmathfloat@a@Mtok\the\pgfmathfloat@tmptoks}% + \pgfmathfloat@tmptoks={}% + \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok#1}% + \pgfmathfloatparsenumber@impl@positiveexp}% + \pgfmathfloatparsenumber@sanitize@digit + \fi\fi\fi + \fi + \fi + \pgfmathfloatparsenumber@NEXT +} + +\def\pgfmathfloatparsenumber@impl@finish@number@after@period#1{% + \def\pgfmathfloatparsenumber@curtok{#1}% + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@ZERO + \def\pgfmathfloatparsenumber@NEXT{% + \pgfmathfloat@tmptoks=\expandafter{\the\pgfmathfloat@tmptoks0}% + \pgfmathfloatparsenumber@impl@pendingzeros}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@e + \def\pgfmathfloatparsenumber@NEXT{\pgfmathfloatparsenumber@impl@readexponent}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@E + \def\pgfmathfloatparsenumber@NEXT{\pgfmathfloatparsenumber@impl@readexponent}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloat@EOI + \def\pgfmathfloatparsenumber@NEXT{}% + \else + \def\pgfmathfloatparsenumber@NEXT{% + \ifpgfmathfloatparsenumberpendingperiod + \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok.}% + \pgfmathfloatparsenumberpendingperiodfalse + \fi + \pgfmathfloat@a@Mtok=\expandafter\expandafter\expandafter{\expandafter\the\expandafter\pgfmathfloat@a@Mtok\the\pgfmathfloat@tmptoks}% + \pgfmathfloat@tmptoks={}% + \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok#1}% + \pgfmathfloatparsenumber@impl@finish@number@after@period}% + \pgfmathfloatparsenumber@sanitize@digit + \fi\fi\fi + \fi + \pgfmathfloatparsenumber@NEXT +} + +\def\pgfmathfloatparsenumber@impl@pendingzeros#1{% + \def\pgfmathfloatparsenumber@curtok{#1}% + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@ZERO + \def\pgfmathfloatparsenumber@NEXT{% + \pgfmathfloat@tmptoks=\expandafter{\the\pgfmathfloat@tmptoks0}% + \pgfmathfloatparsenumber@impl@pendingzeros}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@e + \def\pgfmathfloatparsenumber@NEXT{\pgfmathfloatparsenumber@impl@readexponent}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloatparsenumber@tok@E + \def\pgfmathfloatparsenumber@NEXT{\pgfmathfloatparsenumber@impl@readexponent}% + \else + \ifx\pgfmathfloatparsenumber@curtok\pgfmathfloat@EOI + \def\pgfmathfloatparsenumber@NEXT{}% + \else + \def\pgfmathfloatparsenumber@NEXT{% + \ifpgfmathfloatparsenumberpendingperiod + \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok.}% + \pgfmathfloatparsenumberpendingperiodfalse + \fi + \pgfmathfloat@a@Mtok=\expandafter\expandafter\expandafter{\expandafter\the\expandafter\pgfmathfloat@a@Mtok\the\pgfmathfloat@tmptoks}% + \pgfmathfloat@tmptoks={}% + \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok#1}% + \pgfmathfloatparsenumber@impl@finish@number@after@period}% + \pgfmathfloatparsenumber@sanitize@digit + \fi\fi\fi + \fi + \pgfmathfloatparsenumber@NEXT +} + + + -- cgit v1.2.3