%
%
%
%--------------------------------------------
%
% Package pgfplots
%
% Provides a user-friendly interface to create function plots (normal
% plots, semi-logplots and double-logplots).
%
% It is based on Till Tantau's PGF package.
%
% Copyright 2007/2008 by Christian Feuersänger.
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program. If not, see .
%
%--------------------------------------------
\newif\ifpgfplots@usefpu
\pgfkeys{%
/pgfplots/use fpu/.is if=pgfplots@usefpu,
/pgfplots/use fpu=true,
}
% only useful inside of \ifx (equals only itsself)
\def\pgfplots@EOI{\pgfplots@EOI}%
% Produces an \aftergroup statement for each single token in #1.
%
% ATTENTION: you *can't* use braces inside of '#1'!
\def\pgfplotsqaftergroupeach#1{%
\pgfplotsqaftergroupeach@#1\pgfplots@EOI
}
\def\pgfplotsqaftergroupeach@#1{%
\gdef\pgfplots@TMP{#1}%
\ifx\pgfplots@TMP\pgfplots@EOI
\else
\aftergroup#1%
\expandafter\pgfplotsqaftergroupeach@
\fi
}
\def\pgfplotsaftergroupcollectinto#1#2\pgfplots@EOI{%
\def#1{#2}%
}%
% Assigns list contents #2 to a list macro #1.
%
% The list contents may be provided in one of two formats:
% a) in the list format 'first\\second\\thirst\\'
% or
% b) in the PGF foreach list format 'first,second,third'.
\def\pgfplots@assign@list#1#2{%
\pgfplotslistnew#1{#2}%
}%
\def\pgfplots@shellescape@lua@eightseven#1{%
\pgfplotsutil@directlua{os.execute("\pgfplotsutil@luaescapestring{#1}")}%
}%
\def\pgfplots@shellescape#1{%
\immediate\write18{#1}%
}%
\pgfutil@IfUndefined{directlua}{%
}{%
\pgfutil@IfUndefined{lastsavedimageresourcepages}{%
\pgfplots@log3{Found old luatex which supports write18 (shell-escape)}%
}{%
\pgfplots@log3{Found new luatex: initializing lua commands instead of write18 (shell-escape)}%
\let\pgfplots@shellescape=\pgfplots@shellescape@lua@eightseven
}%
}%
% Sets the boolean \ifpgfplots@is@old@list@format to true if and only
% if the input is a list in the format '{first\\second\\}'.
%
%
% Usage:
% \pgfplots@check@backwards@compatible@list@format '\\'\pgfplots@EOI
% you NEED to append '\\\pgfplots@EOI' at the end.
\def\pgfplots@check@backwards@compatible@list@format#1\pgfplots@EOI{%
\pgfplotslist@check@backslash@list#1\pgfplotslist@EOI
\ifpgfplotslist@is@backslash@terminated
\pgfplots@is@old@list@formattrue
\else
\pgfplots@is@old@list@formatfalse
\fi
}%
% Issues an error message if the **LaTeX** package '#1' is not loaded
% (An error is also raised if the document is not a LaTeX document).
% #1: the required LaTeX package
% #2: the feature which requires this package
\def\pgfplots@assert@LaTeX@package@loaded#1#2{%
\pgfutil@IfUndefined{@ifpackageloaded}{%
\pgfplots@error{Sorry, #2 only works with LaTeX (it relies on the LaTeX package #1)}%
}{%
\pgfutil@IfUndefined{ver@#1.sty}% this here has been extracted from ltclass.dtx. \@ifpackageloaded is only usable in preamble.
{\pgfplots@error{Sorry, use need \string\usepackage{#1} in your preamble for '#2'}}%
{\relax}%
}%
}%
\def\pgfplots@assert@tikzinternal@exists#1{%
\pgfutil@IfUndefined{#1}{%
\pgfplots@error{Sorry, pgfplots relies on the existance of the tikz internal macro '#1'.
Unfortunately, this does no longer exist ... you will need to get an updated version of pgfplots to fix this problem.}%
\expandafter\let\csname #1\endcsname=\pgfutil@empty
}{}%
}%
% A future-version compatibility method which checks whether the
% macro '#2' exists.
%
% We assume that '#2' usually contains the value of the tikz key '#1'.
% Example:
% /tikz/variable is usually stored into '\tikz@plot@var'.
%
% However, this may change in future versions.
%
% So, we do the following:
% 1. check whether '#2' exists, if yet: ok.
% 2. if not, check whether the value is stored directly into '/tikz/#1'.
% 3. if not, check whether the value is stored directly into '/pgf/#1'.
% 4. If everything fails, provide an error message.
%
% #1: a tikz key without key prefix (/tikz/ and /pgf/ will be prepended).
% #2: a macro name WITHOUT backslash.
% #3: the default value if everything fails.
\def\pgfplots@gettikzinternal@keyval#1#2#3{%
\pgfutil@IfUndefined{#2}{%
\pgfkeysifdefined{/tikz/#1}{%
\pgfkeysgetvalue{/tikz/#1}\pgfplots@TMP
\expandafter\let\csname #1\endcsname=\pgfplots@TMP
}{%
\pgfkeysifdefined{/pgf/#1}{%
\pgfkeysgetvalue{/pgf/#1}\pgfplots@TMP
\expandafter\let\csname #1\endcsname=\pgfplots@TMP
}{%
\expandafter\def\csname #1\endcsname{#3}%
{\t@pgfplots@tokc={#3}%
\pgfplots@warning{Sorry, could not find value of '/tikz/#1'. Assuming '\the\t@pgfplots@tokc'.}%
}%
}%
}%
}{}%
}%
\def\pgfplots@getcurrent@plothandler#1{%
\pgfutil@IfUndefined{tikz@plot@handler}{%
\pgfplots@error{Sorry, can't get the current plot handler. It appears that tikz and pgfplots is no longer compatible!? You will need to get a newer version of pgfplots.}%
\let#1=\pgfplothandlerlineto
}{%
\let#1=\tikz@plot@handler
}%
}
% Converts an arbitrary command (without arguments) to a string in which all characters
% have category 12.
%
% #1: a macro name (which takes no arguments)
% #2: a macro name which will be assigned to '#1' converted to string.
%
% This uses '\meaning#1' hackery.
\def\pgfplots@command@to@string#1#2{%
\expandafter\pgfplots@command@to@string@@\meaning#1\pgfplots@EOI{#2}%
}%
\xdef\pgfplots@glob@TMPa{\meaning\pgfutil@empty}%
\expandafter\def\expandafter\pgfplots@command@to@string@@\pgfplots@glob@TMPa#1\pgfplots@EOI#2{%
\def#2{#1}%
}%
\def\pgfplotscommandtostring#1#2{\pgfplots@command@to@string{#1}{#2}}%
\begingroup
\catcode`\|=0
\catcode`\\=12
|gdef|pgfplots@backslash@as@other{\}%
|endgroup
% As \pgfplots@command@to@string, but it works for commands accepting
% arguments. More precisely, #2 will be a string (!) of the form
% { }
% such that you can write
% \def\test #2
% into a file to restore the original macro. This IGNORES \long
% (sorry)
\def\pgfplots@command@with@args@to@string#1#2{%
\expandafter\PGFPLOTS@CS@WITH@ARGS@TO@STRING\meaning#1\EOI{#2}%
}%
{
\let\CATCODE=\catcode
\let\LONG=\long
\CATCODE`\m=12
\CATCODE`\a=12
\CATCODE`\c=12
\CATCODE`\r=12
\CATCODE`\o=12
\CATCODE`\:=12
\CATCODE`\-=12
\CATCODE`\>=12
\LONG\gdef\PGFPLOTS@CS@WITH@ARGS@TO@STRING #1macro:#2->#3\EOI#4{\def#4{#2{#3}}}%
}%
% Defines \pgfplotsretval to be '#1' but without leading and trailing
% spaces.
\def\pgfplotsutil@trim#1{%
\pgfkeys@spdef\pgfplotsretval{#1}%
}%
% Invokes '#2' if the token(s) '#1' are actually are defined control
% sequence and '#3' if not.
%
% This method accepts different values '#1' than \pgfutil@ifundefined.
% It is indended to autodetect values provided in the user interface
% (ui),
% that means '#1' can be anything. But I still like to know whether it
% is a control sequence.
%
% \pgfplotsutil@ifdefinedui{\table} -> yes if \table is defined.
% \pgfplotsutil@ifdefinedui{\csname abc\endcsname} -> no
% \pgfplotsutil@ifdefinedui{a_file_name} -> no
\def\pgfplotsutil@ifdefinedui#1#2#3{%
{\toks0={#1}% this construction is necessary to handle '#' characters in '#1'
\xdef\pgfplotsutil@@arg@ifdefined{\the\toks0}%
}%
\pgfplots@command@to@string\pgfplotsutil@@arg@ifdefined\pgfplotsutil@@arg@ifdefined
\expandafter\pgfplotsutil@trim\expandafter{\pgfplotsutil@@arg@ifdefined}%
\pgfutil@IfUndefined{\pgfplotsretval}{#3}{#2}%
}%
% The same as \pgfplotsutil@ifdefinedui but appends the suffix '#2' to
% '#1' after '#1' has been normalized.
% It invokes '#3' if '#1#2' is defined and '#4' if not.
\def\pgfplotsutil@ifdefinedui@withsuffix#1#2#3#4{%
{\toks0={#1}%
\xdef\pgfplotsutil@@arg@ifdefined{\the\toks0}%
}%
\pgfplots@command@to@string\pgfplotsutil@@arg@ifdefined\pgfplotsutil@@arg@ifdefined
\expandafter\pgfplotsutil@trim\expandafter{\pgfplotsutil@@arg@ifdefined}%
\pgfutil@IfUndefined{\pgfplotsretval #2}{#4}{#3}%
}%
% Writes the command name of '#1' without the leading backslash to
% macro #2.
\def\pgfplotsutil@getcommandname#1#2{%
\begingroup
\escapechar=-1
\xdef\pgfplots@glob@TMPa{\string#1}%
\endgroup
\let#2=\pgfplots@glob@TMPa
}
{
\catcode`\%=12
\gdef\pgfplots@PERCENT@TEXT{%}
\catcode`\^^I=12
\gdef\pgfplots@SPACE{ }
\gdef\pgfplots@TAB{^^I}
\catcode`\#=12 \gdef\pgfplots@ROUTE{#}}
% Usage:
% \pgfplots@if{pgfplots@scaled@ticks}{true-code}{false-code}
%
% it is to be used if the tex boolean is only known as string, not as
% macro.
\def\pgfplots@if#1#2#3{%
\csname if#1\endcsname
#2%
\else
#3%
\fi
}%
% Executes '#2' if the number '#1' is zero and '#3' if not.
% Example:
% \pgfplotsmath@ifzero{0}{It's zero!}{It's not zero}
% \pgfplotsmath@ifzero{0.0}{It's zero!}{It's not zero}
%
% The argument must be assignable to a TeX dimension as 'pt', but
% without units.
\def\pgfplotsmath@ifzero#1#2#3{%
\begingroup
\pgf@xa=#1pt
\ifdim\pgf@xa=0pt
\gdef\pgfplots@glob@TMPa{#2}%
\else
\gdef\pgfplots@glob@TMPa{#3}%
\fi
\endgroup
\pgfplots@glob@TMPa
}%
% Invokes code `#4' if |#1 - #2| <= #3 and `#5' if not.
%
% #1,#2 are dimension (registers or numbers) with unit.
% #3: absolute thresold (dimen)
\def\pgfplotsmath@ifapproxequal@dim#1#2#3#4#5{%
\begingroup
\pgf@xa=#1\relax
\pgf@xb=#2\relax
\advance\pgf@xa by-\pgf@xb
\ifdim\pgf@xa<0pt
\multiply\pgf@xa by-1
\fi
\ifdim\pgf@xa>#3\relax
\gdef\pgfplots@glob@TMPa{#5}%
\else
\gdef\pgfplots@glob@TMPa{#4}%
\fi
\endgroup
\pgfplots@glob@TMPa
}
\def\pgfplotsmathmin#1#2{%
\ifdim#1 pt<#2 pt
\edef\pgfmathresult{#1}%
\else
\edef\pgfmathresult{#2}%
\fi
}%
\def\pgfplotsmathmax#1#2{%
\ifdim#1 pt>#2 pt
\edef\pgfmathresult{#1}%
\else
\edef\pgfmathresult{#2}%
\fi
}%
\def\pgfplotsmathlessthan#1#2{\ifdim#1pt<#2pt \pgfmathfloatcomparisontrue\else\pgfmathfloatcomparisonfalse\fi}
% Re-define two-argument function for min and max.
% The pgfmath engine now uses a variable number of arguments.
\def\pgfplotsmathfloatmax#1#2{%
\pgfmathfloatlessthan{#1}{#2}%
\ifpgfmathfloatcomparison
\edef\pgfmathresult{#2}%
\else
\edef\pgfmathresult{#1}%
\fi
}
\def\pgfplotsmathfloatmin#1#2{%
\pgfmathfloatlessthan{#1}{#2}%
\ifpgfmathfloatcomparison
\edef\pgfmathresult{#1}%
\else
\edef\pgfmathresult{#2}%
\fi
}
% Defines \pgfmathresult to be #1 * 10^{#2}.
%
% #1 a macro without unit suffix.
% #2 an integer number (may be a register)
\def\pgfplotsmathmultiplypowten@#1#2{%
\begingroup
\pgf@xa=#1pt
\ifnum#2<0
\ifcase-#2
\or\divide\pgf@xa by10
\or\divide\pgf@xa by100
\or\divide\pgf@xa by1000
\or\divide\pgf@xa by10000
\or\divide\pgf@xa by100000
\fi
\else
\ifcase#2
\or\multiply\pgf@xa by10
\or\multiply\pgf@xa by100
\or\multiply\pgf@xa by1000
\or\multiply\pgf@xa by10000
\or\multiply\pgf@xa by100000
\fi
\fi
\edef\pgfmathresult{\pgf@sys@tonumber{\pgf@xa}}%
\pgfmath@smuggleone\pgfmathresult
\endgroup
}%
% defines \pgf@x to be the scalar product between points #1 and #2
% #1, #2 are pgfpoint commands
\def\pgfplotsscalarproductofvectors#1#2{%
\begingroup
\pgf@process{#1}%
\edef\pgfplots@scalarprod@a{\pgf@sys@tonumber\pgf@x}%
\edef\pgfplots@scalarprod@b{\pgf@sys@tonumber\pgf@y}%
\pgf@process{#2}%
\pgf@x=\pgfplots@scalarprod@a\pgf@x
\advance\pgf@x by\pgfplots@scalarprod@b\pgf@y
\global\pgf@x=\pgf@x
\endgroup
}%
% converts a comma-separated list (PGF foreach) to my internal list
% structure.
\long\def\pgfplots@foreach@to@list#1\to#2{%
\global\pgfplotslistnewempty\pgfplots@glob@TMPa
\begingroup
\foreach \pgfplots@i in {#1} {%
\expandafter\pgfplotslistpushbackglobal\pgfplots@i\to\pgfplots@glob@TMPa
}%
\endgroup
\pgfplotslistcopy\pgfplots@glob@TMPa\to#2\relax
}
% converts a foreach list to a fully expanded comma-separated list and assigns the result to \pgfplotsretval
\long\def\pgfplots@foreach@to@list@macro#1{%
\begingroup
\pgfplotsapplistXnewempty\pgfplots@tmpa
\pgfplots@loc@tmptrue
\pgfkeys{/pgf/fpu}%
%
\pgfplotsforeachungrouped \pgfplots@i in {#1} {%
\ifpgfplots@loc@tmp
\pgfplots@loc@tmpfalse
\else
\pgfplotsapplistXpushback,\to\pgfplots@tmpa
\fi
\pgfmathfloattosci\pgfplots@i
\expandafter\pgfplotsapplistXpushback\pgfmathresult\to\pgfplots@tmpa
}%
\pgfplotsapplistXlet\pgfplots@loc@TMPa=\pgfplots@tmpa
\global\let\pgfplots@glob@TMPa=\pgfplots@loc@TMPa
\endgroup
\let\pgfplotsretval=\pgfplots@glob@TMPa
}
% Removes duplicates in a comma separated list and creates a new list
% into the macro \pgfplotsretval. The list doesn't need to be sorted,
% but it should not contain too much elements as the runtime for this
% simple method is quadratic.
%
% #1: a CSV list.
% Assigns \pgfplotsretval
\def\pgfplotsutil@unify@short@csv@list#1{%
\begingroup
\def\pgfplotsretval{}%
\pgfplotsutilforeachcommasep{#1}\as\pgfplots@unify@cur{%
\pgfutil@ifundefined{pgfp@unify@\pgfplots@unify@cur @@@}{%
\expandafter\def\csname pgfp@unify@\pgfplots@unify@cur @@@\endcsname{1}%
\ifx\pgfplotsretval\pgfutil@empty
\let\pgfplotsretval=\pgfplots@unify@cur%
\else
\t@pgfplots@toka=\expandafter{\pgfplotsretval}%
\t@pgfplots@tokb=\expandafter{\pgfplots@unify@cur}%
\edef\pgfplotsretval{\the\t@pgfplots@toka,\the\t@pgfplots@tokb}%
\fi
}{}%
}%
\pgfmath@smuggleone\pgfplotsretval
\endgroup
}%
% Simply invokes the code of PGF key #1 with value #2, that means
% #1#2\pgfeov
\def\pgfplots@invoke@pgfkeyscode#1#2{%
\pgfkeysvalueof{#1}#2\pgfeov
}
% Usage:
% \pgfplots@letcsname pgfplots@xtick={pgfplots@kram@x}
% -> invokes \csname ... \endcsname for both args.
\def\pgfplots@letcsname#1=#2{%
\expandafter\let\expandafter\pgfplots@loc@TMPc\csname #2\endcsname
\expandafter\let\csname #1\endcsname=\pgfplots@loc@TMPc
}%
% Inside of a pgfplots axis, this method (together with
% \pgfplotsqpointxyz for 3d axes) is THE
% point method. If you override the mapping to PGF coordinates here,
% all other \pgfplotspoint* commands should inherit the changes as well.
\def\pgfplotsqpointxy#1#2{%
\global\pgf@x=#1\pgf@xx%
\global\advance\pgf@x by #2\pgf@yx%
\global\pgf@y=#1\pgf@xy%
\global\advance\pgf@y by #2\pgf@yy}
% Inside of a pgfplots axis, this method (together with
% \pgfplotsqpointxy for 2d axes) is THE
% point method. If you override the mapping to PGF coordinates here,
% all other \pgfplotspoint* commands should inherit the changes as well.
\def\pgfplotsqpointxyz#1#2#3{%
\global\pgf@x=#1\pgf@xx%
\global\advance\pgf@x by #2\pgf@yx%
\global\advance\pgf@x by #3\pgf@zx%
\global\pgf@y=#1\pgf@xy%
\global\advance\pgf@y by #2\pgf@yy%
\global\advance\pgf@y by #3\pgf@zy}
% A "quick" quick variant of \pgfqpointxy which assumes that
% the X unit vector is ( e_xx,0 )^T and the Y unit vector is ( 0,
% e_yy)^T.
%
% In words, the unit vectors are orthogonal. This is the usual case
% for two-dimensional plots and shall be optimized.
\def\pgfplotsqpointxy@orthogonal#1#2{%
\global\pgf@x=#1\pgf@xx%
\global\pgf@y=#2\pgf@yy
}
% Takes a domain as input and generates a foreach argument which
% samples from the domain.
% Writes the result to \pgfplotsretval
% INPUT:
% #1:#2 the domain
% #3: the number of samples
% OUTPUT:
% \pgfplotsretval a foreach specification.
\def\pgfplots@domain@to@foreach#1:#2\relax#3{%
\pgfmathparse{#1}%
\let\pgfplots@loc@TMPa=\pgfmathresult%
\pgfmathparse{#2}%
\let\pgfplots@loc@TMPb=\pgfmathresult%
\pgfmathparse{\pgfplots@loc@TMPa+(\pgfplots@loc@TMPb-\pgfplots@loc@TMPa)/(#3-1)}%
\edef\pgfplotsretval{\pgfplots@loc@TMPa,\pgfmathresult,...,\pgfplots@loc@TMPb}%
}
{
\catcode`\;=\active
\catcode`\:=\active
\gdef\pgfplots@activesemicolon{;}%
\gdef\pgfplots@activecolon{:}%
}
% checks whether ';' is active and replaces a sequence of commands
% accordingly.
%
% @see \pgfplots@appendto@activesemicolon@switcher
\def\pgfplots@checkandpreparefor@active@semicolon{%
\ifnum\the\catcode`\;=\active\relax
\pgfplots@checkandpreparefor@active@semicolon@
\fi
}%
\def\pgfplots@checkandpreparefor@active@semicolon@{}%
% Adds all commands '#1' to the sequence of commands which will be
% issued in case ';' is active.
\def\pgfplots@appendto@activesemicolon@switcher#1{%
\expandafter\def\expandafter\pgfplots@checkandpreparefor@active@semicolon@\expandafter{%
\pgfplots@checkandpreparefor@active@semicolon@
#1%
}%
}%
% Invokes '#3' for every element in the comma separated list '#1'.
% during '#3', the macro '#2' will be set to the current list element.
%
% In contrast to \foreach of tikz, this processing is NOT scoped by
% TeX groups. However, it can be nested.
%
% Please note that no trimming of white spaces is performed.
%
% This is the (accidentally) the same as \pgfplotsforeachentryinCSV.
\long\def\pgfplotsutilforeachcommasep#1\as#2#3{%
\pgfplots@for@reset@break{%
\pgfplotsforeachentryinCSVisterminated@loop{#2}{#3}#1,\pgfplots@EOI
}%
}%
% Usage:
% \pgfplotsforeachentryinCSV{\value}{1,2,3,4.5,6.7,10}{The value is \value\par}
%
% The loop is ungrouped.
%
% This is the same as \pgfplotsutilforeachcommasep, I must have been
% sleeping somehow.
%
% @see \pgfplotsutilforeachcommasep
% @see \pgfplotsforeachentryinCSVisterminated
% @see \pgfplotsforeachungrouped
% This loop can be nested.
\long\def\pgfplotsforeachentryinCSV#1#2#3{%
\pgfplots@for@reset@break{%
\pgfplotsforeachentryinCSVisterminated@loop{#1}{#3}#2,\pgfplots@EOI
}%
}%
% A variant of \pgfplotsforeachentryinCSV where a trailing comma
% indicates the end of input.
% Example:
%
% \pgfplotsforeachentryinCSV{\value}{1,2,3,4.5,6.7,10,}{The value is \value\par}
% ^
%
% It is permissable to provide an empty list (without trailing comma)
%
% This loop can be nested.
\long\def\pgfplotsforeachentryinCSVisterminated#1#2#3{%
\pgfplots@for@reset@break{%
\pgfplotsforeachentryinCSVisterminated@loop{#1}{#3}#2\pgfplots@EOI
}%
}%
% #1 : the loop macro
% #2 : the loop BODY
% #3 : the loop LIST
% (note the different sequence)
\long\def\pgfplotsforeachentryinCSVisterminated@loop#1#2{%
\pgfutil@ifnextchar\pgfplots@EOI{%
\pgfutil@gobble
}{%
\pgfplotsforeachentryinCSV@next{#1}{#2}%
}%
}%
\long\def\pgfplotsforeachentryinCSV@next#1#2#3,{%
\def#1{#3}%
#2\relax
\ifpgffor@continue
\expandafter\pgfplotsforeachentryinCSVisterminated@loop
\else
\expandafter\pgfplots@gobble@until@EOI
\fi
{#1}{#2}%
}%
% Discards any token up to (and including) \relax.
\def\pgfplots@gobble@until@relax#1\relax{}%
\def\pgfplots@gobble@until@EOI#1\pgfplots@EOI{}%
% A (simple) replacement for \foreach which
% 1. does NOT scope the argument
% 2. allows to use PGF Math routines for loops ( '...' notation)
% instead of TeX registers.
%
% Usage:
% \pgfplotsforeachungrouped \x in {1,2,3,4,5} {}
%
% Some details:
% 1. If #2 is a UNIFORM SAMPLING RANGE, the algorithm is supposed to be
% most effective. This is considered to be the case for the syntax
% \pgfplotsforeachungrouped \x in {1,2,...,8}.
% 2. If case (1.) is not used, \foreach \x in {#2} {} is invoked to
% generate a temporary list. Afterwards, this list is invoked without
% scopes.
%
% This loop *can* be nested.
\def\pgfplotsforeachungrouped#1{%
\pgfutil@ifnextchar/{\pgfplotsforeachungrouped@{#1}}{\pgfplotsforeachungrouped@{#1}/{}}%
}%
% accept both
% \pgfplotsforeachungrouped\x in{1,...,5}{a}
% \pgfplotsforeachungrouped\x in {1,...,5}{a}
\long\def\pgfplotsforeachungrouped@#1/#2in{%
\pgfutil@ifnextchar\bgroup{%
\pgfplotsforeachungrouped@@{#1}{#2}%
}{%
\pgfplots@error{Found unexpected characters: expected 'in '.}%
}%
}
\long\def\pgfplots@for@reset@break#1{%
\ifpgffor@continue
\pgffor@continuetrue
#1\relax
\pgffor@continuetrue
\else
\pgffor@continuetrue
#1\relax
\pgffor@continuefalse
\fi
}%
% Defines \pgfplotsretval to contain a 'domain' argument if '#1' is
% actually a domain listing. In this case, '\pgfplotsretvalb' will be
% set to the number of samples.
%
% If #1 is no valid domain argument, \pgfplotsretval will be set to
% empty.
\def\pgfplotsforeachtodomain#1{%
\begingroup
\long\def\pgfplotsforeachungroupednonuniform@##1##2##3{%
\def\pgfplotsretval{}%
\def\pgfplotsretvalb{}%
}%
\long\def\pgfplotsforeachungroupedslashed@##1/##2##3##4{%
\def\pgfplotsretval{}%
\def\pgfplotsretvalb{}%
}%
\long\def\pgfplotsforeachungroupeduniform@##1##2,##3,...,##4\relax##5{%
\edef\pgfplotsretval{##2:##4}%
\pgfkeys{/pgf/fpu}%
\pgfmathparse{##3-##2}%
\let\pgfplots@h=\pgfmathresult
\pgfmathparse{(##4-##2)/\pgfplots@h + 1}%
\pgfmathfloattofixed\pgfmathresult
\afterassignment\pgfplotsforeachtodomain@@
\c@pgf@counta=\pgfmathresult\relax
}%
\edef\pgfplots@loc@TMPa{\noexpand\pgfplotsforeachungrouped \noexpand\x\space in{#1}{}}%
\pgfplots@loc@TMPa
%
\xdef\pgfplots@glob@TMPa{%
\noexpand\def\noexpand\pgfplotsretval{\pgfplotsretval}%
\noexpand\def\noexpand\pgfplotsretvalb{\pgfplotsretvalb}%
}%
\endgroup
\pgfplots@glob@TMPa
}%
\def\pgfplotsforeachtodomain@@.#1\relax{%
\pgf@xa=0.#1pt %
\ifnum\pgf@xa>0.01pt % FIXME : threshold is chosen in a bad way... should be relative to number range!
% this is not an integer! We cannot convert it to a domain.
\def\pgfplotsretval{}%
\def\pgfplotsretvalb{}%
\else
% ok, it is an integer. Return it as number samples!
% \pgfplotsretval already contains the domain.
\edef\pgfplotsretvalb{\the\c@pgf@counta}%
\fi
}%
\newif\ifpgfplotsforeachungroupedassumenumeric
\pgfplotsforeachungroupedassumenumerictrue
\long\def\pgfplotsforeachungrouped@@#1#2#3#4{%
\pgfplots@for@reset@break{%
%
\def\pgfplots@foreach@loc@TMPa{#2}%
\ifx\pgfplots@foreach@loc@TMPa\pgfutil@empty
\pgfplotsforeachungrouped@isuniform{#3}%
\ifpgfplots@loc@tmp
% special handling:
% \foreach #1 in {a,b,...,c} can be improved:
\pgfplotsforeachungroupeduniform@{#1}#3\relax{#4}%
\else
\ifpgfplotsforeachungroupedassumenumeric
\pgfplotsforeachungrouped@isuniform@dist@one{#3}%
\ifpgfplots@loc@tmp
% special handling:
% \foreach #1 in {a,...,n} can be improved. Let us
% hope it is numeric ...
\pgfmathifexpression{\pgfplotsretval < \pgfplotsretvalb}{%
\edef\pgfplots@foreach@loc@TMPa{\pgfplotsretval,\pgfplotsretval+1,...,\pgfplotsretvalb}%
}{%
\edef\pgfplots@foreach@loc@TMPa{\pgfplotsretval,\pgfplotsretval-1,...,\pgfplotsretvalb}%
}%
\def\pgfplots@foreach@loc@TMPb{\pgfplotsforeachungroupeduniform@{#1}}%
\expandafter\pgfplots@foreach@loc@TMPb\pgfplots@foreach@loc@TMPa\relax{#4}%
\else
% invoke \foreach #1 in {#3} and transport results:
\pgfplotsforeachungroupednonuniform@#1{#3}{#4}%
\fi
\else
% invoke \foreach #1 in {#3} and transport results:
\pgfplotsforeachungroupednonuniform@#1{#3}{#4}%
\fi
\fi
\else
% invoke \foreach #1/#2 in {#3} and transport results:
\pgfplotsforeachungroupedslashed@#1/#2{#3}{#4}%
\fi
}%
}
\let\pgfplots@original@pgfmathadd@=\pgfmathadd@
\long\def\pgfplotsforeachungroupeduniform@#1#2,#3,...,#4\relax#5{%
% Compute mesh width!
\pgfmathparse{#2}%
\let\pgfplots@foreach@loc@TMPa=\pgfmathresult
\pgfmathparse{#3}%
\let\pgfplots@foreach@loc@TMPb=\pgfmathresult
\pgfmathsubtract@{\pgfplots@foreach@loc@TMPb}{\pgfplots@foreach@loc@TMPa}%
% Use \pgfmath engine for the loop:
% mesh width:
\let\pgfplots@foreach@loc@meshwidth=\pgfmathresult
\pgfmathparse{0}% invoke the parser - in case the fpu is active.
\pgfmathlessthan@{\pgfplots@foreach@loc@meshwidth}{\pgfmathresult}%
% the loop will run while ( NOT \pgfplots@foreach@loc@cmp{}{} )
\ifdim\pgfmathresult pt=1pt
\def\pgfplots@foreach@loc@cmp{\pgfmathlessthan@}%
\else
\def\pgfplots@foreach@loc@cmp{\pgfmathgreaterthan@}%
\fi
%
\pgfmathparse{#4 + 0.5*\pgfplots@foreach@loc@meshwidth}%
\let\pgfplots@foreach@loc@TMPb=\pgfmathresult
%
\t@pgfplots@toka={#5}%
% to allow nesting without additional TeX groups of
% \pgfplotsforeachungroupeduniform, I introduce this loop
% structure here which does not need ANY state macro:
\edef\pgfplots@foreach@loc@TMPc{%
\noexpand\pgfplotsforeachungroupeduniform@loop@mathengine
{\expandafter\noexpand\pgfplots@foreach@loc@cmp}% #1= comparison fct
{\pgfplots@foreach@loc@TMPa}% #2 =lower limit (ITERATES)
{\pgfplots@foreach@loc@TMPb}% #3 = upper limit
{\noexpand#1}% #4 = the loop macro name
{\pgfplots@foreach@loc@meshwidth}% #5 = h
{\the\t@pgfplots@toka}% #6 = the code to invoke
{0}% #7 : the loop variable
}%
\pgfplots@foreach@loc@TMPc
}%
% This here is much more accurate and does not suffer from the
% numerical stability issues of the other loop.
%
% #1: comparison fct
% #2: lower limit
% #3: upper limit
% #4: the loop macro name
% #5: h
% #6: code to invoke
% #7: the loop variable (number samples)
\long\def\pgfplotsforeachungroupeduniform@loop@mathengine@precise#1#2#3#4#5#6#7{%
\pgflibraryfpuifactive{%
\pgfmathfloatparsenumber{#7}%
}{%
\edef\pgfmathresult{#7}%
}%
\expandafter\pgfmathmultiply@\expandafter{\pgfmathresult}{#5}%
\expandafter\pgfmathadd@\expandafter{\pgfmathresult}{#2}%
\let#4=\pgfmathresult
#1{#4}{#3}% substitute this by integer arithmetics
\ifdim\pgfmathresult pt=0pt %
\def\pgfplotsforeach@loc@TMP@{\pgfutil@in@{.0\relax}}%
\expandafter\pgfplotsforeach@loc@TMP@\expandafter{#4\relax}%
\ifpgfutil@in@
% ah - our current loop variable has .0 as suffix.
% Strip it.
\def\pgfplotsforeach@loc@TMP@##1.0\relax{%
\def#4{##1}%
}%
\expandafter\pgfplotsforeach@loc@TMP@#4\relax
\fi
#6\relax
\def\pgfplotsforeach@loc@TMP@{#7}%
\pgfplotsutil@advancestringcounter\pgfplotsforeach@loc@TMP@
%
\t@pgfplots@tokc={{#1}{#2}{#3}{#4}{#5}{#6}}%
% loop!
\edef\pgfplots@loc@TMPa{\noexpand\pgfplotsforeachungroupeduniform@loop@mathengine
\the\t@pgfplots@tokc{\pgfplotsforeach@loc@TMP@}}%
\expandafter\pgfplots@loc@TMPa
\fi
}%
\long\def\pgfplotsforeachungroupeduniform@loop@mathengine@legacy#1#2#3#4#5#6#7{%
#1{#2}{#3}%
\ifpgffor@continue
\ifdim\pgfmathresult pt=0pt
\pgfutil@in@{.0\relax}{#2\relax}%
\ifpgfutil@in@
\def\pgfplotsforeach@loc@TMP##1.0\relax{%
\def#4{##1}%
}%
\pgfplotsforeach@loc@TMP#2\relax
\else
\def#4{#2}%
\fi
#6\relax
\pgfmathadd@{#2}{#5}%
\t@pgfplots@toka={{#1}}%
\t@pgfplots@tokb=\expandafter{\pgfmathresult}%
\t@pgfplots@tokc={{#3}{#4}{#5}{#6}{--}}%
% loop!
\edef\pgfplots@loc@TMPa{\noexpand\pgfplotsforeachungroupeduniform@loop@mathengine
\the\t@pgfplots@toka
{\the\t@pgfplots@tokb}%
\the\t@pgfplots@tokc}%
\expandafter\expandafter\expandafter\pgfplots@loc@TMPa
\fi
\fi
}%
\let\pgfplotsforeachungroupeduniform@loop@mathengine=\pgfplotsforeachungroupeduniform@loop@mathengine@legacy
\long\def\pgfplotsforeachungroupednonuniform@#1#2#3{%
\pgfplotsapplistXXglobalnewempty
\foreach\pgfplots@foreach@loc@TMPa in {#2} {%
\expandafter\pgfplotsapplistXXglobalpushback\expandafter{\pgfplots@foreach@loc@TMPa,}%
}%
\pgfplotsapplistXXgloballet\pgfplots@foreach@loc@TMPa
\pgfplotsapplistXXglobalclear
\expandafter\pgfplotsforeachentryinCSVisterminated\expandafter\pgfplots@foreach@loc@TMPa\expandafter{\pgfplots@foreach@loc@TMPa}{%
\let#1=\pgfplots@foreach@loc@TMPa
#3%
}%
}
\long\def\pgfplotsforeachungroupedslashed@#1/#2#3#4{%
\pgfplotsapplistXXglobalnewempty
\foreach\pgfplots@foreach@loc@TMPa/\pgfplots@foreach@loc@TMPb in {#3} {%
\edef\pgfplots@foreach@loc@TMPa{\pgfplots@foreach@loc@TMPa/\pgfplots@foreach@loc@TMPb}%
\expandafter\pgfplotsapplistXXglobalpushback\expandafter{\pgfplots@foreach@loc@TMPa,}%
}%
\pgfplotsapplistXXgloballet\pgfplots@foreach@loc@TMPa
\pgfplotsapplistXXglobalclear
\expandafter\pgfplotsforeachentryinCSVisterminated\expandafter\pgfplots@foreach@loc@TMPa\expandafter{\pgfplots@foreach@loc@TMPa}{%
\expandafter\pgfplotsforeachungroupedslashed@@\pgfplots@foreach@loc@TMPa\pgfplots@EOI
\let#1=\pgfplots@foreach@loc@TMPa
\let#2=\pgfplots@foreach@loc@TMPb
#4%
}%
}
\def\pgfplotsforeachungroupedslashed@@#1/#2\pgfplots@EOI{%
\def\pgfplots@foreach@loc@TMPa{#1}%
\def\pgfplots@foreach@loc@TMPb{#2}%
}%
% Sets \ifpgfplots@loc@tmp to true if and only if '#1' is of the form
% #1 = ,,...,.
\def\pgfplotsforeachungrouped@isuniform#1{%
\edef\pgfplots@foreach@loc@TMPa{#1}%
\expandafter\pgfplotsforeachungrouped@isuniform@\pgfplots@foreach@loc@TMPa,,,,\relax
}%
\def\pgfplotsforeachungrouped@isuniform@#1,#2,#3,#4,#5\relax{%
\def\pgfplots@foreach@loc@TMPa{#5}%
\def\pgfplots@foreach@loc@TMPb{,,,}%
\pgfplots@loc@tmpfalse
\ifx\pgfplots@foreach@loc@TMPa\pgfplots@foreach@loc@TMPb
\def\pgfplots@foreach@loc@TMPa{#3}%
\def\pgfplots@foreach@loc@TMPb{...}%
\ifx\pgfplots@foreach@loc@TMPa\pgfplots@foreach@loc@TMPb
\pgfutil@in@,{#4}%
\ifpgfutil@in@
\else
% ok, we REALLY have a uniform range!
\pgfplots@loc@tmptrue
\fi
\fi
\fi
}%
% Sets \ifpgfplots@loc@tmp to true if and only if '#1' is of the form
% #1 = ,...,
%
% In that case, \pgfplotsretval = and \pgfplotsretvalb =
\def\pgfplotsforeachungrouped@isuniform@dist@one#1{%
\edef\pgfplots@foreach@loc@TMPa{#1}%
\expandafter\pgfplotsforeachungrouped@isuniform@dist@one@\pgfplots@foreach@loc@TMPa,,,\relax
}%
\def\pgfplotsforeachungrouped@isuniform@dist@one@#1,#2,#3,#4\relax{%
\def\pgfplots@foreach@loc@TMPa{#4}%
\def\pgfplots@foreach@loc@TMPb{,,}%
\pgfplots@loc@tmpfalse
\ifx\pgfplots@foreach@loc@TMPa\pgfplots@foreach@loc@TMPb
\def\pgfplots@foreach@loc@TMPa{#2}%
\def\pgfplots@foreach@loc@TMPb{...}%
\ifx\pgfplots@foreach@loc@TMPa\pgfplots@foreach@loc@TMPb
\pgfutil@in@,{#3}%
\ifpgfutil@in@
\else
\pgfplots@loc@tmptrue
\def\pgfplotsretval{#1}%
\def\pgfplotsretvalb{#3}%
\fi
\fi
\fi
}%
% A variant of \pgfplotsforeachungrouped ( or \foreach ) which
% *invokes* with #1 set to the current iterate.
%
% Example:
% \pgfplotsinvokeforeach{a,b,c,d}
% {\pgfkeys{key #1/.style={otherstyle #1}}}
% -> will invoke
% \pgfkeys{key a/.style={otherstyle a}}
% \pgfkeys{key b/.style={otherstyle b}}
% \pgfkeys{key c/.style={otherstyle c}}
% \pgfkeys{key d/.style={otherstyle d}}
% Note that \pgfplotsforeachungrouped \d in {a,b,c,d}
% {\pgfkeys{key \d/.style={}}}
% would not work:
% \pgfkeys{key a/.style={otherstyle \d}}
% \pgfkeys{key b/.style={otherstyle \d}}
% \pgfkeys{key c/.style={otherstyle \d}}
% \pgfkeys{key d/.style={otherstyle \d}}
% such an application would need expansion control.
%
% #1: the iterates. Can be any argument as you would supply it to
% \foreach, for example \foreach \x in {1,2,...,10}
% -> #1 = {1,2,...,10}
% #2: the loop body. It can contain the parameter string '#1' which
% will be set to each element in the iterates list in turn.
%
% This method is actually just a light-weight adapter around
% \pgfplotsforeachungrouped.
\long\def\pgfplotsinvokeforeach#1#2{%
\long\def\pgfplotsinvokeforeach@@##1{#2}%
\pgfplotsforeachungrouped \pgfplotsinvokeforeach@ in {#1} {%
\expandafter\pgfplotsinvokeforeach@@\expandafter{\pgfplotsinvokeforeach@}%
}%
}
% Allows to provide an output routine for
% \pgfplotsforeachlogarithmicungrouped which changes the number format
% of \pgfmathresult.
%
% Example:
% \pgfplotsforeachlogarithmicformatresultwith{\pgfmathfloattofixed{\pgfmathresult}}
%
% #1: is code which modifies \pgfmathresult.
\def\pgfplotsforeachlogarithmicformatresultwith#1{%
\def\pgfplotsforeachlogarithmicungrouped@finalizeresult{#1}%
}
% \pgfplotsforeachlogarithmicungrouped[] \x/\logx in {a:b} {#3}
% \pgfplotsforeachlogarithmicungrouped[][