diff options
Diffstat (limited to 'Master/texmf-dist/tex/generic/pgfplots/util/pgfplotsutil.code.tex')
-rw-r--r-- | Master/texmf-dist/tex/generic/pgfplots/util/pgfplotsutil.code.tex | 510 |
1 files changed, 379 insertions, 131 deletions
diff --git a/Master/texmf-dist/tex/generic/pgfplots/util/pgfplotsutil.code.tex b/Master/texmf-dist/tex/generic/pgfplots/util/pgfplotsutil.code.tex index 68d640693cf..97260a1dae9 100644 --- a/Master/texmf-dist/tex/generic/pgfplots/util/pgfplotsutil.code.tex +++ b/Master/texmf-dist/tex/generic/pgfplots/util/pgfplotsutil.code.tex @@ -30,6 +30,9 @@ /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'! @@ -52,21 +55,11 @@ % Assigns list contents #2 to a list macro #1. % % The list contents may be provided in one of two formats: -% a) in the (deprecated) list format 'first\\second\\thirst\\' +% 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{% - \def\pgfplots@TMP{#2}% - \ifx\pgfplots@TMP\pgfutil@empty - \pgfplotslistnewempty#1% - \else - \pgfplots@check@backwards@compatible@list@format #2\\\pgfplots@EOI - \ifpgfplots@is@old@list@format - \pgfplotslistnew#1{#2}% - \else - \pgfplots@foreach@to@list{#2}\to#1 - \fi - \fi + \pgfplotslistnew#1{#2}% }% % Sets the boolean \ifpgfplots@is@old@list@format to true if and only @@ -166,22 +159,45 @@ \def\pgfplots@command@to@string#1#2{% \expandafter\pgfplots@command@to@string@@\meaning#1\pgfplots@EOI{#2}% }% -{ -\let\CATCODE=\catcode -\CATCODE`\:=12 -\CATCODE`\-=12 -\CATCODE`\>=12 -\CATCODE`\m=12 -\CATCODE`\a=12 -\CATCODE`\c=12 -\CATCODE`\r=12 -\CATCODE`\o=12 -\xdef\pgfplts@glb@TMP{macro:->}% -} -\expandafter\def\expandafter\pgfplots@command@to@string@@\pgfplts@glb@TMP#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}% }% +% 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{% + \def\pgfplotsutil@@arg@ifdefined{#1}% + \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{% + \def\pgfplotsutil@@arg@ifdefined{#1}% + \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{% @@ -210,6 +226,46 @@ \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}% @@ -274,6 +330,19 @@ \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. @@ -287,14 +356,39 @@ \pgfplotslistcopy\pgfplots@glob@TMPa\to#2\relax } + +% 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{% - \pgfkeysgetvalue{#1}\pgfplots@invoke@pgfkeyscode@CODE - \pgfplots@invoke@pgfkeyscode@CODE#2\pgfeov + \pgfkeysvalueof{#1}#2\pgfeov } - % Usage: % \pgfplots@letcsname pgfplots@xtick={pgfplots@kram@x} % -> invokes \csname ... \endcsname for both args. @@ -324,19 +418,19 @@ % Takes a domain as input and generates a foreach argument which % samples from the domain. -% Writes the result to \pgfplotslocretval +% Writes the result to \pgfplotsretval % INPUT: % #1:#2 the domain -% /pgfplots/samples the number of samples +% #3: the number of samples % OUTPUT: -% \pgfplotslocretval a foreach specification. -\def\pgfplots@domain@to@foreach#1:#2\relax{% +% \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)/(\pgfkeysvalueof{/pgfplots/samples}-1)}% - \edef\pgfplotslocretval{\pgfplots@loc@TMPa,\pgfmathresult,...,\pgfplots@loc@TMPb}% + \pgfmathparse{\pgfplots@loc@TMPa+(\pgfplots@loc@TMPb-\pgfplots@loc@TMPa)/(#3-1)}% + \edef\pgfplotsretval{\pgfplots@loc@TMPa,\pgfmathresult,...,\pgfplots@loc@TMPb}% } { @@ -366,15 +460,33 @@ }% }% +% 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{% + \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{% - \def\pgfplotsforeachentryinCSV@{#1}% - \long\def\pgfplotsforeachentryinCSV@@{#3}% - \pgfplotsforeachentryinCSV@loop#2,\pgfplots@EOI + \pgfplotsforeachentryinCSVisterminated@loop{#1}{#3}#2,\pgfplots@EOI }% % A variant of \pgfplotsforeachentryinCSV where a trailing comma % indicates the end of input. @@ -384,25 +496,32 @@ % ^ % % It is permissable to provide an empty list (without trailing comma) +% +% This loop can be nested. \long\def\pgfplotsforeachentryinCSVisterminated#1#2#3{% - \def\pgfplotsforeachentryinCSV@{#1}% - \long\def\pgfplotsforeachentryinCSV@@{#3}% - \pgfplotsforeachentryinCSV@loop#2\pgfplots@EOI + \pgfplotsforeachentryinCSVisterminated@loop{#1}{#3}#2\pgfplots@EOI }% -\def\pgfplotsforeachentryinCSV@loop{% +% #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 + \pgfplotsforeachentryinCSV@next{#1}{#2}% }% }% -\def\pgfplotsforeachentryinCSV@next#1,{% - \expandafter\def\pgfplotsforeachentryinCSV@{#1}% - \pgfplotsforeachentryinCSV@@ - \pgfplotsforeachentryinCSV@loop +\long\def\pgfplotsforeachentryinCSV@next#1#2#3,{% + \def#1{#3}% + #2\relax + \pgfplotsforeachentryinCSVisterminated@loop{#1}{#2}% }% +% Discards any token up to (and including) \relax. +\def\pgfplots@gobble@until@relax#1\relax{}% + % A (simple) replacement for \foreach which % 1. does NOT scope the argument % 2. allows to use PGF Math routines for loops ( '...' notation) @@ -412,102 +531,88 @@ % \pgfplotsforeachungrouped \x in {1,2,3,4,5} {<code>} % % Some details: -% - If #2 is a UNIFORM SAMPLING RANGE, the algorithm is supposed to be -% most effective. -% - If \pgfmathadd@ is the standard PGF math version of \pgfmathadd@, -% we use fast TeX dimensions for any loops. Otherwise, \pgfmathadd@ -% is used (assuming it has been replaced and should be used. +% 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{\pgfplotsforeachungrouped@{#1}}% \long\def\pgfplotsforeachungrouped@#1in #2#3{% \pgfplotsforeachungrouped@isuniform{#2}% \ifpgfplots@loc@tmp - \pgfplotsforeachungroupeduniform@#1{#2}{#3}% + \pgfplotsforeachungroupeduniform@{#1}#2\relax{#3}% \else \pgfplotsforeachungroupednonuniform@#1{#2}{#3}% \fi } \let\pgfplots@original@pgfmathadd@=\pgfmathadd@ -\long\def\pgfplotsforeachungroupeduniform@#1#2#3{% - \pgfplotsforeachungroupeduniform@@{#1}#2\relax{#3}% -} -\long\def\pgfplotsforeachungroupeduniform@@#1#2,#3,...,#4\relax#5{% +\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}% - \ifx\pgfmathadd@\pgfplots@original@pgfmathadd@ - % perform manual restoration of local variables: - \edef\pgfplots@foreach@loc@TMPd{% - \noexpand\pgf@xa=\the\pgf@xa\noexpand\relax - \noexpand\pgf@xb=\the\pgf@xb\noexpand\relax - \noexpand\pgf@ya=\the\pgf@ya\noexpand\relax - }% - % mesh width: - \pgf@ya=\pgfmathresult pt - % the loop will run while ( NOT <cur> \pgfplots@foreach@loc@cmp <last> ) - \ifdim\pgf@ya<0pt - \def\pgfplots@foreach@loc@cmp{<}% - \else - \def\pgfplots@foreach@loc@cmp{>}% - \fi - % - \pgfmathparse{#4}% - \let\pgfplots@foreach@loc@TMPb=\pgfmathresult - \pgf@xa=\pgfplots@foreach@loc@TMPa pt - \pgf@xb=\pgfplots@foreach@loc@TMPb pt - \long\def\pgfplots@foreach@loc@TMPc{#5}% - % - \pgfutil@loop - \ifdim\pgf@xa \pgfplots@foreach@loc@cmp \pgf@xb\relax - \pgfplots@loc@tmpfalse - \else - \pgfplots@loc@tmptrue - \fi - \ifpgfplots@loc@tmp - \edef#1{\pgf@sys@tonumber{\pgf@xa}}% - \pgfplots@foreach@loc@TMPc\relax - \advance\pgf@xa by\pgf@ya\relax - \pgfutil@repeat - % ok, restore them: - \pgfplots@foreach@loc@TMPd + % 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{<cur>}{<last>} ) + \ifdim\pgfmathresult pt=1pt + \def\pgfplots@foreach@loc@cmp{\pgfmathlessthan@}% \else - % Use \pgfmath engine for the loop: - \edef\pgfplots@foreach@loc@TMPd{% - \noexpand\pgf@xa=\the\pgf@xa\noexpand\relax - }% - % 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}% - \pgf@xa=\pgfmathresult pt - % the loop will run while ( NOT \pgfplots@foreach@loc@cmp{<cur>}{<last>} ) - \ifdim\pgf@xa=1pt - \let\pgfplots@foreach@loc@cmp=\pgfmathlessthan@ + \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 + }% + \pgfplots@foreach@loc@TMPc +}% +\long\def\pgfplotsforeachungroupeduniform@loop@mathengine#1#2#3#4#5#6{% + #1{#2}{#3}% + \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 - \let\pgfplots@foreach@loc@cmp=\pgfmathgreaterthan@ + \def#4{#2}% \fi - % - \pgfmathparse{#4}% - \let\pgfplots@foreach@loc@TMPb=\pgfmathresult - \long\def\pgfplots@foreach@loc@TMPc{#5}% - % - \pgfutil@loop - \pgfplots@foreach@loc@cmp{\pgfplots@foreach@loc@TMPa}{\pgfplots@foreach@loc@TMPb}% - \pgf@xa=\pgfmathresult pt - \ifdim\pgf@xa=0pt - \let#1=\pgfplots@foreach@loc@TMPa% - \pgfplots@foreach@loc@TMPc\relax - \pgfmathadd@{\pgfplots@foreach@loc@TMPa}{\pgfplots@foreach@loc@meshwidth}% - \let\pgfplots@foreach@loc@TMPa=\pgfmathresult - \pgfutil@repeat - % ok, restore them: - \pgfplots@foreach@loc@TMPd + #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\pgfplots@loc@TMPa \fi }% + \long\def\pgfplotsforeachungroupednonuniform@#1#2#3{% \pgfplotsapplistXXglobalnewempty \foreach\pgfplots@foreach@loc@TMPa in {#2} {% @@ -521,7 +626,7 @@ }% } -% Sets \ifpgfplots@loc@tmp to something true if and only if '#1' is of the form +% Sets \ifpgfplots@loc@tmp to true if and only if '#1' is of the form % #1 = <number1>,<number2>,...,<number3>. \def\pgfplotsforeachungrouped@isuniform#1{% \edef\pgfplots@foreach@loc@TMPa{#1}% @@ -545,6 +650,41 @@ \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. @@ -557,7 +697,7 @@ \def\pgfplotsforeachlogarithmicungrouped@finalizeresult{#1}% } -% \pgfplotsforeachlogarithmicungrouped \x/\logx in {a:b} {#3} +% \pgfplotsforeachlogarithmicungrouped[<samples>] \x/\logx in {a:b} {#3} % % samples \x between a and b using a logarithmic scale. % @@ -568,19 +708,20 @@ % configured otherwise with \pgfplotsforeachlogarithmicsetoutput, % see above. % -\def\pgfplotsforeachlogarithmicungrouped#1/#2{\pgfplotsforeachlogarithmicungrouped@{#1}{#2}}% -\long\def\pgfplotsforeachlogarithmicungrouped@#1#2in #3#4{% +% FIXME : THIS CAN'T BE NESTED YET! +\def\pgfplotsforeachlogarithmicungrouped[#1]#2/#3{\pgfplotsforeachlogarithmicungrouped@[#1]{#2}{#3}}% +\long\def\pgfplotsforeachlogarithmicungrouped@[#1]#2#3in #4#5{% % define % \pgfplots@foreach@loc@TMPd = N in fixed point % \pgfplots@foreach@loc@TMPc = N-1 in float : - \pgfkeysgetvalue{/pgfplots/samples}{\pgfplots@plot@samples} + \edef\pgfplots@plot@samples@@{#1}% \pgfmathfloatcreate{1}{1.0}{0}% \let\pgfplots@foreach@loc@TMPa=\pgfmathresult - \pgfmathfloatparsenumber{\pgfplots@plot@samples}% + \pgfmathfloatparsenumber{\pgfplots@plot@samples@@}% \expandafter\pgfmathfloatsubtract@\expandafter{\pgfmathresult}{\pgfplots@foreach@loc@TMPa}% \let\pgfplots@foreach@loc@TMPc=\pgfmathresult % - \edef\pgfplots@loc@TMPb{#3}% + \edef\pgfplots@loc@TMPb{#4}% \expandafter\pgfplotsforeachlogarithmicungrouped@readdomain\pgfplots@loc@TMPb\relax % compute mesh width into \pgfplots@foreach@loc@TMPc: % \pgfplots@foreach@loc@TMPc := h := ( log(xmax) - log(xmin) ) / (N-1) @@ -592,20 +733,20 @@ \edef\pgfplots@foreach@loc@TMPd{% \noexpand\c@pgf@counta=\the\c@pgf@counta\noexpand\relax }% - \long\def\pgfplots@foreach@loc@TMPf{#4}% + \long\def\pgfplots@foreach@loc@TMPf{#5}% \c@pgf@counta=0 \pgfutil@loop - \ifnum\c@pgf@counta<\pgfplots@plot@samples + \ifnum\c@pgf@counta<\pgfplots@plot@samples@@ % compute exp(log(min) + i * h) \expandafter\pgfmathfloatparsenumber\expandafter{\the\c@pgf@counta}% \expandafter\pgfmathfloatmultiply@\expandafter{\pgfmathresult}{\pgfplots@foreach@loc@TMPc}% \expandafter\pgfmathfloatadd@\expandafter{\pgfmathresult}{\pgfplots@foreach@loc@TMPa}% \let\pgfplots@loc@TMPa=\pgfmathresult \pgfplotsforeachlogarithmicungrouped@finalizeresult% - \let#2=\pgfmathresult + \let#3=\pgfmathresult \pgfmathfloatexp@{\pgfplots@loc@TMPa}% \pgfplotsforeachlogarithmicungrouped@finalizeresult% - \let#1=\pgfmathresult + \let#2=\pgfmathresult % % ok, invoke it! % -> store \c@pgf@counta before doing so. We need to scope @@ -659,6 +800,28 @@ \expandafter#1\pgfutil@edef@invoke@ } +% defines \pgfmathresult to be the INTEGER result of (#1 mod #2). +% +% \pgfplotsmathmod{2}{4} -> 2 +% \pgfplotsmathmod{9}{5} -> 4 +\def\pgfplotsmathmodint#1#2{% + \begingroup + \c@pgf@counta=#2\relax + \c@pgf@countb=#1\relax + \c@pgf@countc=\c@pgf@countb + \ifnum\c@pgf@counta=0 + \pgfplots@error{Can't compute \the\c@pgf@countb\space mod \the\c@pgf@counta\space -- this yields division by zero (second argument is zero)!}% + \edef\pgfmathresult{#1}% + \else + \divide\c@pgf@countc by\c@pgf@counta + \multiply\c@pgf@countc by\c@pgf@counta + \advance\c@pgf@countb by-\c@pgf@countc + \edef\pgfmathresult{\the\c@pgf@countb}% + \fi + \pgfmath@smuggleone\pgfmathresult + \endgroup +}% + % Advances a number stored in a macro and writes the result back into % the macro. % #1 is a macro containing a number. @@ -670,10 +833,95 @@ \pgfmath@smuggleone#1% \endgroup }% +\def\pgfplotsutil@advancestringcounter@global#1{% + \begingroup + \c@pgf@counta=#1\relax + \advance\c@pgf@counta by1 + \xdef#1{\the\c@pgf@counta}% + \endgroup +}% + +\newif\ifpgfplotsloopcontinue + +% A loop construct which invokes '#1' and continues the loop if the +% boolean \ifpgfplotsloopcontinue is true and stops if it is false. +% +% #1: a statement which is expected to set \ifpgfplotsloopcontinue +% #2: the loop body. +\def\pgfplotsloop#1#2{% + #1\relax + \ifpgfplotsloopcontinue + #2\relax + \def\pgfplotsloop@{\pgfplotsloop{#1}{#2}}% + \expandafter\pgfplotsloop@ + \fi +}% + +\pgfutil@ifundefined{pgfmathdeclarefunction}{% + % BACKWARDS COMPATIBILITY: We have PGF 2.00 : + \def\pgfplotsmathdeclarepseudoconstant#1#2{% + \t@pgfplots@toka=\expandafter{\csname pgfmath#1@\endcsname}% + \t@pgfplots@tokb={\pgfmath@postfunction}% + \expandafter\edef\csname pgfmath@parsefunction@#1\endcsname{\the\t@pgfplots@toka\the\t@pgfplots@tokb}% + \expandafter\edef\csname pgfmath#1\endcsname{\the\t@pgfplots@toka}% + \expandafter\def\csname pgfmath#1@\endcsname{#2}% + }% + \let\pgfplotsmathredeclarepseudoconstant=\pgfplotsmathdeclarepseudoconstant +}{% + \def\pgfplotsmathdeclarepseudoconstant#1#2{% + \pgfmathdeclarefunction*{#1}{0}{#2}% + }% + \def\pgfplotsmathredeclarepseudoconstant#1#2{% + \pgfmathredeclarefunction{#1}{#2}% + }% +}% + + +% Usage: +% \pgfplotsutilstrreplace{<token>}{<replacement>}{<string>} +% +% -> will assign the modified string into \pgfplotsretval. +% +% #1: the string to search (one or more tokens) +% #2: zero, one or more tokens which will be inserted instead of '#1'. +% #3: the string to search in +\long\def\pgfplotsutilstrreplace#1#2#3{% + \def\pgfplotsretval{}% + \long\def\pgfplotsutil@search@and@replace@@##1#1##2\pgfplots@EOI{% + \expandafter\def\expandafter\pgfplotsretval\expandafter{\pgfplotsretval ##1#2}% + \pgfplotsutil@search@and@replace@loop{#1}{##2}% + }% + \pgfplotsutil@search@and@replace@loop{#1}{#3}% +} +\long\def\pgfplotsutil@search@and@replace@loop#1#2{% + \pgfutil@in@{#1}{#2}% + \ifpgfutil@in@ + \def\pgfplots@loc@TMPa{\pgfplotsutil@search@and@replace@@ #2\pgfplots@EOI}% + \else + \expandafter\def\expandafter\pgfplotsretval\expandafter{\pgfplotsretval #2}% + \let\pgfplots@loc@TMPa=\relax + \fi + \pgfplots@loc@TMPa +}% + +% strcmp: invokes #3 if #1=#2 (top level expansion only) and it +% invokes #4 if #1!=#2. +\long\def\pgfplotsutilifstringequal#1#2#3#4{% + \def\pgfplotsifstringequal@{#1}% + \def\pgfplotsifstringequal@@{#2}% + \ifx\pgfplotsifstringequal@\pgfplotsifstringequal@@ #3\else #4\fi +}% + +% this command is in pgfplotscore.code.tex: +% \pgfplotsiffileexists \input pgfplotsliststructure.code.tex \input pgfplotsliststructureext.code.tex \input pgfplotsarray.code.tex \input pgfplotstable.code.tex +\input pgfplotsdeque.code.tex +\input pgfplotsbinary.code.tex + +\usepgfplotslibrary{surfshading} \endinput |