% 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. % % This file provides utitiliy 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 % Simple stuff \long\def\pgfutil@ifundefined#1{% \expandafter\ifx\csname#1\endcsname\relax \expandafter\pgfutil@firstoftwo \else \expandafter\pgfutil@secondoftwo \fi} \def\pgfutil@firstofone#1{#1} \def\pgfutil@firstoftwo#1#2{#1} \def\pgfutil@secondoftwo#1#2{#2} \def\pgfutil@empty{} \def\pgfutil@gobble@until@relax#1\relax{} \def\pgfutil@gobble#1{} \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 % 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@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\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}} % 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 % 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 % 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`\|} \catcode`\@=11 \catcode`\|=12 \input pgflibrary\pgf@temp.code.tex \catcode`\@=\csname pgf@library@#1@atcode\endcsname \catcode`\|=\csname pgf@library@#1@barcode\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`\|} \catcode`\@=11 \catcode`\|=12 \input pgfmodule\pgf@temp.code.tex \catcode`\@=\csname pgf@module@#1@atcode\endcsname \catcode`\|=\csname pgf@module@#1@barcode\endcsname \fi% }% } \def\pgfutilensuremath#1{% \ifmmode#1\else$#1$\fi } % % Guess the driver: % \def\pgfutil@guessdriver{\edef\pgfsysdriver{pgfsys-\Gin@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 % Usage: % \pgfutilstrreplace{}{}{} % % -> 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, % {}{} % {}{} % 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, % {}{} % 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. \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 \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 % % 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 -= 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}% }% \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\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 }% % there are funny programs which overwrite \read and \write (like % tabularx). \let\pgfutil@write=\write \let\pgfutil@read=\read \endinput