Current File : //usr/share/texlive/texmf-dist/tex/generic/pgf/utilities/pgfutil-common.tex |
% Copyright 2019 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.
%
% This file provides utility commands that are used throughout pgf.
%
% For most commands, the definition of these commands is just given
% below. We cannot use the LaTeX definition of these commands since
% LaTeX may not be the current format and since LaTeX packages tend to
% redefine these commands.
%
% For some commands the actual definition of the format (like latex or
% context) is to be preferred over the generic definition below. In
% this case, the definition of the format is installed when the file
% pgfutil-XXXX.tex is read, where XXXX is the format name (latex,
% plain, or context).
\catcode`\@=11\relax
% Which format is loaded?
\newif\ifpgfutil@format@is@latex
\newif\ifpgfutil@format@is@plain
\newif\ifpgfutil@format@is@context
% Simple stuff
% \pgfutil@trimspaces{<token list>}
%
% Removes spaces on both sides of <token list>. Same as trimspaces.sty
\catcode`\Q=3
\def\pgfutil@trimspaces#1{%
\romannumeral-`0\pgfutil@trimspaces@\noexpand#1Q Q}
\def\pgfutil@trimspaces@#1 Q{\pgfutil@trimspaces@@#1Q}
\def\pgfutil@trimspaces@@#1Q#2{#1}
\catcode`\Q=11
% \pgfutil@ifempty{<cs>}{<true code>}{<false code>}
%
% Check if <cs> is equal to \pgfutil@empty
%
% This macro is expandable.
\def\pgfutil@ifempty#1{%
\ifx#1\pgfutil@empty
\expandafter\pgfutil@firstoftwo
\else
\expandafter\pgfutil@secondoftwo
\fi}
% \pgfutil@ifundefined{<macro name with backslash>}
% {<is undefined code>}{<is defined code>}
%
% This will let #1 to \relax if it undefined.
%
% This macro is expandable.
\def\pgfutil@ifundefined#1{%
\expandafter\ifx\csname#1\endcsname\relax
\expandafter\pgfutil@firstoftwo
\else
\expandafter\pgfutil@secondoftwo
\fi}
% A variant of \pgfutil@ifundefined which will NOT let #1 to \relax it
% is undefined.
\def\pgfutil@IfUndefined#1{%
\ifcsname#1\endcsname
\expandafter\pgfutil@secondoftwo
\else
\expandafter\pgfutil@firstoftwo
\fi
}
\long\def\pgfutil@firstofone#1{#1}
\long\def\pgfutil@firstoftwo#1#2{#1}
\long\def\pgfutil@secondoftwo#1#2{#2}
\def\pgfutil@empty{}
\long\def\pgfutil@gobble@until@relax#1\relax{}
\long\def\pgfutil@gobble#1{}
\long\def\pgfutil@gobbletwo#1#2{}
\def\pgfutil@namedef#1{\expandafter\def\csname #1\endcsname}
\def\pgfutil@namelet#1{\expandafter\pgfutil@@namelet\csname#1\endcsname}
\def\pgfutil@@namelet#1#2{\expandafter\let\expandafter#1\csname#2\endcsname}
\long\def\pgfutil@g@addto@macro#1#2{%
\begingroup
\pgfutil@toks@\expandafter{#1#2}%
\xdef#1{\the\pgfutil@toks@}%
\endgroup}
\newif\ifpgfutil@tempswa
\newif\ifpgfutil@tempswb
% \pgfutil@pushmacro
% \pgfutil@popmacro
%
% Macro stack. Allows pushing a macro over \egroup. Taken from ConTeXt
\let\pgfutil@pushmacro@string\pgfutil@empty
\def\pgfutil@pushmacro#1{%
\xdef\pgfutil@pushmacro@string{\string#1}%
\ifcsname pgfutil@pushedmacro@\pgfutil@pushmacro@string\endcsname\else
% \newcount is \outer in Plain
\csname newcount\expandafter\endcsname\csname pgfutil@pushedmacro@\pgfutil@pushmacro@string\endcsname
\fi
\global\advance\csname pgfutil@pushedmacro@\pgfutil@pushmacro@string\endcsname 1\relax
\global\expandafter\let\csname\the\csname pgfutil@pushedmacro@\pgfutil@pushmacro@string\endcsname\pgfutil@pushmacro@string\endcsname#1%
}
\def\pgfutil@popmacro#1{%
\xdef\pgfutil@pushmacro@string{\string#1}%
\expandafter\let\expandafter#1\csname\the\csname pgfutil@pushedmacro@\pgfutil@pushmacro@string\endcsname\pgfutil@pushmacro@string\endcsname
\global\advance\csname pgfutil@pushedmacro@\pgfutil@pushmacro@string\endcsname -1\relax
}
% pgfutil@ifnextchar
\long\def\pgfutil@ifnextchar#1#2#3{%
\let\pgfutil@reserved@d=#1%
\def\pgfutil@reserved@a{#2}%
\def\pgfutil@reserved@b{#3}%
\futurelet\pgfutil@let@token\pgfutil@ifnch}
\def\pgfutil@ifnch{%
\ifx\pgfutil@let@token\pgfutil@sptoken
\let\pgfutil@reserved@c\pgfutil@xifnch
\else
\ifx\pgfutil@let@token\pgfutil@reserved@d
\let\pgfutil@reserved@c\pgfutil@reserved@a
\else
\let\pgfutil@reserved@c\pgfutil@reserved@b
\fi
\fi
\pgfutil@reserved@c}
{%
\def\:{\global\let\pgfutil@sptoken= } \:
\def\:{\pgfutil@xifnch} \expandafter\gdef\: {\futurelet\pgfutil@let@token\pgfutil@ifnch}
}
% pgfutil@ignorespaces
\def\pgfutil@ignorespaces
{\ifx\pgfutil@let@token\pgfutil@sptoken
\expandafter\pgfutil@ignorespaces@helper
\else
\expandafter\pgfutil@next
\fi}
{
\def\:{\pgfutil@ignorespaces@helper}
\expandafter\gdef\: {\futurelet\pgfutil@let@token\pgfutil@ignorespaces}
}
% pgfutil@in@
\newif\ifpgfutil@in@
% Usage:
% \pgfutil@in@{one}{three two one}
% \ifpgfutil@in@
% -> will be true!
% \else
% \fi
%
% \pgfutil@in@{,}{1234,456567}
% \ifpgfutil@in@
% -> will be true!
% \else
% \fi
\def\pgfutil@in@#1#2{%
\def\pgfutil@in@@##1#1##2##3\pgfutil@in@@{%
\ifx\pgfutil@in@##2\pgfutil@in@false\else\pgfutil@in@true\fi}%
\pgfutil@in@@#2#1\pgfutil@in@\pgfutil@in@@}
% pgfutil@for
\def\pgfutil@nnil{\pgfutil@nil}
\def\pgfutil@fornoop#1\@@#2#3{}
\long\def\pgfutil@for#1:=#2\do#3{%
\expandafter\def\expandafter\pgfutil@fortmp\expandafter{#2}%
\ifx\pgfutil@fortmp\pgfutil@empty \else
\expandafter\pgfutil@forloop#2,\pgfutil@nil,\pgfutil@nil\@@#1{#3}\fi}
\long\def\pgfutil@forloop#1,#2,#3\@@#4#5{\def#4{#1}\ifx #4\pgfutil@nnil \else
#5\def#4{#2}\ifx #4\pgfutil@nnil \else#5\pgfutil@iforloop #3\@@#4{#5}\fi\fi}
\long\def\pgfutil@iforloop#1,#2\@@#3#4{\def#3{#1}\ifx #3\pgfutil@nnil
\expandafter\pgfutil@fornoop \else
#4\relax\expandafter\pgfutil@iforloop\fi#2\@@#3{#4}}
\def\pgfutil@tfor#1:={\pgfutil@tf@r#1 }
\long\def\pgfutil@tf@r#1#2\do#3{\def\pgfutil@fortmp{#2}\ifx\pgfutil@fortmp\pgfutil@space\else
\pgfutil@tforloop#2\pgfutil@nil\pgfutil@nil\@@#1{#3}\fi}
\long\def\pgfutil@tforloop#1#2\@@#3#4{\def#3{#1}\ifx #3\pgfutil@nnil
\expandafter\pgfutil@fornoop \else
#4\relax\expandafter\pgfutil@tforloop\fi#2\@@#3{#4}}
\def\pgfutil@space{ }
% pgfutil@IfFileExists
\chardef\pgfutil@inputcheck0
\def\pgfutil@IfFileExists#1#2#3{%
\openin\pgfutil@inputcheck=#1 %
\ifeof\pgfutil@inputcheck
#3\relax
\else
#2\relax
\fi
\closein\pgfutil@inputcheck}
\def\pgfutil@InputIfFileExists#1#2#3{\pgfutil@IfFileExists{#1}{\input #1\relax#2}{#3}}%
% 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
% \pgfutil@switch
%
% #1: string to switch on
% #2: sequence of label-value pairs
%
% Example:
%
% \pgfutil@switch{foo}{%
% {foo}{1}%
% {bar}{2}%
% {default}{X}%
% }
%
% If a statement with the label `default' exists it will be executed
% if no other label matches.
\long\def\pgfutil@switch#1#2{%
\begingroup
\def\pgfutil@switch@selected{}%
\pgfutil@switch@collect@statements#2{}{}%
\ifcsname pgfutil@switch@choice@\detokenize{#1}\endcsname
\expandafter\let\expandafter\pgfutil@switch@selected\csname pgfutil@switch@choice@\detokenize{#1}\endcsname
\else
\ifdefined\pgfutil@switch@choice@default
\let\pgfutil@switch@selected\pgfutil@switch@choice@default
\fi
\fi
\expandafter\endgroup\pgfutil@switch@selected
}
\long\def\pgfutil@switch@collect@statements#1{%
\if\relax\detokenize{#1}\relax
\else
\afterassignment\pgfutil@switch@collect@statements
\expandafter\def\csname pgfutil@switch@choice@\detokenize{#1}\expandafter\endcsname
\fi
}
% aux-read-hook
\let\pgfutil@aux@read@hook=\relax
% Tokens for the end of the typesetting -- they will be added at the
% end of every job (hopefully...).
\newtoks\pgfutil@everybye
%
% PDF-Resource management -- might seem strange that this is here, but
% it turns out to be the correct place since latex and context handle
% this stuff quite differently
%
% Adding something to the pdf-resources:
\def\pgfutil@addpdfresource@extgs#1{\pgf@sys@addpdfresource@extgs@plain{#1}}
\def\pgfutil@addpdfresource@colorspaces#1{\pgf@sys@addpdfresource@colorspaces@plain{#1}}
\def\pgfutil@addpdfresource@patterns#1{\pgf@sys@addpdfresource@patterns@plain{#1}}
\def\pgfutil@setuppdfresources{\pgf@sys@setuppdfresources@plain}
% Inserts the argument at the begin of the current page (hopefully)
\let\pgfutil@insertatbegincurrentpage=\relax
% Ragged left and ragged right
\def\pgfutil@raggedright{\rightskip\z@ plus2em \spaceskip.3333em \xspaceskip.5em\relax}
\def\pgfutil@raggedleft{\leftskip\z@ plus2em \rightskip\z@ \spaceskip.3333em \xspaceskip.5em\parfillskip0pt\relax}
% Error Messages
\def\pgfutil@packageerror#1#2#3{\errhelp{#3}\errmessage{Package #1 Error: #2}}
\def\pgfutil@packagewarning#1#2{\immediate\write17{Package #1: Warning! #2.}}
\def\pgferror#1{\pgfutil@packageerror{pgf}{#1}{}}
\def\pgfwarning#1{\pgfutil@packagewarning{pgf}{#1}}
% Library files inclusion
% Include a library file.
%
% #1 = List of names of library file.
%
% Description:
%
% This command includes a list of library files. For each file X in the
% list, the file pgflibraryX.code.tex is included, provided this has
% not been done earlier.
%
% For the convenience of Context users, both round and square brackets
% are possible for the argument.
%
% Example:
%
% \usepgflibrary{arrows}
% \usepgflibrary[patterns,snakes]
\def\usepgflibrary{\pgfutil@ifnextchar[{\use@pgflibrary}{\use@@pgflibrary}}%}
\def\use@pgflibrary[#1]{\use@@pgflibrary{#1}}
\def\use@@pgflibrary#1{%
\edef\pgf@list{#1}%
\pgfutil@for\pgf@temp:=\pgf@list\do{%
\expandafter\pgfkeys@spdef\expandafter\pgf@temp\expandafter{\pgf@temp}%
\ifx\pgf@temp\pgfutil@empty
\else
\expandafter\ifx\csname pgf@library@\pgf@temp @loaded\endcsname\relax%
\expandafter\let\csname pgf@library@\pgf@temp @loaded\endcsname=\pgfutil@empty%
\expandafter\edef\csname pgf@library@#1@atcode\endcsname{\the\catcode`\@}
\expandafter\edef\csname pgf@library@#1@barcode\endcsname{\the\catcode`\|}
\expandafter\edef\csname pgf@library@#1@dollarcode\endcsname{\the\catcode`\$}
\catcode`\@=11
\catcode`\|=12
\catcode`\$=3
\pgfutil@InputIfFileExists{pgflibrary\pgf@temp.code.tex}{}{%
\pgferror{I did not find the pgf library
'\pgf@temp'. I looked for the file named
pgflibrary\pgf@temp.code.tex, but could not find it in in
the current texmf trees.}
}%
\catcode`\@=\csname pgf@library@#1@atcode\endcsname
\catcode`\|=\csname pgf@library@#1@barcode\endcsname
\catcode`\$=\csname pgf@library@#1@dollarcode\endcsname
\fi%
\fi
}%
}
% Include a module file.
%
% #1 = List of names of module files.
%
% Description:
%
% This command includes a list of module files. For each file X in the
% list, the file pgfmoduleX.code.tex is included, provided this has
% not been done earlier.
%
% For the convenience of Context users, both round and square brackets
% are possible for the argument.
%
% Example:
%
% \usepgfmodule{matrix}
\def\usepgfmodule{\pgfutil@ifnextchar[{\use@pgfmodule}{\use@@pgfmodule}}%}
\def\use@pgfmodule[#1]{\use@@pgfmodule{#1}}
\def\use@@pgfmodule#1{%
\edef\pgf@list{#1}%
\pgfutil@for\pgf@temp:=\pgf@list\do{%
\expandafter\ifx\csname pgf@module@\pgf@temp @loaded\endcsname\relax%
\expandafter\let\csname pgf@module@\pgf@temp @loaded\endcsname=\pgfutil@empty%
\expandafter\edef\csname pgf@module@#1@atcode\endcsname{\the\catcode`\@}
\expandafter\edef\csname pgf@module@#1@barcode\endcsname{\the\catcode`\|}
\expandafter\edef\csname pgf@module@#1@dollarcode\endcsname{\the\catcode`\$}
\catcode`\@=11
\catcode`\|=12
\catcode`\$=3
\input pgfmodule\pgf@temp.code.tex
\catcode`\@=\csname pgf@module@#1@atcode\endcsname
\catcode`\|=\csname pgf@module@#1@barcode\endcsname
\catcode`\$=\csname pgf@module@#1@dollarcode\endcsname
\fi%
}%
}
\def\pgfutilensuremath#1{%
\ifmmode#1\else$#1$\fi
}
%
% Guess the driver:
%
\begingroup
\catcode`\"=12
\edef\pgf@loc@TMPa{"}%
%
% prepares file names by checking for double colons.
%
% If '#1' is a usual file name without anything fancy, \pgfretval
% will simply contain it. However, if '#1' contains double colons
% (introduces, for example, by pdftex because there are white
% spaces in '#1'), the routine
% - removes the double colons,
% - re-inserts them outside of the string.
%
% \pgfutilpreparefilename{file.tex} -> file.tex
% \pgfutilpreparefilename{"A file name".file} -> "A file name.file"
%
% The resulting file name is returned in '\pgfretval',
% furthermore, a *quoted* version of the file name is returned in
% \pgfretvalquoted. The latter result is to have some sort of
% output normalisation: if the file name as such contains double
% quotes, we don't want to insert another set of them.
%
% This special handling has the following purposes:
% 1. Both, treatment of white spaces and double colons is not
% properly defined in TeX. Thus, we should only work with them if
% necessary and maintain backwards compatibility as far as
% possible.
% 2. It *should* work if there are spaces.
%
\gdef\pgfutilpreparefilename#1{%
\begingroup
\ifnum\the\catcode`\"=13
\pgfutilconvertdcolon
\fi
\xdef\pgf@temp{#1}%
\endgroup
\expandafter\pgfutil@in@\expandafter"\expandafter{\pgf@temp}%
\ifpgfutil@in@
\def\pgf@loc@TMPa{\pgfutilstrreplace{"}{}}%
\expandafter\pgf@loc@TMPa\expandafter{\pgf@temp}%
\edef\pgfretval{"\pgfretval"}% re-insert quotes! Otherwise, TeX can't use the file name.
\let\pgfretvalquoted=\pgfretval
\else
\let\pgfretval=\pgf@temp
\edef\pgfretvalquoted{"\pgfretval"}%
\fi
}%
\catcode`\"=13
\xdef\pgfutilconvertdcolon{%
\noexpand\def\noexpand"{\pgf@loc@TMPa}%
}%
\endgroup
% 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\pgfutil@command@to@string#1#2{%
\expandafter\pgfutil@command@to@string@@\meaning#1\pgfutil@EOI{#2}%
}%
\xdef\pgfutil@glob@TMPa{\meaning\pgfutil@empty}%
\expandafter\def\expandafter\pgfutil@command@to@string@@\pgfutil@glob@TMPa#1\pgfutil@EOI#2{%
\def#2{#1}%
}%
\begingroup
\catcode`\|=0
\catcode`\\=12
|gdef|pgfutil@backslash@as@other{\}%
|endgroup
% Checks if the token sequence #1 (unexpanded) contains a macro and
% invokes #2 if so and #3 if not.
\def\pgfutilifcontainsmacro#1#2#3{%
\def\pgf@marshal{#1}%
\pgfutil@command@to@string\pgf@marshal\pgf@marshal
\edef\pgf@marshal{\noexpand\pgfutil@in@{\pgfutil@backslash@as@other}{\pgf@marshal}}%
\pgf@marshal
\ifpgfutil@in@
\def\pgf@marshal{#2}%
\else
\def\pgf@marshal{#3}%
\fi
\pgf@marshal
}%
% Tests if string '#2' starts with pattern '#1'.
%
% If so, it executes #3 and defines \pgfretval to contain the
% suffix which is not equal to #1. Otherwise it executes #4.
\def\pgfutilifstartswith#1#2#3#4{%
\def\pgfutilifstartswith@ ##1#1##2\pgf@EOI{%
\def\pgfutil@tmp{##1}%
\ifx\pgfutil@tmp\pgfutil@empty
% Ah - a hit!
%
% define \pgfretval to be the suffix...
\def\pgfutil@tmp#1####1\pgf@EOI{%
\def\pgfretval{####1}%
}%
\pgfutil@tmp#2\pgf@EOI%
%
% ... and execute the <true> code:
#3\relax%
\else
% hm. No such prefix.
#4\relax%
\fi
}%
\pgfutilifstartswith@#2--#1\pgf@EOI%
}%
% Usage:
% \pgfutilstrreplace{<token>}{<replacement>}{<string>}
%
% -> will assign the modified string into \pgfretval.
%
% #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\pgfutilstrreplace#1#2#3{%
\def\pgfretval{}%
\long\def\pgfutil@search@and@replace@@##1#1##2\pgf@EOI{%
\expandafter\def\expandafter\pgfretval\expandafter{\pgfretval ##1#2}%
\pgfutil@search@and@replace@loop{#1}{##2}%
}%
\pgfutil@search@and@replace@loop{#1}{#3}%
}
\long\def\pgfutil@search@and@replace@loop#1#2{%
\pgfutil@in@{#1}{#2}%
\ifpgfutil@in@
\def\pgf@loc@TMPa{\pgfutil@search@and@replace@@ #2\pgf@EOI}%
\else
\expandafter\def\expandafter\pgfretval\expandafter{\pgfretval #2}%
\let\pgf@loc@TMPa=\relax
\fi
\pgf@loc@TMPa
}%
% Solves a linear equation system of size 2x2 using gauss elimination.
%
% It employs TeX register arithmetics to do so.
% #1: should contain 4 sets of braces with matrix entries,
% {<a11>}{<a12>}
% {<a21>}{<a22>}
% where each entry should be a number without unit.
% It is acceptable if '#1' is a macro which expands to the expected
% format.
% #2: should contain 2 sets of braces with the right-hand-side,
% {<r1>}{<r2>}
% where each entry should be a number without unit.
% It is acceptable if '#2' is a macro which expands to the expected
% format.
%
% It will assign \pgfmathresult to contain two sets of braces with the
% result.
%
% Example:
% \pgfutilsolvetwotwoleq{
% {0.24}{1}
% {-0.97}{0}
% }{
% {-7}
% {18}
% }
% -> yields \pgfmathresult={−18.55618}{−2.54642}
%
% The algorithm employs column pivotisation.
%
% If the matrix is singular, the routine will return {}.
\def\pgfutilsolvetwotwoleq#1#2{%
\begingroup
\dimendef\aa=0
\dimendef\ab=1
\dimendef\ba=2
\dimendef\bb=3
\dimendef\ra=4
\dimendef\rb=5
\dimendef\tmpa=6
\dimendef\tmpb=7
\edef\pgf@temp{#1}%
\expandafter\pgfutilsolvetwotwoleq@A\pgf@temp
\edef\pgf@temp{#2}%
\expandafter\pgfutilsolvetwotwoleq@r\pgf@temp
%
\pgfutilsolvetwotwoleq@ifislarger\aa\ba{%
% identity "permutation":
\def\Pa{a}%
\def\Pb{b}%
}{%
% permutation matrix: switch rows!
\def\Pa{b}%
\def\Pb{a}%
}%
% \pivot := 1/aa
\tmpa=\csname m\Pa a\endcsname pt %
\ifdim\tmpa<0pt \tmpa=-\tmpa\fi
\ifdim\tmpa<0.0001pt
% singular matrix!
\let\pgfmathresult=\pgfutil@empty
\else
\pgfmathreciprocal@
{\csname m\Pa a\endcsname}%
\let\pivot=\pgfmathresult
%
% \factor := 1/aa * ba
\csname \Pb a\endcsname=\pivot\csname \Pb a\endcsname
\edef\factor{\expandafter\pgf@sys@tonumber\csname \Pb a\endcsname}%
%
% bb -= ba/aa * ab
\tmpa=-\factor\csname \Pa b\endcsname
\advance\csname \Pb b\endcsname by\tmpa
%
% rb -= ba/aa * ra
\tmpa=-\factor\csname r\Pa\endcsname
\advance\csname r\Pb\endcsname by\tmpa
%
\tmpa=\csname \Pb b\endcsname%
\ifdim\tmpa<0pt \tmpa=-\tmpa\fi
\ifdim\tmpa<0.0001pt
% singular matrix!
\let\pgfmathresult=\pgfutil@empty
\else
% xb := rb / bb (the modified rb and modified bb!)
\pgfmathdivide@
{\expandafter\pgf@sys@tonumber\csname r\Pb\endcsname}
{\expandafter\pgf@sys@tonumber\csname \Pb b\endcsname}%
\expandafter\let\csname pgfmathresult\Pb\endcsname=\pgfmathresult
%
% ra := ra - xb * ab
\tmpa=\csname pgfmathresult\Pb\endcsname\csname \Pa b\endcsname
\advance\csname r\Pa\endcsname by-\tmpa
%
% xa := 1/aa * ra (the modified ra!)
\tmpa=\pivot\csname r\Pa\endcsname
\expandafter\edef\csname pgfmathresult\Pa\endcsname{\pgf@sys@tonumber\tmpa}%
%
\edef\pgfmathresult{%
{\csname pgfmathresult\Pa\endcsname}%
{\csname pgfmathresult\Pb\endcsname}%
}%
\fi
\fi
\pgfmath@smuggleone\pgfmathresult
\endgroup
}%
\def\pgfutilsolvetwotwoleq@ifislarger#1#2#3#4{%
\tmpa=#1
\ifdim\tmpa<0pt
\multiply\tmpa by-1
\fi
\tmpb=#2
\ifdim\tmpb<0pt
\multiply\tmpb by-1
\fi
\ifdim\tmpa>\tmpb
#3%
\else
#4%
\fi
}%
\def\pgfutilsolvetwotwoleqfloat@ifislarger#1#2#3#4{%
\pgfmathfloatabs@{#1}\let\tmpa=\pgfmathresult
\pgfmathfloatabs@{#2}\let\tmpb=\pgfmathresult
\pgfmathfloatlessthan@{\tmpb}{\tmpa}%
\ifpgfmathfloatcomparison
#3%
\else
#4%
\fi
}%
\def\pgfutilsolvetwotwoleq@A#1#2#3#4{%
\def\maa{#1}\def\mab{#2}%
\def\mba{#3}\def\mbb{#3}%
\aa=#1pt \ab=#2pt
\ba=#3pt \bb=#4pt
}
\def\pgfutilsolvetwotwoleq@r#1#2{%
\ra=#1pt \rb=#2pt
}%
\def\pgfutilsolvetwotwoleqfloat@A#1#2#3#4{%
\pgfmathfloatparsenumber{#1}\let\maa=\pgfmathresult
\pgfmathfloatparsenumber{#2}\let\mab=\pgfmathresult
\pgfmathfloatparsenumber{#3}\let\mba=\pgfmathresult
\pgfmathfloatparsenumber{#4}\let\mbb=\pgfmathresult
}
\def\pgfutilsolvetwotwoleqfloat@r#1#2{%
\pgfmathfloatparsenumber{#1}\let\ra=\pgfmathresult
\pgfmathfloatparsenumber{#2}\let\rb=\pgfmathresult
}%
% Same as \pgfutilsolvetwotwoleq, but using floating point
% arithmetics. The return value is still in fixed point.
\def\pgfutilsolvetwotwoleqfloat#1#2{%
\begingroup
\pgfmathfloatcreate{1}{1.0}{-4}% FIXME : use a smaller threshold for FPU?
\let\thresh=\pgfmathresult
%
\edef\pgf@temp{#1}%
\expandafter\pgfutilsolvetwotwoleqfloat@A\pgf@temp
\edef\pgf@temp{#2}%
\expandafter\pgfutilsolvetwotwoleqfloat@r\pgf@temp
%
\pgfutilsolvetwotwoleqfloat@ifislarger\maa\mba{%
% identity "permutation":
\def\Pa{a}%
\def\Pb{b}%
}{%
% permutation matrix: switch rows!
\def\Pa{b}%
\def\Pb{a}%
}%
% \pivot := 1/aa
\expandafter\pgfmathfloatabs@\expandafter{\csname m\Pa a\endcsname}%
\let\tmpa=\pgfmathresult
\pgfmathfloatlessthan@{\tmpa}{\thresh}%
\ifpgfmathfloatcomparison
% singular matrix!
\let\pgfmathresult=\pgfutil@empty
\else
\expandafter\pgfmathfloatreciprocal@\expandafter{\csname m\Pa a\endcsname}%
\let\pivot=\pgfmathresult
%
% \factor := 1/aa * ba
\expandafter\pgfmathfloatmultiply@\expandafter{\csname m\Pb a\endcsname}{\pivot}%
\let\factor=\pgfmathresult
\expandafter\let\csname m\Pb a\endcsname=\factor
%
% bb -= ba/aa * ab
\expandafter\pgfmathfloatmultiply@\expandafter{\csname m\Pa b\endcsname}{\factor}%
\let\tmpa=\pgfmathresult
\expandafter\pgfmathfloatsubtract@\expandafter{\csname m\Pb b\endcsname}{\tmpa}%
\expandafter\let\csname m\Pb b\endcsname=\pgfmathresult
%
% rb -= ba/aa * ra
\expandafter\pgfmathfloatmultiply@\expandafter{\csname r\Pa\endcsname}{\factor}%
\let\tmpa=\pgfmathresult
\expandafter\pgfmathfloatsubtract@\expandafter{\csname r\Pb\endcsname}{\tmpa}%
\expandafter\let\csname r\Pb\endcsname=\pgfmathresult
%
\expandafter\pgfmathfloatabs@\expandafter{\csname m\Pb b\endcsname}%
\let\tmpa=\pgfmathresult
\pgfmathfloatlessthan@{\tmpa}{\thresh}%
\ifpgfmathfloatcomparison
% singular matrix!
\let\pgfmathresult=\pgfutil@empty
\else
% xb := rb / bb (the modified rb and modified bb!)
\edef\pgf@marshal{%
\noexpand\pgfmathfloatdivide@
{\csname r\Pb\endcsname}
{\csname m\Pb b\endcsname}%
}%
\pgf@marshal
\expandafter\let\csname pgfmathresult\Pb\endcsname=\pgfmathresult
\let\tmpa=\pgfmathresult
%
% ra := ra - xb * ab
\expandafter\pgfmathfloatmultiply@\expandafter{\csname m\Pa b\endcsname}{\tmpa}%
\let\tmpa=\pgfmathresult
\expandafter\pgfmathfloatsubtract@\expandafter{\csname r\Pa\endcsname}{\tmpa}%
\expandafter\let\csname r\Pa\endcsname=\pgfmathresult
%
% xa := 1/aa * ra (the modified ra!)
\expandafter\pgfmathfloatmultiply@\expandafter{\csname r\Pa\endcsname}{\pivot}%
\expandafter\let\csname pgfmathresult\Pa\endcsname=\pgfmathresult
%
\edef\pgfmathresult{%
{\csname pgfmathresult\Pa\endcsname}%
{\csname pgfmathresult\Pb\endcsname}%
}%
\expandafter\pgfutilsolvetwotwoleqfloat@to@pgf@range\pgfmathresult
\fi
\fi
\pgfmath@smuggleone\pgfmathresult
\endgroup
}%
\def\pgfutilsolvetwotwoleqfloat@to@pgf@range#1#2{%
\pgfmathfloatcreate{1}{1.6}{4}\let\pgfutilsolvetwotwoleqfloat@to@pgf@range@max=\pgfmathresult
\pgfmathfloatabs@{#1}%
\expandafter\pgfmathfloatlessthan@\expandafter{\pgfmathresult}{\pgfutilsolvetwotwoleqfloat@to@pgf@range@max}%
\ifpgfmathfloatcomparison
\pgfmathfloatabs@{#2}%
\expandafter\pgfmathfloatlessthan@\expandafter{\pgfmathresult}{\pgfutilsolvetwotwoleqfloat@to@pgf@range@max}%
\ifpgfmathfloatcomparison
% ok.
\pgfmathfloattofixed{#1}\let\tmpa=\pgfmathresult
\pgfmathfloattofixed{#2}%
\edef\pgfmathresult{{\tmpa}{\pgfmathresult}}%
\else
% singular (because PGF cannot represent its result
\let\pgfmathresult=\pgfutil@empty
\fi
\else
% singular (because PGF cannot represent its result
\let\pgfmathresult=\pgfutil@empty
\fi
}%
% there are funny programs which overwrite \read and \write (like
% tabularx).
\let\pgfutil@write=\write
\let\pgfutil@read=\read
% curtesy for latex:
\let\pgfutil@protect\relax
% Used by latex for doing reruns
% #1 = an internal label
% #2 = a to-be-tested text
\def\pgfutil@check@rerun#1#2{}
% new tempdims:
\newdimen\pgfutil@tempdima
\newdimen\pgfutil@tempdimb
% luatex stuff
% We assume luatex version > 0.39:
% - \directlua <general text> will work
% - \directlua is the only luatex primitive that we can assume
% accessible without being prefixed by the format via
% tex.enableprimitives.
% Ideas taken from the ifluatex package (Heiko Oberdiek)
\let\pgfutil@ifluatex\iffalse
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname directlua\endcsname\relax
\else
\expandafter\let\csname pgfutil@ifluatex\expandafter\endcsname
\csname iftrue\endcsname
\fi
\pgfutil@ifluatex
\let\pgfutil@directlua\directlua
\pgfutil@directlua{%
tex.enableprimitives('pgfutil@',{'luaescapestring'})}
\else
\def\pgfutil@directlua#1{}
\def\pgfutil@luaescapestring#1{}
\fi
\def\pgfutil@shellescape@lua@eightseven#1{%
\pgfutil@directlua{os.execute("\pgfutil@luaescapestring{#1}")}%
}%
\def\pgfutil@shellescape#1{%
\immediate\write18{#1}%
}%
\pgfutil@IfUndefined{directlua}{%
}{%
\pgfutil@IfUndefined{lastsavedimageresourcepages}{%
% Ah - an old version of luatex. It still supports \write18
}{%
% take the new variant...
\let\pgfutil@shellescape=\pgfutil@shellescape@lua@eightseven
}%
}%
% End of luatex stuff
% Advances a number stored in a macro and writes the result back into
% the macro.
% #1 is a macro containing a number.
\def\pgfutil@advancestringcounter#1{%
\begingroup
\c@pgf@counta=#1\relax
\advance\c@pgf@counta by1
\edef#1{\the\c@pgf@counta}%
\pgfmath@smuggleone#1%
\endgroup
}%
\input pgfutil-common-lists.tex
\endinput