%% %% This is file `datatool.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% datatool.dtx (with options: `datatool.sty,package') %% %% datatool.dtx %% Copyright 2009 Nicola Talbot %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either version 1.3 %% of this license of (at your option) any later version. %% The latest version of this license is in %% http://www.latex-project.org/lppl.txt %% and version 1.3 or later is part of all distributions of LaTeX %% version 2005/12/01 or later. %% %% This work has the LPPL maintenance status `maintained'. %% %% The Current Maintainer of this work is Nicola Talbot. %% %% This work consists of the files datatool.dtx and datatool.ins and the derived files datatool.sty, datapie.sty, dataplot.sty, databar.sty, databib.sty, databib.bst. %% %% \CharacterTable %% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z %% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z %% Digits \0\1\2\3\4\5\6\7\8\9 %% Exclamation \! Double quote \" Hash (number) \# %% Dollar \$ Percent \% Ampersand \& %% Acute accent \' Left paren \( Right paren \) %% Asterisk \* Plus \+ Comma \, %% Minus \- Point \. Solidus \/ %% Colon \: Semicolon \; Less than \< %% Equals \= Greater than \> Question mark \? %% Commercial at \@ Left bracket \[ Backslash \\ %% Right bracket \] Circumflex \^ Underscore \_ %% Grave accent \` Left brace \{ Vertical bar \| %% Right brace \} Tilde \~} \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{datatool}[2009/03/27 v2.01 (NLCT)] \RequirePackage{xkeyval} \RequirePackage{ifthen} \RequirePackage{xfor} \RequirePackage{fp} \RequirePackage{substr} \RequirePackage{etex} \newcommand*{\@dtl@separator}{,} \newcommand*{\DTLsetseparator}[1]{% \renewcommand*{\@dtl@separator}{#1}% \@dtl@construct@lopoffs } \begingroup \catcode`\ 12 \gdef\DTLsettabseparator{% \catcode`\ 12 \DTLsetseparator{ }% } \endgroup \begingroup \catcode`\"12\relax \gdef\@dtl@delimiter{"} \endgroup \newcommand*\DTLsetdelimiter[1]{% \renewcommand*{\@dtl@delimiter}{#1}% \@dtl@construct@lopoffs} \edef\@dtl@construct@lopoff#1#2{% \noexpand\long\noexpand\def\noexpand\@dtl@lopoff#1##1##2\noexpand \to##3##4{% \noexpand\ifx#2##1\noexpand\relax \noexpand\@dtl@qlopoff#1##1##2\noexpand\to##3##4\relax \noexpand\else \noexpand\@dtl@lop@ff#1##1##2\noexpand\to##3##4\relax \noexpand\fi }} \edef\@dtl@construct@qlopoff#1#2{% \noexpand\long\noexpand\def\noexpand\@dtl@qlopoff#1#2##1#2#1##2\noexpand \to##3##4{% \noexpand\def##4{##1}\noexpand\def##3{#1##2}% }} \edef\@dtl@construct@lop@ff#1{% \noexpand\long\noexpand\def\noexpand\@dtl@lop@ff#1##1#1##2\noexpand \to##3##4{% \noexpand\def##4{##1}\noexpand\def##3{#1##2}% }} \newcommand{\@dtl@construct@lopoffs}{% \edef\@dtl@chars{{\@dtl@separator}{\@dtl@delimiter}}% \expandafter\@dtl@construct@lopoff\@dtl@chars \expandafter\@dtl@construct@qlopoff\@dtl@chars \expandafter\@dtl@construct@lop@ff\expandafter{\@dtl@separator}% } \newcommand*{\@dtl@decimal}{.} \newcommand*{\@dtl@numbergroupchar}{,} \newcommand*{\DTLsetnumberchars}[2]{% \renewcommand*{\@dtl@numbergroupchar}{#1}% \renewcommand*{\@dtl@decimal}{#2}% \@dtl@construct@getnums \@dtl@construct@stripnumgrpchar{#1}} \edef\@dtl@construct@getintfrac#1{% \noexpand\def\noexpand\@dtl@getintfrac##1#1##2\noexpand\relax{% \noexpand\@dtl@get@intpart{##1}% \noexpand\def\noexpand\@dtl@fracpart{##2}% \noexpand\ifx\noexpand\@empty\noexpand\@dtl@fracpart \noexpand\def\noexpand\@dtl@fracpart{0}% \noexpand\else \noexpand\@dtl@getfracpart##2\noexpand\relax \noexpand\@dtl@choptrailingzeroes{\noexpand\@dtl@fracpart}% \noexpand\fi }% \noexpand\def\noexpand\@dtl@getfracpart##1#1\noexpand\relax{% \noexpand\def\noexpand\@dtl@fracpart{##1}% }% \noexpand\def\noexpand\DTLconverttodecimal##1##2{% \noexpand\dtl@ifsingle{##1}% {\noexpand\expandafter\noexpand\toks@\noexpand\expandafter{##1}% \noexpand\edef\noexpand\@dtl@tmp{\noexpand\the\noexpand\toks@}}% {\noexpand\def\noexpand\@dtl@tmp{##1}}% \noexpand\@dtl@standardize@currency\noexpand\@dtl@tmp \noexpand\ifx\noexpand\@dtl@org@currency\noexpand\@empty \noexpand\else \noexpand\let\noexpand\@dtl@currency\noexpand\@dtl@org@currency \noexpand\fi \noexpand\expandafter \noexpand\@dtl@getintfrac\noexpand\@dtl@tmp#1\noexpand\relax \noexpand\edef##2{\noexpand\@dtl@intpart.\noexpand\@dtl@fracpart}}% } \newcommand*{\@dtl@construct@getnums}{% \expandafter\@dtl@construct@getintfrac\expandafter{\@dtl@decimal}} \newcommand*{\@dtl@get@intpart}[1]{% \@dtl@tmpcount=1\relax \def\@dtl@intpart{#1}% \ifx\@dtl@intpart\@empty \def\@dtl@intpart{0}% \else \def\@dtl@intpart{}% \@dtl@get@int@part#1.\relax% \fi \ifnum\@dtl@tmpcount<0\relax \edef\@dtl@intpart{-\@dtl@intpart}% \fi \@dtl@strip@numgrpchar{\@dtl@intpart}% } \def\@dtl@get@int@part#1#2\relax{% \def\@dtl@argi{#1}% \def\@dtl@argii{#2}% \ifx\protect#1\relax% \let\@dtl@get@nextintpart=\@dtl@get@int@part \else \expandafter\ifx\@dtl@argi\$% \let\@dtl@get@nextintpart=\@dtl@get@int@part \else \ifx-#1% \multiply\@dtl@tmpcount by -1\relax \let\@dtl@get@nextintpart=\@dtl@get@int@part \else \if\@dtl@argi+% \let\@dtl@get@nextintpart=\@dtl@get@int@part \else \def\@dtl@intpart{#1}% \ifx.\@dtl@argii \let\@dtl@get@nextintpart=\@gobble \else \let\@dtl@get@nextintpart=\@dtl@get@next@intpart \fi \fi \fi \fi \fi \@dtl@get@nextintpart#2\relax } \def\@dtl@get@next@intpart#1.\relax{% \edef\@dtl@intpart{\@dtl@intpart#1}% } \newcommand*{\@dtl@choptrailingzeroes}[1]{% \def\@dtl@tmpcpz{}% \expandafter\@dtl@chop@trailingzeroes#1\@nil% \let#1=\@dtl@tmpcpz } \def\@dtl@chop@trailingzeroes#1#2\@nil{% \FPifeq{#2}{0}% \edef\@dtl@tmpcpz{\@dtl@tmpcpz#1}% \let\@dtl@chopzeroesnext=\@dtl@gobbletonil \else \edef\@dtl@tmpcpz{\@dtl@tmpcpz#1}% \let\@dtl@chopzeroesnext=\@dtl@chop@trailingzeroes \fi \@dtl@chopzeroesnext#2\@nil } \def\@dtl@gobbletonil#1\@nil{} \newcommand*{\dtl@truncatedecimal}[1]{% \expandafter\@dtl@truncatedecimal#1.\@nil#1} \def\@dtl@truncatedecimal#1.#2\@nil#3{% \def#3{#1}} \newcommand*{\@dtl@strip@numgrpchar}[1]{% \def\@dtl@stripped{}% \edef\@dtl@do@stripnumgrpchar{% \noexpand\@@dtl@strip@numgrpchar#1\@dtl@numbergroupchar \noexpand\relax}% \@dtl@do@stripnumgrpchar \let#1=\@dtl@stripped } \edef\@dtl@construct@stripnumgrpchar#1{% \noexpand\def\noexpand\@@dtl@strip@numgrpchar##1#1##2\noexpand\relax{% \noexpand\expandafter\noexpand\toks@\noexpand\expandafter {\noexpand\@dtl@stripped}% \noexpand\edef\noexpand\@dtl@stripped{\noexpand\the\noexpand\toks@ ##1}% \noexpand\def\noexpand\@dtl@tmp{##2}% \noexpand\ifx\noexpand\@dtl@tmp\noexpand\@empty \noexpand\let\noexpand\@dtl@next=\noexpand\relax \noexpand\else \noexpand\let\noexpand\@dtl@next=\noexpand\@@dtl@strip@numgrpchar \noexpand\fi \noexpand\@dtl@next##2\noexpand\relax }% } \newcommand*{\DTLdecimaltolocale}[2]{% \edef\@dtl@tmpdtl{#1}% \expandafter\@dtl@decimaltolocale\@dtl@tmpdtl.\relax \FPifeq{\@dtl@fracpart}{0}% \edef#2{\@dtl@intpart}% \else \edef#2{\@dtl@intpart\@dtl@decimal\@dtl@fracpart}% \fi } \def\@dtl@decimaltolocale#1.#2\relax{% \@dtl@decimaltolocaleint{#1}% \def\@dtl@fracpart{#2}% \ifx\@dtl@fracpart\@empty \def\@dtl@fracpart{0}% \else \@dtl@decimaltolocalefrac#2\relax \fi } \def\@dtl@decimaltolocaleint#1{% \@dtl@tmpcount=0\relax \@dtl@countdigits#1.\relax \@dtl@numgrpsepcount=\@dtl@tmpcount\relax \divide\@dtl@numgrpsepcount by 3\relax \multiply\@dtl@numgrpsepcount by 3\relax \advance\@dtl@numgrpsepcount by -\@dtl@tmpcount\relax \ifnum\@dtl@numgrpsepcount<0\relax \advance\@dtl@numgrpsepcount by 3\relax \fi \def\@dtl@intpart{}% \@dtl@decimal@to@localeint#1.\relax } \def\@dtl@countdigits#1#2\relax{% \advance\@dtl@tmpcount by 1\relax \ifx.#2\relax \let\@dtl@countnext=\@gobble \else \let\@dtl@countnext=\@dtl@countdigits \fi \@dtl@countnext#2\relax } \def\@dtl@decimal@to@localeint#1#2\relax{% \advance\@dtl@numgrpsepcount by 1\relax \ifx.#2\relax \edef\@dtl@intpart{\@dtl@intpart#1}% \let\@dtl@localeintnext=\@gobble \else \ifnum\@dtl@numgrpsepcount=3\relax \edef\@dtl@intpart{\@dtl@intpart#1\@dtl@numbergroupchar}% \@dtl@numgrpsepcount=0\relax \else \ifnum\@dtl@numgrpsepcount>3\relax \@dtl@numgrpsepcount=0\relax \fi \edef\@dtl@intpart{\@dtl@intpart#1}% \fi \let\@dtl@localeintnext=\@dtl@decimal@to@localeint \fi \@dtl@localeintnext#2\relax } \def\@dtl@decimaltolocalefrac#1.\relax{% \def\@dtl@fracpart{#1}% \@dtl@choptrailingzeroes{\@dtl@fracpart}% } \newcommand*{\DTLdecimaltocurrency}[2]{% \edef\@dtl@tmpdtl{#1}% \expandafter\@dtl@decimaltolocale\@dtl@tmpdtl.\relax \dtl@truncatedecimal\@dtl@tmpdtl \@dtl@tmpcount=\@dtl@tmpdtl\relax \expandafter\@dtl@toks\expandafter{\@dtl@currency}% \FPifeq{\@dtl@fracpart}{0}% \ifnum\@dtl@tmpcount<0\relax \@dtl@tmpcount = -\@dtl@tmpcount\relax \edef#2{-\the\@dtl@toks\the\@dtl@tmpcount\@dtl@decimal00}% \else \edef#2{\the\@dtl@toks\@dtl@intpart\@dtl@decimal00}% \fi \else \ifnum\@dtl@tmpcount<0\relax \@dtl@tmpcount = -\@dtl@tmpcount\relax \ifnum\@dtl@fracpart<10\relax \edef#2{-\the\@dtl@toks\number\@dtl@tmpcount \@dtl@decimal\@dtl@fracpart0}% \else \edef#2{-\the\@dtl@toks\number\@dtl@tmpcount \@dtl@decimal\@dtl@fracpart}% \fi \else \ifnum\@dtl@fracpart<10\relax \edef#2{\the\@dtl@toks\@dtl@intpart\@dtl@decimal\@dtl@fracpart0}% \else \edef#2{\the\@dtl@toks\@dtl@intpart\@dtl@decimal\@dtl@fracpart}% \fi \fi \fi } \@dtl@construct@lopoffs \@dtl@construct@getnums \expandafter\@dtl@construct@stripnumgrpchar\expandafter {\@dtl@numbergroupchar} \define@key{datatool.sty}{separator}{% \DTLsetseparator{#1}} \define@key{datatool.sty}{delimiter}{% \DTLsetdelimiter{#1}} \define@boolkey{datatool.sty}[dtl]{verbose}[true]{% \ifdtlverbose \FPmessagestrue\else \FPmessagesfalse\fi} \newcommand*{\dtl@message}[1]{% \ifdtlverbose\typeout{#1}\fi} \ProcessOptionsX \DeclareRobustCommand\DTLpar{\@par} \newcount\@dtl@datatype \newcount\@dtl@tmpcount \newlength\dtl@tmplength \newcount\@dtl@numgrpsepcount \newcommand{\@dtl@checknumerical}[1]{% \@dtl@numgrpsepfalse \def\@dtl@tmp{#1}% \ifx\@empty#1\@empty \@dtl@datatype=0\relax \else \dtl@ifsingle{#1}% {\expandafter\toks@\expandafter{#1}% \edef\@dtl@tmp{\the\toks@}}% {\def\@dtl@tmp{#1}}% \@dtl@tmpcount=0\relax \@dtl@datatype=0\relax \@dtl@numgrpsepcount=2\relax \@dtl@standardize@currency\@dtl@tmp \ifx\@dtl@org@currency\@empty \else \let\@dtl@currency\@dtl@org@currency \fi \expandafter\@dtl@checknumericalstart\@dtl@tmp\@nil\@nil \fi \ifnum\@dtl@numgrpsepcount>-1\relax \if@dtl@numgrpsep \ifnum\@dtl@numgrpsepcount=3\relax \else \@dtl@datatype=0\relax \fi \fi \fi } \def\@dtl@checknumericalstart#1#2\@nil\@nil{% \ifx#1\protect \@dtl@checknumericalstart#2\@nil\@nil\relax \else \ifx-#1\relax \def\@dtl@tmp{#2}% \ifx\@empty\@dtl@tmp \@dtl@datatype=0\relax \else \ifnum\@dtl@datatype=0\relax \@dtl@datatype=1\relax \fi \@dtl@checknumericalstart#2\@nil\@nil\relax \fi \else \ifx+#1\relax \def\@dtl@tmp{#2}% \ifx\@empty\@dtl@tmp \@dtl@datatype=0\relax \else \ifnum\@dtl@datatype=0\relax \@dtl@datatype=1\relax \fi \@dtl@checknumericalstart#2\@nil\@nil\relax \fi \else \def\@dtl@tmp{#1}% \ifx#1\$\relax \@dtl@datatype=3\relax \@dtl@checknumericalstart#2\@nil\@nil\relax \else \ifx\@empty\@dtl@tmp \@dtl@datatype=0\relax \else \ifnum\@dtl@datatype=0\relax \@dtl@datatype=1\relax \fi \@dtl@checknumericalloop#1#2\@nil\@nil\relax \fi \fi \fi \fi \fi } \newif\if@dtl@numgrpsep \newcommand*{\@dtl@ifDigitOrDecimalSep}[3]{% \ifx0#1\relax #2% \else \ifx1#1\relax #2% \else \ifx2#1\relax #2% \else \ifx3#1\relax #2% \else \ifx4#1\relax #2% \else \ifx5#1\relax #2% \else \ifx6#1\relax #2% \else \ifx7#1\relax #2% \else \ifx8#1\relax #2% \else \ifx9#1\relax #2% \else \expandafter\ifx\@dtl@decimal#1\relax #2% \else #3% \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi } \def\@dtl@checknumericalloop#1#2\@nil{% \def\@dtl@tmp{#1}% \ifx\@nnil\@dtl@tmp\relax \let\@dtl@chcknumnext=\@dtl@checknumericalnoop% \else \@dtl@ifDigitOrDecimalSep{#1}{% \let\@dtl@chcknumnext=\@dtl@checknumericalloop% \expandafter\ifx\@dtl@decimal#1\relax \if@dtl@numgrpsep \ifnum\@dtl@numgrpsepcount=3\relax \@dtl@numgrpsepcount=-1\relax \else \@dtl@datatype=0\relax \let\@dtl@chcknumnext=\@dtl@checknumericalnoop \fi \else \@dtl@numgrpsepcount=-1\relax \fi \else \ifnum\@dtl@numgrpsepcount=-1\relax \else \advance\@dtl@numgrpsepcount by 1\relax \fi \fi }{% \ifx\@dtl@numbergroupchar\@dtl@tmp\relax \@dtl@numgrpseptrue \ifnum\@dtl@numgrpsepcount<3\relax \@dtl@datatype=0\relax \let\@dtl@chcknumnext=\@dtl@checknumericalnoop \else \@dtl@numgrpsepcount=0\relax \fi \else \@dtl@datatype=0\relax \let\@dtl@chcknumnext=\@dtl@checknumericalnoop \fi }% \ifx\@dtl@decimal\@dtl@tmp\relax \ifnum\@dtl@datatype<3\relax \@dtl@datatype=2\relax \fi \advance\@dtl@tmpcount by 1\relax \ifnum\@dtl@tmpcount>1\relax \@dtl@datatype=0\relax \let\@dtl@chcknumnext=\@dtl@checknumericalnoop% \fi \fi \fi \@dtl@chcknumnext#2\@nil } \def\@dtl@checknumericalnoop#1\@nil#2{} \newcommand{\DTLifnumerical}[3]{% \@dtl@checknumerical{#1}% \ifnum\@dtl@datatype=0\relax#3\else#2\fi } \newcommand{\DTLifreal}[3]{% \@dtl@checknumerical{#1}% \ifnum\@dtl@datatype=2\relax #2\else #3\fi } \newcommand{\DTLifint}[3]{% \@dtl@checknumerical{#1}% \ifnum\@dtl@datatype=1\relax #2\else #3\fi } \newcommand{\DTLifstring}[3]{% \@dtl@checknumerical{#1}% \ifnum\@dtl@datatype=0\relax #2\else #3\fi } \newcommand{\DTLifcurrency}[3]{% \@dtl@checknumerical{#1}% \ifnum\@dtl@datatype=3\relax #2\else #3\fi } \newcommand*{\DTLifcurrencyunit}[4]{% \@dtl@checknumerical{#1}% \ifnum\@dtl@datatype=3\relax \ifthenelse{\equal{\@dtl@org@currency}{#2}}{#3}{#4}% \else #4% \fi } \newcommand{\DTLifcasedatatype}[5]{% \@dtl@checknumerical{#1}% \ifcase\@dtl@datatype #2% string \or #3% integer \or #4% number \or #5% currency \fi } \newcommand*{\dtl@testbothnumerical}[2]{% \dtl@ifsingle{#1}{% \edef\@dtl@tmp{#1}}{% \def\@dtl@tmp{#1}}% \expandafter\@dtl@checknumerical\expandafter{\@dtl@tmp}% \edef\@dtl@firsttype{\number\@dtl@datatype}% \dtl@ifsingle{#2}{% \edef\@dtl@tmp{#2}}{% \def\@dtl@tmp{#2}}% \expandafter\@dtl@checknumerical\expandafter{\@dtl@tmp}% \multiply\@dtl@datatype by \@dtl@firsttype\relax \ifnum\@dtl@datatype>0\relax \@dtl@conditiontrue \else \@dtl@conditionfalse \fi } \newcommand*{\DTLifnumlt}[4]{% \DTLconverttodecimal{#1}{\@dtl@numi}% \DTLconverttodecimal{#2}{\@dtl@numii}% \FPiflt{\@dtl@numi}{\@dtl@numii}% #3% \else #4% \fi } \newcommand*{\dtlcompare}[3]{% \dtl@subnobrsp{#2}{\@dtl@argA}% \dtl@subnobrsp{#3}{\@dtl@argB}% \ifx\@dtl@argA\@empty \ifx\@dtl@argB\@empty #1=0\relax \else #1=-1\relax \fi \else \ifx\@dtl@argB\@empty #1=1\relax \else \DTLsubstituteall{\@dtl@argA}{ }{\space }% \DTLsubstituteall{\@dtl@argB}{ }{\space }% \expandafter\dtl@getfirst\@dtl@argA\end \let\dtl@firstA=\dtl@first \let\dtl@restA=\dtl@rest \expandafter\dtl@getfirst\@dtl@argB\end \let\dtl@firstB=\dtl@first \let\dtl@restB=\dtl@rest \expandafter\dtl@ifsingle\expandafter{\dtl@firstA}{% \expandafter\dtl@ifsingle\expandafter{\dtl@firstB}{% \expandafter\dtl@setcharcode\expandafter{\dtl@firstA}{\dtl@codeA}% \expandafter\dtl@setcharcode\expandafter{\dtl@firstB}{\dtl@codeB}% \ifnum\dtl@codeA=-1\relax \ifnum\dtl@codeB=-1\relax \protected@edef\dtl@donext{% \noexpand\dtlcompare{\noexpand#1}{\dtl@restA}{\dtl@restB}}% \dtl@donext \else \protected@edef\dtl@donext{% \noexpand\dtlcompare {\noexpand#1}{\dtl@restA}{\dtl@firstB\dtl@restB}}% \dtl@donext \fi \else \ifnum\dtl@codeB=-1\relax \protected@edef\dtl@donext{% \noexpand\dtlcompare {\noexpand#1}{\dtl@firstA\dtl@restA}{\dtl@restB}}% \dtl@donext \else \ifnum\dtl@codeA<\dtl@codeB #1=-1\relax \else \ifnum\dtl@codeA>\dtl@codeB #1=1\relax \else \ifx\dtl@restA\@empty \ifx\dtl@restB\@empty #1=0\relax \else #1=-1\relax \fi \else \ifx\restB\@empty #1=1\relax \else \protected@edef\dtl@donext{% \noexpand\dtlcompare {\noexpand#1}{\dtl@restA}{\dtl@restB}}% \dtl@donext \fi \fi \fi \fi \fi \fi }{% \protected@edef\dtl@donext{% \noexpand\dtlcompare {\noexpand#1}{\dtl@firstA\dtl@restA}{\dtl@firstB\dtl@restB}}% \dtl@donext }}{% \protected@edef\dtl@donext{% \noexpand\dtlcompare {\noexpand#1}{\dtl@firstA\dtl@restA}{\dtl@firstB\dtl@restB}}% \dtl@donext }% \fi \fi } \def\dtl@getfirst#1#2\end{% \def\dtl@first{#1}% \ifx\dtl@first\@empty \def\dtl@rest{#2}% \else \dtl@ifsingle{#1}{\def\dtl@rest{#2}}{\dtl@getfirst#1#2\end}% \fi } \newcount\dtl@codeA \newcount\dtl@codeB \newcommand*{\dtl@setcharcode}[2]{% \def\@dtl@tmp{#1}% \ifx\@dtl@tmp\@empty #2=-1\relax \else \ifx#1\space\relax #2=`\ \relax \else \ifx#1~\relax #2=`\ \relax \else \ifcat\noexpand#1\relax% #2=-1\relax \else #2=`#1\relax \fi \fi \fi \fi } \newcommand*{\dtl@setlccharcode}[2]{% \def\@dtl@tmp{#1}% \ifx\@dtl@tmp\@empty #2=-1\relax \else \ifx#1\space\relax #2=`\ \relax \else \ifx#1~\relax #2=`\ \relax \else \ifcat\noexpand#1\relax% #2=-1\relax \else #2=\lccode`#1\relax \fi \fi \fi \fi } \newcommand*{\dtlicompare}[3]{% \dtl@subnobrsp{#2}{\@dtl@argA}% \dtl@subnobrsp{#3}{\@dtl@argB}% \ifx\@dtl@argA\@empty \ifx\@dtl@argB\@empty #1=0\relax \else #1=-1\relax \fi \else \ifx\@dtl@argB\@empty #1=1\relax \else \DTLsubstituteall{\@dtl@argA}{ }{\space }% \DTLsubstituteall{\@dtl@argB}{ }{\space }% \expandafter\dtl@getfirst\@dtl@argA\end \let\dtl@firstA=\dtl@first \let\dtl@restA=\dtl@rest \expandafter\dtl@getfirst\@dtl@argB\end \let\dtl@firstB=\dtl@first \let\dtl@restB=\dtl@rest \expandafter\dtl@ifsingle\expandafter{\dtl@firstA}{% \expandafter\dtl@ifsingle\expandafter{\dtl@firstB}{% \expandafter\dtl@setlccharcode\expandafter{\dtl@firstA}{\dtl@codeA}% \expandafter\dtl@setlccharcode\expandafter{\dtl@firstB}{\dtl@codeB}% \ifnum\dtl@codeA=-1\relax \ifnum\dtl@codeB=-1\relax \protected@edef\dtl@donext{% \noexpand\dtlicompare{\noexpand#1}{\dtl@restA}{\dtl@restB}}% \dtl@donext \else \protected@edef\dtl@donext{% \noexpand\dtlicompare {\noexpand#1}{\dtl@restA}{\dtl@firstB\dtl@restB}}% \dtl@donext \fi \else \ifnum\dtl@codeB=-1\relax \protected@edef\dtl@donext{% \noexpand\dtlicompare {\noexpand#1}{\dtl@firstA\dtl@restA}{\dtl@restB}}% \dtl@donext \else \ifnum\dtl@codeA<\dtl@codeB #1=-1\relax \else \ifnum\dtl@codeA>\dtl@codeB #1=1\relax \else \ifx\dtl@restA\@empty \ifx\dtl@restB\@empty #1=0\relax \else #1=-1\relax \fi \else \ifx\restB\@empty #1=1\relax \else \protected@edef\dtl@donext{% \noexpand\dtlicompare {\noexpand#1}{\dtl@restA}{\dtl@restB}}% \dtl@donext \fi \fi \fi \fi \fi \fi }{% \protected@edef\dtl@donext{% \noexpand\dtlicompare {\noexpand#1}{\dtl@firstA\dtl@restA}{\dtl@firstB\dtl@restB}}% \dtl@donext }}{% \protected@edef\dtl@donext{% \noexpand\dtlicompare {\noexpand#1}{\dtl@firstA\dtl@restA}{\dtl@firstB\dtl@restB}}% \dtl@donext }% \fi \fi } \newcommand*{\DTLifstringlt}{\@ifstar\@sDTLifstringlt\@DTLifstringlt} \newcommand*{\@DTLifstringlt}[4]{% \protected@edef\@dtl@tmpcmp{% \noexpand\dtlcompare{\noexpand\@dtl@tmpcount}{#1}{#2}}% \@dtl@tmpcmp \ifnum\@dtl@tmpcount<0\relax #3% \else #4% \fi } \newcommand*{\@sDTLifstringlt}[4]{% \protected@edef\@dtl@tmpcmp{% \noexpand\dtlicompare{\noexpand\@dtl@tmpcount}{#1}{#2}}% \@dtl@tmpcmp \ifnum\@dtl@tmpcount<0\relax #3% \else #4% \fi } \newcommand*{\DTLiflt}{\@ifstar\@sDTLiflt\@DTLiflt} \newcommand*{\@DTLiflt}[4]{% \dtl@testbothnumerical{#1}{#2}% \if@dtl@condition \DTLifnumlt{#1}{#2}{#3}{#4}% \else \@DTLifstringlt{#1}{#2}{#3}{#4}% \fi } \newcommand*{\@sDTLiflt}[4]{% \dtl@testbothnumerical{#1}{#2}% \if@dtl@condition \DTLifnumlt{#1}{#2}{#3}{#4}% \else \@sDTLifstringlt{#1}{#2}{#3}{#4}% \fi } \newcommand*{\DTLifnumgt}[4]{% \DTLconverttodecimal{#1}{\@dtl@numi}% \DTLconverttodecimal{#2}{\@dtl@numii}% \FPifgt{\@dtl@numi}{\@dtl@numii}% #3% \else #4% \fi } \newcommand*{\DTLifstringgt}{\@ifstar\@sDTLifstringgt\@DTLifstringgt} \newcommand*{\@DTLifstringgt}[4]{% \protected@edef\@dtl@tmpcmp{% \noexpand\dtlcompare{\noexpand\@dtl@tmpcount}{#1}{#2}}% \@dtl@tmpcmp \ifnum\@dtl@tmpcount>0\relax #3% \else #4% \fi } \newcommand*{\@sDTLifstringgt}[4]{% \protected@edef\@dtl@tmpcmp{% \noexpand\dtlicompare{\noexpand\@dtl@tmpcount}{#1}{#2}}% \@dtl@tmpcmp \ifnum\@dtl@tmpcount>0\relax #3% \else #4% \fi } \newcommand*{\DTLifgt}{\@ifstar\@sDTLifgt\@DTLifgt} \newcommand*{\@DTLifgt}[4]{% \dtl@testbothnumerical{#1}{#2}% \if@dtl@condition \DTLifnumgt{#1}{#2}{#3}{#4}% \else \@DTLifstringgt{#1}{#2}{#3}{#4}% \fi } \newcommand*{\@sDTLifgt}[4]{% \dtl@testbothnumerical{#1}{#2}% \if@dtl@condition \DTLifnumgt{#1}{#2}{#3}{#4}% \else \@sDTLifstringgt{#1}{#2}{#3}{#4}% \fi } \newcommand*{\DTLifnumeq}[4]{% \DTLconverttodecimal{#1}{\@dtl@numi}% \DTLconverttodecimal{#2}{\@dtl@numii}% \FPifeq{\@dtl@numi}{\@dtl@numii}% #3% \else #4% \fi } \newcommand*{\DTLifstringeq}{\@ifstar\@sDTLifstringeq\@DTLifstringeq} \newcommand*{\@DTLifstringeq}[4]{% \protected@edef\@dtl@tmpcmp{% \noexpand\dtlcompare{\noexpand\@dtl@tmpcount}{#1}{#2}}% \@dtl@tmpcmp \ifnum\@dtl@tmpcount=0\relax #3% \else #4% \fi } \newcommand*{\@sDTLifstringeq}[4]{% \protected@edef\@dtl@tmpcmp{% \noexpand\dtlicompare{\noexpand\@dtl@tmpcount}{#1}{#2}}% \@dtl@tmpcmp \ifnum\@dtl@tmpcount=0\relax #3% \else #4% \fi } \newcommand*{\DTLifeq}{\@ifstar\@sDTLifeq\@DTLifeq} \newcommand*{\@DTLifeq}[4]{% \dtl@testbothnumerical{#1}{#2}% \if@dtl@condition \DTLifnumeq{#1}{#2}{#3}{#4}% \else \@DTLifstringeq{#1}{#2}{#3}{#4}% \fi } \newcommand*{\@sDTLifeq}[4]{% \dtl@testbothnumerical{#1}{#2}% \if@dtl@condition \DTLifnumeq{#1}{#2}{#3}{#4}% \else \@sDTLifstringeq{#1}{#2}{#3}{#4}% \fi } \newcommand*{\DTLifSubString}[4]{% \protected@edef\@dtl@tmp{\noexpand\dtl@testifsubstring {#1}{#2}}% \@dtl@tmp \if@dtl@condition #3% \else #4% \fi } \newcommand*{\dtl@testifsubstring}[2]{% \dtl@subnobrsp{#1}{\@dtl@argA}% \dtl@subnobrsp{#2}{\@dtl@argB}% \ifx\@dtl@argB\@empty \@dtl@conditiontrue \else \ifx\@dtl@argA\@empty \@dtl@conditionfalse \else \dtl@teststartswith{#1}{#2}% \if@dtl@condition \else \DTLsubstituteall{\@dtl@argA}{ }{\space }% \expandafter\dtl@getfirst\@dtl@argA\end \expandafter\dtl@ifsingle\expandafter{\dtl@first}{% \expandafter\dtl@testifsubstring\expandafter{\dtl@rest}{#2}% }{% \protected@edef\@dtl@donext{\noexpand\dtl@testifsubstring {\dtl@first\dtl@rest}{\@dtl@argB}}% \@dtl@donext }% \fi \fi \fi } \newcommand*{\DTLifStartsWith}[4]{% \@dtl@conditionfalse \protected@edef\@dtl@tmp{\noexpand\dtl@teststartswith{#1}{#2}}% \@dtl@tmp \if@dtl@condition #3% \else #4% \fi } \newcommand*{\dtl@teststartswith}[2]{% \dtl@subnobrsp{#1}{\@dtl@argA}% \dtl@subnobrsp{#2}{\@dtl@argB}% \ifx\@dtl@argA\@empty \ifx\@dtl@argB\@empty \@dtl@conditiontrue \else \@dtl@conditionfalse \fi \else \ifx\@dtl@argB\@empty \@dtl@conditiontrue \else \DTLsubstituteall{\@dtl@argA}{ }{\space }% \DTLsubstituteall{\@dtl@argB}{ }{\space }% \expandafter\dtl@getfirst\@dtl@argA\end \let\dtl@firstA=\dtl@first \let\dtl@restA=\dtl@rest \expandafter\dtl@getfirst\@dtl@argB\end \let\dtl@firstB=\dtl@first \let\dtl@restB=\dtl@rest \expandafter\dtl@ifsingle\expandafter{\dtl@firstA}{% \expandafter\dtl@ifsingle\expandafter{\dtl@firstB}{% \expandafter\dtl@setcharcode\expandafter{\dtl@firstA}{\dtl@codeA}% \expandafter\dtl@setcharcode\expandafter{\dtl@firstB}{\dtl@codeB}% \ifnum\dtl@codeA=-1\relax \ifnum\dtl@codeB=-1\relax \protected@edef\dtl@donext{% \noexpand\dtl@teststartswith{\dtl@restA}{\dtl@restB}}% \dtl@donext \else \protected@edef\dtl@donext{% \noexpand\dtl@teststartswith {\dtl@restA}{\dtl@firstB\dtl@restB}}% \dtl@donext \fi \else \ifnum\dtl@codeB=-1\relax \protected@edef\dtl@donext{% \noexpand\dtl@teststartswith {\dtl@firstA\dtl@restA}{\dtl@restB}}% \dtl@donext \else \ifnum\dtl@codeA=\dtl@codeB \protected@edef\dtl@donext{% \noexpand\dtl@teststartswith{\dtl@restA}{\dtl@restB}}% \dtl@donext \else \@dtl@conditionfalse \fi \fi \fi }{% \protected@edef\dtl@donext{% \noexpand\dtl@teststartswith {\dtl@firstA\dtl@restA}{\dtl@firstB\dtl@restB}}% \dtl@donext }}{% \protected@edef\dtl@donext{% \noexpand\dtl@teststartswith {\dtl@firstA\dtl@restA}{\dtl@firstB\dtl@restB}}% }% \fi \fi } \newcommand*{\DTLifnumclosedbetween}[5]{% \DTLconverttodecimal{#1}{\@dtl@numi}% \DTLconverttodecimal{#2}{\@dtl@numii}% \DTLconverttodecimal{#3}{\@dtl@numiii}% \DTLifFPclosedbetween{\@dtl@numi}{\@dtl@numii}{\@dtl@numiii}{#4}{#5}% } \newcommand*{\DTLifstringclosedbetween}{% \@ifstar\@sDTLifstringclosedbetween\@DTLifstringclosedbetween} \newcommand*{\@DTLifstringclosedbetween}[5]{% \protected@edef\@dtl@tmpcmp{% \noexpand\dtlcompare{\noexpand\@dtl@tmpcount}{#1}{#2}}% \@dtl@tmpcmp \let\@dtl@dovalue\relax \ifnum\@dtl@tmpcount<0\relax \def\@dtl@dovalue{#5}% \fi \ifx\@dtl@dovalue\relax \protected@edef\@dtl@tmpcmp{% \noexpand\dtlcompare{\noexpand\@dtl@tmpcount}{#1}{#3}}% \@dtl@tmpcmp \ifnum\@dtl@tmpcount>0\relax \def\@dtl@dovalue{#5}% \else \def\@dtl@dovalue{#4}% \fi \fi \@dtl@dovalue } \newcommand*{\@sDTLifstringclosedbetween}[5]{% \protected@edef\@dtl@tmpcmp{% \noexpand\dtlicompare{\noexpand\@dtl@tmpcount}{#1}{#2}}% \@dtl@tmpcmp \let\@dtl@dovalue\relax \ifnum\@dtl@tmpcount<0\relax \def\@dtl@dovalue{#5}% \fi \ifx\@dtl@dovalue\relax \protected@edef\@dtl@tmpcmp{% \noexpand\dtlicompare{\noexpand\@dtl@tmpcount}{#1}{#3}}% \@dtl@tmpcmp \ifnum\@dtl@tmpcount>0\relax \def\@dtl@dovalue{#5}% \else \def\@dtl@dovalue{#4}% \fi \fi \@dtl@dovalue } \newcommand*{\DTLifclosedbetween}{% \@ifstar\@sDTLifclosedbetween\@DTLifclosedbetween} \newcommand*{\@DTLifclosedbetween}[5]{% \dtl@testbothnumerical{#2}{#3}% \if@dtl@condition \dtl@ifsingle{#1}{% \edef\@dtl@tmp{#1}}{% \def\@dtl@tmp{#1}}% \expandafter\@dtl@checknumerical\expandafter{\@dtl@tmp}% \ifnum\@dtl@datatype>0\relax \DTLifnumclosedbetween{#1}{#2}{#3}{#4}{#5}% \else \@DTLifstringclosedbetween{#1}{#2}{#3}{#4}{#5}% \fi \else \@DTLifstringclosedbetween{#1}{#2}{#3}{#4}{#5}% \fi } \newcommand*{\@sDTLifclosedbetween}[5]{% \dtl@testbothnumerical{#2}{#3}% \if@dtl@condition \dtl@ifsingle{#1}{% \edef\@dtl@tmp{#1}}{% \def\@dtl@tmp{#1}}% \expandafter\@dtl@checknumerical\expandafter{\@dtl@tmp}% \ifnum\@dtl@datatype>0\relax \DTLifnumclosedbetween{#1}{#2}{#3}{#4}{#5}% \else \@sDTLifstringclosedbetween{#1}{#2}{#3}{#4}{#5}% \fi \else \@sDTLifstringclosedbetween{#1}{#2}{#3}{#4}{#5}% \fi } \newcommand*{\DTLifnumopenbetween}[5]{% \DTLconverttodecimal{#1}{\@dtl@numi}% \DTLconverttodecimal{#2}{\@dtl@numii}% \DTLconverttodecimal{#3}{\@dtl@numiii}% \DTLifFPopenbetween{\@dtl@numi}{\@dtl@numii}{\@dtl@numiii}{#4}{#5}% } \newcommand*{\DTLifstringopenbetween}{% \@ifstar\@sDTLifstringopenbetween\@DTLifstringopenbetween} \newcommand*{\@DTLifstringopenbetween}[5]{% \protected@edef\@dtl@tmpcmp{% \noexpand\dtlcompare{\noexpand\@dtl@tmpcount}{#1}{#2}}% \@dtl@tmpcmp \let\@dtl@dovalue\relax \ifnum\@dtl@tmpcount>0\relax \else \def\@dtl@dovalue{#5}% \fi \ifx\@dtl@dovalue\relax \protected@edef\@dtl@tmpcmp{% \noexpand\dtlcompare{\noexpand\@dtl@tmpcount}{#1}{#3}}% \@dtl@tmpcmp \ifnum\@dtl@tmpcount<0\relax \def\@dtl@dovalue{#4}% \else \def\@dtl@dovalue{#5}% \fi \fi \@dtl@dovalue } \newcommand*{\@sDTLifstringopenbetween}[5]{% \protected@edef\@dtl@tmpcmp{% \noexpand\dtlicompare{\noexpand\@dtl@tmpcount}{#1}{#2}}% \@dtl@tmpcmp \let\@dtl@dovalue\relax \ifnum\@dtl@tmpcount>0\relax \else \def\@dtl@dovalue{#5}% \fi \ifx\@dtl@dovalue\relax \protected@edef\@dtl@tmpcmp{% \noexpand\dtlicompare{\noexpand\@dtl@tmpcount}{#1}{#3}}% \@dtl@tmpcmp \ifnum\@dtl@tmpcount<0\relax \def\@dtl@dovalue{#4}% \else \def\@dtl@dovalue{#5}% \fi \fi \@dtl@dovalue } \newcommand*{\DTLifopenbetween}{% \@ifstar\@sDTLifopenbetween\@DTLifopenbetween} \newcommand*{\@DTLifopenbetween}[5]{% \dtl@testbothnumerical{#2}{#3}% \if@dtl@condition \dtl@ifsingle{#1}{% \edef\@dtl@tmp{#1}}{% \def\@dtl@tmp{#1}}% \expandafter\@dtl@checknumerical\expandafter{\@dtl@tmp}% \ifnum\@dtl@datatype>0\relax \DTLifnumopenbetween{#1}{#2}{#3}{#4}{#5}% \else \@DTLifstringopenbetween{#1}{#2}{#3}{#4}{#5}% \fi \else \@DTLifstringopenbetween{#1}{#2}{#3}{#4}{#5}% \fi } \newcommand*{\@sDTLifopenbetween}[5]{% \dtl@testbothnumerical{#2}{#3}% \if@dtl@condition \dtl@ifsingle{#1}{% \edef\@dtl@tmp{#1}}{% \def\@dtl@tmp{#1}}% \expandafter\@dtl@checknumerical\expandafter{\@dtl@tmp}% \ifnum\@dtl@datatype>0\relax \DTLifnumopenbetween{#1}{#2}{#3}{#4}{#5}% \else \@sDTLifstringopenbetween{#1}{#2}{#3}{#4}{#5}% \fi \else \@sDTLifstringopenbetween{#1}{#2}{#3}{#4}{#5}% \fi } \newcommand*{\DTLifFPopenbetween}[5]{% \let\@dtl@dovalue\relax \FPifgt{#1}{#2}% \else \def\@dtl@dovalue{#5}% \fi \FPiflt{#1}{#3}% \ifx\@dtl@dovalue\relax \def\@dtl@dovalue{#4}% \fi \else \def\@dtl@dovalue{#5}% \fi \@dtl@dovalue } \newcommand*{\DTLifFPclosedbetween}[5]{% \let\@dtl@dovalue\relax \FPifgt{#1}{#3}% \def\@dtl@dovalue{#5}% \fi \FPiflt{#1}{#2}% \ifx\@dtl@dovalue\relax \def\@dtl@dovalue{#5}% \fi \else \def\@dtl@dovalue{#4}% \fi \@dtl@dovalue } \newcommand{\DTLiffirstrow}[2]{% \PackageError{datatool}{\string\DTLiffirstrow\space can only be used inside \string\DTLforeach}{}% } \newcommand{\DTLiflastrow}[2]{% \PackageError{datatool}{\string\DTLiflastrow\space can only be used inside \string\DTLforeach}{}% } \newcommand{\DTLifoddrow}[2]{% \PackageError{datatool}{\string\DTLifoddrow\space can only be used inside \string\DTLforeach}{}% } \newif\if@dtl@condition \newcommand*{\dtl@testlt}[2]{% \DTLiflt{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} \newcommand*{\DTLislt}[2]{% \TE@throw\noexpand\dtl@testlt{#1}{#2}\noexpand\if@dtl@condition} \newcommand*{\dtl@testiclt}[2]{% \@sDTLiflt{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} \newcommand*{\DTLisilt}[2]{% \TE@throw\noexpand\dtl@testiclt{#1}{#2}\noexpand\if@dtl@condition} \newcommand*{\dtl@testgt}[2]{% \DTLifgt{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} \newcommand*{\DTLisgt}[2]{% \TE@throw\noexpand\dtl@testgt{#1}{#2}\noexpand\if@dtl@condition} \newcommand*{\dtl@testicgt}[2]{% \@sDTLifgt{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} \newcommand*{\DTLisigt}[2]{% \TE@throw\noexpand\dtl@testicgt{#1}{#2}\noexpand\if@dtl@condition} \newcommand*{\dtl@testeq}[2]{% \DTLifeq{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} \newcommand*{\DTLiseq}[2]{% \TE@throw\noexpand\dtl@testeq{#1}{#2}\noexpand\if@dtl@condition} \newcommand*{\dtl@testiceq}[2]{% \@sDTLifeq{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} \newcommand*{\DTLisieq}[2]{% \TE@throw\noexpand\dtl@testiceq{#1}{#2}\noexpand\if@dtl@condition} \newcommand*{\DTLisSubString}[2]{% \TE@throw\noexpand\dtl@testifsubstring{#1}{#2}% \noexpand\if@dtl@condition} \newcommand*{\DTLisPrefix}[2]{% \TE@throw\noexpand\dtl@teststartswith{#1}{#2}% \noexpand\if@dtl@condition} \newcommand*{\dtl@testclosedbetween}[3]{% \DTLifclosedbetween{#1}{#2}{#3}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} \newcommand*{\DTLisclosedbetween}[3]{% \TE@throw\noexpand\dtl@testclosedbetween{#1}{#2}{#3}% \noexpand\if@dtl@condition} \newcommand*{\dtl@testiclosedbetween}[3]{% \@sDTLifclosedbetween{#1}{#2}{#3}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} \newcommand*{\DTLisiclosedbetween}[3]{% \TE@throw\noexpand\dtl@testiclosedbetween{#1}{#2}{#3}% \noexpand\if@dtl@condition} \newcommand*{\dtl@testopenbetween}[3]{% \DTLifopenbetween{#1}{#2}{#3}{\@dtl@conditiontrue }{\@dtl@conditionfalse}} \newcommand*{\DTLisopenbetween}[3]{% \TE@throw\noexpand\dtl@testopenbetween{#1}{#2}{#3}% \noexpand\if@dtl@condition} \newcommand*{\dtl@testiopenbetween}[3]{% \@sDTLifopenbetween{#1}{#2}{#3}{\@dtl@conditiontrue }{\@dtl@conditionfalse}} \newcommand*{\DTLisiopenbetween}[3]{% \TE@throw\noexpand\dtl@testiopenbetween{#1}{#2}{#3}% \noexpand\if@dtl@condition} \newcommand*{\dtl@testFPclosedbetween}[3]{% \DTLifFPclosedbetween{#1}{#2}{#3}% {\@dtl@conditiontrue}{\@dtl@conditionfalse}} \newcommand*{\DTLisFPclosedbetween}[3]{% \TE@throw\noexpand\dtl@testFPclosedbetween{#1}{#2}{#3}% \noexpand\if@dtl@condition} \newcommand*{\dtl@testFPopenbetween}[3]{% \DTLifFPopenbetween{#1}{#2}{#3}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} \newcommand*{\DTLisFPopenbetween}[3]{% \TE@throw\noexpand\dtl@testFPopenbetween{#1}{#2}{#3}% \noexpand\if@dtl@condition} \newcommand*{\dtl@testFPislt}[2]{% \FPiflt{#1}{#2}\@dtl@conditiontrue\else\@dtl@conditionfalse\fi} \newcommand*{\DTLisFPlt}[2]{% \TE@throw\noexpand\dtl@testFPislt{#1}{#2}% \noexpand\if@dtl@condition} \newcommand*{\dtl@testFPisgt}[2]{% \FPifgt{#1}{#2}\@dtl@conditiontrue\else\@dtl@conditionfalse\fi} \newcommand*{\DTLisFPgt}[2]{% \TE@throw\noexpand\dtl@testFPisgt{#1}{#2}% \noexpand\if@dtl@condition} \newcommand*{\dtl@testFPiseq}[2]{% \FPifeq{#1}{#2}\@dtl@conditiontrue\else\@dtl@conditionfalse\fi} \newcommand*{\DTLisFPeq}[2]{% \TE@throw\noexpand\dtl@testFPiseq{#1}{#2}% \noexpand\if@dtl@condition} \newcommand*{\dtl@testFPislteq}[2]{% \FPiflt{#1}{#2}\@dtl@conditiontrue\else\@dtl@conditionfalse\fi \if@dtl@condition \else \dtl@testFPiseq{#1}{#2}% \fi } \newcommand*{\DTLisFPlteq}[2]{% \TE@throw\noexpand\dtl@testFPislteq{#1}{#2}% \noexpand\if@dtl@condition} \newcommand*{\dtl@testFPisgteq}[2]{% \FPifgt{#1}{#2}\@dtl@conditiontrue\else\@dtl@conditionfalse\fi \if@dtl@condition \else \dtl@testFPiseq{#1}{#2}% \fi } \newcommand*{\DTLisFPgteq}[2]{% \TE@throw\noexpand\dtl@testFPisgteq{#1}{#2}% \noexpand\if@dtl@condition} \newcommand*{\dtl@teststring}[1]{% \DTLifstring{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} \newcommand*{\DTLisstring}[1]{% \TE@throw\noexpand\dtl@teststring{#1}\noexpand\if@dtl@condition} \newcommand*{\dtl@testnumerical}[1]{% \DTLifnumerical{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}% } \newcommand*{\DTLisnumerical}[1]{% \TE@throw\noexpand\dtl@testnumerical{#1}\noexpand\if@dtl@condition} \newcommand*{\dtl@testint}[1]{% \DTLifint{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} \newcommand*{\DTLisint}[1]{% \TE@throw\noexpand\dtl@testint{#1}\noexpand\if@dtl@condition} \newcommand*{\dtl@testreal}[1]{% \DTLifreal{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} \newcommand*{\DTLisreal}[1]{% \TE@throw\noexpand\dtl@testreal{#1}\noexpand\if@dtl@condition} \newcommand*{\dtl@testcurrency}[1]{% \DTLifcurrency{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} \newcommand*{\DTLiscurrency}[1]{% \TE@throw\noexpand\dtl@testcurrency{#1}\noexpand\if@dtl@condition} \newcommand*{\dtl@testcurrencyunit}[2]{% \DTLifcurrencyunit{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} \newcommand*{\DTLiscurrencyunit}[2]{% \TE@throw\noexpand\dtl@testcurrencyunit{#1}{#2}% \noexpand\if@dtl@condition} \newcommand*{\DTLnewdb}[1]{% \DTLifdbexists{#1}% {% \PackageError{datatool}{Database `#1' already exists}{}% }% {% \dtl@message{Creating database `#1'}% \expandafter\newtoks\csname dtldb@#1\endcsname \expandafter\newtoks\csname dtlkeys@#1\endcsname{}% \expandafter\newcount\csname dtlrows@#1\endcsname \expandafter\newcount\csname dtlcols@#1\endcsname }% } \newcommand*{\DTLrowcount}[1]{% \expandafter\number\csname dtlrows@#1\endcsname} \newcommand*{\DTLcolumncount}[1]{% \expandafter\number\csname dtlcols@#1\endcsname} \newcommand{\DTLifdbempty}[3]{% \DTLifdbexists{#1}% {\@DTLifdbempty{#1}{#2}{#3}}% {\PackageError{Can't check if database `#1' is empty: database doesn't exist}{}{}}% } \newcommand{\@DTLifdbempty}[3]{% \expandafter\ifnum\csname dtlrows@#1\endcsname=0\relax #2% \else #3% \fi } \newcommand*{\DTLnewrow}{% \@ifstar\@sDTLnewrow\@DTLnewrow } \newcommand*{\@DTLnewrow}[1]{% \DTLifdbexists{#1}% {\@sDTLnewrow{#1}}% {\PackageErrors{datatool}{Can't add new row to database `#1': database doesn't exist}{}}% } \newcommand*{\@sDTLnewrow}[1]{% \global\advance\csname dtlrows@#1\endcsname by 1\relax \toks@gput@right@cx{dtldb@#1}{% \noexpand\db@row@elt@w% \noexpand\db@row@id@w \number\csname dtlrows@#1\endcsname \noexpand\db@row@id@end@% \noexpand\db@row@id@w \number\csname dtlrows@#1\endcsname \noexpand\db@row@id@end@% \noexpand\db@row@elt@end@% }% \dtl@message{New row added to database `#1'}% } \newcount\dtlcolumnnum \newcount\dtlrownum \newcommand*{\DTLifhaskey}{\@ifstar\@sDTLifhaskey\@DTLifhaskey} \newcommand{\@DTLifhaskey}[4]{% \DTLifdbexists{#1}% {% \@sDTLifhaskey{#1}{#2}{#3}{#4}% }% {% \PackageError{datatool}{Database `#1' doesn't exist}{}% }% } \newcommand{\@sDTLifhaskey}[4]{% \@ifundefined{dtl@ci@#1@#2}% {% #4% }% {% #3% }% } \newcommand*{\DTLgetcolumnindex}{% \@ifstar\@sdtl@getcolumnindex\@dtl@getcolumnindex } \newcommand*{\@dtl@getcolumnindex}[3]{% \DTLifdbexists{#2}% {% \@sDTLifhaskey{#2}{#3}% {% \@sdtl@getcolumnindex{#1}{#2}{#3}% }% {% \PackageError{datatool}{Database `#2' doesn't contain key `#3'}{}% }% }% {% \PackageError{datatool}{Database `#2' doesn't exist}{}% }% } \newcommand*{\@sdtl@getcolumnindex}[3]{% \expandafter\let\expandafter#1\csname dtl@ci@#2@#3\endcsname } \newcommand*{\dtl@columnindex}[2]{% \csname dtl@ci@#1@#2\endcsname } \newcommand*{\DTLgetkeyforcolumn}{% \@ifstar\@sdtlgetkeyforcolumn\@dtlgetkeyforcolumn} \newcommand*{\@dtlgetkeyforcolumn}[3]{% \DTLifdbexists{#2}% {% \ifnum#3<1\relax \PackageError{datatool}{Invalid column index \number#3}{% Column indices start at 1}% \else \expandafter\ifnum\csname dtlcols@#2\endcsname<#3\relax \PackageError{datatool}{Index \number#3\space out of range for database `#2'}{Database `#2' only has \expandafter\number\csname dtlcols@#2\endcsname\space columns}% \else \@sdtlgetkeyforcolumn{#1}{#2}{#3}% \fi \fi }% {% \PackageError{datatool}{Database `#2' doesn't exists}{}% }% } \newcommand*{\@sdtlgetkeyforcolumn}[3]{% \edef\@dtl@dogetkeyforcolumn{\noexpand\@dtl@getkeyforcolumn {\noexpand#1}{#2}{\number#3}}% \@dtl@dogetkeyforcolumn } \newcommand*{\@dtl@getkeyforcolumn}[3]{% \def\@dtl@get@keyforcolumn##1% before stuff \db@plist@elt@w% start of block \db@col@id@w #3\db@col@id@end@% index \db@key@id@w ##2\db@key@id@end@% key \db@type@id@w ##3\db@type@id@end@% data type \db@header@id@w ##4\db@header@id@end@% header \db@col@id@w #3\db@col@id@end@% index \db@plist@elt@end@% end of block ##5\q@nil{\def#1{##2}}% \edef\@dtl@tmp{\expandafter\the\csname dtldb@#2\endcsname}% \expandafter\@dtl@getkeyforcolumn\@dtl@tmp \db@plist@elt@w% start of block \db@col@id@w #3\db@col@id@end@ index \db@key@id@w \@nil\db@key@id@end@% key \db@type@id@w \db@type@id@end@% data type \db@header@id@w \db@header@id@end@% header \db@col@id@w #3\db@col@id@end@% index \db@plist@elt@end@% end of block \q@nil } \def\DTLunsettype{} \def\DTLstringtype{0} \def\DTLinttype{1} \def\DTLrealtype{2} \def\DTLcurrencytype{3} \newcommand*{\DTLgetdatatype}{% \@ifstar\@sdtlgetdatatype\@dtlgetdatatype } \newcommand*{\@dtlgetdatatype}[3]{% \DTLifdbexists{#2}% {% \@sDTLifhaskey{#2}{#3}% {% \@sdtlgetdatatype{#1}{#2}{#3}% }% {% \PackageError{datatool}{Key `#3' undefined in database `#2'}{}% }% }% {% \PackageError{datatool}{Database `#2' doesn't exist}{}% }% } \newcommand*{\@sdtlgetdatatype}[3]{% \edef\@dtl@dogetdata{\noexpand\@dtl@getdatatype{\noexpand#1}% {\expandafter\the\csname dtlkeys@#2\endcsname}% {\dtl@columnindex{#2}{#3}}}% \@dtl@dogetdata } \newcommand*{\@dtl@getdatatype}[3]{% \def\@dtl@get@keydata##1% stuff before \db@plist@elt@w% start of key block \db@col@id@w #3\db@col@id@end@% column index \db@key@id@w ##2\db@key@id@end@% key id \db@type@id@w ##3\db@type@id@end@% data type \db@header@id@w ##4\db@header@id@end@% header \db@col@id@w #3\db@col@id@end@% column index \db@plist@elt@end@% end of key block ##5% stuff afterwards \q@nil{\def#1{##3}}% \@dtl@get@keydata#2\q@nil } \newcommand*{\@dtl@getprops}[7]{% \def\@dtl@get@keydata##1% stuff before \db@plist@elt@w% start of key block \db@col@id@w #7\db@col@id@end@% column index \db@key@id@w ##2\db@key@id@end@% key id \db@type@id@w ##3\db@type@id@end@% data type \db@header@id@w ##4\db@header@id@end@% header \db@col@id@w #7\db@col@id@end@% column index \db@plist@elt@end@% end of key block ##5% stuff afterwards \q@nil{% \def#1{##2}% key \def#2{##3}% data type #3={##4}% header #4={##1}% before stuff #5={##5}% after stuff }% \@dtl@get@keydata#6\q@nil } \newtoks\@dtl@before \newtoks\@dtl@after \newtoks\@dtl@colhead \newcommand*{\@dtl@updatekeys}[3]{% \@sDTLifhaskey{#1}{#2}% {% \expandafter\dtlcolumnnum\expandafter =\dtl@columnindex{#1}{#2}\relax \edef\@dtl@dogetprops{\noexpand\@dtl@getprops {\noexpand\@dtl@key}{\noexpand\@dtl@type}% {\noexpand\@dtl@colhead}{\noexpand\@dtl@before}% {\noexpand\@dtl@after}{\the\csname dtlkeys@#1\endcsname}% {\number\dtlcolumnnum}} \@dtl@dogetprops \def\@dtl@tmp{#3}% \ifx\@dtl@tmp\@empty \else \let\@dtl@oldtype\@dtl@type \@dtl@checknumerical{#3}% \ifx\@dtl@type\@empty \edef\@dtl@type{\number\@dtl@datatype}% \else \ifcase\@dtl@datatype % string \def\@dtl@type{0}% \or % int \or % real \ifnum\@dtl@type=1\relax \def\@dtl@type{2}% \fi \or % currency \ifnum\@dtl@type>0\relax \def\@dtl@type{3}% \fi \fi \fi \ifx\@dtl@oldtype\@dtl@type \else \toks@gconcat@middle@cx{dtlkeys@#1}% {\@dtl@before}% {% \noexpand\db@plist@elt@w% start of key block \noexpand\db@col@id@w \the\dtlcolumnnum \noexpand\db@col@id@end@% column index \noexpand\db@key@id@w #2\noexpand\db@key@id@end@% key id \noexpand\db@type@id@w \@dtl@type \noexpand\db@type@id@end@% data type \noexpand\db@header@id@w \the\@dtl@colhead \noexpand\db@header@id@end@% header \noexpand\db@col@id@w \the\dtlcolumnnum \noexpand\db@col@id@end@% column index \noexpand\db@plist@elt@end@% end of key block }% {\@dtl@after}% \fi \fi }% {% \expandafter\global\expandafter\advance \csname dtlcols@#1\endcsname by 1\relax \dtlcolumnnum=\csname dtlcols@#1\endcsname\relax \expandafter\xdef\csname dtl@ci@#1@#2\endcsname{% \number\dtlcolumnnum}% \def\@dtl@tmp{#3}% \ifx\@dtl@tmp\@empty \edef\@dtl@type{}% don't know data type yet \else \@dtl@checknumerical{#3}% \edef\@dtl@type{\number\@dtl@datatype}% \fi \toks@gput@right@cx{dtlkeys@#1}% {% \noexpand\db@plist@elt@w \noexpand\db@col@id@w \the\dtlcolumnnum \noexpand\db@col@id@end@ \noexpand\db@key@id@w #2\noexpand\db@key@id@end@ \noexpand\db@type@id@w \@dtl@type \noexpand\db@type@id@end@ \noexpand\db@header@id@w #2\noexpand\db@header@id@end@ \noexpand\db@col@id@w \the\dtlcolumnnum \noexpand\db@col@id@end@ \noexpand\db@plist@elt@end@ }% }% } \newcommand*{\DTLsetheader}{\@ifstar\@sDTLsetheader\@DTLsetheader} \newcommand*{\@DTLsetheader}[3]{% \DTLifdbexists{#1}% {% \@sDTLifhaskey{#1}{#2}% {% \@sDTLsetheader{#1}{#2}{#3}% }% {% \PackageError{datatool}{Database `#1' doesn't contain key `#2'}{}% }% }% {% \PackageError{datatool}{Database `#1' doesn't exist}{}% }% } \newcommand*{\@sDTLsetheader}[3]{% \expandafter\dtlcolumnnum\expandafter =\dtl@columnindex{#1}{#2}\relax \@dtl@setheaderforindex{#1}{\dtlcolumnnum}{#3}% } \newcommand*{\@dtl@setheaderforindex}[3]{% \edef\@dtl@dogetprops{\noexpand\@dtl@getprops {\noexpand\@dtl@key}{\noexpand\@dtl@type}% {\noexpand\@dtl@colhead}{\noexpand\@dtl@before}% {\noexpand\@dtl@after}{\the\csname dtlkeys@#1\endcsname}% {\number#2}} \@dtl@dogetprops \@dtl@colhead={#3}% \edef\@dtl@colnum{\number#2}\relax \toks@gconcat@middle@cx{dtlkeys@#1}% {\@dtl@before}% {% \noexpand\db@plist@elt@w% start of block \noexpand\db@col@id@w \@dtl@colnum \noexpand\db@col@id@end@% index \noexpand\db@key@id@w \@dtl@key\noexpand\db@key@id@end@% key \noexpand\db@type@id@w \@dtl@type \noexpand\db@type@id@end@% data type \noexpand\db@header@id@w \the\@dtl@colhead \noexpand\db@header@id@end@% header \noexpand\db@col@id@w \@dtl@colnum \noexpand\db@col@id@end@% index \noexpand\db@plist@elt@end@% end of block }% {\@dtl@after}% } \newcommand{\DTLnewdbentry}{% \@ifstar\@sDTLnewdbentry\@DTLnewdbentry } \newcommand{\@DTLnewdbentry}[3]{% \DTLifdbexists{#1}% {\@sDTLnewdbentry{#1}{#2}{#3}}% {\PackageError{datatool}{Can't add new entry to database `#1': database doesn't exist}{}}% } \newcommand*{\@sDTLnewdbentry}[3]{% \@dtl@updatekeys{#1}{#2}{#3}% \expandafter\dtlcolumnnum\expandafter =\dtl@columnindex{#1}{#2}\relax \edef\dtl@dogetrow{\noexpand\dtlgetrow{#1}% {\number\csname dtlrows@#1\endcsname}}% \dtl@dogetrow \edef\dtl@dogetentry{\noexpand\dtlgetentryfromcurrentrow {\noexpand\dtl@entry}{\number\dtlcolumnnum}% }% \dtl@dogetentry \ifx\dtl@entry\dtlnovalue \@dtl@toks{#3}% \toks@gconcat@middle@cx{dtldb@#1}% {\dtlbeforerow}% {% \noexpand\db@row@elt@w% \noexpand\db@row@id@w \number\csname dtlrows@#1\endcsname \noexpand\db@row@id@end@% \the\dtlcurrentrow \noexpand\db@col@id@w \number\dtlcolumnnum \noexpand\db@col@id@end@% \noexpand\db@col@elt@w \the\@dtl@toks \noexpand\db@col@elt@end@% \noexpand\db@col@id@w \number\dtlcolumnnum \noexpand\db@col@id@end@% \noexpand\db@row@id@w \number\csname dtlrows@#1\endcsname \noexpand\db@row@id@end@% \noexpand\db@row@elt@end@% }% {\dtlafterrow}% \dtl@message{Added #2\space -> #3\space to database `#1'}% \else \PackageError{datatool}{Can't add entry with ID `#2' to current row of database `#1'}{There is already an entry with this ID in the current row}% \fi } \newcommand{\DTLifdbexists}[3]{% \@ifundefined{dtldb@#1}{#3}{#2}} \newcommand*{\@dtl@assign}[2]{% \@dtl@assigncmd#1,\@nil\@@{#2}% } \def\@dtl@assigncmd#1=#2,#3\@@#4{% \@sDTLifhaskey{#4}{#2}% {% \edef\@dtl@dogetentry{% \noexpand\dtlgetentryfromcurrentrow {\noexpand#1}{\dtl@columnindex{#4}{#2}}}% \@dtl@dogetentry \ifx#1\dtlnovalue \@@dtl@setnull{#1}{#2}% \fi \global\let#1=#1\relax }% {% \PackageError{datatool}{Can't assign \string#1\space: there is no key `#2' in data base `#4'}{}% \global\let#1\DTLstringnull }% \def\dtl@tmp{#3}% \ifx\@nnil\dtl@tmp \let\@dtl@next\@dtl@assigncmdnoop \else \let\@dtl@next\@dtl@assigncmd \fi \@dtl@next#3\@@{#4}% } \def\@dtl@assigncmdnoop#1\@@#2{} \newcommand*{\@dtl@setnull}[2]{% \@sDTLifhaskey{\@dtl@dbname}{#2}% {% \@@dtl@setnull{#1}{#2}% }% {% \global\let#1=\DTLstringnull }% } \newcommand*{\@@dtl@setnull}[2]{% \@sdtlgetdatatype{\@dtl@type}{\@dtl@dbname}{#2}% \ifnum0\@dtl@type=0\relax \global\let#1=\DTLstringnull \else \global\let#1=\DTLnumbernull \fi } \newcommand*{\DTLstringnull}{NULL} \newcommand*{\DTLnumbernull}{0} \newcommand*{\DTLifnull}[3]{% \ifx\DTLstringnull#1\relax #2% \else \ifx\DTLnumbernull#1\relax #2% \else #3% \fi \fi } \def\@dtlnovalue{Undefined Value} \def\dtlnovalue{\@dtlnovalue} \newcommand*{\DTLgetkeydata}{% \@ifstar\@sdtlgetkeydata\@dtlgetkeydata } \newcommand*{\@dtlgetkeydata}[5]{% \DTLifdbexists{#2}% {% \@sDTLifhaskey{#2}{#1}% {% \@sdtlgetkeydata{#1}{#2}{#3}{#4}{#5}% }% {% \PackageError{datatool}{Key `#1' not defined in database `#2'}{}% }% }% {% \PackageError{datatool}{Database `#2' doesn't exist}{}% }% } \newcommand*{\@sdtlgetkeydata}[5]{% \@sdtl@getcolumnindex{#3}{#2}{#1}% \edef\@dtl@dogetkeydata{\noexpand\@dtl@getprops {\noexpand\@dtl@key}{\noexpand#4}{\noexpand\@dtl@colhead}% {\noexpand\@dtl@before}{\noexpand\@dtl@after}% {\expandafter\the\csname dtlkeys@#2\endcsname}% {#3}}% \@dtl@dogetkeydata \edef#5{\the\@dtl@toks}% } \newcommand{\dtl@gathervalues}[3][key]{% \dtlforeachkey(\@dtl@key,\@dtl@col,\@dtl@type,\@dtl@head)\in{#2}\do {% \dtlgetentryfromrow{\@dtl@tmp}{\@dtl@col}{\dtlcurrentrow}% \ifx\@dtl@tmp\dtlnovalue \@dtl@setnull{\@dtl@tmp}{\@dtl@key}% \fi \expandafter\let\csname @dtl@#1@\@dtl@key\endcsname\@dtl@tmp }% } \newtoks\dtlcurrentrow \newtoks\dtlbeforerow \newtoks\dtlafterrow \newcommand*{\dtlgetrow}[2]{% \expandafter\toks@\expandafter=\csname dtldb@#1\endcsname \edef\@dtl@dogetrow{\noexpand\@dtlgetrow{\the\toks@}{\number#2}}% \@dtl@dogetrow } \newcommand*{\@dtlgetrow}[2]{% \def\@dtl@getrow##1% before stuff \db@row@elt@w% start of the row \db@row@id@w #2\db@row@id@end@% row id ##2% \db@row@id@w #2\db@row@id@end@% row id \db@row@elt@end@% end of the row ##3% after stuff \q@nil{\dtlbeforerow={##1}\dtlcurrentrow={##2}\dtlafterrow={##3}}% \@dtl@getrow#1\q@nil } \newcommand*{\dtlgetentryfromcurrentrow}[2]{% \dtlgetentryfromrow{#1}{#2}{\dtlcurrentrow}% } \newcommand*{\dtlgetentryfromrow}[3]{% \edef\@dtl@do@getentry{\noexpand\dtl@getentryfromrow {\noexpand#1}{\number#2}{\the#3}}% \@dtl@do@getentry } \newcommand*{\dtl@getentryfromrow}[3]{% \def\dtl@dogetentry##1% before stuff \db@col@id@w #2\db@col@id@end@% Column id \db@col@elt@w ##2\db@col@elt@end@% Value \db@col@id@w #2\db@col@id@end@% Column id ##3% Remaining stuff \q@nil{\def#1{##2}}% \dtl@dogetentry#3% \db@col@id@w #2\db@col@id@end@% \db@col@elt@w \@dtlnovalue\db@col@elt@end@% \db@col@id@w #2\db@col@id@end@% \q@nil } \newcommand*{\DTLgetvalue}[4]{% \edef\dtl@dogetvalue{\noexpand\dtl@getvalue{\noexpand#1}{#2}% {\number#3}{\number#4}}% \dtl@dogetvalue } \newcommand*{\dtl@getvalue}[4]{% \def\@dtl@getvalue ##1% stuff before row \db@row@id@w #3\db@row@id@end@% row id ##2% stuff in row before column \db@col@id@w #4\db@col@id@end@% column id \db@col@elt@w ##3\db@col@elt@end@% value ##4% stuff after value \q@nil{\def#1{##3}}% \toks@=\csname dtldb@#2\endcsname \expandafter\@dtl@getvalue\the\toks@% contents of data base \db@row@id@w #3\db@row@id@end@% \db@col@id@w #4\db@col@id@end@% \db@col@elt@w \@dtlnovalue\db@col@elt@end@% undefined value \q@nil \ifx#1\dtlnovalue \PackageError{datatool}{There is no element at (row=#3, column=#4) in database `#2'}{}% \fi } \newcommand*{\DTLgetlocation}[4]{% \def\@dtl@getlocation##1% stuff before value \db@col@elt@w #4\db@col@elt@end@% value \db@col@id@w ##2\db@col@id@end@% column id ##3% stuff after this column \db@row@id@w ##4\db@row@id@end@% row id ##5% stuff after row \q@nil{\def#1{##4}\def#2{##2}}% \toks@=\csname dtldb@#3\endcsname \expandafter\@dtl@getlocation\the\toks@% contents of data base \db@col@elt@w #4\db@col@elt@end@% value \db@col@id@w \@dtlnovalue\db@col@id@end@% undefined column id \db@row@id@w \@dtlnovalue\db@row@id@end@% undefined row id \q@nil \ifx#1\dtlnovalue \PackageError{datatool}{There is no element `#4' in database `#3'}{}% \fi } \newcommand*{\dtlbreak}{% \PackageError{datatool}{Can't break out of anything}{}% } \long\def\dtlforint#1=#2\to#3\step#4\do#5{% \let\@dtl@orgbreak\dtlbreak \def\@dtl@endloophook{}% \def\dtlbreak{\def\@dtl@endloophook{#1=#3}}% #1=#2\relax \ifnum#4<0\relax \whiledo{\(#1>#3\)\TE@or\(#1=#3\)}% {% #5% \@dtl@endloophook \advance#1 by #4\relax }% \else \whiledo{\(#1<#3\)\TE@or\(#1=#3\)}% {% #5% \@dtl@endloophook \advance#1 by #4\relax }% \fi \let\dtlbreak\@dtl@orgbreak } \newcount\@dtl@foreach@level \long\def\dtlgforint#1=#2\to#3\step#4\do#5{% \global#1=#2\relax \global\advance\@dtl@foreach@level by 1\relax \expandafter\global\expandafter \let\csname @dtl@endhook@\the\@dtl@foreach@level\endcsname \relax \expandafter\global\expandafter \let\csname @dtl@break@\the\@dtl@foreach@level\endcsname \dtlbreak \gdef\dtlbreak{\expandafter \gdef\csname @dtl@endhook@\the\@dtl@foreach@level\endcsname{% #1=#3}}% \ifnum#4<0\relax \whiledo{\(#1>#3\)\TE@or\(#1=#3\)}% {% #5% \csname @dtl@endhook@\the\@dtl@foreach@level\endcsname \global\advance#1 by #4\relax }% \else \whiledo{\(#1<#3\)\TE@or\(#1=#3\)}% {% #5% \csname @dtl@endhook@\the\@dtl@foreach@level\endcsname \global\advance#1 by #4\relax }% \fi \expandafter\global\expandafter\let\expandafter\dtlbreak \csname @dtl@break@\the\@dtl@foreach@level\endcsname \global\advance\@dtl@foreach@level by -1\relax } \long\def\@dtlforeachrow(#1,#2)\in#3\do#4{% \edef\dtl@tmp{\expandafter\the\csname dtldb@#3\endcsname}% \expandafter\@dtl@foreachrow\dtl@tmp \db@row@elt@w% \db@row@id@w \@nil\db@row@id@end@% \db@row@id@w \@nil\db@row@id@end@% \db@row@elt@end@% \@@{#1}{#2}{#4}\q@nil } \long\def\@dtl@foreachrow\db@row@elt@w% \db@row@id@w #1\db@row@id@end@% #2\db@row@id@w #3\db@row@id@end@% \db@row@elt@end@#4\@@#5#6#7\q@nil{% \gdef#5{#1}% \gdef\@dtl@loopbody{#7}% \global\advance\@dtl@foreach@level by 1\relax \ifx#5\@nnil \expandafter\global\expandafter \let\csname @dtl@foreachnext\the\@dtl@foreach@level\endcsname =\@dtl@foreachnoop \else \gdef#6{#2}% \expandafter\let \csname @dtl@break@\the\@dtl@foreach@level\endcsname \dtlbreak \gdef\dtlbreak{\expandafter\global\expandafter \let\csname @dtl@foreachnext\the\@dtl@foreach@level\endcsname =\@dtl@foreachnoop}% \expandafter\global\expandafter \let\csname @dtl@foreachnext\the\@dtl@foreach@level\endcsname =\@dtl@foreachrow \@dtl@loopbody \expandafter\let\expandafter\dtlbreak \csname @dtl@break@\the\@dtl@foreach@level\endcsname \fi \expandafter\let\expandafter\@dtl@foreachnext \csname @dtl@foreachnext\the\@dtl@foreach@level\endcsname \global\advance\@dtl@foreach@level by -1\relax \@dtl@foreachnext#4\@@{#5}{#6}{#7}\q@nil } \long\def\@dtl@foreachnoop#1\@@#2\q@nil{} \long\def\dtlforeachkey(#1,#2,#3,#4)\in#5\do#6{% \gdef\@dtl@loopbody{#6}% \edef\@dtl@keys{\expandafter\the\csname dtlkeys@#5\endcsname}% \expandafter\@dtl@foreachkey\@dtl@keys \db@plist@elt@w% \db@col@id@w -1\db@col@id@end@% \db@key@id@w \db@key@id@end@% \db@type@id@w \db@type@id@end@% \db@header@id@w \db@header@id@end@% \db@col@id@w -1\db@col@id@end@% \db@plist@elt@end@% \@@{\@dtl@updatefkcs{#1}{#2}{#3}{#4}}\q@nil } \newcommand*{\@dtl@updatefkcs}[8]{% \gdef#1{#5}% \gdef#2{#6}% \gdef#3{#7}% \gdef#4{#8}% } \long\def\@dtl@foreachkey\db@plist@elt@w% \db@col@id@w #1\db@col@id@end@% \db@key@id@w #2\db@key@id@end@% \db@type@id@w #3\db@type@id@end@% \db@header@id@w #4\db@header@id@end@% \db@col@id@w #5\db@col@id@end@% \db@plist@elt@end@#6\@@#7\q@nil{% \ifnum#1=-1\relax \let\@dtl@foreachnext\@dtl@foreachnoop \else #7{#2}{#1}{#3}{#4}% \global\advance\@dtl@foreach@level by 1\relax \expandafter\let \csname @dtl@break@\the\@dtl@foreach@level\endcsname \dtlbreak \gdef\dtlbreak{\expandafter\global\expandafter \let\csname @dtl@foreachnext\the\@dtl@foreach@level\endcsname =\@dtl@foreachnoop}% \expandafter\global\expandafter \let\csname @dtl@foreachnext\the\@dtl@foreach@level\endcsname =\@dtl@foreachkey \@dtl@loopbody \expandafter\let\expandafter\@dtl@foreachnext \csname @dtl@foreachnext\the\@dtl@foreach@level\endcsname \expandafter\let\expandafter\dtlbreak \csname @dtl@break@\the\@dtl@foreach@level\endcsname \global\advance\@dtl@foreach@level by -1\relax \fi \@dtl@foreachnext#6\@@{#7}\q@nil } \newcommand*{\dtlforcolumn}{\@ifstar\@sdtlforcolumn\@dtlforcolumn} \newcommand{\@dtlforcolumn}[4]{% \DTLifdbexists{#2}% {% \@dtlifhaskey{#2}{#3}% {% \@sdtlforcolumn{#1}{#2}{#3}{#4}% }% {% \PackageError{datatool}{Database `#2' doesn't contain key `#3'}{}% }% }% {% \PackageError{datatool}{Database `#2' doesn't exist}{}% }% } \newcommand{\@sdtlforcolumn}[4]{% \toks@{#4}% \edef\@dtl@doforcol{\noexpand\dtl@forcolumn{\noexpand#1}% {\expandafter\the\csname dtldb@#2\endcsname}% {\dtl@columnindex{#2}{#3}}{\the\toks@}% }% \@dtl@doforcol% } \newcommand*{\dtlforcolumnidx}{% \@ifstar\@sdtlforcolumnidx\@dtlforcolumnidx } \newcommand{\@dtlforcolumnidx}[4]{% \DTLifdbexists{#2}% {% \expandafter\ifnum\csname dtlcols@#2\endcsname<#3\relax \PackageError{datatool}{Column index \number#3\space out of bounds for database `#2'}{Database `#2' only has \expandafter\number\csname dtlcols@#2\endcsname\space columns}% \else \ifnum#3<1\relax \PackageError{datatool}{Column index \number#3\space out of bounds for database `#2'}{Indices start from 1}% \else \@sdtlforcolumnidx{#1}{#2}{#3}{#4}% \fi \fi }% {% \PackageError{datatool}{Database `#2' doesn't exist}{}% }% } \newcommand{\@sdtlforcolumnidx}[4]{% \toks@{#4}% \edef\@dtl@doforcol{\noexpand\dtl@forcolumn{\noexpand#1}% {\expandafter\the\csname dtldb@#2\endcsname}% {\number#3}{\the\toks@}% }% \@dtl@doforcol } \newcommand{\dtl@forcolumn}[4]{% \let\@dtl@oldbreak\dtlbreak \def\dtlbreak{\let\@dtl@forcolnext=\@dtl@forcolnoop}% \def\@dtl@forcolumn##1% before stuff \db@col@id@w #3\db@col@id@end@% column index \db@col@elt@w ##2\db@col@elt@end@% entry \db@col@id@w #3\db@col@id@end@% column index ##3% after stuff \q@nil{% \def#1{##2}% assign value to \ifx#1\@nnil \let\@dtl@forcolnext=\@dtl@forcolnoop \else #4% \let\@dtl@forcolnext=\@dtl@forcolumn \fi \@dtl@forcolnext##3\q@nil }% \@dtl@forcolumn#2% \db@col@id@w #3\db@col@id@end@% \db@col@elt@w \@nil\db@col@elt@end@% \db@col@id@w #3\db@col@id@end@\q@nil \let\dtlbreak\@dtl@oldbreak } \def\@dtl@forcolnoop#1\q@nil{} \newcount\dtlforeachlevel \newcounter{DTLrowi} \newcounter{DTLrowii} \newcounter{DTLrowiii} \newcounter{DTLrow} \def\theHDTLrow{\arabic{DTLrow}} \def\theHDTLrowi{\theHDTLrow.\arabic{DTLrowi}} \def\theHDTLrowii{\theHDTLrowi.\arabic{DTLrowii}} \def\theHDTLrowiii{\theHDTLrowii.\arabic{DTLrowiii}} \newcount\dtl@rowi \newcount\dtl@rowii \newcount\dtl@rowiii \newtoks\@dtl@curi \newtoks\@dtl@previ \newtoks\@dtl@nexti \newtoks\@dtl@curii \newtoks\@dtl@previi \newtoks\@dtl@nextii \newtoks\@dtl@curiii \newtoks\@dtl@previii \newtoks\@dtl@nextiii \newcommand*{\DTLsavelastrowcount}[1]{% \ifnum\dtlforeachlevel>2\relax \def#1{0}% \else \ifnum\dtlforeachlevel<0\relax \def#1{0}% \else \@dtl@tmpcount=\dtlforeachlevel \advance\@dtl@tmpcount by 1\relax \edef#1{\expandafter\number \csname c@DTLrow\romannumeral\@dtl@tmpcount\endcsname}% \fi \fi} \newcommand*{\DTLforeach}{\@ifstar\@sDTLforeach\@DTLforeach} \newcommand{\@DTLforeach}[4][\boolean{true}]{% \DTLifdbexists{#2}% {% \refstepcounter{DTLrow}% \global\c@DTLrow=\c@DTLrow\relax \gdef\@dtl@dbname{#2}% \global\advance\dtlforeachlevel by 1\relax \ifnum\dtlforeachlevel>3\relax \PackageError{datatool}{\string\DTLforeach\space nested too deeply}{Only 3 levels are allowed}% \else \@DTLifdbempty{#2}% {}% {% \expandafter\global \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname = 0\relax \expandafter\global\expandafter\let% \csname @dtl@iffirstrow\the\dtlforeachlevel\endcsname \DTLiffirstrow \gdef\DTLiffirstrow##1##2{% \expandafter\ifnum \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname =1\relax ##1% \else ##2% \fi}% \expandafter\global\expandafter\let% \csname @dtl@iflastrow\the\dtlforeachlevel\endcsname \DTLiflastrow \gdef\DTLiflastrow##1##2{% \expandafter\ifnum \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname =\csname dtlcols@#2\endcsname\relax ##1% \else ##2% \fi}% \expandafter\global\expandafter\let% \csname @dtl@ifoddrow\the\dtlforeachlevel\endcsname \DTLifoddrow \gdef\DTLifoddrow##1##2{% \expandafter\ifodd \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname ##1% \else ##2% \fi}% \expandafter\global\expandafter\let \csname @dtl@dbname@\romannumeral\dtlforeachlevel\endcsname =\@dtl@dbname \expandafter\global\expandafter\let \csname @dtl@ro@\romannumeral\dtlforeachlevel\endcsname = 0\relax \dtlgforint \csname dtl@row\romannumeral\dtlforeachlevel\endcsname =1\to\csname dtlrows@#2\endcsname\step1\do {% \@dtl@tmpcount= \csname dtl@row\romannumeral\dtlforeachlevel\endcsname \edef\dtl@dogetrow{\noexpand\dtlgetrow{#2}% {\number\@dtl@tmpcount}}% \dtl@dogetrow \expandafter\global \csname @dtl@cur\romannumeral\dtlforeachlevel\endcsname = \dtlcurrentrow \expandafter\global \csname @dtl@prev\romannumeral\dtlforeachlevel\endcsname = \dtlbeforerow \expandafter\global \csname @dtl@next\romannumeral\dtlforeachlevel\endcsname = \dtlafterrow \ifx\relax#3\relax \else \@dtl@assign{#3}{#2}% \fi \ifthenelse{#1}% {% \refstepcounter{DTLrow\romannumeral\dtlforeachlevel}% \expandafter\edef\expandafter\DTLcurrentindex% \expandafter{% \arabic{DTLrow\romannumeral\dtlforeachlevel}}% #4% \edef\@dtl@tmp{\expandafter\the \csname @dtl@cur\romannumeral \dtlforeachlevel\endcsname}% \ifx\@dtl@tmp\@nnil \expandafter\dtl@decrementrows\expandafter {\csname @dtl@prev\romannumeral \dtlforeachlevel\endcsname }{\csname dtl@row\romannumeral \dtlforeachlevel\endcsname}% \expandafter\dtl@decrementrows\expandafter {\csname @dtl@next\romannumeral \dtlforeachlevel\endcsname }{\csname dtl@row\romannumeral \dtlforeachlevel\endcsname}% \edef\@dtl@tmp{% \expandafter\the \csname @dtl@prev\romannumeral \dtlforeachlevel\endcsname \expandafter\the \csname @dtl@next\romannumeral \dtlforeachlevel\endcsname }% \expandafter\global\expandafter \csname dtldb@#2\endcsname\expandafter{\@dtl@tmp}% \expandafter\global\expandafter \advance\csname dtlrows@#2\endcsname by -1\relax \expandafter\global\expandafter \advance\csname dtl@row\romannumeral \dtlforeachlevel\endcsname by -1\relax \else \@dtl@before=\csname @dtl@prev\romannumeral \dtlforeachlevel\endcsname \@dtl@after=\csname @dtl@next\romannumeral \dtlforeachlevel\endcsname \toks@gconcat@middle@cx{dtldb@#2}% {\@dtl@before}% {% \noexpand\db@row@elt@w% \noexpand\db@row@id@w \expandafter\number \csname dtl@row\romannumeral \dtlforeachlevel\endcsname \noexpand\db@row@id@end@% \expandafter\the \csname @dtl@cur\romannumeral \dtlforeachlevel\endcsname \noexpand\db@row@id@w \expandafter\number \csname dtl@row\romannumeral \dtlforeachlevel\endcsname \noexpand\db@row@id@end@% \noexpand\db@row@elt@end@% }% {\@dtl@after}% \fi }% {}% }% \expandafter\global\expandafter\let\expandafter\DTLiffirstrow \csname @dtl@iffirstrow\the\dtlforeachlevel\endcsname \expandafter\global\expandafter\let\expandafter\DTLiflastrow \csname @dtl@iflastrow\the\dtlforeachlevel\endcsname \expandafter\global\expandafter\let\expandafter\DTLifoddrow \csname @dtl@ifoddrow\the\dtlforeachlevel\endcsname }% \fi \global\advance\dtlforeachlevel by -1\relax }% {% \PackageError{datatool}{Database `#2' doesn't exist}{}% }% } \newcommand{\@sDTLforeach}[4][\boolean{true}]{% \DTLifdbexists{#2}% {% \refstepcounter{DTLrow}% \global\c@DTLrow=\c@DTLrow \global\advance\dtlforeachlevel by 1\relax \ifnum\dtlforeachlevel>3\relax \PackageError{datatool}{\string\DTLforeach\space nested too deeply}{Only 3 levels are allowed}% \else \@DTLifdbempty{#2}% {}% {% \expandafter\global \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname = 0\relax \expandafter\global\expandafter\let% \csname @dtl@iffirstrow\the\dtlforeachlevel\endcsname \DTLiffirstrow \gdef\DTLiffirstrow##1##2{% \expandafter\ifnum \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname =1\relax ##1% \else ##2% \fi}% \expandafter\global\expandafter\let% \csname @dtl@iflastrow\the\dtlforeachlevel\endcsname \DTLiflastrow \gdef\DTLiflastrow##1##2{% \expandafter\ifnum \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname =\csname dtlcols@#2\endcsname\relax ##1% \else ##2% \fi}% \expandafter\global\expandafter\let% \csname @dtl@ifoddrow\the\dtlforeachlevel\endcsname \DTLifoddrow \gdef\DTLifoddrow##1##2{% \expandafter\ifodd \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname ##1% \else ##2% \fi}% \expandafter\gdef\csname @dtl@dbname@\romannumeral \dtlforeachlevel\endcsname{#2}% \expandafter\global\expandafter\let \csname @dtl@ro@\romannumeral\dtlforeachlevel\endcsname = 1\relax \@dtlforeachrow(\dtl@thisidx,\dtl@thisrow)\in{#2}\do% {% \csname dtl@row\romannumeral\dtlforeachlevel\endcsname = \dtl@thisidx\relax \expandafter\global \csname @dtl@cur\romannumeral\dtlforeachlevel\endcsname = \expandafter{\dtl@thisrow}% \ifx\relax#3\relax \else \dtlcurrentrow=\expandafter{\dtl@thisrow}% \@dtl@assign{#3}{#2}% \fi \ifthenelse{#1}% {% \refstepcounter{DTLrow\romannumeral\dtlforeachlevel}% \expandafter\edef\expandafter\DTLcurrentindex% \expandafter{% \arabic{DTLrow\romannumeral\dtlforeachlevel}}% #4% }% {}% }% \expandafter\global\expandafter\let\expandafter\DTLiffirstrow \csname @dtl@iffirstrow\the\dtlforeachlevel\endcsname \expandafter\global\expandafter\let\expandafter\DTLiflastrow \csname @dtl@iflastrow\the\dtlforeachlevel\endcsname \expandafter\global\expandafter\let\expandafter\DTLifoddrow \csname @dtl@ifoddrow\the\dtlforeachlevel\endcsname }% \fi \global\advance\dtlforeachlevel by -1\relax }% {% \PackageError{datatool}{Database `#2' doesn't exist}{}% }% } \newcommand*{\@dtlifreadonly}[2]{% \expandafter\ifx \csname @dtl@ro@\romannumeral\dtlforeachlevel\endcsname1\relax #1% \else #2% \fi } \newcommand*{\DTLappendtorow}[2]{% \ifnum\dtlforeachlevel=0\relax \PackageError{datatool}{\string\DTLappendrow\space can only be used inside \string\DTLforeach}{}% \else \expandafter\let\expandafter\@dtl@thisdb \csname @dtl@dbname@\romannumeral\dtlforeachlevel\endcsname \@dtlifreadonly {% \PackageError{datatool}{\string\DTLappendtorow\space can't be used inside \DTLforeach*}{The starred version of \string\DTLforeach\space is read only}% }% {% \dtlrownum= \csname dtl@row\romannumeral\dtlforeachlevel\endcsname\relax \@dtl@updatekeys{\@dtl@thisdb}{#1}{#2}% \expandafter\dtlcolumnnum\expandafter =\dtl@columnindex{\@dtl@thisdb}{#1}\relax \dtlcurrentrow = \csname @dtl@cur\romannumeral\dtlforeachlevel\endcsname \edef\dtl@dogetentry{\noexpand\dtlgetentryfromcurrentrow {\noexpand\dtl@entry}{\number\dtlcolumnnum}% }% \dtl@dogetentry \ifx\dtl@entry\dtlnovalue \expandafter\@dtl@toks\expandafter{#2}% \toks@gput@right@cx{@dtl@cur\romannumeral\dtlforeachlevel}% {% \noexpand\db@col@id@w \number\dtlcolumnnum \noexpand\db@col@id@end@ \noexpand\db@col@elt@w \the\@dtl@toks \noexpand\db@col@elt@end@ \noexpand\db@col@id@w \number\dtlcolumnnum \noexpand\db@col@id@end@ }% \dtl@message{Appended #1\space -> #2\space to database `\@dtl@thisdb'}% \else \PackageError{datatool}{Can't append entry to row: there is already an entry for key `#1' in this row}{}% \fi }% \fi } \newcommand*{\DTLremoveentryfromrow}[1]{% \ifnum\dtlforeachlevel=0\relax \PackageError{datatool}{\string\DTLremoventryfromrow\space can only be used inside \string\DTLforeach}{}% \else \expandafter\let\expandafter\@dtl@thisdb \csname @dtl@dbname@\romannumeral\dtlforeachlevel\endcsname \@dtlifreadonly {% \PackageError{datatool}{\string\DTLremoveentryfromrow\space can't be used inside \string\DTLforeach*}{The starred version of \string\DTLforeach\space is read only}% }% {% \dtlrownum= \csname dtl@row\romannumeral\dtlforeachlevel\endcsname\relax \@dtlifhaskey{\@dtl@thisdb}{#1}% {% \dtl@getcolumnindex{\thiscol}{\@dtl@thisdb}{#1}\relax \dtlcolumnnum=\thiscol\relax \dtlcurrentrow = \csname @dtl@cur\romannumeral\dtlforeachlevel\endcsname \edef\dtl@dogetentry{\noexpand\dtlgetentryfromcurrentrow {\noexpand\dtl@entry}{\number\dtlcolumnnum}% }% \dtl@dogetentry \ifx\dtl@entry\dtlnovalue \PackageError{datatool}{Can't remove entry given by `#1' from current row in database `\@dtl@thisdb': no such entry}{The current row doesn't contain an entry for key `#1'}% \else \edef\@dtl@dosplitrow{% \noexpand\dtlsplitrow{\the\dtlcurrentrow}% {\number\dtlcolumnnum}{\noexpand\dtl@pre}% {\noexpand\dtl@post}% }% \@dtl@dosplitrow \expandafter\@dtl@toks\expandafter{\dtl@pre}% \expandafter\toks@\expandafter{\dtl@post}% \edef\@dtl@tmp{\the\@dtl@toks \the\toks@}% \dtlcurrentrow=\expandafter{\@dtl@tmp}% \expandafter\global \csname @dtl@cur\romannumeral\dtlforeachlevel\endcsname = \dtlcurrentrow \dtl@message{Removed entry given by #1\space from current row of database `\@dtl@thisdb'}% \fi }% {% \PackageError{datatool}{Can't remove entry given by `#1' - no such key exists}{}% }% }% \fi } \newcommand*{\DTLreplaceentryforrow}[2]{% \ifnum\dtlforeachlevel=0\relax \PackageError{datatool}{\string\DTLreplaceentryforrow\space can only be used inside \string\DTLforeach}{}% \else \expandafter\let\expandafter\@dtl@thisdb \csname @dtl@dbname@\romannumeral\dtlforeachlevel\endcsname \@dtlifreadonly {% \PackageError{datatool}{\string\DTLreplaceentryforrow\space can't be used inside \string\DTLforeach*}{The starred version of \string\DTLforeach\space is read only}% }% {% \dtlrownum= \csname dtl@row\romannumeral\dtlforeachlevel\endcsname\relax \@dtlifhaskey{\@dtl@thisdb}{#1}% {% \dtl@getcolumnindex{\thiscol}{\@dtl@thisdb}{#1}\relax \dtlcolumnnum=\thiscol\relax \dtlcurrentrow = \csname @dtl@cur\romannumeral\dtlforeachlevel\endcsname \edef\dtl@dogetentry{\noexpand\dtlgetentryfromcurrentrow {\noexpand\dtl@entry}{\number\dtlcolumnnum}% }% \dtl@dogetentry \ifx\dtl@entry\dtlnovalue \PackageError{datatool}{Can't replace entry given by `#1' from current row in database `\@dtl@thisdb': no such entry}{The current row doesn't contain an entry for key `#1'}% \else \edef\@dtl@dosplitrow{% \noexpand\dtlsplitrow{\the\dtlcurrentrow}% {\number\dtlcolumnnum}{\noexpand\dtl@pre}% {\noexpand\dtl@post}% }% \@dtl@dosplitrow \@dtl@toks{#2}% new value \expandafter\@dtl@before\expandafter{\dtl@pre}% \expandafter\@dtl@after\expandafter{\dtl@post}% \toks@gconcat@middle@cx {@dtl@cur\romannumeral\dtlforeachlevel}% {\@dtl@before}% {% \noexpand\db@col@id@w \number\dtlcolumnnum \noexpand\db@col@id@end@% \noexpand\db@col@elt@w \the\@dtl@toks \noexpand\db@col@elt@end@% \noexpand\db@col@id@w \number\dtlcolumnnum \noexpand\db@col@id@end@% }% {\@dtl@after}% \dtl@message{Updated #1\space -> #2\space in database `\@dtl@thisdb'}% \fi }% {% \PackageError{datatool}{Can't replace key `#1' - no such key in database `\@dtl@thisdb'}{}% }% }% \fi } \newcommand*{\DTLremovecurrentrow}{% \ifnum\dtlforeachlevel=0\relax \PackageError{datatool}{\string\DTLremovecurrentrow\space can only be used inside \string\DTLforeach}{}% \else \expandafter\let\expandafter\@dtl@thisdb \csname @dtl@dbname@\romannumeral\dtlforeachlevel\endcsname \@dtlifreadonly {% \PackageError{datatool}{\string\DTLreplaceentryforrow\space can't be used inside \string\DTLforeach*}{The starred version of \string\DTLforeach\space is read only}% }% {% \expandafter\global \csname @dtl@cur\romannumeral\dtlforeachlevel\endcsname ={\@nil}% }% \fi } \newcommand{\DTLaddentryforrow}[5]{% \DTLifdbexists{#1}% { \def\@dtl@notdone{\PackageError{datatool}{Unable to add entry given by key `#4': condition not met for any row in database `#1'}{}}% \DTLforeach[#3]{#1}{#2}% {% \DTLappendtorow{#4}{#5}% \let\@dtl@notdone\relax \dtlbreak }% \@dtl@notdone }% {% \PackageError{datatool}{Unable to add entry given by key `#4': database `#1' doesn't exist}{}% }% } \newcommand*{\DTLforeachkeyinrow}[2]{% \ifnum\dtlforeachlevel=0\relax \PackageError{datatool}{\string\DTLforeachkeyinrow\space can only be used inside \string\DTLforeach}{}% \else \expandafter\let\expandafter\@dtl@thisdb \csname @dtl@dbname@\romannumeral\dtlforeachlevel\endcsname \dtlforeachkey(\dtlkey,\dtlcol,\dtltype,\dtlheader)\in \@dtl@thisdb\do{% \dtlcurrentrow = \csname @dtl@cur\romannumeral\dtlforeachlevel\endcsname \edef\dtl@dogetentry{\noexpand\dtlgetentryfromcurrentrow {\noexpand#1}{\dtlcol}}% \dtl@dogetentry \ifx#1\dtlnovalue \ifnum0\dtltype=0\relax \let#1=\DTLstringnull \else \let#1=\DTLnumbernull \fi \fi \global\let#1#1% \def\@dtl@loop@body{#2}% \@dtl@loop@body }% \fi } \newcommand*{\dtlbetweencols}{} \newcommand*{\dtlbeforecols}{} \newcommand*{\dtlaftercols}{} \newcommand*{\dtlstringalign}{l} \newcommand*{\dtlintalign}{r} \newcommand*{\dtlrealalign}{r} \newcommand*{\dtlcurrencyalign}{r} \newcommand*{\dtladdalign}[4]{% \ifnum#3=1\relax \protected@edef#1{\dtlbeforecols}% \else \protected@edef#1{#1\dtlbetweencols}% \fi \ifx\@empty#2\@empty \protected@edef#1{#1c}% \else \ifcase#2\relax \protected@edef#1{#1\dtlstringalign}% \or \protected@edef#1{#1\dtlintalign}% \or \protected@edef#1{#1\dtlrealalign}% \or \protected@edef#1{#1\dtlcurrencyalign}% \else \protected@edef#1{#1c}% \PackageError{datatool}{Unknown data type `#2'}{}% \fi \fi \ifnum#3=#4\relax \protected@edef#1{#1\dtlaftercols}% \fi } \newcommand*{\dtlheaderformat}[1]{\null\hfil\textbf{#1}\hfil\null} \newcommand*{\dtlstringformat}[1]{#1} \newcommand*{\dtlintformat}[1]{#1} \newcommand*{\dtlrealformat}[1]{#1} \newcommand*{\dtlcurrencyformat}[1]{#1} \newcommand*{\dtldisplaystarttab}{} \newcommand*{\dtldisplayendtab}{} \newcommand*{\dtldisplayafterhead}{} \newcommand*{\dtldisplaystartrow}{} \newcommand*{\DTLdisplaydb}[1]{% \def\@dtl@doamp{\gdef\@dtl@doamp{&}} \def\@dtl@resetdoamp{\gdef\@dtl@doamp{\gdef\@dtl@doamp{&}}} \edef\@dtl@maxcols{\expandafter\number \csname dtlcols@#1\endcsname}% \def\@dtl@tabargs{}% \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)% \in{#1}\do {% \dtladdalign\@dtl@tabargs\@dtl@type\@dtl@idx\@dtl@maxcols }% \edef\@dtl@dobegintab{\noexpand\begin{tabular}{\@dtl@tabargs}}% \@dtl@dobegintab \dtldisplaystarttab \@dtl@resetdoamp \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)% \in{#1}\do {% \@dtl@doamp \dtlheaderformat{\@dtl@head}% }% \\% \dtldisplayafterhead \@dtl@resetdoamp \DTLforeach*{#1}{}{% \DTLiffirstrow{}{\\\dtldisplaystartrow}% \@dtl@resetdoamp \DTLforeachkeyinrow{\@dtl@val}% {% \global\let\@dtl@val\@dtl@val \@dtl@doamp \@dtl@datatype=0\dtltype\relax \ifcase\@dtl@datatype \dtlstringformat\@dtl@val \or \dtlintformat\@dtl@val \or \dtlrealformat\@dtl@val \or \dtlcurrencyformat\@dtl@val \else \@dtl@val \fi }% }% \dtldisplayendtab \end{tabular}% } \define@key{displaylong}{caption}{\def\@dtl@cap{#1}} \define@key{displaylong}{contcaption}{\def\@dtl@contcap{#1}} \define@key{displaylong}{shortcaption}{\def\@dtl@shortcap{#1}} \define@key{displaylong}{label}{\def\@dtl@label{#1}} \define@key{displaylong}{foot}{\def\@dtl@foot{#1}} \define@key{displaylong}{lastfoot}{\def\@dtl@lastfoot{#1}} \newcommand*{\@dtl@resetdostartrow}{% \gdef\@dtl@dostartrow{% \gdef\@dtl@dostartrow{\\\dtldisplaystartrow}}% } \newcommand*{\DTLdisplaylongdb}[2][]{% \def\@dtl@cap{\@nil}% \def\@dtl@contcap{\@nil}% \def\@dtl@label{\@nil}% \def\@dtl@shortcap{\@dtl@cap}% \def\@dtl@foot{\@nil}% \def\@dtl@lastfoot{\@nil}% \setkeys{displaylong}{#1}% \def\@dtl@doamp{\gdef\@dtl@doamp{&}} \def\@dtl@resetdoamp{\gdef\@dtl@doamp{\gdef\@dtl@doamp{&}}} \@dtl@resetdostartrow \edef\@dtl@maxcols{\expandafter\number \csname dtlcols@#2\endcsname}% \def\@dtl@tabargs{}% \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)% \in{#2}\do {% \dtladdalign\@dtl@tabargs\@dtl@type\@dtl@idx\@dtl@maxcols }% \edef\@dtl@dobegintab{\noexpand\begin{longtable}{\@dtl@tabargs}}% \@dtl@dobegintab \dtldisplaystarttab \ifx\@dtl@foot\@nnil \else \@dtl@foot\endfoot \fi \ifx\@dtl@lastfoot\@nnil \else \@dtl@lastfoot\endlastfoot \fi \ifx\@dtl@cap\@nnil \@dtl@resetdoamp \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)% \in{#2}\do {\@dtl@doamp{\dtlheaderformat{\@dtl@head}}}% \@dtl@resetdoamp \@dtl@resetdostartrow \endhead\dtldisplayafterhead \else \caption[\@dtl@shortcap]{\@dtl@cap}% \ifx\@dtl@label\@nnil \else \label{\@dtl@label}% \fi \\% \@dtl@resetdoamp \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)% \in{#2}\do {\@dtl@doamp{\dtlheaderformat{\@dtl@head}}}% \@dtl@resetdoamp \@dtl@resetdostartrow \endfirsthead \ifx\@dtl@contcap\@nnil \caption{\@dtl@cap}% \else \caption{\@dtl@contcap}% \fi \\% \@dtl@resetdoamp \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)% \in{#2}\do {\@dtl@doamp{\dtlheaderformat{\@dtl@head}}}% \@dtl@resetdoamp \@dtl@resetdostartrow \endhead\dtldisplayafterhead \fi \DTLforeach*{#2}{}{% \@dtl@dostartrow \@dtl@resetdoamp \DTLforeachkeyinrow{\@dtl@val}% {% \global\let\@dtl@val\@dtl@val \@dtl@doamp \@dtl@datatype=0\dtltype\relax \ifcase\@dtl@datatype \dtlstringformat\@dtl@val \or \dtlintformat\@dtl@val \or \dtlrealformat\@dtl@val \or \dtlcurrencyformat\@dtl@val \fi }% }% \dtldisplayendtab \end{longtable}% } \newcommand*{\dtlswaprows}[3]{% \ifnum#2=#3\relax \else \ifnum#2<#3\relax \edef\@dtl@rowAidx{\number#2}% \edef\@dtl@rowBidx{\number#3}% \else \edef\@dtl@rowAidx{\number#3}% \edef\@dtl@rowBidx{\number#2}% \fi \edef\@dtl@dosplit{\noexpand\dtlgetrow{#1}{\@dtl@rowAidx}}% \@dtl@dosplit \expandafter\def\expandafter\@dtl@firstpart\expandafter {\the\dtlbeforerow}% \@dtl@toksA=\dtlcurrentrow \edef\@dtl@dosplit{\noexpand\@dtlgetrow {\the\dtlafterrow}{\@dtl@rowBidx}}% \@dtl@dosplit \expandafter\def\expandafter\@dtl@secondpart\expandafter {\the\dtlbeforerow}% \@dtl@toksB=\dtlcurrentrow \expandafter\def\expandafter\@dtl@thirdpart\expandafter {\the\dtlafterrow}% \toks@=\expandafter{\@dtl@firstpart}% \@dtl@toks=\expandafter{\@dtl@secondpart}% \edef\@dtl@tmp{\the\toks@ \noexpand\db@row@elt@w% \noexpand\db@row@id@w \@dtl@rowAidx\noexpand\db@row@id@end@% \the\@dtl@toksB \noexpand\db@row@id@w \@dtl@rowAidx\noexpand\db@row@id@end@% \noexpand\db@row@elt@end@% \the\@dtl@toks}% \toks@=\expandafter{\@dtl@tmp}% \@dtl@toks=\expandafter{\@dtl@thirdpart}% \edef\@dtl@tmp{\the\toks@ \noexpand\db@row@elt@w% \noexpand\db@row@id@w \@dtl@rowBidx\noexpand\db@row@id@end@% \the\@dtl@toksA \noexpand\db@row@id@w \@dtl@rowBidx\noexpand\db@row@id@end@% \noexpand\db@row@elt@end@% \the\@dtl@toks}% \expandafter\global\csname dtldb@#1\endcsname=\expandafter {\@dtl@tmp}% \fi } \newcommand*{\dtl@decrementrows}[2]{% \def\@dtl@newlist{}% \edef\@dtl@min{\number#2}% \expandafter\@dtl@decrementrows\the#1% \db@row@elt@w% \db@row@id@w \@nil\db@row@id@end@% \db@row@id@w \@nil\db@row@id@end@% \db@row@elt@end@% \@nil #1=\expandafter{\@dtl@newlist}% } \def\@dtl@decrementrows\db@row@elt@w\db@row@id@w #1\db@row@id@end@% #2\db@row@id@w #3\db@row@id@end@\db@row@elt@end@#4\@nil{% \def\@dtl@thisrow{#1}% \ifx\@dtl@thisrow\@nnil \let\@dtl@donextdec=\@dtl@gobbletonil \else \ifnum\@dtl@thisrow>\@dtl@min \@dtl@tmpcount=\@dtl@thisrow\relax \advance\@dtl@tmpcount by -1\relax \toks@{#2}% \@dtl@toks=\expandafter{\@dtl@newlist}% \edef\@dtl@newlist{\the\@dtl@toks \noexpand\db@row@elt@w% row header \noexpand\db@row@id@w \number\@dtl@tmpcount \noexpand\db@row@id@end@% row id \the\toks@ % row contents \noexpand\db@row@id@w \number\@dtl@tmpcount \noexpand\db@row@id@end@% row id \noexpand\db@row@elt@end@% row end }% \else \toks@{#2}% \@dtl@toks=\expandafter{\@dtl@newlist}% \edef\@dtl@newlist{\the\@dtl@toks \noexpand\db@row@elt@w% row header \noexpand\db@row@id@w #1% \noexpand\db@row@id@end@% row id \the\toks@ % row contents \noexpand\db@row@id@w #3% \noexpand\db@row@id@end@% row id \noexpand\db@row@elt@end@% row end }% \fi \let\@dtl@donextdec=\@dtl@decrementrows \fi \@dtl@donextdec#4\@nil } \newcommand*{\DTLremoverow}[2]{% \DTLifdbexists{#1}% {% \ifnum#2>0\relax \expandafter\ifnum\csname dtlrows@#1\endcsname<#2\relax \expandafter\ifnum\csname dtlrows@#1\endcsname=1\relax \PackageError{datatool}{Can't remove row `\number#2' from database `#1': no such row}{Database `#1' only has 1 row}% \else \PackageError{datatool}{Can't remove row `\number#2' from database `#1': no such row}{Database `#1' only has \expandafter\number\csname dtlrows@#1\endcsname\space rows}% \fi \else \@DTLremoverow{#1}{#2}% \fi \else \PackageError{datatool}{Can't remove row \number#2: index out of bounds}{Row indices start at 1}% \fi }% {% \PackageError{datatool}{Can't remove row: database `#1' doesn't exist}{}% }% } \newcommand*{\@DTLremoverow}[2]{% \edef\dtl@dogetrow{\noexpand\dtlgetrow{#1}{\number#2}}% \dtl@dogetrow \expandafter\dtl@decrementrows\expandafter {\dtlbeforerow}{#2}% \expandafter\dtl@decrementrows\expandafter {\dtlafterrow}{#2}% \edef\dtl@tmp{\the\dtlbeforerow \the\dtlafterrow}% \expandafter\global\csname dtldb@#1\endcsname =\expandafter{\dtl@tmp}% \expandafter\global\expandafter\advance \csname dtlrows@#1\endcsname by -1\relax } \newcommand*{\DTLsumforkeys}[1][\boolean{true}\and \DTLisnumerical{\DTLthisval}]{% \def\@dtl@cond{#1}% \@dtlsumforkeys } \newcommand*{\@dtlsumforkeys}[4][]{% \def#4{0}% \@for\@dtl@dbname:=#2\do{% \@sDTLforeach{\@dtl@dbname}% {#1}% assignment list {% \@for\@dtl@key:=#3\do{% \@sdtl@getcolumnindex{\@dtl@col}{\@dtl@dbname}{\@dtl@key}% \dtlcurrentrow=\expandafter{\dtl@thisrow}% \dtlgetentryfromrow{\DTLthisval}{\@dtl@col}{\dtlcurrentrow}% \expandafter\ifthenelse\expandafter{\@dtl@cond}% {\DTLadd{#4}{#4}{\DTLthisval}}{}% }% }% }% } \newcommand*{\DTLsumcolumn}[3]{% \def#3{0}% \DTLifdbexists{#1}% {% \@sDTLifhaskey{#1}{#2}% {% \@sdtlforcolumn{\DTLthisval}{#1}{#2}% {% \DTLadd{#3}{#3}{\DTLthisval}% }% }% {% \PackageError{datatool}{Key `#2' doesn't exist in database `#1'}{}% }% }% {% \PackageError{datatool}{Data base `#1' doesn't exist}{}% }% } \newcommand*{\DTLmeanforkeys}[1][\boolean{true}\and \DTLisnumerical{\DTLthisval}]{% \def\@dtl@cond{#1}% \@dtlmeanforkeys } \newcount\@dtl@elements \newcommand*{\@dtlmeanforkeys}[4][]{% \def#4{0}% \@dtl@elements=0\relax \@for\@dtl@dbname:=#2\do{% \@sDTLforeach{\@dtl@dbname}% {#1}% assignment list {% \@for\@dtl@key:=#3\do{% \@sdtl@getcolumnindex{\@dtl@col}{\@dtl@dbname}{\@dtl@key}% \dtlcurrentrow=\expandafter{\dtl@thisrow}% \dtlgetentryfromrow{\DTLthisval}{\@dtl@col}{\dtlcurrentrow}% \expandafter\ifthenelse\expandafter{\@dtl@cond}% {% \DTLadd{#4}{#4}{\DTLthisval}% \advance\@dtl@elements by 1\relax }{}% }% }% }% \ifnum\@dtl@elements=0\relax \PackageError{datatool}{Unable to evaluate mean: no data}{}% \else \edef\@dtl@n{\number\@dtl@elements}% \DTLdiv{#4}{#4}{\@dtl@n}% \fi } \newcommand*{\DTLmeanforcolumn}[3]{% \def#3{0}% \@dtl@elements=0\relax \DTLifdbexists{#1}% {% \@sDTLifhaskey{#1}{#2}% {% \@sdtlforcolumn{\DTLthisval}{#1}{#2}% {% \DTLadd{#3}{#3}{\DTLthisval}% \advance\@dtl@elements by 1\relax }% \ifnum\@dtl@elements=0\relax \PackageError{datatool}{Can't compute mean for column `#2' in database `#1': no data}{}% \else \edef\@dtl@n{\number\@dtl@elements}% \DTLdiv{#3}{#3}{\@dtl@n}% \fi }% {% \PackageError{datatool}{Key `#2' doesn't exist in database `#1'}{}% }% }% {% \PackageError{datatool}{Data base `#1' doesn't exist}{}% }% } \newcommand*{\DTLvarianceforkeys}[1][\boolean{true}\and \DTLisnumerical{\DTLthisval}]{% \def\@dtl@cond{#1}% \@dtlvarianceforkeys } \newcommand*{\@dtlvarianceforkeys}[4][]{% \@dtlmeanforkeys[#1]{#2}{#3}{\dtl@mean}% \def#4{0}% \@dtl@elements=0\relax \@for\@dtl@dbname:=#2\do{% \@sDTLforeach{\@dtl@dbname}% {#1}% assignment list {% \@for\@dtl@key:=#3\do{% \@sdtl@getcolumnindex{\@dtl@col}{\@dtl@dbname}{\@dtl@key}% \dtlcurrentrow=\expandafter{\dtl@thisrow}% \dtlgetentryfromrow{\DTLthisval}{\@dtl@col}{\dtlcurrentrow}% \expandafter\ifthenelse\expandafter{\@dtl@cond}% {% \DTLsub{\dtl@diff}{\DTLthisval}{\dtl@mean}% \DTLmul{\dtl@diff}{\dtl@diff}{\dtl@diff}% \DTLadd{#4}{#4}{\dtl@diff}% \advance\@dtl@elements by 1\relax }{}% }% }% }% \ifnum\@dtl@elements=0\relax \PackageError{datatool}{Unable to evaluate variance: no data}{}% \else \edef\@dtl@n{\number\@dtl@elements}% \DTLdiv{#4}{#4}{\@dtl@n}% \fi } \newcommand*{\DTLvarianceforcolumn}[3]{% \DTLmeanforcolumn{#1}{#2}{\dtl@mean}% \def#3{0}% \@dtl@elements=0\relax \DTLifdbexists{#1}% {% \@sDTLifhaskey{#1}{#2}% {% \@sdtlforcolumn{\DTLthisval}{#1}{#2}% {% \DTLsub{\dtl@diff}{\DTLthisval}{\dtl@mean}% \DTLmul{\dtl@diff}{\dtl@diff}{\dtl@diff}% \DTLadd{#3}{#3}{\dtl@diff}% \advance\@dtl@elements by 1\relax }% \ifnum\@dtl@elements=0\relax \PackageError{datatool}{Can't compute variance for column `#2' in database `#1': no data}{}% \else \edef\@dtl@n{\number\@dtl@elements}% \DTLdiv{#3}{#3}{\@dtl@n}% \fi }% {% \PackageError{datatool}{Key `#2' doesn't exist in database `#1'}{}% }% }% {% \PackageError{datatool}{Data base `#1' doesn't exist}{}% }% } \newcommand*{\DTLsdforkeys}[1][\boolean{true}\and \DTLisnumerical{\DTLthisval}]{% \def\@dtl@cond{#1}% \@dtlsdforkeys } \newcommand*{\@dtlsdforkeys}[4][]{% \@dtlvarianceforkeys[#1]{#2}{#3}{#4}% \DTLsqrt{#4}{#4}% } \newcommand*{\DTLsdforcolumn}[3]{% \DTLvarianceforcolumn{#1}{#2}{#3}% \DTLsqrt{#3}{#3}% } \newcommand*{\DTLminforkeys}[1][\boolean{true}\and \DTLisnumerical{\DTLthisval}]{% \def\@dtl@cond{#1}% \@dtlminforkeys } \newcommand*{\@dtlminforkeys}[4][]{% \def#4{}% \@for\@dtl@dbname:=#2\do{% \@sDTLforeach{\@dtl@dbname}% {#1}% assignment list {% \@for\@dtl@key:=#3\do{% \@sdtl@getcolumnindex{\@dtl@col}{\@dtl@dbname}{\@dtl@key}% \dtlcurrentrow=\expandafter{\dtl@thisrow}% \dtlgetentryfromrow{\DTLthisval}{\@dtl@col}{\dtlcurrentrow}% \expandafter\ifthenelse\expandafter{\@dtl@cond}% {% \ifx#4\@empty \let#4\DTLthisval \else \DTLmin{#4}{#4}{\DTLthisval}% \fi }{}% }% }% }% } \newcommand*{\DTLminforcolumn}[3]{% \def#3{}% \DTLifdbexists{#1}% {% \@sDTLifhaskey{#1}{#2}% {% \@sdtlforcolumn{\DTLthisval}{#1}{#2}% {% \ifx#3\@empty \let#3\DTLthisval \else \DTLmin{#3}{#3}{\DTLthisval}% \fi }% }% {% \PackageError{datatool}{Key `#2' doesn't exist in database `#1'}{}% }% }% {% \PackageError{datatool}{Data base `#1' doesn't exist}{}% }% } \newcommand*{\DTLmaxforkeys}[1][\boolean{true}\and \DTLisnumerical{\DTLthisval}]{% \def\@dtl@cond{#1}% \@dtlmaxforkeys } \newcommand*{\@dtlmaxforkeys}[4][]{% \def#4{}% \@for\@dtl@dbname:=#2\do{% \@sDTLforeach{\@dtl@dbname}% {#1}% assignment list {% \@for\@dtl@key:=#3\do{% \@sdtl@getcolumnindex{\@dtl@col}{\@dtl@dbname}{\@dtl@key}% \dtlcurrentrow=\expandafter{\dtl@thisrow}% \dtlgetentryfromrow{\DTLthisval}{\@dtl@col}{\dtlcurrentrow}% \expandafter\ifthenelse\expandafter{\@dtl@cond}% {% \ifx#4\@empty \let#4\DTLthisval \else \DTLmax{#4}{#4}{\DTLthisval}% \fi }{}% }% }% }% } \newcommand*{\DTLmaxforcolumn}[3]{% \def#3{}% \DTLifdbexists{#1}% {% \@sDTLifhaskey{#1}{#2}% {% \@sdtlforcolumn{\DTLthisval}{#1}{#2}% {% \ifx#3\@empty \let#3\DTLthisval \else \DTLmax{#3}{#3}{\DTLthisval}% \fi }% }% {% \PackageError{datatool}{Key `#2' doesn't exist in database `#1'}{}% }% }% {% \PackageError{datatool}{Data base `#1' doesn't exist}{}% }% } \newcommand*{\DTLcomputebounds}[8][\boolean{true}]{% \let#5=\relax \let#6=\relax \let#7=\relax \let#8=\relax \@for\dtl@thisdb:=#2\do{% \@sDTLforeach[#1]{\dtl@thisdb}{\DTLthisX=#3,\DTLthisY=#4}{% \DTLconverttodecimal{\DTLthisX}{\dtl@decx}% \DTLconverttodecimal{\DTLthisY}{\dtl@decy}% \ifx#5\relax \let#5=\dtl@decx \let#6=\dtl@decy \let#7=\dtl@decx \let#8=\dtl@decy \else \FPmin{#5}{#5}{\dtl@decx}% \FPmin{#6}{#6}{\dtl@decy}% \FPmax{#7}{#7}{\dtl@decx}% \FPmax{#8}{#8}{\dtl@decy}% \fi }% }% } \newcommand*{\DTLgetvalueforkey}[5]{% \DTLgetrowforkey{\@dtl@row}{#3}{#4}{#5}% \@sdtl@getcolumnindex{\@dtl@col}{#3}{#2}% {% \dtlcurrentrow=\expandafter{\@dtl@row}% \edef\@dtl@dogetval{\noexpand\dtlgetentryfromcurrentrow {\noexpand\@dtl@val}{\@dtl@col}}% \@dtl@dogetval \global\let#1=\@dtl@val }% } \newcommand*{\DTLgetrowforkey}[4]{% \global\let#1=\@empty \@sDTLforeach{#2}{\dtl@refvalue=#3}{% \DTLifnull{\dtl@refvalue}% {}% {% \ifthenelse{\equal{\dtl@refvalue}{#4}}% {% \xdef#1{\the\dtlcurrentrow}% \dtlbreak }% {}% }% }% } \newcommand*{\dtlsplitrow}[4]{% \def\@dtlsplitrow##1%before stuff \db@col@id@w #2\db@col@id@end@% column id ##2% unwanted stuff \db@col@id@w #2\db@col@id@end@% column id ##3% after stuff \q@nil{\def#3{##1}\def#4{##3}}% \@dtlsplitrow#1\q@nil } \newtoks\@dtl@list \newcommand*{\DTLsort}{\@ifstar\@sDTLsort\@DTLsort} \newcommand{\@DTLsort}[3][]{% \DTLifdbexists{#3}% {% \edef\@dtl@replacementkeys{#1}% \edef\@dtl@sortorder{#2}% \let\@dtl@comparecs=\dtlcompare \dtl@sortdata{#3}% }% {% \PackageError{datatool}{Database `#3' doesn't exist}{}% }% } \newcommand{\@sDTLsort}[3][]{% \DTLifdbexists{#3}% {% \edef\@dtl@replacementkeys{#1}% \edef\@dtl@sortorder{#2}% \let\@dtl@comparecs=\dtlicompare \dtl@sortdata{#3}% }% {% \PackageError{datatool}{Database `#3' doesn't exist}{}% }% } \newtoks\@dtl@rowa \newtoks\@dtl@rowb \newcommand*{\dtl@sortdata}[1]{% \def\@dtl@sortedlist{}% \edef\@dtl@dbname{#1}% \@dtlforeachrow(\@dtl@rowAnum,\@dtl@rowAcontents)\in{#1}\do{% \@dtl@rowa=\expandafter{\@dtl@rowAcontents}% \def\@dtl@newlist{}% \@dtl@insertdonefalse \dtlrownum=0\relax \expandafter\@dtl@foreachrow\@dtl@sortedlist \db@row@elt@w% \db@row@id@w \@nil\db@row@id@end@% \db@row@id@w \@nil\db@row@id@end@% \db@row@elt@end@% \@@{\@dtl@rowBnum}{\@dtl@rowBcontents}{% \@dtl@rowb=\expandafter{\@dtl@rowBcontents}% \dtlrownum=\@dtl@rowBnum \if@dtl@insertdone \advance\dtlrownum by 1\relax \else \@dtl@sortcriteria{\@dtl@rowa}{\@dtl@rowb}% \ifnum\dtl@sortresult<0\relax \toks@=\expandafter{\@dtl@newlist}% \edef\@dtl@newlist{% \the\toks@ \noexpand\db@row@elt@w% \noexpand\db@row@id@w \number\dtlrownum \noexpand\db@row@id@end@% \the\@dtl@rowa \noexpand\db@row@id@w \number\dtlrownum \noexpand\db@row@id@end@% \noexpand\db@row@elt@end@% }% \advance\dtlrownum by 1\relax \@dtl@insertdonetrue \fi \fi \toks@=\expandafter{\@dtl@newlist}% \edef\@dtl@newlist{\the\toks@ \noexpand\db@row@elt@w% \noexpand\db@row@id@w \number\dtlrownum \noexpand\db@row@id@end@% \the\@dtl@rowb \noexpand\db@row@id@w \number\dtlrownum \noexpand\db@row@id@end@% \noexpand\db@row@elt@end@% }% }\q@nil \if@dtl@insertdone \else \advance\dtlrownum by 1\relax \toks@=\expandafter{\@dtl@newlist}% \edef\@dtl@newlist{\the\toks@ \noexpand\db@row@elt@w% \noexpand\db@row@id@w \number\dtlrownum \noexpand\db@row@id@end@% \the\@dtl@rowa \noexpand\db@row@id@w \number\dtlrownum \noexpand\db@row@id@end@% \noexpand\db@row@elt@end@% }% \fi \let\@dtl@sortedlist=\@dtl@newlist }% \expandafter\global\csname dtldb@#1\endcsname=\expandafter {\@dtl@sortedlist}% } \newcommand{\@dtl@sortcriteria}[2]{% \@for\@dtl@level:=\@dtl@sortorder\do{% \expandafter\@dtl@getsortdirection\@dtl@level=\relax \let\@dtl@keya=\@dtl@key \let\@dtl@keyb=\@dtl@key \@sdtl@getcolumnindex{\@dtl@col}{\@dtl@dbname}{\@dtl@key}% \dtlgetentryfromrow{\@dtl@a}{\@dtl@col}{#1}% \dtlgetentryfromrow{\@dtl@b}{\@dtl@col}{#2}% \ifx\@dtl@a\dtlnovalue \@dtl@setnull{\@dtl@a}{\@dtl@key}% \fi \ifx\@dtl@b\dtlnovalue \@dtl@setnull{\@dtl@b}{\@dtl@key}% \fi \DTLifnull{\@dtl@a}% {% \@for\@dtl@keya:=\@dtl@replacementkeys\do{% \@sdtl@getcolumnindex{\@dtl@col}{\@dtl@dbname}{\@dtl@keya}% \dtlgetentryfromrow{\@dtl@a}{\@dtl@col}{#1}% \ifx\@dtl@a\dtlnovalue \@dtl@setnull{\@dtl@a}{\@dtl@key}% \fi \DTLifnull{\@dtl@a}{}{\@endfortrue}% }% \ifx\@dtl@keya\@nnil \let\@dtl@keya\@dtl@key \@dtl@setnull{\@dtl@a}{\@dtl@key}% \fi }% {}% \DTLifnull{\@dtl@b}% {% \@for\@dtl@keyb:=\@dtl@replacementkeys\do{% \@sdtl@getcolumnindex{\@dtl@col}{\@dtl@dbname}{\@dtl@keyb}% \dtlgetentryfromrow{\@dtl@b}{\@dtl@col}{#2}% \ifx\@dtl@b\dtlnovalue \@dtl@setnull{\@dtl@b}{\@dtl@key}% \fi \DTLifnull{\@dtl@b}{}{\@endfortrue}% }% \ifx\@dtl@keyb\@nnil \let\@dtl@keyb\@dtl@key \@dtl@setnull{\@dtl@b}{\@dtl@key}% \fi }% {}% \@dtl@toksA=\expandafter{\@dtl@a}% \@dtl@toksB=\expandafter{\@dtl@b}% \edef\@dtl@docompare{\noexpand\dtl@compare@ {\@dtl@keya}{\@dtl@keyb}% {\noexpand\@dtl@toksA}{\noexpand\@dtl@toksB}}% \@dtl@docompare \ifnum\dtl@sortresult=0\relax \@endforfalse \else \@endfortrue \fi }% \multiply\dtl@sortresult by -\@dtl@sortdirection\relax } \def\@dtl@getsortdirection#1=#2\relax{% \def\@dtl@key{#1}% \def\@dtl@sortdirection{#2}% \ifx\@dtl@sortdirection\@empty \def\@dtl@sortdirection{-1}% \else \@dtl@get@sortdirection#2% \def\@dtl@dir{ascending}% \ifx\@dtl@sortdirection\@dtl@dir \def\@dtl@sortdirection{-1}% \else \def\@dtl@dir{descending}% \ifx\@dtl@sortdirection\@dtl@dir \def\@dtl@sortdirection{1}% \else \PackageError{datatool}{Invalid sort direction `\@dtl@sortdirection'}{The sort direction can only be one of `ascending' or `descending'}% \def\@dtl@sortdirection{-1} \fi \fi \fi } \def\@dtl@get@sortdirection#1={\def\@dtl@sortdirection{#1}} \newtoks\@dtl@toksA \newtoks\@dtl@toksB \newtoks\@dtl@toks \newcommand{\dtl@compare}[3]{% \dtl@compare@{#1}{#1}{#2}{#3}% } \newcommand{\dtl@compare@}[4]{% \DTLgetdatatype{\@dtl@typeA}{\@dtl@dbname}{#1}% \ifx\@dtl@typeA\DTLunsettype \let\@dtl@typeA\DTLstringtype \fi \DTLgetdatatype{\@dtl@typeB}{\@dtl@dbname}{#2}% \ifx\@dtl@typeB\DTLunsettype \let\@dtl@typeB\DTLstringtype \fi \@dtl@tmpcount=\@dtl@typeA\relax \multiply\@dtl@tmpcount by \@dtl@typeB\relax \ifnum\@dtl@tmpcount=0\relax \edef\@dtl@tmpcmp{% \noexpand\@dtl@comparecs{\noexpand\dtl@sortresult}% {\the#3}{\the#4}% }% \@dtl@tmpcmp \ifdtlverbose \edef\@dtl@a{\the#3}% \edef\@dtl@b{\the#4}% \fi \else \edef\@dtl@a{\the#3}% \edef\@dtl@b{\the#4}% \DTLifnumlt{\@dtl@a}{\@dtl@b}% {% \dtl@sortresult=-1\relax }% {% \DTLifnumgt{\@dtl@a}{\@dtl@b}% {% \dtl@sortresult=1\relax }% {% \dtl@sortresult=0\relax }% }% \fi \ifdtlverbose \@onelevel@sanitize\@dtl@a \@onelevel@sanitize\@dtl@b \dtl@message{`\@dtl@a' <=> `\@dtl@b' = \number\dtl@sortresult}% \fi } \newcommand*{\dtl@choplast}[3]{% \let#2\@empty \let#3\@empty \@for\@dtl@element:=#1\do{% \ifx#3\@empty \else \ifx#2\@empty \expandafter\toks@\expandafter{#3}% \edef#2{{\the\toks@}}% \else \expandafter\toks@\expandafter{#3}% \expandafter\@dtl@toks\expandafter{#2}% \edef#2{\the\@dtl@toks,{\the\toks@}}% \fi \fi \let#3=\@dtl@element% }% } \newcommand*{\dtl@chopfirst}[3]{% \let#2=\@empty \let#3=\@empty \@for\@dtl@element:=#1\do{% \let#2=\@dtl@element \@endfortrue }% \if@endfor \let#3=\@forremainder \fi \@endforfalse } \newcommand{\dtl@sortlist}[2]{% \def\@dtl@sortedlist{}% \@for\@dtl@currentrow:=#1\do{% \expandafter\dtl@insertinto\expandafter {\@dtl@currentrow}{\@dtl@sortedlist}{#2}% \@endforfalse}% \let#1=\@dtl@sortedlist } \newcommand{\dtl@insertinto}[3]{% \def\@dtl@newsortedlist{}% \@dtl@insertdonefalse \@for\dtl@srtelement:=#2\do{% \if@dtl@insertdone \expandafter\toks@\expandafter{\dtl@srtelement}% \edef\@dtl@newstuff{{\the\toks@}}% \else \expandafter#3\expandafter{\dtl@srtelement}{#1}% \ifnum\dtl@sortresult<0\relax \expandafter\toks@\expandafter{\dtl@srtelement}% \@dtl@toks{#1}% \edef\@dtl@newstuff{{\the\@dtl@toks},{\the\toks@}}% \@dtl@insertdonetrue \else \expandafter\toks@\expandafter{\dtl@srtelement}% \edef\@dtl@newstuff{{\the\toks@}}% \fi \fi \ifx\@dtl@newsortedlist\@empty \expandafter\toks@\expandafter{\@dtl@newstuff}% \edef\@dtl@newsortedlist{\the\toks@}% \else \expandafter\toks@\expandafter{\@dtl@newsortedlist}% \expandafter\@dtl@toks\expandafter{\@dtl@newstuff}% \edef\@dtl@newsortedlist{\the\toks@,\the\@dtl@toks}% \fi \@endforfalse }% \ifx\@dtl@newsortedlist\@empty \@dtl@toks{#1}% \edef\@dtl@newsortedlist{{\the\@dtl@toks}}% \else \if@dtl@insertdone \else \expandafter\toks@\expandafter{\@dtl@newsortedlist}% \@dtl@toks{#1}% \edef\@dtl@newsortedlist{\the\toks@,{\the\@dtl@toks}}% \fi \fi \global\let#2=\@dtl@newsortedlist } \newif\if@dtl@insertdone \newcount\dtl@sortresult \newcommand{\toks@gput@right@cx}[2]{% \def\@toks@name{#1}% \edef\@dtl@stuff{#2}% \global\csname\@toks@name\endcsname\expandafter \expandafter\expandafter{\expandafter\the \csname\expandafter\@toks@name\expandafter\endcsname\@dtl@stuff}% } \newcommand{\toks@gconcat@middle@cx}[4]{% \def\@toks@name{#1}% \edef\@dtl@stuff{#3}% \global\csname\@toks@name\endcsname\expandafter\expandafter \expandafter\expandafter\expandafter \expandafter\expandafter{\expandafter\expandafter\expandafter \the\expandafter\expandafter\expandafter#2% \expandafter\@dtl@stuff\the#4}% } \newcommand*{\DTLadd}[3]{% \DTLconverttodecimal{#2}{\@dtl@numi}% \DTLconverttodecimal{#3}{\@dtl@numii}% \FPadd{\@dtl@tmp}{\@dtl@numi}{\@dtl@numii}% \ifx\@dtl@replaced\@empty \DTLdecimaltolocale{\@dtl@tmp}{#1}% \else \DTLdecimaltocurrency{\@dtl@tmp}{#1}% \fi } \newcommand*{\DTLgadd}[3]{% \DTLadd{\@dtl@tmpii}{#2}{#3}% \global\let#1=\@dtl@tmpii } \newcommand*{\DTLaddall}[2]{% \def\@dtl@sum{0}% \@for\dtl@thisval:=#2\do{% \DTLconverttodecimal{\dtl@thisval}{\@dtl@num}% \FPadd{\@dtl@sum}{\@dtl@sum}{\@dtl@num}% }% \ifx\@dtl@replaced\@empty \DTLdecimaltolocale{\@dtl@sum}{#1}% \else \DTLdecimaltocurrency{\@dtl@sum}{#1}% \fi } \newcommand*{\DTLgaddall}[2]{% \DTLaddall{\@dtl@tmpi}{#2}% \global\let#1=\@dtl@tmpi } \newcommand*{\DTLsub}[3]{% \DTLconverttodecimal{#2}{\@dtl@numi}% \DTLconverttodecimal{#3}{\@dtl@numii}% \FPsub{\@dtl@tmp}{\@dtl@numi}{\@dtl@numii}% \ifx\@dtl@replaced\@empty \DTLdecimaltolocale{\@dtl@tmp}{#1}% \else \DTLdecimaltocurrency{\@dtl@tmp}{#1}% \fi } \newcommand*{\DTLgsub}[3]{% \DTLsub{\@dtl@tmpii}{#2}{#3}% \global\let#1=\@dtl@tmpii } \newcommand*{\DTLmul}[3]{% \let\@dtl@thisreplaced=\@empty \DTLconverttodecimal{#2}{\@dtl@numi}% \ifx\@dtl@replaced\@empty \else \let\@dtl@thisreplaced=\@dtl@replaced \fi \DTLconverttodecimal{#3}{\@dtl@numii}% \ifx\@dtl@replaced\@empty \else \let\@dtl@thisreplaced=\@dtl@replaced \fi \FPmul{\@dtl@tmp}{\@dtl@numi}{\@dtl@numii}% \ifx\@dtl@thisreplaced\@empty \DTLdecimaltolocale{\@dtl@tmp}{#1}% \else \DTLdecimaltocurrency{\@dtl@tmp}{#1}% \fi } \newcommand*{\DTLgmul}[3]{% \DTLmul{\@dtl@tmpii}{#2}{#3}% \global\let#1=\@dtl@tmpii } \newcommand*{\DTLdiv}[3]{% \let\@dtl@thisreplaced=\@empty \DTLconverttodecimal{#2}{\@dtl@numi}% \ifx\@dtl@replaced\@empty \else \let\@dtl@thisreplaced=\@dtl@replaced \fi \DTLconverttodecimal{#3}{\@dtl@numii}% \FPdiv{\@dtl@tmp}{\@dtl@numi}{\@dtl@numii}% \ifx\@dtl@thisreplaced\@empty \DTLdecimaltolocale{\@dtl@tmp}{#1}% \else \ifx\@dtl@thisreplaced\@dtl@replaced \DTLdecimaltolocale{\@dtl@tmp}{#1}% \else \DTLdecimaltocurrency{\@dtl@tmp}{#1}% \fi \fi } \newcommand*{\DTLgdiv}[3]{% \DTLdiv{\@dtl@tmpii}{#2}{#3}% \global\let#1=\@dtl@tmpii } \newcommand*{\DTLabs}[2]{% \DTLconverttodecimal{#2}{\@dtl@numi}% \FPabs{\@dtl@tmp}{\@dtl@numi}% \ifx\@dtl@replaced\@empty \DTLdecimaltolocale{\@dtl@tmp}{#1}% \else \DTLdecimaltocurrency{\@dtl@tmp}{#1}% \fi } \newcommand*{\DTLgabs}[2]{% \DTLabs{\@dtl@tmpii}{#2}% \global\let#1=\@dtl@tmpii } \newcommand*{\DTLneg}[2]{% \DTLconverttodecimal{#2}{\@dtl@numi}% \FPneg{\@dtl@tmp}{\@dtl@numi}% \ifx\@dtl@replaced\@empty \DTLdecimaltolocale{\@dtl@tmp}{#1}% \else \DTLdecimaltocurrency{\@dtl@tmp}{#1}% \fi } \newcommand*{\DTLgneg}[2]{% \DTLneg{\@dtl@tmpii}{#2}% \global\let#1=\@dtl@tmpii } \newcommand*{\DTLsqrt}[2]{% \DTLconverttodecimal{#2}{\@dtl@numi}% \FProot{\@dtl@tmpi}{\@dtl@numi}{2}% \ifx\@dtl@replaced\@empty \DTLdecimaltolocale{\@dtl@tmpi}{#1}% \else \DTLdecimaltocurrency{\@dtl@tmpi}{#1}% \fi } \newcommand*{\DTLgsqrt}[2]{% \DTLsqrt{\@dtl@tmpii}{#2}% \global\let#1=\@dtl@tmpii } \newcommand*{\DTLmin}[3]{% \DTLconverttodecimal{#2}{\@dtl@numi}% \DTLconverttodecimal{#3}{\@dtl@numii}% \FPiflt{\@dtl@numi}{\@dtl@numii}% \dtl@ifsingle{#2}{% \let#1=#2}{% \def#1{#2}}% \else \dtl@ifsingle{#3}{% \let#1=#3}{% \def#1{#3}}% \fi } \newcommand*{\DTLgmin}[3]{% \DTLmin{\@dtl@tmpii}{#2}{#3}% \global\let#1=\@dtl@tmpii } \newcommand*{\DTLminall}[2]{% \let\@dtl@min=\@empty \@for\dtl@thisval:=#2\do{% \DTLconverttodecimal{\dtl@thisval}{\@dtl@num}% \ifx\@dtl@min\@empty \let\@dtl@min=\@dtl@num \else \FPmin{\@dtl@min}{\@dtl@min}{\@dtl@num}% \fi }% \ifx\@dtl@replaced\@empty \DTLdecimaltolocale{\@dtl@min}{#1}% \else \DTLdecimaltocurrency{\@dtl@min}{#1}% \fi } \newcommand*{\DTLgminall}[2]{% \DTLminall{\@dtl@tmpi}{#2}% \global\let#1=\@dtl@tmpi } \newcommand*{\DTLmax}[3]{% \DTLconverttodecimal{#2}{\@dtl@numi}% \DTLconverttodecimal{#3}{\@dtl@numii}% \FPmax{\@dtl@tmp}{\@dtl@numi}{\@dtl@numii}% \FPifgt{\@dtl@numi}{\@dtl@numii}% \dtl@ifsingle{#2}{% \let#1=#2}{% \def#1{#2}}% \else \dtl@ifsingle{#3}{% \let#1=#3}{% \def#1{#3}}% \fi } \newcommand*{\DTLgmax}[3]{% \DTLmax{\@dtl@tmpii}{#2}{#3}% \global\let#1=\@dtl@tmpii } \newcommand*{\DTLmaxall}[2]{% \let\@dtl@max=\@empty \@for\dtl@thisval:=#2\do{% \DTLconverttodecimal{\dtl@thisval}{\@dtl@num}% \ifx\@dtl@max\@empty \let\@dtl@max\@dtl@num \else \FPmax{\@dtl@max}{\@dtl@max}{\@dtl@num}% \fi }% \ifx\@dtl@replaced\@empty \DTLdecimaltolocale{\@dtl@max}{#1}% \else \DTLdecimaltocurrency{\@dtl@max}{#1}% \fi } \newcommand*{\DTLgmaxall}[2]{% \DTLmaxall{\@dtl@tmpi}{#2}% \global\let#1=\@dtl@tmpi } \newcommand*{\DTLmeanforall}[2]{% \def\@dtl@mean{0}% \def\@dtl@n{0}% \@for\dtl@thisval:=#2\do{% \DTLconverttodecimal{\dtl@thisval}{\@dtl@num}% \FPadd{\@dtl@mean}{\@dtl@mean}{\@dtl@num}% \FPadd{\@dtl@n}{\@dtl@n}{1}% }% \FPdiv{\@dtl@mean}{\@dtl@mean}{\@dtl@n}% \ifx\@dtl@replaced\@empty \DTLdecimaltolocale{\@dtl@mean}{#1}% \else \DTLdecimaltocurrency{\@dtl@mean}{#1}% \fi } \newcommand*{\DTLgmeanforall}[2]{% \DTLmeanforall{\@dtl@tmpi}{#2}% \global\let#1=\@dtl@tmpi } \newcommand*{\DTLvarianceforall}[2]{% \def\@dtl@mean{0}% \def\@dtl@n{0}% \let\@dtl@decvals=\@empty \@for\dtl@thisval:=#2\do{% \DTLconverttodecimal{\dtl@thisval}{\@dtl@num}% \ifx\@dtl@decvals\@empty \let\@dtl@decvals=\@dtl@num \else \expandafter\toks@\expandafter{\@dtl@decvals}% \edef\@dtl@decvals{\the\toks@,\@dtl@num}% \fi \FPadd{\@dtl@mean}{\@dtl@mean}{\@dtl@num}% \FPadd{\@dtl@n}{\@dtl@n}{1}% }% \FPdiv{\@dtl@mean}{\@dtl@mean}{\@dtl@n}% \def\@dtl@var{0}% \@for\@dtl@num:=\@dtl@decvals\do{% \FPsub{\@dtl@diff}{\@dtl@num}{\@dtl@mean}% \FPmul{\@dtl@diff}{\@dtl@diff}{\@dtl@diff}% \FPadd{\@dtl@var}{\@dtl@var}{\@dtl@diff}% }% \FPdiv{\@dtl@var}{\@dtl@var}{\@dtl@n}% \ifx\@dtl@replaced\@empty \DTLdecimaltolocale{\@dtl@var}{#1}% \else \DTLdecimaltocurrency{\@dtl@var}{#1}% \fi } \newcommand*{\DTLgvarianceforall}[2]{% \DTLvarianceforall{\@dtl@tmpi}{#2}% \global\let#1=\@dtl@tmpi } \newcommand*{\DTLsdforall}[2]{% \def\@dtl@mean{0}% \def\@dtl@n{0}% \let\@dtl@decvals=\@empty \@for\dtl@thisval:=#2\do{% \DTLconverttodecimal{\dtl@thisval}{\@dtl@num}% \ifx\@dtl@decvals\@empty \let\@dtl@decvals=\@dtl@num \else \expandafter\toks@\expandafter{\@dtl@decvals}% \edef\@dtl@decvals{\the\toks@,\@dtl@num}% \fi \FPadd{\@dtl@mean}{\@dtl@mean}{\@dtl@num}% \FPadd{\@dtl@n}{\@dtl@n}{1}% }% \FPdiv{\@dtl@mean}{\@dtl@mean}{\@dtl@n}% \def\@dtl@sd{0}% \@for\@dtl@num:=\@dtl@decvals\do{% \FPsub{\@dtl@diff}{\@dtl@num}{\@dtl@mean}% \FPmul{\@dtl@diff}{\@dtl@diff}{\@dtl@diff}% \FPadd{\@dtl@sd}{\@dtl@sd}{\@dtl@diff}% }% \FPdiv{\@dtl@sd}{\@dtl@sd}{\@dtl@n}% \FProot{\@dtl@sd}{\@dtl@sd}{2}% \ifx\@dtl@replaced\@empty \DTLdecimaltolocale{\@dtl@sd}{#1}% \else \DTLdecimaltocurrency{\@dtl@sd}{#1}% \fi } \newcommand*{\DTLgsdforall}[2]{% \DTLsdforall{\@dtl@tmpi}{#2}% \global\let#1=\@dtl@tmpi } \newcommand*{\DTLround}[3]{% \DTLconverttodecimal{#2}{\@dtl@numi}% \FPround{\@dtl@tmp}{\@dtl@numi}{#3}% \ifx\@dtl@replaced\@empty \DTLdecimaltolocale{\@dtl@tmp}{#1}% \else \DTLdecimaltocurrency{\@dtl@tmp}{#1}% \fi } \newcommand*{\DTLground}[3]{% \DTLround{\@dtl@tmpii}{#2}{#3}% \global\let#1=\@dtl@tmpii } \newcommand*{\DTLtrunc}[3]{% \DTLconverttodecimal{#2}{\@dtl@numi}% \FPtrunc{\@dtl@tmp}{\@dtl@numi}{#3}% \ifx\@dtl@replaced\@empty \DTLdecimaltolocale{\@dtl@tmp}{#1}% \else \DTLdecimaltocurrency{\@dtl@tmp}{#1}% \fi } \newcommand*{\DTLgtrunc}[3]{% \DTLtrunc{\@dtl@tmpii}{#2}{#3}% \global\let#1=\@dtl@tmpii } \newcommand*{\DTLclip}[2]{% \DTLconverttodecimal{#2}{\@dtl@numi}% \FPclip{\@dtl@tmp}{\@dtl@numi}% \ifx\@dtl@replaced\@empty \DTLdecimaltolocale{\@dtl@tmp}{#1}% \else \DTLdecimaltocurrency{\@dtl@tmp}{#1}% \fi } \newcommand*{\DTLgclip}[3]{% \DTLclip{\@dtl@tmpii}{#2}% \global\let#1=\@dtl@tmpii } \newcommand*\DTLinitials[1]{% \def\dtl@initialscmd{}% \dtl@subnobrsp{#1}{\dtl@string}% \DTLsubstituteall{\dtl@string}{~}{ }% \DTLsubstituteall{\dtl@string}{\ }{ }% \DTLsubstituteall{\dtl@string}{\space}{ }% \expandafter\dtl@initials\dtl@string{} \@nil% \dtl@initialscmd}% \edef\dtl@construct@subnobrsp{% \noexpand\def\noexpand\@dtl@subnobrsp##1\noexpand\protect \expandafter\noexpand\csname nobreakspace \endcsname ##2{% \noexpand\toks@{##1}% \noexpand\expandafter\noexpand\@dtl@toks\noexpand\expandafter{% \noexpand\@dtl@string}% \noexpand\edef\noexpand\@dtl@string{\noexpand\the\noexpand\@dtl@toks \noexpand\the\noexpand\toks@}% \noexpand\def\noexpand\@dtl@tmp{##2}% \noexpand\ifx\noexpand\@dtl@tmp\noexpand\@nnil \noexpand\let\noexpand\@dtl@subnobrspnext=\noexpand\relax \noexpand\else \noexpand\toks@{ }% \noexpand\expandafter\noexpand\@dtl@toks\noexpand\expandafter{% \noexpand\@dtl@string}% \noexpand\edef\noexpand\@dtl@string{\noexpand\the\noexpand\@dtl@toks \noexpand\the\noexpand\toks@}% \noexpand\let\noexpand\@dtl@subnobrspnext=\noexpand\@dtl@subnobrsp \noexpand\fi \noexpand\@dtl@subnobrspnext }% \noexpand\def\noexpand\dtl@subnobrsp##1##2{% \noexpand\def\noexpand\@dtl@string{}% \noexpand\@dtl@subnobrsp ##1\noexpand\protect\expandafter\noexpand \csname nobreakspace \endcsname \noexpand\@nil \noexpand\let##2=\noexpand\@dtl@string }} \dtl@construct@subnobrsp \newcommand*{\DTLstoreinitials}[2]{% \def\dtl@initialscmd{}% \dtl@subnobrsp{#1}{\dtl@string}% \DTLsubstituteall{\dtl@string}{~}{ }% \DTLsubstituteall{\dtl@string}{\ }{ }% \DTLsubstituteall{\dtl@string}{\space}{ }% \expandafter\dtl@initials\dtl@string{} \@nil \let#2=\dtl@initialscmd } \def\dtl@initials#1#2 #3{% \dtl@ifsingle{#1}{% \ifcat\noexpand#1\relax\relax \def\@dtl@donextinitials{\@dtl@initials#2 {#3}}% \else \def\@dtl@donextinitials{\@dtl@initials#1#2 {#3}}% \fi }{% \def\@dtl@donextinitials{\@dtl@initials{#1}#2 {#3}}% }% \@dtl@donextinitials } \def\@dtl@initials#1#2 #3{% \dtl@initialshyphen#2-{}\dtl@endhyp \expandafter\@dtl@toks\expandafter{\dtl@initialscmd}% \toks@{#1}% \ifx\dtl@inithyphen\@empty \else \edef\dtl@initialscmd{\the\@dtl@toks\the\toks@}% \expandafter\@dtl@toks\expandafter{\dtl@initialscmd}% \expandafter\toks@\expandafter{\dtl@inithyphen}% \fi \def\dtl@tmp{#3}% \ifx\@nnil\dtl@tmp \edef\dtl@initialscmd{\the\@dtl@toks\the\toks@\DTLafterinitials}% \let\dtl@initialsnext=\@gobble \else \edef\dtl@initialscmd{\the\@dtl@toks\the\toks@\DTLbetweeninitials}% \let\dtl@initialsnext=\dtl@initials \fi \dtl@initialsnext{#3}} \def\dtl@initialshyphen#1-#2#3\dtl@endhyp{% \def\dtl@inithyphen{#2}% \ifx\dtl@inithyphen\@empty \else \edef\dtl@inithyphen{% \DTLafterinitialbeforehyphen\DTLinitialhyphen#2}% \fi } \newcommand*{\DTLafterinitials}{.} \newcommand*{\DTLbetweeninitials}{.} \newcommand*{\DTLafterinitialbeforehyphen}{.} \newcommand*{\DTLinitialhyphen}{-} \newcommand*{\DTLifAllUpperCase}[3]{% \protected@edef\dtl@tuc{#1}% \expandafter\dtl@testifuppercase\dtl@tuc\@nil\relax \if@dtl@condition#2\else#3\fi } \def\dtl@testifuppercase#1#2{% \def\dtl@argi{#1}% \def\dtl@argii{#2}% \def\dtl@tc@rest{}% \ifx\dtl@argi\@nnil \let\dtl@testifuppernext=\@nnil \else \ifx#1\protect \let\dtl@testifuppernext=\dtl@testifuppercase \else \ifx\uppercase#1\relax \@dtl@conditiontrue \def\dtl@tc@rest{}% \let\dtl@testifuppernext=\relax \else \edef\dtl@tc@arg{\string#1}% \expandafter\dtl@test@ifuppercase\dtl@tc@arg\end \ifx\dtl@argii\@nnil \let\dtl@testifuppernext=\@dtl@gobbletonil \fi \fi \fi \fi \ifx\dtl@testifuppernext\relax \edef\dtl@dotestifuppernext{% \noexpand\dtl@testifuppercase}% \else \ifx\dtl@testifuppernext\@nnil \edef\dtl@dotestifuppernext{#2}% \else \expandafter\toks@\expandafter{\dtl@tc@rest}% \@dtl@toks{#2}% \edef\dtl@dotestifuppernext{% \noexpand\dtl@testifuppernext\the\toks@\the\@dtl@toks}% \fi \fi \dtl@dotestifuppernext } \def\dtl@test@ifuppercase#1#2\end{% \def\dtl@tc@rest{#2}% \IfSubStringInString{\string\MakeUppercase}{#1#2}{% \@dtl@conditiontrue \def\dtl@tc@rest{}% \let\dtl@testifuppernext=\relax }{% \IfSubStringInString{\string\MakeTextUppercase}{#1#2}{% \@dtl@conditiontrue \def\dtl@tc@rest{}% \let\dtl@testifuppernext=\relax }{% \edef\dtl@uccode{\the\uccode`#1}% \edef\dtl@code{\number`#1}% \ifnum\dtl@code=\dtl@uccode\relax \@dtl@conditiontrue \let\dtl@testifuppernext=\dtl@testifuppercase \else \ifnum\dtl@uccode=0\relax \@dtl@conditiontrue \let\dtl@testifuppernext=\dtl@testifuppercase \else \@dtl@conditionfalse \let\dtl@testifuppernext=\@dtl@gobbletonil \fi \fi }}} \newcommand*{\DTLifAllLowerCase}[3]{% \protected@edef\dtl@tlc{#1}% \expandafter\dtl@testiflowercase\dtl@tlc\@nil\relax \if@dtl@condition#2\else#3\fi } \def\dtl@testiflowercase#1#2{% \def\dtl@argi{#1}% \def\dtl@argii{#2}% \ifx\dtl@argi\@nnil \let\dtl@testiflowernext=\@nnil \else \ifx#1\protect \let\dtl@testiflowernext=\dtl@testiflowercase \else \ifx\lowercase#1\relax \@dtl@conditiontrue \def\dtl@tc@rest{}% \let\dtl@testiflowernext=\relax \else \edef\dtl@tc@arg{\string#1}% \expandafter\dtl@test@iflowercase\dtl@tc@arg\end \ifx\dtl@argii\@nnil \let\dtl@testiflowernext=\@dtl@gobbletonil \fi \fi \fi \fi \ifx\dtl@testiflowernext\relax \edef\dtl@dotestiflowernext{% \noexpand\dtl@testiflowercase}% \else \ifx\dtl@testiflowernext\@nnil \edef\dtl@dotestiflowernext{#2}% \else \expandafter\toks@\expandafter{\dtl@tc@rest}% \@dtl@toks{#2}% \edef\dtl@dotestiflowernext{% \noexpand\dtl@testiflowernext\the\toks@\the\@dtl@toks}% \fi \fi \dtl@dotestiflowernext } \def\dtl@test@iflowercase#1#2\end{% \def\dtl@tc@rest{#2}% \IfSubStringInString{\string\MakeLowercase}{#1#2}{% \@dtl@conditiontrue \def\dtl@tc@rest{}% \let\dtl@testiflowernext=\relax }{% \IfSubStringInString{\string\MakeTextLowercase}{#1#2}{% \@dtl@conditiontrue \def\dtl@tc@rest{}% \let\dtl@testiflowernext=\relax }{% \edef\dtl@lccode{\the\lccode`#1}% \edef\dtl@code{\number`#1}% \ifnum\dtl@code=\dtl@lccode\relax \@dtl@conditiontrue \let\dtl@testiflowernext=\dtl@testiflowercase \else \ifnum\dtl@lccode=0\relax \@dtl@conditiontrue \let\dtl@testiflowernext=\dtl@testiflowercase \else \@dtl@conditionfalse \let\dtl@testiflowernext=\@dtl@gobbletonil \fi \fi }}} \newwrite\@dtl@write \newcommand*{\DTLsavedb}[2]{% \DTLifdbexists{#1}% {% \openout\@dtl@write \def\@dtl@header{}% \dtlforeachkey(\@dtl@key,\@dtl@col,\@dtl@type,\@dtl@head)% \in{#1}\do {% \IfSubStringInString{\@dtl@separator}{\@dtl@key}% {% \ifx\@dtl@header\@empty \protected@edef\@dtl@header{% \@dtl@delimiter\@dtl@key\@dtl@delimiter}% \else \toks@=\expandafter{\@dtl@header}% \protected@edef\@dtl@header{% \the\toks@\@dtl@separator \@dtl@delimiter\@dtl@key\@dtl@delimiter}% \fi }% {% \ifx\@dtl@header\@empty \protected@edef\@dtl@header{\@dtl@key}% \else \toks@=\expandafter{\@dtl@header}% \protected@edef\@dtl@header{\the\toks@ \@dtl@separator\@dtl@key}% \fi }% }% \protected@write\@dtl@write{}{\@dtl@header}% \@sDTLforeach{#1}{}% {% \def\@dtl@row{}% \DTLforeachkeyinrow{\@dtl@val}% {% \IfSubStringInString{\@dtl@separator}{\@dtl@val}% {% \ifx\@dtl@row\@empty \protected@edef\@dtl@row{% \@dtl@delimiter\@dtl@val\@dtl@delimiter}% \else \toks@=\expandafter{\@dtl@row}% \protected@edef\@dtl@row{\the\toks@\@dtl@separator \@dtl@delimiter\@dtl@val\@dtl@delimiter}% \fi }% {% \ifx\@dtl@row\@empty \protected@edef\@dtl@row{\@dtl@val}% \else \toks@=\expandafter{\@dtl@row}% \protected@edef\@dtl@row{\the\toks@\@dtl@separator \@dtl@val}% \fi }% \protected@write\@dtl@write{}{\@dtl@row}% }% }% \closeout\@dtl@write }% {% \PackageError{datatool}{Can't save database `#1': no such database}{}% }% } \newcommand*{\DTLsavetexdb}[2]{% \DTLifdbexists{#1}% {% \openout\@dtl@write=#2\relax \protected@write\@dtl@write{}{\string\DTLnewdb{#1}}% \@sDTLforeach{#1}{}% {% \protected@write\@dtl@write{}{\string\DTLnewrow*{#1}}% \DTLforeachkeyinrow{\@dtl@val}% {% \DTLifnull{\@dtl@val}% {\def\@dtl@val{}}% {}% \protected@write\@dtl@write{}{% \string\DTLnewdbentry*{#1}{\dtlkey}{\@dtl@val}}% }% }% \dtlforeachkey(\@dtl@k,\@dtl@c,\@dtl@t,\@dtl@h)\in{#1}\do {% \@onelevel@sanitize\@dtl@h \protected@write\@dtl@write{}{% \string\DTLsetheader*{#1}{\@dtl@k}{\@dtl@h}}% }% \closeout\@dtl@write }% {% \PackageError{datatool}{Can't save database `#1': no such database}{}% }% } \newcommand{\@longempty}{} \newread\@dtl@read \newcount\dtl@entrycr \define@boolkey{loaddb}[dtl]{noheader}[true]{} \define@key{loaddb}{keys}{% \dtl@entrycr=0\relax \@for\@dtl@key:=#1\do {% \advance\dtl@entrycr by 1\relax \expandafter \edef\csname @dtl@inky@\romannumeral\dtl@entrycr\endcsname{% \@dtl@key}% }% } \define@key{loaddb}{headers}{% \dtl@entrycr=0\relax \@for\@dtl@head:=#1\do {% \advance\dtl@entrycr by 1\relax \toks@=\expandafter{\@dtl@head}% \expandafter \edef\csname @dtl@inhd@\romannumeral\dtl@entrycr\endcsname{% \the\toks@}% }% } \newcommand*{\dtldefaultkey}{Column} \newcommand*{\@dtl@readline}[2]{% \read#1 to #2% \dtl@trim#2% } \newcommand*{\@dtl@readrawline}[2]{% \@dtl@rawread#1 to #2% \dtl@trim#2% \dtl@domappings\@dtl@line } \newcommand*{\DTLloaddb}{% \let\@dtl@doreadline\@dtl@readline \@dtlloaddb } \newcommand*{\@dtlloaddb}[3][]{% \IfFileExists{#3}{% \begingroup \catcode`\"12\relax \dtlnoheaderfalse \setkeys{loaddb}{#1}% \openin\@dtl@read=#3% \dtl@message{Reading `#3'}% \DTLnewdb{#2}% \ifeof\@dtl@read \PackageWarning{datatool}{File `#3' has no data}% \else \ifdtlnoheader \else \loop \@dtl@conditionfalse \ifeof\@dtl@read \else \@dtl@doreadline\@dtl@read\@dtl@line \ifx\@dtl@line\@longempty \@dtl@conditiontrue \fi \fi \if@dtl@condition \repeat \protected@edef\@dtl@lin@{% \@dtl@separator\@dtl@line\@dtl@separator}% \dtl@entrycr=0\relax \loop \expandafter\@dtl@lopoff\@dtl@lin@\to\@dtl@lin@\@dtl@key \advance\dtl@entrycr by 1\relax \expandafter\@dtl@toks\expandafter{\@dtl@key}% \@ifundefined{@dtl@inky@\romannumeral\dtl@entrycr}% {% \expandafter \edef\csname @dtl@inky@\romannumeral \dtl@entrycr\endcsname{\the\@dtl@toks}% }% {% \@ifundefined{@dtl@inhd@\romannumeral\dtl@entrycr}% {% \expandafter \edef\csname @dtl@inhd@\romannumeral \dtl@entrycr\endcsname{\the\@dtl@toks}% }% {}% }% \ifx\@dtl@lin@\@dtl@separator \@dtl@conditionfalse \else \@dtl@conditiontrue \fi \if@dtl@condition \repeat \fi \ifeof\@dtl@read \ifdtlnoheader \PackageWarning{datatool}{No data in `#3'}% \else \PackageWarning{datatool}{Only header row found in `#3'}% \fi \else \@dtl@conditiontrue \loop \@dtl@doreadline\@dtl@read\@dtl@line \ifx\@dtl@line\@longempty \else \@sDTLnewrow{#2}% \expandafter\@dtl@toks\expandafter{\@dtl@line}% \edef\@dtl@lin@{\@dtl@separator\the\@dtl@toks \@dtl@separator}% \dtl@entrycr=0\relax {% \@dtl@conditiontrue \loop \expandafter\@dtl@lopoff\@dtl@lin@\to \@dtl@lin@\@dtl@thisentry \advance\dtl@entrycr by 1\relax \@ifundefined{@dtl@inky@\romannumeral\dtl@entrycr}% {% \edef\@dtl@thiskey{\dtldefaultkey \number\dtl@entrycr}% \expandafter\let \csname @dtl@inky@\romannumeral \dtl@entrycr\endcsname\@dtl@thiskey }% {% \edef\@dtl@thiskey{% \csname @dtl@inky@\romannumeral \dtl@entrycr\endcsname}% }% \expandafter\@dtl@toks\expandafter{\@dtl@thisentry}% \edef\@do@dtlnewentry{\noexpand\@sDTLnewdbentry {#2}{\@dtl@thiskey}{\the\@dtl@toks}}% \@do@dtlnewentry \ifx\@dtl@lin@\@dtl@separator \@dtl@conditionfalse \fi \if@dtl@condition \repeat }% \fi \ifeof\@dtl@read \@dtl@conditionfalse\fi \if@dtl@condition \repeat \fi \fi \closein\@dtl@read \edef\@dtl@maxcols{\expandafter \number\csname dtlcols@#2\endcsname}% \dtlgforint\dtl@entrycr=1\to\@dtl@maxcols\step1\do {% \@ifundefined{@dtl@inhd@\romannumeral\dtl@entrycr}% {}% {% \expandafter\let\expandafter\@dtl@head \csname @dtl@inhd@\romannumeral\dtl@entrycr\endcsname \@dtl@toks=\expandafter{\@dtl@head}% \edef\@dtl@dosetheader{\noexpand\@dtl@setheaderforindex {#2}{\number\dtl@entrycr}{\the\@dtl@toks}}% \@dtl@dosetheader }% }% \endgroup }{% \PackageError{datatool}{Can't load database `#2' (file `#3' doesn't exist)}{}% }% } \newcommand{\dtl@trim}[1]{% \def\@dtl@trmstr{}% \expandafter\@dtl@starttrim#1\@nil% \let#1=\@dtl@trmstr } \long\def\@dtl@starttrim#1#2{% \ifx\par#1% \def\@dtl@dotrim{\@dtl@trim{} #2}% \else \def\@dtl@dotrim{\@dtl@trim#1#2}% \fi \@dtl@dotrim% } \long\def\@dtl@trim#1 \@nil{\long\def\@dtl@trmstr{#1}} \newcommand*\DTLloadrawdb{% \let\@dtl@doreadline\@dtl@readrawline \@dtlloaddb } \begingroup \catcode`\%=\active \catcode`$=\active \catcode`&=\active \catcode`~=\active \catcode`_=\active \catcode`^=\active \catcode`#=\active \catcode`?=6\relax \catcode`<=1\relax \catcode`>=2\relax \catcode`\{=\active \catcode`\}=\active \gdef\@dtl@rawread?1to?2<\relax <<\catcode`\%=\active \catcode`$=\active \catcode`&=\active \catcode`~=\active \catcode`_=\active \catcode`^=\active \catcode`#=\active \catcode`\{=\active \catcode`\}=\active \def%<\noexpand\%>\relax \def$<\noexpand\$>\relax \def&<\&>\relax \def#<\#>\relax \def~<\noexpand\textasciitilde>\relax \def_<\noexpand\_>\relax \def^<\noexpand\textasciicircum>\relax \@dtl@activatebraces \@dtl@doreadraw?1?2>>> \gdef\@dtl@doreadraw?1?2<\relax \read?1 to \tmp \xdef?2<\tmp>\relax > \endgroup \begingroup \catcode`\{=\active \catcode`\}=\active \catcode`<=1\relax \catcode`>=2\relax \gdef\@dtl@activatebraces<% \catcode`\{=\active \catcode`\}=\active \def{<\noexpand\{>% \def}<\noexpand\}>% >% \endgroup \newcommand*{\DTLrawmap}[2]{% \expandafter\@dtl@toks\expandafter{\@dtl@rawmappings}% \ifx\@dtl@rawmappings\@empty \def\@dtl@rawmappings{{#1}{#2}}% \else \def\@dtl@tmp{{#1}{#2}} \protected@edef\@dtl@rawmappings{\the\@dtl@toks,\@dtl@tmp} \fi } \newcommand*{\@dtl@rawmappings}{} \newcommand*{\dtl@domappings}[1]{% \@for\@dtl@map:=\@dtl@rawmappings\do{% \expandafter\DTLsubstitute\expandafter#1\@dtl@map }} \newcommand{\DTLsubstitute}[3]{% \expandafter\DTLsplitstring\expandafter {#1}{#2}{\@dtl@beforepart}{\@dtl@afterpart}% \ifx\@dtl@replaced\@empty \else \def#1{}% \expandafter\@dtl@toks\expandafter{\@dtl@beforepart}% \expandafter\toks@\expandafter{#1}% \protected@edef#1{\the\toks@\the\@dtl@toks#3}% \expandafter\@dtl@toks\expandafter{\@dtl@afterpart}% \expandafter\toks@\expandafter{#1}% \edef#1{\the\toks@\the\@dtl@toks}% \fi } \newcommand*{\DTLsplitstring}[4]{% \def\dtl@splitstr##1#2##2\@nil{% \def#3{##1}% \def#4{##2}% \ifx#4\@empty \let\@dtl@replaced=\@empty \else \def\@dtl@replaced{#2}% \dtl@split@str##2\@nil \fi }% \def\dtl@split@str##1#2\@nil{% \def#4{##1}}% \dtl@splitstr#1#2\@nil } \newcommand{\DTLsubstituteall}[3]{% \def\@dtl@splitsubstr{}% \let\@dtl@afterpart=#1\relax \@dtl@dosubstitute{#2}{#3}% \expandafter\toks@\expandafter{\@dtl@splitsubstr}% \expandafter\@dtl@toks\expandafter{\@dtl@afterpart}% \edef#1{\the\toks@\the\@dtl@toks}% } \def\@dtl@dosubstitute#1#2{% \expandafter\DTLsplitstring\expandafter {\@dtl@afterpart}{#1}{\@dtl@beforepart}{\@dtl@afterpart}% \expandafter\toks@\expandafter{\@dtl@splitsubstr}% \expandafter\@dtl@toks\expandafter{\@dtl@beforepart}% \edef\@dtl@splitsubstr{\the\toks@\the\@dtl@toks}% \ifx\@dtl@replaced\@empty \let\@dtl@dosubstnext=\@dtl@dosubstitutenoop \else \expandafter\toks@\expandafter{\@dtl@splitsubstr}% \@dtl@toks{#2}% \edef\@dtl@splitsubstr{\the\toks@\the\@dtl@toks}% \let\@dtl@dosubstnext=\@dtl@dosubstitute \fi \@dtl@dosubstnext{#1}{#2}% } \def\@dtl@dosubstitutenoop#1#2{} \newcommand*{\DTLifinlist}[4]{% \def\@dtl@doifinlist##1,#1,##2\end@dtl@doifinlist{% \def\@before{##1}% \def\@after{##2}% }% \expandafter\@dtl@doifinlist\expandafter,#2,#1,\@nil \end@dtl@doifinlist \ifx\@after\@nnil #4% \else #3% \fi } \newcommand*{\@dtl@currencies}{\$,\pounds} \newcommand*{\DTLnewcurrencysymbol}[1]{% \expandafter\toks@\expandafter{\@dtl@currencies}% \@dtl@toks{#1}% \edef\@dtl@currencies{\the\@dtl@toks,\the\toks@}% } \AtBeginDocument{% \@ifundefined{texteuro}{}{\DTLnewcurrencysymbol{\texteuro}}% \@ifundefined{textdollar}{}{\DTLnewcurrencysymbol{\textdollar}}% \@ifundefined{textstirling}{}{\DTLnewcurrencysymbol{\textstirling}}% \@ifundefined{textyen}{}{\DTLnewcurrencysymbol{\textyen}}% \@ifundefined{textwon}{}{\DTLnewcurrencysymbol{\textwon}}% \@ifundefined{textcurrency}{}{\DTLnewcurrencysymbol{\textcurrency}}% \@ifundefined{euro}{}{\DTLnewcurrencysymbol{\euro}}% \@ifundefined{yen}{}{\DTLnewcurrencysymbol{\yen}}% } \newcommand{\@dtl@standardize@currency}[1]{% \def\@dtl@org@currency{}% \@for\@dtl@thiscurrency:=\@dtl@currencies\do{% \expandafter\toks@\expandafter{\@dtl@thiscurrency}% \edef\@dtl@dosubs{\noexpand\DTLsubstitute{\noexpand#1}% {\the\toks@}{\noexpand\$}}% \@dtl@dosubs \ifx\@dtl@replaced\@empty \else \let\@dtl@org@currency=\@dtl@replaced \@endfortrue \fi }% \@endforfalse} \newcommand*{\@dtl@currency}{\$} \newcommand*{\DTLsetdefaultcurrency}[1]{% \renewcommand*{\@dtl@currency}{#1}} \newcommand{\dtl@ifsingle}[3]{% \def\@dtl@arg{#1}% \ifx\@dtl@arg\@empty #3% \else \@dtl@ifsingle#1\@nil{#2}{#3}% \fi } \def\@dtl@ifsingle#1#2\@nil#3#4{% \def\dtl@sg@arg{#2}% \ifx\dtl@sg@arg\@empty #3% \else #4% \fi } \newcommand*{\dtlshowdb}[1]{% \expandafter\showthe\csname dtldb@#1\endcsname} \newcommand*{\dtlshowdbkeys}[1]{% \expandafter\showthe\csname dtlkeys@#1\endcsname} \newcommand*{\dtlshowtype}[2]{% \DTLgetdatatype{\@dtl@type}{#1}{#2}\show\@dtl@type } \endinput %% %% End of file `datatool.sty'.