diff options
author | Karl Berry <karl@freefriends.org> | 2012-07-23 21:55:18 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2012-07-23 21:55:18 +0000 |
commit | d5ef93ccfdd8ddb5ee3d5a41434e0aec04df8fa0 (patch) | |
tree | 0bfa67f70ec53a66e165994e6bfc17b52ff92130 /Master | |
parent | 44928b3e4ed601cdf5afd19c5abb613fe3e8b4a0 (diff) |
datatool 2.10 (23jul12)
git-svn-id: svn://tug.org/texlive/trunk@27115 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
29 files changed, 20785 insertions, 19066 deletions
diff --git a/Master/texmf-dist/bibtex/bst/datatool/databib.bst b/Master/texmf-dist/bibtex/bst/datatool/databib.bst deleted file mode 100644 index 3f779b2f863..00000000000 --- a/Master/texmf-dist/bibtex/bst/datatool/databib.bst +++ /dev/null @@ -1,1277 +0,0 @@ -%% -%% This is file `databib.bst', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% datatool.dtx (with options: `databib.bst') -%% -%% 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, person.sty. -%% -%% load student information from file "students.csv" -%% Iterate through the student database: -%% Define "anon": -%% Do the letter: -%% Undefine "anon": - -ENTRY - { address - author - booktitle - chapter - edition - editor - howpublished - institution - journal - key - month - note - number - organization - pages - publisher - school - series - title - type - volume - year - isbn - doi - pubmed - url - abstract - file - } - {} - { label } - -INTEGERS { output.state before.all mid.sentence after.sentence after.block } - -FUNCTION {init.state.consts} -{ #0 'before.all := - #1 'mid.sentence := - #2 'after.sentence := - #3 'after.block := -} - -STRINGS { s t } - -FUNCTION {output.nonnull} -{ 's := - output.state before.all = - { - "%" * write$ - newline$ - } - { newline$ - %add.period$ " " * write$ - } - if$ - % if$ - % mid.sentence 'output.state := - % } - %if$ - s -} - -FUNCTION {output} -{ duplicate$ empty$ - 'pop$ - 'output.nonnull - if$ -} - -FUNCTION {output.check} -{ 't := - duplicate$ empty$ - { pop$ "empty " t * " in " * cite$ * warning$ } - { - output.nonnull - } - if$ -} - -FUNCTION {output.bibitem} -{ "\DTLnewbibrow" write$ - newline$ - "\DTLnewbibitem {CiteKey}{" write$ - cite$ write$ - "}%" write$ - newline$ - "" - before.all 'output.state := -} - -FUNCTION {fin.entry} -{ "%" * - write$ - newline$ -} - -FUNCTION {new.block} -{ output.state before.all = - 'skip$ - { after.block 'output.state := } - if$ -} - -FUNCTION {new.sentence} -{ output.state after.block = - 'skip$ - { output.state before.all = -'skip$ -{ after.sentence 'output.state := } - if$ - } - if$ -} - -FUNCTION {not} -{ { #0 } - { #1 } - if$ -} - -FUNCTION {and} -{ 'skip$ - { pop$ #0 } - if$ -} - -FUNCTION {or} -{ { pop$ #1 } - 'skip$ - if$ -} - -FUNCTION {new.block.checka} -{ empty$ - 'skip$ - 'new.block - if$ -} - -FUNCTION {new.block.checkb} -{ empty$ - swap$ empty$ - and - 'skip$ - 'new.block - if$ -} - -FUNCTION {new.sentence.checka} -{ empty$ - 'skip$ - 'new.sentence - if$ -} - -FUNCTION {new.sentence.checkb} -{ empty$ - swap$ empty$ - and - 'skip$ - 'new.sentence - if$ -} - -FUNCTION {field.or.null} -{ duplicate$ empty$ - { pop$ "" } - 'skip$ - if$ -} - -FUNCTION {emphasize} -{ duplicate$ empty$ - { pop$ "" } - { "{\em " swap$ * "}" * } - if$ -} - -FUNCTION {group} -{ duplicate$ empty$ - { pop$ "" } - { "{" swap$ * "}" * } - if$ -} - -INTEGERS { nameptr namesleft numnames } - -FUNCTION {format.names} -{ - 's := - #1 'nameptr := - s num.names$ 'numnames := - numnames 'namesleft := - { namesleft #0 > } - { - %s nameptr "{vv,}{ll,}{jj,}{ff}" format.name$ 't := - "{" * - s nameptr "{vv}" format.name$ 't := - t * "}" * - "{" * - s nameptr "{ll}" format.name$ 't := - t * "}{" * - s nameptr "{jj}" format.name$ 't := - t * "}" * - "{" * - s nameptr "{ff}" format.name$ 't := - t * "}" * - s nameptr "" format.name$ 't := - namesleft #1 > - { "," * } - { } - if$ - nameptr #1 > -{ - t * -} -'t - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ - "}" * -} - -FUNCTION {format.authors} -{ - author empty$ - { "" } - { author - "\DTLnewbibitem {Author}{" write$ - format.names } - if$ -} - -FUNCTION {format.editors} -{ editor empty$ - { "" } - { editor - "\DTLnewbibitem {Editor}{" write$ - format.names - } - if$ -} - -FUNCTION {format.title} -{ title empty$ - { "" } - { - "\DTLnewbibitem {Title}" - title "t" change.case$ group * - } - if$ -} - -FUNCTION {format.howpublished} -{ howpublished empty$ - { "" } - { - howpublished - "\DTLnewbibitem {HowPublished}" swap$ group * - } - if$ -} - -FUNCTION {format.organization} -{ organization empty$ - { "" } - { - organization - "\DTLnewbibitem {Organization}" swap$ group * - } - if$ -} - -FUNCTION {format.institution} -{ institution empty$ - { "" } - { - institution - "\DTLnewbibitem {Institution}" swap$ group * - } - if$ -} - -FUNCTION {format.key} -{ key empty$ - { "" } - { - key - "\DTLnewbibitem {Key}" swap$ group * - } - if$ -} - -FUNCTION {format.note} -{ note empty$ - { "" } - { - note - "\DTLnewbibitem {Note}" swap$ group * - } - if$ -} - -FUNCTION {format.isbn} -{ isbn empty$ - { "" } - { - isbn - "\DTLnewbibitem {ISBN}" swap$ group * - } - if$ -} - -FUNCTION {format.doi} -{ doi empty$ - { "" } - { - doi - "\DTLnewbibitem {DOI}" swap$ group * - } - if$ -} - -FUNCTION {format.pubmed} -{ pubmed empty$ - { "" } - { - pubmed - "\DTLnewbibitem {PubMed}" swap$ group * - } - if$ -} - -FUNCTION {format.abstract} -{ abstract empty$ - { "" } - { - abstract - "\DTLnewbibitem {Abstract}" swap$ group * - } - if$ -} - -FUNCTION {format.url} -{ url empty$ - { "" } - { - url - "\DTLnewbibitem {Url}" swap$ group * - } - if$ -} - -FUNCTION {format.file} -{ file empty$ - { "" } - { - file - "\DTLnewbibitem {File}" swap$ group * - } - if$ -} - -FUNCTION {format.address} -{ address empty$ - { "" } - { - address - "\DTLnewbibitem {Address}" swap$ group * - } - if$ -} - -FUNCTION {format.school} -{ school empty$ - { "" } - { - school - "\DTLnewbibitem {School}" swap$ group * - } - if$ -} - -FUNCTION {format.publisher} -{ publisher empty$ - { "" } - { - publisher - "\DTLnewbibitem {Publisher}" swap$ group * - } - if$ -} - -FUNCTION {n.dashify} -{ 't := - "" - { t empty$ not } - { t #1 #1 substring$ "-" = -{ t #1 #2 substring$ "--" = not - { "--" * - t #2 global.max$ substring$ 't := - } - { { t #1 #1 substring$ "-" = } -{ "-" * - t #2 global.max$ substring$ 't := -} - while$ - } - if$ -} -{ t #1 #1 substring$ * - t #2 global.max$ substring$ 't := -} - if$ - } - while$ -} - -FUNCTION {format.date} -{ year empty$ - { month empty$ -{ "" } -{ "there's a month but no year in " cite$ * warning$ - "\DTLnewbibitem {Month}" * - month group -} - if$ - } - { month empty$ -{ } -{ "\DTLnewbibitem {Month}{" * month * "}" * } - if$ - "\DTLnewbibitem {Year}{" * year * "}" - } - if$ -} - -FUNCTION {format.btitle} -{ title - "\DTLnewbibitem {Title}{" swap$ * - "}" * -} - -FUNCTION {tie.or.space.connect} -{ duplicate$ text.length$ #3 < - { "~" } - { " " } - if$ - swap$ * * -} - -FUNCTION {either.or.check} -{ empty$ - 'pop$ - { "can't use both " swap$ * " fields in " * cite$ * warning$ } - if$ -} - -FUNCTION {format.bvolume} -{ volume empty$ - { "" } - { - "\DTLnewbibitem {Volume}{" volume * "}" * - series empty$ -'skip$ -{ - "\DTLnewbibitem {Series}" * series group * - } - if$ - "volume and number" number either.or.check - } - if$ -} - -FUNCTION {format.number.series} -{ volume empty$ - { number empty$ -{ - %series field.or.null group - series empty$ - { "" } - { "\DTLnewbibitem {Series}" * series group } - if$ - } -{ - "\DTLnewbibitem {Number}" number group * - series empty$ - { "there's a number but no series in " cite$ * warning$ } - { "\DTLnewbibitem {Series}{" * series * "}" * } - if$ -} - if$ - } - { "" } - if$ -} - -FUNCTION {format.edition} -{ edition empty$ - { "" } - { - "\DTLnewbibitem {Edition}" - edition "l" change.case$ group * - } - if$ -} - -INTEGERS { multiresult } - -FUNCTION {multi.page.check} -{ 't := - #0 'multiresult := - { multiresult not - t empty$ not - and - } - { t #1 #1 substring$ - duplicate$ "-" = - swap$ duplicate$ "," = - swap$ "+" = - or or -{ #1 'multiresult := } -{ t #2 global.max$ substring$ 't := } - if$ - } - while$ - multiresult -} - -FUNCTION {format.pages} -{ pages empty$ - { "" } - { pages multi.page.check -{ "\DTLnewbibitem {Pages}" pages n.dashify - group * } -{ "\DTLnewbibitem {Pages}" pages - group *} - if$ - } - if$ -} - -FUNCTION {format.vol.num.pages} -{ - volume empty$ - { "" } - { - "\DTLnewbibitem {Volume}{" volume * "}" * - } - if$ - number empty$ - 'skip$ - { "\DTLnewbibitem {Number}{" number * "}\relax " * * - volume empty$ -{ "there's a number but no volume in " cite$ * warning$ } -'skip$ - if$ - } - if$ - pages empty$ - 'skip$ - { duplicate$ empty$ -{ pop$ format.pages } -{ "\DTLnewbibitem {Pages}" * pages n.dashify group * } - if$ - } - if$ -} - -FUNCTION {format.chapter.pages} -{ chapter empty$ - 'format.pages - { type empty$ -{ "\DTLnewbibitem {Type}{chapter}" } -{ "\DTLnewbibitem {Type}" type "l" change.case$ group *} - if$ - "\DTLnewbibitem {Chapter}{" * chapter * "}" * - pages empty$ -'skip$ -{ format.pages * } - if$ - } - if$ -} - -FUNCTION {format.in.ed.booktitle} -{ booktitle empty$ - { "" } - { - "\DTLnewbibitem {BookTitle}" booktitle group * - editor empty$ - {} - { - "\DTLnewbibitem {Editor}{" * - editor format.names * - } - if$ - } - if$ -} - -FUNCTION {empty.misc.check} -{ author empty$ title empty$ howpublished empty$ - month empty$ year empty$ note empty$ - and and and and and - { "all relevant fields are empty in " cite$ * warning$ } - 'skip$ - if$ -} - -FUNCTION {format.thesis.type} -{ type empty$ - 'skip$ - { pop$ - type "t" change.case$ - "\DTLnewbibitem {Type}" swap$ group * - } - if$ -} - -FUNCTION {format.tr.number} -{ - type empty$ - { "\techreportname " } - 'type - if$ - number empty$ - { "t" change.case$ "\DTLnewbibitem {Type}" swap$ group *} - { "\DTLnewbibitem {Type}" swap$ group * - "\DTLnewbibitem {Number}" * - number group * } - if$ -} - -FUNCTION {format.article.crossref} -{ key empty$ - { journal empty$ -{ "need key or journal for " cite$ * " to crossref " * crossref * - warning$ - "" -} -{ - "\DTLnewbibitem {Journal}" journal group * - } - if$ - } - { - "" - } - if$ - "\DTLnewbibitem {CrossRef}{" * crossref * "}" * -} - -FUNCTION {format.crossref.editor} -{ format.editors -} - -FUNCTION {format.book.crossref} -{ volume empty$ - { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ - } - { - "\DTLnewbibitem {Volume}" - volume group * - } - if$ - editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ -{ series empty$ - { "need editor, key, or series for " cite$ * " to crossref " * - crossref * warning$ - "" * - } - { - "\DTLnewbibitem {Series}{" * series * - "}" * - } - if$ -} -{ "" - } - if$ - } - { - format.crossref.editor * - } - if$ - "\DTLnewbibitem {CrossRef}{" * crossref * "}" * -} - -FUNCTION {format.incoll.inproc.crossref} -{ editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ -{ booktitle empty$ - { "need editor, key, or booktitle for " cite$ * " to crossref " * - crossref * warning$ - "" - } - { "\DTLnewbibitem {BookTitle}{" booktitle * "}" * } - if$ -} -{ "" } - if$ - } - { - "\DTLnewbibitem {Editor}{" * - editor format.names - } - if$ - "\DTLnewbibitem {CrossRef}{" * crossref * "}" * -} - -FUNCTION {article} -{ output.bibitem - "\DTLnewbibitem {EntryType}{article}%" write$ - newline$ - format.authors "author" - output.check - format.title "title" output.check - new.block - crossref missing$ - { - "\DTLnewbibitem {Journal}" * - journal group "journal" output.check - format.vol.num.pages output - format.date "year" output.check - } - { format.article.crossref output.nonnull - format.pages output - } - if$ - new.block - format.key output - format.note output - format.isbn output - format.doi output - format.pubmed output - format.url output - format.abstract output - format.file output - fin.entry -} - -FUNCTION {book} -{ output.bibitem - "\DTLnewbibitem {EntryType}{book}%" write$ - newline$ - author empty$ - { format.editors "author and editor" output.check } - { format.authors output.nonnull - crossref missing$ -{ "author and editor" editor either.or.check - } -'skip$ - if$ - } - if$ - new.block - format.btitle "title" output.check - crossref missing$ - { format.bvolume output - new.block - format.number.series output - %new.sentence - format.publisher "publisher" output.check - format.address output - } - { new.block - format.book.crossref output.nonnull - } - if$ - format.edition output - format.date "year" output.check - new.block - format.key output - format.note output - format.isbn output - format.doi output - format.pubmed output - format.url output - format.abstract output - format.file output - fin.entry -} - -FUNCTION {booklet} -{ output.bibitem - "\DTLnewbibitem {EntryType}{booklet}%" write$ - newline$ - format.authors output - new.block - format.title "title" output.check - howpublished address new.block.checkb - format.howpublished output - format.address output - format.date output - new.block - format.key output - format.note output - format.isbn output - format.doi output - format.pubmed output - format.url output - format.abstract output - format.file output - fin.entry -} - -FUNCTION {inbook} -{ output.bibitem - "\DTLnewbibitem {EntryType}{inbook}%" write$ - newline$ - author empty$ - { format.editors "author and editor" output.check } - { format.authors output.nonnull - crossref missing$ -{ "author and editor" editor either.or.check } -'skip$ - if$ - } - if$ - new.block - format.btitle "title" output.check - crossref missing$ - { format.bvolume output - format.chapter.pages "chapter and pages" output.check - new.block - format.number.series output - new.sentence - format.publisher "publisher" output.check - format.address output - } - { format.chapter.pages "chapter and pages" output.check - new.block - format.book.crossref output.nonnull - } - if$ - format.edition output - format.date "year" output.check - new.block - format.key output - format.note output - format.isbn output - format.doi output - format.pubmed output - format.url output - format.abstract output - format.file output - fin.entry -} - -FUNCTION {incollection} -{ output.bibitem - "\DTLnewbibitem {EntryType}{incollection}%" write$ - newline$ - format.authors "author" output.check - format.title "title" output.check - crossref missing$ - { format.in.ed.booktitle "booktitle" output.check - format.bvolume output - format.number.series output - format.chapter.pages output - new.sentence - format.publisher "publisher" output.check - format.address output - format.edition output - format.date "year" output.check - } - { format.incoll.inproc.crossref output.nonnull - format.chapter.pages output - } - if$ - format.key output - format.note output - format.isbn output - format.doi output - format.pubmed output - format.url output - format.abstract output - format.file output - fin.entry -} - -FUNCTION {inproceedings} -{ output.bibitem - "\DTLnewbibitem {EntryType}{inproceedings}%" write$ - newline$ - format.authors "author" output.check - format.title "title" output.check - crossref missing$ - { format.in.ed.booktitle "booktitle" output.check - format.bvolume output - format.number.series output - format.pages output - address empty$ -{ %organization publisher new.sentence.checkb - format.organization write$ - format.publisher output -} -{ format.address write$ - new.sentence - format.organization output - format.publisher output -} - if$ - format.date "year" output.check - } - { - format.incoll.inproc.crossref output.nonnull - format.pages output - } - if$ - format.key output - format.note output - format.isbn output - format.doi output - format.pubmed output - format.url output - format.abstract output - format.file output - fin.entry -} - -FUNCTION {conference} { inproceedings } - -FUNCTION {manual} -{ output.bibitem - "\DTLnewbibitem {EntryType}{manual}%" write$ - newline$ - author empty$ - { organization empty$ -'skip$ -{ format.organization output - format.address output -} - if$ - } - { format.authors output } - if$ - new.block - format.btitle "title" output.check - author empty$ - { organization empty$ -{ address new.block.checka - address output -} -'skip$ - if$ - } - { %organization address new.block.checkb - format.organization output - format.address output - } - if$ - format.edition output - format.date output - new.block - format.key output - format.note output - format.isbn output - format.doi output - format.pubmed output - format.url output - format.abstract output - format.file output - fin.entry -} - -FUNCTION {mastersthesis} -{ output.bibitem - "\DTLnewbibitem {EntryType}{mastersthesis}%" write$ - newline$ - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - "\DTLnewbibitem {Type}{\mscthesisname }" - format.thesis.type output.nonnull - format.school "school" output.check - format.address output - format.date "year" output.check - new.block - format.key output - format.note output - format.isbn output - format.doi output - format.pubmed output - format.url output - format.abstract output - format.file output - fin.entry -} - -FUNCTION {misc} -{ output.bibitem - "\DTLnewbibitem {EntryType}{misc}%" write$ - newline$ - format.authors output - title howpublished new.block.checkb - format.title output - %howpublished new.block.checka - format.howpublished output - format.date output - new.block - format.key output - format.note output - format.isbn output - format.doi output - format.pubmed output - format.url output - format.abstract output - format.file output - fin.entry - empty.misc.check -} - -FUNCTION {phdthesis} -{ output.bibitem - "\DTLnewbibitem {EntryType}{phdthesis}%" write$ - newline$ - format.authors "author" output.check - new.block - format.btitle "title" output.check - new.block - "\DTLnewbibitem {Type}{\phdthesisname }" - format.thesis.type output.nonnull - format.school "school" output.check - format.address output - format.date "year" output.check - new.block - format.key output - format.note output - format.isbn output - format.doi output - format.pubmed output - format.url output - format.abstract output - format.file output - fin.entry -} - -FUNCTION {proceedings} -{ output.bibitem - "\DTLnewbibitem {EntryType}{proceedings}%" write$ - newline$ - editor empty$ - { format.organization output } - { format.editors output.nonnull } - if$ - new.block - format.btitle "title" output.check - format.bvolume output - format.number.series output - address empty$ - { editor empty$ -{ publisher new.sentence.checka } -{ organization publisher new.sentence.checkb - format.organization output -} - if$ - format.publisher output - format.date "year" output.check - } - { format.address output - format.date "year" output.check - new.sentence - editor empty$ -'skip$ -{ format.organization output } - if$ - format.publisher output - } - if$ - new.block - format.key output - format.note output - format.isbn output - format.doi output - format.pubmed output - format.url output - format.abstract output - format.file output - fin.entry -} - -FUNCTION {techreport} -{ output.bibitem - "\DTLnewbibitem {EntryType}{techreport}%" write$ - newline$ - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - format.tr.number output.nonnull - format.institution "institution" output.check - format.address output - format.date "year" output.check - new.block - format.key output - format.note output - format.isbn output - format.doi output - format.pubmed output - format.url output - format.abstract output - format.file output - fin.entry -} - -FUNCTION {unpublished} -{ output.bibitem - "\DTLnewbibitem {EntryType}{unpublished}%" write$ - newline$ - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - format.key output - format.note output - format.isbn output - format.doi output - format.pubmed output - format.url output - format.abstract output - format.file output - format.date output - fin.entry -} - -FUNCTION {default.type} { misc } - -MACRO {jan} {"\DTLmonthname{01}"} - -MACRO {feb} {"\DTLmonthname{02}"} - -MACRO {mar} {"\DTLmonthname{03}"} - -MACRO {apr} {"\DTLmonthname{04}"} - -MACRO {may} {"\DTLmonthname{05}"} - -MACRO {jun} {"\DTLmonthname{06}"} - -MACRO {jul} {"\DTLmonthname{07}"} - -MACRO {aug} {"\DTLmonthname{08}"} - -MACRO {sep} {"\DTLmonthname{09}"} - -MACRO {oct} {"\DTLmonthname{10}"} - -MACRO {nov} {"\DTLmonthname{11}"} - -MACRO {dec} {"\DTLmonthname{12}"} - -MACRO {acmcs} {"\DTLacmcs "} - -MACRO {acta} {"\DTLacta "} - -MACRO {cacm} {"\DTLcacm "} - -MACRO {ibmjrd} {"\DTLibmjrd "} - -MACRO {ibmsj} {"\DTLibmsj "} - -MACRO {ieeese} {"\DTLieeese "} - -MACRO {ieeetc} {"\DTLieeetc "} - -MACRO {ieeetcad} {"\DTLieeetcad "} - -MACRO {ipl} {"\DTLipl "} - -MACRO {jacm} {"\DTLjacm "} - -MACRO {jcss} {"\DTLjcss "} - -MACRO {scp} {"\DTLscp "} - -MACRO {sicomp} {"\DTLsicomp "} - -MACRO {tocs} {"\DTLtocs "} - -MACRO {tods} {"\DTLtods "} - -MACRO {tog} {"\DTLtog "} - -MACRO {toms} {"\DTLtoms "} - -MACRO {toois} {"\DTLtoois "} - -MACRO {toplas} {"\DTLtoplas "} - -MACRO {tcs} {"\DTLtcs "} - -READ - -STRINGS { longest.label } - -INTEGERS { number.label longest.label.width } - -FUNCTION {initialize.longest.label} -{ "" 'longest.label := - #1 'number.label := - #0 'longest.label.width := -} - -FUNCTION {longest.label.pass} -{ number.label int.to.str$ 'label := - number.label #1 + 'number.label := - label width$ longest.label.width > - { label 'longest.label := - label width$ 'longest.label.width := - } - 'skip$ - if$ -} - -EXECUTE {initialize.longest.label} - -ITERATE {longest.label.pass} - -FUNCTION {begin.bib} -{ preamble$ empty$ - 'skip$ - { preamble$ write$ newline$ } - if$ -} - -EXECUTE {begin.bib} - -EXECUTE {init.state.consts} - -ITERATE {call.type$} - -FUNCTION {end.bib} -{ -} - -EXECUTE {end.bib} diff --git a/Master/texmf-dist/doc/latex/datatool/CHANGES b/Master/texmf-dist/doc/latex/datatool/CHANGES index bee8676f0e6..7236ed455d9 100644 --- a/Master/texmf-dist/doc/latex/datatool/CHANGES +++ b/Master/texmf-dist/doc/latex/datatool/CHANGES @@ -1,3 +1,73 @@ +v2.10 (2012/07/18): + + * datatool.sty: + + - Split package into datatool-base.sty, datatool-fp.sty and + datatool-pgfmath.sty + + - Added package option "math" (math=fp -> use fp.sty, + math=pgfmath -> use pgfmath.sty) + + - datatool.sty now requires etoolbox (changed commands like + \@ifundefined to etoolbox equivalents) + + - Added 'omitlines' option when loading csv file (from patch supplied by Bruno Le Floch + at: + http://tex.stackexchange.com/questions/22942/skipping-the-first-line-of-a-data-file-for-pgfplotstable/25133#25133 ) + + - \DTLloaddb : adds default column header if missing + + - Added optional argument to \DTLdisplaydb + + - Added omit key to \DTLdisplaylongdb + + - added environment dtlenvgforint + + - added environments DTLenvforeach and DTLenvforeach* + + - added check for at least version 1.2 (2009/10/20) of substr.sty + + - added \DTLassign + + - added DTLnumitemsinlist + + - added \dtlrecombine, \dtlrecombineomitcurrent, + \dtlreplaceentryincurrentrow, \dtlswapentriesincurrentrow, + \dtlremoveentryincurrentrow, \dtlappendentrytocurrentrow + + - Rewritten \@dtl@ifDigitOrDecimalSep (code provided by Bruno Le Floch) + + - ensured first argument of \DTLconverttodecimal gets one-level + expansion in commands like \DTLaddall + + - Fixed \DTLloaddb to work if % used at the start of a row in CSV file. + + - Fixed \@dtl@qlopoff to substitute escaped CSV delimiters + + - Fixed bug in \DTLloadrawdb, which only performed a single + substitution per line + + - Added \long before \edef in \DTLsubstituteall + + - Fixed bug in \@dtl@getkeyforcolumn (affects + \DTLgetkeyforcolumn) + + - Changed tab character to ^^I + + - Fixed bug in \DTLloaddb and \DTLloadrawdb when CSV file only contains one column + + * databib.bst: + + - Added eprints field + + * datatool-user.tex (User guide): + + - fixed typo "\value{DTLbibrow}<11" => "\value{DTLbibrow}<10" + + - added section "Operating on Current Row" + + - added remark on using etoolbox to check for empty values + v2.03 (2009/11/15): * Added facility to clear or delete a database. diff --git a/Master/texmf-dist/doc/latex/datatool/INSTALL b/Master/texmf-dist/doc/latex/datatool/INSTALL new file mode 100644 index 00000000000..55acc329594 --- /dev/null +++ b/Master/texmf-dist/doc/latex/datatool/INSTALL @@ -0,0 +1,64 @@ +INSTALLATION + +If you have downloaded the datatool package using the TeX +Directory Structure (TDS), that is you have downloaded the archive +datatool.tds.zip containing doc, tex, scripts and source +directories, you need to follow the "Installing from TDS" +instructions below. + +If you have downloaded the following files: + +datatool.dtx +datatool.ins + +You need to follow the "Installing from DTX and INS" instructions +below. + +For further information on installing LaTeX packages see: + +http://www.tex.ac.uk/cgi-bin/texfaq2html?label=installthings + +INSTALLING FROM TDS +=================== + +Files in tex and doc directories should go in the corresponding +TEXMF directories (for example, /usr/share/texmf-local/ or +C:\localtexmf\). + +*Remember to refresh TeX's database* + +Example (on UNIX like systems): + +unzip datatool.tds.zip -d ~/texmf/ +texhash ~/texmf/ + +INSTALLING FROM DTX AND INS +=========================== + +Run LaTeX on datatool.ins to generate the package style files: + +latex datatool.ins + +To create the package documentation (datatool.pdf): + +pdflatex datatool.dtx +makeindex -s gind.ist datatool.idx +pdflatex datatool.dtx +pdflatex datatool.dtx + +If TEXMF denotes the base directory of your local TeX installation (e.g. +/usr/share/texmf-local/ or C:\localtexmf\) then create the following +directories (if they don't already exist): + +TEXMF/doc/latex/datatool +TEXMF/doc/latex/datatool/samples +TEXMF/tex/latex/datatool + +Move the sample files (*.tex) to TEXMF/doc/latex/datatool/sample/ + +Move the documentation (*.pdf) to TEXMF/doc/latex/datatool/ + +Move style files (*.sty) to TEXMF/tex/latex/datatool/ + +*Remember to refresh TeX's database* + diff --git a/Master/texmf-dist/doc/latex/datatool/README b/Master/texmf-dist/doc/latex/datatool/README index 0a6d97f88d4..23c357ae670 100644 --- a/Master/texmf-dist/doc/latex/datatool/README +++ b/Master/texmf-dist/doc/latex/datatool/README @@ -1,9 +1,14 @@ -LaTeX Bundle : datatool v2.03 (datatool.sty, datapie.sty, dataplot.sty, databar.sty, databib.sty) +LaTeX Bundle : datatool v2.10 -Last Modified : 15 November 2009 +Last Modified : 2012-07-18 Author : Nicola Talbot +This bundle consists of the packages: datatool.sty, +datatool-base.sty, datatool-fp.sty, datatool-pgfmath.sty, +databar.sty, databib.sty, datapie.sty dataplot.sty, +person.sty. + datatool.sty: Databases can be created using LaTeX commands or loaded @@ -17,6 +22,8 @@ datatool.sty: data in a database (such as mail merging.) Conditions can be imposed to exclude rows. +datatool-base.sty: + Commands are provided to determine if an argument is an integer, a real number, currency or a string. (Scientific notation is currently not supported.) @@ -27,7 +34,7 @@ datatool.sty: Commands are provided to convert between locale dependent numbers/currency and the standard decimal format required - by the fp package enabling fixed point arithmetic to be + by the fp or pgfmath packages enabling fixed point arithmetic to be performed on elements of the database. Strings can be tested to determine if they are all upper @@ -35,6 +42,12 @@ datatool.sty: Names can be converted to initials using \DTLinitials. +datatool-fp.sty: + Provides an interface with fp.sty + +datatool-pgfmath.sty: + Provides an interface with pgfmath.sty + datapie.sty: A database defined by datatool.sty can be converted into a @@ -87,14 +100,18 @@ person.sty: REQUIRED PACKAGES: -The datatool.sty package requires the following packages/files: +The datatool.sty and datatool-base.sty packages requires the following packages/files: xkeyval ifthen xfor -fp -substr +substr (at least 2009/10/20) etex +etoolbox +amsmath + +The datatool-fp package requires fp.sty +The datatool-pgfmath package requires pgfmath.sty The datapie.sty, dataplot.sty and databar.sty packages additionally require the tikz/pgf bundle. diff --git a/Master/texmf-dist/doc/latex/datatool/datatool-user.pdf b/Master/texmf-dist/doc/latex/datatool/datatool-user.pdf Binary files differnew file mode 100644 index 00000000000..59d242c0cee --- /dev/null +++ b/Master/texmf-dist/doc/latex/datatool/datatool-user.pdf diff --git a/Master/texmf-dist/doc/latex/datatool/datatool-user.tex b/Master/texmf-dist/doc/latex/datatool/datatool-user.tex new file mode 100644 index 00000000000..86ac37d6af7 --- /dev/null +++ b/Master/texmf-dist/doc/latex/datatool/datatool-user.tex @@ -0,0 +1,8247 @@ +\documentclass[report,widecs]{nlctdoc} + +\usepackage{ifthen} +\usepackage[verbose=false]{datatool} +\usepackage{datapie,databar,databib,person} +\usepackage{textcomp} +\usepackage{graphicx} +\usepackage{colortbl} +\usepackage{cmap} +\usepackage[T1]{fontenc} +\usepackage[utf8]{inputenc} +\ifpdf +\usepackage{mathpazo} +\usepackage[scaled=.88]{helvet} +\usepackage{courier} +\fi +\usepackage{caption} +\usepackage[colorlinks, + bookmarks, + hyperindex=false, + pdfauthor={Nicola L.C. Talbot}, + pdftitle={datatool: Databases and data manipulation}, + pdfkeywords={LaTeX,package,database,data,chart,plot}]{hyperref} +\usepackage{xr-hyper} +\usetikzlibrary{snakes} + +\PageIndex +\IndexPrologue{\chapter*{Index}} +\setcounter{IndexColumns}{2} + +\ifpdf + \externaldocument{datatool} +\fi + +\doxitem{Counter}{counter}{counters} +\doxitem{Option}{option}{package options} + +\newcommand*{\desctr}[1]{\ctrfmt{#1}\DescribeCounter{#1}} + + %bibliography database +\DTLnewdb{docbib} +\DTLnewrow{docbib} +\DTLnewdbentry{docbib}{CiteKey}{Goossens} +\DTLnewdbentry{docbib}{EntryType}{book} +\DTLnewdbentry{docbib}{Author}{{}{Goossens}{}{Michel},{}{Mittelbach}{}{Frank},{}{Samarin}{}{Alexander}} +\DTLnewdbentry{docbib}{Title}{The \LaTeX\ Companion} +\DTLnewdbentry{docbib}{Publisher}{Addison-Wesley} +\DTLnewdbentry{docbib}{Year}{1994} + + +\begin{document} +% Some of the commands are too long to produce nicely formatted +% paragraphs so use ragged-right: +\raggedright + +\MakeShortVerb{"} +\DeleteShortVerb{\|} + + \title{User Manual for datatool bundle version~2.10} + \author{Nicola L.C. Talbot\\[10pt] +School of Computing Sciences\\ +University of East Anglia\\ +Norwich. Norfolk\\ +NR4 7TJ. United Kingdom.\\ +\url{http://theoval.cmp.uea.ac.uk/~nlct/}} + + \date{2012-07-18} + \maketitle + +\pagenumbering{roman} + +\noindent +The \styfmt{datatool} bundle comes with the following documentation: +\begin{description} + \item[datatool-user.pdf] + This document is the main user guide for the \styfmt{datatool} + bundle. + + \item[\url{datatool.pdf}] + Advanced users wishing to know more about the inner workings of + all the packages provided in the \styfmt{datatool} bundle should + read \qt{Documented Code for datatool v2.10} + + \item[INSTALL] Installation instructions. + + \item[CHANGES] Change log. + + \item[README] Package summary. +\end{description} + +\begin{important} +The \styfmt{datatool} bundle is provided to help perform repetitive +commands, such as mail merging, but since \TeX\ is designed as a +typesetting language, don't expect this bundle to perform as +efficiently as custom database systems or a dedicated mathematical or +scripting language. +\end{important} + +This bundle consists of the following packages: +\begin{description} +\item[\sty{datatool}] Main package providing database support. +Automatically loads \sty{datatool-base}. + +\item[\sty{datatool-base}] Provides the main library code for +numerical and string functions. Automatically +loads \sty{datatool-fp} or \sty{datatool-pgfmath} depending on +package options. + +\item[\sty{databar}] Package for drawing bar charts. +Automatically loads \sty{datatool}. + +\item[\sty{datapie}] Package for drawing pie charts. +Automatically loads \sty{datatool}. + +\item[\sty{dataplot}] Package for drawing simple line graphs. +Automatically loads \sty{datatool}. + +\item[\sty{databib}] Package for loading a bibliography into a +database. Automatically loads \sty{datatool}. + +\item[\sty{person}] Package for referencing people by the +appropriate gender pronouns. Automatically loads \sty{datatool}. + +\end{description} + +In addition, there are two mutually exclusive packages +\sty{datatool-fp} and \sty{datatool-pgfmath} that provide +mathematical related commands that are just wrapper functions for +\sty{fp} or \sty{pgfmath} commands. These can be loaded individually +without loading \sty{datatool}. For example, the following documents +produce the same results, but the first uses the \sty{fp} package +and the second uses the \sty{pgfmath} package: + +\begin{enumerate} +\item Using \sty{fp} macros: +\begin{verbatim} +\documentclass{article} +\usepackage{datatool-fp} +\begin{document} +1=2: \dtlifnumeq{1}{2}{true}{false}. +\end{document} +\end{verbatim} + +\item Using \sty{pgfmath} macros: +\begin{verbatim} +\documentclass{article} +\usepackage{datatool-pgfmath} +\begin{document} +1=2: \dtlifnumeq{1}{2}{true}{false}. +\end{document} +\end{verbatim} + +\end{enumerate} + +\cleardoublepage +\pdfbookmark[0]{Contents}{contents} +\tableofcontents +\cleardoublepage +\pdfbookmark[0]{List of Examples}{examples} +\listofexamples +\cleardoublepage +\pdfbookmark[0]{List of Figures}{figures} +\listoffigures +\cleardoublepage +\pdfbookmark[0]{List of Tables}{tables} +\listoftables + +\pagenumbering{arabic} +\chapter{Introduction} + + \changes{1.0}{2007 July 22}{Initial version} +The \sty{datatool} bundle consists of the following +packages: \sty{datatool} (which loads \sty{datatool-base} and either \sty{datatool-fp} or \sty{datatool-pgfmath}), \sty{datapie}, \sty{dataplot}, +\sty{databar} and \sty{databib}. + +The \sty{datatool} package can be used to: +\begin{itemize} +\item Create or load databases. +\item Sort rows of a database (either numerically or alphabetically, +ascending or descending). +\item Perform repetitive operations on each row of a database +(e.g.\ mail merging). Conditions may be imposed to exclude rows. + +\item Package Options: + \begin{description} + \item[\pkgopt{verbose}] Boolean key. If + \pkgoptval{true}{verbose}, prints informational messages in + transcript. + \item[\pkgopt{math}] May take one of two values: + \pkgoptval{fp}{math} (load \sty{datatool-fp}) or + \pkgoptval{pgfmath}{math} (load \sty{datatool-pgfmath}). Default is: + \pkgoptval{fp}{math}. + \item[\pkgopt{delimiter}] Delimiter used in CSV files. + Default is a double quote (\texttt{\string"}). + \item[\pkgopt{separator}] Delimiter used in CSV files. + Default is a comma (\texttt{,}). + \end{description} +\end{itemize} + +The \sty{datatool-base} package can be used to: +\begin{itemize} +\item Determine whether an argument is an integer, a real number, +currency or a string. (Scientific notation is currently not +supported.) Locale dependent number settings are supported (such +as a comma as a decimal character and a full stop as a number +group character). +\item Convert locale dependent numbers/currency to the decimal +format required by the \sty{fp} or \sty{pgfmath} packages, enabling fixed point +arithmetic to be performed on elements of the database. +\item Names can be converted to initials. +\item Determine if strings are all upper or lower case. +\item Perform string comparisons (both case sensitive and case insensitive). + +\item Package Options: + \begin{description} + \item[\pkgopt{verbose}] Boolean key. If + \pkgoptval{true}{verbose}, prints informational messages in + transcript. + \item[\pkgopt{math}] May take one of two values: + \pkgoptval{fp}{math} (load \sty{datatool-fp}) or + \pkgoptval{pgfmath}{math} (load \sty{datatool-pgfmath}). Default is: + \pkgoptval{fp}{math}. + \end{description} +\end{itemize} + +The \sty{datapie} package (see \autoref{sec:datapie}) can be used to convert a database into +a pie chart: +\begin{itemize} +\item Segments can be separated from the rest of the chart to make +them stand out. +\item Colour/grey scale options. +\item Predefined segment colours can be changed. +\item Hooks provided to add extra information to the chart +\end{itemize} + +The \sty{databar} package (see \autoref{sec:databar}) can be used to convert a database into +a bar chart: +\begin{itemize} +\item Colour/grey scale options. +\item Predefined bar colours can be changed. +\item Hooks provided to add extra information to the chart +\end{itemize} + +(The \sty{datapie} and \sty{databar} packages do not support the +creation of 3D charts, and I have no plans to implement them at any +later date. The use of 3D charts should be discouraged. They may look +pretty, but the purpose of a chart is to be informative. Three +dimensional graphics cause distortion, which can result in misleading +impressions. The \sty{pgf} manual provides a more in-depth +discussion on the matter.) + +The \sty{dataplot} package (see \autoref{sec:dataplot}) can be used to convert a database into +a two dimensional plot using markers and/or lines. Three dimensional +plots are currently not supported. + +The \sty{databib} package (see \autoref{sec:databib}) can be used to convert a \BibTeX\ database +into a \sty{datatool} database. + +\chapter{Data Types} +\label{sec:datatypes} + +The \sty{datatool-base} package recognises four data types: integers, +real numbers, currency and strings. + +\begin{description} +\item[Integers] An integer is a sequence of digits, optionally +groups of three digits may be separated by the number group character. +The default number group character is a comma (,) but may be +changed using \cs{DTLsetnumberchars} (see below). + +\item[Real Numbers] A real number is an integer followed by the +decimal character followed by one or more digits. The decimal +character is a full stop (.) by default. The number group +and decimal characters may be changed using +\begin{definition}[\DescribeMacro{\DTLsetnumberchars}]% +\cs{DTLsetnumberchars}\marg{number group character}\marg{decimal character} +\end{definition} +Note that scientific notation is not supported, and the number group +character may not be used after the decimal character. + +\item[Currency] A currency symbol followed by an integer or +real number is considered to be the currency data type. +There are two predefined currency symbols, "\$" and \cs{pounds}. +In addition, if any of the following commands are defined at the +start of the document, they are also considered to be a currency +symbol: \cs{texteuro}, \cs{textdollar}, \cs{textstirling}, +\cs{textyen}, \cs{textwon}, \cs{textcurrency}, \cs{euro} +and \cs{yen}. Additional currency symbols can be defined using +\begin{definition}[\DescribeMacro{\DTLnewcurrencysymbol}]% +\cs{DTLnewcurrencysymbol}\marg{symbol} +\end{definition} + +\item[Strings] Anything that doesn't belong to the above three +types is considered to be a string. + +\end{description} + +\section{Conditionals} +\label{sec:ifconditions} + +The following conditionals are provided by the \sty{datatool-base} +package: +\begin{definition}[\DescribeMacro{\DTLifint}]% +\cs{DTLifint}\marg{text}\marg{true part}\marg{false part} +\end{definition} +If \meta{text} is an integer then do \meta{true part}, otherwise +do \meta{false part}. For example +\begin{verbatim} +\DTLifint{2536}{integer}{not an integer} +\end{verbatim} +produces: +\DTLifint{2536}{integer}{not an integer}. + +The number group character may appear in the number, for example: +\begin{verbatim} +\DTLifint{2,536}{integer}{not an integer} +\end{verbatim} +produces: +\DTLifint{2,536}{integer}{not an integer}. +However, the number group character may only be followed by a group +of three digits. For example: +\begin{verbatim} +\DTLifint{2,5,3,6}{integer}{not an integer} +\end{verbatim} +produces: +\DTLifint{2,5,3,6}{integer}{not an integer}. +The number group character may be changed. For example: +\begin{verbatim} +\DTLsetnumberchars{.}{,}% +\DTLifint{2,536}{integer}{not an integer} +\end{verbatim} +this now produces: +\DTLsetnumberchars{.}{,}\relax +\DTLifint{2,536}{integer}{not an integer}, since 2,536 is now +a real number. + +Note that nothing else can be appended or prepended to the +number. For example: +\begin{verbatim} +\DTLsetnumberchars{,}{.}% +\DTLifint{2,536m}{integer}{not an integer} +\end{verbatim} +produces: +\DTLsetnumberchars{,}{.}\relax +\DTLifint{2,536m}{integer}{not an integer}. + +\begin{definition}[\DescribeMacro{\DTLifreal}]% +\cs{DTLifreal}\marg{text}\marg{true part}\marg{false part} +\end{definition} +If \meta{text} is a real number then do \meta{true part}, otherwise +do \meta{false part}. For example +\begin{verbatim} +\DTLifreal{1000.0}{real}{not real} +\end{verbatim} +produces: +\DTLifreal{1000.0}{real}{not real}. + +Note that an integer is not considered a real number: +\begin{verbatim} +\DTLifreal{1,000}{real}{not real} +\end{verbatim} +produces: +\DTLifreal{1,000}{real}{not real}. + +Whereas +\begin{verbatim} +\DTLifreal{1,000.0}{real}{not real} +\end{verbatim} +produces: +\DTLifreal{1,000.0}{real}{not real}. + +However +\begin{verbatim} +\DTLsetnumberchars{.}{,}% +\DTLifreal{1,000}{real}{not real} +\end{verbatim} +produces: +\DTLsetnumberchars{.}{,}\relax +\DTLifreal{1,000}{real}{not real} since the comma is now +the decimal character. + +Currency is not considered to be real: +\begin{verbatim} +\DTLsetnumberchars{,}{.}% +\DTLifreal{\$1.00}{real}{not real} +\end{verbatim} +produces: +\DTLsetnumberchars{,}{.}\relax +\DTLifreal{\$1.00}{real}{not real}. + +\begin{definition}[\DescribeMacro{\DTLifcurrency}]% +\cs{DTLifcurrency}\marg{text}\marg{true part}\marg{false part} +\end{definition} +If \meta{text} is currency, then do \meta{true part}, otherwise +do false part. For example: +\begin{verbatim} +\DTLifcurrency{\$5.99}{currency}{not currency} +\end{verbatim} +produces: +\DTLifcurrency{\$5.99}{currency}{not currency}. Similarly: +\begin{verbatim} +\DTLifcurrency{\pounds5.99}{currency}{not currency} +\end{verbatim} +produces: +\DTLifcurrency{\pounds5.99}{currency}{not currency}. +Note, however, that +\begin{verbatim} +\DTLifcurrency{US\$5.99}{currency}{not currency} +\end{verbatim} +produces: +\DTLifcurrency{US\$5.99}{currency}{not currency}. If you want +this to be considered currency, you will have to add the +sequence "US\$" to the set of currency symbols: +\begin{verbatim} +\DTLnewcurrencysymbol{US\$}% +\DTLifcurrency{US\$5.99}{currency}{not currency} +\end{verbatim} +this now produces: +\DTLnewcurrencysymbol{US\$}\relax +\DTLifcurrency{US\$5.99}{currency}{not currency}. + +This document has used the \sty{textcomp} package which defines +\cs{texteuro}, so this is also considered to be currency. For +example: +\begin{verbatim} +\DTLifcurrency{\texteuro5.99}{currency}{not currency} +\end{verbatim} +produces: +\DTLifcurrency{\texteuro5.99}{currency}{not currency}. + +The preferred method is to display the euro symbol in a sans-serif +font, but +\begin{verbatim} +\DTLifcurrency{\textsf{\texteuro}5.99}{currency}{not currency} +\end{verbatim} +will produce: +\DTLifcurrency{\textsf{\texteuro}5.99}{currency}{not currency}. + +It is better to define a new command, for example: +\begin{verbatim} +\DeclareRobustCommand*{\euro}{\textsf{\texteuro}} +\end{verbatim} +and add that command to the list of currency symbols. In fact, +in this case, if you define the command \cs{euro} in the +preamble, it will automatically be added to the list of known +currency symbols. If however you define \cs{euro} in the document, +you will have to add it using \ics{DTLnewcurrencysymbol}. For +example: +\begin{verbatim} +\newcommand*{\euro}{\textsf{\texteuro}}% +\DTLnewcurrencysymbol{\euro}% +\DTLifcurrency{\euro5.99}{currency}{not currency} +\end{verbatim} +produces: +\DeclareRobustCommand*{\euro}{\textsf{\texteuro}}\relax +\DTLnewcurrencysymbol{\euro}\relax +\DTLifcurrency{\euro5.99}{currency}{not currency}. + +\begin{definition}[\DescribeMacro{\DTLifcurrencyunit}]% +\cs{DTLifcurrencyunit}\marg{text}\marg{symbol}\marg{true part}\marg{false part} +\end{definition} +If \meta{text} is currency, and uses \meta{symbol} as the unit of +currency, then do \meta{true part} otherwise do \meta{false part}. +For example: +\begin{verbatim} +\DTLifcurrencyunit{\$6.99}{\$}{dollars}{not dollars} +\end{verbatim} +produces: +\DTLifcurrencyunit{\$6.99}{\$}{dollars}{not dollars}. +Another example: +\begin{verbatim} +\def\cost{\euro10.50}% +\DTLifcurrencyunit{\cost}{\euro}{euros}{not euros} +\end{verbatim} +produces: +\def\cost{\euro10.50}\relax +\DTLifcurrencyunit{\cost}{\euro}{euros}{not euros}. + +\begin{definition}[\DescribeMacro{\DTLifnumerical}]% +\cs{DTLifnumerical}\marg{text}\marg{true part}\marg{false part} +\end{definition} +If \meta{text} is numerical (either an integer, real number or +currency) then do \meta{true part} otherwise do +\meta{false part}. +For example: +\begin{verbatim} +\DTLifnumerical{1,000.0}{number}{string}. +\end{verbatim} +produces: \DTLifnumerical{1,000.0}{number}{string}. +Whereas +\begin{verbatim} +\DTLsetnumberchars{.}{,}% +\DTLifnumerical{1,000.0}{number}{string}. +\end{verbatim} +produces: +\DTLsetnumberchars{.}{,}\relax +\DTLifnumerical{1,000.0}{number}{string}. +Since the number group character is now a full stop, and the +decimal character is now a comma. (The number group character +may only appear before the decimal character, not after it.) + +Currency is also considered to be numerical: +\begin{verbatim} +\DTLsetnumberchars{,}{.}% +\DTLifnumerical{\$1,000.0}{number}{string}. +\end{verbatim} +produces: +\DTLsetnumberchars{,}{.}\relax +\DTLifnumerical{\$1,000.0}{number}{string}. + +\begin{definition}[\DescribeMacro{\DTLifstring}]% +\cs{DTLifstring}\marg{text}\marg{true part}\marg{false part} +\end{definition} +This is the opposite of \cs{DTLifnumerical}. If \meta{text} is +not numerical, do \meta{true part}, otherwise do \meta{false part}. + +\begin{definition}[\DescribeMacro{\DTLifcasedatatype}]% +\cs{DTLifcasedatatype}\marg{text}\marg{string case}\marg{int case}\marg{real case}\marg{currency case} +\end{definition} +If \meta{text} is a string do \meta{string case}, if \meta{text} +is an integer do \meta{int case}, if \meta{text} is a real number +do \meta{real case}, if \meta{text} is currency do +\meta{currency case}. For example: +\begin{verbatim} +\DTLifcasedatatype{1,000}{string}{integer}{real}{currency} +\end{verbatim} +produces: +\DTLifcasedatatype{1,000}{string}{integer}{real}{currency}. + +\begin{definition}[\DescribeMacro{\dtlifnumeq}]% +\cs{dtlifnumeq}\marg{num1}\marg{num2}\marg{true part}\marg{false +paty} +\end{definition} +If \meta{num1} is equal to \meta{num2}, then do \meta{true part}, +otherwise to \meta{false part} where \meta{num1} and \meta{num2} +are plain numbers using a full stop as the decimal point and no +number group separator. For currency or locale dependent numbers use +\cs{DTLifnumeq}. + +\begin{definition}[\DescribeMacro{\DTLifnumeq}]% +\cs{DTLifnumeq}\marg{num1}\marg{num2}\marg{true part}\marg{false part} +\end{definition} +If \meta{num1} is equal to \meta{num2}, then do \meta{true part}, +otherwise do \meta{false part}. Note that both \meta{num1} and +\meta{num2} must be numerical (either integers, real numbers or +currency). The currency symbol is ignored when determining +equality. For example +\begin{verbatim} +\DTLifnumeq{\pounds10.50}{10.5}{true}{false} +\end{verbatim} +produces: +\DTLifnumeq{\pounds10.50}{10.5}{true}{false}, since they are +considered to be numerically equivalent. Likewise: +\begin{verbatim} +\DTLifnumeq{\pounds10.50}{\$10.50}{true}{false} +\end{verbatim} +produces: +\DTLifnumeq{\pounds10.50}{\$10.50}{true}{false}. + +\pagebreak +\begin{definition}[\DescribeMacro{\DTLifstringeq}]% +\cs{DTLifstringeq}\marg{string1}\marg{string2}\marg{true part}\marg{false part} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLifstringeq*}]% +\cs{DTLifstringeq*}\marg{string1}\marg{string2}\marg{true part}\marg{false part} +\end{definition} +If \meta{string1} and \meta{string2} are the same, then do +\meta{true part}, otherwise do \meta{false part}. The starred +version ignores the case, the unstarred version is case +sensitive. Both +\meta{string1} and \meta{string2} are considered to be strings, +so for example: +\begin{verbatim} +\DTLifstringeq{10.50}{10.5}{true}{false} +\end{verbatim} +produces: +\DTLifstringeq{10.50}{10.5}{true}{false}. + +Note that +\begin{verbatim} +\DTLifstringeq{Text}{text}{true}{false} +\end{verbatim} +produces: +\DTLifstringeq{Text}{text}{true}{false}, whereas +\begin{verbatim} +\DTLifstringeq*{Text}{text}{true}{false} +\end{verbatim} +produces: +\DTLifstringeq*{Text}{text}{true}{false}, however it should also be +noted that many commands will be ignored, so: +\begin{verbatim} +\DTLifstringeq{\uppercase{t}ext}{text}{true}{false} +\end{verbatim} +produces: +\DTLifstringeq{\uppercase{t}ext}{text}{true}{false}. + +Spaces are considered to be equivalent to \cs{space} and "~". For +example: +\begin{verbatim} +\DTLifstringeq{an apple}{an~apple}{true}{false} +\end{verbatim} +produces: +\DTLifstringeq{an apple}{an~apple}{true}{false}. Consecutive spaces +are treated as the same, for example: +\begin{verbatim} +\DTLifstringeq{an apple}{an apple}{true}{false} +\end{verbatim} +produces: +\DTLifstringeq{an apple}{an apple}{true}{false}. + +\begin{definition}[\DescribeMacro{\DTLifeq}]% +\cs{DTLifeq}\marg{arg1}\marg{arg2}\marg{true part}\marg{false part} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLifeq*}]% +\cs{DTLifeq*}\marg{arg1}\marg{arg2}\marg{true part}\marg{false part} +\end{definition} +If both \meta{arg1} and \meta{arg2} are numerical, then this is +equivalent to \cs{DTLifnumeq}, otherwise it is equivalent to +\cs{DTLifstringeq} (when using \cs{DTLifeq}) or \cs{DTLifstringeq*} +(when using \cs{DTLifeq*}). + +\begin{definition}[\DescribeMacro{\dtlifnumlt}]% +\cs{dtlifnumlt}\marg{num1}\marg{num2}\marg{true part}\marg{false +paty} +\end{definition} +If \meta{num1} is less than \meta{num2}, then do \meta{true part}, +otherwise to \meta{false part} where \meta{num1} and \meta{num2} +are plain numbers using a full stop as the decimal point and no +number group separator. For currency or locale dependent numbers use +\cs{DTLifnumlt}. + +\begin{definition}[\DescribeMacro{\DTLifnumlt}]% +\cs{DTLifnumlt}\marg{num1}\marg{num2}\marg{true part}\marg{false part} +\end{definition} +If \meta{num1} is less than \meta{num2}, then do \meta{true part}, +otherwise do \meta{false part}. Note that both \meta{num1} and +\meta{num2} must be numerical (either integers, real numbers or +currency). + +\begin{definition}[\DescribeMacro{\DTLifstringlt}]% +\cs{DTLifstringlt}\marg{string1}\marg{string2}\marg{true +part}\marg{false part} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLifstringlt*}]% +\cs{DTLifstringlt*}\marg{string1}\marg{string2}\marg{true +part}\marg{false part} +\end{definition} +If \meta{string1} is alphabetically less than \meta{string2}, then do +\meta{true part}, otherwise do \meta{false part}. The starred +version ignores the case, the unstarred version is case +sensitive. +For example: +\begin{verbatim} +\DTLifstringlt{aardvark}{zebra}{less}{not less} +\end{verbatim} +produces: +\DTLifstringlt{aardvark}{zebra}{less}{not less}. + +Note that both \meta{string1} and \meta{string2} are considered to be +strings, so for example: +\begin{verbatim} +\DTLifstringlt{2}{10}{less}{not less} +\end{verbatim} +produces: +\DTLifstringlt{2}{10}{less}{not less}, since the string "2" +comes after the string "10" when arranged alphabetically. + +The case sensitive (unstarred) version considers uppercase characters +to be less than lowercase characters, so +\begin{verbatim} +\DTLifstringlt{B}{a}{less}{not less} +\end{verbatim} +produces: +\DTLifstringlt{B}{a}{less}{not less}, whereas +\begin{verbatim} +\DTLifstringlt*{B}{a}{less}{not less} +\end{verbatim} +produces: +\DTLifstringlt*{B}{a}{less}{not less}. + +\begin{definition}[\DescribeMacro{\DTLiflt}]% +\cs{DTLiflt}\marg{arg1}\marg{arg2}\marg{true part}\marg{false part} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLiflt*}]% +\cs{DTLiflt*}\marg{arg1}\marg{arg2}\marg{true part}\marg{false part} +\end{definition} +If \meta{arg1} and \meta{arg2} are both numerical, then this +is equivalent to \cs{DTLifnumlt}, otherwise it is equivalent +to \cs{DTLstringlt} (when using \cs{DTLiflt}) or +\cs{DTLstringlt*} (when using \cs{DTLiflt*}). + +\begin{definition}[\DescribeMacro{\DTLifnumgt}]% +\cs{DTLifnumgt}\marg{num1}\marg{num2}\marg{true part}\marg{false part} +\end{definition} +If \meta{num1} is greater than \meta{num2}, then do \meta{true part}, +otherwise do \meta{false part}. Note that both \meta{num1} and +\meta{num2} must be numerical (either integers, real numbers or +currency). + +\begin{definition}[\DescribeMacro{\DTLifstringgt}]% +\cs{DTLifstringgt}\marg{string1}\marg{string2}\marg{true +part}\marg{false part} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLifstringgt*}]% +\cs{DTLifstringgt*}\marg{string1}\marg{string2}\marg{true +part}\marg{false part} +\end{definition} +If \meta{string1} is alphabetically greater than \meta{string2}, then +do \meta{true part}, otherwise do \meta{false part}. The +starred version ignores the case, the unstarred version is +case sensitive. For example: +\begin{verbatim} +\DTLifstringgt{aardvark}{zebra}{greater}{not greater} +\end{verbatim} +produces: +\DTLifstringgt{aardvark}{zebra}{greater}{not greater}. + +Note that both \meta{string1} and \meta{string2} are considered to be +strings, so for example: +\begin{verbatim} +\DTLifstringgt{2}{10}{greater}{not greater} +\end{verbatim} +produces: +\DTLifstringgt{2}{10}{greater}{not greater}, since the string "2" +comes after the string "10" when arranged alphabetically. + +As with \cs{DTLifstringlt}, uppercase characters are considered +to be less than lower case characters when performing a +case sensitive comparison so: +\begin{verbatim} +\DTLifstringgt{B}{a}{greater}{not greater} +\end{verbatim} +produces: +\DTLifstringgt{B}{a}{greater}{not greater}, whereas +\begin{verbatim} +\DTLifstringgt*{B}{a}{greater}{not greater} +\end{verbatim} +produces: +\DTLifstringgt*{B}{a}{greater}{not greater}. + +\begin{definition}[\DescribeMacro{\DTLifgt}]% +\cs{DTLifgt}\marg{arg1}\marg{arg2}\marg{true part}\marg{false part} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLifgt*}]% +\cs{DTLifgt*}\marg{arg1}\marg{arg2}\marg{true part}\marg{false part} +\end{definition} +If \meta{arg1} and \meta{arg2} are both numerical, then this +is equivalent to \cs{DTLifnumgt}, otherwise it is equivalent +to \cs{DTLstringgt} (when using \cs{DTLifgt}) or +\cs{DTLstringgt*} (when using \cs{DTLifgt*}). + +\begin{definition}[\DescribeMacro{\DTLifnumclosedbetween}]% +\cs{DTLifnumclosedbetween}\marg{num}\marg{min}\marg{max}\marg{true part}\marg{false part} +\end{definition} +If \meta{min} $\leq$ \meta{num} $\leq$ \meta{max} then do \meta{true part}, +otherwise do \meta{false part}. Note that \meta{num}, \meta{min} and +\meta{max} must be numerical (either integers, real numbers or +currency). The currency symbol is ignored when determining +equality. For example: +\begin{verbatim} +\DTLifnumclosedbetween{5.4}{5}{7}{inside}{outside} +\end{verbatim} +produces: +\DTLifnumclosedbetween{5.4}{5}{7}{inside}{outside}. +Note that the closed range includes end points: +\begin{verbatim} +\DTLifnumclosedbetween{5}{5}{7}{inside}{outside} +\end{verbatim} +produces: +\DTLifnumclosedbetween{5}{5}{7}{inside}{outside}. + +\begin{definition}[\DescribeMacro{\DTLifstringclosedbetween}]% +\cs{DTLifstringclosedbetween}\marg{string}\marg{min}\marg{max}\marg{true part}\marg{false part} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLifstringclosedbetween*}]% +\cs{DTLifstringclosedbetween*}\marg{string}\marg{min}\marg{max}\marg{true part}\marg{false part} +\end{definition} +This determines if \meta{string} is between \meta{min} and +\meta{max} in the alphabetical sense, or is equal to either +\meta{min} or \meta{max}. The starred version ignores the case, +the unstarred version is case sensitive. + +\begin{definition}[\DescribeMacro{\DTLifclosedbetween}]% +\cs{DTLifclosedbetween}\marg{arg}\marg{min}\marg{max}\marg{true part}\marg{false part} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLifclosedbetween*}]% +\cs{DTLifclosedbetween*}\marg{arg}\marg{min}\marg{max}\marg{true part}\marg{false part} +\end{definition} +If \meta{arg}, \meta{min} and \meta{max} are numerical, then this is +equivalent to\newline +\cs{DTLifnumclosedbetween}\newline +otherwise it is equivalent to\newline +\cs{DTLifstringclosedbetween}\newline +(when using \cs{DTLifclosedbetween}) or\newline +\cs{DTLifstringclosedbetween*}\newline +(when using \cs{DTLifclosedbetween*}). + +\begin{definition}[\DescribeMacro{\DTLifnumopenbetween}]% +\cs{DTLifnumopenbetween}\marg{num}\marg{min}\marg{max}\marg{true part}\marg{false part} +\end{definition} +If \meta{min} $<$ \meta{num} $<$ \meta{max} then do \meta{true part}, +otherwise do \meta{false part}. Note that \meta{num}, \meta{min} and +\meta{max} must be numerical (either integers, real numbers or +currency). Again, the currency symbol is ignored when determining +equality. For example: +\begin{verbatim} +\DTLifnumopenbetween{5.4}{5}{7}{inside}{outside} +\end{verbatim} +produces: +\DTLifnumopenbetween{5.4}{5}{7}{inside}{outside}. +Note that end points are not included. For example: +\begin{verbatim} +\DTLifnumopenbetween{5}{5}{7}{inside}{outside} +\end{verbatim} +produces: +\DTLifnumopenbetween{5}{5}{7}{inside}{outside}. + +\begin{definition}[\DescribeMacro{\DTLifstringopenbetween}]% +\cs{DTLifstringopenbetween}\marg{string}\marg{min}\marg{max}\marg{true part}\marg{false part} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLifstringopenbetween*}]% +\cs{DTLifstringopenbetween*}\marg{string}\marg{min}\marg{max}\marg{true part}\marg{false part} +\end{definition} +This determines if \meta{string} is between \meta{min} and +\meta{max} in the alphabetical sense. +The starred version ignores the case, +the unstarred version is case sensitive. + +\begin{definition}[\DescribeMacro{\DTLifopenbetween}]% +\cs{DTLifopenbetween}\marg{arg}\marg{min}\marg{max}\marg{true part}\marg{false part} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLifopenbetween*}]% +\cs{DTLifopenbetween*}\marg{arg}\marg{min}\marg{max}\marg{true part}\marg{false part} +\end{definition} +If \meta{arg}, \meta{min} and \meta{max} are numerical, then this is +equivalent to +\cs{DTLifnumopenbetween} +otherwise it is equivalent to +\cs{DTLifstringopenbetween} +(when using \cs{DTLifopenbetween}) or +\cs{DTLifstringopenbetween*} +(when using \cs{DTLifopenbetween*}). + +\begin{definition}[\DescribeMacro{\DTLifFPclosedbetween}]% +\cs{DTLifFPclosedbetween}\marg{num}\marg{min}\marg{max}\marg{true part}\marg{false part} +\end{definition} +If \meta{min} $\leq$ \meta{num} $\leq$ \meta{max} then do \meta{true part}, +otherwise do \meta{false part} where \meta{num}, \meta{min} +and \meta{max} are all in standard fixed point notation (i.e.\ +no number group separator, no currency symbols and a full stop as +a decimal point). + +\begin{definition}[\DescribeMacro{\DTLifFPopenbetween}]% +\cs{DTLifFPopenbetween}\marg{num}\marg{min}\marg{max}\marg{true part}\marg{false part} +\end{definition} +If \meta{min} $<$ \meta{num} $<$ \meta{max} then do \meta{true part}, +otherwise do \meta{false part} where \meta{num}, \meta{min} +and \meta{max} are all in standard fixed point notation (i.e.\ +no number group separator, no currency symbols and a full stop as +a decimal point). + +\begin{definition}[\DescribeMacro{\DTLifAllUpperCase}]% +\cs{DTLifAllUpperCase}\marg{string}\marg{true part}\marg{false part} +\end{definition} +Tests if \meta{string} is all upper case. For example: +\begin{verbatim} +\DTLifAllUpperCase{WORD}{all upper}{not all upper} +\end{verbatim} +produces: +\DTLifAllUpperCase{WORD}{all upper}{not all upper}, +whereas +\begin{verbatim} +\DTLifAllUpperCase{Word}{all upper}{not all upper} +\end{verbatim} +produces: +\DTLifAllUpperCase{Word}{all upper}{not all upper}. +Note also that: +\begin{verbatim} +\DTLifAllUpperCase{\MakeUppercase{word}}{all upper}{not all upper} +\end{verbatim} +also produces: +\DTLifAllUpperCase{\MakeUppercase{word}}{all upper}{not all upper}. +\cs{MakeTextUppercase} (defined in David Carlisle's \sty{textcase} +package) and \cs{uppercase} are also detected, otherwise, if +a command is encountered, the case of the command is considered. +For example: +\begin{verbatim} +\DTLifAllUpperCase{MAN{\OE}UVRE}{all upper}{not all upper} +\end{verbatim} +produces: +\DTLifAllUpperCase{MAN{\OE}UVRE}{all upper}{not all upper}. + +\begin{definition}[\DescribeMacro{\DTLifAllLowerCase}]% +\cs{DTLifAllLowerCase}\marg{string}\marg{true part}\marg{false part} +\end{definition} +Tests if \meta{string} is all lower case. For example: +\begin{verbatim} +\DTLifAllLowerCase{word}{all lower}{not all lower} +\end{verbatim} +produces: +\DTLifAllLowerCase{word}{all lower}{not all lower}, +whereas +\begin{verbatim} +\DTLifAllLowerCase{Word}{all lower}{not all lower} +\end{verbatim} +produces: +\DTLifAllLowerCase{Word}{all lower}{not all lower}. +Note also that: +\begin{verbatim} +\DTLifAllLowerCase{\MakeLowercase{WORD}}{all lower}{not all lower} +\end{verbatim} +also produces: +\DTLifAllLowerCase{\MakeLowercase{WORD}}{all lower}{not all lower}. +\cs{MakeTextLowercase} (defined in David Carlisle's \sty{textcase} +package) and \cs{lowercase} are also detected, otherwise, if +a command is encountered, the case of the command is considered. +For example: +\begin{verbatim} +\DTLifAllLowerCase{man{\oe}uvre}{all lower}{not all lower} +\end{verbatim} +produces: +\DTLifAllLowerCase{man{\oe}uvre}{all lower}{not all lower}. + +\begin{definition}[\DescribeMacro{\DTLifSubString}]% +\cs{DTLifSubString}\marg{string}\marg{substring}\marg{true +part}\marg{false part} +\end{definition} +This tests if \meta{substring} is a sub-string of \meta{string}. +This command performs a case sensitive match. For example: +\begin{verbatim} +\DTLifSubString{An apple}{app}{is substring}{isn't substring} +\end{verbatim} +produces: +\DTLifSubString{An apple}{app}{is substring}{isn't substring}. +Note that spaces are considered to be equivalent to \cs{space} +or "~", so +\begin{verbatim} +\DTLifSubString{An apple}{n~a}{is substring}{isn't substring} +\end{verbatim} +produces: +\DTLifSubString{An apple}{n~a}{is substring}{isn't substring}, +but other commands are skipped, so +\begin{verbatim} +\DTLifSubString{An \uppercase{a}pple}{app}{is substring}{isn't +substring} +\end{verbatim} +produces: +\DTLifSubString{An \uppercase{a}pple}{app}{is substring}{isn't +substring}, since the \cs{uppercase} command is ignored. Note also +that grouping is ignored, so: +\begin{verbatim} +\DTLifSubString{An {ap}ple}{app}{is substring}{isn't substring} +\end{verbatim} +produces: +\DTLifSubString{An {ap}ple}{app}{is substring}{isn't substring}. + +\cs{DTLifSubString} is case sensitive, so: +\begin{verbatim} +\DTLifSubString{An Apple}{app}{is substring}{isn't substring} +\end{verbatim} +produces: +\DTLifSubString{An Apple}{app}{is substring}{isn't substring}. + +\begin{definition}[\DescribeMacro{\DTLifStartsWith}]% +\cs{DTLifStartsWith}\marg{string}\marg{substring}\marg{true +part}\marg{false part} +\end{definition} +This is like \cs{DTLifSubString}, except that \meta{substring} must +occur at the start of \meta{string}. This command performs a case +sensitive match. For example, +\begin{verbatim} +\DTLifStartsWith{An apple}{app}{prefix}{not a prefix} +\end{verbatim} +produces: +\DTLifStartsWith{An apple}{app}{prefix}{not a prefix}. All the +above remarks for \cs{DTLifSubString} also applies to +\cs{DTLifStartsWith}. For example: +\begin{verbatim} +\DTLifStartsWith{\uppercase{a}n apple}{an~}{prefix}{not a prefix} +\end{verbatim} +produces: +\DTLifStartsWith{\uppercase{a}n apple}{an~}{prefix}{not a prefix}, +since \cs{uppercase} is ignored, and "~" is considered to be the +same as a space, whereas +\begin{verbatim} +\DTLifStartsWith{An apple}{an~}{prefix}{not a prefix} +\end{verbatim} +produces: +\DTLifStartsWith{An apple}{an~}{prefix}{not a prefix}. + +\section{\texorpdfstring{\sty{ifthen}}{ifthen} conditionals} +\label{sec:ifthen} + +The commands described in the previous section can not be +used as the conditional part of the \cs{ifthenelse} or +\cs{whiledo} commands provided by the \sty{ifthen} package. +This section describes analogous commands which may only be +used in the conditional argument of \cs{ifthenelse} and +\cs{whiledo}. These may be used with the boolean operations +\cs{not}, \cs{and} and \cs{or} provided by the \sty{ifthen} package. +See the \sty{ifthen} documentation for further details. + +\begin{definition}[\DescribeMacro{\DTLisstring}]% +\cs{DTLisstring}\marg{text} +\end{definition} +Tests if \meta{text} is a string. For example: +\begin{verbatim} +\ifthenelse{\DTLisstring{some text}}{string}{not a string} +\end{verbatim} +produces: +\ifthenelse{\DTLisstring{some text}}{string}{not a string}. + +\begin{definition}[\DescribeMacro{\DTLisnumerical}]% +\cs{DTLisnumerical}\marg{text} +\end{definition} +Tests if \meta{text} is numerical (i.e.\ not a string). For example: +\begin{verbatim} +\ifthenelse{\DTLisnumerical{\$10.95}}{numerical}{not numerical} +\end{verbatim} +produces: +\ifthenelse{\DTLisnumerical{\$10.95}}{numerical}{not numerical}. + +Note however that \cs{DTLisnumerical} requires more care than +\cs{DTLifnumerical} when used with some of the other currency +symbols. Consider: +\begin{verbatim} +\DTLifnumerical{\pounds10.95}{numerical}{not numerical} +\end{verbatim} +This produces: +\DTLifnumerical{\pounds10.95}{numerical}{not numerical}. +However +\begin{verbatim} +\ifthenelse{\DTLisnumerical{\pounds10.95}}{numerical}{not numerical} +\end{verbatim} +produces: +\ifthenelse{\DTLisnumerical{\pounds10.95}}{numerical}{not numerical}. +This is due to the expansion that occurs within \cs{ifthenelse}. +This can be prevented using \cs{noexpand}, for example: +\begin{verbatim} +\ifthenelse{\DTLisnumerical{\noexpand\pounds10.95}}{numerical}{not numerical} +\end{verbatim} +produces: +\ifthenelse{\DTLisnumerical{\noexpand\pounds10.95}}{numerical}{not numerical}. + +Likewise: +\begin{verbatim} +\def\cost{\pounds10.95}% +\ifthenelse{\DTLisnumerical{\noexpand\cost}}{numerical}{not numerical} +\end{verbatim} +produces: +\def\cost{\pounds10.95}\relax +\ifthenelse{\DTLisnumerical{\noexpand\cost}}{numerical}{not numerical}. + +\begin{definition}[\DescribeMacro{\DTLiscurrency}]% +\cs{DTLiscurrency}\marg{text} +\end{definition} +Tests if \meta{text} is currency. For example: +\begin{verbatim} +\ifthenelse{\DTLiscurrency{\$10.95}}{currency}{not currency} +\end{verbatim} +produces: +\ifthenelse{\DTLiscurrency{\$10.95}}{currency}{not currency}. + +The same warning given above for \cs{DTLisnumerical} also applies +here. + +\begin{definition}[\DescribeMacro{\DTLiscurrencyunit}]% +\cs{DTLiscurrencyunit}\marg{text}\marg{symbol} +\end{definition} +Tests if \meta{text} is currency and that currency uses \meta{symbol} as the unit +of currency. +For example: +\begin{verbatim} +\ifthenelse{\DTLiscurrencyunit{\$6.99}{\$}}{dollars}{not dollars} +\end{verbatim} +produces: +\ifthenelse{\DTLiscurrencyunit{\$6.99}{\$}}{dollars}{not dollars}. +Another example: +\begin{verbatim} +\def\cost{\euro10.50}% +\ifthenelse{\DTLiscurrencyunit{\noexpand\cost}{\noexpand\euro}}% +{euros}{not euros} +\end{verbatim} +produces: +\def\cost{\euro10.50}\relax +\ifthenelse{\DTLiscurrencyunit{\noexpand\cost}{\noexpand\euro}}% +{euros}{not euros}. Again note the use of \cs{noexpand}. + +\begin{definition}[\DescribeMacro{\DTLisreal}]% +\cs{DTLisreal}\marg{text} +\end{definition} +Tests if \meta{text} is a fixed point number (again, an integer is +not considered to be a fixed point number). For example: +\begin{verbatim} +\ifthenelse{\DTLisreal{1.5}}{real}{not real} +\end{verbatim} +produces: +\ifthenelse{\DTLisreal{1.5}}{real}{not real}. + +\begin{definition}[\DescribeMacro{\DTLisint}]% +\cs{DTLisint}\marg{text} +\end{definition} +Tests if \meta{text} is an integer. For example: +\begin{verbatim} +\ifthenelse{\DTLisint{153}}{integer}{not an integer} +\end{verbatim} +produces: +\ifthenelse{\DTLisint{153}}{integer}{not an integer}. + +\begin{definition}[\DescribeMacro{\DTLislt}]% +\cs{DTLislt}\marg{arg1}\marg{arg2} +\end{definition} +This checks if \meta{arg1} is less than \meta{arg2}. As with +\cs{DTLiflt}, if \meta{arg1} and \meta{arg2} are numerical, +a numerical comparison is used, otherwise a case sensitive +alphabetical comparison is used. (Note that there is no starred +version of this command, but you can instead use \cs{DTLisilt} +to ignore the case.) + +\begin{definition}[\DescribeMacro{\DTLisilt}]% +\cs{DTLisilt}\marg{arg1}\marg{arg2} +\end{definition} +This checks if \meta{arg1} is less than \meta{arg2}. As with +\cs{DTLiflt*}, if \meta{arg1} and \meta{arg2} are numerical, +a numerical comparison is used, otherwise a case insensitive +alphabetical comparison is used. + +\begin{definition}[\DescribeMacro{\DTLisgt}]% +\cs{DTLisgt}\marg{arg1}\marg{arg2} +\end{definition} +This checks if \meta{arg1} is greater than \meta{arg2}. As with +\cs{DTLifgt}, if \meta{arg1} and \meta{arg2} are numerical, +a numerical comparison is used, otherwise a case sensitive +alphabetical comparison is used. (Note that there is no starred +version of this command, instead use \cs{DTLisigt} to +ignore the case.) + +\begin{definition}[\DescribeMacro{\DTLisigt}]% +\cs{DTLisigt}\marg{arg1}\marg{arg2} +\end{definition} +This checks if \meta{arg1} is greater than \meta{arg2}. As with +\cs{DTLifgt*}, if \meta{arg1} and \meta{arg2} are numerical, +a numerical comparison is used, otherwise a case insensitive +alphabetical comparison is used. + +\begin{definition}[\DescribeMacro{\DTLiseq}]% +\cs{DTLiseq}\marg{arg1}\marg{arg2} +\end{definition} +This checks if \meta{arg1} is equal to \meta{arg2}. As with +\cs{DTLifeq}, if \meta{arg1} and \meta{arg2} are numerical, +a numerical comparison is used, otherwise a case sensitive +alphabetical comparison is used. (Note that there is no starred +version of this command, instead use \cs{DTLisieq}.) + +\begin{definition}[\DescribeMacro{\DTLisieq}]% +\cs{DTLisieq}\marg{arg1}\marg{arg2} +\end{definition} +This checks if \meta{arg1} is equal to \meta{arg2}. As with +\cs{DTLifeq*}, if \meta{arg1} and \meta{arg2} are numerical, +a numerical comparison is used, otherwise a case insensitive +alphabetical comparison is used. + +\begin{definition}[\DescribeMacro{\DTLisclosedbetween}]% +\cs{DTLisclosedbetween}\marg{arg}\marg{min}\marg{max} +\end{definition} +This checks if \meta{arg} lies between \meta{min} and +\meta{max} (end points included). As with +\cs{DTLifclosedbetween}, if the arguments are numerical, +a numerical comparison is used, otherwise a case sensitive +alphabetical comparison is used. (Note that there is no starred +version of this command, instead use \cs{DTLisiclosedbetween}.) + +\begin{definition}[\DescribeMacro{\DTLisiclosedbetween}]% +\cs{DTLisiclosedbetween}\marg{arg}\marg{min}\marg{max} +\end{definition} +This checks if \meta{arg} lies between \meta{min} and +\meta{max} (end points included). As with +\cs{DTLifclosedbetween*}, if the arguments are numerical, +a numerical comparison is used, otherwise a case insensitive +alphabetical comparison is used. + +\begin{definition}[\DescribeMacro{\DTLisopenbetween}]% +\cs{DTLisopenbetween}\marg{arg}\marg{min}\marg{max} +\end{definition} +This checks if \meta{arg} lies between \meta{min} and +\meta{max} (end points excluded). As with +\cs{DTLifopenbetween}, if the arguments are numerical, +a numerical comparison is used, otherwise a case sensitive +alphabetical comparison is used. (Note that there is no starred +version of this command, instead use \cs{DTLisiopenbetween}.) + +\begin{definition}[\DescribeMacro{\DTLisiopenbetween}]% +\cs{DTLisiopenbetween}\marg{arg}\marg{min}\marg{max} +\end{definition} +This checks if \meta{arg} lies between \meta{min} and +\meta{max} (end points excluded). As with +\cs{DTLifopenbetween*}, if the arguments are numerical, +a numerical comparison is used, otherwise a case insensitive +alphabetical comparison is used. + +\begin{definition}[\DescribeMacro{\DTLisFPlt}]% +\cs{DTLisFPlt}\marg{num1}\marg{num2} +\end{definition} +This checks if \meta{num1} is less than \meta{num2}, where both +numbers are in standard fixed point format (i.e.\ no number group +separators, no currency and a full stop as a decimal point). + +\begin{definition}[\DescribeMacro{\DTLisFPlteq}]% +\cs{DTLisFPlteq}\marg{num1}\marg{num2} +\end{definition} +This checks if \meta{num1} is less than or equal to \meta{num2}, where both +numbers are in standard fixed point format (i.e.\ no number group +separators, no currency and a full stop as a decimal point). + +\begin{definition}[\DescribeMacro{\DTLisFPgt}]% +\cs{DTLisFPgt}\marg{num1}\marg{num2} +\end{definition} +This checks if \meta{num1} is greater than \meta{num2}, where both +numbers are in standard fixed point format (i.e.\ no number group +separators, no currency and a full stop as a decimal point). + +\begin{definition}[\DescribeMacro{\DTLisFPgteq}]% +\cs{DTLisFPgteq}\marg{num1}\marg{num2} +\end{definition} +This checks if \meta{num1} is greater than or equal to \meta{num2}, where both +numbers are in standard fixed point format (i.e.\ no number group +separators, no currency and a full stop as a decimal point). + +\begin{definition}[\DescribeMacro{\DTLisFPeq}]% +\cs{DTLisFPeq}\marg{num1}\marg{num2} +\end{definition} +This checks if \meta{num1} is equal to \meta{num2}, where both +numbers are in standard fixed point format (i.e.\ no number group +separators, no currency and a full stop as a decimal point). + +\begin{definition}[\DescribeMacro{\DTLisFPclosedbetween}]% +\cs{DTLisFPclosedbetween}\marg{num}\marg{min}\marg{max} +\end{definition} +This checks if \meta{num} lies between \meta{min} and +\meta{max} (end points included). All arguments must be +numbers in standard fixed point format (i.e.\ no number group +separators, no currency and a full stop as a decimal point). + +\begin{definition}[\DescribeMacro{\DTLisFPopenbetween}]% +\cs{DTLisFPopenbetween}\marg{num}\marg{min}\marg{max} +\end{definition} +This checks if \meta{num} lies between \meta{min} and +\meta{max} (end points excluded). All arguments must be +numbers in standard fixed point format (i.e.\ no number group +separators, no currency and a full stop as a decimal point). + +\begin{definition}[\DescribeMacro{\DTLisSubString}]% +\cs{DTLisSubString}\marg{string}\marg{substring} +\end{definition} +This checks if \meta{substring} is contained in \meta{string}. +The remarks about \cs{DTLifSubString} also apply to +\cs{DTLisSubString}. This command performs a case sensitive +match. + +\begin{definition}[\DescribeMacro{\DTLisPrefix}]% +\cs{DTLisPrefix}\marg{string}\marg{prefix} +\end{definition} +This checks if \meta{string} starts with \meta{prefix}. +The remarks about \cs{DTLifStartsWith} also apply to +\cs{DTLisPrefix}. This command performs a case sensitive +match. + +\chapter{Fixed Point Arithmetic} +\label{sec:fp} + +The \sty{datatool-base} package uses either the \sty{fp} or the \sty{pgfmath} package to perform +fixed point arithmetic, however all numbers must be converted +from the locale dependent format into the format required by the +\sty{fp} or \sty{pgfmath} packages. A numerical value (i.e.\ an integer, a real +or currency) can be converted into a plain decimal number using +\begin{definition}[\DescribeMacro{\DTLconverttodecimal}]% +\cs{DTLconverttodecimal}\marg{num}\marg{cmd} +\end{definition} +The decimal number will be stored in \meta{cmd} which must be +a control sequence. For example: +\begin{verbatim} +\DTLconverttodecimal{1,563.54}{\mynum} +\end{verbatim} +\DTLconverttodecimal{1,563.54}{\mynum}\relax +will define \cs{mynum} to be \texttt{\mynum}. The command \cs{mynum} +can then be used in any of the arithmetic macros provided by the +\sty{fp} or \sty{pgfmath} packages. + +\begin{important} +The arguments to \cs{DTLconverttodecimal} don't get fully expanded +so, for example, +\begin{verbatim} +\def\myval{1.23} +\DTLconverttodecimal{\myval}{\mynum} +\end{verbatim} +will work, but the following \emph{\bfseries won't} work: +\begin{verbatim} +\def\myval{1.23} +\def\myotherval{\myval} +\DTLconverttodecimal{\myotherval}{\mynum} +\end{verbatim} +Nor will the following work: +\begin{verbatim} +\def\myval{9} +\DTLconverttodecimal{\myval 9}{\mynum} +\end{verbatim} +\end{important} +There are two commands provided to perform +the reverse: +\begin{definition}[\DescribeMacro{\DTLdecimaltolocale}]% +\cs{DTLdecimaltolocale}\marg{number}\marg{cmd} +\end{definition} +This converts a plain decimal number \meta{number} (that uses a full +stop as the decimal character and has no number group characters) +into a locale dependent format. The resulting number is stored +in \meta{cmd}, which must be a control sequence. For example: +\begin{verbatim} +\DTLdecimaltolocale{6795.3}{\mynum} +\end{verbatim} +\DTLdecimaltolocale{6795.3}{\mynum} +will define \cs{mynum} to be \texttt{\mynum}. + +\begin{definition}[\DescribeMacro{\DTLdecimaltocurrency}]% +\cs{DTLdecimaltocurrency}\marg{number}\marg{cmd} +\end{definition} +This will convert a plain decimal number \meta{number} into a +locale dependent currency format. For example: +\begin{verbatim} +\DTLdecimaltocurrency{267.5}{\price}\price +\end{verbatim} +will produce: +\DTLdecimaltocurrency{267.5}{\price}\price. + +The currency symbol used by \cs{DTLdecimaltocurrency} is +initially "\$", but it will use the currency last encountered. +So, for example +\begin{verbatim} +\DTLifcurrency{\texteuro45.00}{}{}% +\DTLdecimaltocurrency{267.5}{\price}\price +\end{verbatim} +will produce: +\DTLifcurrency{\texteuro45.00}{}{}\relax +\DTLdecimaltocurrency{267.5}{\price}\price. This is because +the last currency symbol to be encountered was \cs{texteuro}. +You can reset the currency symbol using the command: +\begin{definition}[\DescribeMacro{\DTLsetdefaultcurrency}]% +\cs{DTLsetdefaultcurrency}\marg{symbol} +\end{definition} +For example: +\begin{verbatim} +\DTLsetdefaultcurrency{\textyen}% +\DTLdecimaltocurrency{267.5}{\price}\price +\end{verbatim} +will produce: +\DTLsetdefaultcurrency{\textyen}\relax +\DTLdecimaltocurrency{267.5}{\price}\price + +The \sty{datatool-base} package provides convenience commands which +use \cs{DTLconverttodecimal}, and then use the basic macros provided +by the \sty{fp}\slash\sty{pgfmath} package. The resulting value is then converted +back into the locale format using +\cs{DTLdecimaltolocale} or \cs{DTLdecimaltocurrency}. +Note that since these commands use \cs{DTLconverttodecimal} the +caveat above regarding expansion also applies to all the commands. + + +\begin{definition}[\DescribeMacro{\DTLadd}]% +\cs{DTLadd}\marg{cmd}\marg{num1}\marg{num2} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLgadd}]% +\cs{DTLgadd}\marg{cmd}\marg{num1}\marg{num2} +\end{definition} +This sets the control sequence \meta{cmd} to \meta{num1}+\meta{num2}. +\cs{DLTadd} sets \meta{cmd} locally, while \cs{DTLgadd} sets +\meta{cmd} globally. + +For example: +\begin{verbatim} +\DTLadd{\result}{3,562.65}{412.2}\result +\end{verbatim} +will produce: +\DTLadd{\result}{3,562.65}{412.2}\result. Since +\cs{DTLconverttodecimal} can convert currency to a real +number, you can also add prices. For example: +\begin{verbatim} +\DTLadd{\result}{\pounds3,562.65}{\pounds452.2}\result +\end{verbatim} +produces: +\DTLadd{\result}{\pounds3,562.65}{\pounds452.2}\result. + +Note that \sty{datatool} isn't aware of exchange rates! If you +use different currency symbols, the last symbol will be used. +For example +\begin{verbatim} +\DTLadd{\result}{\pounds3,562.65}{\euro452.2}\result +\end{verbatim} +produces: +\DTLadd{\result}{\pounds3,562.65}{\euro452.2}\result. + +Likewise, if one value is a number and the other is a currency, +the type of the last value, \meta{num2}, will be used for the +result. For example: +\begin{verbatim} +\DTLadd{\result}{3,562.65}{\$452.2}\result +\end{verbatim} +produces: +\DTLadd{\result}{3,562.65}{\$452.2}\result. + +\begin{definition}[\DescribeMacro{\DTLaddall}]% +\cs{DTLaddall}\marg{cmd}\marg{number list} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLgaddall}]% +\cs{DTLgaddall}\marg{cmd}\marg{number list} +\end{definition} +This sets the control sequence \meta{cmd} to the sum of all +the numbers in \meta{number list}. +\cs{DLTaddall} sets \meta{cmd} locally, while \cs{DTLgaddall} sets +\meta{cmd} globally. Example: +\begin{verbatim} +\DTLaddall{\total}{25.1,45.2,35.6}\total +\end{verbatim} +produces: +\DTLaddall{\total}{25.1,45.2,35.6}\total. +Note that if any of the numbers in \meta{number list} contain +a comma, you must group the number. Example: +\begin{verbatim} +\DTLaddall{\total}{{1,525},{2,340},500}\total +\end{verbatim} +produces: +\DTLaddall{\total}{{1,525},{2,340},500}\total. + +\begin{definition}[\DescribeMacro{\DTLsub}]% +\cs{DTLsub}\marg{cmd}\marg{num1}\marg{num2} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLgsub}]% +\cs{DTLgsub}\marg{cmd}\marg{num1}\marg{num2} +\end{definition} +This sets the control sequence \meta{cmd} to +\meta{num1}$-$\meta{num2}. +\cs{DLTsub} sets \meta{cmd} locally, while \cs{DTLgsub} sets +\meta{cmd} globally. + +For example: +\begin{verbatim} +\DTLsub{\result}{3,562.65}{412.2}\result +\end{verbatim} +will produce: +\DTLsub{\result}{3,562.65}{412.2}\result. As with \cs{DTLadd}, +\meta{num1} and \meta{num2} may be currency. + +\begin{definition}[\DescribeMacro{\DTLmul}]% +\cs{DTLmul}\marg{cmd}\marg{num1}\marg{num2} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLgmul}]% +\cs{DTLgmul}\marg{cmd}\marg{num1}\marg{num2} +\end{definition} +This sets the control sequence \meta{cmd} to +\meta{num1}$\times$\meta{num2}. +\cs{DLTmul} sets \meta{cmd} locally, while \cs{DTLgmul} sets +\meta{cmd} globally. + +For example: +\begin{verbatim} +\DTLmul{\result}{568.95}{2}\result +\end{verbatim} +will produce: +\DTLmul{\result}{568.95}{2}\result. Again, \meta{num1} or +\meta{num2} may be currency, but unlike \cs{DTLadd} and \cs{DTLsub}, +currency overrides integer/real. For example: +\begin{verbatim} +\DTLmul{\result}{\pounds568.95}{2}\result +\end{verbatim} +will produce: +\DTLmul{\result}{\pounds568.95}{2}\result. Likewise, +\begin{verbatim} +\DTLmul{\result}{2}{\pounds568.95}\result +\end{verbatim} +will produce: +\DTLmul{\result}{2}{\pounds568.95}\result. Although it doesn't make +sense to multiply two currencies, \sty{datatool} will allow +\begin{verbatim} +\DTLmul{\result}{\$2}{\pounds568.95}\result +\end{verbatim} +which will produce: +\DTLmul{\result}{\$2}{\pounds568.95}\result. + +\begin{definition}[\DescribeMacro{\DTLdiv}]% +\cs{DTLdiv}\marg{cmd}\marg{num1}\marg{num2} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLgdiv}]% +\cs{DTLgdiv}\marg{cmd}\marg{num1}\marg{num2} +\end{definition} +This sets the control sequence \meta{cmd} to +\meta{num1}$\div$\meta{num2}. +\cs{DLTdiv} sets \meta{cmd} locally, while \cs{DTLgdiv} sets +\meta{cmd} globally. + +For example: +\begin{verbatim} +\DTLdiv{\result}{501}{2}\result +\end{verbatim} +will produce: +\DTLdiv{\result}{501}{2}\result. Again, \meta{num1} or \meta{num2} +may be currency, but the resulting type will be not be a currency +if both \meta{num1} and \meta{num2} use the same currency symbol. +For example: +\begin{verbatim} +\DTLdiv{\result}{\$501}{\$2}\result +\end{verbatim} +will produce: +\DTLdiv{\result}{\$501}{\$2}\result. Whereas +\begin{verbatim} +\DTLdiv{\result}{\$501}{2}\result +\end{verbatim} +will produce: +\DTLdiv{\result}{\$501}{2}\result. + +\begin{definition}[\DescribeMacro{\DTLabs}]% +\cs{DTLabs}\marg{cmd}\marg{num} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLgabs}]% +\cs{DTLgabs}\marg{cmd}\marg{num} +\end{definition} +This sets \meta{cmd} to the absolute value of \meta{num}. +\cs{DLTabs} sets \meta{cmd} locally, while \cs{DTLgabs} sets +\meta{cmd} globally. Example: +\begin{verbatim} +\DTLabs{\result}{-\pounds2.50}\result +\end{verbatim} +produces: +\DTLabs{\result}{-\pounds2.50}\result. + +\begin{definition}[\DescribeMacro{\DTLneg}]% +\cs{DTLneg}\marg{cmd}\marg{num} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLgneg}]% +\cs{DTLgneg}\marg{cmd}\marg{num} +\end{definition} +This sets \meta{cmd} to the negative of \meta{num}. +\cs{DLTneg} sets \meta{cmd} locally, while \cs{DTLgneg} sets +\meta{cmd} globally. Example: +\begin{verbatim} +\DTLneg{\result}{\pounds2.50}\result +\end{verbatim} +produces: +\DTLneg{\result}{\pounds2.50}\result. + +\begin{definition}[\DescribeMacro{\DTLsqrt}]% +\cs{DTLsqrt}\marg{cmd}\marg{num} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLgsqrt}]% +\cs{DTLgsqrt}\marg{cmd}\marg{num} +\end{definition} +This sets \meta{cmd} to the sqrt root of \meta{num}. +\cs{DLTsqrt} sets \meta{cmd} locally, while \cs{DTLgsqrt} sets +\meta{cmd} globally. Example: +\begin{verbatim} +\DTLsqrt{\result}{2}\result +\end{verbatim} +produces: +\DTLsqrt{\result}{2}\result. + +\begin{definition}[\DescribeMacro{\DTLmin}]% +\cs{DTLmin}\marg{cmd}\marg{num1}\marg{num2} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLgmin}]% +\cs{DTLgmin}\marg{cmd}\marg{num1}\marg{num2} +\end{definition} +This sets the control sequence \meta{cmd} to the minimum of +\meta{num1} and \meta{num2}. +\cs{DLTmin} sets \meta{cmd} locally, while \cs{DTLgmin} sets +\meta{cmd} globally. For example: +\begin{verbatim} +\DTLmin{\result}{256}{32}\result +\end{verbatim} +produces: +\DTLmin{\result}{256}{32}\result. +Again, \meta{num1} and \meta{num2} may +be currency. For example: +\begin{verbatim} +\DTLmin{\result}{256}{\pounds32}\result +\end{verbatim} +produces: +\DTLmin{\result}{256}{\pounds32}\result, whereas +\begin{verbatim} +\DTLmin{\result}{\pounds256}{32}\result +\end{verbatim} +produces: +\DTLmin{\result}{\pounds256}{32}\result. As mentioned above, +\sty{datatool} doesn't know about exchange rates, so be careful +about mixing currencies. For example: +\begin{verbatim} +\DTLmin{\result}{\pounds5}{\$6}\result +\end{verbatim} +produces: +\DTLmin{\result}{\pounds5}{\$6}\result, which may not necessarily +be true! + +\begin{definition}[\DescribeMacro{\DTLminall}]% +\cs{DTLminall}\marg{cmd}\marg{number list} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLgminall}]% +\cs{DTLgminall}\marg{cmd}\marg{number list} +\end{definition} +This sets the control sequence \meta{cmd} to the minimum of all +the numbers in \meta{number list}. +\cs{DLTminall} sets \meta{cmd} locally, while \cs{DTLgminall} sets +\meta{cmd} globally. Example: +\begin{verbatim} +\DTLminall{\theMin}{25.1,45.2,35.6}\theMin +\end{verbatim} +produces: +\DTLminall{\theMin}{25.1,45.2,35.6}\theMin. +Note that if any of the numbers in \meta{number list} contain +a comma, you must group the number. Example: +\begin{verbatim} +\DTLminall{\theMin}{{1,525},{2,340},500}\theMin +\end{verbatim} +produces: +\DTLminall{\theMin}{{1,525},{2,340},500}\theMin. + +\begin{definition}[\DescribeMacro{\DTLmax}]% +\cs{DTLmax}\marg{cmd}\marg{num1}\marg{num2} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLgmax}]% +\cs{DTLgmax}\marg{cmd}\marg{num1}\marg{num2} +\end{definition} +This sets the control sequence \meta{cmd} to the maximum of +\meta{num1} and \meta{num2}. +\cs{DLTmax} sets \meta{cmd} locally, while \cs{DTLgmax} sets +\meta{cmd} globally. For example: +\begin{verbatim} +\DTLmax{\result}{256}{32}\result +\end{verbatim} +produces: +\DTLmax{\result}{256}{32}\result. +Again, \meta{num1} and \meta{num2} may +be currency, but the same warnings for \cs{DTLmin} apply. + +\begin{definition}[\DescribeMacro{\DTLmaxall}]% +\cs{DTLmaxall}\marg{cmd}\marg{number list} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLgmaxall}]% +\cs{DTLgmaxall}\marg{cmd}\marg{number list} +\end{definition} +This sets the control sequence \meta{cmd} to the maximum of all +the numbers in \meta{number list}. +\cs{DLTmaxall} sets \meta{cmd} locally, while \cs{DTLgmaxall} sets +\meta{cmd} globally. Example: +\begin{verbatim} +\DTLmaxall{\theMax}{25.1,45.2,35.6}\theMax +\end{verbatim} +produces: +\DTLmaxall{\theMax}{25.1,45.2,35.6}\theMax. +Note that if any of the numbers in \meta{number list} contain +a comma, you must group the number. Example: +\begin{verbatim} +\DTLmaxall{\theMax}{{1,525},{2,340},500}\theMax +\end{verbatim} +produces: +\DTLmaxall{\theMax}{{1,525},{2,340},500}\theMax. + +\begin{definition}[\DescribeMacro{\DTLmeanforall}]% +\cs{DTLmeanforall}\marg{cmd}\marg{number list} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLgmeanall}]% +\cs{DTLgmeanforall}\marg{cmd}\marg{number list} +\end{definition} +This sets the control sequence \meta{cmd} to the arithmetic mean of all +the numbers in \meta{number list}. +\cs{DLTmeanforall} sets \meta{cmd} locally, while \cs{DTLgmeanforall} sets +\meta{cmd} globally. Example: +\begin{verbatim} +\DTLmeanforall{\theMean}{25.1,45.2,35.6}\theMean +\end{verbatim} +produces: +\DTLmeanforall{\theMean}{25.1,45.2,35.6}\theMean. +Note that if any of the numbers in \meta{number list} contain +a comma, you must group the number. Example: +\begin{verbatim} +\DTLmeanforall{\theMean}{{1,525},{2,340},500}\theMean +\end{verbatim} +produces: +\DTLmeanforall{\theMean}{{1,525},{2,340},500}\theMean. + +\begin{definition}[\DescribeMacro{\DTLvarianceforall}]% +\cs{DTLvarianceforall}\marg{cmd}\marg{number list} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLgvarianceforall}]% +\cs{DTLgvarianceforall}\marg{cmd}\marg{number list} +\end{definition} +This sets the control sequence \meta{cmd} to the variance of all +the numbers in \meta{number list}. +\cs{DLTvarianceforall} sets \meta{cmd} locally, while \cs{DTLgvarianceforall} sets +\meta{cmd} globally. Example: +\begin{verbatim} +\DTLvarianceforall{\theVar}{25.1,45.2,35.6}\theVar +\end{verbatim} +produces: +\DTLvarianceforall{\theVar}{25.1,45.2,35.6}\theVar. +Again note that if any of the numbers in \meta{number list} +contain a comma, you must group the number. + +\begin{definition}[\DescribeMacro{\DTLsdforall}]% +\cs{DTLsdforall}\marg{cmd}\marg{number list} +\end{definition} +\pagebreak +\begin{definition}[\DescribeMacro{\DTLgsdforall}]% +\cs{DTLgsdforall}\marg{cmd}\marg{number list} +\end{definition} +This sets the control sequence \meta{cmd} to the standard deviation of all +the numbers in \meta{number list}. +\cs{DLTsdforall} sets \meta{cmd} locally, while \cs{DTLgsdforall} sets +\meta{cmd} globally. Example: +\begin{verbatim} +\DTLsdforall{\theSD}{25.1,45.2,35.6}\theSD +\end{verbatim} +produces: +\DTLsdforall{\theSD}{25.1,45.2,35.6}\theSD. +Note that if any of the numbers in \meta{number list} contain +a comma, you must group the number. Example: +\begin{verbatim} +\DTLsdforall{\theSD}{{1,525},{2,340},500}\theSD +\end{verbatim} +produces: +\DTLsdforall{\theSD}{{1,525},{2,340},500}\theSD. + +\begin{definition}[\DescribeMacro{\DTLround}]% +\cs{DTLround}\marg{cmd}\marg{num}\marg{num digits} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLground}]% +\cs{DTLground}\marg{cmd}\marg{num}\marg{num digits} +\end{definition} +This sets \meta{cmd} to \meta{num} rounded to \meta{num digits} +after the decimal character. +\cs{DLTround} sets \meta{cmd} locally, while \cs{DTLground} sets +\meta{cmd} globally. Example: +\begin{verbatim} +\DTLround{\result}{3.135276}{2}\result +\end{verbatim} +produces: \DTLround{\result}{3.135276}{2}\result. + +\begin{definition}[\DescribeMacro{\DTLtrunc}]% +\cs{DTLtrunc}\marg{cmd}\marg{num}\marg{num digits} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLgtrunc}]% +\cs{DTLgtrunc}\marg{cmd}\marg{num}\marg{num digits} +\end{definition} +This sets \meta{cmd} to \meta{num} truncated to \meta{num digits} +after the decimal character. +\cs{DLTtrunc} sets \meta{cmd} locally, while \cs{DTLgtrunc} sets +\meta{cmd} globally. Example: +\begin{verbatim} +\DTLtrunc{\result}{3.135276}{2}\result +\end{verbatim} +produces: \DTLtrunc{\result}{3.135276}{2}\result. + +\pagebreak +\begin{definition}[\DescribeMacro{\DTLclip}]% +\cs{DTLclip}\marg{cmd}\marg{num} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLgclip}]% +\cs{DTLgclip}\marg{cmd}\marg{num} +\end{definition} +This sets \meta{cmd} to \meta{num} with all unnecessary 0's +removed. +\cs{DLTclip} sets \meta{cmd} locally, while \cs{DTLgclip} sets +\meta{cmd} globally. + +\chapter{Strings} +\label{sec:strings} + +Strings are considered to be anything non-numerical. The +\sty{datatool} package loads the \sty{substr} package, so +you can use the commands defined in that package to determine +if one string is contained in another string. In addition, +the \sty{datatool} provides the following macros: + +\begin{definition}[\DescribeMacro{\DTLsubstitute}]% +\cs{DTLsubstitute}\marg{cmd}\marg{original}\marg{replacement} +\end{definition} +This replaces the first occurrence of \meta{original} in +\meta{cmd} with \meta{replacement}. Note that \meta{cmd} must +be the name of a command. For example: +\begin{verbatim} +\def\mystr{abcdce}\DTLsubstitute{\mystr}{c}{z}\mystr +\end{verbatim} +produces: +\def\mystr{abcdce}\DTLsubstitute{\mystr}{c}{z}\mystr. + +\begin{definition}[\DescribeMacro{\DTLsubstituteall}]% +\cs{DTLsubstituteall}\marg{cmd}\marg{original}\marg{replacement} +\end{definition} +This replaces all occurrences of \meta{original} in +\meta{cmd} with \meta{replacement}, where again, \meta{cmd} must +be the name of a command. For example: +\begin{verbatim} +\def\mystr{abcdce}\DTLsubstituteall{\mystr}{c}{z}\mystr +\end{verbatim} +produces: +\def\mystr{abcdce}\DTLsubstituteall{\mystr}{c}{z}\mystr. + +\begin{definition}[\DescribeMacro{\DTLsplitstring}]% +\cs{DTLsplitstring}\marg{string}\marg{split text}\marg{before +cmd}\marg{after cmd} +\end{definition} +This splits \meta{string} at the first occurrence of \meta{split text} +and stores the before part in the command \meta{before cmd} and +the after part in the command \meta{after cmd}. For example: +\begin{verbatim} +\DTLsplitstring{abcdce}{c}{\beforepart}{\afterpart}% +Before part: ``\beforepart''. After part: ``\afterpart'' +\end{verbatim} +produces: +\DTLsplitstring{abcdce}{c}{\beforepart}{\afterpart}\relax +Before part: ``\beforepart''. After part: ``\afterpart''. +Note that for \cs{DTLsplitstring}, \meta{string} is not +expanded, so +\begin{verbatim} +\def\mystr{abcdce}% +\DTLsplitstring{\mystr}{c}{\beforepart}{\afterpart}% +Before part: ``\beforepart''. After part: ``\afterpart'' +\end{verbatim} +produces: +\def\mystr{abcdce}\relax +\DTLsplitstring{\mystr}{c}{\beforepart}{\afterpart}% +Before part: ``\beforepart''. After part: ``\afterpart''. If you +want the string expanded, you will need to use \cs{expandafter}: +\begin{verbatim} +\def\mystr{abcdce}% +\expandafter\DTLsplitstring\expandafter +{\mystr}{c}{\beforepart}{\afterpart}% +Before part: ``\beforepart''. After part: ``\afterpart'' +\end{verbatim} +which produces: +\def\mystr{abcdce}\relax +\expandafter\DTLsplitstring\expandafter +{\mystr}{c}{\beforepart}{\afterpart}\relax +Before part: ``\beforepart''. After part: ``\afterpart''. + +\begin{definition}[\DescribeMacro{\DTLinitials}]% +\cs{DTLinitials}\marg{string} +\end{definition} +This converts \meta{string} (typically a name) into initials. +For example: +\begin{verbatim} +\DTLinitials{Mary Ann} +\end{verbatim} +produces: +\DTLinitials{Mary Ann} (including the final full stop). Note that +\begin{verbatim} +\DTLinitials{Mary-Ann} +\end{verbatim} +produces: +\DTLinitials{Mary-Ann} (including the final full stop). +Be careful if the initial letter has an +accent. The accented letter needs to be placed in a group, if +you want the initial to also have an accent, otherwise the +accent command will be ignored. For example: +\begin{verbatim} +\DTLinitials{{\'E}lise Adams} +\end{verbatim} +produces: +\DTLinitials{{\'E}lise Adams}, whereas +\begin{verbatim} +\DTLinitials{\'Elise Adams} +\end{verbatim} +produces: +\DTLinitials{\'Elise Adams} In fact, any command which appears +at the start of the name that is not enclosed in a group will +be ignored. For example: +\begin{verbatim} +\DTLinitials{\MakeUppercase{m}ary ann} +\end{verbatim} +produces: +\DTLinitials{\MakeUppercase{m}ary ann}, whereas +\begin{verbatim} +\DTLinitials{{\MakeUppercase{m}}ary ann} +\end{verbatim} +produces: +\DTLinitials{{\MakeUppercase{m}}ary ann}, but note that +\begin{verbatim} +\DTLinitials{\MakeUppercase{mary ann}} +\end{verbatim} +produces: +\DTLinitials{\MakeUppercase{mary ann}} + +\begin{definition}[\DescribeMacro{\DTLstoreinitials}]% +\cs{DTLstoreinitials}\marg{string}\marg{cmd} +\end{definition} +This converts \meta{string} into initials and stores the +result in \meta{cmd} which must be a command name. The remarks +about \cs{DTLinitials} also relate to \cs{DTLstoreinitials}. +For example +\begin{verbatim} +\DTLstoreinitials{Marie-{\'E}lise del~Rosario}{\theInitials}\theInitials +\end{verbatim} +produces: +\DTLstoreinitials{Marie-{\'E}lise del~Rosario}{\theInitials}\theInitials + +Both the above commands rely on the following to format the +initials: +\begin{definition}[\DescribeMacro{\DTLafterinitials}]% +\cs{DTLafterinitials} +\end{definition} +This indicates what to do at the end of the initials. This +simply does a full stop by default. + +\begin{definition}[\DescribeMacro{\DTLbetweeninitials}]% +\cs{DTLbetweeninitials} +\end{definition} +This indicates what to do between initials. This does a +full stop by default. + +\begin{definition}[\DescribeMacro{\DTLinitialhyphen}]% +\cs{DTLinitialhyphen} +\end{definition} +This indicates what to do at a hyphen. This simply does a hyphen +by default, but can be redefined to do nothing to prevent the +hyphen appearing in the initials. + +\begin{definition}[\DescribeMacro{\DTLafterinitialbeforehyphen}]% +\cs{DTLafterinitialbeforehyphen} +\end{definition} +This indicates what to do between an initial and a hyphen. +This simply does a full stop by default. + +For example +\begin{verbatim} +\renewcommand*{\DTLafterinitialbeforehyphen}{}% +\DTLinitials{Marie-{\'E}lise del~Rosario} +\end{verbatim} +produces: +{\renewcommand*{\DTLafterinitialbeforehyphen}{}\relax +\DTLinitials{Marie-{\'E}lise del~Rosario}} +whereas +\begin{verbatim} +\renewcommand*{\DTLafterinitialbeforehyphen}{}% +\renewcommand*{\DTLafterinitials}{}% +\renewcommand*{\DTLbetweeninitials}{}% +\renewcommand*{\DTLinitialhyphen}{}% +\DTLinitials{Marie-{\'E}lise del~Rosario} +\end{verbatim} +produces: +{\renewcommand*{\DTLafterinitialbeforehyphen}{}\relax +\renewcommand*{\DTLafterinitials}{}\relax +\renewcommand*{\DTLbetweeninitials}{}\relax +\renewcommand*{\DTLinitialhyphen}{}\relax +\DTLinitials{Marie-{\'E}lise del~Rosario}} + +\chapter{Databases} +\label{sec:databases} + +The \sty{datatool} package provides a means of creating and +loading databases. Once a database has been created (or loaded), +it is possible to iterate through each row of data, to make it +easier to perform repetitive actions, such as mail merging. + +\begin{important} +Whilst \TeX\ is an excellent typesetting language, +it is not designed as a database management system, and +attempting to use it as such is like trying to fasten a screw +with a knife instead of a screwdriver: it can be done, but requires +great care and is more time consuming. Version 2.0 of the +\sty{datatool} package uses a completely different method of storing +the data to previous versions.\footnote{Thanks to Morten H\o gholm +for the suggestion.} As a result, the code is much more efficient, +however, large databases and complex operations will still slow the +time taken to process your document. Therefore, if you can, it is +better to do the complex operations using whatever system created +the data in the first place. +\end{important} + +Some advanced commands for accessing database information are +described in \autoref{sec:advanced}, but using \TeX\ is nowhere near +as efficient as, say, using a SQL database, so don't expect too much +from this package. + +\section{Creating a New Database} +\label{sec:newdb} + +\begin{definition}[\DescribeMacro{\DTLnewdb}]% +\cs{DTLnewdb}\marg{db name} +\end{definition} +This command creates a new empty database called \meta{db name}. You +can test if a database is empty using: +\begin{definition}[\DescribeMacro{\DTLifdbempty}]% +\cs{DTLifdbempty}\marg{db name}\marg{true part}\marg{false part} +\end{definition} +If the database called \meta{db name} is empty, do \meta{true part}, +otherwise do \meta{false part}. + +\begin{definition}[\DescribeMacro{\DTLrowcount}]% +\cs{DTLrowcount}\marg{db name} +\end{definition} +This command displays the number of rows in the database called +\meta{db name}. + +\begin{definition}[\DescribeMacro{\DTLcolumncount}]% +\cs{DTLcolumncount}\marg{db name} +\end{definition} +This command displays the number of columns (or keys) in the +database called \meta{db name}. + +\begin{definition}[\DescribeMacro{\DTLnewrow}]% +\cs{DTLnewrow}\marg{db name} +\end{definition} +This command starts a new row in the database called \meta{db name}. +This new row becomes the current row when adding new entries. + +For example, the following creates an empty database called +\texttt{mydata}: +\begin{verbatim} +\DTLnewdb{mydata} +\end{verbatim} +\DTLnewdb{mydata}\relax +The following tests if the database is empty: +\begin{verbatim} +\DTLifdbempty{mydata}{empty}{not empty}! +\end{verbatim} +This produces: +\DTLifdbempty{mydata}{empty}{not empty}! + +The following adds an empty row to the database, this is the +first row of the database: +\begin{verbatim} +\DTLnewrow{mydata} +\end{verbatim} +\DTLnewrow{mydata}\relax +Note that even though the only row in the database is currently +empty, the database is no longer considered to be empty: +\begin{verbatim} +\DTLifdbempty{mydata}{empty}{not empty}! +\end{verbatim} +This now produces: +\DTLifdbempty{mydata}{empty}{not empty}! The row count is +given by +\begin{verbatim} +\DTLrowcount{mydata} +\end{verbatim} +which produces: +\DTLrowcount{mydata}. The column count is given by +\begin{verbatim} +\DTLcolumncount{mydata} +\end{verbatim} +which produces: \DTLcolumncount{mydata}. + +\begin{definition}[\DescribeMacro{\DTLnewdbentry}]% +\cs{DTLnewdbentry}\marg{db name}\marg{key}\marg{value} +\end{definition} +This creates a new entry with the identifier \meta{key} whose value +is \meta{value} and adds it to the last row of the database +called \meta{db name}. For example: +\begin{verbatim} +\DTLnewdbentry{mydata}{Surname}{Smith} +\DTLnewdbentry{mydata}{FirstName}{John} +\end{verbatim} +Adds an entry with identifier \texttt{Surname} and value +\texttt{Smith} to the last row of the database named +\texttt{mydata}, and then adds an entry with identifier +\texttt{FirstName} and value \texttt{John}. Note that the +key should not contain any fragile commands. It is generally +best to only use non-active characters in the key. + +The value isn't expanded by default, but you can change this +using the declaration: +\begin{definition}[\DescribeMacro{\dtlexpandnewvalue}] +\cs{dtlexpandnewvalue} +\end{definition} +This can be localised by placing it in a group, or you can +switch back using: +\begin{definition}[\DescribeMacro{\dtlnoexpandnewvalue}] +\cs{dtlnoexpandnewvalue} +\end{definition} + +\importantpar +Note that database entries can't contain paragraph +breaks as many of the macros used by \sty{datatool} are short +commands. If you do need a paragraph break in an entry, you can +instead use the command: +\begin{definition}[\DescribeMacro{\DTLpar}]% +\cs{DTLpar} +\end{definition} +For example: +\begin{verbatim} +\DTLnewdbentry{mydata}{Description}{First paragraph.\DTLpar +Second paragraph.} +\end{verbatim} + +\begin{definition}[\DescribeMacro{\DTLaddentryforrow}]% +\cs{DTLaddentryforrow}\marg{db}\marg{assign list}\marg{condition}\marg{key}\marg{value} +\end{definition} +This adds the entry with the key given by \meta{key} and value +given by \meta{value} to the first row in the database +\meta{db} which satisfies the condition given by +\meta{condition}. The \meta{assign list} argument is the same +as for \cs{DTLforeach} (described in \autoref{sec:dbforeach}) +and may be used to set the values which are to be tested in +\meta{condition} (where, again, \meta{condition} is the same +as for \cs{DTLforeach}). For example: +\begin{verbatim} +\DTLaddentryforrow{mydata}{\firstname=FirstName,\surname=Surname}% +{\DTLiseq{\firstname}{John}\and\DTLiseq{\surname}{Smith}}% +{Score}{75} +\end{verbatim} +Note that unlike \cs{DTLnewdbentry}, the value is always expanded +when adding an entry using \cs{DTLaddentryforrow}. + +\begin{definition}[\DescribeMacro{\DTLsetheader}]% +\cs{DTLsetheader}\marg{db}\marg{key}\marg{header} +\end{definition} +This assigns a header for a given key in the database named +\meta{db}. This is used by \cs{DTLdisplaydb} and +\cs{DTLdisplaylongdb} in the header row (see +\autoref{sec:displaydb}). If you don't assign +a header, the header will be given by the key. +For example: +\begin{verbatim} +\DTLsetheader{mydata}{Price}{Price (\$)} +\end{verbatim} + +\section{Loading a Database from an External ASCII File} +\label{sec:loaddb} + +Instead of using the commands described in \autoref{sec:newdb} +to create a new database, you can load a database from an +external ASCII file using: +\begin{definition}[\DescribeMacro{\DTLloaddb}]% +\cs{DTLloaddb}\oarg{options}\marg{db name}\marg{filename} +\end{definition} +\begin{important} +Make sure your document uses the same encoding as \meta{filename}. +For example, if \meta{filename} is UTF-8, then include the following +in your document: +\begin{verbatim} +\usepackage[utf8]{inputenc} +\end{verbatim} +\end{important} +This creates a new database called \meta{db name}, and fills +it with the entries given in the file \meta{filename}. +The filename may have a header row at the start of the file, +which provides the \meta{key} when creating a new database entry +using \ics{DTLnewdbentry}. The optional argument \meta{options} +is a key=value list of options. Available options are: +\begin{description} +\item[\csopt{DTLloaddb}{noheader}] This is a boolean value and +indicates if the file does not contain a header. If no value is +supplied, "true" is assumed (i.e.\ the file doesn't contain a header +row). If this option is omitted, it is assumed that the file +contains a header row. + +\item[\csopt{DTLloaddb}{keys}] This is a comma-separated list of +keys to use, where the keys are listed in the same order as the +columns. If the file has a header, these keys will override the +values given in the header row. If the file has no header row and no +keys are supplied in \meta{options}, then the keys will be given by +\cs{dtldefaultkey}\meta{n}, where \meta{n} is the column number and +\DescribeMacro{\dtldefaultkey}\cs{dtldefaultkey} defaults to +``\dtldefaultkey''. Note that the list of keys must be delimited by +braces since they contain commas. For example: +\begin{verbatim} +\DTLloaddb[noheader,keys={Temperature,Time,T2G}]{data}{data.csv} +\end{verbatim} + +\item[\csopt{DTLloaddb}{headers}] This is a comma-separated list of +headers. If not supplied, the header will be the same as that given +in the header row, or the key if there is no header row. Note that +the list of headers must be delimited by braces since they contain +commas. For example: +\begin{verbatim} +\DTLloaddb[noheader,keys={Temperature,Time,T2G},% +headers={\shortstack{Incubation\\Temperature},% +\shortstack{Incubation\\Time},% +\shortstack{Time to\\Growth}}]{data}{data.csv} +\end{verbatim} + +\item[\csopt{DTLloaddb}{omitlines}] +This should be a non-negative integer that specifies how many rows +to skip at the start of the file. +\end{description} + +By default, the entries in the database +must be separated by a comma, and optionally delimited by the +double quote character (\verb|"|). The separator can be changed +to a tab separator using the command: +\begin{definition}[\DescribeMacro{\DTLsettabseparator}]% +\cs{DTLsettabseparator} +\end{definition} +To set the separator to a character other than a tab, you need to use +\begin{definition}[\DescribeMacro{\DTLsetseparator}]% +\cs{DTLsetseparator}\marg{character} +\end{definition} +The delimiter can be changed using +\begin{definition}[\DescribeMacro{\DTLsetdelimiter}]% +\cs{DTLsetdelimiter}\marg{character} +\end{definition} + +For example, suppose you have a file called \texttt{mydata.csv} +which contains the following: +\begin{verbatim} +FirstName,Surname,Score +John,"Smith, Jr",68 +Jane,Brown,75 +Andy,Brown,42 +Z\"oe,Adams,52 +\end{verbatim} +then +\begin{verbatim} +\DTLloaddb{mydata}{mydata.csv} +\end{verbatim} +is equivalent to: +\begin{verbatim} +\DTLnewdb{mydata} +\DTLnewrow{mydata}% +\DTLnewdbentry{mydata}{FirstName}{John}% +\DTLnewdbentry{mydata}{Surname}{Smith, Jr}% +\DTLnewdbentry{mydata}{Score}{68}% +\DTLnewrow{mydata}% +\DTLnewdbentry{mydata}{FirstName}{Jane}% +\DTLnewdbentry{mydata}{Surname}{Brown}% +\DTLnewdbentry{mydata}{Score}{75}% +\DTLnewrow{mydata}% +\DTLnewdbentry{mydata}{FirstName}{Andy}% +\DTLnewdbentry{mydata}{Surname}{Brown}% +\DTLnewdbentry{mydata}{Score}{42}% +\DTLnewrow{mydata}% +\DTLnewdbentry{mydata}{FirstName}{Z\"oe}% +\DTLnewdbentry{mydata}{Score}{52}% +\DTLnewdbentry{mydata}{Surname}{Adams}% +\end{verbatim} +Note that the entry \texttt{Smith, Jr} had to be delimited in +\texttt{mydata.csv} using the double quote character since it +contained a comma which is used as the separator. +The percent symbol \% can be used as a comment character within the +file. + +The file used in the above example contained a \LaTeX\ command, +namely \verb|\"|. When using \ics{DTLloaddb} all the special +characters that appear in the command retain their \LaTeX\ meaning +when the file is loaded. It is likely however that the data file +may have been created by another application that is not \TeX-aware, +such as a spreadsheet application. For example, suppose you +have a file called, say, \texttt{products.csv} which looks +like: +\begin{verbatim} +Product,Cost +Fruit & Veg,$1.25 +Stationary,$0.80 +\end{verbatim} +This file contains two of \TeX's special characters, namely +"&" and \verb|$|. In this case, if you try to load the file +using \ics{DTLloaddb}, you will encounter errors. Instead you +can use: +\begin{definition}[\DescribeMacro{\DTLloadrawdb}]% +\cs{DTLloadrawdb}\oarg{options}\marg{db name}\marg{filename} +\end{definition} +This is the same as \ics{DTLloaddb} except that it maps nine of +the ten special characters onto commands which produce that +symbol. The only character that retains its active state is the +backslash character, so you will still need to check the file +for backslash characters. The mappings used are listed in +\autoref{tab:rawmappings}. So using the file \texttt{products.csv}, +as described above, +\begin{verbatim} +\DTLloadrawdb{mydata}{products.csv} +\end{verbatim} +is equivalent to: +\begin{verbatim} +\DTLnewdb{mydata} +\DTLnewrow{mydata}% +\DTLnewdbentry{mydata}{Product}{Fruit \& Veg}% +\DTLnewdbentry{mydata}{Cost}{\$1.25}% +\DTLnewrow{mydata}% +\DTLnewdbentry{mydata}{Product}{Stationary}% +\DTLnewdbentry{mydata}{Cost}{\$0.80}% +\end{verbatim} + +\begin{table}[htbp] +\caption[Special character mappings used by +\cs{DTLloadrawdb}]{Special character mappings used by +\cs{DTLloadrawdb} (note that the backslash retains its active state)} +\label{tab:rawmappings} +\centering +\begin{tabular}{cl} +Character & Mapping\\ +\verb|%| & \verb|\%|\\ +\verb|$| & \verb|\$|\\ +\verb|&| & \verb|\&|\\ +\verb|#| & \verb|\#|\\ +\verb|_| & \verb|\_|\\ +\verb|{| & \verb|\{|\\ +\verb|}| & \verb|\}|\\ +\verb|~| & \cs{textasciitilde}\\ +\verb|^| & \cs{textasciicircum} +\end{tabular} +\end{table} + +It may be that there are other characters that require mapping. +For example, the file \texttt{products.csv} may instead look like:\par +\vskip\baselineskip +\begin{ttfamily}\obeylines\setlength{\parindent}{0pt} +Product,Cost +Fruit \& Veg,\pounds1.25 +Stationary,\pounds0.80 +\end{ttfamily} +\vskip\baselineskip +The pound character is not an internationally standard keyboard +character, and does not generally achieve the desired effect when used +in a \LaTeX\ document. It may therefore be necessary to convert +this symbol to an appropriate control sequence. This can be done +using the command: +\begin{definition}[\DescribeMacro{\DTLrawmap}]% +\cs{DTLrawmap}\marg{string}\marg{replacement} +\end{definition} +For example:\par +\vskip\baselineskip +\begin{ttfamily}\obeylines\setlength{\parindent}{0pt} +\cs{DTLrawmap}\char`\{\pounds\char`\}\char`\{\cs{pounds}\char`\} +\end{ttfamily} +\vskip\baselineskip\noindent +will replace all occurrences\footnote{when it is loaded into the +\LaTeX\ database, it does not modify the data file!}\ of +\texttt{\pounds} with \cs{pounds}. Naturally, the mappings must be +set \emph{prior} to loading the data with \cs{DTLloadrawdb}. + +\begin{important} +Note that the warning in the previous section about no +paragraph breaks in an entry also applies to entries loaded from a +database. If you do need a paragraph break, use \ics{DTLpar} instead +of \cs{par}, but remember that each row of data in an external data +file must not have a line break. +\end{important} + +\section{Displaying the Contents of a Database} +\label{sec:displaydb} + +Once you have created a database, either loading it from an +external file, as described in \autoref{sec:loaddb}, or using the +commands described in \autoref{sec:newdb}, you can display the +entire database in a \env{tabular} or \env{longtable} +environment. + +\begin{definition}[\DescribeMacro{\DTLdisplaydb}]% +\cs{DTLdisplaydb}\oarg{omit list}\marg{db} +\end{definition} +This displays the database given by \meta{db} in a \env{tabular} +environment. The first row displays the headers for the database +in bold, the subsequent rows display the values for each key +in each row of the database. The optional argument \meta{omit list} +is a comma-separated list of column keys to omit. (All columns displayed by default.) + +\begin{definition}[\DescribeMacro{\DTLdisplaylongdb}]% +\cs{DTLdisplaylongdb}\oarg{options}\marg{db} +\end{definition} +This is like \cs{DTLdisplaydb} except that it uses the +\env{longtable} environment instead of the \env{tabular} +environment. Note that if you use this command, you must load the +\sty{longtable} package, as it is not loaded by \sty{datatool}. +The optional argument \meta{options} is a comma-separated list +of key=value pairs. The following keys are available: +\begin{description} +\item[caption] The caption for the \env{longtable}. + +\item[contcaption] The continuation caption. + +\item[shortcaption] The caption to be used in the list of figures. + +\item[label] The label for this table. + +\item[omit] Comma-separated list of column keys to omit. + +\item[foot] The \env{longtable}'s foot. + +\item[lastfoot] The foot for the last page of the \env{longtable}. +\end{description} +For example, suppose I have a database called "iris", then I can +display the contents in a \env{longtable} using: +\begin{verbatim} +\DTLdisplaylongdb[% +caption={Iris Data},% +label={tab:iris},% +contcaption={Iris Data (continued)},% +foot={\em Continued overleaf},% +lastfoot={}% +]{iris} +\end{verbatim} +I can then reference the table using \verb|\ref{tab:iris}|. + +See the \sty{longtable} documentation for details on how to +change the \env{longtable} settings, such as how to change the +table so that it is left aligned instead of centred on the page. + +Note that if you want more control over the way the data is +displayed, for example, you want to filter rows or columns, you will +need to use \cs{DTLforeach}, described in \autoref{sec:dbforeach}. + +\begin{example}{Displaying the Contents of a Database}{ex:displaydb} +Suppose I have a file called \texttt{t2g.csv} that contains the +following: +\begin{verbatim} +40,120,40 +40,90,60 +35,180,20 +55,190,40 +\end{verbatim} +This represents time to growth data, where the first column +is the incubation temperature, the second column is the incubation +time and the third column is the time to growth. This file has no +header row, so when it is loaded, the \csopt{DTLloaddb}{noheaders} +option is required. Note that \cs{DTLdisplaydb} only puts the data +in a \env{tabular} environment, so \cs{DTLdisplaydb} needs to be +put in a \env{table} environment with a caption to make it a float. + +First load the data base, setting the keys and headers: +\begin{verbatim} +\DTLloaddb[noheader,% +keys={Temperature,Time,T2G},% +headers={\shortstack{Incubation\\Temperature},% +\shortstack{Incubation\\Time},\shortstack{Time to\\Growth}}% +]{t2g}{t2g.csv} +\end{verbatim} +\DTLnewdb{t2g}\relax +\DTLnewrow*{t2g}\relax +\DTLnewdbentry*{t2g}{Temperature}{40}\relax +\DTLnewdbentry*{t2g}{Time}{120}\relax +\DTLnewdbentry*{t2g}{T2G}{40}\relax +\DTLnewrow*{t2g}\relax +\DTLnewdbentry*{t2g}{Temperature}{40}\relax +\DTLnewdbentry*{t2g}{Time}{90}\relax +\DTLnewdbentry*{t2g}{T2G}{60}\relax +\DTLnewrow*{t2g}\relax +\DTLnewdbentry*{t2g}{Temperature}{35}\relax +\DTLnewdbentry*{t2g}{Time}{180}\relax +\DTLnewdbentry*{t2g}{T2G}{20}\relax +\DTLnewrow*{t2g}\relax +\DTLnewdbentry*{t2g}{Temperature}{55}\relax +\DTLnewdbentry*{t2g}{Time}{190}\relax +\DTLnewdbentry*{t2g}{T2G}{40}\relax +\DTLsetheader*{t2g}{Temperature}{\shortstack{Incubation\\Temperature}}\relax +\DTLsetheader*{t2g}{Time}{\shortstack {Incubation\\Time}}\relax +\DTLsetheader*{t2g}{T2G}{\shortstack {Time to\\Growth}}\relax + +Now display the data in a table: +\begin{verbatim} +\begin{table}[htbp] +\caption{Time to Growth Data} +\centering +\DTLdisplaydb{t2g} +\end{table} +\end{verbatim} +The result is shown in \autoref{tab:t2g}. +\begin{table}[htbp] +\caption{Time to Growth Data} +\label{tab:t2g} +\centering +\DTLdisplaydb{t2g} +\end{table} +\end{example} + +Each column in the database has an associated data type which +indicates what type of data is in that column. This may be one +of: string, integer, real number or currency. If a column contains +more than one type, the data type is determined as follows: +\begin{itemize} +\item If the column contains at least one string, then the column +data type is string. + +\item If the column doesn't contain a string, but contains at least +one currency, then the column data type is currency. + +\item If the column contains only real numbers and integers, the +column data type is real number. + +\item The column data type is integer if the column only +contains integers. +\end{itemize} +The column data type is updated whenever a new entry is added +to the database. Note that the column data type is not adjusted +when an entry is removed from the database. + +The column alignments used by \cs{DTLdisplaydb} are given by: +\begin{definition}[\DescribeMacro{\dtlstringalign}]% +\cs{dtlstringalign} +\end{definition}\noindent +The string alignment defaults to \texttt{l} (left aligned). + +\begin{definition}[\DescribeMacro{\dtlintalign}]% +\cs{dtlintalign} +\end{definition}\noindent +The integer alignment defaults to \texttt{r} (right aligned). + +\begin{definition}[\DescribeMacro{\dtlrealalign}]% +\cs{dtlrealalign} +\end{definition}\noindent +The alignment for real numbers defaults to \texttt{r} (right +aligned). + +\begin{definition}[\DescribeMacro{\dtlcurrencyalign}]% +\cs{dtlcurrencyalign} +\end{definition}\noindent +The currency alignment defaults to \texttt{r} (right aligned). + +You can redefine these to change the column alignments. For +example, if you want columns containing strings to have the +alignment "p{2in}", then you can redefine \cs{dtlstringalign} as +follows: +\begin{verbatim} +\renewcommand{\dtlstringalign}{p{2in}} +\end{verbatim} + +\begin{important} +You can't use \sty{siunitx}'s "S" column alignment +with either \cs{DTLdisplaydb} or \cs{DTLdisplaylongdb}. Instead, you +will need to use \cs{DTLforeach}. The \sty{siunitx} documentation +provides an example. +\end{important} + +In addition to the \cs{dtl}\meta{type}"align" commands above, you +can also modify the \env{tabular} column styles by redefining +\DescribeMacro{\dtlbeforecols}\cs{dtlbeforecols}, +\DescribeMacro{\dtlbetweencols}\cs{dtlbetweencols} and +\DescribeMacro{\dtlaftercols}\cs{dtlaftercols}. For example, to +place a vertical line before the start of the first column and +after the last column, do: +\begin{verbatim} +\renewcommand{\dtlbeforecols}{|} +\renewcommand{\dtlaftercols}{|} +\end{verbatim} +If you additionally want vertical lines between columns, do: +\begin{verbatim} +\renewcommand{\dtlbetweencols}{|} +\end{verbatim} + +Limited modifications can be made to the way the data is displayed +with \cs{DTLdisplaydb} and \cs{DTLdisplaylongdb}. +The commands controlling the formatting are described below. +If a more complicated layout is required, you will need to use +\cs{DTLforeach} described in \autoref{sec:dbforeach}. + +\begin{definition}[\DescribeMacro{\dtlheaderformat}]% +\cs{dtlheaderformat}\marg{header} +\end{definition} +This indicates how to format a column header, where the header is +given by \meta{header}. This defaults to +\cs{null}\cs{hfil}\cs{textbf}\marg{header}\cs{hfil}\cs{null}. + +\begin{definition}[\DescribeMacro{\dtlstringformat}]% +\cs{dtlstringformat}\marg{text} +\end{definition} +This specifies how to format each entry in the columns that contain +strings. This defaults to just displaying \meta{text}. + +\begin{definition}[\DescribeMacro{\dtlintformat}]% +\cs{dtlintformat}\marg{text} +\end{definition} +This specifies how to format each entry in the columns that contain +only integers. This defaults to just displaying \meta{text}. + +\begin{definition}[\DescribeMacro{\dtlrealformat}]% +\cs{dtlrealformat}\marg{text} +\end{definition} +This specifies how to format each entry in the columns that contain +only real numbers or a mixture of real numbers and integers. This +defaults to just displaying \meta{text}. + +\begin{definition}[\DescribeMacro{\dtlcurrencyformat}]% +\cs{dtlcurrencyformat}\marg{text} +\end{definition} +This specifies how to format each entry in the columns that contain +only currency or currency mixed with real numbers and/or integers. +This defaults to just displaying \meta{text}. + +\begin{definition}[\DescribeMacro{\dtldisplaystarttab}]% +\cs{dtldisplaystarttab} +\end{definition} +This is a hook to add something at the beginning of the +\env{tabular} environment. This defaults to nothing. + +\begin{definition}[\DescribeMacro{\dtldisplayendtab}]% +\cs{dtldisplayendtab} +\end{definition} +This is a hook to add something at the end of the +\env{tabular} environment. This defaults to nothing. + +\begin{definition}[\DescribeMacro{\dtldisplayafterhead}]% +\cs{dtldisplayafterhead} +\end{definition} +This is a hook to add something after the header row, before +the first row of data. This defaults to nothing. + +\begin{definition}[\DescribeMacro{\dtldisplaystartrow}]% +\cs{dtldisplaystartrow} +\end{definition} +This is a hook to add something at the start of each row, but +not including the header row or the first row of data. This +defaults to nothing. + +If you want to use the \sty{booktabs} package, you can redefine the +above three commands to use \ics{toprule}, \ics{midrule} and +\ics{bottomrule}: +\begin{verbatim} +\renewcommand{\dtldisplaystarttab}{\toprule} +\renewcommand{\dtldisplayafterhead}{\midrule} +\renewcommand{\dtldisplayendtab}{\\\bottomrule} +\end{verbatim} + +\begin{example}{Balance Sheet}{ex:balance} +Suppose you have a file called "balance.csv" that contains +the following: +\begin{verbatim} +Description,In,Out,Balance +Travel expenses,,230,-230 +Conference fees,,400,-630 +Grant,700,,70 +Train fare,,70,0 +\end{verbatim} +\DTLnewdb{balance}\relax +\DTLnewrow{balance}\relax +\DTLnewdbentry{balance}{Description}{Travel expenses}\relax +\DTLnewdbentry{balance}{In}{}\relax +\DTLnewdbentry{balance}{Out}{230.00}\relax +\DTLnewdbentry{balance}{Balance}{-230.00}\relax +\DTLnewrow{balance}\relax +\DTLnewdbentry{balance}{Description}{Conference fees}\relax +\DTLnewdbentry{balance}{In}{}\relax +\DTLnewdbentry{balance}{Out}{400.00}\relax +\DTLnewdbentry{balance}{Balance}{-630.00}\relax +\DTLnewrow{balance}\relax +\DTLnewdbentry{balance}{Description}{Grant}\relax +\DTLnewdbentry{balance}{In}{700.00}\relax +\DTLnewdbentry{balance}{Out}{}\relax +\DTLnewdbentry{balance}{Balance}{70.00}\relax +\DTLnewrow{balance}\relax +\DTLnewdbentry{balance}{Description}{Train Fare}\relax +\DTLnewdbentry{balance}{In}{}\relax +\DTLnewdbentry{balance}{Out}{70.00}\relax +\DTLnewdbentry{balance}{Balance}{0.00}\relax +\DTLsetheader{balance}{In}{In (\pounds)}\relax +\DTLsetheader{balance}{Out}{Out (\pounds)}\relax +\DTLsetheader{balance}{Balance}{Balance (\pounds)}\relax +The data can be loaded using: +\begin{verbatim} +\DTLloaddb[headers={Description,In (\pounds),Out (\pounds),Balance +(\pounds)}]{balance}{balance.csv} +\end{verbatim} + +Suppose I want negative numbers to be displayed in red. I can do +this by redefining \cs{dtlrealformat} to check if the entry +is negative. For example: +\begin{verbatim} +\begin{table}[htbp] +\caption{Balance Sheet} +\renewcommand*{\dtlrealformat}[1]{\DTLiflt{#1}{0}{\color{red}}{}#1} +\centering +\DTLdisplaydb{balance} +\end{table} +\end{verbatim} +This produces \autoref{tab:balance}. +\begin{table}[htbp] +\caption{Balance Sheet} +\label{tab:balance} +\renewcommand*{\dtlrealformat}[1]{\DTLiflt{#1}{0}{\color{red}}{}#1} +\centering +\DTLdisplaydb{balance} +\end{table} +\end{example} + +\section{Iterating Through a Database} +\label{sec:dbforeach} + +Once you have created a database, either loading it from an +external file, as described in \autoref{sec:loaddb}, or using the +commands described in \autoref{sec:newdb}, you can then iterate +through each row of the database and access elements in that row. + +\begin{definition}[\DescribeMacro{\DTLforeach}]% +\cs{DTLforeach}\oarg{condition}\marg{db name}\marg{assign list}\marg{text} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLforeach*}]% +\cs{DTLforeach*}\oarg{condition}\marg{db name}\marg{assign list}\marg{text} +\end{definition} +This will iterate through each row of the database called +\meta{db name}, applying \meta{text} to each row of the database +where \meta{condition} is met. The argument \meta{assign list} is a +comma separated list of \meta{cmd}"="\meta{key} pairs. At the +start of each row, each command \meta{cmd} in \meta{assign list} +will be set to the value of the entry given by \meta{key}. +These commands may then be used in \meta{text}. + +\begin{important} +Note that this assignment is done globally to ensure +that \cs{DLTforeach} works correctly in a \env{tabular} environment. +Since you may want to use the same set of commands in a later +\cs{DTLforeach}, the commands are not checked to determine if they +already exist. It is therefore important that you check you are not +using an existing command whose value should not be changed. +\end{important} + +The optional argument \meta{condition} is a condition in the +form allowed by \cs{ifthenelse}. This includes the commands +provided by the \sty{ifthen} package (such as \cs{not}, \cs{and}, +\cs{or}), as well as the commands +described in \autoref{sec:ifthen}. The default value of +\meta{condition} is "\boolean{true}". + +The starred version \cs{DTLforeach*} is a read-only version. +If you want to modify the database using any of the commands +described in \autoref{sec:editdb}, you must use the unstarred +version. The starred version is faster. + +\begin{important} +As is generally the case with command arguments, verbatim (for +example, using \cs{verb} or the \env{verbatim} environment) can't be used in any of +the arguments of \cs{DTLforeach}, specifically verbatim can't be +used in \meta{text}. +\end{important} + +There are also environment alternatives: +\begin{definition}[\DescribeEnv{DTLenvforeach}]% +\cs{begin}\{DTLenvforeach\}\oarg{condition}\marg{db name}\marg{assign list} +\end{definition} +\begin{definition}[\DescribeEnv{DTLenvforeach*}]% +\cs{begin}\{DTLenvforeach*\}\oarg{condition}\marg{db name}\marg{assign list} +\end{definition} +However, note that since these environments gather the contents of +their body, they also suffer from the above limitation. +\begin{important} +Verbatim can't be used in the body of \env{DTLenvforeach} or +\env{DTLenvforeach*}. +\end{important} + +\begin{example}{Student scores}{ex:scores} +Suppose you have a data file called \texttt{studentscores.csv} that +contains the following: +\begin{verbatim} +FirstName,Surname,StudentNo,Score +John,"Smith, Jr",102689,68 +Jane,Brown,102647,75 +Andy,Brown,103569,42 +Z\"oe,Adams,105987,52 +Roger,Brady,106872,58 +Clare,Verdon,104356,45 +\end{verbatim} +\DTLnewdb{scores}\relax +\DTLnewrow{scores}\relax +\DTLnewdbentry{scores}{FirstName}{John}\relax +\DTLnewdbentry{scores}{Surname}{Smith, Jr}\relax +\DTLnewdbentry{scores}{StudentNo}{102689}\relax +\DTLnewdbentry{scores}{Score}{68}\relax +\DTLnewrow{scores}\relax +\DTLnewdbentry{scores}{FirstName}{Jane}\relax +\DTLnewdbentry{scores}{Surname}{Brown}\relax +\DTLnewdbentry{scores}{StudentNo}{102647}\relax +\DTLnewdbentry{scores}{Score}{75}\relax +\DTLnewrow{scores}\relax +\DTLnewdbentry{scores}{FirstName}{Andy}\relax +\DTLnewdbentry{scores}{Surname}{Brown}\relax +\DTLnewdbentry{scores}{StudentNo}{103569}\relax +\DTLnewdbentry{scores}{Score}{42}\relax +\DTLnewrow{scores}\relax +\DTLnewdbentry{scores}{FirstName}{Z\"oe}\relax +\DTLnewdbentry{scores}{Score}{52}\relax +\DTLnewdbentry{scores}{StudentNo}{105987}\relax +\DTLnewdbentry{scores}{Surname}{Adams}\relax +\DTLnewrow{scores}\relax +\DTLnewdbentry{scores}{FirstName}{Roger}\relax +\DTLnewdbentry{scores}{Score}{58}\relax +\DTLnewdbentry{scores}{StudentNo}{106872}\relax +\DTLnewdbentry{scores}{Surname}{Brady}\relax +\DTLnewrow{scores}\relax +\DTLnewdbentry{scores}{FirstName}{Clare}\relax +\DTLnewdbentry{scores}{Score}{45}\relax +\DTLnewdbentry{scores}{StudentNo}{104356}\relax +\DTLnewdbentry{scores}{Surname}{Verdon}\relax +and you load the data into a database called "scores" using: +\begin{verbatim} +\DTLloaddb{scores}{studentscores.csv} +\end{verbatim} +you can then display the database in a table as follows: +\begin{verbatim} +\begin{table}[htbp] +\caption{Student scores} +\centering +\begin{tabular}{llr} +\bfseries First Name & +\bfseries Surname & +\bfseries Score (\%)% +\DTLforeach{scores}{% +\firstname=FirstName,\surname=Surname,\score=Score}{% +\\ +\firstname & \surname & \score} +\end{tabular} +\end{table} +\end{verbatim} +This produces \autoref{tab:scores}. (Note that since I didn't +need the student registration number, I didn't bother to +assign a command to the key "StudentNo".) + +\begin{table}[htbp] +\caption[Student scores (displaying a database in a +table)]{Student scores}\label{tab:scores} +\centering +\begin{tabular}{llr} +\bfseries First Name & +\bfseries Surname & +\bfseries Score (\%)\relax +\DTLforeach{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax +\\ +\firstname & \surname & \score} +\end{tabular} +\end{table} +\end{example} + +The macro \ics{DTLforeach} may be nested up to three times. Each +level uses the corresponding counters: +\desctr{DTLrowi}, +\desctr{DTLrowii} and +\desctr{DTLrowiii} which keep track of +the current row. + +\begin{important} +Note that these counters are only incremented when +\meta{condition} is satisfied, therefore they will not have the +correct value in \meta{condition}. These counters are incremented +using \cs{refstepcounter} before the start of \meta{text}, so they +may be referenced using \cs{label}, however remember that \cs{label} +references the last counter to be incremented using +\cs{refstepcounter} \emph{in the current scope}. The \cs{label} +should therefore be the first command in \meta{text} to ensure that +it references the current row counter. +\end{important} + +\begin{definition}[\DescribeMacro{\DTLcurrentindex}]% +\cs{DTLcurrentindex} +\end{definition} +At the start of each iteration in \cs{DTLforeach}, +\cs{DTLcurrentindex} is set to the arabic value of the current row +counter. Note that this is only set after the condition is tested, +so it should only be used in the body of \cs{DTLforeach} not in +the condition. It is also only set locally, so if you use it in +a tabular environment, it can only be used before the first instance +of \verb|\\| or \verb|&| in the current iteration. + +Within the body of \ics{DTLforeach} (i.e.\ within \meta{text}) +the following conditionals may be used: +\begin{definition}[\DescribeMacro{\DTLiffirstrow}]% +\cs{DTLiffirstrow}\marg{true part}\marg{false part} +\end{definition} +If the current row is the first row, then do \meta{true part}, +otherwise do \meta{false part}. + +\begin{definition}[\DescribeMacro{\DTLifoddrow}]% +\cs{DTLifoddrow}\marg{true part}\marg{false part} +\end{definition} +If the current row number is an odd number, then do \meta{true part}, +otherwise do \meta{false part}. + +\begin{definition}[\DescribeMacro{\DTLsavelastrowcount}]% +\cs{DTLsavelastrowcount}\marg{cmd} +\end{definition} +This command will store the value of the row counter used in +the last occurrence of \ics{DTLforeach} in the control sequence +\meta{cmd}. + +\begin{definition}[\DescribeMacro{\DTLforeachkeyinrow}]% +\cs{DTLforeachkeyinrow}\marg{cmd}\marg{text} +\end{definition} +This iterates through each key in the current row, (globally) assigns +\meta{cmd} to the value of that key, and does \meta{text} +(\meta{cmd} must be a control sequence and may be used in +\meta{text}). This command may only be used in the body of +\cs{DTLforeach}. At each iteration, \cs{DTLforeachkeyinrow} sets +\cs{dtlkey} to the current key, \cs{dtlcol} to the current column +index, \cs{dtltype} to the data type for the current column, +and \cs{dtlheader} to the header for the current column. Note that +\cs{dtltype} corresponds to the column type but if the entries in +the column have mixed types, it may not correspond to the type +of the current entry. + +\begin{definition}[\DescribeMacro{\dtlbreak}]% +\cs{dtlbreak} +\end{definition} +You can break out of most of the loops provided by \sty{datatool} +using \cs{dtlbreak}. Note, however, that it doesn't break the loop +until the end of the current iteration. There is no provision for +a "next" or "continue" style command. + +Additional loop commands provided by \sty{datatool} are +described in the documented code (datatool.pdf). + +\begin{example}{Student Scores---Labelling}{ex:label} +In the previous example, the student scores, stored in the +database "scores" were placed in a table. In this example the +table will be modified slightly to number each student according +to the row. Suppose I also want to identify which row Jane Brown +is in, and reference it in the text. The easiest way to do this +is to construct a label on each row which uniquely identifies +that student. The label can't simply be constructed from the +surname, as there are two students with the same surname. In order +to create a unique label, I can either construct a label from +both the surname and the first name, or I can use the student's +registration number, or I can use the student's score, since all +the scores are unique. The former method will cause a problem since +one of the names (Z\"oe) contains an accent command. Although +the registration numbers are all unique, they are not particularly +memorable, so I shall instead use the scores. +\begin{verbatim} +\begin{table}[htbp] +\caption{Student scores} +\centering +\begin{tabular}{cllc} +\bfseries Row & +\bfseries First Name & +\bfseries Surname & +\bfseries Score (\%)% +\DTLforeach*{scores}{% +\firstname=FirstName,\surname=Surname,\score=Score}{% +\label{row:\score}\\\theDTLrowi & +\firstname & \surname & \score}% +\end{tabular} +\end{table} + +Jane Brown scored the highest (75\%), her score can be seen on +row~\ref{row:75}. +\end{verbatim} +This produces \autoref{tab:scoreslab} and the following text: +Jane Brown scored the highest (75\%), her score can be seen on +row~\ref*{row:75}. + +Notes: +\begin{itemize} +\item the \cs{label} command is placed before +"\\" to ensure that it is in the same scope as the command +"\refstepcounter{DTLrowi}". + +\item To avoid unwanted spaces the end of line characters are +commented out with the percent (\texttt{\%}) symbol. +\end{itemize} + +\begin{table}[htbp] +\caption[Student scores (labelling rows)]{Student +scores}\label{tab:scoreslab} +\centering +\begin{tabular}{cllc} +\bfseries Row & +\bfseries First Name & +\bfseries Surname & +\bfseries Score (\%)\relax +\DTLforeach*{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax +\label{row:\score}\\\theDTLrowi & +\firstname & \surname & \score}\relax +\end{tabular} +\end{table} +\end{example} + +\begin{example}{Filtering Rows}{ex:filter} +As mentioned earlier, the optional argument \meta{condition} of +\ics{DTLforeach} provides a means to exclude certain rows. +This example uses the database defined in \autoref{ex:scores}, +but only displays the information for students whose marks are +above 60. At the end of the table, \cs{DTLsavelastrowcount} +is used to store the number of rows in the table. (Note that +\cs{DTLsavelastrowcount} is outside of \ics{DTLforeach}.) +\begin{verbatim} +\begin{table}[htbp] +\caption{Top student scores} +\centering +\begin{tabular}{llr} +\bfseries First Name & +\bfseries Surname & +\bfseries Score (\%)% +\DTLforeach*[\DTLisgt{\score}{60}]{scores}{% +\firstname=FirstName,\surname=Surname,\score=Score}{% +\\ +\firstname & \surname & \score} +\end{tabular} + +\DTLsavelastrowcount{\n}% +\n\ students scored above 60\%. +\end{table} +\end{verbatim} +This produces \autoref{tab:topscores}. Note that in this example, +I could have specified the condition as "\score>60" since all +the scores are integers, however, as it's possible that an entry +may feasibly have a decimal score I have used \ics{DTLisgt} instead. + +\begin{table}[htbp] +\caption[Top student scores (filtering rows using +\cs{DTLisgt})]{Top student scores}\label{tab:topscores} +\centering +\begin{tabular}{llr} +\bfseries First Name & +\bfseries Surname & +\bfseries Score (\%)\relax +\DTLforeach*[\DTLisgt{\score}{60}]{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax +\\ +\firstname & \surname & \score} +\end{tabular} + +\DTLsavelastrowcount{\n}\relax +\n\ students scored above 60\%. +\end{table} + +Suppose now, I only want to display the scores for students whose +surname begins with `B'. I can do this as follows: +\begin{verbatim} +\begin{table}[htbp] +\caption{Student scores (B)} +\centering +\begin{tabular}{llr} +\bfseries First Name & +\bfseries Surname & +\bfseries Score (\%)% +\DTLforeach*[\DTLisopenbetween{\surname}{B}{C}]{scores}{% +\firstname=FirstName,\surname=Surname,\score=Score}{% +\\ +\firstname & \surname & \score} +\end{tabular} +\end{table} +\end{verbatim} +This produces \autoref{tab:Bscores}. + +\begin{table}[htbp] +\caption[Student scores (B) --- filtering rows using \newline +\cs{DTLisopenbetween}]{Student scores (B)}\label{tab:Bscores} +\centering +\begin{tabular}{llr} +\bfseries First Name & +\bfseries Surname & +\bfseries Score (\%)\relax +\DTLforeach*[\DTLisopenbetween{\surname}{B}{C}]{scores} +{\firstname=FirstName,\surname=Surname,\score=Score}{\relax +\\ +\firstname & \surname & \score} +\end{tabular} +\end{table} + +\end{example} + +\begin{example}{Breaking Out of a Loop}{ex:dtlbreak} +Suppose I only want to display the first three rows of a database. +I could do:\footnote{Recall that \ctr{DTLrowi} is incremented +after the condition is tested, so it will be out by 1 when the +condition is tested which is why \texttt{<3} is used instead of +\texttt{<4}.} +\begin{verbatim} +\DTLforeach*[\value{DTLrowi}<3]{scores}% +{\firstname=FirstName,\surname=Surname,\score=Score}{% +\\\firstname & \surname & \score +} +\end{verbatim} +However, this isn't very efficient, as it still has to iterate +through the entire database, checking if the condition is met. If +the database has over 100 entries, this will slow the time taken +to create the table. It would therefore be much more efficient +to break out of the loop when row count exceeds 3: +\begin{verbatim} +\begin{table}[htbp] +\caption{First Three Rows} +\centering +\begin{tabular}{llr} +\bfseries First Name & \bfseries Surname & \bfseries Score (\%)% +\DTLforeach*{scores}% +{\firstname=FirstName,\surname=Surname,\score=Score}{% +\ifthenelse{\DTLcurrentindex=3}{\dtlbreak}{}% +\\\firstname & \surname & \score +}% +\end{tabular} +\end{table} +\end{verbatim} +This produces \autoref{tab:dtlbreak}. Note that the loop is not +broken until the end of the current iteration, so even though +\cs{dtlbreak} occurs at the start of the third row, the loop isn't +finished until the third row is completed. (Recall that +\cs{DTLcurrentindex} must be used before the first instance of +\verb|\\| or \verb|&|.) Alternatively, you can use +\ctr{DTLrowi} instead: +\begin{verbatim} +\DTLforeach{scores}% +{\firstname=FirstName,\surname=Surname,\score=Score}{% +\\\firstname & \surname & \score +\ifthenelse{\value{DTLrowi}=3}{\dtlbreak}{}% +}% +\end{verbatim} + +\begin{table}[htbp] +\caption{First Three Rows} +\label{tab:dtlbreak}% +\centering +\begin{tabular}{llr} +\bfseries First Name & \bfseries Surname & \bfseries Score (\%)\relax +\DTLforeach*{scores}% +{\firstname=FirstName,\surname=Surname,\score=Score}{% +\ifthenelse{\DTLcurrentindex=3}{\dtlbreak}{}\relax +\\\firstname & \surname & \score +}% +\end{tabular} +\end{table} +\end{example} + +\begin{example}{Stripy Tables}{ex:stripy} +This example uses the same database as in the previous examples. +It requires the \sty{colortbl} package, which provides the +command \cs{rowcolor}. The command \cs{DTLifoddrow} is used +to produce a striped table. +\begin{verbatim} +\begin{table}[htbp] +\caption{A stripy table}\label{tab:stripy} +\centering +\begin{tabular}{llc} +\bfseries First Name & +\bfseries Surname & +\bfseries Score (\%)% +\DTLforeach*{scores}{% +\firstname=FirstName,\surname=Surname,\score=Score}{% +\\\DTLifoddrow{\rowcolor{blue}}{\rowcolor{green}}% +\firstname & \surname & \score}% +\end{tabular} +\end{table} +\end{verbatim} +This produces \autoref{tab:stripy}. + +\begin{table}[htbp] +\caption[A stripy table (illustrating the use of +\cs{DTLifoddrow})]{A stripy table}\label{tab:stripy} +\centering +\begin{tabular}{llc} +\bfseries First Name & +\bfseries Surname & +\bfseries Score (\%)\relax +\DTLforeach*{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax +\\\DTLifoddrow{\rowcolor{blue}}{\rowcolor{green}}\relax +\firstname & \surname & \score}\relax +\end{tabular} +\end{table} +\end{example} + +\begin{example}{Two Database Rows per Tabular Row}{ex:2rows} +In order to save space, you may want two database rows per +tabular row, when displaying a database in a \env{tabular} +environment. This can be accomplished using \ics{DTLifoddrow}. +For example +\begin{verbatim} +\begin{table}[htbp] +\caption{Two database rows per tabular row} +\centering +\begin{tabular}{llcllc} +\bfseries First Name & +\bfseries Surname & +\bfseries Score (\%) & +\bfseries First Name & +\bfseries Surname & +\bfseries Score (\%)% +\DTLforeach*{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{% +\DTLifoddrow{\\}{&}% +\firstname & \surname & \score}% +\end{tabular} +\end{table} +\end{verbatim} +produces \autoref{tab:2rows} + +\begin{table}[htbp] +\caption[Two database rows per tabular row (illustrating the +use of\newline \cs{DTLifoddrow})]{Two database rows per tabular +row}\label{tab:2rows} +\centering +\begin{tabular}{llcllc} +\bfseries First Name & +\bfseries Surname & +\bfseries Score (\%) & +\bfseries First Name & +\bfseries Surname & +\bfseries Score (\%)\relax +\DTLforeach*{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax +\DTLifoddrow{\\}{&}\relax +\firstname & \surname & \score}\relax +\end{tabular} +\end{table} + +(To order column-wise, instead of row-wise, see +\autoref{ex:twoblocks}.) +\end{example} + +\begin{example}{Iterating Through Keys in a Row}{ex:foreachkey} +Suppose you have lots of columns in your database, and you +want to display them all without having to set a variable for +each column. You can leave the assignment list in \cs{DTLforeach} +blank, and iterate through the keys using \cs{DTLforeachkeyinrow}. +For example: +\begin{verbatim} +\begin{table}[htbp] +\caption{Student Scores (Iterating Through Keys)} +\centering +\begin{tabular}{llll} +\bfseries First Name & \bfseries Surname & +\bfseries Registration No. & +\bfseries Score (\%)% +\DTLforeach*{scores}{}{% +\\\gdef\doamp{\gdef\doamp{&}}% +\DTLforeachkeyinrow{\thisValue}{\doamp\thisValue}}% +\end{tabular} +\end{table} +\end{verbatim} +This produces \autoref{tab:foreachkey}. +\begin{table}[htbp] +\caption{Student Scores (Iterating Through Keys)} +\label{tab:foreachkey} +\centering +\begin{tabular}{llll} +\bfseries First Name & \bfseries Surname & +\bfseries Registration No. & +\bfseries Score (\%)\relax +\DTLforeach*{scores}{}{% +\\\gdef\doamp{\gdef\doamp{&}}\relax +\DTLforeachkeyinrow{\thisValue}{\doamp\thisValue}}\relax +\end{tabular} +\end{table} + +Note that the "&" must be between columns, so I have defined +a command called \cs{doamp} that on first use redefines +itself to do "&". So, for each row, at the start of +the key iteration, \cs{doamp} does nothing, and on subsequent +iterations it does "&". This ensures that the correct number of +"&"s are used. Since each cell in the \env{tabular} environment +is scoped, \cs{gdef} is needed instead of \cs{def}. + +In the above, I needed to know how many columns are in the +database, and the order that the headings should appear. If you +are unsure, you can use \cs{dtlforeachkey} to determine the +number of columns and to display the header row. For example: +\begin{verbatim} + \begin{table}[htbp] + \caption{Student Scores} + \centering + % Work out the column alignments. + \def\colalign{}% + \dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do + {\edef\colalign{\colalign l}}% + % Begin the tabular environment. + \edef\dobegintabular{\noexpand\begin{tabular}{\colalign}}% + \dobegintabular + % Do the header row. + \gdef\doamp{\gdef\doamp{&}}% + \dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do + {\doamp\bfseries \theHead}% + % Iterate through the data. + \DTLforeach*{scores}{}{% + \\\gdef\doamp{\gdef\doamp{&}}% + \DTLforeachkeyinrow{\thisValue}{\doamp\thisValue}}% + \end{tabular} + \end{table} +\end{verbatim} + +\begin{table}[htbp] +\caption[Student Scores (Using \cs{dtlforeachkey} and \newline +\cs{DTLforeachkeyinrow})]{Student Scores (Using \cs{dtlforeachkey} and +\cs{DTLforeachkeyinrow})} +\label{tab:foreachkey2} +\centering +\def\colalign{}% +\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do +{\edef\colalign{\colalign l}}% +\edef\dobegintabular{\noexpand\begin{tabular}{\colalign}}\relax +\dobegintabular +\gdef\doamp{\gdef\doamp{&}}\relax +\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do +{\doamp\bfseries \theHead}\relax +\DTLforeach*{scores}{}{% +\\\gdef\doamp{\gdef\doamp{&}}\relax +\DTLforeachkeyinrow{\thisValue}{\doamp\thisValue}}\relax +\end{tabular} +\end{table} + +Notes: +\begin{itemize} +\item In order to determine the column alignment for the +\env{tabular} environment, I first define \cs{colalign} to +nothing, and then I iterate through the keys appending +\texttt{l} to \cs{colalign}. Since \cs{colalign} only contains +alphabetical characters, I can just use \cs{edef} for this. I +could modify this to check the data type and, say, use \texttt{l} +(left alignment) for columns containing strings and \texttt{c} +(centred) for the other columns: +\begin{verbatim} +\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do +{\ifnum\theType=0\relax + \edef\colalign{\colalign l}% column contains strings + \else + \edef\colalign{\colalign c}% column contains numerical values + \fi +}% +\end{verbatim} + +\item To ensure \cs{colalign} gets correct expanded when passed +to the \env{tabular} environment I temporarily define +\cs{dobegintabular} to the code required to start the +\env{tabular} environment: +\begin{verbatim} +\edef\dobegintabular{\noexpand\begin{tabular}{\colalign}}% +\end{verbatim} +This sets \cs{dobegintabular} to \verb|\begin{tabular}{llll}|. +After defining \cs{dobegintabular}, I then need to use it. + +\item As before, I use \cs{doamp} to put the ampersands between +columns. + +\item Recall that I can set the headers using \cs{DTLsetheader} +or using the \csopt{DTLloaddb}{headers} key when loading the data +from an external file. For example: +\begin{verbatim} +\DTLsetheaders{scores}{FirstName}{First Name} +\DTLsetheaders{scores}{Score}{Score (\%)} +\end{verbatim} +\end{itemize} + +Recall that \cs{DTLforeachkeyinrow} sets \cs{dtlkey} to the +current key. This can be used to filter out columns. Alternatively, +if you know the column index, you can test \cs{dtlcol} instead. +The following code modifies the above example so that it filters +out the column whose key is \texttt{StudentNo}: +\begin{verbatim} +\begin{table}[htbp] +\caption{Student Scores (Filtering Out a Column)} +\centering +\def\colalign{}% +\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do +{\DTLifeq{\theKey}{StudentNo}{}{\edef\colalign{\colalign l}}}% +\edef\dobegintabular{\noexpand\begin{tabular}{\colalign}}% +\dobegintabular +\gdef\doamp{\gdef\doamp{&}}% +\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do +{\DTLifeq{\theKey}{StudentNo}{}{\doamp\bfseries \theHead}}% +\DTLforeach*{scores}{}{% +\\\gdef\doamp{\gdef\doamp{&}}% +\DTLforeachkeyinrow{\thisValue}{% + \DTLifeq{\dtlkey}{StudentNo}{}{\doamp\thisValue}}}% +\end{tabular} +\end{table} +\end{verbatim} +The result is shown in \autoref{tab:foreachkey3}. + +\begin{table}[htbp] +\caption{Student Scores (Filtering Out a Column)} +\label{tab:foreachkey3} +\centering +\def\colalign{}% +\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do +{\DTLifeq{\theKey}{StudentNo}{}{\edef\colalign{\colalign l}}}% +\edef\dobegintabular{\noexpand\begin{tabular}{\colalign}}\relax +\dobegintabular +\gdef\doamp{\gdef\doamp{&}}\relax +\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do +{\DTLifeq{\theKey}{StudentNo}{}{\doamp\bfseries \theHead}}\relax +\DTLforeach*{scores}{}{% +\\\gdef\doamp{\gdef\doamp{&}}\relax +\DTLforeachkeyinrow{\thisValue}{\relax +\DTLifeq{\dtlkey}{StudentNo}{}{\doamp\thisValue}}}\relax +\end{tabular} +\end{table} +\end{example} + +\begin{example}{Nested \cs{DTLforeach}}{ex:nested} +In this example I have a CSV file called "index.csv" which +contains: +\begin{verbatim} +File,Temperature,NaCl,pH +exp25a.csv,25,4.7,0.5 +exp25b.csv,25,4.8,1.5 +exp30a.csv,30,5.12,4.5 +\end{verbatim} +\DTLnewdb{index}\relax +\DTLnewrow{index}\relax +\DTLnewdbentry{index}{File}{exp25a.csv}\relax +\DTLnewdbentry{index}{Temperature}{25}\relax +\DTLnewdbentry{index}{NaCl}{4.7}\relax +\DTLnewdbentry{index}{pH}{0.5}\relax +\DTLnewrow{index}\relax +\DTLnewdbentry{index}{File}{exp25b.csv}\relax +\DTLnewdbentry{index}{Temperature}{25}\relax +\DTLnewdbentry{index}{NaCl}{4.8}\relax +\DTLnewdbentry{index}{pH}{1.5}\relax +\DTLnewrow{index}\relax +\DTLnewdbentry{index}{File}{exp30a.csv}\relax +\DTLnewdbentry{index}{Temperature}{30}\relax +\DTLnewdbentry{index}{NaCl}{5.12}\relax +\DTLnewdbentry{index}{pH}{4.5}\relax +The first column of this file contains the name of another +CSV file which has the results of a time to growth experiment +performed at the given incubation temperature, salt concentration +and pH. The file "exp25a.csv" contains the following: +\begin{verbatim} +Time,Log Count +0,3.75 +23,3.9 +45,4.0 +\end{verbatim} +\DTLnewdb{exp25a.csv}\relax +\DTLnewrow{exp25a.csv}\relax +\DTLnewdbentry{exp25a.csv}{Time}{0}\relax +\DTLnewdbentry{exp25a.csv}{Log Count}{3.75}\relax +\DTLnewrow{exp25a.csv}\relax +\DTLnewdbentry{exp25a.csv}{Time}{23}\relax +\DTLnewdbentry{exp25a.csv}{Log Count}{3.9}\relax +\DTLnewrow{exp25a.csv}\relax +\DTLnewdbentry{exp25a.csv}{Time}{45}\relax +\DTLnewdbentry{exp25a.csv}{Log Count}{4.0}\relax +The file "exp25b.csv" contains the following: +\begin{verbatim} +Time,Log Count +0,3.6 +60,3.8 +120,4.0 +\end{verbatim} +\DTLnewdb{exp25b.csv}\relax +\DTLnewrow{exp25b.csv}\relax +\DTLnewdbentry{exp25b.csv}{Time}{0}\relax +\DTLnewdbentry{exp25b.csv}{Log Count}{3.6}\relax +\DTLnewrow{exp25b.csv}\relax +\DTLnewdbentry{exp25b.csv}{Time}{60}\relax +\DTLnewdbentry{exp25b.csv}{Log Count}{3.8}\relax +\DTLnewrow{exp25b.csv}\relax +\DTLnewdbentry{exp25b.csv}{Time}{120}\relax +\DTLnewdbentry{exp25b.csv}{Log Count}{4.0}\relax +The file "exp30a.csv" contains the following: +\begin{verbatim} +Time,Log Count +0,3.73 +23,3.67 +60,4.9 +\end{verbatim} +\DTLnewdb{exp30a.csv}\relax +\DTLnewrow{exp30a.csv}\relax +\DTLnewdbentry{exp30a.csv}{Time}{0}\relax +\DTLnewdbentry{exp30a.csv}{Log Count}{3.73}\relax +\DTLnewrow{exp30a.csv}\relax +\DTLnewdbentry{exp30a.csv}{Time}{23}\relax +\DTLnewdbentry{exp30a.csv}{Log Count}{3.67}\relax +\DTLnewrow{exp30a.csv}\relax +\DTLnewdbentry{exp30a.csv}{Time}{60}\relax +\DTLnewdbentry{exp30a.csv}{Log Count}{4.9}\relax +Suppose I now want to iterate through "index.csv", load the given +file, and create a table for that data. I can do this using +nested \ics{DTLforeach} as follows: +\begin{verbatim} + % load index data file +\DTLloaddb{index}{index.csv} + + % iterate through index database +\DTLforeach{index}{\theFile=File,\theTemp=Temperature,% +\theNaCl=NaCl,\thepH=pH}{% + % load results file into database of the same name +\DTLloaddb{\theFile}{\theFile}% + % Create a table +\begin{table}[htbp] +\caption{Temperature = \theTemp, NaCl = \theNaCl, +pH = \thepH}\label{tab:\theFile} +\centering +\begin{tabular}{rl} +\bfseries Time & \bfseries Log Count +\DTLforeach{\theFile}{\theTime=Time,\theLogCount=Log Count}{% +\\\theTime & \theLogCount}% +\end{tabular} +\end{table} +} +\end{verbatim} +This creates \autoref{tab:exp25a.csv} to \autoref{tab:exp30a.csv}. +(Note that each table is given a label that is based on the +database name, to ensure that it is unique.) + +\DTLforeach{index}{\theFile=File,\theTemp=Temperature,\theNaCl +=NaCl,\thepH=pH}{ +\begin{table}[htbp] +\caption[Temperature = \theTemp, NaCl = \theNaCl, +pH = \thepH\space (illustrating nested +\cs{DTLforeach})]{Temperature = \theTemp, NaCl = \theNaCl, +pH = \thepH}\label{tab:\theFile} +\centering +\begin{tabular}{rl} +\bfseries Time & \bfseries Log Count +\DTLforeach{\theFile}{\theTime=Time,\theLogCount=Log Count}{ +\\\theTime & \theLogCount}% +\end{tabular} +\end{table} +} +\end{example} + +\begin{example}{Dynamically Allocating Field Name}{ex:dyn} +(This example was suggested by Bill~Hobbs.) Suppose you have a +directory containing members of multiple clubs. The CSV file +(say, \texttt{clubs.csv}) may look something like: +\begin{verbatim} +First Name,Surname,Rockin,Single +John,"Smith, Jr",member, +Jane,Brown,,friend +Andy,Brown,friend,member +Z\"oe,Adams,member,member +Roger,Brady,friend,friend +Clare,Verdon,member, +\end{verbatim} +\DTLnewdb{clubs}\relax +\DTLnewrow{clubs}\relax +\DTLnewdbentry{clubs}{First Name}{John}\relax +\DTLnewdbentry{clubs}{Surname}{Smith, Jr}\relax +\DTLnewdbentry{clubs}{Rockin}{member}\relax +\DTLnewdbentry{clubs}{Single}{}\relax +\DTLnewrow{clubs}\relax +\DTLnewdbentry{clubs}{First Name}{Jane}\relax +\DTLnewdbentry{clubs}{Surname}{Brown}\relax +\DTLnewdbentry{clubs}{Rockin}{}\relax +\DTLnewdbentry{clubs}{Single}{friend}\relax +\DTLnewrow{clubs}\relax +\DTLnewdbentry{clubs}{First Name}{Andy}\relax +\DTLnewdbentry{clubs}{Surname}{Brown}\relax +\DTLnewdbentry{clubs}{Rockin}{friend}\relax +\DTLnewdbentry{clubs}{Single}{member}\relax +\DTLnewrow{clubs}\relax +\DTLnewdbentry{clubs}{First Name}{Z\"oe}\relax +\DTLnewdbentry{clubs}{Surname}{Adams}\relax +\DTLnewdbentry{clubs}{Rockin}{member}\relax +\DTLnewdbentry{clubs}{Single}{member}\relax +\DTLnewrow{clubs}\relax +\DTLnewdbentry{clubs}{First Name}{Roger}\relax +\DTLnewdbentry{clubs}{Surname}{Brady}\relax +\DTLnewdbentry{clubs}{Rockin}{friend}\relax +\DTLnewdbentry{clubs}{Single}{friend}\relax +\DTLnewrow{clubs}\relax +\DTLnewdbentry{clubs}{First Name}{Clare}\relax +\DTLnewdbentry{clubs}{Surname}{Verdon}\relax +\DTLnewdbentry{clubs}{Rockin}{member}\relax +\DTLnewdbentry{clubs}{Single}{}\relax +(Blank entries indicate that the person is not a member of that +club.) The data can be loaded as follows: +\begin{verbatim} +\DTLloaddb{clubs}{clubs.csv} +\end{verbatim} +Suppose at the beginning of your document you have specified +which club you are interested in ("Rockin" or "Single") and +store it in \cs{DIdent}: +\begin{verbatim} +\newcommand{\DIdent}{Rockin} +\end{verbatim} +\newcommand{\DIdent}{Rockin}\relax +You can now display the members for this particular club as +follows: +\begin{verbatim} +\begin{table}[htbp] +\caption{Club Membership} +\centering +\begin{tabular}{lll} +\bfseries First Name & \bfseries Surname & \bfseries Status +\DTLforeach*[\not\DTLiseq{\status}{}]{clubs} +{\firstname=First Name,\surname=Surname,\status=\DIdent}{% +\\\firstname & \surname & \status +}% +\end{tabular} +\end{table} +\end{verbatim} +The result is shown in \autoref{tab:dyn}. + +\begin{table}[htbp] +\caption{Club Membership} +\label{tab:dyn} +\centering +\begin{tabular}{lll} +\bfseries First Name & \bfseries Surname & \bfseries Status +\DTLforeach*[\not\DTLiseq{\status}{}]{clubs} +{\firstname=First Name,\surname=Surname,\status=\DIdent}{\relax +\\\firstname & \surname & \status +}\relax +\end{tabular} +\end{table} +\end{example} + +\section{Null Values} +If a database is created using \cs{DTLnewdb}, \cs{DTLnewrow} +and \cs{DTLnewdbentry} (rather than loading it from an ASCII +file), it is possible for some of the entries to have null values +when a value is not assigned to a given key for a given row. +(Note that a null value is not the same as an empty value. Empty +values can be tested using \sty{etoolbox}'s \ics{ifdefempty} or +similar.) + +When you iterate through the database using \cs{DTLforeach} +(described in \autoref{sec:dbforeach}), +if an entry is missing for a given row, the associated command given +in the \meta{values} argument will be set to a null value. This +value depends on the data type associated with the given key. + +\begin{definition}[\DescribeMacro{\DTLstringnull}]% +\cs{DTLstringnull} +\end{definition} +This is the null value for a string. + +\begin{definition}[\DescribeMacro{\DTLnumbernull}]% +\cs{DTLnumbernull} +\end{definition} +This is the null value for a number. + +\begin{definition}[\DescribeMacro{\DTLifnull}]% +\cs{DTLifnull}\marg{cmd}\marg{true part}\marg{false part} +\end{definition} +This checks if \meta{cmd} is null where \meta{cmd} is a command name, +if it is, then \meta{true part} +is done, otherwise \meta{false part} is done. This macro is +illustrated in \autoref{ex:null} below. + +\begin{example}{Null Values}{ex:null} +Consider the following (which creates a database called "emailDB"): +\begin{verbatim} +\DTLnewdb{emailDB} +\DTLnewrow{emailDB} +\DTLnewdbentry{emailDB}{Surname}{Jones} +\DTLnewdbentry{emailDB}{FirstName}{Mary} +\DTLnewdbentry{emailDB}{Email1}{mj@my.uni.ac.uk} +\DTLnewdbentry{emailDB}{Email2}{mj@somewhere.com} +\DTLnewrow{emailDB} +\DTLnewdbentry{emailDB}{Surname}{Smith} +\DTLnewdbentry{emailDB}{FirstName}{Adam} +\DTLnewdbentry{emailDB}{Email1}{as@my.uni.ac.uk} +\DTLnewdbentry{emailDB}{RegNum}{12345} +\end{verbatim} +\DTLnewdb{emailDB}\relax +\DTLnewrow{emailDB}\relax +\DTLnewdbentry{emailDB}{Surname}{Jones}\relax +\DTLnewdbentry{emailDB}{FirstName}{Mary}\relax +\DTLnewdbentry{emailDB}{Email1}{mj@my.uni.ac.uk}\relax +\DTLnewdbentry{emailDB}{Email2}{mj@somewhere.com}\relax +\DTLnewrow{emailDB}\relax +\DTLnewdbentry{emailDB}{Surname}{Smith}\relax +\DTLnewdbentry{emailDB}{FirstName}{Adam}\relax +\DTLnewdbentry{emailDB}{Email1}{as@my.uni.ac.uk}\relax +\DTLnewdbentry{emailDB}{RegNum}{12345}\relax +In the above example, the first row of the database contains +an entry with the key "Email2", but the second row doesn't. +Whereas the second row contains an entry with the key "RegNum", +but the first row doesn't. + +The following code puts the information in a \env{tabular} +environment: +\begin{verbatim} +\begin{tabular}{lllll} +\bfseries First Name & +\bfseries Surname & +\bfseries Email 1 & +\bfseries Email 2 & +\bfseries Reg Num% +\DTLforeach{emailDB}{\firstname=FirstName,\surname=Surname,% +\emailI=Email1,\emailII=Email2,\regnum=RegNum}{% +\\\firstname & \surname & \emailI & \emailII & \regnum}% +\end{tabular} +\end{verbatim} +This produces the following:\par\vskip\baselineskip\noindent +\begin{tabular}{lllll} +\bfseries First Name & +\bfseries Surname & +\bfseries Email 1 & +\bfseries Email 2 & +\bfseries Reg Num\relax +\DTLforeach{emailDB}{\firstname=FirstName,\surname +=Surname,\emailI=Email1,\emailII=Email2,\regnum=RegNum}{\relax +\\\firstname & \surname & \emailI & \emailII & \regnum}\relax +\end{tabular} +\par\vskip\baselineskip +Note that on the first row of data, the registration number appears as +0, while on the next row, the second email address appears as +NULL. The \sty{datatool} package has identified the key "RegNum" +for this database as a numerical key, since all elements in the +database with that key are numerical, whereas it has +identified the key "Email2" as a string, since there is at least +one element in this database with that key that is a string. Null +numerical values are set to \cs{DTLnumbernull} (\DTLnumbernull), and +null strings are set to \cs{DTLstringnull} (\DTLstringnull). + +The following code checks each value to determine whether it +is null using \cs{DTLifnull}. If it is, the text \emph{Missing} +is inserted, otherwise the value itself is used: +\begin{verbatim} +\begin{tabular}{lllll} +\bfseries First Name & +\bfseries Surname & +\bfseries Email 1 & +\bfseries Email 2 & +\bfseries Reg Num% +\DTLforeach{emailDB}{\firstname=FirstName,\surname=Surname,% +\emailI=Email1,\emailII=Email2,\regnum=RegNum}{% +\\\DTLifnull{\firstname}{\emph{Missing}}{\firstname} & +\DTLifnull{\surname}{\emph{Missing}}{\surname} & +\DTLifnull{\emailI}{\emph{Missing}}{\emailI} & +\DTLifnull{\emailII}{\emph{Missing}}{\emailII} & +\DTLifnull{\regnum}{\emph{Missing}}{\regnum}}% +\end{tabular} +\end{verbatim} +This produces the following:\par\vskip\baselineskip\noindent +\begin{tabular}{lllll} +\bfseries First Name & +\bfseries Surname & +\bfseries Email 1 & +\bfseries Email 2 & +\bfseries Reg Num\relax +\DTLforeach{emailDB}{\firstname=FirstName,\surname +=Surname,\emailI=Email1,\emailII=Email2,\regnum=RegNum}{\relax +\\\DTLifnull{\firstname}{\emph{Missing}}{\firstname} & +\DTLifnull{\surname}{\emph{Missing}}{\surname} & +\DTLifnull{\emailI}{\emph{Missing}}{\emailI} & +\DTLifnull{\emailII}{\emph{Missing}}{\emailII} & +\DTLifnull{\regnum}{\emph{Missing}}{\regnum}}\relax +\end{tabular} +\par\vskip\baselineskip\noindent +If you want to do this, you may find it easier to define a +convenience command that will display some appropriate text +if an entry is missing, for example: +\begin{verbatim} +\newcommand*{\checkmissing}[1]{\DTLifnull{#1}{---}{#1}} +\end{verbatim} +Then instead of typing, say, +\begin{verbatim} +\DTLifnull{\regnum}{---}{\regnum} +\end{verbatim} +you can instead type: +\begin{verbatim} +\checkmissing{\regnum} +\end{verbatim} + +Now suppose that instead of defining the database using \cs{DTLnewdb}, +\cs{DTLnewrow} and \cs{DTLnewdbentry}, you have a file with the +contents: +\begin{ttfamily}\setlength{\parindent}{0pt}\par\vskip\baselineskip +Surname,FirstName,RegNum,Email1,Email2 + +\DTLforeach{emailDB}{\surname=Surname,\firstname=FirstName,\regNo +=RegNum,\emailI=Email1,\emailII +=Email2}{\relax +\surname,\firstname,\DTLifnull{\regNo}{}{\regNo},\emailI,\DTLifnull{\emailII}{}{\emailII}\par +} +\end{ttfamily}\par\vskip\baselineskip\noindent +and you load the data from this file using \cs{DTLloaddb} +(defined in \autoref{sec:loaddb}). Now the +database has no null values, but has an empty value for the +key "RegNum" on the first row of the database, and an empty +value for the key "Email2" on the second row of the database. +Now, the following code +\begin{verbatim} +\begin{tabular}{lllll} +\bfseries First Name & +\bfseries Surname & +\bfseries Email 1 & +\bfseries Email 2 & +\bfseries Reg Number% +\DTLforeach{emailDB}{\firstname=FirstName,\surname=Surname,% +\emailI=Email1,\emailII=Email2,\regnum=RegNum}{% +\\\DTLifnull{\firstname}{\emph{Missing}}{\firstname} & +\DTLifnull{\surname}{\emph{Missing}}{\surname} & +\DTLifnull{\emailI}{\emph{Missing}}{\emailI} & +\DTLifnull{\emailII}{\emph{Missing}}{\emailII} & +\DTLifnull{\regnum}{\emph{Missing}}{\regnum}}% +\end{tabular} +\end{verbatim} +produces:\par\vskip\baselineskip\noindent +\begin{tabular}{lllll} +\bfseries First Name & +\bfseries Surname & +\bfseries Email 1 & +\bfseries Email 2 & +\bfseries Reg Number\relax +\DTLforeach{emailDB}{\firstname=FirstName,\surname +=Surname,\emailI=Email1,\emailII=Email2,\regnum=RegNum}{\relax +\\\firstname & \surname & \emailI & \DTLifnull{\emailII}{}{\emailII} & \DTLifnull{\regnum}{}{\regnum}}\relax +\end{tabular} +\end{example} + +\section{Editing Database Rows} +\label{sec:editdb} + +A row can be removed from a data base using: +\begin{definition}[\DescribeMacro{\DTLremoverow}]% +\cs{DTLremoverow}\marg{db name}\marg{row index} +\end{definition} +where \meta{row index} is the index of the unwanted row. For +example: +\begin{verbatim} +\DTLremoverow{scores}{2} +\end{verbatim} +will delete the second row in the database labelled ``scores''. +There is also a starred version that doesn't check for the +existence of the database. + +The following commands may be used in the body of the +\ics{DTLforeach} loop,\footnote{Only the unstarred version of +\cs{DTLforeach}; the starred version is read-only.}\ to edit the +current row of the loop. (See also \autoref{sec:currentrow}.) + +\begin{definition}[\DescribeMacro{\DTLappendtorow}]% +\cs{DTLappendtorow}\marg{key}\marg{value} +\end{definition} +This appends a new entry with the given \meta{key} and \meta{value} +to the current row. +(\meta{value} is expanded.) + +\begin{definition}[\DescribeMacro{\DTLreplaceentryforrow}]% +\cs{DTLreplaceentryforrow}\marg{key}\marg{value} +\end{definition} +This replaces the entry for \meta{key} with \meta{value}. +(\meta{value} is expanded.) + +\begin{definition}[\DescribeMacro{\DTLremoveentryfromrow}]% +\cs{DTLremoveentryfromrow}\marg{key} +\end{definition} +This removes the entry for \meta{key} from the current row. + +\begin{definition}[\DescribeMacro{\DTLremovecurrentrow}]% +\cs{DTLremovecurrentrow} +\end{definition} +This removes the current row from the database. + +\begin{example}{Editing Database Rows}{ex:editdb} +In this example I have a CSV file called "marks.csv" that contains +student marks for three assignments: +\DTLnewdb{marks}\relax +\DTLnewrow{marks}\relax +\DTLnewdbentry{marks}{FirstName}{John}\relax +\DTLnewdbentry{marks}{Surname}{Smith, Jr}\relax +\DTLnewdbentry{marks}{StudentNo}{102689}\relax +\DTLnewdbentry{marks}{Assignment 1}{68}\relax +\DTLnewdbentry{marks}{Assignment 2}{57}\relax +\DTLnewdbentry{marks}{Assignment 3}{72}\relax +\DTLnewrow{marks}\relax +\DTLnewdbentry{marks}{FirstName}{Jane}\relax +\DTLnewdbentry{marks}{Surname}{Brown}\relax +\DTLnewdbentry{marks}{StudentNo}{102647}\relax +\DTLnewdbentry{marks}{Assignment 1}{75}\relax +\DTLnewdbentry{marks}{Assignment 2}{84}\relax +\DTLnewdbentry{marks}{Assignment 3}{80}\relax +\DTLnewrow{marks}\relax +\DTLnewdbentry{marks}{FirstName}{Andy}\relax +\DTLnewdbentry{marks}{Surname}{Brown}\relax +\DTLnewdbentry{marks}{StudentNo}{103569}\relax +\DTLnewdbentry{marks}{Assignment 1}{42}\relax +\DTLnewdbentry{marks}{Assignment 2}{52}\relax +\DTLnewdbentry{marks}{Assignment 3}{54}\relax +\DTLnewrow{marks}\relax +\DTLnewdbentry{marks}{FirstName}{Z\"oe}\relax +\DTLnewdbentry{marks}{Surname}{Adams}\relax +\DTLnewdbentry{marks}{StudentNo}{105987}\relax +\DTLnewdbentry{marks}{Assignment 1}{52}\relax +\DTLnewdbentry{marks}{Assignment 2}{48}\relax +\DTLnewdbentry{marks}{Assignment 3}{57}\relax +\DTLnewrow{marks}\relax +\DTLnewdbentry{marks}{FirstName}{Roger}\relax +\DTLnewdbentry{marks}{Surname}{Brady}\relax +\DTLnewdbentry{marks}{StudentNo}{106872}\relax +\DTLnewdbentry{marks}{Assignment 1}{58}\relax +\DTLnewdbentry{marks}{Assignment 2}{60}\relax +\DTLnewdbentry{marks}{Assignment 3}{62}\relax +\DTLnewrow{marks}\relax +\DTLnewdbentry{marks}{FirstName}{Clare}\relax +\DTLnewdbentry{marks}{Surname}{Verdon}\relax +\DTLnewdbentry{marks}{StudentNo}{104356}\relax +\DTLnewdbentry{marks}{Assignment 1}{45}\relax +\DTLnewdbentry{marks}{Assignment 2}{50}\relax +\DTLnewdbentry{marks}{Assignment 3}{48}\relax +\begin{ttfamily}\setlength{\parindent}{0pt}\par +Surname,FirstName,StudentNo,Assignment 1,Assignment 2,Assignment 3 + +\DTLforeach{marks}{\surname=Surname,\firstname=FirstName,\regNo +=StudentNo,\assignI=Assignment 1,\assignII +=Assignment 2,\assignIII=Assignment 3}{\relax +\char`\"\surname\char`\",\DTLifstringeq{\firstname}{Zoe}{Z\string\"oe}{\firstname},\regNo,\assignI,\assignII,\assignIII\par +} +\end{ttfamily}\par\noindent +First load this into a database called "marks": +\begin{verbatim} +\DTLloaddb{marks}{marks.csv} +\end{verbatim} +Suppose now I want to compute the average mark for each +student, and append this to the database. I can do this as +follows: +\begin{verbatim} +\DTLforeach{marks}{% +\assignI=Assignment 1,% +\assignII=Assignment 2,% +\assignIII=Assignment 3}{% +\DTLmeanforall{\theMean}{\assignI,\assignII,\assignIII}% +\DTLappendtorow{Average}{\theMean}} +\end{verbatim} +\DTLforeach{marks}{\assignI=Assignment 1,\assignII +=Assignment 2,\assignIII=Assignment 3}{\relax +\DTLmeanforall{\theMean}{\assignI,\assignII,\assignIII}% +\DTLappendtorow{Average}{\theMean}}\relax +For each row in the "marks" database, I now have an extra key +called "Average" that contains the average mark over all three +assignments for a given student. I can now put this data into +a table: +\begin{verbatim} +\begin{table}[htbp] +\caption{Student marks} +\centering +\begin{tabular}{llcccc} +\bfseries Surname & \bfseries First Name & +\bfseries Assign 1 & +\bfseries Assign 2 & +\bfseries Assign 3 & +\bfseries Average Mark% +\DTLforeach{marks}{\surname=Surname,\firstname=FirstName,\average +=Average,\assignI=Assignment 1,\assignII=Assignment 2,\assignIII +=Assignment 3}{\\\surname +& \firstname & \assignI & \assignII & \assignIII & +\DTLround{\average}{\average}{2}\DTLclip{\average}\average}\relax +\end{tabular} +\end{table} +\end{verbatim} +This produces \autoref{tab:meanmarks}. + +Note that if I only wanted the averages for the table and nothing +else, I could simply have computed the average in each row of the +table and displayed it without adding the information to the +database, however I am going to reuse this information in +\autoref{ex:multibar}, so adding it to the database means that +I don't need to recompute the mean. + +\begin{table}[htbp] +\caption[Student marks (with averages)]{Student +marks}\label{tab:meanmarks} +\centering +\begin{tabular}{llcccc} +\bfseries Surname & \bfseries First Name & +\bfseries Assign 1 & +\bfseries Assign 2 & +\bfseries Assign 3 & +\bfseries Average Mark\relax +\DTLforeach{marks}{\surname=Surname,\firstname=FirstName,\average +=Average,\assignI=Assignment 1,\assignII=Assignment 2,\assignIII +=Assignment 3}{\\\surname +& \firstname & \assignI & \assignII & \assignIII & +\DTLround{\average}{\average}{2}\DTLclip{\average}\average}\relax +\end{tabular} +\end{table} + +\end{example} + +\section{Arithmetical Computations on Database Entries} + +The commands used in \autoref{sec:fp} can be used on database +entries. You can, of course, directly use the commands provided +by the \sty{fp} package if you know that the values are in the +correct format (i.e.\ no currency symbols, no number group +separators and a full stop as the decimal point) but if this is +not the case, then you should use the commands described in +\autoref{sec:fp}. If you want to use a command provided by the +\sty{fp} package, that does not have a wrapper function in +\sty{datatool}, then you will need to convert the value using +\ics{DTLconverttodecimal}, and convert it back using either +\ics{DTLdecimaltolocale} or \ics{DTLdecimaltocurrency}. + +\begin{example}{Arithmetical Computations}{ex:mean} +In this example, I am going to produce a table similar to +\autoref{tab:scores}, except that I want to add an extra row at the +end which contains the average score. +\begin{verbatim} +\begin{table}[htbp] +\caption{Student scores}\label{tab:mean} +\centering +\def\total{0}% +\begin{tabular}{llr} +\bfseries First Name & +\bfseries Surname & +\bfseries Score (\%)% +\DTLforeach{scores}{% +\firstname=FirstName,\surname=Surname,\score=Score}{% +\\ +\firstname & \surname & +\DTLgadd{\total}{\score}{\total}% +\score +}\\ +\multicolumn{2}{l}{\bfseries Average Score} & +\DTLsavelastrowcount{\n}% +\DTLdiv{\average}{\total}{\n}% +\DTLround{\average}{\average}{2}% +\average +\end{tabular} +\end{table} +\end{verbatim} +This produces \autoref{tab:mean}. +\textbf{Notes:} +\begin{itemize} +\item I had to use \ics{DTLgadd} rather than \ics{DTLadd} since it +occurs within a \env{tabular} environment which puts each entry +in a local scope. + +\item I used \ics{DTLsavelastrowcount} to store the number of +rows produced by \ics{DTLforeach} in the control sequence \cs{n}. + +\item I used \ics{DTLround} to round the average score to 2 decimal +places. +\end{itemize} + +\begin{table}[htbp] +\caption[Student scores (using arithmetic computations)]{Student +scores}\label{tab:mean} +\centering +\def\total{0}\relax +\begin{tabular}{llr} +\bfseries First Name & +\bfseries Surname & +\bfseries Score (\%)\relax +\DTLforeach{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax +\\ +\firstname & \surname & +\DTLgadd{\total}{\score}{\total}\relax +\score +}\\ +\multicolumn{2}{l}{\bfseries Average Score} & +\DTLsavelastrowcount{\n}\relax +\DTLdiv{\average}{\total}{\n}\relax +\DTLround{\average}{\average}{2}\relax +\average +\end{tabular} +\end{table} +\end{example} + +\begin{definition}[\DescribeMacro{\DTLsumforkeys}]% +\cs{DTLsumforkeys}\oarg{condition}\oarg{assign list}\marg{db list}\marg{key list}\marg{cmd} +\end{definition} +This command sums all the entries over all the databases listed in +the comma separated list of database names \meta{db list} for each +key in \meta{key list} where the condition given by \meta{condition} +is true. The second optional argument \meta{assign list} is the same +as the assignment list used by \ics{DTLforeach}, so that you can use +the information in \meta{condition}. The result is stored in +\meta{cmd} which must be a control sequence. For example: +\begin{verbatim} +\DTLsumforkeys{scores}{Score}{\total} +\end{verbatim} +sets \cs{total} to the sum of all the scores in the database +called "scores". + +\begin{definition}[\DescribeMacro{\DTLsumcolumn}]% +\cs{DTLsumcolumn}\marg{db}\marg{key}\marg{cmd} +\end{definition} +This is a faster version of \cs{DTLsumforkeys} that only sums +the entries in a single column (specified by \meta{key}) for +a single database (specified by \meta{db}) and doesn't provide any +filtering. The result is stored in \meta{cmd} which must be +a control sequence. + +\begin{definition}[\DescribeMacro{\DTLmeanforkeys}]% +\cs{DTLmeanforkeys}\oarg{condition}\oarg{assign list}\marg{db list}\marg{key list}\marg{cmd} +\end{definition} +This command computes the arithmetic mean of all the entries over +all the databases listed in \meta{db list} for all keys in \meta{key +list} where the condition given by \meta{condition} is true. The +second optional argument \meta{assign list} is the same as the +assignment list used by \ics{DTLforeach}, so that you can use the +information in \meta{condition}. The result is stored in \meta{cmd} +which must be a control sequence. For example: +\begin{verbatim} +\DTLmeanforkeys{scores}{Score}{\average} +\end{verbatim} +sets \cs{average} to the mean of all the scores in the database +called "scores". + +\begin{definition}[\DescribeMacro{\DTLmeanforcolumn}]% +\cs{DTLmeanforcolumn}\marg{db}\marg{key}\marg{cmd} +\end{definition} +This is a faster version of \cs{DTLmeanforkeys} that only computes +the mean for a single column (specified by \meta{key}) for +a single database (specified by \meta{db}) and doesn't provide any +filtering. The result is stored in \meta{cmd} which must be +a control sequence. + +\begin{definition}[\DescribeMacro{\DTLvarianceforkeys}]% +\cs{DTLvarianceforkeys}\oarg{condition}\oarg{assign list}\marg{db list}\marg{key list}\marg{cmd} +\end{definition} +This command computes the variance of all the entries over all the +databases listed in \meta{db list} for all keys in \meta{key list} +where the condition given by \meta{condition} is true. The second +optional argument \meta{assign list} is the same as the assignment +list used by \ics{DTLforeach}, so that you can use the information +in \meta{condition}. The result is stored in \meta{cmd} which must +be a control sequence. + +\begin{definition}[\DescribeMacro{\DTLvarianceforcolumn}]% +\cs{DTLvarianceforcolumn}\marg{db}\marg{key}\marg{cmd} +\end{definition} +This is a faster version of \cs{DTLvarianceforkeys} that only +computes the variance for a single column (specified by \meta{key}) +for a single database (specified by \meta{db}) and doesn't provide +any filtering. The result is stored in \meta{cmd} which must be a +control sequence. + +\begin{definition}[\DescribeMacro{\DTLsdforkeys}]% +\cs{DTLsdforkeys}\oarg{condition}\oarg{assign list}\marg{db list}\marg{key list}\marg{cmd} +\end{definition} +This command computes the standard deviation of all the entries over +all the databases listed in \meta{db list} for all keys in \meta{key +list} where the condition given by \meta{condition} is true. The +second optional argument \meta{assign list} is the same as the +assignment list used by \ics{DTLforeach}, so that you can use the +information in \meta{condition}. The result is stored in \meta{cmd} +which must be a control sequence. + +\begin{definition}[\DescribeMacro{\DTLsdforcolumn}]% +\cs{DTLsdforcolumn}\marg{db}\marg{key}\marg{cmd} +\end{definition} +This is a faster version of \cs{DTLsdforkeys} that only computes the +standard deviation for a single column (specified by \meta{key}) for +a single database (specified by \meta{db}) and doesn't provide any +filtering. The result is stored in \meta{cmd} which must be a +control sequence. + +\begin{definition}[\DescribeMacro{\DTLminforkeys}]% +\cs{DTLminforkeys}\oarg{condition}\oarg{assign list}\marg{db list}\marg{key list}\marg{cmd} +\end{definition} +This command determines the minimum value over all entries for all +keys in \meta{key list} over all the databases listed in \meta{db +list} where \meta{condition} is true. The second optional argument +\meta{assign list} is the same as the assignment list used by +\ics{DTLforeach}, so that you can use the information in +\meta{condition}. The result is stored in \meta{cmd}, which must be +a control sequence. For example +\begin{verbatim} +\DTLminforkeys{scores}{Score}{\theMin} +\end{verbatim} +sets \cs{theMin} to the minimum score in the database. + +\begin{definition}[\DescribeMacro{\DTLminforcolumn}]% +\cs{DTLminforcolumn}\marg{db}\marg{key}\marg{cmd} +\end{definition} +This is a faster version of \cs{DTLminforkeys} that only computes +the minimum for a single column (specified by \meta{key}) for +a single database (specified by \meta{db}) and doesn't provide any +filtering. The result is stored in \meta{cmd} which must be +a control sequence. + +\begin{definition}[\DescribeMacro{\DTLmaxforkeys}]% +\cs{DTLmaxforkeys}\oarg{condition}\oarg{assign list}\marg{db list}\marg{key list}\marg{cmd} +\end{definition} +This command determines the maximum value over all entries for all +keys in \meta{key list} over all the databases listed in \meta{db +list} where \meta{condition} is true. The second optional argument +\meta{assign list} is the same as the assignment list used by +\ics{DTLforeach}, so that you can use the information in +\meta{condition}. The result is stored in \meta{cmd}, which must be +a control sequence. For example +\begin{verbatim} +\DTLminforkeys{scores}{Score}{\theMax} +\end{verbatim} +sets \cs{theMax} to the minimum score in the database. + +\begin{definition}[\DescribeMacro{\DTLmaxforcolumn}]% +\cs{DTLmaxforcolumn}\marg{db}\marg{key}\marg{cmd} +\end{definition} +This is a faster version of \cs{DTLmaxforkeys} that only computes +the maximum for a single column (specified by \meta{key}) for +a single database (specified by \meta{db}) and doesn't provide any +filtering. The result is stored in \meta{cmd} which must be +a control sequence. + +\begin{definition}[\DescribeMacro{\DTLcomputebounds}]% +\cs{DTLcomputebounds}\marg{db list}\marg{x key}\marg{y key}\marg{minX cmd}\marg{minY cmd}\marg{maxX cmd}\marg{maxY cmd} +\end{definition} +Computes the maximum and minimum $x$ and $y$ values over all +the databases listed in \meta{db list} where the $x$ value +is given by \meta{x key} and the $y$ value is given by +\meta{y key}. The results are stored in \meta{minX cmd}, +\meta{minY cmd}, \meta{maxX cmd} and \meta{maxY cmd}. + +\begin{example}{Mail Merging}{ex:mailmerging} +This example uses the database given in \autoref{ex:scores} and +uses \ics{DTLmeanforkeys} to determine the average score. A letter +is then created for each student to inform them of their score +and the class average. + +\begin{verbatim} +\documentclass{letter} + +\usepackage{datatool} + +\begin{document} + % load database +\DTLloaddb{scores}{studentscores.csv} + % compute arithmetic mean for key `Score' +\DTLmeanforkeys{scores}{Score}{\average} + % Round the average to 2 decimal places +\DTLround{\average}{\average}{2} + % Save the highest score in \maxscore +\DTLmaxforkeys{scores}{Score}{\maxscore} + +\DTLforeach{scores}{\firstname=FirstName,\surname=Surname,% +\score=Score}{% +\begin{letter}{} +\opening{Dear \firstname\ \surname} + +\DTLifnumgt{\score}{60}{Congratulations you}{You} achieved a score +of \score\% which was \DTLifnumgt{\score}{\average}{above}{below} +the average of \average\%. \DTLifnumeq{\score}{\maxscore}{You +achieved the highest score}{The top score was \maxscore}. + +\closing{Yours Sincerely} +\end{letter} +} +\end{document} +\end{verbatim} + +To determine a person's gender when mail merging, see +\autoref{sec:person}. +\end{example} + +\section{Sorting a Database} +\label{sec:sort} + +\begin{definition}[\DescribeMacro{\DTLsort}]% +\cs{DTLsort}\oarg{replacement key list}\marg{sort criteria}\marg{db name} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLsort*}]% +\cs{DTLsort*}\oarg{replacement key list}\marg{sort criteria}\marg{db name} +\end{definition} +This will sort the database called \meta{db name} according to +the criteria given by \meta{sort criteria}, which must be a +comma separated list of keys and optionally "="\meta{order}, where +\meta{order} is either "ascending" or "descending". If the order +is omitted, "ascending" is assumed. The database keeps track of +the data type for a given key, and uses this to determine whether +an alphabetical or numerical sort is required. (String comparisons +are made using the command \cs{dtlcompare} or \cs{dtlicompare} +described in \autoref{src:dtlcompare}.) + +The optional argument \meta{replacement key list} is a list of +keys to use if the current key given in \meta{sort criteria} +is null for a given entry. Null keys are unlikely to occur if +you have loaded the database from an external ASCII file, but +may occur if the database is created using \cs{DTLnewdb}, +\cs{DTLnewrow} and \cs{DTLnewdbentry}. For example: +\begin{verbatim} +\DTLsort[Editor,Organization]{Author}{mydata} +\end{verbatim} +will sort according to the "Author" key, but if that key is missing +for a given row of the database, the "Editor" key will be used, +and if the "Editor" key is missing, it will use the "Organization" +key. Note that this is not the same as: +\begin{verbatim} +\DTLsort{Author,Editor,Organization}{mydata} +\end{verbatim} +which will first compare the "Author" keys, but if the author names +are the same, it will then compare the "Editor" keys, and if the +editor names are also the same, it will then compare the +"Organization" keys. + +The unstarred version uses a case sensitive comparison for strings, +whereas the starred version ignores the case when comparing strings. +Note that the case sensitive comparison orders uppercase characters +before lowercase characters, so the letter B is considered to be +lower than the letter a. + +\begin{example}{Sorting a Database}{ex:sort} +This example uses the database called "scores" defined in +\autoref{ex:scores}. First, I am going to sort the database +according to the student scores in descending order (highest to +lowest) and display the database in a table +\begin{verbatim} +\begin{table}[htbp] +\caption{Student scores (sorted by score)} +\centering +\DTLsort{Score=descending}{scores}% +\begin{tabular}{llr} +\bfseries First Name & +\bfseries Surname & +\bfseries Score (\%)% +\DTLforeach{scores}{% +\firstname=FirstName,\surname=Surname,\score=Score}{% +\\ +\firstname & \surname & \score} +\end{tabular} +\end{table} +\end{verbatim} +This produces \autoref{tab:sortscores}. + +\begin{table}[htbp] +\caption{Student scores (sorted by score)}\label{tab:sortscores} +\centering +\DTLsort{Score=descending}{scores}\relax +\begin{tabular}{llr} +\bfseries First Name & +\bfseries Surname & +\bfseries Score (\%)\relax +\DTLforeach{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax +\\ +\firstname & \surname & \score} +\end{tabular} +\end{table} + +Now I am going to sort the database according to +surname and then first name, and display it in a table. Note that +since I want to sort in ascending order, I can omit the +"=ascending" part of the sort criteria. I have also decided to +reverse the first and second columns, so that the surname is +in the first column. +\begin{verbatim} +\begin{table}[htbp] +\caption{Student scores (sorted by name)} +\centering +\DTLsort{Surname,FirstName}{scores}% +\begin{tabular}{llr} +\bfseries Surname & +\bfseries First Name & +\bfseries Score (\%)% +\DTLforeach{scores}{% +\firstname=FirstName,\surname=Surname,\score=Score}{% +\\ +\surname & \firstname & \score} +\end{tabular} +\end{table} +\end{verbatim} +This produces \autoref{tab:sortname}. +\begin{table}[htbp] +\caption{Student scores (sorted by name)}\label{tab:sortname} +\centering +\DTLsort{Surname,FirstName}{scores}\relax +\begin{tabular}{llr} +\bfseries Surname & +\bfseries First Name & +\bfseries Score (\%)\relax +\DTLforeach{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax +\\ +\surname & \firstname & \score} +\end{tabular} +\end{table} + +Now suppose I add two new students to the database: +\begin{verbatim} +\DTLnewrow{scores}% +\DTLnewdbentry{scores}{Surname}{van der Mere}% +\DTLnewdbentry{scores}{FirstName}{Henk}% +\DTLnewdbentry{scores}{Score}{71}% +\DTLnewrow{scores}% +\DTLnewdbentry{scores}{Surname}{de la Mere}% +\DTLnewdbentry{scores}{FirstName}{Jos}% +\DTLnewdbentry{scores}{Score}{58}% +\end{verbatim} +\DTLnewrow{scores} +\DTLnewdbentry{scores}{Surname}{van der Mere}\relax +\DTLnewdbentry{scores}{FirstName}{Henk}\relax +\DTLnewdbentry{scores}{Score}{71}\relax +\DTLnewrow{scores}\relax +\DTLnewdbentry{scores}{Surname}{de la Mere}\relax +\DTLnewdbentry{scores}{FirstName}{Jos}\relax +\DTLnewdbentry{scores}{Score}{58}\relax +and again I try sorting the database, and displaying the contents +as a table: +\begin{verbatim} +\begin{table}[htbp] +\caption{Student scores (case sensitive sort)} +\centering +\DTLsort{Surname,FirstName}{scores}% +\begin{tabular}{llr} +\bfseries Surname & +\bfseries First Name & +\bfseries Score (\%)% +\DTLforeach{scores}{% +\firstname=FirstName,\surname=Surname,\score=Score}{% +\\ +\surname & \firstname & \score} +\end{tabular} +\end{table} +\end{verbatim} +This produces \autoref{tab:sortname2}. Notice that the surnames +aren't correctly ordered. This is because a case-sensitive +sort was used. Changing \cs{DTLsort} to \cs{DTLsort*} in the +above code produces \autoref{tab:sortname3}. + +\begin{table}[htbp] +\caption{Student scores (case sensitive sort)}\label{tab:sortname2} +\centering +\DTLsort{Surname,FirstName}{scores}\relax +\begin{tabular}{llr} +\bfseries Surname & +\bfseries First Name & +\bfseries Score (\%)\relax +\DTLforeach{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax +\\ +\surname & \firstname & \score} +\end{tabular} +\end{table} + +\begin{table}[htbp] +\caption{Student scores (case ignored when +sorting)}\label{tab:sortname3} +\centering +\DTLsort*{Surname,FirstName}{scores}\relax +\begin{tabular}{llr} +\bfseries Surname & +\bfseries First Name & +\bfseries Score (\%)\relax +\DTLforeach{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax +\\ +\surname & \firstname & \score} +\end{tabular} +\end{table} + +\end{example} + +\begin{example}{Influencing the sort order}{ex:sortswitchargs} +Consider the data displayed in \autoref{tab:sortname3}, suppose that +you want the names ``van der Mere'' and ``de la Mere'' sorted +according to the actual surname ``Mere'' rather than by the ``von +part''. There are two ways you can do this: firstly, you could store +the von part in a separate field, and then sort by surname, then von +part, then first name, or you could define a command called, say, +\cs{switchargs}, as follows: +\begin{verbatim} +\newcommand*{\switchargs}[2]{#2#1} +\end{verbatim} +\newcommand*{\switchargs}[2]{#2#1}\relax +then store the data as: +\begin{verbatim} +FirstName,Surname,StudentNo,Score +John,"Smith, Jr",102689,68 +Jane,Brown,102647,75 +Andy,Brown,103569,42 +Z\"oe,Adams,105987,52 +Roger,Brady,106872,58 +Clare,Verdon,104356,45 +Henk,\switchargs{Mere}{van der },106789,71 +Jos,\switchargs{Mere}{de la },104256,58 +\end{verbatim} +\DTLnewdb{scores2}\relax +\DTLnewrow{scores2}\relax +\DTLnewdbentry{scores2}{FirstName}{John}\relax +\DTLnewdbentry{scores2}{Surname}{Smith, Jr}\relax +\DTLnewdbentry{scores2}{StudentNo}{102689}\relax +\DTLnewdbentry{scores2}{Score}{68}\relax +\DTLnewrow{scores2}\relax +\DTLnewdbentry{scores2}{FirstName}{Jane}\relax +\DTLnewdbentry{scores2}{Surname}{Brown}\relax +\DTLnewdbentry{scores2}{StudentNo}{102647}\relax +\DTLnewdbentry{scores2}{Score}{75}\relax +\DTLnewrow{scores2}\relax +\DTLnewdbentry{scores2}{FirstName}{Andy}\relax +\DTLnewdbentry{scores2}{Surname}{Brown}\relax +\DTLnewdbentry{scores2}{StudentNo}{103569}\relax +\DTLnewdbentry{scores2}{Score}{42}\relax +\DTLnewrow{scores2}\relax +\DTLnewdbentry{scores2}{FirstName}{Z\"oe}\relax +\DTLnewdbentry{scores2}{Score}{52}\relax +\DTLnewdbentry{scores2}{StudentNo}{105987}\relax +\DTLnewdbentry{scores2}{Surname}{Adams}\relax +\DTLnewrow{scores2}\relax +\DTLnewdbentry{scores2}{FirstName}{Roger}\relax +\DTLnewdbentry{scores2}{Score}{58}\relax +\DTLnewdbentry{scores2}{StudentNo}{106872}\relax +\DTLnewdbentry{scores2}{Surname}{Brady}\relax +\DTLnewrow{scores2}\relax +\DTLnewdbentry{scores2}{FirstName}{Clare}\relax +\DTLnewdbentry{scores2}{Score}{45}\relax +\DTLnewdbentry{scores2}{StudentNo}{104356}\relax +\DTLnewdbentry{scores2}{Surname}{Verdon}\relax +\DTLnewrow{scores2} +\DTLnewdbentry{scores2}{Surname}{\switchargs{Mere}{van der }}\relax +\DTLnewdbentry{scores2}{FirstName}{Henk}\relax +\DTLnewdbentry{scores2}{Score}{71}\relax +\DTLnewrow{scores2}\relax +\DTLnewdbentry{scores2}{Surname}{\switchargs{Mere}{de la }}\relax +\DTLnewdbentry{scores2}{FirstName}{Jos}\relax +\DTLnewdbentry{scores2}{Score}{58}\relax +Now sort the data, and put it in table (this is the same code +as in the previous example: +\begin{verbatim} +\begin{table}[htbp] +\caption{Student scores (influencing the sort order)} +\centering +\DTLsort*{Surname,FirstName}{scores}% +\begin{tabular}{llr} +\bfseries Surname & +\bfseries First Name & +\bfseries Score (\%)% +\DTLforeach{scores}{% +\firstname=FirstName,\surname=Surname,\score=Score}{% +\\ +\surname & \firstname & \score} +\end{tabular} +\end{table} +\end{verbatim} +This produces \autoref{tab:influencesort}. + +\begin{table}[htbp] +\caption{Student scores (influencing the sort order)}\label{tab:influencesort} +\centering +\DTLsort*{Surname,FirstName}{scores2}\relax +\begin{tabular}{llr} +\bfseries Surname & +\bfseries First Name & +\bfseries Score (\%)\relax +\DTLforeach{scores2}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax +\\ +\surname & \firstname & \score} +\end{tabular} +\end{table} + +\end{example} + +\section{Saving a Database to an External File} +\label{sec:savedb} + +\begin{definition}[\DescribeMacro{\DTLsavedb}]% +\cs{DTLsavedb}\marg{db name}\marg{filename} +\end{definition} +This writes the database called \meta{db name} to a file called +\meta{filename}. The separator and delimiter characters used +are as given by \ics{DTLsetseparator} (or \ics{DTLsettabseparator}) +and \ics{DTLsetdelimiter}. For example: +\begin{verbatim} +\DTLsettabdelimiter +\DTLsavedb{scores}{scores.txt} +\end{verbatim} +will create a file called "scores.txt" and will save the data in a +tab separated format. (The delimiters will only be used if a +given entry contains the separator character.) + +\begin{definition}[\DescribeMacro{\DTLsavetexdb}]% +\cs{DTLsavetexdb}\marg{db name}\marg{filename} +\end{definition} +This writes the database called \meta{db name} to a \LaTeX\ file +called \meta{filename}, where the database is stored as +a combination of \ics{DTLnewdb}, \ics{DTLnewrow} and +\ics{DTLnewdbentry} commands. + +\section{Deleting or Clearing a Database}\label{sec:deletedb} + +A database can be cleared or deleted when its contents are no +longer required. +\begin{definition}[\DescribeMacro{\DTLcleardb}] +\cs{DTLcleardb}\marg{db name} +\end{definition} +Clears the database given by \meta{db name}. The database is emptied +but remains defined. + +\begin{definition}[\DescribeMacro{\DTLdeletedb}] +\cs{DTLdeletedb}\marg{db name} +\end{definition} +Deletes (undefines) the database given by \meta{db name}. + +\section{Advanced Database Commands} +\label{sec:advanced} + +This section describes more advanced commands. Further details +can be found in the documented code (datatool.pdf). + +\begin{definition}[\DescribeMacro{\DTLgetdatatype}] +\cs{DTLgetdatatype}\marg{cs}\marg{db}\marg{key} +\end{definition} +Gets the data type for the given key \meta{key} for the database +given by \meta{db}. The data type is stored in \meta{cs} which +must be a command name. The type will be one of: +\begin{itemize} +\item\DescribeMacro{\DTLunsettype}\cs{DTLunsettype} (not set), +\item\DescribeMacro{\DTLstringtype}\cs{DTLstringtype} (string), +\item\DescribeMacro{\DTLinttype}\cs{DTLinttype} (integer), +\item\DescribeMacro{\DTLrealtype}\cs{DTLrealtype} (real number) or +\item\DescribeMacro{\DTLcurrencytype}\cs{DTLcurrenttype} (currency). +\end{itemize} + +\begin{definition}[\DescribeMacro{\dtlforeachkey}]% +\cs{dtlforeachkey}(\meta{key cs},\meta{col cs},\meta{type +cs},\meta{header cs})\cs{in}\marg{db}\cs{do}\marg{body} +\end{definition} +This iterates through all the keys in the database given by +\meta{db}. In each iteration, \meta{key cs} is set to the key, +\meta{col cs} is set to the column index, \meta{type cs} is set to +the data type (as for \cs{DTLgetdatatype}), \meta{header cs} is set +to the header for that column, and then \meta{body} is done. Note +that \meta{key cs}, \meta{col cs}, \meta{type cs} and \meta{header +cs} must all be control sequences. No check is performed to +determine if that control sequence already exists, and the control +sequences are defined globally (since it's likely that +\cs{dtlforeachkey} may be used within a \env{tabular} environment), +so you need to make sure you don't override an existing command of +the same name. + +\begin{definition}[\DescribeMacro{\dtlforcolumn}]% +\cs{dtlforcolumn}\marg{cs}\marg{db}\marg{key}\marg{body} +\end{definition} +This iterates through the column given by \meta{key} in the +database given by \meta{db} and applies \meta{body}. In each +iteration, \meta{cs} (which must be a control sequence) is set to +the current element in the column and may be used in \meta{body}. +Alternatively, if you want to identify the column by its index +rather than its key, use: +\begin{definition}[\DescribeMacro{\dtlforcolumnindex}]% +\cs{dtlforcolumnindex}\marg{cs}\marg{db}\marg{col index}\marg{body} +\end{definition} + +\begin{definition}[\DescribeMacro{\DTLifdbexists}] +\cs{DTLifdbexists}\marg{db name}\marg{true part}\marg{false part} +\end{definition} +Determines if the database given by \meta{db name} exists. + +\begin{definition}[\DescribeMacro{\DTLifhaskey}] +\cs{DTLifhaskey}\marg{db name}\marg{key}\marg{true part}\marg{false part} +\end{definition} +This determines if the database given by \meta{db name} has +any entries with the key given by \meta{key}. If so, it does +\meta{true part} otherwise it does \meta{false part}. + +Each key has an associated column index. This can be obtained +using: +\begin{definition}[\DescribeMacro{\DTLgetcolumnindex}] +\cs{DTLgetcolumnindex}\marg{cs}\marg{db}\marg{key} +\end{definition} +where \meta{cs} is a command name, \meta{db} is the database label +and \meta{key} is the key. The column index is stored in +\meta{cs}. + +You can also do the reverse and find the key associated with a +given column index: +\begin{definition}[\DescribeMacro{\DTLgetkeyforcolumn}] +\cs{DTLgetkeyforcolumn}\marg{key cs}\marg{db}\marg{column index} +\end{definition} +The key is stored in \meta{key cs} (which must be a command name). + +There is also a full expandable way of obtaining the column +index, but note that no check is performed to determine +if the database exists, or if it contains the given key: +\begin{definition}[\DescribeMacro{\dtlcolumnindex}] +\cs{dtlcolumnindex}\marg{db name}\marg{key} +\end{definition} + +\begin{definition}[\DescribeMacro{\DTLgetkeydata}] +\cs{DTLgetkeydata}\marg{key}\marg{db}\marg{col cs}\marg{type cs}\marg{header cs} +\end{definition} +Gets data for given key in database \meta{db}: the column index is +stored in \meta{col cs} (as \cs{DTLgetcolumnindex}), the type is +stored in \meta{type cs} (as \cs{DTLgetdatatype}) and the header +is stored in \meta{header cs}. + +\begin{definition}[\DescribeMacro{\DTLgetvalue}] +\cs{DTLgetvalue}\marg{cs}\marg{db}\marg{r}\marg{c} +\end{definition} +This gets the value for row given by index \meta{r} and column +given by \meta{c} for the database \meta{db} and stores it in +\meta{cs} which must be a command name. If you want to get the +value by key rather than column index you can use +\cs{dtlcolumnindex}. For example, the following gets the value +for row~3 with key \texttt{Surname} from the database +\texttt{data} and stores in \cs{myval}: +\begin{verbatim} +\DTLgetvalue{\myval}{data}{3}{\dtlcolumnindex{data}{Surname}} +\end{verbatim} + +\begin{definition}[\DescribeMacro{\DTLgetlocation}] +\cs{DTLgetlocation}\marg{row cs}\marg{column cs}\marg{database}% +\marg{value} +\end{definition} +Assigns \meta{row cs} and \meta{column cs} to the indices of the +first entry in \meta{database} that matches \meta{value}. + +\begin{definition}[\DescribeMacro{\DTLgetvalueforkey}] +\cs{DTLgetvalueforkey}\marg{cmd}\marg{key}\marg{db name}\marg{ref + key}\marg{ref value} +\end{definition} +This (globally) sets \meta{cmd} (a control sequence) to the +value of the key specified by \meta{key} in the first row +of the database called \meta{db name} which contains the key +\meta{ref key} which has the value \meta{value}. + +\begin{definition}[\DescribeMacro{\DTLassign}] +\cs{DTLassign}\marg{db name}\marg{row idx}\marg{assign list} +\end{definition} +This (globally) assigns the list of commands in \meta{assign list} +for row \meta{row idx} in database \meta{db name}, where +\meta{assign list} has the same format as in \ics{DTLforeach}. + +Two rows can be swapped using: +\begin{definition}[\DescribeMacro{\DTLswaprows}]% +\cs{DTLswaprows}\marg{db name}\marg{row1 index}\marg{row2 index} +\end{definition} +where \meta{row1 index} and \meta{row2 index} are the indices +of the rows to be swapped. For example: +\begin{verbatim} +\DTLswaprows{scores}{3}{5} +\end{verbatim} +will swap the third and fifth rows. + +\begin{definition}[\DescribeMacro{\DTLifinlist}] +\cs{DTLifinlist}\marg{element}\marg{list}\marg{true part}\marg{false part} +\end{definition} +If \meta{element} is contained in the comma-separated list given +by \meta{list}, then do \meta{true part} otherwise do false +part. (Does a one level expansion on \meta{list}, but no +expansion on \meta{element}.) + +\begin{definition}[\DescribeMacro{\DTLnumitemsinlist}] +\cs{DTLnumitemsinlist}\marg{list}\marg{cmd} +\end{definition} +Counts the number of non-empty elements in \meta{list} and stores +result in \meta{cmd}, which must be a control sequence. + +\begin{example}{Two Database Rows Per Tabular Row +(Column-Wise)}{ex:twoblocks} +This example adapts \autoref{ex:2rows} so that the list is ordered +vertically rather than horizontally. +\begin{verbatim} +\begin{table}[htbp] + \caption{Two database rows per tabular row (column-wise)} + \centering + % store half number of rows + \edef\maxrows{\DTLrowcount{scores}}% + \DTLdiv{\halfrowidx}{\maxrows}{2} + \begin{tabular}{llcllc} + \bfseries First Name & + \bfseries Surname & + \bfseries Score (\%) & + \bfseries First Name & + \bfseries Surname & + \bfseries Score (\%)% + \DTLforeach*[\value{DTLrowi}<\halfrowidx]{scores}% + {\firstname=FirstName,\surname=Surname,\score=Score}% + {% + \\% + \firstname & \surname & \score + & + \edef\currentrowidx{\arabic{DTLrowi}}% + \DTLadd{\rowidxII}{\halfrowidx}{\currentrowidx}% + \DTLassign{scores}{\rowidxII}% + {\firstnameII=FirstName,\surnameII=Surname,\scoreII=Score}% + \firstnameII & \surnameII & \scoreII + }% + \end{tabular} +\end{table} +\end{verbatim} + +This produces \autoref{tab:twoblocks}. + +\begin{table}[htbp] + \caption{Two database rows per tabular row (column-wise)} + \label{tab:twoblocks} + \centering + % store half number of rows + \edef\maxrows{\DTLrowcount{scores}}% + \DTLdiv{\halfrowidx}{\maxrows}{2} + \begin{tabular}{llcllc} + \bfseries First Name & + \bfseries Surname & + \bfseries Score (\%) & + \bfseries First Name & + \bfseries Surname & + \bfseries Score (\%)% + \DTLforeach*[\value{DTLrowi}<\halfrowidx]{scores}% + {\firstname=FirstName,\surname=Surname,\score=Score}% + {% + \\% + \firstname & \surname & \score + & + \edef\currentrowidx{\arabic{DTLrowi}}% + \DTLadd{\rowidxII}{\halfrowidx}{\currentrowidx}% + \DTLassign{scores}{\rowidxII}{\firstnameII=FirstName,\surnameII=Surname,\scoreII=Score}% + \firstnameII & \surnameII & \scoreII + }% + \end{tabular} +\end{table} +\end{example} + +\subsection{Operating on Current Row} +\label{sec:currentrow} + +If you want to select from or edit a particular row in a database without having +to iterate through the database using \cs{DTLforeach}, you can use +the commands described in this section. + +\begin{definition}[\DescribeMacro{\dtlgetrow}] +\cs{dtlgetrow}\marg{db name}\marg{row idx} +\end{definition} +Gets the row with index \meta{row idx} from the database \meta{db +name}. The required row is stored in the token register +\begin{definition}[\DescribeMacro{\dtlcurrentrow}] +\cs{dtlcurrentrow} +\end{definition} +the preceding rows are stored in the token register +\begin{definition}[\DescribeMacro{\dtlbeforerow}] +\cs{dtlbeforerow} +\end{definition} +the following rows are stored in the token register +\begin{definition}[\DescribeMacro{\dtlafterrow}] +\cs{dtlafterrow} +\end{definition} +the row index, \meta{row idx}, is stored in the register +\begin{definition}[\DescribeMacro{\dtlrownum}] +\cs{dtlrownum} +\end{definition} +and the database name is stored in the control sequence +\begin{definition}[\DescribeMacro{\dtldbname}] +\cs{dtldbname} +\end{definition} +\begin{important} +No check is made in \cs{dtlgetrow} to see +if the database exists or if the row index is valid. You will probably get a \qt{Missing \{ +inserted} error if you misspell the database name and a \qt{Runaway +argument} error if you specify a row index that is out of range. +\end{important} + +You can use the commands below to access or edit \cs{dtlcurrentrow}, but +they won't change the database. Instead, once you've finished +editing \cs{dtlcurrentrow}, you need to reconstruct the database +token by recombining \cs{dtlbeforerow}, \cs{dtlcurrentrow} and +\cs{dtlafterrow} using: +\begin{definition}[\DescribeMacro{\dtlrecombine}] +\cs{dtlrecombine} +\end{definition} +Alternatively, to recombine omitting the current row: +\begin{definition}[\DescribeMacro{\dtlrecombineomitcurrent}] +\cs{dtlrecombineomitcurrent} +\end{definition} +(This removes the current row from the database, shifting the row +indices in \cs{dtlafterrow}.) Note that these recombining commands +assume that you haven't altered \cs{dtlrownum}, \cs{dtldbname}, +\cs{dtlbeforerow} and \cs{dtlafterrow}. + +\begin{important} +\cs{dtlcurrentrow} stores the row information using \sty{datatool}'s +internal row syntax, described in the documented code (datatool.pdf). +Don't explicitly modify \cs{dtlcurrentrow} unless you have a good +understanding of the syntax. +\end{important} + +\begin{definition}[\DescribeMacro{\dtlgetentryfromcurrentrow}] +\cs{dtlgetentryfromcurrentrow}\marg{cs}\marg{col idx} +\end{definition} +Gets the value from \cs{dtlcurrentrow} for the column given by +\meta{col idx} (an integer) and stores in \meta{cs}, which must be a +control sequence. + +\begin{definition}[\DescribeMacro{\dtlreplaceentryincurrentrow}] +\cs{dtlreplaceentryincurrentrow}\meta{new value}\marg{col idx} +\end{definition} +Replaces the value in \cs{dtlcurrentrow} for the column given by +\meta{col idx} (an integer) with \meta{new value}. +\begin{important} +The new value doesn't get expanded. +\end{important} + +\begin{definition}[\DescribeMacro{\dtlremoveentryincurrentrow}] +\cs{dtlremoveentryincurrentrow}\marg{col idx} +\end{definition} +Removes the value in \cs{dtlcurrentrow} for the column given by +\meta{col idx}. + +\begin{definition}[\DescribeMacro{\dtlswapentriesincurrentrow}] +\cs{dtlswapentriesincurrentrow}\marg{col1 idx}\marg{col2 idx} +\end{definition} +Swaps entries in columns \meta{col1 idx} and \meta{col2 idx} in +\cs{dtlcurrentrow} (where \meta{col1 idx} and \meta{col2 idx} are +the column indices). + +\begin{definition}[\DescribeMacro{\dtlappendentrytocurrentrow}] +\cs{dtlappendentrytocurrentrow}\marg{key}\marg{value} +\end{definition} +Appends \meta{value} to the current row for column given by +\meta{key}. (Note this is the only command in this section to +reference by key rather than by index.) + +\chapter{Pie Charts (\texorpdfstring{\sty{datapie}}{datapie} package)} +\label{sec:datapie} + +The \sty{datapie} package is not loaded by the \sty{datatool} package, +so you need to explicitly load \sty{datapie} if you want to use any of the +commands defined in this section. You will also need to have the +\sty{pgf}/\sty{tikz} packages installed. The \sty{datapie} package +may be given the following options: +\begin{description} +\item[{\pkgopt[datapie]{color}}] Colour option (default). +\item[{\pkgopt[datapie]{gray}}] Grey scale option. +\item[{\pkgopt[datapie]{rotateinner}}] +Rotate inner labels so that they are aligned +with the pie chart radial axis. +\item[{\pkgopt[datapie]{norotateinner}}] +Don't rotate inner labels (default). +\item[{\pkgopt[datapie]{rotateouter}}] +Rotate outer labels so that they are aligned +with the pie chart radial axis. +\item[{\pkgopt[datapie]{norotateouter}}] +Don't rotate outer labels (default). +\end{description} + +Numerical information contained in a database created by the +\sty{datatool} package can be converted into a pie chart using +\begin{definition}[\DescribeMacro{\DTLpiechart}]% +\cs{DTLpiechart}\oarg{condition}\marg{settings list}\marg{db name}\marg{values} +\end{definition}\noindent +where \meta{db name} is the name of the database, and +\meta{condition} has the same form as the optional argument +to \ics{DTLforeach} described in \autoref{sec:dbforeach}. If +\meta{condition} is false, that information is omitted from the +construction of the pie chart. The argument \meta{values} is a +comma separated list of \meta{cmd}"="\meta{key} pairs, the same +as that required by the penultimate argument of \ics{DTLforeach}. +The \meta{settings list} is a comma separated list of +\meta{setting}=\meta{value} pairs, where \meta{setting} can be any of +the following: +\begin{description} +\item[\csopt{DTLpiechart}{variable}] +This specifies the control sequence to use that +contains the value used to construct the pie chart. The control +sequence must be one of the control sequences to appear in +the assignment list \meta{values}. This setting is required. + +\item[\csopt{DTLpiechart}{start}] +This is the starting angle of the first segment. The +value is 0 by default. + +\item[\csopt{DTLpiechart}{radius}] +This is the radius of the pie chart. The default value +is 2cm. + +\item[\csopt{DTLpiechart}{innerratio}] +The distance from the centre of the +pie chart to the point where the inner labels are placed is given +by this value multiplied by the ratio. The default value is 0.5. + +\item[\csopt{DTLpiechart}{outerratio}] +The distance from the centre of the +pie chart to the point where the outer labels are placed is given +by this value multiplied by the ratio. The default value is 1.25. + +\item[\csopt{DTLpiechart}{cutawayratio}] +The distance from the centre of the pie chart +to the point of cutaway segments is given by this value multiplied +by the ratio. The default value is 0.2. + +\item[\csopt{DTLpiechart}{inneroffset}] +This is the absolute distance from the centre +of the pie chart to the point where the inner labels are placed. +You should use only one or other of \csopt{DTLpiechart}{innerratio} +and \csopt{DTLpiechart}{inneroffset}, not both. If you also want to +specify the radius, you must use \csopt{DTLpiechart}{ratio} +before \csopt{DTLpiechart}{inneroffset}. If omitted, the inner +offset is obtained from the ratio multiplied by the +\csopt{DTLpiechart}{innerratio} value. + +\item[\csopt{DTLpiechart}{outeroffset}] +This is the absolute distance from the centre +of the pie chart to the point where the outer labels are placed. +You should use only one or other of \csopt{DTLpiechart}{outerratio} +and \csopt{DTLpiechart}{outeroffset}, not both. If you also want to +specify the radius, you must use \csopt{DTLpiechart}{ratio} +before \csopt{DTLpiechart}{outeroffset}. If omitted, the outer +offset is obtained from the ratio multiplied by the +\csopt{DTLpiechart}{outerratio} value. + +\item[\csopt{DTLpiechart}{cutawayoffset}] +This is the absolute distance from the centre of +the pie chart to the point of the cutaway segments. You should use +only one or other of \csopt{DTLpiechart}{cutawayratio} and +\csopt{DTLpiechart}{cutawayoffset}, not both. If +you also want to specify the radius, you must use +\csopt{DTLpiechart}{ratio} before +\csopt{DTLpiechart}{cutawayoffset}. If omitted, the cutaway offset +is obtained from the ratio multiplied by the +\csopt{DTLpiechart}{cutawayratio} value. + +\item[\csopt{DTLpiechart}{cutaway}] +This is a list of cutaway segments. This should be +a comma separated list of individual numbers, or number ranges +(separated by a dash). For example "cutaway={1,3}" will separate +the first and third segments from the rest of the pie chart, offset +by the value of the \csopt{DTLpiechart}{cutawayoffset} setting, +whereas "cutaway={1-3}" will separate the +first three segments from the rest of the pie chart. If omitted, +the pie chart will be whole. + +\item[\csopt{DTLpiechart}{innerlabel}] +The value of this is positioned in the middle of each segment at a +distance of \csopt{DTLpiechart}{inneroffset} from the centre +of the pie chart. The default is the same as the value of +\csopt{DTLpiechart}{variable}. + +\item[\csopt{DTLpiechart}{outerlabel}] +The value of this is positioned at a distance of +\csopt{DTLpiechart}{outeroffset} from the centre of the pie chart. +The default is empty. + +\item[\csopt{DTLpiechart}{rotateinner}] This is a boolean setting, +so it can only take the values "true" and "false". If the value is +omitted "true" is assumed. If true, the inner labels are rotated +along the spokes of the pie chart, otherwise the inner labels are not +rotated. There are analogous package options +\pkgopt[datapie]{rotateinner} and \pkgopt[datapie]{norotateinner}. + +\item[\csopt{DTLpiechart}{rotateouter}] +This is a boolean setting, so it can only take +the values "true" and "false". If the value is omitted "true" is +assumed. If true, the outer labels are rotated along the spokes of +the pie chart, otherwise the outer labels are not rotated. +There are analogous package options +\pkgopt[datapie]{rotateouter} and \pkgopt[datapie]{norotateouter}. + +\end{description} + +\begin{example}{A Pie Chart}{ex:piechart} +This example loads data from a file called "fruit.csv" which contains +the following: +\begin{verbatim} +Name,Quantity +"Apples",30 +"Pears",25 +"Lemons,Limes",40.5 +"Peaches",34.5 +"Cherries",20 +\end{verbatim} +First load the data: +\begin{verbatim} +\DTLloaddb{fruit}{fruit.csv} +\end{verbatim} +\DTLnewdb{fruit}\relax +\DTLnewrow{fruit}\relax +\DTLnewdbentry{fruit}{Name}{Apples}\relax +\DTLnewdbentry{fruit}{Quantity}{30}\relax +\DTLnewrow{fruit}\relax +\DTLnewdbentry{fruit}{Name}{Pears}\relax +\DTLnewdbentry{fruit}{Quantity}{25}\relax +\DTLnewrow{fruit}\relax +\DTLnewdbentry{fruit}{Name}{Lemons,Limes}\relax +\DTLnewdbentry{fruit}{Quantity}{40.5}\relax +\DTLnewrow{fruit}\relax +\DTLnewdbentry{fruit}{Name}{Peaches}\relax +\DTLnewdbentry{fruit}{Quantity}{34.5}\relax +\DTLnewrow{fruit}\relax +\DTLnewdbentry{fruit}{Name}{Cherries}\relax +\DTLnewdbentry{fruit}{Quantity}{20}\relax +Now create a pie chart in a figure: +\begin{verbatim} +\begin{figure}[htbp] +\centering +\DTLpiechart{variable=\quantity}{fruit}{\name=Name,\quantity=Quantity} +\caption{A pie chart} +\end{figure} +\end{verbatim} +This creates \autoref{fig:piechart}. + +\begin{figure}[htbp] +\centering +\DTLpiechart{variable=\quantity}{fruit}{\name=Name,\quantity=Quantity} +\caption{A pie chart} +\label{fig:piechart} +\end{figure} + +There are no outer labels by default, but they can be set +using the \csopt{DTLpiechart}{outerlabel} setting. +The following sets the outer label to the value of the "Name" key: +\begin{verbatim} +\begin{figure}[htbp] +\centering +\DTLpiechart{variable=\quantity,outerlabel=\name}{fruit}{% +\name=Name,\quantity=Quantity} +\caption{A pie chart (outer labels set)} +\end{figure} +\end{verbatim} +This creates \autoref{fig:piechartouter}. + +\begin{figure}[htbp] +\centering +\DTLpiechart{variable=\quantity,outerlabel=\name}{fruit} +{\name=Name,\quantity=Quantity} +\caption{A pie chart (outer labels set)} +\label{fig:piechartouter} +\end{figure} + +You may prefer the labels to be rotated. The following +switches on the rotation for the inner and outer labels: +\begin{verbatim} +\begin{figure}[htbp] +\centering +\DTLpiechart{variable=\quantity,outerlabel=\name,% +rotateinner,rotateouter}{fruit}{% +\name=Name,\quantity=Quantity} +\caption{A pie chart (rotation enabled)} +\end{figure} +\end{verbatim} +This creates \autoref{fig:piechartrot}. + +\begin{figure}[htbp] +\centering +\DTLpiechart{variable=\quantity,outerlabel=\name +,rotateinner,rotateouter}{fruit} +{\name=Name,\quantity=Quantity} +\caption{A pie chart (rotation enabled)} +\label{fig:piechartrot} +\end{figure} +\end{example} + +\begin{example}{Separating Segments from the Pie Chart}{ex:cutaway} +You may want to separate one or more segments from the pie chart, +perhaps to emphasize them. You can do this using the +\csopt{DTLpiechart}{cutaway} +setting. The following separates the first and third segments +from the pie chart: +\begin{verbatim} +\begin{figure}[htbp] +\centering +\DTLpiechart{variable=\quantity,outerlabel=\name,% +cutaway={1,3}}{fruit}{% +\name=Name,\quantity=Quantity} +\caption{A pie chart with cutaway segments} +\end{figure} +\end{verbatim} +This produces \autoref{fig:piecutaway}. + +\begin{figure}[htbp] +\centering +\DTLpiechart{variable=\quantity,outerlabel=\name +,cutaway={1,3}}{fruit}{\name=Name,\quantity=Quantity} +\caption{A pie chart with cutaway segments} +\label{fig:piecutaway} +\end{figure} + +Alternatively I can specify a range of segments. The following +separates the first two segments: +\begin{verbatim} +\begin{figure}[htbp] +\centering +\DTLpiechart{variable=\quantity,outerlabel=\name,% +cutaway={1-2}}{fruit}{% +\name=Name,\quantity=Quantity} +\caption{A pie chart with cutaway segments (\texttt{cutaway=\{1-2\}})} +\end{figure} +\end{verbatim} +This produces \autoref{fig:piecutaway2}. + +\begin{figure}[htbp] +\centering +\DTLpiechart{variable=\quantity,outerlabel=\name +,cutaway={1-2}}{fruit}{\name=Name,\quantity=Quantity} +\caption{A pie chart with cutaway segments (\texttt{cutaway=\{1-2\}})} +\label{fig:piecutaway2} +\end{figure} + +Notice the difference between \autoref{fig:piecutaway2} and +\autoref{fig:piecutaway3} which was produced using: +\begin{verbatim} +\begin{figure}[htbp] +\centering +\DTLpiechart{variable=\quantity,outerlabel=\name,% +cutaway={1,2}}{fruit}{% +\name=Name,\quantity=Quantity} +\caption{A pie chart with cutaway segments (\texttt{cutaway=\{1,2\}})} +\end{figure} +\end{verbatim} + +\begin{figure}[htbp] +\centering +\DTLpiechart{variable=\quantity,outerlabel=\name +,cutaway={1,2}}{fruit}{\name=Name,\quantity=Quantity} +\caption{A pie chart with cutaway segments (\texttt{cutaway=\{1,2\}})} +\label{fig:piecutaway3} +\end{figure} + +\end{example} + +\section{Pie Chart Variables} + +\begin{definition}[\DescribeMacro{\DTLpievariable}]% +\cs{DTLpievariable} +\end{definition} +This command is set to the variable given by the +\csopt{DTLpiechart}{variable} setting in the \meta{settings list} +argument of \cs{DTLpiechart}. The \csopt{DTLpiechart}{innerlabel} +is set to \cs{DTLpievariable} by default. + +\begin{definition}[\DescribeMacro{\DTLpiepercent}]% +\cs{DTLpiepercent} +\end{definition} +This command is set to the percentage value of \cs{DTLpievariable}. +The percentage value is rounded to \meta{n} digits, where \meta{n} +is the value of the \LaTeX\ counter +\desctr{DTLpieroundvar}. + +\begin{example}{Changing the Inner and Outer Labels}{ex:pielabels} +This example uses the database defined in \autoref{ex:piechart}. +The inner label is now set to the percentage value, rather than +the actual value, and the outer label is set to the name with +the actual value in parentheses. +\begin{verbatim} +\begin{figure}[htbp] +\centering +\DTLpiechart{variable=\quantity,% +innerlabel={\DTLpiepercent\%},% +outerlabel={\name\ (\DTLpievariable)}}{fruit}{% +\name=Name,\quantity=Quantity} +\caption{A pie chart (changing the labels)} +\end{figure} +\end{verbatim} +This produces \autoref{fig:piechartlabels}. + +\begin{figure}[htbp] +\centering +\DTLpiechart{variable=\quantity,innerlabel={\DTLpiepercent +\%},outerlabel={\name\ (\DTLpievariable)}}{fruit}{\name=Name,\quantity=Quantity} +\caption{A pie chart (changing the labels)} +\label{fig:piechartlabels} +\end{figure} +\end{example} + +\section{Pie Chart Label Formatting} + +\begin{definition}[\DescribeMacro{\DTLdisplayinnerlabel}]% +\cs{DTLdisplayinnerlabel}\marg{text} +\end{definition} +This governs how the inner label is formatted, where \meta{text} +is the text of the inner label. The default is to just do \meta{text}. + +\begin{definition}[\DescribeMacro{\DTLdisplayouterlabel}]% +\cs{DTLdisplayouterlabel}\marg{text} +\end{definition} +This governs how the outer label is formatted, where \meta{text} +is the text of the outer label. The default is to just do \meta{text}. + +\begin{example}{Changing the Inner and Outer Label +Format}{ex:pielabelformat} +This example extends \autoref{ex:pielabels}. +The inner and outer labels are now both typeset in a sans-serif +font: +\begin{verbatim} +\begin{figure}[htbp] +\centering +\renewcommand*{\DTLdisplayinnerlabel}[1]{\textsf{#1}} +\renewcommand*{\DTLdisplayouterlabel}[1]{\textsf{#1}} +\DTLpiechart{variable=\quantity,% +innerlabel={\DTLpiepercent\%},% +outerlabel={\name\ (\DTLpievariable)}}{fruit}{% +\name=Name,\quantity=Quantity} +\caption{A pie chart (changing the label format)} +\end{figure} +\end{verbatim} +This produces \autoref{fig:piechartlabelformat}. + +\begin{figure}[htbp] +\centering +\renewcommand*{\DTLdisplayinnerlabel}[1]{\textsf{#1}} +\renewcommand*{\DTLdisplayouterlabel}[1]{\textsf{#1}} +\DTLpiechart{variable=\quantity,innerlabel={\DTLpiepercent +\%},outerlabel={\name\ (\DTLpievariable)}}{fruit}{\name=Name,\quantity=Quantity} +\caption{A pie chart (changing the label format)} +\label{fig:piechartlabelformat} +\end{figure} +\end{example} + +\section{Pie Chart Colours} + +The \sty{datapie} package predefines colours for the first +eight segments of the pie chart. If you require more than +eight segments or if you want to change the default colours, you +will need to use +\begin{definition}[\DescribeMacro{\DTLsetpiesegmentcolor}]% +\cs{DTLsetpiesegmentcolor}\marg{n}\marg{color} +\end{definition}\noindent +The first argument \meta{n} is the segment index (starting from 1), +and the second argument \meta{color} is a colour specifier as used +in commands such as \cs{color}. + +It is a good idea to set the colours so that each segment colour +is somehow relevant to whatever the segment represents. For +example, in the previous examples of pie charts depicting fruit, +some of default colours were inappropriate. Whilst red is +appropriate for apples and green is appropriate for pears, blue +doesn't really correspond to lemons or limes. + +\begin{definition}[\DescribeMacro{\DTLdopiesegmentcolor}]% +\cs{DTLdopiesegmentcolor}\meta{n} +\end{definition} +This sets the current text colour to that of the \meta{n}th +segment. + +\begin{definition}[\DescribeMacro{\DTLdocurrentpiesegmentcolor}]% +\cs{DTLdocurrentpiesegmentcolor} +\end{definition} +This sets the current text colour to that of the current pie +segment. This command may only be used within a pie chart, or +within the body of \ics{DTLforeach}. + +\begin{definition}[\DescribeMacro{\DTLpieoutlinecolor}]% +\cs{DTLpieoutlinecolor} +\end{definition} +This sets the outline colour for the pie chart. The default is +black. + +\begin{definition}[\DescribeMacro{\DTLpieoutlinewidth}]% +\cs{DTLpieoutlinewidth} +\end{definition} +This is a length that governs the line width of the outline. The +default value is 0pt, but can be changed using \cs{setlength}. +The outline is only drawn if \cs{DTLpieoutlinewidth} is greater +than 0pt. + +\begin{example}{Pie Segment Colours}{ex:piecolours} +This example extends \autoref{ex:pielabelformat}. +It sets the outline thickness to 2pt, and +the outer label is now set in the same colour as the fill colour +of the segment to which it belongs. The third segment (lemons and +limes) is set to yellow and the fourth segment (peaches) is set +to pink. In addition, a legend is created using \ics{DTLforeach}. +\begin{verbatim} +\begin{figure}[htbp] +\centering +\setlength{\DTLpieoutlinewidth}{2pt} +\DTLsetpiesegmentcolor{3}{yellow} +\DTLsetpiesegmentcolor{4}{pink} +\renewcommand*{\DTLdisplayinnerlabel}[1]{\textsf{#1}} +\renewcommand*{\DTLdisplayouterlabel}[1]{% +\DTLdocurrentpiesegmentcolor +\textsf{\shortstack{#1}}} +\DTLpiechart{variable=\quantity,% +innerlabel={\DTLpiepercent\%},% +outerlabel={\name\\(\DTLpievariable)}}{fruit}{% +\name=Name,\quantity=Quantity} +\begin{tabular}[b]{ll} +\DTLforeach{fruit}{\name=Name}{\DTLiffirstrow{}{\\}% +\DTLdocurrentpiesegmentcolor\rule{10pt}{10pt} & +\name +} +\end{tabular} +\caption{A pie chart (using segment colours and outline)} +\end{figure} +\end{verbatim} +This produces \autoref{fig:piesegcolour}. (The format of the +outer label has been changed to use \cs{shortstack} to +prevent the outer labels from taking up so much horizontal +space. The \csopt{DTLpiechart}{outerlabel} setting has also been +modified to use "\\" after the name to move the percentage value onto +the next row.) + +\begin{figure}[htbp] +\centering +\setlength{\DTLpieoutlinewidth}{2pt} +\DTLsetpiesegmentcolor{3}{yellow} +\DTLsetpiesegmentcolor{4}{pink} +\renewcommand*{\DTLdisplayinnerlabel}[1]{\textsf{#1}} +\renewcommand*{\DTLdisplayouterlabel}[1]{\relax +\DTLdocurrentpiesegmentcolor +\textsf{\shortstack{#1}}} +\DTLpiechart{variable=\quantity,innerlabel={\DTLpiepercent +\%},outerlabel={\name\\(\DTLpievariable)}}{fruit}{\name=Name,\quantity=Quantity} +\begin{tabular}[b]{ll} +\DTLforeach{fruit}{\name=Name}{\DTLiffirstrow{}{\\}\relax +\DTLdocurrentpiesegmentcolor\rule{10pt}{10pt} & +\name +} +\end{tabular} +\caption{A pie chart (using segment colours and outline)} +\label{fig:piesegcolour} +\end{figure} +\end{example} + +\section{Adding Extra Commands Before and After the Pie Chart} + +The pie charts created using \ics{DTLpiechart} are placed inside +a \env{tikzpicture} environment (defined by the \sty{tikz} package). + +\begin{definition}[\DescribeMacro{\DTLpieatbegintikz}]% +\cs{DTLpieatbegintikz} +\end{definition} +The macro \cs{DTLpieatbegintikz} is called at the start of the +\env{tikzpicture} environment, allowing you to change the +\env{tikzpicture} settings. By default \cs{DTLpieatbegintikz} +does nothing, but you can redefine it to, say, scale the pie +chart (but be careful not to distort the chart). + +\begin{definition}[\DescribeMacro{\DTLpieatendtikz}]% +\cs{DTLpieatendtikz} +\end{definition} +The macro \cs{DTLpieatendtikz} is called at the end of the +\env{tikzpicture} environment, allowing you add additional +graphics to the pie chart. This does nothing by default. + +\begin{example}{Adding Information to the Pie Chart}{ex:piescale} +This example modifies \autoref{ex:piechart}. It redefines +\cs{DTLpieatendtikz} to add an annotated arrow. +\begin{verbatim} +\begin{figure}[htbp] +\centering +\renewcommand*{\DTLpieatendtikz}{% +\draw[<-] (45:1.5cm) -- (40:2.5cm)node[right]{Apples};} +\DTLpiechart{variable=\quantity}{fruit}{% +\name=Name,\quantity=Quantity} +\caption{An annotated pie chart} +\end{figure} +\end{verbatim} +This produces \autoref{fig:pieannote}. (Note that the centre +of the pie chart is the origin of the TikZ picture.) + +\begin{figure}[htbp] +\centering +\renewcommand*{\DTLpieatendtikz}{% +\draw[<-] (45:1.5cm) -- (40:2.5cm)node[right]{Apples};} +\DTLpiechart{variable=\quantity}{fruit}{\name=Name,\quantity=Quantity} +\caption{An annotated pie chart} +\label{fig:pieannote} +\end{figure} +\end{example} + +\chapter{Scatter and Line Plots (\texorpdfstring{\sty{dataplot}}{dataplot} +package)} +\label{sec:dataplot} + +The \sty{dataplot} package provides commands for creating +scatter or line plots from databases. It uses the pgf/TikZ plot +handler library to create the plots. See the \sty{pgf} manual for +more detail on pgf streams and plot handles. The \sty{dataplot} +package is not loaded by \sty{datatool} so if you want to use +it you need to load it explicitly using "\usepackage{dataplot}". + + +\begin{definition}[\DescribeMacro{\DTLplot}]% +\cs{DTLplot}\oarg{condition}\marg{db list}\marg{settings} +\end{definition} +This command creates a plot (inside a \env{tikzpicture} environment) +of all the data given in the databases listed in \meta{db list}, +which should be a comma separated list of database names. +The optional argument \meta{condition} is the same as that for +\ics{DTLforeach}. The \meta{settings} argument is a comma separated +list of \meta{setting}"="\meta{value} pairs. There are two settings +that must be specified \csopt{DTLplot}{x} and \csopt{DTLplot}{y}. +The other settings are optional. Note that any value that contains +a comma, must be enclosed in braces. For example +"colors={red,cyan,blue}". Note where any setting requires +a number, or list of numbers (such as \csopt{DTLplot}{bounds}) +the number must be supplied in standard decimal notation (i.e.\ +no currency, no number groups, and a full stop as the decimal +point). Available settings are as follows: +\begin{description} +\item[\csopt{DTLplot}{x}] The database key +that specifies the $x$ co-ordinates. This setting is required. + +\item[\csopt{DTLplot}{y}] The database key that specifies +the $y$ co-ordinates. This setting is required. + +\item[\csopt{DTLplot}{markcolors}] A comma separated list of colour +names for the markers. An empty value will use the current colour. + +\item[\csopt{DTLplot}{linecolors}] A comma separated list of colour +names for the plot lines. An empty value will use the current colour. + +\item[\csopt{DTLplot}{colors}] A comma separated list of colour +names for the lines and markers. + +\item[\csopt{DTLplot}{marks}] A comma separated list of +code to generate plot marks. (This should typically be a list +of \cs{pgfuseplotmark} commands, see the \sty{pgf} manual for +further details.) You may use \cs{relax} as an element +of the list to suppress markers for the corresponding plot. +For example: "marks={\pgfuseplotmark{o},\relax}" will use an +open circle marker for the first database, and no markers for the +second database listed in \meta{db list}. + +\item[\csopt{DTLplot}{lines}] A comma separated list of +line style settings. (This should typically be a list of +\cs{pgfsetdash} commands, see the \sty{pgf} manual for +further details on how to set the line style.) An empty value +will use the current line style. +You may use \cs{relax} as an element +of the list to suppress line for the corresponding plot. +For example: "lines={\relax,\pgfsetdash{}{0pt}}" +will have no lines for the first database, and a solid line +for the second database listed in \meta{db list}. + +\item[\csopt{DTLplot}{width}] The width of the plot. This must +be a length. The plot width does not include outer tick marks or +labels. + +\item[\csopt{DTLplot}{height}] The height of the plot. This must +be a length. The plot height does not include outer tick marks +or labels. + +\item[\csopt{DTLplot}{style}] This setting governs whether +to use lines or markers in the plot, and may take one of +the following values: "both" (lines and markers), +"lines" (only lines) or "markers" (only markers). The default is +"markers". + +\item[\csopt{DTLplot}{axes}] This setting governs whether +to display the axes, and may take one of +the following values: "both", "x", "y" or "none". If no value +is specified, "both" is assumed. + +\item[\csopt{DTLplot}{box}] This setting governs whether +or not to surround the plot in a box. It is a boolean setting, +taking only the values "true" and "false". If no value is +specified, "true" is assumed. + +\item[\csopt{DTLplot}{xtics}] This setting governs whether +or not to display the $x$ tick marks. It is a boolean setting, +taking only the values "true" and "false". If no value is +specified "true" is assumed. If the \csopt{DTLplot}{axes} +setting is set to "both" or "x", this value will automatically +be set to "true", otherwise it will be set to "false". + +\item[\csopt{DTLplot}{ytics}] This setting governs whether +or not to display the $y$ ticks. It is a boolean setting, +taking only the values "true" and "false". If no value is +specified "true" is assumed. If the \csopt{DTLplot}{axes} +setting is set to "both" or "y", this value will automatically +be set to "true", otherwise it will be set to "false". + + +\item[\csopt{DTLplot}{xminortics}] This setting governs whether +or not to display the $x$ minor tick marks. It is a boolean +setting, taking only the values "true" and "false". If no value is +specified "true" is assumed. This setting also sets the +$x$ major tick marks on if the value is "true". + +\item[\csopt{DTLplot}{yminortics}] This setting governs whether +or not to display the $y$ minor tick marks. It is a boolean +setting, taking only the values "true" and "false". If no value is +specified "true" is assumed. This setting also sets the +$y$ major tick marks on if the value is "true". + +\item[\csopt{DTLplot}{xticdir}] This sets the $x$ tick direction, +and may only take the values "in" or "out". + +\item[\csopt{DTLplot}{yticdir}] This sets the $y$ tick direction, +and may only take the values "in" or "out". + +\item[\csopt{DTLplot}{ticdir}] This sets the $x$ and $y$ tick +direction, and may only take the values "in" or "out". + +\item[\csopt{DTLplot}{bounds}] The value must be in the form +\meta{min x}","\meta{min y}","\meta{max x}","\meta{max y}. This +sets the graph bounds to the given values. If omitted the +bounds are computed from the maximum and minimum values of the +data. For example +\begin{verbatim} +\DTLplot{data1,data2}{x=Height,y=Weight,bounds={0,0,10,20}} +\end{verbatim} +Note that the \csopt{DTLplot}{bounds} setting overrides +the \csopt{DTLplot}{minx}, \csopt{DTLplot}{maxx}, +\csopt{DTLplot}{miny} and \csopt{DTLplot}{maxy} settings. + +\item[\csopt{DTLplot}{minx}] The value is the minimum value +of the $x$ axis. + +\item[\csopt{DTLplot}{miny}] The value is the minimum value +of the $y$ axis. + +\item[\csopt{DTLplot}{maxx}] The value is the maximum value +of the $x$ axis. + +\item[\csopt{DTLplot}{maxy}] The value is the maximum value +of the $y$ axis. + +\item[\csopt{DTLplot}{xticpoints}] The value must be a comma +separated list of decimal numbers indicating where to put the +$x$ tick marks. If omitted, the $x$ tick marks are placed at +equal intervals along the $x$ axis such that each interval is +not less than the length given by \ics{DTLmintickgap}. +This setting overrides \csopt{DTLplot}{xticgap}. + +\item[\csopt{DTLplot}{xticgap}] This value specifies the +gap between the $x$ tick marks. + +\item[\csopt{DTLplot}{yticpoints}] The value must be a comma +separated list of decimal numbers indicating where to put the +$y$ tick marks. If omitted, the $y$ tick marks are placed at +equal intervals along the $y$ axis such that each interval is +not less than the length given by \ics{DTLmintickgap}. +This setting overrides \csopt{DTLplot}{yticgap}. + +\item[\csopt{DTLplot}{yticgap}] This value specifies the +gap between the $y$ tick marks. + +\item[\csopt{DTLplot}{grid}] This is a boolean value that +specifies whether or not to display the grid. If no value +is given, "true" is assumed. The minor grid lines are only +displayed if the minor tick marks are set. + +\item[\csopt{DTLplot}{xticlabels}] The value must be a comma +separated list of labels for each $x$ tick mark. If omitted, +the labels are the value of the $x$ tick position, rounded +\meta{n} digits after the decimal point, where \meta{n} is +given by the value of the counter \ctr{DTLplotroundXvar}. + +\item[\csopt{DTLplot}{yticlabels}] The value must be a comma +separated list of labels for each $y$ tick mark. If omitted, +the labels are the value of the $y$ tick position, rounded +\meta{n} digits after the decimal point, where \meta{n} is +given by the value of the counter \ctr{DTLplotroundYvar}. + +\item[\csopt{DTLplot}{xlabel}] The value is the label for +the $x$ axis. If omitted, the axis has no label. + +\item[\csopt{DTLplot}{ylabel}] The value is the label for +the $y$ axis. If omitted, the axis has no label. + +\item[\csopt{DTLplot}{legend}] This setting governs whether +or not to display the legend, and where it should be displayed. +It may take one of the following values "none" (don't display +the legend), "north", "northeast", "east", "southeast", "south", +"southwest", "west" or "northwest". If the value is omitted, +"northeast" is assumed. + +\item[\csopt{DTLplot}{legendlabels}] The value must be a comma +separated list of labels for the legend. If omitted, the database +names are used. + +\end{description} + +\begin{example}{A Basic Graph}{ex:basicplot} +Suppose you have a file called "groupa.csv" that contains the +following: +\DTLnewdb{groupa}\relax +\DTLnewrow{groupa}\relax +\DTLnewdbentry{groupa}{Height}{1.55}\relax +\DTLnewdbentry{groupa}{Weight}{45.4}\relax +\DTLnewrow{groupa}\relax +\DTLnewdbentry{groupa}{Height}{1.54}\relax +\DTLnewdbentry{groupa}{Weight}{48.0}\relax +\DTLnewrow{groupa}\relax +\DTLnewdbentry{groupa}{Height}{1.56}\relax +\DTLnewdbentry{groupa}{Weight}{58.0}\relax +\DTLnewrow{groupa}\relax +\DTLnewdbentry{groupa}{Height}{1.56}\relax +\DTLnewdbentry{groupa}{Weight}{50.2}\relax +\DTLnewrow{groupa}\relax +\DTLnewdbentry{groupa}{Height}{1.57}\relax +\DTLnewdbentry{groupa}{Weight}{46.0}\relax +\DTLnewrow{groupa}\relax +\DTLnewdbentry{groupa}{Height}{1.58}\relax +\DTLnewdbentry{groupa}{Weight}{48.3}\relax +\DTLnewrow{groupa}\relax +\DTLnewdbentry{groupa}{Height}{1.59}\relax +\DTLnewdbentry{groupa}{Weight}{56.5}\relax +\DTLnewrow{groupa}\relax +\DTLnewdbentry{groupa}{Height}{1.59}\relax +\DTLnewdbentry{groupa}{Weight}{58.1}\relax +\DTLnewrow{groupa}\relax +\DTLnewdbentry{groupa}{Height}{1.60}\relax +\DTLnewdbentry{groupa}{Weight}{60.9}\relax +\DTLnewrow{groupa}\relax +\DTLnewdbentry{groupa}{Height}{1.62}\relax +\DTLnewdbentry{groupa}{Weight}{56.3}\relax +\begin{ttfamily}\obeylines\setlength{\parindent}{0pt} +Height,Weight +\DTLforeach{groupa}{\x=Height,\y=Weight}{\x,\y +}\end{ttfamily}\par\noindent +First load this into a database called "groupa": +\begin{verbatim} +\DTLloaddb{groupa}{groupa.csv} +\end{verbatim} +The data can now be converted into a scatter plot as follows: +\begin{verbatim} +\begin{figure}[htbp] +\centering +\DTLplot{groupa}{x=Height,y=Weight} +\caption{A scatter plot} +\end{figure} +\end{verbatim} +This produces \autoref{fig:basicplot}. + +\begin{figure}[htbp] +\centering +\DTLplot{groupa}{x=Height,y=Weight} +\caption{A scatter plot} +\label{fig:basicplot} +\end{figure} + +Alternatively, you can use the \csopt{DTLplot}{style} setting +to change it into a line plot: +\begin{verbatim} +\begin{figure}[htbp] +\centering +\DTLplot{groupa}{x=Height,y=Weight,style=lines} +\caption{A line plot} +\end{figure} +\end{verbatim} +This produces \autoref{fig:basiclineplot}. + +\begin{figure}[htbp] +\centering +\DTLplot{groupa}{x=Height,y=Weight,style=lines} +\caption{A line plot} +\label{fig:basiclineplot} +\end{figure} +\end{example} + +\begin{example}{Plotting Multiple Data Sets}{ex:2db} +In this example, I shall use the database called "groupa" defined +in \autoref{ex:basicplot}, and another database called "groupb" +which is loaded from the file "groupb.csv" which contains the +following: +\DTLnewdb{groupb} +\DTLnewrow{groupb}\relax +\DTLnewdbentry{groupb}{Height}{1.54}\relax +\DTLnewdbentry{groupb}{Weight}{48.4}\relax +\DTLnewrow{groupb}\relax +\DTLnewdbentry{groupb}{Height}{1.54}\relax +\DTLnewdbentry{groupb}{Weight}{42.0}\relax +\DTLnewrow{groupb}\relax +\DTLnewdbentry{groupb}{Height}{1.55}\relax +\DTLnewdbentry{groupb}{Weight}{64.0}\relax +\DTLnewrow{groupb}\relax +\DTLnewdbentry{groupb}{Height}{1.56}\relax +\DTLnewdbentry{groupb}{Weight}{58.2}\relax +\DTLnewrow{groupb}\relax +\DTLnewdbentry{groupb}{Height}{1.56}\relax +\DTLnewdbentry{groupb}{Weight}{49.0}\relax +\DTLnewrow{groupb}\relax +\DTLnewdbentry{groupb}{Height}{1.57}\relax +\DTLnewdbentry{groupb}{Weight}{40.3}\relax +\DTLnewrow{groupb}\relax +\DTLnewdbentry{groupb}{Height}{1.58}\relax +\DTLnewdbentry{groupb}{Weight}{51.5}\relax +\DTLnewrow{groupb}\relax +\DTLnewdbentry{groupb}{Height}{1.58}\relax +\DTLnewdbentry{groupb}{Weight}{63.1}\relax +\DTLnewrow{groupb}\relax +\DTLnewdbentry{groupb}{Height}{1.59}\relax +\DTLnewdbentry{groupb}{Weight}{74.9}\relax +\DTLnewrow{groupb}\relax +\DTLnewdbentry{groupb}{Height}{1.59}\relax +\DTLnewdbentry{groupb}{Weight}{59.3}\relax +\begin{ttfamily}\obeylines\setlength{\parindent}{0pt} +Height,Weight +\DTLforeach{groupb}{\x=Height,\y=Weight}{\x,\y +}\end{ttfamily}\par\noindent +First load this into a database called "groupb": +\begin{verbatim} +\DTLloaddb{groupb}{groupb.csv} +\end{verbatim} +I can now plot both groups in the same graph, but I want a smaller +graph than \autoref{fig:basicplot} and \autoref{fig:basiclineplot}, +so I am going to set the plot width and height to 3in: +\begin{verbatim} +\begin{figure}[htbp] +\centering +\DTLplot{groupa,groupb}{x=Height,y=Weight,width=3in,height=3in} +\caption{A scatter plot} +\end{figure} +\end{verbatim} +This produces \autoref{fig:2db}. + +\begin{figure}[htbp] +\centering +\DTLplot{groupa,groupb}{x=Height,y=Weight,width=3in,height=3in} +\caption[A scatter plot (multiple datasets)]{A scatter plot} +\label{fig:2db} +\end{figure} + +Now let's add a legend using the \csopt{DTLplot}{legend} setting, +with the legend labels "Group A" and "Group B", +and set the $x$ tick intervals using \csopt{DTLplot}{xticpoints} +setting. I am also going to set the $x$ axis label to +"Height (m)" and the $y$ axis label to "Weight (kg)", and place +a box around the plot. +\begin{verbatim} +\begin{figure}[htbp] +\centering +\DTLplot{groupa,groupb}{x=Height,y=Weight, +width=3in,height=3in,legend,legendlabels={Group A,Group B}, +xlabel={Height (m)},ylabel={Weight (kg)},box, +xticpoints={1.54,1.55,1.56,1.57,1.58,1.59,1.60,1.61,1.62}} +\caption{A scatter plot} +\end{figure} +\end{verbatim} +This produces \autoref{fig:legend}. + +\begin{figure}[htbp] +\centering +\DTLplot{groupa,groupb}{x=Height,y=Weight,legend, +width=3in,height=3in,legendlabels={Group A,Group B}, +xlabel={Height (m)},ylabel={Weight (kg)},box, +xticpoints={1.54,1.55,1.56,1.57,1.58,1.59,1.60,1.61,1.62}} +\caption[A scatter plot (with a legend)]{A scatter plot} +\label{fig:legend} +\end{figure} +\end{example} + +\section{Adding Information to the Plot} + +The \sty{datatool} package provides two hooks used at the beginning +and end of the \env{tikzpicture} environment: +\begin{definition}[\DescribeMacro{\DTLplotatbegintikz}]% +\cs{DTLplotatbegintikz} +\end{definition}\noindent +and +\begin{definition}[\DescribeMacro{\DTLplotatendtikz}]% +\cs{DTLplotatendtikz} +\end{definition} +They are both defined to do nothing by default, but can be redefined +to add commands to the image. The unit vectors are set prior to +using these hooks, so you can use the same co-ordinates as those +in the data sets. + +\begin{definition}[\DescribeMacro{\DTLaddtoplotlegend}]% +\cs{DTLaddtoplotlegend}\marg{marker}\marg{line style}\marg{text} +\end{definition} +This adds a new row to the plot legend where \meta{marker} is +code to produce the marker, \meta{line style} is code to set +the line style and \meta{text} is a textual label. You can +use \cs{relax} to suppress the marker or line. For example: +\begin{verbatim} +\DTLaddtoplotlegend{\pgfuseplotmark{x}}{\relax}{Some Data} +\end{verbatim} +Note that the legend is plotted before \cs{DTLplotatendtikz}, +so if you want to add information to the legend you will need +to do the in \cs{DTLplotatstarttikz}. + +\begin{example}{Adding Information to a Plot}{ex:addtoplot} +Returning to the plots created in \autoref{ex:2db}, suppose +I now want to annotate the plot, say I want to draw your notice +to a particular point, say the point (1.58,48.3), then I can +redefine \cs{DTLplotatendtikz} to draw an annotated arrow to +that point: +\begin{verbatim} +\renewcommand*{\DTLplotatendtikz}{% +\draw[<-,line width=1pt] (1.58,48.3) -- (1.6,43) + node[below]{interesting point}; +} +\end{verbatim} +So \autoref{fig:legend} now looks like \autoref{fig:annote}. +(Obviously, \cs{DTLplotatendtikz} needs to be redefined before +using \cs{DTLplot}.) + +\begin{figure}[htbp] +\renewcommand*{\DTLplotatendtikz}{% +\draw[<-,line width=1pt] (1.58,48.3) -- (1.6,43) + node[below]{interesting point}; +} +\centering +\DTLplot{groupa,groupb}{x=Height,y=Weight,legend, +width=3in,height=3in,legendlabels={Group A,Group B},box, +xlabel={Height (m)},ylabel={Weight (kg)}, +xticpoints={1.54,1.55,1.56,1.57,1.58,1.59,1.60,1.61,1.62}} +\caption[A scatter plot (using the end plot hook to annotate the +plot)]{A scatter plot} + +\label{fig:annote} +\end{figure} +\end{example} + +\section{Global Plot Settings} + +\subsection{Lengths} +This section describes the lengths that govern the appearance of +the plot created using \ics{DTLplot}. These lengths can be +changed using \cs{setlength}. + +\begin{definition}[\DescribeMacro{\DTLplotwidth}]% +\cs{DTLplotwidth} +\end{definition} +This length governs the length of the $x$ axis. Note that the plot +width does not include any outer tick marks or labels. The default +value is 4in. + +\begin{definition}[\DescribeMacro{\DTLplotheight}]% +\cs{DTLplotheight} +\end{definition} +This length governs the length of the $y$ axis. Note that the plot +height does not include any outer tick marks or labels. The default +value is 4in + +\begin{definition}[\DescribeMacro{\DTLticklength}]% +\cs{DTLticklength} +\end{definition} +This governs the length of the tick marks. The default value is +5pt. + +\begin{definition}[\DescribeMacro{\DTLminorticklength}]% +\cs{DTLminorticklength} +\end{definition} +This governs the length of the minor tick marks. The default value is +2pt. + +\begin{definition}[\DescribeMacro{\DTLticklabeloffset}]% +\cs{DTLticklabeloffset} +\end{definition} +This governs the distance from the axis to the tick labels. The +default value is 8pt. + +\begin{definition}[\DescribeMacro{\DTLmintickgap}]% +\cs{DTLmintickgap} +\end{definition} +This is the minimum distance allowed between tick marks. If the +plot width or height is less than this distance there will only +be tick marks at either end of the axis. The default value is +20pt. + +\begin{definition}[\DescribeMacro{\DTLlegendxoffset}]% +\cs{DTLlegendxoffset} +\end{definition} +This is the horizontal distance from the border of the plot to the +outer border of the legend. The default value is 10pt. + +\begin{definition}[\DescribeMacro{\DTLlegendyoffset}]% +\cs{DTLlegendyoffset} +\end{definition} +This is the vertical distance from the border of the plot to the +outer border of the legend. The default value is 10pt. + +\subsection{Counters} +These counters govern the appearance of plots +created using \ics{DTLplot}. The value of the counters can be +changed using \cs{setcounter}. + +\begin{definition}[\DescribeCounter{DTLplotroundXvar}] +\ctrfmt{DTLplotroundXvar} +\end{definition} +Unless you specify your own tick labels, the $x$ tick labels will +be given by the tick points rounded to \meta{n} digits after the +decimal point, where \meta{n} is the value of the counter +\ctrfmt{DTLplotroundXvar}. + +\begin{definition}[\DescribeCounter{DTLplotroundYvar}] +\ctrfmt{DTLplotroundYvar} +\end{definition} +Unless you specify your own tick labels, the $y$ tick labels will +be given by the tick points rounded to \meta{n} digits after the +decimal point, where \meta{n} is the value of the counter +\ctrfmt{DTLplotroundYvar}. + +\subsection{Macros} +These macros govern the appearance of plots created using +\ics{DTLplot}. They can be changed using \cs{renewcommand}. + +\begin{definition}[\DescribeMacro{\DTLplotmarks}]% +\cs{DTLplotmarks} +\end{definition} +This must be a comma separated list of \sty{pgf} code to create the +plot marks. \ics{DTLplot} cycles through this list for each +database listed. The \sty{pgf} package provides convenient commands +for generating plots using \cs{pgfuseplotmark}. See the \sty{pgf} +manual for more details. + +\begin{definition}[\DescribeMacro{\DTLplotmarkcolors}]% +\cs{DTLplotmarkcolors} +\end{definition} +This must be a comma separated list of defined colours to apply to the +plot marks. \ics{DTLplot} cycles through this list for each database +listed. If this macro is set to empty, the current colour will +be used instead. + +\begin{definition}[\DescribeMacro{\DTLplotlines}]% +\cs{DTLplotlines} +\end{definition} +This must be a comma separated list of \sty{pgf} code to set the +style of the plot lines. \ics{DTLplot} cycles through this list for +each database listed. Dash patterns can be set using \cs{pgfsetdash}, +see the \sty{pgf} manual for more details. If \cs{DTLplotlines} is +set to empty the current line style will be used instead. + +\begin{definition}[\DescribeMacro{\DTLplotlinecolors}]% +\cs{DTLplotlinecolors} +\end{definition} +This must be a comma separated list of defined colours to apply to the +plot lines. \cs{DTLplot} cycles through this list for each database +listed. If this macro is set to empty, the current colour will +be used instead. The default is the same as \cs{DTLplotmarkcolors}. + +\begin{definition}[\DescribeMacro{\DTLXAxisStyle}]% +\cs{DTLXAxisStyle} +\end{definition} +This governs the style of the $x$ axis. It is passed as the optional +argument to the TikZ \cs{draw} command. By default it is just "-" +which is a solid line style with no start or end arrows. The $x$ +axis line starts from the bottom left corner of the plot and extends +to the bottom right corner of the plot. So if you want the $x$ axis +to have an arrow head at the right end, you can do: +\begin{verbatim} +\renewcommand*{\DTLXAxisStyle}{->} +\end{verbatim} + +\begin{definition}[\DescribeMacro{\DTLYAxisStyle}]% +\cs{DTLYAxisStyle} +\end{definition} +This governs the style of the $y$ axis. It is analogous to +\cs{DTLXAxisStyle} described above. + +\begin{definition}[\DescribeMacro{\DTLmajorgridstyle}]% +\cs{DTLmajorgridstyle} +\end{definition} +This specifies the format of the major grid lines. +It may be set to any TikZ setting that you can pass to the +optional argument of \cs{draw}. The default value is +"color=gray,-" which indicates a grey solid line. + +\begin{definition}[\DescribeMacro{\DTLminorgridstyle}]% +\cs{DTLminorgridstyle} +\end{definition} +This specifies the format of the minor grid lines. +It may be set to any TikZ setting that you can pass to the +optional argument of \cs{draw}. The default value is +"color=gray,loosely dotted" which indicates a grey dotted line. + +\begin{definition}[\DescribeMacro{\DTLformatlegend}]% +\cs{DTLformatlegend}\marg{legend} +\end{definition} +This formats the entire legend, which is passed as the argument. +The default is to set the legend with +a white background, a black frame. + +\section{Adding to a Plot Stream} + +\begin{definition}[\DescribeMacro{\DTLplotstream}]% +\cs{DTLplotstream}\oarg{condition}\marg{db name}\marg{x key}\marg{y key} +\end{definition} +This adds points to a stream from the database called \meta{db name} +where the $x$ co-ordinates are given by the key \meta{x key} +and the $y$ co-ordinates are given by the key \meta{y key}. +(\ics{DTLconverttodecimal} is used to convert locale dependent +values to a standard decimal that is recognised by the +\sty{pgf} package.) +The optional argument \meta{condition} is the same as that +for \ics{DTLforeach}. + +\begin{example}{Adding to a Plot Stream}{ex:plotstream} +Suppose you have a CSV file called "data.csv" containing the +following: +\begin{verbatim} +x,y +0,0 +1,1 +2,0.5 +1.5,0.3 +\end{verbatim} +\DTLnewdb{data}\relax +\DTLnewrow{data}\relax +\DTLnewdbentry{data}{x}{0}\relax +\DTLnewdbentry{data}{y}{0}\relax +\DTLnewrow{data}\relax +\DTLnewdbentry{data}{x}{1}\relax +\DTLnewdbentry{data}{y}{1}\relax +\DTLnewrow{data}\relax +\DTLnewdbentry{data}{x}{2}\relax +\DTLnewdbentry{data}{y}{0.5}\relax +\DTLnewrow{data}\relax +\DTLnewdbentry{data}{x}{1.5}\relax +\DTLnewdbentry{data}{y}{0.3}\relax +First load the file into a database called "data": +\begin{verbatim} +\DTLloaddb{data}{data.csv} +\end{verbatim} +Now create a figure containing this data: +\begin{verbatim} +\begin{figure}[tbhp] +\centering +\begin{tikzpicture} +\pgfplothandlermark{\pgfuseplotmark{o}} +\pgfplotstreamstart +\DTLplotstream{data}{x}{y}% +\pgfplotstreamend +\pgfusepath{stroke} +\end{tikzpicture} +\caption{Adding to a plot stream} +\end{figure} +\end{verbatim} +This produces \autoref{fig:plotstream}. + +\begin{figure}[tbhp] +\centering +\begin{tikzpicture} +\pgfplothandlermark{\pgfuseplotmark{o}} +\pgfplotstreamstart +\DTLplotstream{data}{x}{y}% +\pgfplotstreamend +\pgfusepath{stroke} +\end{tikzpicture} +\caption{Adding to a plot stream} +\label{fig:plotstream} +\end{figure} +\end{example} + +\begin{example}{Plotting Multiple Keys in the Same +Database}{ex:multikey} +Suppose I have conducted two time to growth experiments. For each +experiment, I have recorded the log count at set times, and I have +recorded this information in the same data file called, say, +"growth.csv" which contains the following: +\begin{verbatim} +Time,Experiment 1,Experiment 2 +0,3.73,3.6 +23,3.67,3.7 +60,4.9,3.8 +\end{verbatim} +\DTLnewdb{growth}\DTLnewrow{growth}\relax +\DTLnewdbentry{growth}{Time}{0}\relax +\DTLnewdbentry{growth}{Experiment 1}{3.73}\relax +\DTLnewdbentry{growth}{Experiment 2}{3.6}\relax +\DTLnewrow{growth}\relax +\DTLnewdbentry{growth}{Time}{23}\relax +\DTLnewdbentry{growth}{Experiment 1}{3.67}\relax +\DTLnewdbentry{growth}{Experiment 2}{3.7}\relax +\DTLnewrow{growth}\relax +\DTLnewdbentry{growth}{Time}{60}\relax +\DTLnewdbentry{growth}{Experiment 1}{4.9}\relax +\DTLnewdbentry{growth}{Experiment 2}{3.8}\relax +I can load the data into a database using: +\begin{verbatim} +\DTLloaddb{growth}{growth.csv} +\end{verbatim} +However, I'd like to plot both results on the same graph. Since they +are contained in the same database, I can't use the method I used +in \autoref{ex:2db}. Instead I can use a combination of +\ics{DTLplot} and \ics{DTLplotstream}: +\begin{verbatim} +\begin{figure}[tbhp] +\centering + % computer bounds +\DTLminforkeys{growth}{Time}{\minX} +\DTLminforkeys{growth}{Experiment 1,Experiment 2}{\minY} +\DTLmaxforkeys{growth}{Time}{\maxX} +\DTLmaxforkeys{growth}{Experiment 1,Experiment 2}{\maxY} + % round x tick labels +\setcounter{DTLplotroundXvar}{0} + % redefine \DTLplotatbegintikz to plot the data for Experiment 1 +\renewcommand*{\DTLplotatbegintikz}{% + % set plot mark +\pgfplothandlermark{\color{green}\pgfuseplotmark{x}} + % start plot stream +\pgfplotstreamstart + % add data from Experiment 1 to plot stream +\DTLplotstream{growth}{Time}{Experiment 1}% + % end plot stream +\pgfplotstreamend + % stroke path +\pgfusepath{stroke} + % add information to legend (no line is require so use \relax) +\DTLaddtoplotlegend{\color{green}% +\pgfuseplotmark{x}}{\relax}{Experiment 1} +} + % now plot the data for Experiment 2 +\DTLplot{growth}{x=Time,y=Experiment 2,legend, +width=3in,height=3in,bounds={\minX,\minY,\maxX,\maxY}, +xlabel={Time},ylabel={Log Count}, +legendlabels={Experiment 2}} +\caption{Time to growth data} +\end{figure} +\end{verbatim} +This produces \autoref{fig:multikey}. +Notes: +\begin{itemize} +\item I redefined \ics{DTLplotatbegintikz} in order to add +the new plot to the legend, since \ics{DTLplotatendtikz} is +used after the legend is plotted. The $x$ and $y$ unit vectors +are set before \ics{DTLplotatbegintikz} so I don't need to +worry about the co-ordinates. +\item I set the counter \ctr{DTLplotroundXvar} to zero +otherwise the $x$ axis would have looked too cluttered. +\item I have used \ics{DTLminforkeys} and \ics{DTLmaxforkeys} to +determine the bounds since \ics{DTLplot} won't take the data +for Experiment 1 into account when computing the bounds. +\end{itemize} + +\begin{figure}[htbp] +\DTLminforkeys{growth}{Time}{\minX} +\DTLminforkeys{growth}{Experiment 1,Experiment 2}{\minY} +\DTLmaxforkeys{growth}{Time}{\maxX} +\DTLmaxforkeys{growth}{Experiment 1,Experiment 2}{\maxY} +\setcounter{DTLplotroundXvar}{0} +\renewcommand*{\DTLplotatbegintikz}{% +\pgfplothandlermark{\color{green}\pgfuseplotmark{x}} +\pgfplotstreamstart +\DTLplotstream{growth}{Time}{Experiment 1}% +\pgfplotstreamend +\pgfusepath{stroke} +\DTLaddtoplotlegend{\color{green}\pgfuseplotmark{x}}{\relax}{Experiment 1} +} +\centering +\DTLplot{growth}{x=Time,y=Experiment 2,legend, +width=3in,height=3in,bounds={\minX,\minY,\maxX,\maxY}, +xlabel={Time},ylabel={Log Count}, +legendlabels={Experiment 2}} +\caption[Time to growth data (plotting from the same database using +different keys)]{Time to growth data} +\label{fig:multikey} +\end{figure} +\end{example} + +\chapter{Bar Charts (\texorpdfstring{\sty{databar}}{databar} +package)} +\label{sec:databar} + +The \sty{databar} package provides commands for creating bar charts. +It is not loaded by the \sty{datatool} package, so if you want to +use it you will need to load it explicitly using +"\usepackage{databar}". You must also have the \sty{pgf} package +installed. + +Bar charts can either be vertical or horizontal, the default is +vertical. In this section the $x$ axis refers to the horizontal +axis when plotting a vertical bar chart and to the vertical axis +when plotting a horizontal bar chart. The $x$ axis units are in +increments of one bar. The $y$ axis refers to the vertical axis +when plotting a vertical bar chart and to the horizontal axis when +plotting a horizontal bar chart. The $y$ axis uses the same +co-ordinates as the data. The bars may have an upper and lower +label. In a vertical bar chart, the lower label is placed below +the $x$ axis and the upper label is placed above the top of the bar. +In a horizontal bar chart, the lower label is placed to the left of +the $x$ axis and the upper label is placed to the right of the +end of the bar. (This is actually a misnomer as it is possible +for the ``upper'' label to be below the ``lower'' label if a +bar has a negative value, however the bars are considered to +be anchored on the $x$ axis, and the other end of the bar is +considered to be the ``upper'' end, regardless of its +direction.) + +The \sty{databar} package options are as follows: +\begin{description} +\item[{\pkgopt[databar]{color}}] Created coloured bar charts +(default). + +\item[{\pkgopt[databar]{gray}}] Created grey scale bar charts. + +\item[{\pkgopt[databar]{vertical}}] Created vertical bar charts +(default). + +\item[{\pkgopt[databar]{horizontal}}] Created horizontal bar charts. +\end{description} + + + +\begin{definition}[\DescribeMacro{\DTLbarchart}]% +\cs{DTLbarchart}\oarg{condition}\marg{db name}\marg{settings}\marg{values} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLmultibarchart}]% +\cs{DTLmultibarchart}\oarg{condition}\marg{db name}\marg{settings}\marg{values} +\end{definition} +These commands both create a bar chart from the information in +the database \meta{db name}, where \meta{condition} is the same +as the optional argument for \ics{DTLforeach} described in +\autoref{sec:dbforeach}, and \meta{values} is the same as the +penultimate argument of \ics{DTLforeach}. The \meta{settings} +argument is a \meta{setting}"="\meta{value} list of settings. The +first command, \cs{DLTbarchart}, will draw a bar chart for a +given column of data in the database, whereas the second command, +\cs{DTLmultibarchart}, will draw a bar chart that is divided into +groups of bars where each bar within a group represents data from +several columns of a given row in the database. + +The \csopt{DTLbarchart}{variable} setting is +required for \cs{DTLbarchart} and the +\csopt{DTLmultibarchart}{variables}, the other settings are +optional (though some may only be used for one of +\cs{DTLbarchart} and \cs{DLTmultibarchart}), and are as follows: + +\begin{description} +\item[\csopt{DTLbarchart}{variable}] +This specifies the control sequence to use that +contains the value used to construct the bar chart. The control +sequence must be one of the control sequences to appear in +the assignment list \meta{values}. This setting is required +for \cs{DTLbarchart}, and is unavailable for \cs{DTLmultibarchart}. + +\item[\csopt{DTLmultibarchart}{variables}] +This specifies a list of control sequences to use which +contain the values used to construct the bar chart. Each control +sequence must be one of the control sequences to appear in +the assignment list \meta{values}. This setting is required +for \cs{DTLmultibarchart}, and is unavailable for +\cs{DTLbarchart}. + +\item[\csopt{DTLbarchart,DTLmultibarchart}{max}] +This specifies the maximum value on the $y$ axis. (This should +be a standard decimal value.) + +\item[\csopt{DTLbarchart,DTLmultibarchart}{length}] +This specifies the overall length of the $y$ axis, and must +be a dimension. + +\item[\csopt{DTLbarchart,DTLmultibarchart}{maxdepth}] +This must be a zero or negative number. It specifies the maximum +depth of the $y$ axis. (This should be a standard decimal value.) + +\item[\csopt{DTLbarchart,DTLmultibarchart}{axes}] +This setting specifies which axes to display. This may take one +of the following values: "both", "x", "y" or "none". + +\item[\csopt{DTLbarchart,DTLmultibarchart}{barlabel}] +This setting specifies the lower bar label. When used with +\cs{DTLmultibarchart} it indicates the group label. + +\item[\csopt{DTLmultibarchart}{multibarlabels}] +This setting should contain a comma separated list of labels +for each bar within a group for \cs{DTLmultibarchart}. This +setting is not available for \cs{DTLbarchart}. + +\item[\csopt{DTLbarchart}{upperbarlabel}] +This setting specifies the upper bar label. This setting +is not available for \cs{DTLmultibarchart}. + +\item[\csopt{DTLmultibarchart}{uppermultibarlabels}] +This setting must be a comma separated list of upper bar +labels for each bar within a group. This setting is not +available for \cs{DTLbarchart}. + +\item[\csopt{DTLbarchart,DTLmultibarchart}{yticpoints}] +This must be a comma separated list of tick locations for the +$y$ axis. (These should be standard decimal values.) +This setting overrides \csopt{DTLbarchart}{yticgap}. + +\item[\csopt{DTLbarchart,DTLmultibarchart}{yticgap}] +This specifies the gap between the $y$ tick marks. (This should +be a standard decimal value.) + +\item[\csopt{DTLbarchart,DTLmultibarchart}{yticlabels}] +This must be a comma separated list of tick labels for the +$y$ axis. + +\item[\csopt{DTLbarchart,DTLmultibarchart}{ylabel}] +This specifies the label for the $y$ axis. + +\item[\csopt{DTLmultibarchart}{groupgap}] This specifies +the gap between groups when using \cs{DTLmultibarchart}. +This value is given as a multiple of the bar width. The +default value is 1, which indicates a gap of one bar width. +This setting is not available for \cs{DTLbarchart}. + +\item[\csopt{DTLbarchart,DTLmultibarchart}{verticalbars}] +This is a boolean setting, so it can only take the values +"true" (do a vertical bar chart) or "false" (do a horizontal +bar chart). If the value is omitted, "true" is assumed. +\end{description} + +\begin{example}{A Basic Bar Chart}{ex:barchart} +Recall \autoref{ex:piechart} defined a database called "fruit". +This example will be using that database to plot a bar chart. +The following plots a basic vertical bar chart: +\begin{verbatim} +\begin{figure}[htbp] +\centering +\DTLbarchart{variable=\theQuantity}{fruit}{\theQuantity=Quantity} +\caption{A basic bar chart} +\end{figure} +\end{verbatim} +This produces \autoref{fig:barchart}. + +\begin{figure}[htbp] +\centering +\DTLbarchart{variable=\theQuantity}{fruit}{\theQuantity=Quantity} +\caption{A basic bar chart} +\label{fig:barchart} +\end{figure} +\end{example} + +\section{Changing the Appearance of a Bar Chart} + + +\begin{definition}[\DescribeMacro{\DTLbarchartlength}]% +\cs{DTLbarchartlength} +\end{definition} +This specifies the total length of the $y$ axis. You must use +\cs{setlength} to change this value. The default value is 3in. + +\begin{definition}[\DescribeMacro{\DTLbarwidth}]% +\cs{DTLbarwidth} +\end{definition} +This specifies the width of each bar. You must use \cs{setlength} +to change this value. The default value is 1cm. + +\begin{definition}[\DescribeMacro{\DTLbarlabeloffset}]% +\cs{DTLbarlabeloffset} +\end{definition} +This specifies the distance from the $x$ axis to the lower bar label. +You must use \cs{setlength} to change this value. The default value +is 10pt. + +\begin{definition}[\DescribeCounter{DTLbarroundvar}] +\ctrfmt{DTLbarroundvar} +\end{definition} +The $y$ tick labels are rounded to \meta{n} digits after the +decimal point, where \meta{n} is given by the value of the +counter \ctrfmt{DTLbarroundvar}. You must use \cs{setcounter} +to change this value. + +\begin{definition}[\DescribeMacro{\DTLsetbarcolor}]% +\cs{DTLsetbarcolor}\marg{n}\marg{color} +\end{definition} +This sets the \meta{n}th bar colour to \meta{color}. +Only the first eight bars have a colour defined by default. If you +need more than eight bars, you will need to define more bar colours. +It is recommended that you set the colour of each bar to +correspond with whatever the bar represents. + +\begin{definition}[\DescribeMacro{\DTLdobarcolor}]% +\cs{DTLdobarcolor}\marg{n} +\end{definition} +This sets the current colour to the colour of the \meta{n}th bar. + +\begin{definition}[\DescribeMacro{\DTLbaroutlinecolor}]% +\cs{DTLbaroutlinecolor} +\end{definition} +This macro contains the colour of the bar outlines. This defaults +to "black". + +\begin{definition}[\DescribeMacro{\DTLbaroutlinewidth}]% +\cs{DTLbaroutlinewidth} +\end{definition} +This length specifies the line width for the bar outlines. If it +is 0pt, the outline is not drawn. The default value is 0pt. + + +\begin{definition}[\DescribeMacro{\DTLbaratbegintikz}]% +\cs{DTLbaratbegintikz} +\end{definition} +This specifies any additional commands to add to the start of +the plot. It defaults to nothing, and is called after the +unit vectors are set. + +\begin{definition}[\DescribeMacro{\DTLbaratendtikz}]% +\cs{DTLbaratendtikz} +\end{definition} +This specifies any additional commands to add to the end of +the plot. It defaults to nothing. + +\begin{definition}[\DescribeMacro{\DTLeverybarhook}]% +\cs{DTLeverybarhook} +\end{definition} +The specifies code to apply at every bar. Within the definition +of \cs{DTLeverybarhook} you can use the commands +\DescribeMacro{\DTLstartpt}\cs{DTLstartpt} (the start +of the bar), \DescribeMacro{\DTLmidpt}\cs{DTLmidpt} +(the mid point of the bar) and +\DescribeMacro{\DTLendpt}\cs{DTLendpt} (the end of the bar). For +example (using the earlier "fruit" database): +\begin{verbatim} +\renewcommand*{\DTLeverybarhook}{% +\pgftext[at=\DTLmidpt]{\insertName\space(\insertValue)}% +} +\DTLbarchart{variable=\insertValue,axes=both, +ylabel=Quantity,max=50,verticalbars=false +}% +{fruit}{\insertValue=Value,\insertName=Name} +\end{verbatim} +This puts the name followed by the quantity in brackets in the +middle of the bar. + +\begin{definition}[\DescribeMacro{\ifDTLverticalbars}]% +\cs{ifDTLverticalbars} +\end{definition} +This conditional governs whether the chart uses vertical or +horizontal bars. + +\begin{definition}[\DescribeMacro{\DTLbarXlabelalign}]% +\cs{DTLbarXlabelalign} +\end{definition} +This specifies the text alignment of the lower bar labels. This +defaults to "left,rotate=-90" if you use the \pkgopt[databar]{vertical} +package option or the \csopt{DTLbarchart}{verticalbars} setting, +and defaults to "right" if you use the \pkgopt[databar]{horizontal} +package option or the \csopt{DTLbarchart}{verticalbars}"=false" +setting. + +\begin{definition}[\DescribeMacro{\DTLbarYticklabelalign}]% +\cs{DTLbarYlabelalign} +\end{definition} +This specifies the text alignment of the $y$ axis labels. This +defaults to "right" for vertical bar charts and "center" for +horizontal bar charts. + +\begin{definition}[\DescribeMacro{\DTLbardisplayYticklabel}]% +\cs{DTLbardisplayYticklabel}\marg{text} +\end{definition} +This specifies how to display the $y$ tick label. The argument +is the tick label. + +\begin{definition}[\DescribeMacro{\DTLdisplaylowerbarlabel}]% +\cs{DTLdisplaylowerbarlabel}\marg{text} +\end{definition} +This specifies how to display the lower bar label for +\cs{DTLbarchart} and the lower bar group label for +\cs{DTLmultibarchart}. The argument is the label. + +\begin{definition}[\DescribeMacro{\DTLdisplaylowermultibarlabel}]% +\cs{DTLdisplaylowermultibarlabel}\marg{text} +\end{definition} +This specifies how to display the lower bar label for +\cs{DTLmultibarchart}. The argument is the label. This +command is ignored by \cs{DTLbarchart}. + +\begin{definition}[\DescribeMacro{\DTLdisplayupperbarlabel}]% +\cs{DTLdisplayupperbarlabel}\marg{text} +\end{definition} +This specifies how to display the upper bar label for +\cs{DTLbarchart} and the upper bar group label for +\cs{DTLmultibarchart}. The argument is the label. + +\begin{definition}[\DescribeMacro{\DTLdisplayuppermultibarlabel}]% +\cs{DTLdisplayuppermultibarlabel}\marg{text} +\end{definition} +This specifies how to display the upper bar label for +\cs{DTLmultibarchart}. The argument is the label. This +command is ignored by \cs{DTLbarchart}. + +\begin{example}{A Labelled Bar Chart}{ex:annotebarchart} +This example extends \autoref{ex:barchart} so that the chart is +a bit more informative (which is after all the whole point of +a chart). This chart now has a label below each bar, as well +as a label above the bar. The lower label uses the value of the +"Name" key, and the upper label uses the quantity. I have also +set the outline width so each bar has a border. +\begin{verbatim} +\begin{figure}[htbp] +\setlength{\DTLbaroutlinewidth}{1pt} +\centering +\DTLbarchart{variable=\theQuantity,barlabel=\theName,% +upperbarlabel=\theQuantity}{fruit}{% +\theQuantity=Quantity,\theName=Name} +\caption{A bar chart} +\end{figure} +\end{verbatim} +This produces \autoref{fig:annotebarchart}. + +\begin{figure}[htbp] +\centering +\setlength{\DTLbaroutlinewidth}{1pt} +\DTLbarchart{variable=\theQuantity,barlabel=\theName, +upperbarlabel=\theQuantity}{fruit}{\theQuantity=Quantity,\theName=Name} +\caption[A bar chart (labelled)]{A bar chart} +\label{fig:annotebarchart} +\end{figure} +\end{example} + +\begin{example}{Profit/Loss Bar Chart}{ex:profit} +Suppose I have a file called "profits.csv" that looks like: +\DTLnewdb{profits} +\DTLnewrow{profits} +\DTLnewdbentry{profits}{Year}{2000}\relax +\DTLnewdbentry{profits}{Profit}{\protect\pounds2,525}\relax +\DTLnewrow{profits} +\DTLnewdbentry{profits}{Year}{2001}\relax +\DTLnewdbentry{profits}{Profit}{\protect\pounds3,752}\relax +\DTLnewrow{profits} +\DTLnewdbentry{profits}{Year}{2002}\relax +\DTLnewdbentry{profits}{Profit}{-\protect\pounds1,520}\relax +\DTLnewrow{profits} +\DTLnewdbentry{profits}{Year}{2003}\relax +\DTLnewdbentry{profits}{Profit}{\protect\pounds1,270}\relax +\begin{verbatim} +Year,Profit +2000,\pounds2,535 +2001,\pounds3,752 +2002,-\pounds1,520 +2003,\pounds1,270 +\end{verbatim} +First I can load this file into a database called "profits": +\begin{verbatim} +\DTLloaddb{profits}{profits.csv} +\end{verbatim} +Now I can plot the data as a bar chart: +\begin{verbatim} +\begin{figure}[htbp] +\centering + % Set the width of each bar to 10pt +\setlength{\DTLbarwidth}{10pt} + % Set the outline width to 1pt +\setlength{\DTLbaroutlinewidth}{1pt} + % Round the $y$ tick labels to integers +\setcounter{DTLbarroundvar}{0} + % Adjust the tick label offset +\setlength{\DTLticklabeloffset}{20pt} + % Change the y tick label alignment +\renewcommand*{\DTLbarYticklabelalign}{left} + % Rotate the y tick labels +\renewcommand*{\DTLbardisplayYticklabel}[1]{\rotatebox{-45}{#1}} + % Set the bar colours depending on the value of \theProfit +\DTLforeach{profits}{\theProfit=Profit}{% +\ifthenelse{\DTLislt{\theProfit}{0}} +{\DTLsetbarcolor{\DTLcurrentindex}{red}} +{\DTLsetbarcolor{\DTLcurrentindex}{blue}}} + % Do the bar chart +\DTLbarchart{variable=\theProfit,upperbarlabel=\theYear, +ylabel={Profit/Loss (\pounds)},verticalbars=false, +maxdepth=-2000,max=4000}{profits} +{\theProfit=Profit,\theYear=Year} +\caption{Profits for 2000--2003} +\end{figure} +\end{verbatim} +This produces \autoref{fig:profits}. Notes: +\begin{enumerate} +\item This example uses \cs{rotatebox}, so the \sty{graphics} +or \sty{graphicx} package is required. +\item The $y$ tick labels are too wide to fit horizontally +so they have been rotated to avoid overlapping with their +neighbour. +\item Rotating the $y$ tick labels puts them too close to +the $y$ axis, so \ics{DTLticklabeloffset} is made larger to +compensate. +\item Remember not to use \cs{year} as an assignment command +as this command already exists! +\item Before the bar chart is created I have iterated through +the database, setting the bar colour to red or blue +depending on the value of \cs{theProfit}. +\end{enumerate} + +Both \cs{DTLbarchart} and \cs{DTLmultibarchart} set the following +macros, which may be used in \cs{DTLbaratbegintikz} and +\cs{DTLbaratendtikz}: +\begin{definition}[\DescribeMacro{\DTLbarchartwidth}]% +\cs{DTLbarchartwidth} +\end{definition} +This is the overall width of the bar chart. In the case of +\cs{DTLbarchart} this is just the number of bars. In the case +of \cs{DTLmultibarchart} it is computed as: +\begin{displaymath} +m \times n + (m-1)\times g +\end{displaymath} +where $m$ is the number of bar groups (i.e.\ the number of rows +of data), $n$ is the number of bars within a group (i.e.\ +the number of commands listed in the +\csopt{DTLmultibarchart}{variables}) setting and $g$ is the +group gap (as specified by the \csopt{DTLmultibarchart}{groupgap} setting). + +\begin{definition}[\DescribeMacro{\DTLnegextent}]% +\cs{DTLnegextent} +\end{definition} +This is set to the negative extent of the bar chart. (This value +may either be zero or negative, and corresponds to the +\csopt{DTLbarchart,DTLmultibarchart}{maxdepth} setting.) + +\begin{definition}[\DescribeMacro{\DTLbarmax}]% +\cs{DTLbarmax} +\end{definition} +This is set to the maximum extent of the bar chart. (This value +corresponds to the +\csopt{DTLbarchart,DTLmultibarchart}{max} setting.) + +\begin{figure}[htbp] +\centering +\setlength{\DTLbarwidth}{10pt} +\setlength{\DTLbaroutlinewidth}{1pt} +\setlength{\DTLticklabeloffset}{20pt} +\setcounter{DTLbarroundvar}{0} +\renewcommand*{\DTLbarYticklabelalign}{left} +\renewcommand*{\DTLbardisplayYticklabel}[1]{\rotatebox{-45}{#1}} +\DTLforeach{profits}{\theProfit=Profit}{\relax +\ifthenelse{\DTLislt{\theProfit}{0}} +{\DTLsetbarcolor{\DTLcurrentindex}{red}} +{\DTLsetbarcolor{\DTLcurrentindex}{blue}}} +\DTLbarchart{variable=\theProfit,upperbarlabel=\theYear, +ylabel={Profit/Loss (\pounds)},verticalbars=false, +maxdepth=-2000,max=4000 +}{profits} +{\theProfit=Profit,\theYear=Year} +\caption[Profits for 2000--2003 (a horizontal bar chart)]{Profits for +2000--2003} +\label{fig:profits} +\end{figure} + +\end{example} + +\begin{example}{A Multi-Bar Chart}{ex:multibar} +This example uses the "marks" database described in +\autoref{ex:editdb}. +Recall that this database stores student marks for three +assignments. The keys for the assignment marks are +\texttt{Assignment 1}, \texttt{Assignment 2} and +\texttt{Assignment 3}, respectively. I can convert this +data into a bar chart using the following: +\begin{verbatim} +\begin{figure}[htbp] +\centering +\DTLmultibarchart{variables={\assignI,\assignII,\assignIII}, +barwidth=10pt,uppermultibarlabels={\assignI,\assignII,\assignIII}, +barlabel={\firstname\ \surname}}{marks}{% +\surname=Surname,\firstname=FirstName,\assignI=Assignment 1,% +\assignII=Assignment 2,\assignIII=Assignment 3} +\caption{Student marks} +\end{figure} +\end{verbatim} +This produces \autoref{fig:multibar}. Notes: +\begin{enumerate} +\item I used "variables={\assignI,\assignII,\assignIII}" to +set the variable to use for each bar within a group. This means +that there will be three bars in each group. +\item I have set the bar width to 10pt, otherwise the chart +will be too wide. +\item I used "uppermultibarlabels={\assignI,\assignII,\assignIII}" +to set the upper labels for each bar within a group. This +will print the assignment mark above the relevant bar. +\item I used "barlabel={\firstname\ \surname}" to place the +student's name below the group corresponding to that student. +\end{enumerate} + +\begin{figure}[htbp] +\centering +\DTLmultibarchart{variables={\assignI,\assignII,\assignIII}, +barwidth=10pt,uppermultibarlabels={\assignI,\assignII,\assignIII}, +barlabel={\firstname\ \surname}}{marks} +{\surname=Surname,\firstname=FirstName,\assignI=Assignment 1,\assignII=Assignment 2,\assignIII=Assignment 3} +\caption[Student marks (a multi-bar chart)]{Student +marks}\label{fig:multibar} +\end{figure} + +Recall that \autoref{ex:editdb} computed the average score over +for each student, and saved it with the key "Average". This +information can be added to the bar chart. It might also be +useful to compute the average over all students and add this +information to the chart. This is done as follows: +\begin{verbatim} + \begin{figure}[htbp] + \centering + % compute the overall mean + \DTLmeanforkeys{marks}{Average}{\overallmean} + % round it to 2 decimal places + \DTLround{\overallmean}{\overallmean}{2} + % draw a grey dotted line indicating the overall mean + % covering the entire width of the bar chart + \renewcommand*{\DTLbaratendtikz}{% + \draw[lightgray,loosely dotted] (0,\overallmean) -- + (\DTLbarchartwidth,\overallmean) + node[right,black]{Average (\overallmean)};} + % Set the lower bar labels to draw a brace across the current + % group, along with the student's name and average score + \renewcommand*{\DTLdisplaylowerbarlabel}[1]{% + \tikz[baseline=(current bounding box.center)]{ + \draw[snake=brace,rotate=-90](0,0) -- (\DTLbargroupwidth,0);} + \DTLround{\theMean}{\theMean}{2}% + \shortstack{#1\\(Average: \theMean)}} + % draw the bar chart + \DTLmultibarchart{variables={\assignI,\assignII,\assignIII}, + barwidth=10pt,uppermultibarlabels={\assignI,\assignII,\assignIII}, + barlabel={\firstname\ \surname}}{marks} + {\surname=Surname,\firstname=FirstName,\assignI=Assignment 1,% + \assignII=Assignment 2,\assignIII=Assignment 3,\theMean=Average} + \caption{Student marks} + \end{figure} +\end{verbatim} +which produces \autoref{fig:multibarmean}. Notes: +\begin{enumerate} +\item I've used the TikZ snake library to create a brace, so +I need to put +\begin{verbatim} +\usetikzlibrary{snakes} +\end{verbatim} +in the preamble. See the \sty{pgf} manual for more details on +how to use this library. + +\item I used \ics{DTLbargroupwidth} to indicate the width of +each bar group. + +\item I used \ics{DTLbarchartwidth} to indicate the width of the +entire bar chart +\end{enumerate} + +\begin{figure}[htbp] +\centering +\DTLmeanforkeys{marks}{Average}{\overallmean} +\DTLround{\overallmean}{\overallmean}{2} +\renewcommand*{\DTLbaratendtikz}{\draw[lightgray,loosely dotted] (0,\overallmean) -- +(\DTLbarchartwidth,\overallmean) node[right,black]{Average (\overallmean)};} +\renewcommand*{\DTLdisplaylowerbarlabel}[1]{\relax +\tikz[baseline=(current bounding box.center)]{ +\draw[snake=brace,rotate=-90](0,0) -- (\DTLbargroupwidth,0);} +\DTLround{\theMean}{\theMean}{2}\relax +\shortstack{#1\\(Average: \theMean)}} +\DTLmultibarchart{variables={\assignI,\assignII,\assignIII}, +barwidth=10pt,uppermultibarlabels={\assignI,\assignII,\assignIII}, +barlabel={\firstname\ \surname}}{marks} +{\surname=Surname,\firstname=FirstName,\assignI=Assignment 1,\assignII=Assignment 2,\assignIII=Assignment 3,\theMean=Average} +\caption[Student marks (annotating a bar chart)]{Student marks} +\label{fig:multibarmean} +\end{figure} + +\end{example} + +\chapter{Converting a \texorpdfstring{\BibTeX}{BibTeX} database +into a \texorpdfstring{\sty{datatool}}{datatool} database +(\texorpdfstring{\sty{databib}}{databib} package)} +\label{sec:databib} + +The \sty{databib} package provides the means of converting a \BibTeX\ +database into a \sty{datatool} database. The database can then be +sorted using \cs{DTLsort}, described in \autoref{sec:sort}. +For example, you may want to sort the bibliography in +reverse chronological order. Once you have sorted the bibliography, +you can display it using \cs{DTLbibliography}, described in +\autoref{sec:thebib}, or you can iterate through the database +using \cs{DTLforeachbib}, described in \autoref{sec:foreachbib}. + +Note that the \sty{databib} +package is not automatically loaded by \sty{datatool}, so if +you want to use it, you must load it using +"\usepackage{databib}". + +\begin{important} +The purpose of this package is to provide a means for +authors to format their own bibliography style where there is no +bibliography style file available that produces the desired results. +The \cs{DTLsort} macro uses a much less efficient sorting algorithm +than \BibTeX, and loading the bibliography as a \sty{datatool} +database is much slower than loading a standard \filetype{bbl} file. If +you have a large database, and you are worried that \LaTeX\ may have +become stuck, try using the \pkgopt{verbose} option to \sty{datatool} +or use the command \cs{dtlverbosetrue}. This will print informative +messages to the console and transcript file, to let you know what's +going on. +\end{important} + +\section{\texorpdfstring{\BibTeX}{BibTeX}: An Overview} +\label{sec:bibtex} +This document assumes that you have at least some passing +familiarity with \BibTeX, but here follows a brief refresher. + +\BibTeX\ is an external application used in conjunction with \LaTeX. +When you run \BibTeX, you need to specify the name of the document's +auxiliary file (without the \filetype{aux} extension). \BibTeX\ then reads +this file and looks for the commands \cs{bibstyle} (which indicates +which bibliography style (\filetype{bst}) file to load), \cs{bibdata} +(which indicates which bibliography database (\filetype{bib}) files to +load) and \cs{citation} (produced by \cs{cite} and \cs{nocite}, which +indicates which entries should be included in the bibliography). +\BibTeX\ then creates a file with the extension \filetype{bbl} which +contains the bibliography, formatted according to the layout defined +in the bibliography style file. + +In general, given a document called, say, \texttt{mydoc.tex}, you +will have to perform the following steps to ensure that the +bibliography and all citations are up-to-date: +\begin{enumerate} +\item +\begin{verbatim} +latex mydoc +\end{verbatim} +This writes the citation information to the auxiliary file. +The bibliography currently doesn't exists, so it isn't displayed. +Citations will appear in the document as ?? since the internal +cross-references don't exist yet. + +\item +\begin{verbatim} +bibtex mydoc +\end{verbatim} +This reads the auxiliary file, and creates a file with the extension +\filetype{bbl} which typically contains the typeset bibliography. + +\item +\begin{verbatim} +latex mydoc +\end{verbatim} +Now that the \filetype{bbl} file exists, the bibliography can be input +into the document. The internal cross-referencing information for the +bibliography can now be written to the auxiliary file. + +\item +\begin{verbatim} +latex mydoc +\end{verbatim} +The cross-referencing information can be read from the auxiliary +file. +\end{enumerate} + +\subsection{\texorpdfstring{\BibTeX}{BibTeX} database} + +The bibliographic data required by \BibTeX\ must be stored in +a file with the extension \filetype{bib}, where each entry is stored +in the form:\par\vskip\baselineskip\noindent +{\obeylines +\noindent\texttt{@}\meta{entry\_type}\verb|{|\meta{cite\_key}\texttt, + \meta{field\_name} \texttt{=} \char`\"\meta{value}\char`\"\texttt, + \mbox{}\vdots + \meta{field\_name} \texttt{=} \char`\"\meta{value}\char`\" +\noindent\verb|}| +} +\par\vskip\baselineskip\noindent +Note that curly braces "{" and "}" may be used instead of \verb|"| +and \verb|"|. + +The entry type, given by \meta{entry\_type} above, indicates +the type of document. This may be one of: "article", "book", +"booklet", "inbook", "incollection", "inproceedings"\footnote +{Note that \texttt{conference} is a synonym for \texttt{inproceedings}.}, +"manual", +"mastersthesis", "misc", "phdthesis", "proceedings", \linebreak +"techreport" or "unpublished". + +The \meta{cite\_key} above is a unique label identifying this +entry, and is the label used in the argument of \cs{cite} or +\cs{nocite}. The available fields depends on the entry type, for +example, the field "journal" is required for the "article" entry +type, but is ignored for the "inproceedings" entry type. The standard +fields are: "address", "author", "booktitle", "chapter", "edition", +"editor", "howpublished", "institution", "journal", "key", "month", +"note", "number", "organization", "pages", "publisher", "school", +"series", "title", "type", "volume" and "year". + +Author and editor names must be entered in one of the following +ways: +\begin{enumerate} +\item \meta{First names} \meta{von part} \meta{Surname}, \meta{Jr part} + +The \meta{von part} is optional and is identified by the name(s) +starting with lowercase letters. The final comma followed by +\meta{Jr part} is also optional. Examples: +\begin{verbatim} +author = "Henry James de Vere" +\end{verbatim} +In the above, the first names are Henry James, the ``von part'' is +de and the surname is Vere. There is no ``junior part''. +\begin{verbatim} +author = "Mary-Jane Brown, Jr" +\end{verbatim} +In the above, the first name is Mary-Jane, there is no von part, +the surname is Brown and the junior part is Jr. +\begin{verbatim} +author = "Peter {Murphy Allen}" +\end{verbatim} +In the above, the first name is Peter, and the surname is Murphy +Allen. Note that in this case, the surname must be grouped, otherwise +Murphy would be considered part of the forename. +\begin{verbatim} +author = "Maria Eliza {\uppercase{d}e La} Cruz" +\end{verbatim} +In the above, the first name is Maria Eliza, the von part is +De La, and the surname is Cruz. In this case, the von part starts +with an uppercase letter, but specifying +\begin{verbatim} +author = "Maria Eliza De La Cruz" +\end{verbatim} +would make \BibTeX\ incorrectly classify ``Maria Eliza De La'' as +the first names, and the von part would be empty. Since \BibTeX\ +doesn't understand \LaTeX\ commands, using "{\uppercase{d}e La}" +will trick \BibTeX\ into thinking that it starts with a lower +case letter. + +\item \meta{von part} \meta{Surname}, \meta{Forenames} + +Again the \meta{von part} is optional, and is determined by the +case of the first letter. For example: +\begin{verbatim} +author = "de Vere, Henry James" +\end{verbatim} +\end{enumerate} + +Multiple authors or editors should be separated by the key word +"and", for example: +\begin{verbatim} +author = "Michel Goossens and Frank Mittlebach and Alexander Samarin" +\end{verbatim} + +Below is an example of a book entry: +\begin{verbatim} +@book{latexcomp, + title = "The \LaTeX\ Companion", + author = "Michel Goossens and Frank Mittlebach and + Alexander Samarin", + publisher = "Addison-Wesley", + year = 1994 +} +\end{verbatim} +Note that numbers may be entered without delimiters, as in "year = 1994". +There are also some predefined strings, including those for the month +names. You should always use these strings instead of the actual +month name, as the way the month name is displayed depends on the +bibliography style. For example: +\begin{verbatim} +@article{Cawley2007b, +author = "Gavin C. Cawley and Nicola L. C. Talbot", +title = "Preventing over-fitting in model selection via {B}ayesian + regularisation of the hyper-parameters", +journal = "Journal of Machine Learning Research", +volume = 8, +pages = "841--861", +month = APR, +year = 2007 +} +\end{verbatim} + +You can concatenate strings using the "#" character, for example: +\begin{verbatim} +month = JUL # "~31~--~" # AUG # "~4", +\end{verbatim} +Depending on the bibliography style, this may be displayed as: +July~31~--~August~4, or it may be displayed as: +Jul~31~--~Aug~4. For further information, see~\cite{Goossens}. + +\section{Loading a \texorpdfstring{\sty{databib}}{databib} +database} +\label{sec:loadbbl} + +The \sty{databib} package always requires the \texttt{databib.bst} +bibliography style file (which is supplied with this bundle). +You need to use \cs{cite} or \cs{nocite} as usual. If you want to +add all entries in the \filetype{bib} file to the \sty{datatool} database, +you can use "\nocite{*}". + +\begin{definition}[\DescribeMacro{\DTLloadbbl}]% +\cs{DTLloadbbl}\oarg{bbl name}\marg{db name}\marg{bib list} +\end{definition} +This command performs several functions: + +\begin{enumerate} +\item it writes the following line in the auxiliary file: +\begin{verbatim} +\bibstyle{databib} +\end{verbatim} +which tells \BibTeX\ to use the \texttt{databib.bst} +\BibTeX\ style file, + +\item it writes \cs{bibdata}\marg{bib list} to the +auxiliary file, which tells \BibTeX\ which \filetype{bib} files to use, + +\item it creates a \sty{datatool} database called \meta{db name}, + +\item it loads the file \meta{bbl name} if it exists. (The value +defaults to \cs{jobname}".bbl", which is the usual name for +a \filetype{bbl} file.) If the \filetype{bbl} file doesn't exist, the +database \meta{db name} will remain empty. +\end{enumerate} + +You then need to run your document through \LaTeX\ (or PDF\LaTeX) +and then run \BibTeX\ on the auxiliary file, as described in +\autoref{sec:bibtex}. This will create a \filetype{bbl} file which +contains all the commands required to add the bibliography information +to the \sty{datatool} database called \meta{db name}. The next +time you \LaTeX\ your document, this file will be read, and the +information will be added to \meta{db name}. + +\begin{important} +Note that \cs{DTLloadbbl} doesn't generate any text. Once you have +loaded the data, you can display the bibliography uses +\cs{DTLbibliography} (described below) or you can iterate through it +using \cs{DTLforeachbibentry} described in \autoref{sec:foreachbib}. +\end{important} + +Note that the \texttt{databib.bst} \BibTeX\ style file provides +the following additional fields: "isbn", "doi", "pubmed", "url" +and "abstract". +However these fields are ignored by the three predefined +\sty{databib} styles ("plain", "abbrv" and "alpha"). If you +want these fields to be displayed in the bibliography you will +need to modify the bibliography style (see \autoref{sec:modbibstyle}). + +\section{Displaying a \texorpdfstring{\sty{databib}}{databib} +database} +\label{sec:thebib} + +A \sty{databib} database which has been loaded using +\cs{DTLloadbbl} (described in \autoref{sec:loadbbl}) can be +displayed using: +\begin{definition}[\DescribeMacro{\DTLbibliography}] +\cs{DTLbibliography}\oarg{conditions}\marg{db name} +\end{definition}\noindent +where \meta{db name} is the name of the database. + +Within the optional argument \meta{condition}, you may use any of the +commands that may be used within the optional argument of +\cs{DTLforeach} \emph{In addition}, you may use the following +commands: + +\begin{definition}[\DescribeMacro{\DTLbibfieldexists}]% +\cs{DTLbibfieldexists}\marg{field label} +\end{definition} +This tests whether the field with the given label exists for the +current entry. +The field label may be one of: "Address", "Author", +"BookTitle", "Chapter", "Edition", "Editor", "HowPublished", +"Institution", "Journal", "Key", "Month", "Note", "Number", +"Organization", "Pages", "Publisher", "School", "Series", +"Title", "Type", "Volume", "Year", "ISBN", "DOI", "PubMed", +"Abstract", "Url" or "Eprints". + +For example, suppose you have loaded a \sty{databib} database +called "mybib" using \cs{DTLloadbbl} (described in +\autoref{sec:loadbbl}) then the following bibliography will only +include those entries which have a "Year" field: +\begin{verbatim} +\DTLbibliography[\DTLbibfieldexists{Year}]{mybib} +\end{verbatim} + +\begin{definition}[\DescribeMacro{\DTLbibfieldiseq}]% +\cs{DTLbibfieldiseq}\marg{field label}\marg{value} +\end{definition} +This tests whether the value of the field given by +\meta{field label} equals \meta{value}. If the field doesn't +exist for the current entry, this evaluates to false. +For example, the following will produce a bibliography which +only contains entries which have the "Year" field set to 2004: +\begin{verbatim} +\DTLbibliography[\DTLbibfieldiseq{Year}{2004}]{mybib} +\end{verbatim} + +\begin{definition}[\DescribeMacro{\DTLbibfieldcontains}]% +\cs{DTLbibfieldcontains}\marg{field label}\marg{sub string} +\end{definition} +This tests whether the value of the field given by \meta{field label} +contains \meta{sub string}. For example, the following will produce +a bibliography which only contains entries where the author field +contains the name "Knuth": +\begin{verbatim} +\DTLbibliography[\DTLbibfieldcontains{Author}{Knuth}]{mybib} +\end{verbatim} + +\begin{definition}[\DescribeMacro{\DTLbibfieldislt}]% +\cs{DTLbibfieldislt}\marg{field label}\marg{value} +\end{definition} +This tests whether the value of the field given by \meta{field label} +is less than \meta{value}. If the field doesn't exist for the +current entry, this evaluates to false. +For example, the following will produce a bibliography which only +contains entries whose "Year" field is less than 1983: +\begin{verbatim} +\DTLbibliography[\DTLbibfieldislt{Year}{1983}]{mybib} +\end{verbatim} + +\begin{definition}[\DescribeMacro{\DTLbibfieldisle}]% +\cs{DTLbibfieldisle}\marg{field label}\marg{value} +\end{definition} +This tests whether the value of the field given by \meta{field label} +is less than or equal to \meta{value}. If the field doesn't exist +for the current entry, this evaluates to false. +For example, the following will produce a bibliography which only +contains entries whose "Year" field is less than or equal to 1983: +\begin{verbatim} +\DTLbibliography[\DTLbibfieldisle{Year}{1983}]{mybib} +\end{verbatim} + +\begin{definition}[\DescribeMacro{\DTLbibfieldisgt}]% +\cs{DTLbibfieldisgt}\marg{field label}\marg{value} +\end{definition} +This tests whether the value of the field given by \meta{field label} +is greater than \meta{value}. If the field doesn't exist for the +current entry, this evaluates to false. +For example, the following will produce a bibliography which only +contains entries whose "Year" field is greater than 1983: +\begin{verbatim} +\DTLbibliography[\DTLbibfieldisgt{Year}{1983}]{mybib} +\end{verbatim} + +\begin{definition}[\DescribeMacro{\DTLbibfieldisge}]% +\cs{DTLbibfieldisge}\marg{field label}\marg{value} +\end{definition} +This tests whether the value of the field given by \meta{field label} +is greater than or equal to \meta{value}. If the field doesn't exist +for the current entry, this evaluates to false. +For example, the following will produce a bibliography which only +contains entries whose "Year" field is greater than or equal to 1983: +\begin{verbatim} +\DTLbibliography[\DTLbibfieldisge{Year}{1983}]{mybib} +\end{verbatim} + +Note that \cs{DTLbibliography} uses \cs{DTLforeachbibentry} +(described in \autoref{sec:foreachbib}) so you may also use +test the value of the counter \ctr{DTLbibrow} within +\meta{conditions}. You may also use the boolean commands defined +by the \sty{ifthen} package, such as \ics{not}. + +\begin{example}{Creating a list of publications since a given year}{ex:bibsince2000} +Suppose my boss has asked me to produce a list of my +publications in reverse chronological order, but doesn't want any +publications published prior +to the year 2000. I have a file called "nlct.bib" which contains +all my publications which I keep in the directory +\verb!$HOME/texmf/bibtex/bib/!. I could look through this file, +work out the labels for all the publications whose year field +is greater or equal to 2000, and +create a file with a \cs{nocite} command containing all those labels +in a comma separated list in reverse chronological order, +but I really can't be bothered to do that. +Instead, I can create the following document: +\begin{verbatim} +\documentclass{article} +\usepackage{databib} +\begin{document} +\nocite{*} +\DTLloadbbl{mybib}{nlct} +\DTLsort{Year=descending,Month=descending}{mybib} +\DTLbibliography[\DTLbibfieldisge{Year}{2000}]{mybib} +\end{document} +\end{verbatim} +Suppose I save this file as "mypubs.tex", then I need to do: +\begin{verbatim} +latex mypubs +bibtex mypubs +latex mypubs +\end{verbatim} +Notes: +\begin{enumerate} +\item "\nocite{*}" is used to add all the citations in the +bibliography file ("nlct.bib" in this case) to the \sty{databib} +database. + +\item "\DTLloadbbl{mybib}{nlct}" does the following: +\begin{enumerate} +\item writes the line +\begin{verbatim} +\bibstyle{databib} +\end{verbatim} +to the auxiliary file. This tells \BibTeX\ to use "databib.bst" +(which is supplied with this package). You therefore shouldn't +use \cs{bibliographystyle}. + +\item writes the line +\begin{verbatim} +\bibdata{nlct} +\end{verbatim} +to the auxiliary file. This tells \BibTeX\ that the bibliography +data is stored in the file "nlct.bib". Since I have placed this +file in \TeX's search path, \BibTeX\ will be able to find it. + +\item creates a \sty{datatool} database called "mybib". + +\item if the \filetype{bbl} file ("mypubs.bbl" in this example) exists, +it loads this file (which adds the bibliography data to the +database), otherwise it does nothing further. + +\end{enumerate} + +\item In my \BibTeX\ database ("nlct.bib" in this example), I +have remembered to use the \BibTeX\ month macros: "jan", "feb" +etc. This means that the months are stored in the database in +the form \cs{DTLmonthname}\marg{nn}, where \meta{nn} is a two +digit number from 01 to 12. \cs{DTLsort} ignores command names +when it compares strings, which means I can not only sort by +year, but also by month\footnote{as long as I haven't put anything +before the month name in the bibliography file, e.g.\ +\mbox{\texttt{month = "2~" \# apr}} will sort by 2~03, instead of +03}. + +\item Once I have loaded and sorted my database, I can then +display it using \cs{DTLbibliography}. This uses the style +given by the \sty{databib} \pkgopt[databib]{style} package option, +or the \cs{DTLbibliographystyle} command, both of which are +described in \autoref{sec:bibstyle}. + +\item I have filtered the bibliography using the optional +argument\linebreak "[\DTLbibfieldisge{Year}{2000}]", which checks if the +year field of the current entry is greater than or equal to +2000. (Note that if an entry has no year field, the condition +evaluates to false, and the entry will be omitted from the +bibliography.) + +\item If the bibliography database is large, sorting and creating +the bibliography may take a while. Using \sty{databib} is much +slower than using a standard \BibTeX\ style file. +\end{enumerate} +\end{example} + +\begin{example}{Creating a list of my 10 most recent +publications}{ex:top10bib} +Suppose now my boss has asked me to produce a list of my ten most +recent publications (in reverse chronological order). +As in the previous example, I have a file called "nlct.bib" +which contains all my publications. I can create the required +document as follows: +\begin{verbatim} +\documentclass{article} +\usepackage{databib} +\begin{document} +\nocite{*} +\DTLloadbbl{mybib}{nlct} +\DTLsort{Year=descending,Month=descending}{mybib} +\DTLbibliography[\value{DTLbibrow}<10]{mybib} +\end{document} +\end{verbatim} +\end{example} + +\section{Changing the bibliography style} +\label{sec:bibstyle} +The style of the bibliography produced using \cs{DTLbibliography} +depends on the \pkgopt[databib]{style} +package option, or can be set using +\begin{definition}[\DescribeMacro{\DTLbibliographystyle}]% +\cs{DTLbibliographystyle}\marg{style} +\end{definition} +Note that this is \emph{not} the same as \cs{bibliographystyle}, +as the \sty{databib} package uses its custom \texttt{databib.bst} +bibliography style file. + +Example: +\begin{verbatim} +\usepackage[style=plain]{databib} +\end{verbatim} +This sets the plain bibliography style. This is, in fact, the +default style, so it need not be specified. + +Available styles are: "plain", "abbrv" and "alpha". These are similar to the +standard \BibTeX\ styles of the same name, but are by no means +identical. The most notable difference is that these styles +do not sort the bibliography. It is up to you to sort the +bibliography using \cs{DTLsort} (described in \autoref{sec:sort}). + +\subsection{Modifying an existing style} +\label{sec:modbibstyle} + +This section describes some of the commands which are used to +format the bibliography. You can choose whichever predefined +style best fits your required style, and then modify the commands +described in this section. A description of the remaining +commands not listed in this section can be found in +\autoref{sec:src:bibnames}, \autoref{sec:src:displaybib} +and \autoref{sec:src:bibstyle}. + +\begin{definition}[\DescribeMacro{\DTLformatauthor}]% +\cs{DTLformatauthor}\marg{von part}\marg{surname}\marg{jr part}\marg{forenames} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLformateditor}]% +\cs{DTLformateditor}\marg{von part}\marg{surname}\marg{jr part}\marg{forenames} +\end{definition} +These commands are used to format an author/editor's name, +respectively. The list of authors and editors are stored in +the \sty{databib} database as a comma separated list of +\marg{von part}\marg{surname}\marg{jr part}\marg{forenames} +data. This ensures that when you sort on the Author or Editor +field, the names will be sorted by the first author or editor's +surname. + +Within \cs{DTLformatauthor} and \cs{DTLformateditor}, you may +use the following commands: +\begin{definition}[\DescribeMacro{\DTLformatforenames}]% +\cs{DTLformatforenames}\marg{forenames} +\end{definition} +This is used by the "plain" style to display the author's +forenames\footnote{It also checks +whether \meta{forenames} ends with a full stop using +\cs{DTLcheckendsperiod} to prevent a sentence ending full stop +from following an abbreviation full stop}. + +\begin{definition}[\DescribeMacro{\DTLformatabbrvforenames}]% +\cs{DTLformatabbrvforenames}\marg{forenames} +\end{definition} +This is used by the "abbrv" style to display the author's +initials (which are determined from \meta{forenames}). +Note that if any of the authors has a name starting with an +accent, the accented letter must be grouped in order for this +command to work. For example: +\begin{verbatim} +author = "{\'E}lise {\"E}awyn Edwards", +\end{verbatim} +The initials are formed using \cs{DTLstoreinitials} described +in \autoref{sec:strings}, so if you want to change the way the +initials are displayed (e.g.\ put a space between them) you will +need to redefine the commands used by \cs{DTLstoreinitials} (such +as \cs{DTLbetweeninitials}). + +\begin{definition}[\DescribeMacro{\DTLformatsurname}]% +\cs{DTLformatsurname}\marg{surname} +\end{definition} +This displays its argument by default\footnote{It also checks +whether the surname ends with a full stop using +\cs{DTLcheckendsperiod}}. + +\begin{definition}[\DescribeMacro{\DTLformatvon}]% +\cs{DTLformatvon}\marg{von part} +\end{definition} +If the \meta{von part} is empty, this command does nothing, +otherwise it displays its argument followed by a +non-breakable space. +\begin{definition}[\DescribeMacro{\DTLformatjr}]% +\cs{DTLformatjr}\marg{jr part} +\end{definition} +If the \meta{jr part} is empty, this command displays nothing, +otherwise it displays a comma followed by its argument\footnote +{again, it also checks \meta{jr part} to determine if it ends +with a full stop}. + +For example, suppose you want the author's surname to appear +first in small capitals, followed by a comma and the forenames. This +can be achieved by redefining \cs{DTLformatauthor} as follows: +\begin{verbatim} +\renewcommand*{\DTLformatauthor}[4]{% +\textsc{\DTLformatvon{#1}% +\DTLformatsurname{#2}\DTLformatjr{#3}}, +\DTLformatforenames{#4}% +} +\end{verbatim} + +\begin{definition}[\DescribeCounter{DTLmaxauthors}] +\ctrfmt{DTLmaxauthors} +\end{definition} +The counter \ctrfmt{DTLmaxauthors} is used to determine the +maximum number of authors to display for a given entry. If the +entry's author list contains more than that number of authors, +\cs{etalname} is used, the definition of which is given in +\autoref{sec:src:bibnames}. The default value of +\ctrfmt{DTLmaxauthors} is \theDTLmaxauthors. + +\begin{definition}[\DescribeCounter{DTLmaxeditors}] +\ctrfmt{DTLmaxeditors} +\end{definition} +The \ctrfmt{DTLmaxeditors} counter is analogous to the +\ctrfmt{DTLmaxauthors} counter. It is used to determine the +maximum number of editor names to display. The default value +of \ctrfmt{DTLmaxeditors} is \theDTLmaxeditors. + +\DescribeMacro{\DTLandlast} +Within a list of author or editor names, \cs{DTLandlast} is +used between the last two names, otherwise +\DescribeMacro{\DTLandnotlast}\cs{DTLandnotlast} is used between +names. +However, if there are only two author or editor names, +\DescribeMacro{\DTLtwoand}\cs{DTLtwoand} +is used instead of \cs{DTLandlast}. + +\DescribeMacro{\DTLendbibitem} +The command \cs{DTLendbibitem} is a hook provided to add +additional information at the end of each bibliography item. +This does nothing by default, but if you want to display the +additional fields provided by the "databib.bst" style file, +you can redefine \cs{DTLendbibitem} so that it displays a +particular field, if it is defined. Within this command, you +may use the commands \cs{DTLbibfield}, \cs{DTLifbibfieldexist} +and \cs{DTLifanybibfieldexist}, which are described in +\autoref{sec:foreachbib}. For example, if you have used the +"abstract" field in any of your entries, you can display the +abstract as follows: +\begin{verbatim} +\renewcommand{\DTLendbibitem}{% +\DTLifbibfieldexists{Abstract}{\DTLpar\textbf{Abstract} +\begin{quote}\DTLbibfield{Abstract}\end{quote}}{}} +\end{verbatim} +(Note that \cs{DTLpar} needs to be used instead of +\cs{par}.) + +\begin{example}{Compact bibliography}{ex:compactbib} +Suppose I don't have much space in my document, and I need to +produce a compact bibliography. Firstly, I can use the +bibliography style "abbrv", either through the package option: +\begin{verbatim} +\usepackage[style=abbrv]{databib} +\end{verbatim} +or using: +\begin{verbatim} +\DTLbibliographystyle{abbrv} +\end{verbatim} +Once I have set the style, I can further modify it thus: +\begin{verbatim} +\renewcommand*{\andname}{\&} +\renewcommand*{\editorname}{ed.} +\renewcommand*{\editorsname}{eds.} +\renewcommand*{\pagesname}{pp.} +\renewcommand*{\pagename}{p.} +\renewcommand*{\volumename}{vol.} +\renewcommand*{\numbername}{no.} +\renewcommand*{\editionname}{ed.} +\renewcommand*{\techreportname}{T.R.} +\renewcommand*{\mscthesisname}{MSc thesis} +\end{verbatim} +Now I can load\footnote{I can load the bibliography earlier, but +obviously the bibliography should only be displayed after the +bibliography styles have been set, otherwise they will have no +effect} and display the bibliography: +\begin{verbatim} + % create a database called mybib from the information given + % in mybib1.bib and mybib2.bib + \DTLloadbbl{mybib}{mybib1,mybib2} + % display the bibliography + \DTLbibliography{mybib} +\end{verbatim} +\end{example} + +\begin{example}{Highlighting a given author}{ex:highlightauthor} +Suppose my boss wants me to produce a list of all my publications +(which I have stored in the file "nlct.bib", as in +\autoref{ex:bibsince2000}). Most of my +publications have multiple co-authors, but suppose my boss would +like me to highlight my name so that when he skims through +the document, he can easily see my name in the list of +co-authors. I can do this by redefining \cs{DTLformatauthor} +so that it checks if the given surname matches mine. (This +assumes that none of the other co-author's share my surname.) +\begin{verbatim} +\renewcommand*{\DTLformatauthor}[4]{% +{\DTLifstringeq{#2}{Talbot}{\bfseries }{}% +\DTLformatforenames{#4} +\DTLformatvon{#1}% +\DTLformatsurname{#2}% +\DTLformatjr{#3}}} +\end{verbatim} +Notes: +\begin{enumerate} +\item I have used \cs{DTLifstringeq} (described in +\autoref{sec:ifconditions}) to perform the string comparison. +\item If one or more of my co-authors shared the same surname as +me, I would also have had to check the first name, however there +is regrettably a lack of consistency in my \filetype{bib} file when +it comes to my forenames. Sometimes my name is given as +\texttt{Nicola L. C. Talbot}, sometimes the middle initials +are omitted, \texttt{Nicola Talbot}, or sometimes, just initials +are used, \texttt{N. L. C. Talbot}. This can cause problems +when checking the forenames, but as long as the other authors +who share the same surname as me, don't also share the same +first initial, I can use \cs{DTLifStartsWith} or \cs{DTLisPrefix}, +which are described in \autoref{sec:ifconditions} and +\autoref{sec:ifthen}, respectively. Using the first approach +I can do: +\begin{verbatim} +\renewcommand*{\DTLformatauthor}[4]{% +{\DTLifstringeq{#2}{Talbot}{\DTLifStartsWith{#4}{N}{\bfseries }{}}{}% +\DTLformatforenames{#4} +\DTLformatvon{#1}% +\DTLformatsurname{#2}% +\DTLformatjr{#3}}} +\end{verbatim} +Using the second approach I can do: +\begin{verbatim} +\renewcommand*{\DTLformatauthor}[4]{% +{\ifthenelse{\DTLiseq{#2}{Talbot}\and +\DTLisPrefix{#4}{N}}{\bfseries }{}% +\DTLformatforenames{#4} +\DTLformatvon{#1}% +\DTLformatsurname{#2}% +\DTLformatjr{#3}}} +\end{verbatim} + +\item I have used a group to localise the effect of \cs{bfseries}. +\end{enumerate} +\end{example} + +\section{Iterating through a +\texorpdfstring{\sty{databib}}{databib} database} +\label{sec:foreachbib} + +\cs{DTLbibliography} (described in \autoref{sec:thebib}) may still +not meet your needs. For example, you may be required +to list journal papers and conference proceedings in separate +sections. In which case, you may find it easier to iterate through +the bibliography using: +\begin{definition}[\DescribeMacro{\DTLforeachbib}]% +\cs{DTLforeachbib}\oarg{condition}\marg{db name}\marg{text} +\end{definition} +\begin{definition}[\DescribeMacro{\DTLforeachbib*}]% +\cs{DTLforeachbib*}\oarg{condition}\marg{db name}\marg{text} +\end{definition} +This iterates through the \sty{databib} database called +\meta{db name} and does \meta{text} if \meta{condition} is met. +As with \cs{DTLforeach}, the starred version is read-only. + +For each row of the database, the following commands are set: +\begin{itemize} +\item \cs{DBIBcitekey} \DescribeMacro{\DBIBcitekey}This is the +unique label which identifies the current entry (as used in the +argument of \cs{cite} and \cs{nocite}). + +\item \cs{DBIBentrytype} \DescribeMacro{\DBIBentrytype}This +is the current entry type, and will be one of: "article", "book", +"booklet", "inbook", "incollection", "inproceedings", +"manual", "mastersthesis", "misc", "phdthesis", "proceedings", +"techreport" or "unpublished". (Note that even if you used the +entry type "conference" in your \filetype{bib} file, its entry type +will be set to "inproceedings"). +\end{itemize} + +The remaining fields may be accessed using: +\begin{definition}[\DescribeMacro{\DTLbibfield}]% +\cs{DTLbibfield}\marg{field label} +\end{definition}\noindent +where \meta{field label} may be one of: "Address", "Author", +"BookTitle", "Chapter", "Edition", "Editor", "HowPublished", +"Institution", "Journal", "Key", "Month", "Note", "Number", +"Organization", "Pages", "Publisher", "School", "Series", +"Title", "Type", "Volume", "Year", "ISBN", "DOI", "PubMed", +"Abstract" or "Url". + +You can determine if a field exists for a given entry using +\begin{definition}[\DescribeMacro{\DTLifbibfieldexists}]% +\cs{DTLifbibfieldexists}\marg{field label}\marg{true part}\marg{false +part} +\end{definition} +If the field given by \meta{field label} exists for the current +bibliography entry, it does \meta{true part}, otherwise it +does \meta{false part}. + +\begin{definition}[\DescribeMacro{\DTLifbibanyfieldexists}]% +\cs{DTLifanybibfieldexists}\marg{field label list}\marg{true +part}\marg{false part} +\end{definition} +This is similar to \cs{DTLifbibfieldexists} except that the +first argument is a list of field names. If one or more of +the fields given in \meta{field label list} exists for the +current bibliography item, this does \meta{true part}, otherwise +it does \meta{false part}. + +\begin{definition}[\DescribeMacro{\DTLformatbibentry}]% +\cs{DTLformatbibentry} +\end{definition} +This formats the bibliography entry for the current row. It +checks for the existence of the command +\cs{DTLformat}\meta{entry type}, where \meta{entry type} +is given by \cs{DBIBentrytype}. These commands are defined +by the bibliography style. + +\begin{definition}[\DescribeMacro{\DTLcomputewidestbibentry}]% +\cs{DTLcomputewidestbibentry}\marg{conditions}\marg{db +name}\marg{bib label}\marg{cmd} +\end{definition} +This computes the widest bibliography entry over all entries +satisfying \meta{conditions} in the database \meta{db name}, +where the label is given by \meta{bib label}, and the result +is stored in \meta{cmd}, which may then be used in the +argument of the \env{thebibliography} environment. + +The counter \desctr{DTLbibrow} keeps track of the current +bibliography entry. This is reset at the start of each +\cs{DTLforeachbib} and is incremented if \meta{conditions} +is met. + +Within the optional argument \meta{condition}, you may use any of the +commands that may be used within the optional argument of +\cs{DTLbibliography}, described in \autoref{sec:thebib}. + +\begin{example}{Separate List of Journals and Conference Papers}{ex:jcbib} +Suppose now my boss has decided that I need to produce a list +of all my publications, but they need to be separated so that +all the journal papers appear in one section, and all the +conference papers appear in another section. The journal papers +need to be labelled [J1], [J2] and so on, while the conference +papers need to be labelled [C1], [C2] and so on. (My boss isn't +interested in any of my other publications!) Again, all my +publications are stored in the \BibTeX\ database "nlct.bib". The +following creates the required document: +\begin{verbatim} +\documentclass{article} +\usepackage{databib} +\begin{document} +\nocite{*} +\DTLloadbbl{mybib}{nlct} + +\renewcommand*{\refname}{Journal Papers} +\DTLcomputewidestbibentry{\equal{\DBIBentrytype}{article}} +{mybib}{J\theDTLbibrow}{\widest} + +\begin{thebibliography}{\widest} +\DTLforeachbibentry[\equal{\DBIBentrytype}{article}]{mybib}{% +\bibitem[J\theDTLbibrow]{\DBIBcitekey} \DTLformatbibentry} +\end{thebibliography} + +\renewcommand*{\refname}{Conference Papers} +\DTLcomputewidestbibentry{\equal{\DBIBentrytype}{inproceedings}} +{mybib}{C\theDTLbibrow}{\widest} + +\begin{thebibliography}{\widest} +\DTLforeachbibentry[\equal{\DBIBentrytype}{inproceedings}]{mybib}{% +\bibitem[C\theDTLbibrow]{\DBIBcitekey} \DTLformatbibentry} +\end{thebibliography} + +\end{document} +\end{verbatim} +\end{example} + +\section{Multiple Bibliographies} +\label{sec:multibib} + +It is possible to have more than one bibliography in a document, +but it then becomes necessary to have a separate auxiliary file +for each bibliography, and each auxiliary file must then be +passed to \BibTeX. In order to do this, you need to use +\begin{definition}[\DescribeMacro{\DTLmultibibs}]% +\cs{DTLmultibibs}\marg{name list} +\end{definition} +where \meta{name list} is a comma separated list of names, +\meta{name}. For each \meta{name}, this command creates an +auxiliary file called \meta{name}".aux" (note that this +command may only be used in the preamble). + +When you want to cite an entry for a given bibliography named +in \cs{DTLmultibibs}, you must use: +\begin{definition}[\DescribeMacro{\DTLcite}]% +\cs{DTLcite}\oarg{text}\marg{mbib}\marg{cite key list} +\end{definition}\noindent +This is analogous to \cs{cite}\oarg{text}\marg{cite key list}, +but writes the \cs{citation} command to \meta{mbib}".aux" instead +of to the document's main auxiliary file. It also ensures that +the cross-referencing labels are based on \meta{mbib}, to allow +you to have the same reference in more than one bibliography +without incurring a ``multiply defined'' warning message. Note +that you can still use \cs{cite} to add citation information to +the main auxiliary file. + +If you want to add an entry to the bibliography without producing +any text, you can use +\begin{definition}[\DescribeMacro{\DTLnocite}] +\cs{DTLnocite}\marg{mbib}\marg{cite key list} +\end{definition}\noindent +which is analogous to \cs{nocite}\marg{cite key list}, where +again the citation information is written to \meta{mbib}".aux" +instead of the document's main auxiliary file. + +Note that for both \cs{DTLcite} and \cs{DTLnocite} the +\meta{mbib} part must be one of the names listed in +\cs{DTLmultibibs}. + +\begin{definition}[\DescribeMacro{\DTLloadmbbl}]% +\cs{DTLloadmbbl}\marg{mbib}\marg{db name}\marg{bib list} +\end{definition} +This is analogous to \cs{DTLloadbbl}\marg{db name}\marg{bib list} +described in \autoref{sec:loadbbl}. (Again \meta{mbib} must be +one of the names listed in \cs{DTLmultibibs}.) This creates +a new \sty{datatool} database called \meta{db name} and loads the +bibliography information from \meta{mbib}".bbl" (if it exists). + +\begin{definition}[\DescribeMacro{\DTLmbibliography}]% +\cs{DTLmbibliography}\oarg{condition}\marg{mbib}\marg{db name} +\end{definition} +This is analogous to \cs{DTLbibliography}\oarg{condition}\marg{db name}, +but is required when displaying a bibliography in which elements have +been cited using \cs{DTLcite} and \cs{DTLnocite}. + +\begin{example}{Multiple Bibliographies}{ex:multibib} +Suppose I need to create a document which contains a section listing +all my publications, but I also need to have separate sections +covering each of my research topics, with a mini-bibliography +at the end of each section. As in the earlier examples, all my +publications are stored in the file "nlct.bib" which is somewhere +on \TeX's path. Note that there will be some duplication as the +references in the mini-bibliographies will also appear in the +main bibliography at the end of the document, but using +\cs{DTLcite} and \cs{DTLmbibliography} ensures that all the +cross-referencing labels (and hyperlinks if they are enabled) +are unique. +\begin{verbatim} +\documentclass{article} +\usepackage{databib} +\DTLmultibibs{kernel,food} +\begin{document} +\section{Kernel methods} +In this section I'm going to describe some research work into +kernel methods, and in the process I'm going to cite some related +papers \DTLcite{kernel}{Cawley2007a,Cawley2006a}. + +\DTLloadmbbl{kernel}{kernelDB}{nlct} +\DTLmbibliography{kernel}{kernelDB} + +\section{Food research} + +In this section I'm going to describe some research work +in the area of food safety, and in the process, I'm going +to cite some related papers \DTLcite{food}{Peck1999,Barker1999a} + +\DTLloadmbbl{food}{foodDB}{nlct} +\DTLmbibliography{food}{foodDB} + +\cite{*} +\renewcommand{\refname}{Complete List of Publications} +\DTLloadbbl{fullDB}{nlct} +\DTLbibliography{fullDB} +\end{document} +\end{verbatim} +Notes: +\begin{enumerate} +\item This will create the files "kernel.aux" and "food.aux". +These will have to be passed to \BibTeX, in addition to the +documents main auxiliary file. So, if my document is called +"researchwork.tex", then I need to do: +\begin{verbatim} +latex researchwork +bibtex researchwork +bibtex kernel +bibtex food +latex researchwork +latex researchwork +\end{verbatim} + +\item "\cite{*}" is used to add all the entries in the bib file +to the main bibliography database. As before, \cs{DTLloadbbl} +and \cs{DTLbibliography} are used to load and display the main +bibliography. +\end{enumerate} +\end{example} + +\begin{important} +Don't try to directly input the ".bbl" file using \cs{input} (or +\cs{include}) instead of using \cs{DTLloadbbl} or \cs{DTLloadmbbl} +as these commands store the name of the required database and +initialise the database before loading the \texttt{.bbl} file. +Similarly, don't just copy the contents of the ".bbl" file into your +document without first defining the database using \ics{DTLnewdb} +and setting \ics{DTLBIBdbname} to the name of the database. +\end{important} + +\chapter{Referencing People (\sty{person} package)} +\label{sec:person} + +Sometimes when mail-merging, it may be necessary to reference a +person by their pronoun which can lead to the cumbersome and +impersonal ``he/she'' construct. The \sty{person} package +allows you to define a person by their full name, familiar name and +gender. You can then use the commands described in +\autoref{sec:refperson} to produce the appropriate pronoun. + +This can also be useful for other types of documents, such as an +order of service for a baptism or funeral. Since the +document is much the same from one person to the next, documents of +this nature are frequently simply copied and a search and replace +edit is used to change the relevant text. However this can lead to +errors (especially if the previous person's name was Mary!) With +the \sty{person} package, you need only change the definition of +the person by modifying the arguments of \cs{newperson}. + +\section{Defining and Undefining People} + +A person is defined (globally) using the command: +\begin{definition}[\DescribeMacro{\newperson}] +\cs{newperson}\oarg{label}\marg{full name}\marg{familiar name}\marg{gender} +\end{definition} +The optional argument is a unique label identifying this person, +in the event that there is more than one person. If \meta{label} +is omitted \texttt{anon} is used. (This is also the case for +subsequent commands that take an optional label.) +The gender may be any of those given by +\begin{definition}[\DescribeMacro{\malelabels}] +\cs{malelabels} +\end{definition} +or +\begin{definition}[\DescribeMacro{\femalelabels}] +\cs{femalelabels} +\end{definition} +The default definition of \cs{malelabels} is \texttt{\malelabels} +and the default definition of \cs{femalelabels} is +\texttt{\femalelabels}. You can add extra identifiers using +\begin{definition}[\DescribeMacro{\addmalelabel}] +\cs{addmalelabel}\marg{identifier} +\end{definition} +or +\begin{definition}[\DescribeMacro{\addfemalelabel}] +\cs{addfemalelabel}\marg{identifier} +\end{definition} +For example: +\begin{verbatim} +\addmalelabel{boy} +\addfemalelabel{girl} +\end{verbatim} + +The total number of defined people is given by: +\begin{definition}[\DescribeMacro{\thepeople}] +\cs{thepeople} +\end{definition} + +A person can be undefined using: +\begin{definition}[\DescribeMacro{\removeperson}] +\cs{removeperson}\oarg{label} +\end{definition} +where the person is given by \meta{label}. + +If more than one person has been defined, they can all be +removed using: +\begin{definition}[\DescribeMacro{\removeallpeople}] +\cs{removeallpeople} +\end{definition} +or you can remove a subset using: +\begin{definition}[\DescribeMacro{\removepeople}] +\cs{removepeople}\marg{list} +\end{definition} +where \meta{list} is a comma-separated list of labels. + +\section{Displaying Information} +\label{sec:refperson} + +Once a person has been defined, you can display their name using: +\begin{definition}[\DescribeMacro{\personfullname}] +\cs{personfullname}\oarg{label} +\end{definition} +where \meta{label} is the unique label used in the optional +argument to \cs{newperson}. The person's familiar name is displayed +using: +\begin{definition}[\DescribeMacro{\personname}] +\cs{personname}\oarg{label} +\end{definition} +The person's pronoun (``he'' or ``she'') is displayed using: +\begin{definition}[\DescribeMacro{\personpronoun}] +\cs{personpronoun}\oarg{label} +\end{definition} +The objective pronoun (``him'' or ``her'') is displayed using: +\begin{definition}[\DescribeMacro{\personobjpronoun}] +\cs{personobjpronoun}\oarg{label} +\end{definition} +The possessive adjective (``his'' or ``her'') is displayed using: +\begin{definition}[\DescribeMacro{\personpossadj}] +\cs{personpossadj}\oarg{label} +\end{definition} +The possessive pronoun ``his'' or ``hers'' is displayed using: +\begin{definition}[\DescribeMacro{\personposspronoun}] +\cs{personposspronoun}\oarg{label} +\end{definition} +The person's relationship to their parent (``son'' or ``daughter'') +is displayed using: +\begin{definition}[\DescribeMacro{\personchild}] +\cs{personchild}\oarg{label} +\end{definition} +The person's relationship to their child (``mother'' or ``father'') +is displayed using: +\begin{definition}[\DescribeMacro{\personparent}] +\cs{personparent}\oarg{label} +\end{definition} +The person's relationship to their sibling (``brother'' or +``sister'') is displayed using: +\begin{definition}[\DescribeMacro{\personsibling}] +\cs{personsibling}\oarg{label} +\end{definition} + +If the word occurs at the start of a sentence, you will need one +of the following commands, which are as the above, except the +first letter is converted to upper case: +\begin{definition}[\DescribeMacro{\Personpronoun}] +\cs{Personpronoun}\oarg{label} +\end{definition} +\begin{definition}[\DescribeMacro{\Personobjpronoun}] +\cs{Personobjpronoun}\oarg{label} +\end{definition} +\begin{definition}[\DescribeMacro{\Personpossadj}] +\cs{Personpossadj}\oarg{label} +\end{definition} +\begin{definition}[\DescribeMacro{\Personposspronoun}] +\cs{Personposspronoun}\oarg{label} +\end{definition} +\begin{definition}[\DescribeMacro{\Personchild}] +\cs{Personchild}\oarg{label} +\end{definition} +\begin{definition}[\DescribeMacro{\Personparent}] +\cs{Personparent}\oarg{label} +\end{definition} +\begin{definition}[\DescribeMacro{\Personsibling}] +\cs{Personsibling}\oarg{label} +\end{definition} + +\begin{example}{Order of Service (Memorial)}{ex:memorial} +This example is for a memorial order of service. + +\begin{verbatim} +\documentclass{article} + +\usepackage{person} + +\newperson{Jane Doe}{Jane}{female} + +\begin{document} +\begin{center} +\Large +In Memory of \personfullname +\end{center} + +We are gathered here to remember our \personsibling\ \personname. +\Personpronoun\ will be much missed, and \personpossadj\ +family are in our prayers. +\end{document} +\end{verbatim} + +\newperson{Jane Doe}{Jane}{female} +\begin{center} +\Large +In Memory of \personfullname +\end{center} + +We are gathered here to remember our \personsibling\ \personname. +\Personpronoun\ will be much missed, and \personpossadj\ +family are in our prayers. +\removeperson + +\end{example} + +If there is more than one person, you will need to use the +optional argument \meta{label} to \cs{newperson} to uniquely +identify each person. You can then list all of the people's full +or familiar names using: +\begin{definition}[\DescribeMacro{\peoplefullname}] +\cs{peoplefullname} +\end{definition} +\begin{definition}[\DescribeMacro{\peoplename}] +\cs{peoplename} +\end{definition} +Note that if there is only one person defined, these commands behave +the same as \cs{personfullname}\oarg{label} and +\cs{personname}[\meta{label}]. + +Similarly for the pronouns: +\begin{definition}[\DescribeMacro{\peoplepronoun}] +\cs{peoplepronoun} +\end{definition} +\begin{definition}[\DescribeMacro{\Peoplepronoun}] +\cs{Peoplepronoun} +\end{definition} +\begin{definition}[\DescribeMacro{\peopleobjpronoun}] +\cs{peopleobjpronoun} +\end{definition} +\begin{definition}[\DescribeMacro{\Peopleobjpronoun}] +\cs{Peopleobjpronoun} +\end{definition} +\begin{definition}[\DescribeMacro{\peoplepossadj}] +\cs{peoplepossadj} +\end{definition} +\begin{definition}[\DescribeMacro{\Peoplepossadj}] +\cs{Peoplepossadj} +\end{definition} +\begin{definition}[\DescribeMacro{\peopleposspronoun}] +\cs{peopleposspronoun} +\end{definition} +\begin{definition}[\DescribeMacro{\Peopleposspronoun}] +\cs{Peopleposspronoun} +\end{definition} +where, again, if only one person has been defined, each of these +commands is equivalent to +\cs{person}\ldots\oarg{label} or +\cs{Person}\ldots\oarg{label}. If more than +one person has been defined, these commands will display +they/them/their/theirs or They/Them/Their/Theirs, as appropriate. + +Likewise for relationship commands: +\begin{definition}[\DescribeMacro{\peoplechild}] +\cs{peoplechild} +\end{definition} +\begin{definition}[\DescribeMacro{\Peoplechild}] +\cs{Peoplechild} +\end{definition} +\begin{definition}[\DescribeMacro{\peopleparent}] +\cs{peopleparent} +\end{definition} +\begin{definition}[\DescribeMacro{\Peopleparent}] +\cs{Peopleparent} +\end{definition} +\begin{definition}[\DescribeMacro{\peoplesibling}] +\cs{peoplesibling} +\end{definition} +\begin{definition}[\DescribeMacro{\Peoplesibling}] +\cs{Peoplesibling} +\end{definition} + +\begin{example}{Order of Service (Baptism)}{ex:baptism} +In this example two people are defined. +\begin{verbatim} +\documentclass{article} + +\usepackage{person} + +\newperson[john]{John Joseph}{John}{male} +\newperson[jane]{Jane Mary}{Jane}{female} + +\begin{document} +\begin{center} +\Large +Baptism of \peoplefullname. +\end{center} + +Today we welcome \peoplename\ into God's family, may He guide +and protect \peopleobjpronoun. +\end{document} +\end{verbatim} + +This is produces the following text: + +\newperson[john]{John Joseph}{John}{male} +\newperson[jane]{Jane Mary}{Jane}{female} + +\begin{center} +\Large +Baptism of \peoplefullname. +\end{center} + +Today we welcome \peoplename\ into God's family, may He guide +and protect \peopleobjpronoun. +\removeallpeople +\end{example} + +\begin{example}{Mail Merging Using Appropriate Gender}{ex:personmerge} +In this example I have a CSV file called \texttt{students.csv} +containing the following: +\begin{verbatim} +FirstName,Surname,Gender,Parent,Address +John,"Smith, Jr",M,Mr and Mrs Smith,1 The Street\\Newtown +Jane,Brown,F,Ms Brown,2 The Avenue\\Oldtown +Andy,Brown,male,Mr Brown and Miss Sepia,3 The Road\\Newtown +Z\"oe,Adams,f,Mr and Mrs Adams,5 The Street\\Newtown +Roger,Brady,m,Mrs Brady,6 The Avenue\\Oldtowm +Clare,Vernon,female,Mr Vernon,7 The Close\\Anytown +\end{verbatim} +Suppose I have to write to each student's parents regarding their +child. I can load the information using \ics{DTLloaddb} (described +in \autoref{sec:loaddb}). I can then iterate through the database +and define the student as a person and use the commands defined in +the \sty{person} package to display the correct gender related text. +I could give each person a unique label based on the row count +(\ics{DTLcurrentindex}), but since I don't need to reuse the +information, I can use the default "anon" label and undefine the +person when no longer required. + +Note that in the CSV file, the gender label isn't consistent. +For some students the gender is identified by a single letter +(``m'' or ``f'') and for others the gender is identified by a +complete word (``male'' or ``female''). There's also no regard +for case. This doesn't matter to \ics{newperson} as all the +identifiers used are listed in \ics{malelabels} and +\ics{femalelabels}. + +The following is an example letter sent to all parents: +\begin{verbatim} +\documentclass{letter} +\usepackage{person} + +% load student information from file "students.csv" +\DTLloaddb{students}{students.csv} +\begin{document} +% Iterate through the student database: +\DTLforeach{students}{\FirstName=FirstName,\Surname=Surname,% +\Gender=Gender,\Parent=Parent,\Address=Address}{% +% Define "anon": + \newperson{\FirstName\space\Surname}{\FirstName}{\Gender}% +% Do the letter: + \begin{letter}{\Parent\\\Address} + \opening{Dear \Parent} + Your \personchild\ \personname\ has been awarded a + place. We look forward to seeing \personobjpronoun\ + on \personpossadj\ arrival. + \closing{Yours Sincerely} + \end{letter} +% Undefine "anon": + \removeperson +} +\end{document} +\end{verbatim} + +The body of the first letter appears as follows: +\newperson{John Smith Jr}{John}{m} +\par\vskip\baselineskip + + Your \personchild\ \personname\ has been awarded a + place. We look forward to seeing \personobjpronoun\ + on \personpossadj\ arrival. + +\removeperson +\par\vskip\baselineskip +Whereas the body of the second letter appears as follows: +\newperson{Jane Brown}{Jane}{f} +\par\vskip\baselineskip + + Your \personchild\ \personname\ has been awarded a + place. We look forward to seeing \personobjpronoun\ + on \personpossadj\ arrival. + +\removeperson +\end{example} + +\section{Advanced Commands} + +This section describes additional commands provided by the +\sty{person} package. More detail can be found in +the documented code (datatool.pdf). + +\subsection{Conditionals} + +\begin{definition}[\DescribeMacro{\ifpersonexists}] +\cs{ifpersonexists}\marg{label}\marg{true part}\marg{false part} +\end{definition} +Tests if the person identified by \meta{label} has been defined. +If true, do \meta{true part} otherwise do \meta{false part}. + +\begin{definition}[\DescribeMacro{\ifmale}] +\cs{ifmale}\marg{label}\marg{true part}\marg{false part} +\end{definition} +Test if the person identified by \meta{label} is male. +If true, do \meta{true part} otherwise do \meta{false part}. + +\begin{definition}[\DescribeMacro{\iffemale}] +\cs{iffemale}\marg{label}\marg{true part}\marg{false part} +\end{definition} +Test if the person identified by \meta{label} is female. +If true, do \meta{true part} otherwise do \meta{false part}. + +\begin{definition}[\DescribeMacro{\ifallmale}] +\cs{ifallmale}\oarg{label list}\marg{true part}\marg{false part} +\end{definition} +Tests if all the people listed in \meta{label list} are male. +If true, do \meta{true part} otherwise do \meta{false part}. +If \meta{label list} is omitted, applied to all defined people. +\begin{definition}[\DescribeMacro{\ifallfemale}] +\cs{ifallfemale}\oarg{label list}\marg{true part}\marg{false part} +\end{definition} +Likewise to test if all the people tested are female. + +To determine if a string is an allowed male label: +\begin{definition}[\DescribeMacro{\ifmalelabel}] +\cs{ifmalelabel}\marg{identifier}\marg{true part}\marg{false part} +\end{definition} +where \meta{identifier} is the string to be tested. If true, do +\meta{true part} otherwise do \meta{false part}. +For example: +\begin{verbatim} +\def\gender{M} +\ifmalelabel{\gender}{male}{not male} +\end{verbatim} +Similarly to for an allowed female label: +\begin{definition}[\DescribeMacro{\iffemalelabel}] +\cs{iffemalelabel}\marg{identifier}\marg{true part}\marg{false part} +\end{definition} +For example: +\begin{verbatim} +\ifmalelabel{\gender}{Male}{% + \iffemalelabel{\gender}{Female}% + {Undefined Gender}% +} +\end{verbatim} + +\subsection{Iterating Through Defined People} + +You can iterate through all defined people using: +\begin{definition}[\DescribeMacro{\foreachperson}] +\cs{foreachperson}(\meta{name cs},\meta{full name cs},\meta{gender cs},\meta{label cs})\cs{do}\marg{body} +\end{definition} +At each iteration, \meta{name cs}, \meta{full name cs}, +\meta{gender cs} and \meta{label cs} are set to the current person's +name, full name, gender and label, respectively. (These arguments +must all be command names.) Note that the gender is set to +the definition of \DescribeMacro{\malename}\cs{malename} or +\DescribeMacro{\femalename}\cs{femalename}, as appropriate.\footnote{Predefined names provided by the \sty{person} package are described +in the documented code (datatool.pdf).} Once these +commands are set, \meta{body} is applied. + +If you only want to iterate through a subset of defined people, +you can use: +\begin{definition} +\cs{foreachperson}(\meta{name cs},\meta{full name cs},\meta{gender cs},\meta{label cs})\cs{in}\marg{list}\cs{do}\marg{body} +\end{definition} +where \meta{list} is a comma-separated list of labels. + +\subsection{Accessing Individual Information} + +\begin{definition}[\DescribeMacro{\getpersongender}] +\cs{getpersongender}\marg{cs}\marg{label} +\end{definition} +Gets the gender of the person identified by \meta{label} and +stores in \meta{cs} (which must be a command name). This +sets \meta{cs} to the definition of \ics{malename} or +\ics{femalename} as appropriate. + +\begin{definition}[\DescribeMacro{\getpersonname}] +\cs{getpersonname}\marg{cs}\marg{label} +\end{definition} +Gets the name of the person identified by \meta{label} and +stores in \meta{cs} (which must be a command name). + +\begin{definition}[\DescribeMacro{\getpersonfullname}] +\cs{getpersonfullname}\marg{cs}\marg{label} +\end{definition} +Gets the full name of the person identified by \meta{label} and +stores in \meta{cs} (which must be a command name). + +\clearpage +\phantomsection +\addcontentsline{toc}{chapter}{\bibname} +\DTLbibliography{docbib} + +\clearpage +\phantomsection +\addcontentsline{toc}{chapter}{Acknowledgements} +\chapter*{Acknowledgements} + +Many thanks to Morten~H\o gholm for suggesting a much more +efficient way of storing the information in databases which +has significantly improved the time it takes to \LaTeX\ documents +containing large databases. + +\clearpage +\phantomsection +\addcontentsline{toc}{chapter}{Index}\PrintIndex + +\end{document} diff --git a/Master/texmf-dist/doc/latex/datatool/datatool.pdf b/Master/texmf-dist/doc/latex/datatool/datatool.pdf Binary files differindex 61220a750bb..bd25ebec2ea 100644 --- a/Master/texmf-dist/doc/latex/datatool/datatool.pdf +++ b/Master/texmf-dist/doc/latex/datatool/datatool.pdf diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-barchart.pdf b/Master/texmf-dist/doc/latex/datatool/samples/sample-barchart.pdf Binary files differnew file mode 100644 index 00000000000..89ea8bf27c2 --- /dev/null +++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-barchart.pdf diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-barchart.tex b/Master/texmf-dist/doc/latex/datatool/samples/sample-barchart.tex new file mode 100644 index 00000000000..142f1eeb810 --- /dev/null +++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-barchart.tex @@ -0,0 +1,57 @@ + % This file is public domain. +\documentclass[captions=tableheading]{scrartcl} + +\usepackage{tikz} +\usetikzlibrary{snakes} + +\usepackage{databar} + +\DTLloaddb{marks}{sample-student-records.csv} + +\begin{document} + +% Compute average mark for each student: +\DTLforeach{marks}{% +\assignI=Assignment 1,% +\assignII=Assignment 2,% +\assignIII=Assignment 3}{% +\DTLmeanforall{\theMean}{\assignI,\assignII,\assignIII}% +\DTLround{\theMean}{\theMean}{0}\DTLclip{\theMean}{\theMean}% +\DTLappendtorow{Average}{\theMean}} + +\begin{table} +\caption{Student Marks} + \centering +\DTLdisplaydb[Address,RegNum,Title]{marks} +\end{table} + +\begin{figure}[htbp] + \centering + % compute the overall mean + \DTLmeanforkeys{marks}{Average}{\overallmean} + % round it to 2 decimal places + \DTLround{\overallmean}{\overallmean}{2} + % draw a grey dotted line indicating the overall mean + % covering the entire width of the bar chart + \renewcommand*{\DTLbaratendtikz}{% + \draw[lightgray,loosely dotted] (0,\overallmean) -- + (\DTLbarchartwidth,\overallmean) + node[right,black]{Average (\overallmean)};} + % Set the lower bar labels to draw a brace across the current + % group, along with the student's name and average score + \renewcommand*{\DTLdisplaylowerbarlabel}[1]{% + \tikz[baseline=(current bounding box.center)]{ + \draw[snake=brace,rotate=-90](0,0) -- (\DTLbargroupwidth,0);} + \DTLround{\theMean}{\theMean}{2}% + \shortstack{#1\\(Average: \theMean)}} + % draw the bar chart + \DTLmultibarchart{variables={\assignI,\assignII,\assignIII}, + barwidth=10pt,uppermultibarlabels={\assignI,\assignII,\assignIII}, + barlabel={\firstname\ \surname}}{marks} + {\surname=Surname,\firstname=First Name,\assignI=Assignment 1,% + \assignII=Assignment 2,\assignIII=Assignment 3,\theMean=Average} + \caption{Student marks} +\end{figure} + + +\end{document} diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-mail-merge.pdf b/Master/texmf-dist/doc/latex/datatool/samples/sample-mail-merge.pdf Binary files differnew file mode 100644 index 00000000000..73fb2f1c83e --- /dev/null +++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-mail-merge.pdf diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-mail-merge.tex b/Master/texmf-dist/doc/latex/datatool/samples/sample-mail-merge.tex new file mode 100644 index 00000000000..384584e540e --- /dev/null +++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-mail-merge.tex @@ -0,0 +1,21 @@ + % This file is public domain. +\documentclass{scrlttr2} + +\usepackage{datatool} + +\DTLloaddb{data}{sample-student-records.csv} + +\begin{document} +\begin{DTLenvforeach*}{data}{\Title=Title,\FirstName=First Name,\Surname=Surname,\AssignmentI=Assignment 1,\AssignmentII=Assignment 2,\AssignmentIII=Assignment 3,\Address=Address} +\begin{letter}{\Title\space\FirstName\space\Surname\\\Address} +\opening{Dear \Title~\Surname} + +\DTLmeanforall{\Score}{\AssignmentI,\AssignmentII,\AssignmentIII} +\DTLround{\Score}{\Score}{0}\DTLclip{\Score}{\Score}% +You were awarded a mark of \Score\%. + +\closing{Yours Sincerely} +\end{letter} + +\end{DTLenvforeach*} +\end{document} diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-piechart.pdf b/Master/texmf-dist/doc/latex/datatool/samples/sample-piechart.pdf Binary files differnew file mode 100644 index 00000000000..43d1a30f341 --- /dev/null +++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-piechart.pdf diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-piechart.tex b/Master/texmf-dist/doc/latex/datatool/samples/sample-piechart.tex new file mode 100644 index 00000000000..2bcd49dcf61 --- /dev/null +++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-piechart.tex @@ -0,0 +1,36 @@ + % This file is public domain. +\documentclass[captions=tableheading]{scrartcl} + +\usepackage{datapie} + +\DTLloaddb{marks}{sample-student-records.csv} + +\begin{document} + +% Compute average mark for each student: +\DTLforeach{marks}{% +\assignI=Assignment 1,% +\assignII=Assignment 2,% +\assignIII=Assignment 3}{% +\DTLmeanforall{\theMean}{\assignI,\assignII,\assignIII}% +\DTLround{\theMean}{\theMean}{0}\DTLclip{\theMean}{\theMean}% +\DTLappendtorow{Average}{\theMean}} + +% Sort according to average mark +\DTLsort{Average=descending}{marks} + +\begin{table} +\caption{Student Marks} +\centering +\DTLdisplaydb[Address,RegNum,Title]{marks} +\end{table} + +\begin{figure} +\caption{Pie Chart} +\centering +\DTLpiechart{variable=\Average,outerlabel={\Surname, \FirstName},rotateouter}{marks}% + {\Average=Average,\Surname=Surname,\FirstName=First +Name} +\end{figure} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-student-records.csv b/Master/texmf-dist/doc/latex/datatool/samples/sample-student-records.csv new file mode 100644 index 00000000000..b8d212d4885 --- /dev/null +++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-student-records.csv @@ -0,0 +1,7 @@ +"Title","First Name","Surname","RegNum","Assignment 1","Assignment 2","Assignment 3","Address" +"Miss","Jane","Brown",1234567891,75,84,80,"Flat 1a\\The Street\\The Town" +"Mr","John","Smith, Jr",1234567892,68,57,72,"Flat 1b\\The Street\\The Town" +"Mr","Zack","Watts",1234567893,32,43,49,"Flat 1c\\The Street\\The Town" +"Mrs","Hillary","Rix",1234567894,87,88,86,"Flat 1d\\The Street\\The Town" +"Miss","Z\""oe","Adams",1234567895,52,48,57,"Flat 1e\\The Street\\The Town" +"Mr","Andy","Brown",1234567896,42,52,54,"Flat 1f\\The Street\\The Town" diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-student-scores.pdf b/Master/texmf-dist/doc/latex/datatool/samples/sample-student-scores.pdf Binary files differnew file mode 100644 index 00000000000..1abee68d126 --- /dev/null +++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-student-scores.pdf diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-student-scores.tex b/Master/texmf-dist/doc/latex/datatool/samples/sample-student-scores.tex new file mode 100644 index 00000000000..ff61d4dbbff --- /dev/null +++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-student-scores.tex @@ -0,0 +1,34 @@ + % This file is public domain. +\documentclass[captions=tableheading]{scrartcl} + +\usepackage{datatool} +\usepackage{longtable} + +\DTLloaddb{scores}{sample-student-records.csv} + +\begin{document} +Sort by surname, then first name: +\DTLsort{Surname,First Name}{scores} + +% omit Address column +\DTLdisplaydb[Address]{scores} + +Sort by assignment 1 score in descending order: +\DTLsort{Assignment 1=descending}{scores} + +% omit Address column +\DTLdisplaydb[Address]{scores} + +Average score: +\DTLmeanforcolumn{scores}{Assignment 1}{\averagescore}% +\averagescore\%. +Rounded to two decimal places: \DTLround{\averagescore}{\averagescore}{2}% +\averagescore\%. + +A long list will require the longtable environment (supplied by +longtable.sty). Example in Table~\ref{tab:records}. + +% Omit RegNum and Address columns +\DTLdisplaylongdb[caption={Student Scores},label={tab:records},omit={RegNum,Address}]{scores} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-two-per-row.pdf b/Master/texmf-dist/doc/latex/datatool/samples/sample-two-per-row.pdf Binary files differnew file mode 100644 index 00000000000..17676a1093f --- /dev/null +++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-two-per-row.pdf diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-two-per-row.tex b/Master/texmf-dist/doc/latex/datatool/samples/sample-two-per-row.tex new file mode 100644 index 00000000000..c8f266d739a --- /dev/null +++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-two-per-row.tex @@ -0,0 +1,55 @@ + % This file is public domain. +\documentclass[captions=tableheading]{scrartcl} + +\usepackage{datatool} + +\DTLloaddb{scores}{sample-student-records.csv} +% Sort by surname then first name +\DTLsort{Surname,First Name}{scores} + +\begin{document} + +\begin{table}[htbp] + \caption{Two database rows per tabular row} + \centering + \begin{tabular}{llcllc} + \bfseries First Name & + \bfseries Surname & + \bfseries Assignment 1 (\%) & + \bfseries First Name & + \bfseries Surname & + \bfseries Assignment 1 (\%)% + \DTLforeach*{scores}{\firstname=First Name,\surname=Surname,\score=Assignment 1}{% + \DTLifoddrow{\\}{&}% + \firstname & \surname & \score}% + \end{tabular} +\end{table} + +\begin{table}[htbp] + \caption{Two database rows per tabular row (column-wise)} + \centering + % store half number of rows + \edef\maxrows{\DTLrowcount{scores}}% + \DTLdiv{\halfrowidx}{\maxrows}{2} + \begin{tabular}{llcllc} + \bfseries First Name & + \bfseries Surname & + \bfseries Assignment 1 (\%) & + \bfseries First Name & + \bfseries Surname & + \bfseries Assignment 1 (\%)% + \DTLforeach*[\value{DTLrowi}<\halfrowidx]{scores}% + {\firstname=First Name,\surname=Surname,\score=Assignment 1}% + {% + \\% + \firstname & \surname & \score + & + \edef\currentrowidx{\arabic{DTLrowi}}% + \DTLadd{\rowidxII}{\halfrowidx}{\currentrowidx}% + \DTLassign{scores}{\rowidxII}{\firstnameII=First Name,\surnameII=Surname,\scoreII=Assignment 1}% + \firstnameII & \surnameII & \scoreII + }% + \end{tabular} +\end{table} + +\end{document} diff --git a/Master/texmf-dist/source/latex/datatool/datatool.dtx b/Master/texmf-dist/source/latex/datatool/datatool.dtx index fcae77779b6..48dbc515cb4 100644 --- a/Master/texmf-dist/source/latex/datatool/datatool.dtx +++ b/Master/texmf-dist/source/latex/datatool/datatool.dtx @@ -1,22 +1,22 @@ %\iffalse % datatool.dtx generated using makedtx version 0.94b (c) Nicola Talbot % Command line args: -% -macrocode "databib.bst" -% -src "datatool\.sty\Z=>datatool.sty" -% -src "datapie\.sty\Z=>datapie.sty" -% -src "dataplot\.sty\Z=>dataplot.sty" -% -src "databar\.sty\Z=>databar.sty" -% -src "databib\.sty\Z=>databib.sty" -% -src "databib\.bst\Z=>databib.bst" -% -src "person\.sty\Z=>person.sty" -% -author "Nicola Talbot" -% -dir "source" -% -setambles ".*\.bst=>\nopreamble\usepreamble\defaultpreamble\nopostamble" -% -comment "databib.bst" +% -macrocode "databib\.bst" +% -src "datatool-base.sty\Z=>datatool-base.sty" +% -src "datatool-fp.sty\Z=>datatool-fp.sty" +% -src "datatool-pgfmath.sty\Z=>datatool-pgfmath.sty" +% -src "datatool.sty\Z=>datatool.sty" +% -src "databib.sty\Z=>databib.sty" +% -src "databar.sty\Z=>databar.sty" +% -src "datapie.sty\Z=>datapie.sty" +% -src "dataplot.sty\Z=>dataplot.sty" +% -src "person.sty\Z=>person.sty" +% -src "databib.bst\Z=>databib.bst" % -doc "datatool-manual.tex" -% -codetitle "datatool.sty" +% -author "Nicola Talbot" +% -codetitle "" % datatool -% Created on 2009/11/15 15:10 +% Created on 2012/7/19 16:34 %\fi %\iffalse %<*package> @@ -39,139 +39,35 @@ %\fi % \iffalse % Doc-Source file to use with LaTeX2e -% Copyright (C) 2009 Nicola Talbot, all rights reserved. +% Copyright (C) 2012 Nicola Talbot, all rights reserved. % \fi % \iffalse %<*driver> -\documentclass[a4paper]{ltxdoc} -\usepackage{dox} -\usepackage{ifthen} -\usepackage[verbose=false]{datatool} -\usepackage{datapie,databar,databib,person} -\usepackage{textcomp} -\usepackage{graphicx} -\usepackage{colortbl} -\usepackage{cmap} -\usepackage[T1]{fontenc} +\documentclass[report]{nlctdoc} + +\iffalse +datatool-manual.tex is a stub file used by makedtx to create +datatool.dtx +\fi + +\usepackage{datatool} \usepackage[utf8]{inputenc} -\usepackage{caption} +\usepackage[T1]{fontenc} \usepackage[colorlinks, bookmarks, hyperindex=false, - pdfauthor={Nicola L.C. Talbot}, + pdfauthor={Nicola L. C. Talbot}, pdftitle={datatool: Databases and data manipulation}, pdfkeywords={LaTeX,package,database,data,chart,plot}]{hyperref} -\usetikzlibrary{snakes} - %hyperindex conflicts with doc - %(end up with |usage|hyperpage in indexentry) - %This unfortunately means that the changes section doesn't - %have active links, but at least it will keep makeindex happy. +\doxitem{Counter}{counter}{counters} +\doxitem{Option}{option}{package options} -\renewcommand{\usage}[1]{\textit{\hyperpage{#1}}} -\renewcommand{\main}[1]{\hyperpage{#1}} -\newcommand{\see}[2]{\emph{see} #1} -\makeatletter -\def\index@prologue{\section*{Index}} +\CheckSum{16856} - % commands are too wide for a 3 column index - \def\theindex{\@restonecoltrue\if@twocolumn\@restonecolfalse\fi - \columnseprule \z@ \columnsep 35\p@ - \twocolumn[\index@prologue]% - \IndexParms \let\item\@idxitem \ignorespaces} - \def\endtheindex{\if@restonecol\onecolumn\else\clearpage\fi} -\makeatother \RecordChanges \PageIndex -\CheckSum{16375} - -\newcommand*{\sty}[1]{\textsf{#1}} -\newcommand*{\env}[1]{\textsf{#1}} -\newcommand*{\ext}[1]{\texttt{#1}} -\definecolor{defbackground}{rgb}{0.8,1,1} - -\makeatletter -\newcommand*{\setting}[2]{\textsf{#2}\relax -\@for\thiscmd:=#1\do{% -\edef\doindex{\noexpand\index -{\thiscmd\space settings=\noexpand\cs{\thiscmd} settings>#2=\noexpand -\textsf{#2}|hyperpage}}\doindex -}} -\makeatother - -\newsavebox\defsbox -\newlength\defwidth -\newenvironment{definition}[1][]{% -\def\defarg{#1}% -\setlength{\fboxsep}{4pt}\setlength{\fboxrule}{1.25pt}% -\begin{lrbox}{\defsbox}% -\setlength\defwidth\linewidth -\addtolength\defwidth{-2\fboxrule}% -\addtolength\defwidth{-2\fboxsep}% -\begin{minipage}{\defwidth}\flushleft -}{% -\end{minipage} -\end{lrbox}% -\vskip10pt -\noindent -\defarg\fcolorbox{black}{defbackground}{\usebox\defsbox}% -\vskip10pt -\noindent -\ignorespacesafterend -} - -\newlength\tmplength -\newcommand{\importantpar}{\relax -\settowidth{\hangindent}{\bfseries\Huge$\bigtriangleup$\space}\relax -\settoheight{\tmplength}{\bfseries\Huge$\bigtriangleup$}\relax -\addtolength{\tmplength}{-0.5\baselineskip}\relax -\hskip-\hangindent -\smash{\raisebox{-\tmplength}{\bfseries -\raisebox{3pt}{\large!}$\!$\makebox[0pt]{\Huge$\bigtriangleup$}\relax -}}\relax -\hskip0.5\hangindent -\hangafter=-2\relax -} - -\doxitem{Counter}{counter}{counters} - -\newcommand*{\ctrfmt}[1]{\texttt{#1}} -\newcommand*{\ctr}[1]{\ctrfmt{#1}\SpecialMainCounterIndex{#1}} -\newcommand*{\desctr}[1]{\ctrfmt{#1}\DescribeCounter{#1}} - -\newcommand*{\ics}[1]{\cs{#1}\SpecialMainIndex{#1}} - -\newcommand*{\pkgopt}[2][datatool]{\textsf{#2}\index -{#1 package options=\textsf{#1} package options>#2=\textsf{#2}|hyperpage}} - -\newcommand*{\cmdopt}[2]{\textsf{#2}\index{#1 options=\cs{#1} -options>#2=\textsf{#2}|hyperpage}} - -\newcounter{example} -\newcommand*{\examplename}{example} -\makeatletter -\newenvironment{example}[2]{\refstepcounter{example}\label{#2}% -\par\vskip10pt\noindent -\textbf{\large Example \theexample\ (#1)}% -\addcontentsline{loe}{section}{\protect\numberline{\theexample}#1}% -\nopagebreak\par\vskip10pt\nopagebreak -}% -{\begin{center}\rule{2in}{1pt}\end{center}} - -\newcommand*{\listofexamples}{\section*{List of Examples}% -\@starttoc{loe}} -\makeatother - - %bibliography database -\DTLnewdb{docbib} -\DTLnewrow{docbib} -\DTLnewdbentry{docbib}{CiteKey}{Goossens} -\DTLnewdbentry{docbib}{EntryType}{book} -\DTLnewdbentry{docbib}{Author}{{}{Goossens}{}{Michel},{}{Mittelbach}{}{Frank},{}{Samarin}{}{Alexander}} -\DTLnewdbentry{docbib}{Title}{The \LaTeX\ Companion} -\DTLnewdbentry{docbib}{Publisher}{Addison-Wesley} -\DTLnewdbentry{docbib}{Year}{1994} - +\setcounter{IndexColumns}{2} \begin{document} \DocInput{datatool.dtx} @@ -179,7922 +75,490 @@ options>#2=\textsf{#2}|hyperpage}} %</driver> %\fi %\MakeShortVerb{"} -%\DeleteShortVerb{\|} % -% \title{datatool v 2.03: Databases and data manipulation} -% \author{Nicola L.C. Talbot\\[10pt] +%\title{Documented Code for datatool v2.10} +%\author{Nicola L. C. Talbot\\[10pt] %School of Computing Sciences\\ %University of East Anglia\\ %Norwich. Norfolk\\ -%NR4 7TJ. United Kingdom.\\ +%NR4 7TJ. United Kingdom\\ %\url{http://theoval.cmp.uea.ac.uk/~nlct/}} % -% \date{15th November 2009} -% \maketitle -% -%\pdfbookmark[1]{Contents}{contents} -%\tableofcontents -%\pdfbookmark[1]{List of Examples}{examples} -%\listofexamples -%\pdfbookmark[1]{List of Figures}{figures} -%\listoffigures -%\pdfbookmark[1]{List of Tables}{tables} -%\listoftables -% -% \section{Introduction} -% -% \changes{1.0}{2007 July 22}{Initial version} -%The \sty{datatool} bundle consists of the following -%packages: \sty{datatool}, \sty{datapie}, \sty{dataplot}, -%\sty{databar} and \sty{databib}. -% -%The \sty{datatool} package can be used to: -%\begin{itemize} -%\item Create or load databases. -%\item Sort rows of a database (either numerically or alphabetically, -%ascending or descending). -%\item Perform repetitive operations on each row of a database -%(e.g.\ mail merging). Conditions may be imposed to exclude rows. -%\item Determine whether an argument is an integer, a real number, -%currency or a string. (Scientific notation is currently not -%supported.) Locale dependent number settings are supported (such -%as a comma as a decimal character and a full stop as a number -%group character). -%\item Convert locale dependent numbers/currency to the decimal -%format required by the \sty{fp} package, enabling fixed point -%arithmetic to be performed on elements of the database. -%\item Names can be converted to initials. -%\item Strings can be tested to determine if they are all -%upper or lower case. -%\item String comparisons (both case sensitive and case insensitive) -%can be performed. -%\end{itemize} -% -%The \sty{datapie} package can be used to convert a database into -%a pie chart: -%\begin{itemize} -%\item Segments can be separated from the rest of the chart to make -%them stand out. -%\item Colour/grey scale options. -%\item Predefined segment colours can be changed. -%\item Hooks provided to add extra information to the chart -%\end{itemize} -% -%The \sty{databar} package can be used to convert a database into -%a bar chart: -%\begin{itemize} -%\item Colour/grey scale options. -%\item Predefined bar colours can be changed. -%\item Hooks provided to add extra information to the chart -%\end{itemize} -% -%(The \sty{datapie} and \sty{databar} packages do not support the -%creation of 3D charts, and I have no plans to implement them at any -%later date. The use of 3D charts should be discouraged. They may look -%pretty, but the purpose of a chart is to be informative. Three -%dimensional graphics cause distortion, which can result in misleading -%impressions. The \sty{pgf} manual provides a more in-depth -%discussion on the matter.) -% -%The \sty{dataplot} package can be used to convert a database into -%a two dimensional plot using markers and/or lines. Three dimensional -%plots are currently not supported. -% -%The \sty{databib} package can be used to convert a \BibTeX\ database -%into a \sty{datatool} database. -% -%\section{Data Types} -%\label{sec:datatypes} -% -%The \sty{datatool} package recognises four data types: integers, -%real numbers, currency and strings. -% -%\begin{description} -%\item[Integers] An integer is a sequence of digits, optionally -%groups of three digits may be separated by the number group character. -%The default number group character is a comma (,) but may be -%changed using \cs{DTLsetnumberchars} (see below). -% -%\item[Real Numbers] A real number is an integer followed by the -%decimal character followed by one or more digits. The decimal -%character is a full stop (.) by default. The number group -%and decimal characters may be changed using -%\begin{definition}[\DescribeMacro{\DTLsetnumberchars}]% -%\cs{DTLsetnumberchars}\marg{number group character}\marg{decimal character} -%\end{definition} -%Note that scientific notation is not supported, and the number group -%character may not be used after the decimal character. -% -%\item[Currency] A currency symbol followed by an integer or -%real number is considered to be the currency data type. -%There are two predefined currency symbols, "\$" and \cs{pounds}. -%In addition, if any of the following commands are defined at the -%start of the document, they are also considered to be a currency -%symbol: \cs{texteuro}, \cs{textdollar}, \cs{textstirling}, -%\cs{textyen}, \cs{textwon}, \cs{textcurrency}, \cs{euro} -%and \cs{yen}. Additional currency symbols can be defined using -%\begin{definition}[\DescribeMacro{\DTLnewcurrencysymbol}]% -%\cs{DTLnewcurrencysymbol}\marg{symbol} -%\end{definition} -% -%\item[Strings] Anything that doesn't belong to the above three -%types is considered to be a string. -% -%\end{description} -% -%\subsection{Conditionals} -%\label{sec:ifconditions} -% -%The following conditionals are provided by the \sty{datatool} -%package: -%\begin{definition}[\DescribeMacro{\DTLifint}]% -%\cs{DTLifint}\marg{text}\marg{true part}\marg{false part} -%\end{definition} -%If \meta{text} is an integer then do \meta{true part}, otherwise -%do \meta{false part}. For example -%\begin{verbatim} -%\DTLifint{2536}{integer}{not an integer} -%\end{verbatim} -%produces: -%\DTLifint{2536}{integer}{not an integer}. -% -%The number group character may appear in the number, for example: -%\begin{verbatim} -%\DTLifint{2,536}{integer}{not an integer} -%\end{verbatim} -%produces: -%\DTLifint{2,536}{integer}{not an integer}. -%However, the number group character may only be followed by a group -%of three digits. For example: -%\begin{verbatim} -%\DTLifint{2,5,3,6}{integer}{not an integer} -%\end{verbatim} -%produces: -%\DTLifint{2,5,3,6}{integer}{not an integer}. -%The number group character may be changed. For example: -%\begin{verbatim} -%\DTLsetnumberchars{.}{,}% -%\DTLifint{2,536}{integer}{not an integer} -%\end{verbatim} -%this now produces: -%\DTLsetnumberchars{.}{,}\relax -%\DTLifint{2,536}{integer}{not an integer}, since 2,536 is now -%a real number. -% -%Note that nothing else can be appended or prepended to the -%number. For example: -%\begin{verbatim} -%\DTLsetnumberchars{,}{.}% -%\DTLifint{2,536m}{integer}{not an integer} -%\end{verbatim} -%produces: -%\DTLsetnumberchars{,}{.}\relax -%\DTLifint{2,536m}{integer}{not an integer}. -% -%\begin{definition}[\DescribeMacro{\DTLifreal}]% -%\cs{DTLifreal}\marg{text}\marg{true part}\marg{false part} -%\end{definition} -%If \meta{text} is a real number then do \meta{true part}, otherwise -%do \meta{false part}. For example -%\begin{verbatim} -%\DTLifreal{1000.0}{real}{not real} -%\end{verbatim} -%produces: -%\DTLifreal{1000.0}{real}{not real}. -% -%Note that an integer is not a real number: -%\begin{verbatim} -%\DTLifreal{1,000}{real}{not real} -%\end{verbatim} -%produces: -%\DTLifreal{1,000}{real}{not real}. -% -%Whereas -%\begin{verbatim} -%\DTLifreal{1,000.0}{real}{not real} -%\end{verbatim} -%produces: -%\DTLifreal{1,000.0}{real}{not real}. -% -%However -%\begin{verbatim} -%\DTLsetnumberchars{.}{,}% -%\DTLifreal{1,000}{real}{not real} -%\end{verbatim} -%produces: -%\DTLsetnumberchars{.}{,}\relax -%\DTLifreal{1,000}{real}{not real} since the comma is now -%the decimal character. -% -%Currency is not considered to be real: -%\begin{verbatim} -%\DTLsetnumberchars{,}{.}% -%\DTLifreal{\$1.00}{real}{not real} -%\end{verbatim} -%produces: -%\DTLsetnumberchars{,}{.}\relax -%\DTLifreal{\$1.00}{real}{not real}. -% -%\begin{definition}[\DescribeMacro{\DTLifcurrency}]% -%\cs{DTLifcurrency}\marg{text}\marg{true part}\marg{false part} -%\end{definition} -%If \meta{text} is currency, then do \meta{true part}, otherwise -%do false part. For example: -%\begin{verbatim} -%\DTLifcurrency{\$5.99}{currency}{not currency} -%\end{verbatim} -%produces: -%\DTLifcurrency{\$5.99}{currency}{not currency}. Similarly: -%\begin{verbatim} -%\DTLifcurrency{\pounds5.99}{currency}{not currency} -%\end{verbatim} -%produces: -%\DTLifcurrency{\pounds5.99}{currency}{not currency}. -%Note, however, that -%\begin{verbatim} -%\DTLifcurrency{US\$5.99}{currency}{not currency} -%\end{verbatim} -%produces: -%\DTLifcurrency{US\$5.99}{currency}{not currency}. If you want -%this to be considered currency, you will have to add the -%sequence "US\$" to the set of currency symbols: -%\begin{verbatim} -%\DTLnewcurrencysymbol{US\$}% -%\DTLifcurrency{US\$5.99}{currency}{not currency} -%\end{verbatim} -%this now produces: -%\DTLnewcurrencysymbol{US\$}\relax -%\DTLifcurrency{US\$5.99}{currency}{not currency}. -% -%This document has used the \sty{textcomp} package which defines -%\cs{texteuro}, so this is also considered to be currency. For -%example: -%\begin{verbatim} -%\DTLifcurrency{\texteuro5.99}{currency}{not currency} -%\end{verbatim} -%produces: -%\DTLifcurrency{\texteuro5.99}{currency}{not currency}. -% -%The preferred method is to display the euro symbol in a sans-serif -%font, but -%\begin{verbatim} -%\DTLifcurrency{\textsf{\texteuro}5.99}{currency}{not currency} -%\end{verbatim} -%will produce: -%\DTLifcurrency{\textsf{\texteuro}5.99}{currency}{not currency}. -% -%It is better to define a new command, for example: -%\begin{verbatim} -%\DeclareRobustCommand*{\euro}{\textsf{\texteuro}} -%\end{verbatim} -%and add that command to the list of currency symbols. In fact, -%in this case, if you define the command \cs{euro} in the -%preamble, it will automatically be added to the list of known -%currency symbols. If however you define \cs{euro} in the document, -%you will have to add it using \ics{DTLnewcurrencysymbol}. For -%example: -%\begin{verbatim} -%\newcommand*{\euro}{\textsf{\texteuro}}% -%\DTLnewcurrencysymbol{\euro}% -%\DTLifcurrency{\euro5.99}{currency}{not currency} -%\end{verbatim} -%produces: -%\DeclareRobustCommand*{\euro}{\textsf{\texteuro}}\relax -%\DTLnewcurrencysymbol{\euro}\relax -%\DTLifcurrency{\euro5.99}{currency}{not currency}. -% -%\begin{definition}[\DescribeMacro{\DTLifcurrencyunit}]% -%\cs{DTLifcurrencyunit}\marg{text}\marg{symbol}\marg{true part}\marg{false part} -%\end{definition} -%If \meta{text} is currency, and uses \meta{symbol} as the unit of -%currency, then do \meta{true part} otherwise do \meta{false part}. -%For example: -%\begin{verbatim} -%\DTLifcurrencyunit{\$6.99}{\$}{dollars}{not dollars} -%\end{verbatim} -%produces: -%\DTLifcurrencyunit{\$6.99}{\$}{dollars}{not dollars}. -%Another example: -%\begin{verbatim} -%\def\cost{\euro10.50}% -%\DTLifcurrencyunit{\cost}{\euro}{euros}{not euros} -%\end{verbatim} -%produces: -%\def\cost{\euro10.50}\relax -%\DTLifcurrencyunit{\cost}{\euro}{euros}{not euros}. -% -%\begin{definition}[\DescribeMacro{\DTLifnumerical}]% -%\cs{DTLifnumerical}\marg{text}\marg{true part}\marg{false part} -%\end{definition} -%If \meta{text} is numerical (either an integer, real number or -%currency) then do \meta{true part} otherwise do -%\meta{false part}. -%For example: -%\begin{verbatim} -%\DTLifnumerical{1,000.0}{number}{string}. -%\end{verbatim} -%produces: \DTLifnumerical{1,000.0}{number}{string}. -%Whereas -%\begin{verbatim} -%\DTLsetnumberchars{.}{,}% -%\DTLifnumerical{1,000.0}{number}{string}. -%\end{verbatim} -%produces: -%\DTLsetnumberchars{.}{,}\relax -%\DTLifnumerical{1,000.0}{number}{string}. -%Since the number group character is now a full stop, and the -%decimal character is now a comma. (The number group character -%may only appear before the decimal character, not after it.) -% -%Currency is also considered to be numerical: -%\begin{verbatim} -%\DTLsetnumberchars{,}{.}% -%\DTLifnumerical{\$1,000.0}{number}{string}. -%\end{verbatim} -%produces: -%\DTLsetnumberchars{,}{.}\relax -%\DTLifnumerical{\$1,000.0}{number}{string}. -% -%\begin{definition}[\DescribeMacro{\DTLifstring}]% -%\cs{DTLifstring}\marg{text}\marg{true part}\marg{false part} -%\end{definition} -%This is the opposite of \cs{DTLifnumerical}. If \meta{text} is -%not numerical, do \meta{true part}, otherwise do \meta{false part}. -% -%\begin{definition}[\DescribeMacro{\DTLifcasedatatype}]% -%\cs{DTLifcasedatatype}\marg{text}\marg{string case}\marg{int case}\marg{real case}\marg{currency case} -%\end{definition} -%If \meta{text} is a string do \meta{string case}, if \meta{text} -%is an integer do \meta{int case}, if \meta{text} is a real number -%do \meta{real case}, if \meta{text} is currency do -%\meta{currency case}. For example: -%\begin{verbatim} -%\DTLifcasedatatype{1,000}{string}{integer}{real}{currency} -%\end{verbatim} -%produces: -%\DTLifcasedatatype{1,000}{string}{integer}{real}{currency}. -% -%\begin{definition}[\DescribeMacro{\DTLifnumeq}]% -%\cs{DTLifnumeq}\marg{num1}\marg{num2}\marg{true part}\marg{false part} -%\end{definition} -%If \meta{num1} is equal to \meta{num2}, then do \meta{true part}, -%otherwise do \meta{false part}. Note that both \meta{num1} and -%\meta{num2} must be numerical (either integers, real numbers or -%currency). The currency symbol is ignored when determining -%equality. For example -%\begin{verbatim} -%\DTLifnumeq{\pounds10.50}{10.5}{true}{false} -%\end{verbatim} -%produces: -%\DTLifnumeq{\pounds10.50}{10.5}{true}{false}, since they are -%considered to be numerically equivalent. Likewise: -%\begin{verbatim} -%\DTLifnumeq{\pounds10.50}{\$10.50}{true}{false} -%\end{verbatim} -%produces: -%\DTLifnumeq{\pounds10.50}{\$10.50}{true}{false}. -% -%\begin{definition}[\DescribeMacro{\DTLifstringeq}]% -%\cs{DTLifstringeq}\marg{string1}\marg{string2}\marg{true part}\marg{false part} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLifstringeq*}]% -%\cs{DTLifstringeq*}\marg{string1}\marg{string2}\marg{true part}\marg{false part} -%\end{definition} -%If \meta{string1} and \meta{string2} are the same, then do -%\meta{true part}, otherwise do \meta{false part}. The starred -%version ignores the case, the unstarred version is case -%sensitive. Both -%\meta{string1} and \meta{string2} are considered to be strings, -%so for example: -%\begin{verbatim} -%\DTLifstringeq{10.50}{10.5}{true}{false} -%\end{verbatim} -%produces: -%\DTLifstringeq{10.50}{10.5}{true}{false}. -% -%Note that -%\begin{verbatim} -%\DTLifstringeq{Text}{text}{true}{false} -%\end{verbatim} -%produces: -%\DTLifstringeq{Text}{text}{true}{false}, whereas -%\begin{verbatim} -%\DTLifstringeq*{Text}{text}{true}{false} -%\end{verbatim} -%produces: -%\DTLifstringeq*{Text}{text}{true}{false}, however it should also be -%noted that many commands will be ignored, so: -%\begin{verbatim} -%\DTLifstringeq{\uppercase{t}ext}{text}{true}{false} -%\end{verbatim} -%produces: -%\DTLifstringeq{\uppercase{t}ext}{text}{true}{false}. -% -%Spaces are considered to be equivalent to \cs{space} and "~". For -%example: -%\begin{verbatim} -%\DTLifstringeq{an apple}{an~apple}{true}{false} -%\end{verbatim} -%produces: -%\DTLifstringeq{an apple}{an~apple}{true}{false}. Consecutive spaces -%are treated as the same, for example: -%\begin{verbatim} -%\DTLifstringeq{an apple}{an apple}{true}{false} -%\end{verbatim} -%produces: -%\DTLifstringeq{an apple}{an apple}{true}{false}. -% -%\begin{definition}[\DescribeMacro{\DTLifeq}]% -%\cs{DTLifeq}\marg{arg1}\marg{arg2}\marg{true part}\marg{false part} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLifeq*}]% -%\cs{DTLifeq*}\marg{arg1}\marg{arg2}\marg{true part}\marg{false part} -%\end{definition} -%If both \meta{arg1} and \meta{arg2} are numerical, then this is -%equivalent to \cs{DTLifnumeq}, otherwise it is equivalent to -%\cs{DTLifstringeq} (when using \cs{DTLifeq}) or \cs{DTLifstringeq*} -%(when using \cs{DTLifeq*}). -% -%\begin{definition}[\DescribeMacro{\DTLifnumlt}]% -%\cs{DTLifnumlt}\marg{num1}\marg{num2}\marg{true part}\marg{false part} -%\end{definition} -%If \meta{num1} is less than \meta{num2}, then do \meta{true part}, -%otherwise do \meta{false part}. Note that both \meta{num1} and -%\meta{num2} must be numerical (either integers, real numbers or -%currency). -% -%\begin{definition}[\DescribeMacro{\DTLifstringlt}]% -%\cs{DTLifstringlt}\marg{string1}\marg{string2}\marg{true -%part}\marg{false part} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLifstringlt*}]% -%\cs{DTLifstringlt*}\marg{string1}\marg{string2}\marg{true -%part}\marg{false part} -%\end{definition} -%If \meta{string1} is alphabetically less than \meta{string2}, then do -%\meta{true part}, otherwise do \meta{false part}. The starred -%version ignores the case, the unstarred version is case -%sensitive. -%For example: -%\begin{verbatim} -%\DTLifstringlt{aardvark}{zebra}{less}{not less} -%\end{verbatim} -%produces: -%\DTLifstringlt{aardvark}{zebra}{less}{not less}. -% -%Note that both \meta{string1} and \meta{string2} are considered to be -%strings, so for example: -%\begin{verbatim} -%\DTLifstringlt{2}{10}{less}{not less} -%\end{verbatim} -%produces: -%\DTLifstringlt{2}{10}{less}{not less}, since the string "2" -%comes after the string "10" when arranged alphabetically. -% -%The case sensitive (unstarred) version considers uppercase characters -%to be less than lowercase characters, so -%\begin{verbatim} -%\DTLifstringlt{B}{a}{less}{not less} -%\end{verbatim} -%produces: -%\DTLifstringlt{B}{a}{less}{not less}, whereas -%\begin{verbatim} -%\DTLifstringlt*{B}{a}{less}{not less} -%\end{verbatim} -%produces: -%\DTLifstringlt*{B}{a}{less}{not less}. -% -%\begin{definition}[\DescribeMacro{\DTLiflt}]% -%\cs{DTLiflt}\marg{arg1}\marg{arg2}\marg{true part}\marg{false part} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLiflt*}]% -%\cs{DTLiflt*}\marg{arg1}\marg{arg2}\marg{true part}\marg{false part} -%\end{definition} -%If \meta{arg1} and \meta{arg2} are both numerical, then this -%is equivalent to \cs{DTLifnumlt}, otherwise it is equivalent -%to \cs{DTLstringlt} (when using \cs{DTLiflt}) or -%\cs{DTLstringlt*} (when using \cs{DTLiflt*}). -% -%\begin{definition}[\DescribeMacro{\DTLifnumgt}]% -%\cs{DTLifnumgt}\marg{num1}\marg{num2}\marg{true part}\marg{false part} -%\end{definition} -%If \meta{num1} is greater than \meta{num2}, then do \meta{true part}, -%otherwise do \meta{false part}. Note that both \meta{num1} and -%\meta{num2} must be numerical (either integers, real numbers or -%currency). -% -%\begin{definition}[\DescribeMacro{\DTLifstringgt}]% -%\cs{DTLifstringgt}\marg{string1}\marg{string2}\marg{true -%part}\marg{false part} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLifstringgt*}]% -%\cs{DTLifstringgt*}\marg{string1}\marg{string2}\marg{true -%part}\marg{false part} -%\end{definition} -%If \meta{string1} is alphabetically greater than \meta{string2}, then -%do \meta{true part}, otherwise do \meta{false part}. The -%starred version ignores the case, the unstarred version is -%case sensitive. For example: -%\begin{verbatim} -%\DTLifstringgt{aardvark}{zebra}{greater}{not greater} -%\end{verbatim} -%produces: -%\DTLifstringgt{aardvark}{zebra}{greater}{not greater}. -% -%Note that both \meta{string1} and \meta{string2} are considered to be -%strings, so for example: -%\begin{verbatim} -%\DTLifstringgt{2}{10}{greater}{not greater} -%\end{verbatim} -%produces: -%\DTLifstringgt{2}{10}{greater}{not greater}, since the string "2" -%comes after the string "10" when arranged alphabetically. -% -%As with \cs{DTLifstringlt}, uppercase characters are considered -%to be less than lower case characters when performing a -%case sensitive comparison so: -%\begin{verbatim} -%\DTLifstringgt{B}{a}{greater}{not greater} -%\end{verbatim} -%produces: -%\DTLifstringgt{B}{a}{greater}{not greater}, whereas -%\begin{verbatim} -%\DTLifstringgt*{B}{a}{greater}{not greater} -%\end{verbatim} -%produces: -%\DTLifstringgt*{B}{a}{greater}{not greater}. -% -%\begin{definition}[\DescribeMacro{\DTLifgt}]% -%\cs{DTLifgt}\marg{arg1}\marg{arg2}\marg{true part}\marg{false part} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLifgt*}]% -%\cs{DTLifgt*}\marg{arg1}\marg{arg2}\marg{true part}\marg{false part} -%\end{definition} -%If \meta{arg1} and \meta{arg2} are both numerical, then this -%is equivalent to \cs{DTLifnumgt}, otherwise it is equivalent -%to \cs{DTLstringgt} (when using \cs{DTLifgt}) or -%\cs{DTLstringgt*} (when using \cs{DTLifgt*}). -% -%\begin{definition}[\DescribeMacro{\DTLifnumclosedbetween}]% -%\cs{DTLifnumclosedbetween}\marg{num}\marg{min}\marg{max}\marg{true part}\marg{false part} -%\end{definition} -%If \meta{min} $\leq$ \meta{num} $\leq$ \meta{max} then do \meta{true part}, -%otherwise do \meta{false part}. Note that \meta{num}, \meta{min} and -%\meta{max} must be numerical (either integers, real numbers or -%currency). The currency symbol is ignored when determining -%equality. For example: -%\begin{verbatim} -%\DTLifnumclosedbetween{5.4}{5}{7}{inside}{outside} -%\end{verbatim} -%produces: -%\DTLifnumclosedbetween{5.4}{5}{7}{inside}{outside}. -%Note that the closed range includes end points: -%\begin{verbatim} -%\DTLifnumclosedbetween{5}{5}{7}{inside}{outside} -%\end{verbatim} -%produces: -%\DTLifnumclosedbetween{5}{5}{7}{inside}{outside}. -% -%\begin{definition}[\DescribeMacro{\DTLifstringclosedbetween}]% -%\cs{DTLifstringclosedbetween}\marg{string}\marg{min}\marg{max}\marg{true part}\marg{false part} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLifstringclosedbetween*}]% -%\cs{DTLifstringclosedbetween*}\marg{string}\marg{min}\marg{max}\marg{true part}\marg{false part} -%\end{definition} -%This determines if \meta{string} is between \meta{min} and -%\meta{max} in the alphabetical sense, or is equal to either -%\meta{min} or \meta{max}. The starred version ignores the case, -%the unstarred version is case sensitive. -% -%\begin{definition}[\DescribeMacro{\DTLifclosedbetween}]% -%\cs{DTLifclosedbetween}\marg{arg}\marg{min}\marg{max}\marg{true part}\marg{false part} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLifclosedbetween*}]% -%\cs{DTLifclosedbetween*}\marg{arg}\marg{min}\marg{max}\marg{true part}\marg{false part} -%\end{definition} -%If \meta{arg}, \meta{min} and \meta{max} are numerical, then this is -%equivalent to \cs{DTLifnumclosedbetween}, otherwise it is equivalent to -%\cs{DTLifstringclosedbetween} (when using \cs{DTLifclosedbetween}) -%or -%\cs{DTLifstringclosedbetween*} (when using \cs{DTLifclosedbetween*}). -% -%\begin{definition}[\DescribeMacro{\DTLifnumopenbetween}]% -%\cs{DTLifnumopenbetween}\marg{num}\marg{min}\marg{max}\marg{true part}\marg{false part} -%\end{definition} -%If \meta{min} $<$ \meta{num} $<$ \meta{max} then do \meta{true part}, -%otherwise do \meta{false part}. Note that \meta{num}, \meta{min} and -%\meta{max} must be numerical (either integers, real numbers or -%currency). Again, the currency symbol is ignored when determining -%equality. For example: -%\begin{verbatim} -%\DTLifnumopenbetween{5.4}{5}{7}{inside}{outside} -%\end{verbatim} -%produces: -%\DTLifnumopenbetween{5.4}{5}{7}{inside}{outside}. -%Note that end points are not included. For example: -%\begin{verbatim} -%\DTLifnumopenbetween{5}{5}{7}{inside}{outside} -%\end{verbatim} -%produces: -%\DTLifnumopenbetween{5}{5}{7}{inside}{outside}. -% -%\begin{definition}[\DescribeMacro{\DTLifstringopenbetween}]% -%\cs{DTLifstringopenbetween}\marg{string}\marg{min}\marg{max}\marg{true part}\marg{false part} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLifstringopenbetween*}]% -%\cs{DTLifstringopenbetween*}\marg{string}\marg{min}\marg{max}\marg{true part}\marg{false part} -%\end{definition} -%This determines if \meta{string} is between \meta{min} and -%\meta{max} in the alphabetical sense. -%The starred version ignores the case, -%the unstarred version is case sensitive. -% -%\begin{definition}[\DescribeMacro{\DTLifopenbetween}]% -%\cs{DTLifopenbetween}\marg{arg}\marg{min}\marg{max}\marg{true part}\marg{false part} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLifopenbetween*}]% -%\cs{DTLifopenbetween*}\marg{arg}\marg{min}\marg{max}\marg{true part}\marg{false part} -%\end{definition} -%If \meta{arg}, \meta{min} and \meta{max} are numerical, then this is -%equivalent to \cs{DTLifnumopenbetween}, otherwise it is equivalent to -%\cs{DTLifstringopenbetween} (when using \cs{DTLifopenbetween}) -%\cs{DTLifstringopenbetween*} (when using \cs{DTLifopenbetween*}). -% -%\begin{definition}[\DescribeMacro{\DTLifFPclosedbetween}]% -%\cs{DTLifFPclosedbetween}\marg{num}\marg{min}\marg{max}\marg{true part}\marg{false part} -%\end{definition} -%If \meta{min} $\leq$ \meta{num} $\leq$ \meta{max} then do \meta{true part}, -%otherwise do \meta{false part} where \meta{num}, \meta{min} -%and \meta{max} are all in standard fixed point notation (i.e.\ -%no number group separator, no currency symbols and a full stop as -%a decimal point). -% -%\begin{definition}[\DescribeMacro{\DTLifFPopenbetween}]% -%\cs{DTLifFPopenbetween}\marg{num}\marg{min}\marg{max}\marg{true part}\marg{false part} -%\end{definition} -%If \meta{min} $<$ \meta{num} $<$ \meta{max} then do \meta{true part}, -%otherwise do \meta{false part} where \meta{num}, \meta{min} -%and \meta{max} are all in standard fixed point notation (i.e.\ -%no number group separator, no currency symbols and a full stop as -%a decimal point). -% -%\begin{definition}[\DescribeMacro{\DTLifAllUpperCase}]% -%\cs{DTLifAllUpperCase}\marg{string}\marg{true part}\marg{false part} -%\end{definition} -%Tests if \meta{string} is all upper case. For example: -%\begin{verbatim} -%\DTLifAllUpperCase{WORD}{all upper}{not all upper} -%\end{verbatim} -%produces: -%\DTLifAllUpperCase{WORD}{all upper}{not all upper}, -%whereas -%\begin{verbatim} -%\DTLifAllUpperCase{Word}{all upper}{not all upper} -%\end{verbatim} -%produces: -%\DTLifAllUpperCase{Word}{all upper}{not all upper}. -%Note also that: -%\begin{verbatim} -%\DTLifAllUpperCase{\MakeUppercase{word}}{all upper}{not all upper} -%\end{verbatim} -%also produces: -%\DTLifAllUpperCase{\MakeUppercase{word}}{all upper}{not all upper}. -%\cs{MakeTextUppercase} (defined in David Carlisle's \sty{textcase} -%package) and \cs{uppercase} are also detected, otherwise, if -%a command is encountered, the case of the command is considered. -%For example: -%\begin{verbatim} -%\DTLifAllUpperCase{MAN{\OE}UVRE}{all upper}{not all upper} -%\end{verbatim} -%produces: -%\DTLifAllUpperCase{MAN{\OE}UVRE}{all upper}{not all upper}. -% -%\begin{definition}[\DescribeMacro{\DTLifAllLowerCase}]% -%\cs{DTLifAllLowerCase}\marg{string}\marg{true part}\marg{false part} -%\end{definition} -%Tests if \meta{string} is all lower case. For example: -%\begin{verbatim} -%\DTLifAllLowerCase{word}{all lower}{not all lower} -%\end{verbatim} -%produces: -%\DTLifAllLowerCase{word}{all lower}{not all lower}, -%whereas -%\begin{verbatim} -%\DTLifAllLowerCase{Word}{all lower}{not all lower} -%\end{verbatim} -%produces: -%\DTLifAllLowerCase{Word}{all lower}{not all lower}. -%Note also that: -%\begin{verbatim} -%\DTLifAllLowerCase{\MakeLowercase{WORD}}{all lower}{not all lower} -%\end{verbatim} -%also produces: -%\DTLifAllLowerCase{\MakeLowercase{WORD}}{all lower}{not all lower}. -%\cs{MakeTextLowercase} (defined in David Carlisle's \sty{textcase} -%package) and \cs{lowercase} are also detected, otherwise, if -%a command is encountered, the case of the command is considered. -%For example: -%\begin{verbatim} -%\DTLifAllLowerCase{man{\oe}uvre}{all lower}{not all lower} -%\end{verbatim} -%produces: -%\DTLifAllLowerCase{man{\oe}uvre}{all lower}{not all lower}. -% -%\begin{definition}[\DescribeMacro{\DTLifSubString}]% -%\cs{DTLifSubString}\marg{string}\marg{substring}\marg{true -%part}\marg{false part} -%\end{definition} -%This tests if \meta{substring} is a sub-string of \meta{string}. -%This command performs a case sensitive match. For example: -%\begin{verbatim} -%\DTLifSubString{An apple}{app}{is substring}{isn't substring} -%\end{verbatim} -%produces: -%\DTLifSubString{An apple}{app}{is substring}{isn't substring}. -%Note that spaces are considered to be equivalent to \cs{space} -%or "~", so -%\begin{verbatim} -%\DTLifSubString{An apple}{n~a}{is substring}{isn't substring} -%\end{verbatim} -%produces: -%\DTLifSubString{An apple}{n~a}{is substring}{isn't substring}, -%but other commands are skipped, so -%\begin{verbatim} -%\DTLifSubString{An \uppercase{a}pple}{app}{is substring}{isn't -%substring} -%\end{verbatim} -%produces: -%\DTLifSubString{An \uppercase{a}pple}{app}{is substring}{isn't -%substring}, since the \cs{uppercase} command is ignored. Note also -%that grouping is ignored, so: -%\begin{verbatim} -%\DTLifSubString{An {ap}ple}{app}{is substring}{isn't substring} -%\end{verbatim} -%produces: -%\DTLifSubString{An {ap}ple}{app}{is substring}{isn't substring}. -% -%\cs{DTLifSubString} is case sensitive, so: -%\begin{verbatim} -%\DTLifSubString{An Apple}{app}{is substring}{isn't substring} -%\end{verbatim} -%produces: -%\DTLifSubString{An Apple}{app}{is substring}{isn't substring}. -% -%\begin{definition}[\DescribeMacro{\DTLifStartsWith}]% -%\cs{DTLifStartsWith}\marg{string}\marg{substring}\marg{true -%part}\marg{false part} -%\end{definition} -%This is like \cs{DTLifSubString}, except that \meta{substring} must -%occur at the start of \meta{string}. This command performs a case -%sensitive match. For example, -%\begin{verbatim} -%\DTLifStartsWith{An apple}{app}{prefix}{not a prefix} -%\end{verbatim} -%produces: -%\DTLifStartsWith{An apple}{app}{prefix}{not a prefix}. All the -%above remarks for \cs{DTLifSubString} also applies to -%\cs{DTLifStartsWith}. For example: -%\begin{verbatim} -%\DTLifStartsWith{\uppercase{a}n apple}{an~}{prefix}{not a prefix} -%\end{verbatim} -%produces: -%\DTLifStartsWith{\uppercase{a}n apple}{an~}{prefix}{not a prefix}, -%since \cs{uppercase} is ignored, and "~" is considered to be the -%same as a space, whereas -%\begin{verbatim} -%\DTLifStartsWith{An apple}{an~}{prefix}{not a prefix} -%\end{verbatim} -%produces: -%\DTLifStartsWith{An apple}{an~}{prefix}{not a prefix}. -% -%\subsection{\texorpdfstring{\sty{ifthen}}{ifthen} conditionals} -%\label{sec:ifthen} -% -%The commands described in the previous section can not be -%used as the conditional part of the \cs{ifthenelse} or -%\cs{whiledo} commands provided by the \sty{ifthen} package. -%This section describes analogous commands which may only be -%used in the conditional argument of \cs{ifthenelse} and -%\cs{whiledo}. These may be used with the boolean operations -%\cs{not}, \cs{and} and \cs{or} provided by the \sty{ifthen} package. -%See the \sty{ifthen} documentation for further details. -% -%\begin{definition}[\DescribeMacro{\DTLisstring}]% -%\cs{DTLisstring}\marg{text} -%\end{definition} -%Tests if \meta{text} is a string. For example: -%\begin{verbatim} -%\ifthenelse{\DTLisstring{some text}}{string}{not a string} -%\end{verbatim} -%produces: -%\ifthenelse{\DTLisstring{some text}}{string}{not a string}. -% -%\begin{definition}[\DescribeMacro{\DTLisnumerical}]% -%\cs{DTLisnumerical}\marg{text} -%\end{definition} -%Tests if \meta{text} is numerical (i.e.\ not a string). For example: -%\begin{verbatim} -%\ifthenelse{\DTLisnumerical{\$10.95}}{numerical}{not numerical} -%\end{verbatim} -%produces: -%\ifthenelse{\DTLisnumerical{\$10.95}}{numerical}{not numerical}. -% -%Note however that \cs{DTLisnumerical} requires more care than -%\cs{DTLifnumerical} when used with some of the other currency -%symbols. Consider: -%\begin{verbatim} -%\DTLifnumerical{\pounds10.95}{numerical}{not numerical} -%\end{verbatim} -%This produces: -%\DTLifnumerical{\pounds10.95}{numerical}{not numerical}. -%However -%\begin{verbatim} -%\ifthenelse{\DTLisnumerical{\pounds10.95}}{numerical}{not numerical} -%\end{verbatim} -%produces: -%\ifthenelse{\DTLisnumerical{\pounds10.95}}{numerical}{not numerical}. -%This is due to the expansion that occurs within \cs{ifthenelse}. -%This can be prevented using \cs{noexpand}, for example: -%\begin{verbatim} -%\ifthenelse{\DTLisnumerical{\noexpand\pounds10.95}}{numerical}{not numerical} -%\end{verbatim} -%produces: -%\ifthenelse{\DTLisnumerical{\noexpand\pounds10.95}}{numerical}{not numerical}. -% -%Likewise: -%\begin{verbatim} -%\def\cost{\pounds10.95}% -%\ifthenelse{\DTLisnumerical{\noexpand\cost}}{numerical}{not numerical} -%\end{verbatim} -%produces: -%\def\cost{\pounds10.95}\relax -%\ifthenelse{\DTLisnumerical{\noexpand\cost}}{numerical}{not numerical}. -% -%\begin{definition}[\DescribeMacro{\DTLiscurrency}]% -%\cs{DTLiscurrency}\marg{text} -%\end{definition} -%Tests if \meta{text} is currency. For example: -%\begin{verbatim} -%\ifthenelse{\DTLiscurrency{\$10.95}}{currency}{not currency} -%\end{verbatim} -%produces: -%\ifthenelse{\DTLiscurrency{\$10.95}}{currency}{not currency}. -% -%The same warning given above for \cs{DTLisnumerical} also applies -%here. -% -%\begin{definition}[\DescribeMacro{\DTLiscurrencyunit}]% -%\cs{DTLiscurrencyunit}\marg{text}\marg{symbol} -%\end{definition} -%Tests if \meta{text} is currency and that currency uses \meta{symbol} as the unit -%of currency. -%For example: -%\begin{verbatim} -%\ifthenelse{\DTLiscurrencyunit{\$6.99}{\$}}{dollars}{not dollars} -%\end{verbatim} -%produces: -%\ifthenelse{\DTLiscurrencyunit{\$6.99}{\$}}{dollars}{not dollars}. -%Another example: -%\begin{verbatim} -%\def\cost{\euro10.50}% -%\ifthenelse{\DTLiscurrencyunit{\noexpand\cost}{\noexpand\euro}}% -%{euros}{not euros} -%\end{verbatim} -%produces: -%\def\cost{\euro10.50}\relax -%\ifthenelse{\DTLiscurrencyunit{\noexpand\cost}{\noexpand\euro}}% -%{euros}{not euros}. Again note the use of \cs{noexpand}. -% -%\begin{definition}[\DescribeMacro{\DTLisreal}]% -%\cs{DTLisreal}\marg{text} -%\end{definition} -%Tests if \meta{text} is a fixed point number (again, an integer is -%not considered to be a fixed point number). For example: -%\begin{verbatim} -%\ifthenelse{\DTLisreal{1.5}}{real}{not real} -%\end{verbatim} -%produces: -%\ifthenelse{\DTLisreal{1.5}}{real}{not real}. -% -%\begin{definition}[\DescribeMacro{\DTLisint}]% -%\cs{DTLisint}\marg{text} -%\end{definition} -%Tests if \meta{text} is an integer. For example: -%\begin{verbatim} -%\ifthenelse{\DTLisint{153}}{integer}{not an integer} -%\end{verbatim} -%produces: -%\ifthenelse{\DTLisint{153}}{integer}{not an integer}. -% -%\begin{definition}[\DescribeMacro{\DTLislt}]% -%\cs{DTLislt}\marg{arg1}\marg{arg2} -%\end{definition} -%This checks if \meta{arg1} is less than \meta{arg2}. As with -%\cs{DTLiflt}, if \meta{arg1} and \meta{arg2} are numerical, -%a numerical comparison is used, otherwise a case sensitive -%alphabetical comparison is used. (Note that there is no starred -%version of this command, but you can instead use \cs{DTLisilt} -%to ignore the case.) -% -%\begin{definition}[\DescribeMacro{\DTLisilt}]% -%\cs{DTLisilt}\marg{arg1}\marg{arg2} -%\end{definition} -%This checks if \meta{arg1} is less than \meta{arg2}. As with -%\cs{DTLiflt*}, if \meta{arg1} and \meta{arg2} are numerical, -%a numerical comparison is used, otherwise a case insensitive -%alphabetical comparison is used. -% -%\begin{definition}[\DescribeMacro{\DTLisgt}]% -%\cs{DTLisgt}\marg{arg1}\marg{arg2} -%\end{definition} -%This checks if \meta{arg1} is greater than \meta{arg2}. As with -%\cs{DTLifgt}, if \meta{arg1} and \meta{arg2} are numerical, -%a numerical comparison is used, otherwise a case sensitive -%alphabetical comparison is used. (Note that there is no starred -%version of this command, instead use \cs{DTLisigt} to -%ignore the case.) -% -%\begin{definition}[\DescribeMacro{\DTLisigt}]% -%\cs{DTLisigt}\marg{arg1}\marg{arg2} -%\end{definition} -%This checks if \meta{arg1} is greater than \meta{arg2}. As with -%\cs{DTLifgt*}, if \meta{arg1} and \meta{arg2} are numerical, -%a numerical comparison is used, otherwise a case insensitive -%alphabetical comparison is used. -% -%\begin{definition}[\DescribeMacro{\DTLiseq}]% -%\cs{DTLiseq}\marg{arg1}\marg{arg2} -%\end{definition} -%This checks if \meta{arg1} is equal to \meta{arg2}. As with -%\cs{DTLifeq}, if \meta{arg1} and \meta{arg2} are numerical, -%a numerical comparison is used, otherwise a case sensitive -%alphabetical comparison is used. (Note that there is no starred -%version of this command, instead use \cs{DTLisieq}.) -% -%\begin{definition}[\DescribeMacro{\DTLisieq}]% -%\cs{DTLisieq}\marg{arg1}\marg{arg2} -%\end{definition} -%This checks if \meta{arg1} is equal to \meta{arg2}. As with -%\cs{DTLifeq*}, if \meta{arg1} and \meta{arg2} are numerical, -%a numerical comparison is used, otherwise a case insensitive -%alphabetical comparison is used. -% -%\begin{definition}[\DescribeMacro{\DTLisclosedbetween}]% -%\cs{DTLisclosedbetween}\marg{arg}\marg{min}\marg{max} -%\end{definition} -%This checks if \meta{arg} lies between \meta{min} and -%\meta{max} (end points included). As with -%\cs{DTLifclosedbetween}, if the arguments are numerical, -%a numerical comparison is used, otherwise a case sensitive -%alphabetical comparison is used. (Note that there is no starred -%version of this command, instead use \cs{DTLisiclosedbetween}.) -% -%\begin{definition}[\DescribeMacro{\DTLisiclosedbetween}]% -%\cs{DTLisiclosedbetween}\marg{arg}\marg{min}\marg{max} -%\end{definition} -%This checks if \meta{arg} lies between \meta{min} and -%\meta{max} (end points included). As with -%\cs{DTLifclosedbetween*}, if the arguments are numerical, -%a numerical comparison is used, otherwise a case insensitive -%alphabetical comparison is used. -% -%\begin{definition}[\DescribeMacro{\DTLisopenbetween}]% -%\cs{DTLisopenbetween}\marg{arg}\marg{min}\marg{max} -%\end{definition} -%This checks if \meta{arg} lies between \meta{min} and -%\meta{max} (end points excluded). As with -%\cs{DTLifopenbetween}, if the arguments are numerical, -%a numerical comparison is used, otherwise a case sensitive -%alphabetical comparison is used. (Note that there is no starred -%version of this command, instead use \cs{DTLisiopenbetween}.) -% -%\begin{definition}[\DescribeMacro{\DTLisiopenbetween}]% -%\cs{DTLisiopenbetween}\marg{arg}\marg{min}\marg{max} -%\end{definition} -%This checks if \meta{arg} lies between \meta{min} and -%\meta{max} (end points excluded). As with -%\cs{DTLifopenbetween*}, if the arguments are numerical, -%a numerical comparison is used, otherwise a case insensitive -%alphabetical comparison is used. -% -%\begin{definition}[\DescribeMacro{\DTLisFPlt}]% -%\cs{DTLisFPlt}\marg{num1}\marg{num2} -%\end{definition} -%This checks if \meta{num1} is less than \meta{num2}, where both -%numbers are in standard fixed point format (i.e.\ no number group -%separators, no currency and a full stop as a decimal point). -% -%\begin{definition}[\DescribeMacro{\DTLisFPlteq}]% -%\cs{DTLisFPlteq}\marg{num1}\marg{num2} -%\end{definition} -%This checks if \meta{num1} is less than or equal to \meta{num2}, where both -%numbers are in standard fixed point format (i.e.\ no number group -%separators, no currency and a full stop as a decimal point). -% -%\begin{definition}[\DescribeMacro{\DTLisFPgt}]% -%\cs{DTLisFPgt}\marg{num1}\marg{num2} -%\end{definition} -%This checks if \meta{num1} is greater than \meta{num2}, where both -%numbers are in standard fixed point format (i.e.\ no number group -%separators, no currency and a full stop as a decimal point). -% -%\begin{definition}[\DescribeMacro{\DTLisFPgteq}]% -%\cs{DTLisFPgteq}\marg{num1}\marg{num2} -%\end{definition} -%This checks if \meta{num1} is greater than or equal to \meta{num2}, where both -%numbers are in standard fixed point format (i.e.\ no number group -%separators, no currency and a full stop as a decimal point). -% -%\begin{definition}[\DescribeMacro{\DTLisFPeq}]% -%\cs{DTLisFPeq}\marg{num1}\marg{num2} -%\end{definition} -%This checks if \meta{num1} is equal to \meta{num2}, where both -%numbers are in standard fixed point format (i.e.\ no number group -%separators, no currency and a full stop as a decimal point). -% -%\begin{definition}[\DescribeMacro{\DTLisFPclosedbetween}]% -%\cs{DTLisFPclosedbetween}\marg{num}\marg{min}\marg{max} -%\end{definition} -%This checks if \meta{num} lies between \meta{min} and -%\meta{max} (end points included). All arguments must be -%numbers in standard fixed point format (i.e.\ no number group -%separators, no currency and a full stop as a decimal point). -% -%\begin{definition}[\DescribeMacro{\DTLisFPopenbetween}]% -%\cs{DTLisFPopenbetween}\marg{num}\marg{min}\marg{max} -%\end{definition} -%This checks if \meta{num} lies between \meta{min} and -%\meta{max} (end points excluded). All arguments must be -%numbers in standard fixed point format (i.e.\ no number group -%separators, no currency and a full stop as a decimal point). -% -%\begin{definition}[\DescribeMacro{\DTLisSubString}]% -%\cs{DTLisSubString}\marg{string}\marg{substring} -%\end{definition} -%This checks if \meta{substring} is contained in \meta{string}. -%The remarks about \cs{DTLifSubString} also apply to -%\cs{DTLisSubString}. This command performs a case sensitive -%match. -% -%\begin{definition}[\DescribeMacro{\DTLisPrefix}]% -%\cs{DTLisPrefix}\marg{string}\marg{prefix} -%\end{definition} -%This checks if \meta{string} starts with \meta{prefix}. -%The remarks about \cs{DTLifStartsWith} also apply to -%\cs{DTLisPrefix}. This command performs a case sensitive -%match. -% -%\section{Fixed Point Arithmetic} -%\label{sec:fp} -% -%The \sty{datatool} package uses the \sty{fp} package to perform -%fixed point arithmetic, however all numbers must be converted -%from the locale dependent format into the format required by the -%\sty{fp} package. A numerical value (i.e.\ an integer, a real -%or currency) can be converted into a plain decimal number using -%\begin{definition}[\DescribeMacro{\DTLconverttodecimal}]% -%\cs{DTLconverttodecimal}\marg{num}\marg{cmd} -%\end{definition} -%The decimal number will be stored in \meta{cmd} which must be -%a control sequence. For example: -%\begin{verbatim} -%\DTLconverttodecimal{1,563.54}{\mynum} -%\end{verbatim} -%\DTLconverttodecimal{1,563.54}{\mynum}\relax -%will define \cs{mynum} to be \texttt{\mynum}. The command \cs{mynum} -%can then be used in any of the arithmetic macros provided by the -%\sty{fp} package. There are two commands provided to perform -%the reverse: -%\begin{definition}[\DescribeMacro{\DTLdecimaltolocale}]% -%\cs{DTLdecimaltolocale}\marg{number}\marg{cmd} -%\end{definition} -%This converts a plain decimal number \meta{number} (that uses a full -%stop as the decimal character and has no number group characters) -%into a locale dependent format. The resulting number is stored -%in \meta{cmd}, which must be a control sequence. For example: -%\begin{verbatim} -%\DTLdecimaltolocale{6795.3}{\mynum} -%\end{verbatim} -%\DTLdecimaltolocale{6795.3}{\mynum} -%will define \cs{mynum} to be \texttt{\mynum}. -% -%\begin{definition}[\DescribeMacro{\DTLdecimaltocurrency}]% -%\cs{DTLdecimaltocurrency}\marg{number}\marg{cmd} -%\end{definition} -%This will convert a plain decimal number \meta{number} into a -%locale dependent currency format. For example: -%\begin{verbatim} -%\DTLdecimaltocurrency{267.5}{\price}\price -%\end{verbatim} -%will produce: -%\DTLdecimaltocurrency{267.5}{\price}\price. -% -%The currency symbol used by \cs{DTLdecimaltocurrency} is -%initially "\$", but will use the currency last encountered. -%So, for example -%\begin{verbatim} -%\DTLifcurrency{\texteuro45.00}{}{}% -%\DTLdecimaltocurrency{267.5}{\price}\price -%\end{verbatim} -%will produce: -%\DTLifcurrency{\texteuro45.00}{}{}\relax -%\DTLdecimaltocurrency{267.5}{\price}\price. This is because -%the last currency symbol to be encountered was \cs{texteuro}. -%You can reset the currency symbol using the command: -%\begin{definition}[\DescribeMacro{\DTLsetdefaultcurrency}]% -%\cs{DTLsetdefaultcurrency}\marg{symbol} -%\end{definition} -%For example: -%\begin{verbatim} -%\DTLsetdefaultcurrency{\textyen}% -%\DTLdecimaltocurrency{267.5}{\price}\price -%\end{verbatim} -%will produce: -%\DTLsetdefaultcurrency{\textyen}\relax -%\DTLdecimaltocurrency{267.5}{\price}\price -% -%The \sty{datatool} package provides convenience commands which -%use \cs{DTLconverttodecimal}, and then use the basic macros provided -%by the \sty{fp} package. The resulting value is then converted -%back into the locale format using -%\cs{DTLdecimaltolocale} or \cs{DTLdecimaltocurrency}. -% -% -%\begin{definition}[\DescribeMacro{\DTLadd}]% -%\cs{DTLadd}\marg{cmd}\marg{num1}\marg{num2} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLgadd}]% -%\cs{DTLgadd}\marg{cmd}\marg{num1}\marg{num2} -%\end{definition} -%This sets the control sequence \meta{cmd} to \meta{num1}+\meta{num2}. -%\cs{DLTadd} sets \meta{cmd} locally, while \cs{DTLgadd} sets -%\meta{cmd} globally. -% -%For example: -%\begin{verbatim} -%\DTLadd{\result}{3,562.65}{412.2}\result -%\end{verbatim} -%will produce: -%\DTLadd{\result}{3,562.65}{412.2}\result. Since -%\cs{DTLconverttodecimal} can convert currency to a real -%number, you can also add prices. For example: -%\begin{verbatim} -%\DTLadd{\result}{\pounds3,562.65}{\pounds452.2}\result -%\end{verbatim} -%produces: -%\DTLadd{\result}{\pounds3,562.65}{\pounds452.2}\result. -% -%Note that \sty{datatool} isn't aware of exchange rates! If you -%use different currency symbols, the last symbol will be used. -%For example -%\begin{verbatim} -%\DTLadd{\result}{\pounds3,562.65}{\euro452.2}\result -%\end{verbatim} -%produces: -%\DTLadd{\result}{\pounds3,562.65}{\euro452.2}\result. -% -%Likewise, if one value is a number and the other is a currency, -%the type of the last value, \meta{num2}, will be used for the -%result. For example: -%\begin{verbatim} -%\DTLadd{\result}{3,562.65}{\$452.2}\result -%\end{verbatim} -%produces: -%\DTLadd{\result}{3,562.65}{\$452.2}\result. -% -%\begin{definition}[\DescribeMacro{\DTLaddall}]% -%\cs{DTLaddall}\marg{cmd}\marg{number list} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLgaddall}]% -%\cs{DTLgaddall}\marg{cmd}\marg{number list} -%\end{definition} -%This sets the control sequence \meta{cmd} to the sum of all -%the numbers in \meta{number list}. -%\cs{DLTaddall} sets \meta{cmd} locally, while \cs{DTLgaddall} sets -%\meta{cmd} globally. Example: -%\begin{verbatim} -%\DTLaddall{\total}{25.1,45.2,35.6}\total -%\end{verbatim} -%produces: -%\DTLaddall{\total}{25.1,45.2,35.6}\total. -%Note that if any of the numbers in \meta{number list} contain -%a comma, you must group the number. Example: -%\begin{verbatim} -%\DTLaddall{\total}{{1,525},{2,340},500}\total -%\end{verbatim} -%produces: -%\DTLaddall{\total}{{1,525},{2,340},500}\total. -% -%\begin{definition}[\DescribeMacro{\DTLsub}]% -%\cs{DTLsub}\marg{cmd}\marg{num1}\marg{num2} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLgsub}]% -%\cs{DTLgsub}\marg{cmd}\marg{num1}\marg{num2} -%\end{definition} -%This sets the control sequence \meta{cmd} to -%\meta{num1}$-$\meta{num2}. -%\cs{DLTsub} sets \meta{cmd} locally, while \cs{DTLgsub} sets -%\meta{cmd} globally. -% -%For example: -%\begin{verbatim} -%\DTLsub{\result}{3,562.65}{412.2}\result -%\end{verbatim} -%will produce: -%\DTLsub{\result}{3,562.65}{412.2}\result. As with \cs{DTLadd}, -%\meta{num1} and \meta{num2} may be currency. -% -%\begin{definition}[\DescribeMacro{\DTLmul}]% -%\cs{DTLmul}\marg{cmd}\marg{num1}\marg{num2} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLgmul}]% -%\cs{DTLgmul}\marg{cmd}\marg{num1}\marg{num2} -%\end{definition} -%This sets the control sequence \meta{cmd} to -%\meta{num1}$\times$\meta{num2}. -%\cs{DLTmul} sets \meta{cmd} locally, while \cs{DTLgmul} sets -%\meta{cmd} globally. -% -%For example: -%\begin{verbatim} -%\DTLmul{\result}{568.95}{2}\result -%\end{verbatim} -%will produce: -%\DTLmul{\result}{568.95}{2}\result. Again, \meta{num1} or -%\meta{num2} may be currency, but unlike \cs{DTLadd} and \cs{DTLsub}, -%currency overrides integer/real. For example: -%\begin{verbatim} -%\DTLmul{\result}{\pounds568.95}{2}\result -%\end{verbatim} -%will produce: -%\DTLmul{\result}{\pounds568.95}{2}\result. Likewise, -%\begin{verbatim} -%\DTLmul{\result}{2}{\pounds568.95}\result -%\end{verbatim} -%will produce: -%\DTLmul{\result}{2}{\pounds568.95}\result. Although it doesn't make -%sense to multiply two currencies, \sty{datatool} will allow -%\begin{verbatim} -%\DTLmul{\result}{\$2}{\pounds568.95}\result -%\end{verbatim} -%which will produce: -%\DTLmul{\result}{\$2}{\pounds568.95}\result. -% -%\begin{definition}[\DescribeMacro{\DTLdiv}]% -%\cs{DTLdiv}\marg{cmd}\marg{num1}\marg{num2} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLgdiv}]% -%\cs{DTLgdiv}\marg{cmd}\marg{num1}\marg{num2} -%\end{definition} -%This sets the control sequence \meta{cmd} to -%\meta{num1}$\div$\meta{num2}. -%\cs{DLTdiv} sets \meta{cmd} locally, while \cs{DTLgdiv} sets -%\meta{cmd} globally. -% -%For example: -%\begin{verbatim} -%\DTLdiv{\result}{501}{2}\result -%\end{verbatim} -%will produce: -%\DTLdiv{\result}{501}{2}\result. Again, \meta{num1} or \meta{num2} -%may be currency, but the resulting type will be not be a currency -%if both \meta{num1} and \meta{num2} use the same currency symbol. -%For example: -%\begin{verbatim} -%\DTLdiv{\result}{\$501}{\$2}\result -%\end{verbatim} -%will produce: -%\DTLdiv{\result}{\$501}{\$2}\result. Whereas -%\begin{verbatim} -%\DTLdiv{\result}{\$501}{2}\result -%\end{verbatim} -%will produce: -%\DTLdiv{\result}{\$501}{2}\result. -% -%\begin{definition}[\DescribeMacro{\DTLabs}]% -%\cs{DTLabs}\marg{cmd}\marg{num} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLgabs}]% -%\cs{DTLgabs}\marg{cmd}\marg{num} -%\end{definition} -%This sets \meta{cmd} to the absolute value of \meta{num}. -%\cs{DLTabs} sets \meta{cmd} locally, while \cs{DTLgabs} sets -%\meta{cmd} globally. Example: -%\begin{verbatim} -%\DTLabs{\result}{-\pounds2.50}\result -%\end{verbatim} -%produces: -%\DTLabs{\result}{-\pounds2.50}\result. -% -%\begin{definition}[\DescribeMacro{\DTLneg}]% -%\cs{DTLneg}\marg{cmd}\marg{num} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLgneg}]% -%\cs{DTLgneg}\marg{cmd}\marg{num} -%\end{definition} -%This sets \meta{cmd} to the negative of \meta{num}. -%\cs{DLTneg} sets \meta{cmd} locally, while \cs{DTLgneg} sets -%\meta{cmd} globally. Example: -%\begin{verbatim} -%\DTLneg{\result}{\pounds2.50}\result -%\end{verbatim} -%produces: -%\DTLneg{\result}{\pounds2.50}\result. -% -%\begin{definition}[\DescribeMacro{\DTLsqrt}]% -%\cs{DTLsqrt}\marg{cmd}\marg{num} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLgsqrt}]% -%\cs{DTLgsqrt}\marg{cmd}\marg{num} -%\end{definition} -%This sets \meta{cmd} to the sqrt root of \meta{num}. -%\cs{DLTsqrt} sets \meta{cmd} locally, while \cs{DTLgsqrt} sets -%\meta{cmd} globally. Example: -%\begin{verbatim} -%\DTLsqrt{\result}{2}\result -%\end{verbatim} -%produces: -%\DTLsqrt{\result}{2}\result. -% -%\begin{definition}[\DescribeMacro{\DTLmin}]% -%\cs{DTLmin}\marg{cmd}\marg{num1}\marg{num2} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLgmin}]% -%\cs{DTLgmin}\marg{cmd}\marg{num1}\marg{num2} -%\end{definition} -%This sets the control sequence \meta{cmd} to the minimum of -%\meta{num1} and \meta{num2}. -%\cs{DLTmin} sets \meta{cmd} locally, while \cs{DTLgmin} sets -%\meta{cmd} globally. For example: -%\begin{verbatim} -%\DTLmin{\result}{256}{32}\result -%\end{verbatim} -%produces: -%\DTLmin{\result}{256}{32}\result. -%Again, \meta{num1} and \meta{num2} may -%be currency. For example: -%\begin{verbatim} -%\DTLmin{\result}{256}{\pounds32}\result -%\end{verbatim} -%produces: -%\DTLmin{\result}{256}{\pounds32}\result, whereas -%\begin{verbatim} -%\DTLmin{\result}{\pounds256}{32}\result -%\end{verbatim} -%produces: -%\DTLmin{\result}{\pounds256}{32}\result. As mentioned above, -%\sty{datatool} doesn't know about exchange rates, so be careful -%about mixing currencies. For example: -%\begin{verbatim} -%\DTLmin{\result}{\pounds5}{\$6}\result -%\end{verbatim} -%produces: -%\DTLmin{\result}{\pounds5}{\$6}\result, which may not necessarily -%be true! -% -%\begin{definition}[\DescribeMacro{\DTLminall}]% -%\cs{DTLminall}\marg{cmd}\marg{number list} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLgminall}]% -%\cs{DTLgminall}\marg{cmd}\marg{number list} -%\end{definition} -%This sets the control sequence \meta{cmd} to the minimum of all -%the numbers in \meta{number list}. -%\cs{DLTminall} sets \meta{cmd} locally, while \cs{DTLgminall} sets -%\meta{cmd} globally. Example: -%\begin{verbatim} -%\DTLminall{\theMin}{25.1,45.2,35.6}\theMin -%\end{verbatim} -%produces: -%\DTLminall{\theMin}{25.1,45.2,35.6}\theMin. -%Note that if any of the numbers in \meta{number list} contain -%a comma, you must group the number. Example: -%\begin{verbatim} -%\DTLminall{\theMin}{{1,525},{2,340},500}\theMin -%\end{verbatim} -%produces: -%\DTLminall{\theMin}{{1,525},{2,340},500}\theMin. -% -%\begin{definition}[\DescribeMacro{\DTLmax}]% -%\cs{DTLmax}\marg{cmd}\marg{num1}\marg{num2} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLgmax}]% -%\cs{DTLgmax}\marg{cmd}\marg{num1}\marg{num2} -%\end{definition} -%This sets the control sequence \meta{cmd} to the maximum of -%\meta{num1} and \meta{num2}. -%\cs{DLTmax} sets \meta{cmd} locally, while \cs{DTLgmax} sets -%\meta{cmd} globally. For example: -%\begin{verbatim} -%\DTLmax{\result}{256}{32}\result -%\end{verbatim} -%produces: -%\DTLmax{\result}{256}{32}\result. -%Again, \meta{num1} and \meta{num2} may -%be currency, but the same warnings for \cs{DTLmin} apply. -% -%\begin{definition}[\DescribeMacro{\DTLmaxall}]% -%\cs{DTLmaxall}\marg{cmd}\marg{number list} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLgmaxall}]% -%\cs{DTLgmaxall}\marg{cmd}\marg{number list} -%\end{definition} -%This sets the control sequence \meta{cmd} to the maximum of all -%the numbers in \meta{number list}. -%\cs{DLTmaxall} sets \meta{cmd} locally, while \cs{DTLgmaxall} sets -%\meta{cmd} globally. Example: -%\begin{verbatim} -%\DTLmaxall{\theMax}{25.1,45.2,35.6}\theMax -%\end{verbatim} -%produces: -%\DTLmaxall{\theMax}{25.1,45.2,35.6}\theMax. -%Note that if any of the numbers in \meta{number list} contain -%a comma, you must group the number. Example: -%\begin{verbatim} -%\DTLmaxall{\theMax}{{1,525},{2,340},500}\theMax -%\end{verbatim} -%produces: -%\DTLmaxall{\theMax}{{1,525},{2,340},500}\theMax. -% -%\begin{definition}[\DescribeMacro{\DTLmeanforall}]% -%\cs{DTLmeanforall}\marg{cmd}\marg{number list} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLgmeanall}]% -%\cs{DTLgmeanforall}\marg{cmd}\marg{number list} -%\end{definition} -%This sets the control sequence \meta{cmd} to the arithmetic mean of all -%the numbers in \meta{number list}. -%\cs{DLTmeanforall} sets \meta{cmd} locally, while \cs{DTLgmeanforall} sets -%\meta{cmd} globally. Example: -%\begin{verbatim} -%\DTLmeanforall{\theMean}{25.1,45.2,35.6}\theMean -%\end{verbatim} -%produces: -%\DTLmeanforall{\theMean}{25.1,45.2,35.6}\theMean. -%Note that if any of the numbers in \meta{number list} contain -%a comma, you must group the number. Example: -%\begin{verbatim} -%\DTLmeanforall{\theMean}{{1,525},{2,340},500}\theMean -%\end{verbatim} -%produces: -%\DTLmeanforall{\theMean}{{1,525},{2,340},500}\theMean. -% -%\begin{definition}[\DescribeMacro{\DTLvarianceforall}]% -%\cs{DTLvarianceforall}\marg{cmd}\marg{number list} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLgvarianceforall}]% -%\cs{DTLgvarianceforall}\marg{cmd}\marg{number list} -%\end{definition} -%This sets the control sequence \meta{cmd} to the variance of all -%the numbers in \meta{number list}. -%\cs{DLTvarianceforall} sets \meta{cmd} locally, while \cs{DTLgvarianceforall} sets -%\meta{cmd} globally. Example: -%\begin{verbatim} -%\DTLvarianceforall{\theVar}{25.1,45.2,35.6}\theVar -%\end{verbatim} -%produces: -%\DTLvarianceforall{\theVar}{25.1,45.2,35.6}\theVar. -%Again note that if any of the numbers in \meta{number list} -%contain a comma, you must group the number. -% -%\begin{definition}[\DescribeMacro{\DTLsdforall}]% -%\cs{DTLsdforall}\marg{cmd}\marg{number list} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLgsdforall}]% -%\cs{DTLgsdforall}\marg{cmd}\marg{number list} -%\end{definition} -%This sets the control sequence \meta{cmd} to the standard deviation of all -%the numbers in \meta{number list}. -%\cs{DLTsdforall} sets \meta{cmd} locally, while \cs{DTLgsdforall} sets -%\meta{cmd} globally. Example: -%\begin{verbatim} -%\DTLsdforall{\theSD}{25.1,45.2,35.6}\theSD -%\end{verbatim} -%produces: -%\DTLsdforall{\theSD}{25.1,45.2,35.6}\theSD. -%Note that if any of the numbers in \meta{number list} contain -%a comma, you must group the number. Example: -%\begin{verbatim} -%\DTLsdforall{\theSD}{{1,525},{2,340},500}\theSD -%\end{verbatim} -%produces: -%\DTLsdforall{\theSD}{{1,525},{2,340},500}\theSD. -% -%\begin{definition}[\DescribeMacro{\DTLround}]% -%\cs{DTLround}\marg{cmd}\marg{num}\marg{num digits} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLground}]% -%\cs{DTLground}\marg{cmd}\marg{num}\marg{num digits} -%\end{definition} -%This sets \meta{cmd} to \meta{num} rounded to \meta{num digits} -%after the decimal character. -%\cs{DLTround} sets \meta{cmd} locally, while \cs{DTLground} sets -%\meta{cmd} globally. Example: -%\begin{verbatim} -%\DTLround{\result}{3.135276}{2}\result -%\end{verbatim} -%produces: \DTLround{\result}{3.135276}{2}\result. -% -%\begin{definition}[\DescribeMacro{\DTLtrunc}]% -%\cs{DTLtrunc}\marg{cmd}\marg{num}\marg{num digits} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLgtrunc}]% -%\cs{DTLgtrunc}\marg{cmd}\marg{num}\marg{num digits} -%\end{definition} -%This sets \meta{cmd} to \meta{num} truncated to \meta{num digits} -%after the decimal character. -%\cs{DLTtrunc} sets \meta{cmd} locally, while \cs{DTLgtrunc} sets -%\meta{cmd} globally. Example: -%\begin{verbatim} -%\DTLtrunc{\result}{3.135276}{2}\result -%\end{verbatim} -%produces: \DTLtrunc{\result}{3.135276}{2}\result. -% -%\begin{definition}[\DescribeMacro{\DTLclip}]% -%\cs{DTLclip}\marg{cmd}\marg{num} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLgclip}]% -%\cs{DTLgclip}\marg{cmd}\marg{num} -%\end{definition} -%This sets \meta{cmd} to \meta{num} with all unnecessary 0's -%removed. -%\cs{DLTclip} sets \meta{cmd} locally, while \cs{DTLgclip} sets -%\meta{cmd} globally. -% -%\section{Strings} -%\label{sec:strings} -% -%Strings are considered to be anything non-numerical. The -%\sty{datatool} package loads the \sty{substr} package, so -%you can use the commands defined in that package to determine -%if one string is contained in another string. In addition, -%the \sty{datatool} provides the following macros: -% -%\begin{definition}[\DescribeMacro{\DTLsubstitute}]% -%\cs{DTLsubstitute}\marg{cmd}\marg{original}\marg{replacement} -%\end{definition} -%This replaces the first occurrence of \meta{original} in -%\meta{cmd} with \meta{replacement}. Note that \meta{cmd} must -%be the name of a command. For example: -%\begin{verbatim} -%\def\mystr{abcdce}\DTLsubstitute{\mystr}{c}{z}\mystr -%\end{verbatim} -%produces: -%\def\mystr{abcdce}\DTLsubstitute{\mystr}{c}{z}\mystr. -% -%\begin{definition}[\DescribeMacro{\DTLsubstituteall}]% -%\cs{DTLsubstituteall}\marg{cmd}\marg{original}\marg{replacement} -%\end{definition} -%This replaces all occurrences of \meta{original} in -%\meta{cmd} with \meta{replacement}, where again, \meta{cmd} must -%be the name of a command. For example: -%\begin{verbatim} -%\def\mystr{abcdce}\DTLsubstituteall{\mystr}{c}{z}\mystr -%\end{verbatim} -%produces: -%\def\mystr{abcdce}\DTLsubstituteall{\mystr}{c}{z}\mystr. -% -%\begin{definition}[\DescribeMacro{\DTLsplitstring}]% -%\cs{DTLsplitstring}\marg{string}\marg{split text}\marg{before -%cmd}\marg{after cmd} -%\end{definition} -%This splits \meta{string} at the first occurrence of \meta{split text} -%and stores the before part in the command \meta{before cmd} and -%the after part in the command \meta{after cmd}. For example: -%\begin{verbatim} -%\DTLsplitstring{abcdce}{c}{\beforepart}{\afterpart}% -%Before part: ``\beforepart''. After part: ``\afterpart'' -%\end{verbatim} -%produces: -%\DTLsplitstring{abcdce}{c}{\beforepart}{\afterpart}\relax -%Before part: ``\beforepart''. After part: ``\afterpart''. -%Note that for \cs{DTLsplitstring}, \meta{string} is not -%expanded, so -%\begin{verbatim} -%\def\mystr{abcdce}% -%\DTLsplitstring{\mystr}{c}{\beforepart}{\afterpart}% -%Before part: ``\beforepart''. After part: ``\afterpart'' -%\end{verbatim} -%produces: -%\def\mystr{abcdce}\relax -%\DTLsplitstring{\mystr}{c}{\beforepart}{\afterpart}% -%Before part: ``\beforepart''. After part: ``\afterpart''. If you -%want the string expanded, you will need to use \cs{expandafter}: -%\begin{verbatim} -%\def\mystr{abcdce}% -%\expandafter\DTLsplitstring\expandafter -%{\mystr}{c}{\beforepart}{\afterpart}% -%Before part: ``\beforepart''. After part: ``\afterpart'' -%\end{verbatim} -%which produces: -%\def\mystr{abcdce}\relax -%\expandafter\DTLsplitstring\expandafter -%{\mystr}{c}{\beforepart}{\afterpart}\relax -%Before part: ``\beforepart''. After part: ``\afterpart''. -% -%\begin{definition}[\DescribeMacro{\DTLinitials}]% -%\cs{DTLinitials}\marg{string} -%\end{definition} -%This converts \meta{string} (typically a name) into initials. -%For example: -%\begin{verbatim} -%\DTLinitials{Mary Ann} -%\end{verbatim} -%produces: -%\DTLinitials{Mary Ann} (including the final full stop). Note that -%\begin{verbatim} -%\DTLinitials{Mary-Ann} -%\end{verbatim} -%produces: -%\DTLinitials{Mary-Ann} (including the final full stop). -%Be careful if the initial letter has an -%accent. The accented letter needs to be placed in a group, if -%you want the initial to also have an accent, otherwise the -%accent command will be ignored. For example: -%\begin{verbatim} -%\DTLinitials{{\'E}lise Adams} -%\end{verbatim} -%produces: -%\DTLinitials{{\'E}lise Adams}, whereas -%\begin{verbatim} -%\DTLinitials{\'Elise Adams} -%\end{verbatim} -%produces: -%\DTLinitials{\'Elise Adams} In fact, any command which appears -%at the start of the name that is not enclosed in a group will -%be ignored. For example: -%\begin{verbatim} -%\DTLinitials{\MakeUppercase{m}ary ann} -%\end{verbatim} -%produces: -%\DTLinitials{\MakeUppercase{m}ary ann}, whereas -%\begin{verbatim} -%\DTLinitials{{\MakeUppercase{m}}ary ann} -%\end{verbatim} -%produces: -%\DTLinitials{{\MakeUppercase{m}}ary ann}, but note that -%\begin{verbatim} -%\DTLinitials{\MakeUppercase{mary ann}} -%\end{verbatim} -%produces: -%\DTLinitials{\MakeUppercase{mary ann}} -% -%\begin{definition}[\DescribeMacro{\DTLstoreinitials}]% -%\cs{DTLstoreinitials}\marg{string}\marg{cmd} -%\end{definition} -%This converts \meta{string} into initials and stores the -%result in \meta{cmd} which must be a command name. The remarks -%about \cs{DTLinitials} also relate to \cs{DTLstoreinitials}. -%For example -%\begin{verbatim} -%\DTLstoreinitials{Marie-{\'E}lise del~Rosario}{\theInitials}\theInitials -%\end{verbatim} -%produces: -%\DTLstoreinitials{Marie-{\'E}lise del~Rosario}{\theInitials}\theInitials -% -%Both the above commands rely on the following to format the -%initials: -%\begin{definition}[\DescribeMacro{\DTLafterinitials}]% -%\cs{DTLafterinitials} -%\end{definition} -%This indicates what to do at the end of the initials. This -%simply does a full stop by default. -% -%\begin{definition}[\DescribeMacro{\DTLbetweeninitials}]% -%\cs{DTLbetweeninitials} -%\end{definition} -%This indicates what to do between initials. This does a -%full stop by default. -% -%\begin{definition}[\DescribeMacro{\DTLinitialhyphen}]% -%\cs{DTLinitialhyphen} -%\end{definition} -%This indicates what to do at a hyphen. This simply does a hyphen -%by default, but can be redefined to do nothing to prevent the -%hyphen appearing in the initials. -% -%\begin{definition}[\DescribeMacro{\DTLafterinitialbeforehyphen}]% -%\cs{DTLafterinitialbeforehyphen} -%\end{definition} -%This indicates what to do between an initial and a hyphen. -%This simply does a full stop by default. -% -%For example -%\begin{verbatim} -%\renewcommand*{\DTLafterinitialbeforehyphen}{}% -%\DTLinitials{Marie-{\'E}lise del~Rosario} -%\end{verbatim} -%produces: -%{\renewcommand*{\DTLafterinitialbeforehyphen}{}\relax -%\DTLinitials{Marie-{\'E}lise del~Rosario}} -%whereas -%\begin{verbatim} -%\renewcommand*{\DTLafterinitialbeforehyphen}{}% -%\renewcommand*{\DTLafterinitials}{}% -%\renewcommand*{\DTLbetweeninitials}{}% -%\renewcommand*{\DTLinitialhyphen}{}% -%\DTLinitials{Marie-{\'E}lise del~Rosario} -%\end{verbatim} -%produces: -%{\renewcommand*{\DTLafterinitialbeforehyphen}{}\relax -%\renewcommand*{\DTLafterinitials}{}\relax -%\renewcommand*{\DTLbetweeninitials}{}\relax -%\renewcommand*{\DTLinitialhyphen}{}\relax -%\DTLinitials{Marie-{\'E}lise del~Rosario}} -% -%\section{Databases} -%\label{sec:databases} -% -%The \sty{datatool} package provides a means of creating and -%loading databases. Once a database has been created (or loaded), -%it is possible to iterate through each row of data, to make it -%easier to perform repetitive actions, such as mail merging. -% -%\importantpar Whilst \TeX\ is an excellent typesetting language, -%it is not designed as a database management system, and -%attempting to use it as such is like trying to fasten a screw -%with a knife instead of a screwdriver: it can be done, but requires -%great care and is more time consuming. Version 2.0 of the -%\sty{datatool} package uses a completely different method of storing -%the data to previous versions.\footnote{Thanks to Morten H\o gholm -%for the suggestion.} As a result, the code is much more efficient, -%however, large databases and complex operations will still slow the -%time taken to process your document. Therefore, if you can, it is -%better to do the complex operations using whatever system created -%the data in the first place. -% -%\subsection{Creating a New Database} -%\label{sec:newdb} -% -%\begin{definition}[\DescribeMacro{\DTLnewdb}]% -%\cs{DTLnewdb}\marg{db name} -%\end{definition} -%This command creates a new empty database called \meta{db name}. You -%can test if a database is empty using: -%\begin{definition}[\DescribeMacro{\DTLifdbempty}]% -%\cs{DTLifdbempty}\marg{db name}\marg{true part}\marg{false part} -%\end{definition} -%If the database called \meta{db name} is empty, do \meta{true part}, -%otherwise do \meta{false part}. -% -%\begin{definition}[\DescribeMacro{\DTLrowcount}]% -%\cs{DTLrowcount}\marg{db name} -%\end{definition} -%This command displays the number of rows in the database called -%\meta{db name}. -% -%\begin{definition}[\DescribeMacro{\DTLcolumncount}]% -%\cs{DTLcolumncount}\marg{db name} -%\end{definition} -%This command displays the number of columns (or keys) in the -%database called \meta{db name}. -% -%\begin{definition}[\DescribeMacro{\DTLnewrow}]% -%\cs{DTLnewrow}\marg{db name} -%\end{definition} -%This command starts a new row in the database called \meta{db name}. -%This new row becomes the current row when adding new entries. -% -%For example, the following creates an empty database called -%\texttt{mydata}: -%\begin{verbatim} -%\DTLnewdb{mydata} -%\end{verbatim} -%\DTLnewdb{mydata}\relax -%The following tests if the database is empty: -%\begin{verbatim} -%\DTLifdbempty{mydata}{empty}{not empty}! -%\end{verbatim} -%This produces: -%\DTLifdbempty{mydata}{empty}{not empty}! -% -%The following adds an empty row to the database, this is the -%first row of the database: -%\begin{verbatim} -%\DTLnewrow{mydata} -%\end{verbatim} -%\DTLnewrow{mydata}\relax -%Note that even though the only row in the database is currently -%empty, the database is no longer considered to be empty: -%\begin{verbatim} -%\DTLifdbempty{mydata}{empty}{not empty}! -%\end{verbatim} -%This now produces: -%\DTLifdbempty{mydata}{empty}{not empty}! The row count is -%given by -%\begin{verbatim} -%\DTLrowcount{mydata} -%\end{verbatim} -%which produces: -%\DTLrowcount{mydata}. The column count is given by -%\begin{verbatim} -%\DTLcolumncount{mydata} -%\end{verbatim} -%which produces: \DTLcolumncount{mydata}. -% -%\begin{definition}[\DescribeMacro{\DTLnewdbentry}]% -%\cs{DTLnewdbentry}\marg{db name}\marg{key}\marg{value} -%\end{definition} -%This creates a new entry with the identifier \meta{key} whose value -%is \meta{value} and adds it to the last row of the database -%called \meta{db name}. For example: -%\begin{verbatim} -%\DTLnewdbentry{mydata}{Surname}{Smith} -%\DTLnewdbentry{mydata}{FirstName}{John} -%\end{verbatim} -%Adds an entry with identifier \texttt{Surname} and value -%\texttt{Smith} to the last row of the database named -%\texttt{mydata}, and then adds an entry with identifier -%\texttt{FirstName} and value \texttt{John}. Note that the -%key should not contain any fragile commands. It is generally -%best to only use non-active characters in the key. -% -%The value isn't expanded by default, but you can change this -%using the declaration: -%\begin{definition}[\DescribeMacro{\dtlexpandnewvalue}] -%\cs{dtlexpandnewvalue} -%\end{definition} -%This can be localised by placing it in a group, or you can -%switch back using: -%\begin{definition}[\DescribeMacro{\dtlnoexpandnewvalue}] -%\cs{dtlnoexpandnewvalue} -%\end{definition} -% -%\importantpar Note that database entries can't contain paragraph -%breaks as many of the macros used by \sty{datatool} are short -%commands. If you do need a paragraph break in an entry, you can -%instead use the command: -%\begin{definition}[\DescribeMacro{\DTLpar}]% -%\cs{DTLpar} -%\end{definition} -% -%For example: -%\begin{verbatim} -%\DTLnewdbentry{mydata}{Description}{First paragraph.\DTLpar -%Second paragraph.} -%\end{verbatim} -% -%\begin{definition}[\DescribeMacro{\DTLaddentryforrow}]% -%\cs{DTLaddentryforrow}\marg{db}\marg{assign list}\marg{condition}\marg{key}\marg{value} -%\end{definition} -%This adds the entry with the key given by \meta{key} and value -%given by \meta{value} to the first row in the database -%\meta{db} which satisfies the condition given by -%\meta{condition}. The \meta{assign list} argument is the same -%as for \cs{DTLforeach} (described in \autoref{sec:dbforeach}) -%and may be used to set the values which are to be tested in -%\meta{condition} (where, again, \meta{condition} is the same -%as for \cs{DTLforeach}). For example: -%\begin{verbatim} -%\DTLaddentryforrow{mydata}{\firstname=FirstName,\surname=Surname}% -%{\DTLiseq{\firstname}{John}\and\DTLiseq{\surname}{Smith}}% -%{Score}{75} -%\end{verbatim} -%Note that unlike \cs{DTLnewdbentry}, the value is always expanded -%when adding an entry using \cs{DTLaddentryforrow}. -% -%\begin{definition}[\DescribeMacro{\DTLsetheader}]% -%\cs{DTLsetheader}\marg{db}\marg{key}\marg{header} -%\end{definition} -%This assigns a header for a given key in the database named -%\meta{db}. This is used by \cs{DTLdisplaydb} and -%\cs{DTLdisplaylongdb} in the header row (see -%\autoref{sec:displaydb}). If you don't assign -%a header, the header will be given by the key. -%For example: -%\begin{verbatim} -%\DTLsetheader{mydata}{Price}{Price (\$)} -%\end{verbatim} -% -%\subsection{Loading a Database from an External ASCII File} -%\label{sec:loaddb} -% -%Instead of using the commands described in \autoref{sec:newdb} -%to create a new database, you can load a database from an -%external ASCII file using: -%\begin{definition}[\DescribeMacro{\DTLloaddb}]% -%\cs{DTLloaddb}\oarg{options}\marg{db name}\marg{filename} -%\end{definition} -%This creates a new database called \meta{db name}, and fills -%it with the entries given in the file \meta{filename}. -%The filename may have a header row at the start of the file, -%which provides the \meta{key} when creating a new database entry -%using \ics{DTLnewdbentry}. The optional argument \meta{options} -%is a key=value list of options. Available options are: -%\begin{description} -%\item[\cmdopt{DTLloaddb}{noheader}] This is a boolean value and -%indicates if the file does not contain a header. If no value is -%supplied, "true" is assumed (i.e.\ the file doesn't contain a header -%row). If this option is omitted, it is assumed that the file -%contains a header row. -% -%\item[\cmdopt{DTLloaddb}{keys}] This is a comma-separated list of -%keys to use, where the keys are listed in the same order as the -%columns. If the file has a header, these keys will override the -%values given in the header row. If the file has no header row and no -%keys are supplied in \meta{options}, then the keys will be given by -%\cs{dtldefaultkey}\meta{n}, where \meta{n} is the column number and -%\DescribeMacro{\dtldefaultkey}\cs{dtldefaultkey} defaults to -%``\dtldefaultkey''. Note that the list of keys must be delimited by -%braces since they contain commas. For example: -%\begin{verbatim} -%\DTLloaddb[noheader,keys={Temperature,Time,T2G}]{data}{data.csv} -%\end{verbatim} -% -%\item[\cmdopt{DTLloaddb}{headers}] This is a comma-separated list of -%headers. If not supplied, the header will be the same as that given -%in the header row, or the key if there is no header row. Note that -%the list of headers must be delimited by braces since they contain -%commas. For example: -%\begin{verbatim} -%\DTLloaddb[noheader,keys={Temperature,Time,T2G},% -%headers={\shortstack{Incubation\\Temperature},% -%\shortstack{Incubation\\Time},% -%\shortstack{Time to\\Growth}}]{data}{data.csv} -%\end{verbatim} -%\end{description} -% -%By default, the entries in the database -%must be separated by a comma, and optionally delimited by the -%double quote character (\verb|"|). The separator can be changed -%to a tab separator using the command: -%\begin{definition}[\DescribeMacro{\DTLsettabseparator}]% -%\cs{DTLsettabseparator} -%\end{definition} -%To set the separator to a character other than a tab, you need to use -%\begin{definition}[\DescribeMacro{\DTLsetseparator}]% -%\cs{DTLsetseparator}\marg{character} -%\end{definition} -%The delimiter can be changed using -%\begin{definition}[\DescribeMacro{\DTLsetdelimiter}]% -%\cs{DTLsetdelimiter}\marg{character} -%\end{definition} -% -%For example, suppose you have a file called \texttt{mydata.csv} -%which contains the following: -%\begin{verbatim} -%FirstName,Surname,Score -%John,"Smith, Jr",68 -%Jane,Brown,75 -%Andy,Brown,42 -%Z\"oe,Adams,52 -%\end{verbatim} -%then -%\begin{verbatim} -%\DTLloaddb{mydata}{mydata.csv} -%\end{verbatim} -%is equivalent to: -%\begin{verbatim} -%\DTLnewdb{mydata} -%\DTLnewrow{mydata}% -%\DTLnewdbentry{mydata}{FirstName}{John}% -%\DTLnewdbentry{mydata}{Surname}{Smith, Jr}% -%\DTLnewdbentry{mydata}{Score}{68}% -%\DTLnewrow{mydata}% -%\DTLnewdbentry{mydata}{FirstName}{Jane}% -%\DTLnewdbentry{mydata}{Surname}{Brown}% -%\DTLnewdbentry{mydata}{Score}{75}% -%\DTLnewrow{mydata}% -%\DTLnewdbentry{mydata}{FirstName}{Andy}% -%\DTLnewdbentry{mydata}{Surname}{Brown}% -%\DTLnewdbentry{mydata}{Score}{42}% -%\DTLnewrow{mydata}% -%\DTLnewdbentry{mydata}{FirstName}{Z\"oe}% -%\DTLnewdbentry{mydata}{Score}{52}% -%\DTLnewdbentry{mydata}{Surname}{Adams}% -%\end{verbatim} -%Note that the entry \texttt{Smith, Jr} had to be delimited in -%\texttt{mydata.csv} using the double quote character since it -%contained a comma which is used as the separator. -% -%The file used in the above example contained a \LaTeX\ command, -%namely \verb|\"|. When using \ics{DTLloaddb} all the special -%characters that appear in the command retain their \LaTeX\ meaning -%when the file is loaded. It is likely however that the data file -%may have been created by another application that is not \TeX-aware, -%such as a spreadsheet application. For example, suppose you -%have a file called, say, \texttt{products.csv} which looks -%like: -%\begin{verbatim} -%Product,Cost -%Fruit & Veg,$1.25 -%Stationary,$0.80 -%\end{verbatim} -%This file contains two of \TeX's special characters, namely -%"&" and \verb|$|. In this case, if you try to load the file -%using \ics{DTLloaddb}, you will encounter errors. Instead you -%can use: -%\begin{definition}[\DescribeMacro{\DTLloadrawdb}]% -%\cs{DTLloadrawdb}\oarg{options}\marg{db name}\marg{filename} -%\end{definition} -%This is the same as \ics{DTLloaddb} except that it maps nine of -%the ten special characters onto commands which produce that -%symbol. The only character that retains its active state is the -%backslash character, so you will still need to check the file -%for backslash characters. The mappings used are listed in -%\autoref{tab:rawmappings}. So using the file \texttt{products.csv}, -%as described above, -%\begin{verbatim} -%\DTLloadrawdb{mydata}{products.csv} -%\end{verbatim} -%is equivalent to: -%\begin{verbatim} -%\DTLnewdb{mydata} -%\DTLnewrow{mydata}% -%\DTLnewdbentry{mydata}{Product}{Fruit \& Veg}% -%\DTLnewdbentry{mydata}{Cost}{\$1.25}% -%\DTLnewrow{mydata}% -%\DTLnewdbentry{mydata}{Product}{Stationary}% -%\DTLnewdbentry{mydata}{Cost}{\$0.80}% -%\end{verbatim} -% -%\begin{table}[htbp] -%\caption[Special character mappings used by -%\cs{DTLloadrawdb}]{Special character mappings used by -%\cs{DTLloadrawdb} (note that the backslash retains its active state)} -%\label{tab:rawmappings} -%\centering -%\begin{tabular}{cl} -%Character & Mapping\\ -%\verb|%| & \verb|\%|\\ -%\verb|$| & \verb|\$|\\ -%\verb|&| & \verb|\&|\\ -%\verb|#| & \verb|\#|\\ -%\verb|_| & \verb|\_|\\ -%\verb|{| & \verb|\{|\\ -%\verb|}| & \verb|\}|\\ -%\verb|~| & \cs{textasciitilde}\\ -%\verb|^| & \cs{textasciicircum} -%\end{tabular} -%\end{table} -% -%It may be that there are other characters that require mapping. -%For example, the file \texttt{products.csv} may instead look like:\par -%\vskip\baselineskip -%\begin{ttfamily}\obeylines\setlength{\parindent}{0pt} -%Product,Cost -%Fruit \& Veg,\pounds1.25 -%Stationary,\pounds0.80 -%\end{ttfamily} -%\vskip\baselineskip -%The pound character is not an internationally standard keyboard -%character, and does not generally achieve the desired effect when used -%in a \LaTeX\ document. It may therefore be necessary to convert -%this symbol to an appropriate control sequence. This can be done -%using the command: -%\begin{definition}[\DescribeMacro{\DTLrawmap}]% -%\cs{DTLrawmap}\marg{string}\marg{replacement} -%\end{definition} -%For example:\par -%\vskip\baselineskip -%\begin{ttfamily}\obeylines\setlength{\parindent}{0pt} -%\cs{DTLrawmap}\char`\{\pounds\char`\}\char`\{\cs{pounds}\char`\} -%\end{ttfamily} -%\vskip\baselineskip\noindent -%will replace all occurrences\footnote{when it is loaded into the -%\LaTeX\ database, it does not modify the data file!}\ of -%\texttt{\pounds} with \cs{pounds}. Naturally, the mappings must be -%set \emph{prior} to loading the data with \cs{DTLloadrawdb}. -% -%\importantpar Note that the warning in the previous section about no -%paragraph breaks in an entry also applies to entries loaded from a -%database. If you do need a paragraph break, use \ics{DTLpar} instead -%of \cs{par}, but remember that each row of data in an external data -%file must not have a line break. -% -%\subsection{Displaying the Contents of a Database} -%\label{sec:displaydb} -% -%Once you have created a database, either loading it from an -%external file, as described in \autoref{sec:loaddb}, or using the -%commands described in \autoref{sec:newdb}, you can display the -%entire database in a \env{tabular} or \env{longtable} -%environment. -% -%\begin{definition}[\DescribeMacro{\DTLdisplaydb}]% -%\cs{DTLdisplaydb}\marg{db} -%\end{definition} -%This displays the database given by \meta{db} in a \env{tabular} -%environment. The first row displays the headers for the database -%in bold, the subsequent rows display the values for each key -%in each row of the database. -% -%\begin{definition}[\DescribeMacro{\DTLdisplaylongdb}]% -%\cs{DTLdisplaylongdb}\oarg{options}\marg{db} -%\end{definition} -%This is like \cs{DTLdisplaydb} except that it uses the -%\env{longtable} environment instead of the \env{tabular} -%environment. Note that if you use this command, you must load the -%\sty{longtable} package, as it is not loaded by \sty{datatool}. -%The optional argument \meta{options} is a comma-separated list -%of key=value pairs. The following keys are available: -%\begin{description} -%\item[caption] The caption for the \env{longtable}. -% -%\item[contcaption] The continuation caption. -% -%\item[shortcaption] The caption to be used in the list of figures. -% -%\item[label] The label for this table. -% -%\item[foot] The \env{longtable}'s foot. -% -%\item[lastfoot] The foot for the last page of the \env{longtable}. -%\end{description} -%For example, suppose I have a database called "iris", then I can -%display the contents in a \env{longtable} using: -%\begin{verbatim} -%\DTLdisplaylongdb[% -%caption={Iris Data},% -%label={tab:iris},% -%contcaption={Iris Data (continued)},% -%foot={\em Continued overleaf},% -%lastfoot={}% -%]{iris} -%\end{verbatim} -%I can then reference the table using \verb|\ref{tab:iris}|. -% -%See the \sty{longtable} documentation for details on how to -%change the \env{longtable} settings, such as how to change the -%table so that it is left aligned instead of centred on the page. -% -%Note that if you want more control over the way the data is -%displayed, for example, you want to filter rows or columns, you will -%need to use \cs{DTLforeach}, described in \autoref{sec:dbforeach}. -% -%\begin{example}{Displaying the Contents of a Database}{ex:displaydb} -%Suppose I have a file called \texttt{t2g.csv} that contains the -%following: -%\begin{verbatim} -%40,120,40 -%40,90,60 -%35,180,20 -%55,190,40 -%\end{verbatim} -%This represents time to growth data, where the first column -%is the incubation temperature, the second column is the incubation -%time and the third column is the time to growth. This file has no -%header row, so when it is loaded, the \cmdopt{DTLloaddb}{noheaders} -%option is required. Note that \cs{DTLdisplaydb} only puts the data -%in a \env{tabular} environment, so \cs{DTLdisplaydb} needs to be -%put in a \env{table} environment with a caption to make it a float. -% -%First load the data base, setting the keys and headers: -%\begin{verbatim} -%\DTLloaddb[noheader,% -%keys={Temperature,Time,T2G},% -%headers={\shortstack{Incubation\\Temperature},% -%\shortstack{Incubation\\Time},\shortstack{Time to\\Growth}}% -%]{t2g}{t2g.csv} -%\end{verbatim} -%\DTLnewdb{t2g}\relax -%\DTLnewrow*{t2g}\relax -%\DTLnewdbentry*{t2g}{Temperature}{40}\relax -%\DTLnewdbentry*{t2g}{Time}{120}\relax -%\DTLnewdbentry*{t2g}{T2G}{40}\relax -%\DTLnewrow*{t2g}\relax -%\DTLnewdbentry*{t2g}{Temperature}{40}\relax -%\DTLnewdbentry*{t2g}{Time}{90}\relax -%\DTLnewdbentry*{t2g}{T2G}{60}\relax -%\DTLnewrow*{t2g}\relax -%\DTLnewdbentry*{t2g}{Temperature}{35}\relax -%\DTLnewdbentry*{t2g}{Time}{180}\relax -%\DTLnewdbentry*{t2g}{T2G}{20}\relax -%\DTLnewrow*{t2g}\relax -%\DTLnewdbentry*{t2g}{Temperature}{55}\relax -%\DTLnewdbentry*{t2g}{Time}{190}\relax -%\DTLnewdbentry*{t2g}{T2G}{40}\relax -%\DTLsetheader*{t2g}{Temperature}{\shortstack{Incubation\\Temperature}}\relax -%\DTLsetheader*{t2g}{Time}{\shortstack {Incubation\\Time}}\relax -%\DTLsetheader*{t2g}{T2G}{\shortstack {Time to\\Growth}}\relax -% -%Now display the data in a table: -%\begin{verbatim} -%\begin{table}[htbp] -%\caption{Time to Growth Data} -%\centering -%\DTLdisplaydb{t2g} -%\end{table} -%\end{verbatim} -%The result is shown in \autoref{tab:t2g}. -%\begin{table}[htbp] -%\caption{Time to Growth Data} -%\label{tab:t2g} -%\centering -%\DTLdisplaydb{t2g} -%\end{table} -%\end{example} -% -%Each column in the database has an associated data type which -%indicates what type of data is in that column. This may be one -%of: string, integer, real number or currency. If a column contains -%more than one type, the data type is determined as follows: -%\begin{itemize} -%\item If the column contains at least one string, then the column -%data type is string. -% -%\item If the column doesn't contain a string, but contains at least -%one currency, then the column data type is currency. -% -%\item If the column contains only real numbers and integers, the -%column data type is real number. -% -%\item The column data type is integer if the column only -%contains integers. -%\end{itemize} -%The column data type is updated whenever a new entry is added -%to the database. Note that the column data type is not adjusted -%when an entry is removed from the database. -% -%The column alignments used by \cs{DTLdisplaydb} are given by: -%\begin{definition}[\DescribeMacro{\dtlstringalign}]% -%\cs{dtlstringalign} -%\end{definition}\noindent -%The string alignment defaults to \texttt{l} (left aligned). -% -%\begin{definition}[\DescribeMacro{\dtlintalign}]% -%\cs{dtlintalign} -%\end{definition}\noindent -%The integer alignment defaults to \texttt{r} (right aligned). -% -%\begin{definition}[\DescribeMacro{\dtlrealalign}]% -%\cs{dtlrealalign} -%\end{definition}\noindent -%The alignment for real numbers defaults to \texttt{r} (right -%aligned). -% -%\begin{definition}[\DescribeMacro{\dtlcurrencyalign}]% -%\cs{dtlcurrencyalign} -%\end{definition}\noindent -%The currency alignment defaults to \texttt{r} (right aligned). -% -%You can redefine these to change the column alignments. For -%example, if you want columns containing strings to have the -%alignment "p{2in}", then you can redefine \cs{dtlstringalign} as -%follows: -%\begin{verbatim} -%\renewcommand{\dtlstringalign}{p{2in}} -%\end{verbatim} -% -%\importantpar You can't use \sty{siunitx}'s "S" column alignment -%with either \cs{DTLdisplaydb} or \cs{DTLdisplaylongdb}. Instead, you -%will need to use \cs{DTLforeach}. The \sty{siunitx} documentation -%provides an example. -% -%In addition to the \cs{dtl}\meta{type}"align" commands above, you -%can also modify the \env{tabular} column styles by redefining -%\DescribeMacro{\dtlbeforecols}\cs{dtlbeforecols}, -%\DescribeMacro{\dtlbetweencols}\cs{dtlbetweencols} and -%\DescribeMacro{\dtlaftercols}\cs{dtlaftercols}. For example, to -%place a vertical line before the start of the first column and -%after the last column, do: -%\begin{verbatim} -%\renewcommand{\dtlbeforecols}{|} -%\renewcommand{\dtlaftercols}{|} -%\end{verbatim} -%If you additionally want vertical lines between columns, do: -%\begin{verbatim} -%\renewcommand{\dtlbetweencols}{|} -%\end{verbatim} -% -%Limited modifications can be made to the way the data is displayed -%with \cs{DTLdisplaydb} and \cs{DTLdisplaylongdb}. -%The commands controlling the formatting are described below. -%If a more complicated layout is required, you will need to use -%\cs{DTLforeach} described in \autoref{sec:dbforeach}. -% -%\begin{definition}[\DescribeMacro{\dtlheaderformat}]% -%\cs{dtlheaderformat}\marg{header} -%\end{definition} -%This indicates how to format a column header, where the header is -%given by \meta{header}. This defaults to -%\cs{null}\cs{hfil}\cs{textbf}\marg{header}\cs{hfil}\cs{null}. -% -%\begin{definition}[\DescribeMacro{\dtlstringformat}]% -%\cs{dtlstringformat}\marg{text} -%\end{definition} -%This specifies how to format each entry in the columns that contain -%strings. This defaults to just displaying \meta{text}. -% -%\begin{definition}[\DescribeMacro{\dtlintformat}]% -%\cs{dtlintformat}\marg{text} -%\end{definition} -%This specifies how to format each entry in the columns that contain -%only integers. This defaults to just displaying \meta{text}. -% -%\begin{definition}[\DescribeMacro{\dtlrealformat}]% -%\cs{dtlrealformat}\marg{text} -%\end{definition} -%This specifies how to format each entry in the columns that contain -%only real numbers or a mixture of real numbers and integers. This -%defaults to just displaying \meta{text}. -% -%\begin{definition}[\DescribeMacro{\dtlcurrencyformat}]% -%\cs{dtlcurrencyformat}\marg{text} -%\end{definition} -%This specifies how to format each entry in the columns that contain -%only currency or currency mixed with real numbers and/or integers. -%This defaults to just displaying \meta{text}. -% -%\begin{definition}[\DescribeMacro{\dtldisplaystarttab}]% -%\cs{dtldisplaystarttab} -%\end{definition} -%This is a hook to add something at the beginning of the -%\env{tabular} environment. This defaults to nothing. -% -%\begin{definition}[\DescribeMacro{\dtldisplayendtab}]% -%\cs{dtldisplayendtab} -%\end{definition} -%This is a hook to add something at the end of the -%\env{tabular} environment. This defaults to nothing. -% -%\begin{definition}[\DescribeMacro{\dtldisplayafterhead}]% -%\cs{dtldisplayafterhead} -%\end{definition} -%This is a hook to add something after the header row, before -%the first row of data. This defaults to nothing. -% -%\begin{definition}[\DescribeMacro{\dtldisplaystartrow}]% -%\cs{dtldisplaystartrow} -%\end{definition} -%This is a hook to add something at the start of each row, but -%not including the header row or the first row of data. This -%defaults to nothing. -% -%\begin{example}{Balance Sheet}{ex:balance} -%Suppose you have a file called "balance.csv" that contains -%the following: -%\begin{verbatim} -%Description,In,Out,Balance -%Travel expenses,,230,-230 -%Conference fees,,400,-630 -%Grant,700,,70 -%Train fare,,70,0 -%\end{verbatim} -%\DTLnewdb{balance}\relax -%\DTLnewrow{balance}\relax -%\DTLnewdbentry{balance}{Description}{Travel expenses}\relax -%\DTLnewdbentry{balance}{In}{}\relax -%\DTLnewdbentry{balance}{Out}{230.00}\relax -%\DTLnewdbentry{balance}{Balance}{-230.00}\relax -%\DTLnewrow{balance}\relax -%\DTLnewdbentry{balance}{Description}{Conference fees}\relax -%\DTLnewdbentry{balance}{In}{}\relax -%\DTLnewdbentry{balance}{Out}{400.00}\relax -%\DTLnewdbentry{balance}{Balance}{-630.00}\relax -%\DTLnewrow{balance}\relax -%\DTLnewdbentry{balance}{Description}{Grant}\relax -%\DTLnewdbentry{balance}{In}{700.00}\relax -%\DTLnewdbentry{balance}{Out}{}\relax -%\DTLnewdbentry{balance}{Balance}{70.00}\relax -%\DTLnewrow{balance}\relax -%\DTLnewdbentry{balance}{Description}{Train Fare}\relax -%\DTLnewdbentry{balance}{In}{}\relax -%\DTLnewdbentry{balance}{Out}{70.00}\relax -%\DTLnewdbentry{balance}{Balance}{0.00}\relax -%\DTLsetheader{balance}{In}{In (\pounds)}\relax -%\DTLsetheader{balance}{Out}{Out (\pounds)}\relax -%\DTLsetheader{balance}{Balance}{Balance (\pounds)}\relax -%The data can be loaded using: -%\begin{verbatim} -%\DTLloaddb[headers={Description,In (\pounds),Out (\pounds),Balance -%(\pounds)}]{balance}{balance.csv} -%\end{verbatim} -% -%Suppose I want negative numbers to be displayed in red. I can do -%this by redefining \cs{dtlrealformat} to check if the entry -%is negative. For example: -%\begin{verbatim} -%\begin{table}[htbp] -%\caption{Balance Sheet} -%\renewcommand*{\dtlrealformat}[1]{\DTLiflt{#1}{0}{\color{red}}{}#1} -%\centering -%\DTLdisplaydb{balance} -%\end{table} -%\end{verbatim} -%This produces \autoref{tab:balance}. -%\begin{table}[htbp] -%\caption{Balance Sheet} -%\label{tab:balance} -%\renewcommand*{\dtlrealformat}[1]{\DTLiflt{#1}{0}{\color{red}}{}#1} -%\centering -%\DTLdisplaydb{balance} -%\end{table} -%\end{example} -% -%\subsection{Iterating Through a Database} -%\label{sec:dbforeach} -% -%Once you have created a database, either loading it from an -%external file, as described in \autoref{sec:loaddb}, or using the -%commands described in \autoref{sec:newdb}, you can then iterate -%through each row of the database and access elements in that row. -% -%\begin{definition}[\DescribeMacro{\DTLforeach}]% -%\cs{DTLforeach}\oarg{condition}\marg{db name}\marg{assign list}\marg{text} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLforeach*}]% -%\cs{DTLforeach*}\oarg{condition}\marg{db name}\marg{assign list}\marg{text} -%\end{definition} -%This will iterate through each row of the database called -%\meta{db name}, applying \meta{text} to each row of the database -%where \meta{condition} is met. The argument \meta{assign list} is a -%comma separated list of \meta{cmd}"="\meta{key} pairs. At the -%start of each row, each command \meta{cmd} in \meta{assign list} -%will be set to the value of the entry given by \meta{key}. -%These commands may then be used in \meta{text}. -% -%\importantpar Note that this assignment is done globally to ensure -%that \cs{DLTforeach} works correctly in a \env{tabular} environment. -%Since you may want to use the same set of commands in a later -%\cs{DTLforeach}, the commands are not checked to determine if they -%already exist. It is therefore important that you check you are not -%using an existing command whose value should not be changed. -% -%The optional argument \meta{condition} is a condition in the -%form allowed by \cs{ifthenelse}. This includes the commands -%provided by the \sty{ifthen} package (such as \cs{not}, \cs{and}, -%\cs{or}), as well as the commands -%described in \autoref{sec:ifthen}. The default value of -%\meta{condition} is "\boolean{true}". -% -%The starred version \cs{DTLforeach*} is a read-only version. -%If you want to modify the database using any of the commands -%described in \autoref{sec:editdb}, you must use the unstarred -%version. The starred version is faster. -% -%\begin{example}{Student scores}{ex:scores} -%Suppose you have a data file called \texttt{studentscores.csv} that -%contains the following: -%\begin{verbatim} -%FirstName,Surname,StudentNo,Score -%John,"Smith, Jr",102689,68 -%Jane,Brown,102647,75 -%Andy,Brown,103569,42 -%Z\"oe,Adams,105987,52 -%Roger,Brady,106872,58 -%Clare,Verdon,104356,45 -%\end{verbatim} -%\DTLnewdb{scores}\relax -%\DTLnewrow{scores}\relax -%\DTLnewdbentry{scores}{FirstName}{John}\relax -%\DTLnewdbentry{scores}{Surname}{Smith, Jr}\relax -%\DTLnewdbentry{scores}{StudentNo}{102689}\relax -%\DTLnewdbentry{scores}{Score}{68}\relax -%\DTLnewrow{scores}\relax -%\DTLnewdbentry{scores}{FirstName}{Jane}\relax -%\DTLnewdbentry{scores}{Surname}{Brown}\relax -%\DTLnewdbentry{scores}{StudentNo}{102647}\relax -%\DTLnewdbentry{scores}{Score}{75}\relax -%\DTLnewrow{scores}\relax -%\DTLnewdbentry{scores}{FirstName}{Andy}\relax -%\DTLnewdbentry{scores}{Surname}{Brown}\relax -%\DTLnewdbentry{scores}{StudentNo}{103569}\relax -%\DTLnewdbentry{scores}{Score}{42}\relax -%\DTLnewrow{scores}\relax -%\DTLnewdbentry{scores}{FirstName}{Z\"oe}\relax -%\DTLnewdbentry{scores}{Score}{52}\relax -%\DTLnewdbentry{scores}{StudentNo}{105987}\relax -%\DTLnewdbentry{scores}{Surname}{Adams}\relax -%\DTLnewrow{scores}\relax -%\DTLnewdbentry{scores}{FirstName}{Roger}\relax -%\DTLnewdbentry{scores}{Score}{58}\relax -%\DTLnewdbentry{scores}{StudentNo}{106872}\relax -%\DTLnewdbentry{scores}{Surname}{Brady}\relax -%\DTLnewrow{scores}\relax -%\DTLnewdbentry{scores}{FirstName}{Clare}\relax -%\DTLnewdbentry{scores}{Score}{45}\relax -%\DTLnewdbentry{scores}{StudentNo}{104356}\relax -%\DTLnewdbentry{scores}{Surname}{Verdon}\relax -%and you load the data into a database called "scores" using: -%\begin{verbatim} -%\DTLloaddb{scores}{studentscores.csv} -%\end{verbatim} -%you can then display the database in a table as follows: -%\begin{verbatim} -%\begin{table}[htbp] -%\caption{Student scores} -%\centering -%\begin{tabular}{llr} -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Score (\%)% -%\DTLforeach{scores}{% -%\firstname=FirstName,\surname=Surname,\score=Score}{% -%\\ -%\firstname & \surname & \score} -%\end{tabular} -%\end{table} -%\end{verbatim} -%This produces \autoref{tab:scores}. (Note that since I didn't -%need the student registration number, I didn't bother to -%assign a command to the key "StudentNo".) -% -%\begin{table}[htbp] -%\caption[Student scores (displaying a database in a -%table)]{Student scores}\label{tab:scores} -%\centering -%\begin{tabular}{llr} -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Score (\%)\relax -%\DTLforeach{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax -%\\ -%\firstname & \surname & \score} -%\end{tabular} -%\end{table} -%\end{example} -% -%The macro \ics{DTLforeach} may be nested up to three times. Each -%level uses the corresponding counters: -%\desctr{DTLrowi}, -%\desctr{DTLrowii} and -%\desctr{DTLrowiii} which keep track of -%the current row. -% -%\importantpar Note that these counters are only incremented when -%\meta{condition} is satisfied, therefore they will not have the -%correct value in \meta{condition}. These counters are incremented -%using \cs{refstepcounter} before the start of \meta{text}, so they -%may be referenced using \cs{label}, however remember that \cs{label} -%references the last counter to be incremented using -%\cs{refstepcounter} \emph{in the current scope}. The \cs{label} -%should therefore be the first command in \meta{text} to ensure that -%it references the current row counter. -% -%\begin{definition}[\DescribeMacro{\DTLcurrentindex}]% -%\cs{DTLcurrentindex} -%\end{definition} -%At the start of each iteration in \cs{DTLforeach}, -%\cs{DTLcurrentindex} is set to the arabic value of the current row -%counter. Note that this is only set after the condition is tested, -%so it should only be used in the body of \cs{DTLforeach} not in -%the condition. It is also only set locally, so if you use it in -%a tabular environment, it can only be used before the first instance -%of \verb|\\| or \verb|&| in the current iteration. -% -%Within the body of \ics{DTLforeach} (i.e.\ within \meta{text}) -%the following conditionals may be used: -%\begin{definition}[\DescribeMacro{\DTLiffirstrow}]% -%\cs{DTLiffirstrow}\marg{true part}\marg{false part} -%\end{definition} -%If the current row is the first row, then do \meta{true part}, -%otherwise do \meta{false part}. -% -%\begin{definition}[\DescribeMacro{\DTLifoddrow}]% -%\cs{DTLifoddrow}\marg{true part}\marg{false part} -%\end{definition} -%If the current row number is an odd number, then do \meta{true part}, -%otherwise do \meta{false part}. -% -%\begin{definition}[\DescribeMacro{\DTLsavelastrowcount}]% -%\cs{DTLsavelastrowcount}\marg{cmd} -%\end{definition} -%This command will store the value of the row counter used in -%the last occurrence of \ics{DTLforeach} in the control sequence -%\meta{cmd}. -% -%\begin{definition}[\DescribeMacro{\DTLforeachkeyinrow}]% -%\cs{DTLforeachkeyinrow}\marg{cmd}\marg{text} -%\end{definition} -%This iterates through each key in the current row, (globally) assigns -%\meta{cmd} to the value of that key, and does \meta{text} -%(\meta{cmd} must be a control sequence and may be used in -%\meta{text}). This command may only be used in the body of -%\cs{DTLforeach}. At each iteration, \cs{DTLforeachkeyinrow} sets -%\cs{dtlkey} to the current key, \cs{dtlcol} to the current column -%index, \cs{dtltype} to the data type for the current column, -%and \cs{dtlheader} to the header for the current column. Note that -%\cs{dtltype} corresponds to the column type but if the entries in -%the column have mixed types, it may not correspond to the type -%of the current entry. -% -%\begin{definition}[\DescribeMacro{\dtlbreak}]% -%\cs{dtlbreak} -%\end{definition} -%You can break out of most of the loops provided by \sty{datatool} -%using \cs{dtlbreak}. Note, however, that it doesn't break the loop -%until the end of the current iteration. There is no provision for -%a "next" or "continue" style command. -% -%Additional loop commands provided by \sty{datatool} are -%described in \autoref{sec:code:loops}. -% -%\begin{example}{Student Scores---Labelling}{ex:label} -%In the previous example, the student scores, stored in the -%database "scores" were placed in a table. In this example the -%table will be modified slightly to number each student according -%to the row. Suppose I also want to identify which row Jane Brown -%is in, and reference it in the text. The easiest way to do this -%is to construct a label on each row which uniquely identifies -%that student. The label can't simply be constructed from the -%surname, as there are two students with the same surname. In order -%to create a unique label, I can either construct a label from -%both the surname and the first name, or I can use the student's -%registration number, or I can use the student's score, since all -%the scores are unique. The former method will cause a problem since -%one of the names (Z\"oe) contains an accent command. Although -%the registration numbers are all unique, they are not particularly -%memorable, so I shall instead use the scores. -%\begin{verbatim} -%\begin{table}[htbp] -%\caption{Student scores} -%\centering -%\begin{tabular}{cllc} -%\bfseries Row & -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Score (\%)% -%\DTLforeach*{scores}{% -%\firstname=FirstName,\surname=Surname,\score=Score}{% -%\label{row:\score}\\\theDTLrowi & -%\firstname & \surname & \score}% -%\end{tabular} -%\end{table} -% -%Jane Brown scored the highest (75\%), her score can be seen on -%row~\ref{row:75}. -%\end{verbatim} -%This produces \autoref{tab:scoreslab} and the following text: -%Jane Brown scored the highest (75\%), her score can be seen on -%row~\ref*{row:75}. -% -%Notes: -%\begin{itemize} -%\item the \cs{label} command is placed before -%"\\" to ensure that it is in the same scope as the command -%"\refstepcounter{DTLrowi}". -% -%\item To avoid unwanted spaces the end of line characters are -%commented out with the percent (\texttt{\%}) symbol. -%\end{itemize} -% -%\begin{table}[htbp] -%\caption[Student scores (labelling rows)]{Student -%scores}\label{tab:scoreslab} -%\centering -%\begin{tabular}{cllc} -%\bfseries Row & -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Score (\%)\relax -%\DTLforeach*{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax -%\label{row:\score}\\\theDTLrowi & -%\firstname & \surname & \score}\relax -%\end{tabular} -%\end{table} -%\end{example} -% -%\begin{example}{Filtering Rows}{ex:filter} -%As mentioned earlier, the optional argument \meta{condition} of -%\ics{DTLforeach} provides a means to exclude certain rows. -%This example uses the database defined in \autoref{ex:scores}, -%but only displays the information for students whose marks are -%above 60. At the end of the table, \cs{DTLsavelastrowcount} -%is used to store the number of rows in the table. (Note that -%\cs{DTLsavelastrowcount} is outside of \ics{DTLforeach}.) -%\begin{verbatim} -%\begin{table}[htbp] -%\caption{Top student scores} -%\centering -%\begin{tabular}{llr} -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Score (\%)% -%\DTLforeach*[\DTLisgt{\score}{60}]{scores}{% -%\firstname=FirstName,\surname=Surname,\score=Score}{% -%\\ -%\firstname & \surname & \score} -%\end{tabular} -% -%\DTLsavelastrowcount{\n}% -%\n\ students scored above 60\%. -%\end{table} -%\end{verbatim} -%This produces \autoref{tab:topscores}. Note that in this example, -%I could have specified the condition as "\score>60" since all -%the scores are integers, however, as it's possible that an entry -%may feasibly have a decimal score I have used \ics{DTLisgt} instead. -% -%\begin{table}[htbp] -%\caption[Top student scores (filtering rows using -%\cs{DTLisgt})]{Top student scores}\label{tab:topscores} -%\centering -%\begin{tabular}{llr} -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Score (\%)\relax -%\DTLforeach*[\DTLisgt{\score}{60}]{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax -%\\ -%\firstname & \surname & \score} -%\end{tabular} -% -%\DTLsavelastrowcount{\n}\relax -%\n\ students scored above 60\%. -%\end{table} -% -%Suppose now, I only want to display the scores for students whose -%surname begins with `B'. I can do this as follows: -%\begin{verbatim} -%\begin{table}[htbp] -%\caption{Student scores (B)} -%\centering -%\begin{tabular}{llr} -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Score (\%)% -%\DTLforeach*[\DTLisopenbetween{\surname}{B}{C}]{scores}{% -%\firstname=FirstName,\surname=Surname,\score=Score}{% -%\\ -%\firstname & \surname & \score} -%\end{tabular} -%\end{table} -%\end{verbatim} -%This produces \autoref{tab:Bscores}. -% -%\begin{table}[htbp] -%\caption[Student scores (B) --- filtering rows using -%\cs{DTLisopenbetween}]{Student scores (B)}\label{tab:Bscores} -%\centering -%\begin{tabular}{llr} -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Score (\%)\relax -%\DTLforeach*[\DTLisopenbetween{\surname}{B}{C}]{scores} -%{\firstname=FirstName,\surname=Surname,\score=Score}{\relax -%\\ -%\firstname & \surname & \score} -%\end{tabular} -%\end{table} -% -%\end{example} -% -%\begin{example}{Breaking Out of a Loop}{ex:dtlbreak} -%Suppose I only want to display the first three rows of a database. -%I could do:\footnote{Recall that \ctr{DTLrowi} is incremented -%after the condition is tested, so it will be out by 1 when the -%condition is tested which is why \texttt{<3} is used instead of -%\texttt{<4}.} -%\begin{verbatim} -%\DTLforeach*[\value{DTLrowi}<3]{scores}% -%{\firstname=FirstName,\surname=Surname,\score=Score}{% -%\\\firstname & \surname & \score -%} -%\end{verbatim} -%However, this isn't very efficient, as it still has to iterate -%through the entire database, checking if the condition is met. If -%the database has over 100 entries, this will slow the time taken -%to create the table. It would therefore be much more efficient -%to break out of the loop when row count exceeds 3: -%\begin{verbatim} -%\begin{table}[htbp] -%\caption{First Three Rows} -%\centering -%\begin{tabular}{llr} -%\bfseries First Name & \bfseries Surname & \bfseries Score (\%)% -%\DTLforeach*{scores}% -%{\firstname=FirstName,\surname=Surname,\score=Score}{% -%\ifthenelse{\DTLcurrentindex=3}{\dtlbreak}{}% -%\\\firstname & \surname & \score -%}% -%\end{tabular} -%\end{table} -%\end{verbatim} -%This produces \autoref{tab:dtlbreak}. Note that the loop is not -%broken until the end of the current iteration, so even though -%\cs{dtlbreak} occurs at the start of the third row, the loop isn't -%finished until the third row is completed. (Recall that -%\cs{DTLcurrentindex} must be used before the first instance of -%\verb|\\| or \verb|&|.) Alternatively, you can use -%\ctr{DTLrowi} instead: -%\begin{verbatim} -%\DTLforeach{scores}% -%{\firstname=FirstName,\surname=Surname,\score=Score}{% -%\\\firstname & \surname & \score -%\ifthenelse{\value{DTLrowi}=3}{\dtlbreak}{}% -%}% -%\end{verbatim} -% -%\begin{table}[htbp] -%\caption{First Three Rows} -%\label{tab:dtlbreak}% -%\centering -%\begin{tabular}{llr} -%\bfseries First Name & \bfseries Surname & \bfseries Score (\%)\relax -%\DTLforeach*{scores}% -%{\firstname=FirstName,\surname=Surname,\score=Score}{% -%\ifthenelse{\DTLcurrentindex=3}{\dtlbreak}{}\relax -%\\\firstname & \surname & \score -%}% -%\end{tabular} -%\end{table} -%\end{example} -% -%\begin{example}{Stripy Tables}{ex:stripy} -%This example uses the same database as in the previous examples. -%It requires the \sty{colortbl} package, which provides the -%command \cs{rowcolor}. The command \cs{DTLifoddrow} is used -%to produce a striped table. -%\begin{verbatim} -%\begin{table}[htbp] -%\caption{A stripy table}\label{tab:stripy} -%\centering -%\begin{tabular}{llc} -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Score (\%)% -%\DTLforeach*{scores}{% -%\firstname=FirstName,\surname=Surname,\score=Score}{% -%\\\DTLifoddrow{\rowcolor{blue}}{\rowcolor{green}}% -%\firstname & \surname & \score}% -%\end{tabular} -%\end{table} -%\end{verbatim} -%This produces \autoref{tab:stripy}. -% -%\begin{table}[htbp] -%\caption[A stripy table (illustrating the use of -%\cs{DTLifoddrow})]{A stripy table}\label{tab:stripy} -%\centering -%\begin{tabular}{llc} -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Score (\%)\relax -%\DTLforeach*{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax -%\\\DTLifoddrow{\rowcolor{blue}}{\rowcolor{green}}\relax -%\firstname & \surname & \score}\relax -%\end{tabular} -%\end{table} -%\end{example} -% -%\begin{example}{Two Database Rows per Tabular Row}{ex:2rows} -%In order to save space, you may want two database rows per -%tabular row, when displaying a database in a \env{tabular} -%environment. This can be accomplished using \ics{DTLifoddrow}. -%For example -%\begin{verbatim} -%\begin{table}[htbp] -%\caption{Two database rows per tabular row} -%\centering -%\begin{tabular}{llcllc} -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Score (\%) & -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Score (\%)% -%\DTLforeach*{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{% -%\DTLifoddrow{\\}{&}% -%\firstname & \surname & \score}% -%\end{tabular} -%\end{table} -%\end{verbatim} -%produces \autoref{tab:2rows} -% -%\begin{table}[htbp] -%\caption[Two database rows per tabular row (illustrating the -%use of\newline \cs{DTLifoddrow})]{Two database rows per tabular -%row}\label{tab:2rows} -%\centering -%\begin{tabular}{llcllc} -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Score (\%) & -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Score (\%)\relax -%\DTLforeach*{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax -%\DTLifoddrow{\\}{&}\relax -%\firstname & \surname & \score}\relax -%\end{tabular} -%\end{table} -%\end{example} -% -%\begin{example}{Iterating Through Keys in a Row}{ex:foreachkey} -%Suppose you have lots of columns in your database, and you -%want to display them all without having to set a variable for -%each column. You can leave the assignment list in \cs{DTLforeach} -%blank, and iterate through the keys using \cs{DTLforeachkeyinrow}. -%For example: -%\begin{verbatim} -%\begin{table}[htbp] -%\caption{Student Scores (Iterating Through Keys)} -%\centering -%\begin{tabular}{llll} -%\bfseries First Name & \bfseries Surname & -%\bfseries Registration No. & -%\bfseries Score (\%)% -%\DTLforeach*{scores}{}{% -%\\\gdef\doamp{\gdef\doamp{&}}% -%\DTLforeachkeyinrow{\thisValue}{\doamp\thisValue}}% -%\end{tabular} -%\end{table} -%\end{verbatim} -%This produces \autoref{tab:foreachkey}. -%\begin{table}[htbp] -%\caption{Student Scores (Iterating Through Keys)} -%\label{tab:foreachkey} -%\centering -%\begin{tabular}{llll} -%\bfseries First Name & \bfseries Surname & -%\bfseries Registration No. & -%\bfseries Score (\%)\relax -%\DTLforeach*{scores}{}{% -%\\\gdef\doamp{\gdef\doamp{&}}\relax -%\DTLforeachkeyinrow{\thisValue}{\doamp\thisValue}}\relax -%\end{tabular} -%\end{table} -% -%Note that the "&" must be between columns, so I have defined -%a command called \cs{doamp} that on first use redefines -%itself to do "&". So, for each row, at the start of -%the key iteration, \cs{doamp} does nothing, and on subsequent -%iterations it does "&". This ensures that the correct number of -%"&"s are used. Since each cell in the \env{tabular} environment -%is scoped, \cs{gdef} is needed instead of \cs{def}. -% -%In the above, I needed to know how many columns are in the -%database, and the order that the headings should appear. If you -%are unsure, you can use \cs{dtlforeachkey} to determine the -%number of columns and to display the header row. For example: -%\begin{verbatim} -% \begin{table}[htbp] -% \caption{Student Scores} -% \centering -% % Work out the column alignments. -% \def\colalign{}% -% \dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do -% {\edef\colalign{\colalign l}}% -% % Begin the tabular environment. -% \edef\dobegintabular{\noexpand\begin{tabular}{\colalign}}% -% \dobegintabular -% % Do the header row. -% \gdef\doamp{\gdef\doamp{&}}% -% \dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do -% {\doamp\bfseries \theHead}% -% % Iterate through the data. -% \DTLforeach*{scores}{}{% -% \\\gdef\doamp{\gdef\doamp{&}}% -% \DTLforeachkeyinrow{\thisValue}{\doamp\thisValue}}% -% \end{tabular} -% \end{table} -%\end{verbatim} -% -%\begin{table}[htbp] -%\caption{Student Scores (Using \cs{dtlforeachkey} and -%\cs{DTLforeachkeyinrow})} -%\label{tab:foreachkey2} -%\centering -%\def\colalign{}% -%\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do -%{\edef\colalign{\colalign l}}% -%\edef\dobegintabular{\noexpand\begin{tabular}{\colalign}}\relax -%\dobegintabular -%\gdef\doamp{\gdef\doamp{&}}\relax -%\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do -%{\doamp\bfseries \theHead}\relax -%\DTLforeach*{scores}{}{% -%\\\gdef\doamp{\gdef\doamp{&}}\relax -%\DTLforeachkeyinrow{\thisValue}{\doamp\thisValue}}\relax -%\end{tabular} -%\end{table} -% -%Notes: -%\begin{itemize} -%\item In order to determine the column alignment for the -%\env{tabular} environment, I first define \cs{colalign} to -%nothing, and then I iterate through the keys appending -%\texttt{l} to \cs{colalign}. Since \cs{colalign} only contains -%alphabetical characters, I can just use \cs{edef} for this. I -%could modify this to check the data type and, say, use \texttt{l} -%(left alignment) for columns containing strings and \texttt{c} -%(centred) for the other columns: -%\begin{verbatim} -%\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do -%{\ifnum\theType=0\relax -% \edef\colalign{\colalign l}% column contains strings -% \else -% \edef\colalign{\colalign c}% column contains numerical values -% \fi -%}% -%\end{verbatim} -% -%\item To ensure \cs{colalign} gets correct expanded when passed -%to the \env{tabular} environment I temporarily define -%\cs{dobegintabular} to the code required to start the -%\env{tabular} environment: -%\begin{verbatim} -%\edef\dobegintabular{\noexpand\begin{tabular}{\colalign}}% -%\end{verbatim} -%This sets \cs{dobegintabular} to \verb|\begin{tabular}{llll}|. -%After defining \cs{dobegintabular}, I then need to use it. -% -%\item As before, I use \cs{doamp} to put the ampersands between -%columns. -% -%\item Recall that I can set the headers using \cs{DTLsetheader} -%or using the \cmdopt{DTLloaddb}{headers} key when loading the data -%from an external file. For example: -%\begin{verbatim} -%\DTLsetheaders{scores}{FirstName}{First Name} -%\DTLsetheaders{scores}{Score}{Score (\%)} -%\end{verbatim} -%\end{itemize} -% -%Recall that \cs{DTLforeachkeyinrow} sets \cs{dtlkey} to the -%current key. This can be used to filter out columns. Alternatively, -%if you know the column index, you can test \cs{dtlcol} instead. -%The following code modifies the above example so that it filters -%out the column whose key is \texttt{StudentNo}: -%\begin{verbatim} -%\begin{table}[htbp] -%\caption{Student Scores (Filtering Out a Column)} -%\centering -%\def\colalign{}% -%\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do -%{\DTLifeq{\theKey}{StudentNo}{}{\edef\colalign{\colalign l}}}% -%\edef\dobegintabular{\noexpand\begin{tabular}{\colalign}}% -%\dobegintabular -%\gdef\doamp{\gdef\doamp{&}}% -%\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do -%{\DTLifeq{\theKey}{StudentNo}{}{\doamp\bfseries \theHead}}% -%\DTLforeach*{scores}{}{% -%\\\gdef\doamp{\gdef\doamp{&}}% -%\DTLforeachkeyinrow{\thisValue}{% -% \DTLifeq{\dtlkey}{StudentNo}{}{\doamp\thisValue}}}% -%\end{tabular} -%\end{table} -%\end{verbatim} -%The result is shown in \autoref{tab:foreachkey3}. -% -%\begin{table}[htbp] -%\caption{Student Scores (Filtering Out a Column)} -%\label{tab:foreachkey3} -%\centering -%\def\colalign{}% -%\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do -%{\DTLifeq{\theKey}{StudentNo}{}{\edef\colalign{\colalign l}}}% -%\edef\dobegintabular{\noexpand\begin{tabular}{\colalign}}\relax -%\dobegintabular -%\gdef\doamp{\gdef\doamp{&}}\relax -%\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do -%{\DTLifeq{\theKey}{StudentNo}{}{\doamp\bfseries \theHead}}\relax -%\DTLforeach*{scores}{}{% -%\\\gdef\doamp{\gdef\doamp{&}}\relax -%\DTLforeachkeyinrow{\thisValue}{\relax -%\DTLifeq{\dtlkey}{StudentNo}{}{\doamp\thisValue}}}\relax -%\end{tabular} -%\end{table} -%\end{example} -% -%\begin{example}{Nested \cs{DTLforeach}}{ex:nested} -%In this example I have a CSV file called "index.csv" which -%contains: -%\begin{verbatim} -%File,Temperature,NaCl,pH -%exp25a.csv,25,4.7,0.5 -%exp25b.csv,25,4.8,1.5 -%exp30a.csv,30,5.12,4.5 -%\end{verbatim} -%\DTLnewdb{index}\relax -%\DTLnewrow{index}\relax -%\DTLnewdbentry{index}{File}{exp25a.csv}\relax -%\DTLnewdbentry{index}{Temperature}{25}\relax -%\DTLnewdbentry{index}{NaCl}{4.7}\relax -%\DTLnewdbentry{index}{pH}{0.5}\relax -%\DTLnewrow{index}\relax -%\DTLnewdbentry{index}{File}{exp25b.csv}\relax -%\DTLnewdbentry{index}{Temperature}{25}\relax -%\DTLnewdbentry{index}{NaCl}{4.8}\relax -%\DTLnewdbentry{index}{pH}{1.5}\relax -%\DTLnewrow{index}\relax -%\DTLnewdbentry{index}{File}{exp30a.csv}\relax -%\DTLnewdbentry{index}{Temperature}{30}\relax -%\DTLnewdbentry{index}{NaCl}{5.12}\relax -%\DTLnewdbentry{index}{pH}{4.5}\relax -%The first column of this file contains the name of another -%CSV file which has the results of a time to growth experiment -%performed at the given incubation temperature, salt concentration -%and pH. The file "exp25a.csv" contains the following: -%\begin{verbatim} -%Time,Log Count -%0,3.75 -%23,3.9 -%45,4.0 -%\end{verbatim} -%\DTLnewdb{exp25a.csv}\relax -%\DTLnewrow{exp25a.csv}\relax -%\DTLnewdbentry{exp25a.csv}{Time}{0}\relax -%\DTLnewdbentry{exp25a.csv}{Log Count}{3.75}\relax -%\DTLnewrow{exp25a.csv}\relax -%\DTLnewdbentry{exp25a.csv}{Time}{23}\relax -%\DTLnewdbentry{exp25a.csv}{Log Count}{3.9}\relax -%\DTLnewrow{exp25a.csv}\relax -%\DTLnewdbentry{exp25a.csv}{Time}{45}\relax -%\DTLnewdbentry{exp25a.csv}{Log Count}{4.0}\relax -%The file "exp25b.csv" contains the following: -%\begin{verbatim} -%Time,Log Count -%0,3.6 -%60,3.8 -%120,4.0 -%\end{verbatim} -%\DTLnewdb{exp25b.csv}\relax -%\DTLnewrow{exp25b.csv}\relax -%\DTLnewdbentry{exp25b.csv}{Time}{0}\relax -%\DTLnewdbentry{exp25b.csv}{Log Count}{3.6}\relax -%\DTLnewrow{exp25b.csv}\relax -%\DTLnewdbentry{exp25b.csv}{Time}{60}\relax -%\DTLnewdbentry{exp25b.csv}{Log Count}{3.8}\relax -%\DTLnewrow{exp25b.csv}\relax -%\DTLnewdbentry{exp25b.csv}{Time}{120}\relax -%\DTLnewdbentry{exp25b.csv}{Log Count}{4.0}\relax -%The file "exp30a.csv" contains the following: -%\begin{verbatim} -%Time,Log Count -%0,3.73 -%23,3.67 -%60,4.9 -%\end{verbatim} -%\DTLnewdb{exp30a.csv}\relax -%\DTLnewrow{exp30a.csv}\relax -%\DTLnewdbentry{exp30a.csv}{Time}{0}\relax -%\DTLnewdbentry{exp30a.csv}{Log Count}{3.73}\relax -%\DTLnewrow{exp30a.csv}\relax -%\DTLnewdbentry{exp30a.csv}{Time}{23}\relax -%\DTLnewdbentry{exp30a.csv}{Log Count}{3.67}\relax -%\DTLnewrow{exp30a.csv}\relax -%\DTLnewdbentry{exp30a.csv}{Time}{60}\relax -%\DTLnewdbentry{exp30a.csv}{Log Count}{4.9}\relax -%Suppose I now want to iterate through "index.csv", load the given -%file, and create a table for that data. I can do this using -%nested \ics{DTLforeach} as follows: -%\begin{verbatim} -% % load index data file -%\DTLloaddb{index}{index.csv} -% -% % iterate through index database -%\DTLforeach{index}{\theFile=File,\theTemp=Temperature,% -%\theNaCl=NaCl,\thepH=pH}{% -% % load results file into database of the same name -%\DTLloaddb{\theFile}{\theFile}% -% % Create a table -%\begin{table}[htbp] -%\caption{Temperature = \theTemp, NaCl = \theNaCl, -%pH = \thepH}\label{tab:\theFile} -%\centering -%\begin{tabular}{rl} -%\bfseries Time & \bfseries Log Count -%\DTLforeach{\theFile}{\theTime=Time,\theLogCount=Log Count}{% -%\\\theTime & \theLogCount}% -%\end{tabular} -%\end{table} -%} -%\end{verbatim} -%This creates \autoref{tab:exp25a.csv} to \autoref{tab:exp30a.csv}. -%(Note that each table is given a label that is based on the -%database name, to ensure that it is unique.) -% -%\DTLforeach{index}{\theFile=File,\theTemp=Temperature,\theNaCl -%=NaCl,\thepH=pH}{ -%\begin{table}[htbp] -%\caption[Temperature = \theTemp, NaCl = \theNaCl, -%pH = \thepH\space (illustrating nested -%\cs{DTLforeach})]{Temperature = \theTemp, NaCl = \theNaCl, -%pH = \thepH}\label{tab:\theFile} -%\centering -%\begin{tabular}{rl} -%\bfseries Time & \bfseries Log Count -%\DTLforeach{\theFile}{\theTime=Time,\theLogCount=Log Count}{ -%\\\theTime & \theLogCount}% -%\end{tabular} -%\end{table} -%} -%\end{example} -% -%\begin{example}{Dynamically Allocating Field Name}{ex:dyn} -%(This example was suggested by Bill~Hobbs.) Suppose you have a -%directory containing members of multiple clubs. The CSV file -%(say, \texttt{clubs.csv}) may look something like: -%\begin{verbatim} -%First Name,Surname,Rockin,Single -%John,"Smith, Jr",member, -%Jane,Brown,,friend -%Andy,Brown,friend,member -%Z\"oe,Adams,member,member -%Roger,Brady,friend,friend -%Clare,Verdon,member, -%\end{verbatim} -%\DTLnewdb{clubs}\relax -%\DTLnewrow{clubs}\relax -%\DTLnewdbentry{clubs}{First Name}{John}\relax -%\DTLnewdbentry{clubs}{Surname}{Smith, Jr}\relax -%\DTLnewdbentry{clubs}{Rockin}{member}\relax -%\DTLnewdbentry{clubs}{Single}{}\relax -%\DTLnewrow{clubs}\relax -%\DTLnewdbentry{clubs}{First Name}{Jane}\relax -%\DTLnewdbentry{clubs}{Surname}{Brown}\relax -%\DTLnewdbentry{clubs}{Rockin}{}\relax -%\DTLnewdbentry{clubs}{Single}{friend}\relax -%\DTLnewrow{clubs}\relax -%\DTLnewdbentry{clubs}{First Name}{Andy}\relax -%\DTLnewdbentry{clubs}{Surname}{Brown}\relax -%\DTLnewdbentry{clubs}{Rockin}{friend}\relax -%\DTLnewdbentry{clubs}{Single}{member}\relax -%\DTLnewrow{clubs}\relax -%\DTLnewdbentry{clubs}{First Name}{Z\"oe}\relax -%\DTLnewdbentry{clubs}{Surname}{Adams}\relax -%\DTLnewdbentry{clubs}{Rockin}{member}\relax -%\DTLnewdbentry{clubs}{Single}{member}\relax -%\DTLnewrow{clubs}\relax -%\DTLnewdbentry{clubs}{First Name}{Roger}\relax -%\DTLnewdbentry{clubs}{Surname}{Brady}\relax -%\DTLnewdbentry{clubs}{Rockin}{friend}\relax -%\DTLnewdbentry{clubs}{Single}{friend}\relax -%\DTLnewrow{clubs}\relax -%\DTLnewdbentry{clubs}{First Name}{Clare}\relax -%\DTLnewdbentry{clubs}{Surname}{Verdon}\relax -%\DTLnewdbentry{clubs}{Rockin}{member}\relax -%\DTLnewdbentry{clubs}{Single}{}\relax -%(Blank entries indicate that the person is not a member of that -%club.) The data can be loaded as follows: -%\begin{verbatim} -%\DTLloaddb{clubs}{clubs.csv} -%\end{verbatim} -%Suppose at the beginning of your document you have specified -%which club you are interested in ("Rockin" or "Single") and -%store it in \cs{DIdent}: -%\begin{verbatim} -%\newcommand{\DIdent}{Rockin} -%\end{verbatim} -%\newcommand{\DIdent}{Rockin}\relax -%You can now display the members for this particular club as -%follows: -%\begin{verbatim} -%\begin{table}[htbp] -%\caption{Club Membership} -%\centering -%\begin{tabular}{lll} -%\bfseries First Name & \bfseries Surname & \bfseries Status -%\DTLforeach*[\not\DTLiseq{\status}{}]{clubs} -%{\firstname=First Name,\surname=Surname,\status=\DIdent}{% -%\\\firstname & \surname & \status -%}% -%\end{tabular} -%\end{table} -%\end{verbatim} -%The result is shown in \autoref{tab:dyn}. -% -%\begin{table}[htbp] -%\caption{Club Membership} -%\label{tab:dyn} -%\centering -%\begin{tabular}{lll} -%\bfseries First Name & \bfseries Surname & \bfseries Status -%\DTLforeach*[\not\DTLiseq{\status}{}]{clubs} -%{\firstname=First Name,\surname=Surname,\status=\DIdent}{\relax -%\\\firstname & \surname & \status -%}\relax -%\end{tabular} -%\end{table} -%\end{example} -% -%\subsection{Null Values} -%If a database is created using \cs{DTLnewdb}, \cs{DTLnewrow} -%and \cs{DTLnewdbentry} (rather than loading it from an ASCII -%file), it is possible for some of the entries to have null values -%when a value is not assigned to a given key for a given row. -%(Note that a null value is not the same as an empty value.) -% -%When you iterate through the database using \cs{DTLforeach} -%(described in \autoref{sec:dbforeach}), -%if an entry is missing for a given row, the associated command given -%in the \meta{values} argument will be set to a null value. This -%value depends on the data type associated with the given key. -% -%\begin{definition}[\DescribeMacro{\DTLstringnull}]% -%\cs{DTLstringnull} -%\end{definition} -%This is the null value for a string. -% -%\begin{definition}[\DescribeMacro{\DTLnumbernull}]% -%\cs{DTLnumbernull} -%\end{definition} -%This is the null value for a number. -% -%\begin{definition}[\DescribeMacro{\DTLifnull}]% -%\cs{DTLifnull}\marg{cmd}\marg{true part}\marg{false part} -%\end{definition} -%This checks if \meta{cmd} is null where \meta{cmd} is a command name, -%if it is, then \meta{true part} -%is done, otherwise \meta{false part} is done. This macro is -%illustrated in \autoref{ex:null} below. -% -%\begin{example}{Null Values}{ex:null} -%Consider the following (which creates a database called "emailDB"): -%\begin{verbatim} -%\DTLnewdb{emailDB} -%\DTLnewrow{emailDB} -%\DTLnewdbentry{emailDB}{Surname}{Jones} -%\DTLnewdbentry{emailDB}{FirstName}{Mary} -%\DTLnewdbentry{emailDB}{Email1}{mj@my.uni.ac.uk} -%\DTLnewdbentry{emailDB}{Email2}{mj@somewhere.com} -%\DTLnewrow{emailDB} -%\DTLnewdbentry{emailDB}{Surname}{Smith} -%\DTLnewdbentry{emailDB}{FirstName}{Adam} -%\DTLnewdbentry{emailDB}{Email1}{as@my.uni.ac.uk} -%\DTLnewdbentry{emailDB}{RegNum}{12345} -%\end{verbatim} -%\DTLnewdb{emailDB}\relax -%\DTLnewrow{emailDB}\relax -%\DTLnewdbentry{emailDB}{Surname}{Jones}\relax -%\DTLnewdbentry{emailDB}{FirstName}{Mary}\relax -%\DTLnewdbentry{emailDB}{Email1}{mj@my.uni.ac.uk}\relax -%\DTLnewdbentry{emailDB}{Email2}{mj@somewhere.com}\relax -%\DTLnewrow{emailDB}\relax -%\DTLnewdbentry{emailDB}{Surname}{Smith}\relax -%\DTLnewdbentry{emailDB}{FirstName}{Adam}\relax -%\DTLnewdbentry{emailDB}{Email1}{as@my.uni.ac.uk}\relax -%\DTLnewdbentry{emailDB}{RegNum}{12345}\relax -%In the above example, the first row of the database contains -%an entry with the key "Email2", but the second row doesn't. -%Whereas the second row contains an entry with the key "RegNum", -%but the first row doesn't. -% -%The following code puts the information in a \env{tabular} -%environment: -%\begin{verbatim} -%\begin{tabular}{lllll} -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Email 1 & -%\bfseries Email 2 & -%\bfseries Reg Num% -%\DTLforeach{emailDB}{\firstname=FirstName,\surname=Surname,% -%\emailI=Email1,\emailII=Email2,\regnum=RegNum}{% -%\\\firstname & \surname & \emailI & \emailII & \regnum}% -%\end{tabular} -%\end{verbatim} -%This produces the following:\par\vskip\baselineskip\noindent -%\begin{tabular}{lllll} -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Email 1 & -%\bfseries Email 2 & -%\bfseries Reg Num\relax -%\DTLforeach{emailDB}{\firstname=FirstName,\surname -%=Surname,\emailI=Email1,\emailII=Email2,\regnum=RegNum}{\relax -%\\\firstname & \surname & \emailI & \emailII & \regnum}\relax -%\end{tabular} -%\par\vskip\baselineskip -%Note that on the first row of data, the registration number appears as -%0, while on the next row, the second email address appears as -%NULL. The \sty{datatool} package has identified the key "RegNum" -%for this database as a numerical key, since all elements in the -%database with that key are numerical, whereas it has -%identified the key "Email2" as a string, since there is at least -%one element in this database with that key that is a string. Null -%numerical values are set to \cs{DTLnumbernull} (\DTLnumbernull), and -%null strings are set to \cs{DTLstringnull} (\DTLstringnull). -% -%The following code checks each value to determine whether it -%is null using \cs{DTLifnull}. If it is, the text \emph{Missing} -%is inserted, otherwise the value itself is used: -%\begin{verbatim} -%\begin{tabular}{lllll} -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Email 1 & -%\bfseries Email 2 & -%\bfseries Reg Num% -%\DTLforeach{emailDB}{\firstname=FirstName,\surname=Surname,% -%\emailI=Email1,\emailII=Email2,\regnum=RegNum}{% -%\\\DTLifnull{\firstname}{\emph{Missing}}{\firstname} & -%\DTLifnull{\surname}{\emph{Missing}}{\surname} & -%\DTLifnull{\emailI}{\emph{Missing}}{\emailI} & -%\DTLifnull{\emailII}{\emph{Missing}}{\emailII} & -%\DTLifnull{\regnum}{\emph{Missing}}{\regnum}}% -%\end{tabular} -%\end{verbatim} -%This produces the following:\par\vskip\baselineskip\noindent -%\begin{tabular}{lllll} -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Email 1 & -%\bfseries Email 2 & -%\bfseries Reg Num\relax -%\DTLforeach{emailDB}{\firstname=FirstName,\surname -%=Surname,\emailI=Email1,\emailII=Email2,\regnum=RegNum}{\relax -%\\\DTLifnull{\firstname}{\emph{Missing}}{\firstname} & -%\DTLifnull{\surname}{\emph{Missing}}{\surname} & -%\DTLifnull{\emailI}{\emph{Missing}}{\emailI} & -%\DTLifnull{\emailII}{\emph{Missing}}{\emailII} & -%\DTLifnull{\regnum}{\emph{Missing}}{\regnum}}\relax -%\end{tabular} -%\par\vskip\baselineskip\noindent -%If you want to do this, you may find it easier to define a -%convenience command that will display some appropriate text -%if an entry is missing, for example: -%\begin{verbatim} -%\newcommand*{\checkmissing}[1]{\DTLifnull{#1}{---}{#1}} -%\end{verbatim} -%Then instead of typing, say, -%\begin{verbatim} -%\DTLifnull{\regnum}{---}{\regnum} -%\end{verbatim} -%you can instead type: -%\begin{verbatim} -%\checkmissing{\regnum} -%\end{verbatim} -% -%Now suppose that instead of defining the database using \cs{DTLnewdb}, -%\cs{DTLnewrow} and \cs{DTLnewdbentry}, you have a file with the -%contents: -%\begin{ttfamily}\setlength{\parindent}{0pt}\par\vskip\baselineskip -%Surname,FirstName,RegNum,Email1,Email2 -% -%\DTLforeach{emailDB}{\surname=Surname,\firstname=FirstName,\regNo -%=RegNum,\emailI=Email1,\emailII -%=Email2}{\relax -%\surname,\firstname,\DTLifnull{\regNo}{}{\regNo},\emailI,\DTLifnull{\emailII}{}{\emailII}\par -%} -%\end{ttfamily}\par\vskip\baselineskip\noindent -%and you load the data from this file using \cs{DTLloaddb} -%(defined in \autoref{sec:loaddb}). Now the -%database has no null values, but has an empty value for the -%key "RegNum" on the first row of the database, and an empty -%value for the key "Email2" on the second row of the database. -%Now, the following code -%\begin{verbatim} -%\begin{tabular}{lllll} -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Email 1 & -%\bfseries Email 2 & -%\bfseries Reg Number% -%\DTLforeach{emailDB}{\firstname=FirstName,\surname=Surname,% -%\emailI=Email1,\emailII=Email2,\regnum=RegNum}{% -%\\\DTLifnull{\firstname}{\emph{Missing}}{\firstname} & -%\DTLifnull{\surname}{\emph{Missing}}{\surname} & -%\DTLifnull{\emailI}{\emph{Missing}}{\emailI} & -%\DTLifnull{\emailII}{\emph{Missing}}{\emailII} & -%\DTLifnull{\regnum}{\emph{Missing}}{\regnum}}% -%\end{tabular} -%\end{verbatim} -%produces:\par\vskip\baselineskip\noindent -%\begin{tabular}{lllll} -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Email 1 & -%\bfseries Email 2 & -%\bfseries Reg Number\relax -%\DTLforeach{emailDB}{\firstname=FirstName,\surname -%=Surname,\emailI=Email1,\emailII=Email2,\regnum=RegNum}{\relax -%\\\firstname & \surname & \emailI & \DTLifnull{\emailII}{}{\emailII} & \DTLifnull{\regnum}{}{\regnum}}\relax -%\end{tabular} -%\end{example} -% -%\subsection{Editing Database Rows} -%\label{sec:editdb} -% -%A row can be removed from a data base using: -%\begin{definition}[\DescribeMacro{\DTLremoverow}]% -%\cs{DTLremoverow}\marg{db name}\marg{row index} -%\end{definition} -%where \meta{row index} is the index of the unwanted row. For -%example: -%\begin{verbatim} -%\DTLremoverow{scores}{2} -%\end{verbatim} -%will delete the second row in the database labelled ``scores''. -%There is also a starred version that doesn't check for the -%existence of the database. -% -%In the body of the \ics{DTLforeach} loop,\footnote{Only the -%unstarred version of \cs{DTLforeach}; the starred version is -%read-only.}\ you can use the following to edit the current row: -%\begin{definition}[\DescribeMacro{\DTLappendtorow}]% -%\cs{DTLappendtorow}\marg{key}\marg{value} -%\end{definition} -%This appends a new entry with the given \meta{key} and \meta{value} -%to the current row. -%(\meta{value} is expanded.) -% -%\begin{definition}[\DescribeMacro{\DTLreplaceentryforrow}]% -%\cs{DTLreplaceentryforrow}\marg{key}\marg{value} -%\end{definition} -%This replaces the entry for \meta{key} with \meta{value}. -%(\meta{value} is expanded.) -% -%\begin{definition}[\DescribeMacro{\DTLremoveentryfromrow}]% -%\cs{DTLremoveentryfromrow}\marg{key} -%\end{definition} -%This removes the entry for \meta{key} from the current row. -% -%\begin{definition}[\DescribeMacro{\DTLremovecurrentrow}]% -%\cs{DTLremovecurrentrow} -%\end{definition} -%This removes the current row from the database. -% -%\begin{example}{Editing Database Rows}{ex:editdb} -%In this example I have a CSV file called "marks.csv" that contains -%student marks for three assignments: -%\DTLnewdb{marks}\relax -%\DTLnewrow{marks}\relax -%\DTLnewdbentry{marks}{FirstName}{John}\relax -%\DTLnewdbentry{marks}{Surname}{Smith, Jr}\relax -%\DTLnewdbentry{marks}{StudentNo}{102689}\relax -%\DTLnewdbentry{marks}{Assignment 1}{68}\relax -%\DTLnewdbentry{marks}{Assignment 2}{57}\relax -%\DTLnewdbentry{marks}{Assignment 3}{72}\relax -%\DTLnewrow{marks}\relax -%\DTLnewdbentry{marks}{FirstName}{Jane}\relax -%\DTLnewdbentry{marks}{Surname}{Brown}\relax -%\DTLnewdbentry{marks}{StudentNo}{102647}\relax -%\DTLnewdbentry{marks}{Assignment 1}{75}\relax -%\DTLnewdbentry{marks}{Assignment 2}{84}\relax -%\DTLnewdbentry{marks}{Assignment 3}{80}\relax -%\DTLnewrow{marks}\relax -%\DTLnewdbentry{marks}{FirstName}{Andy}\relax -%\DTLnewdbentry{marks}{Surname}{Brown}\relax -%\DTLnewdbentry{marks}{StudentNo}{103569}\relax -%\DTLnewdbentry{marks}{Assignment 1}{42}\relax -%\DTLnewdbentry{marks}{Assignment 2}{52}\relax -%\DTLnewdbentry{marks}{Assignment 3}{54}\relax -%\DTLnewrow{marks}\relax -%\DTLnewdbentry{marks}{FirstName}{Z\"oe}\relax -%\DTLnewdbentry{marks}{Surname}{Adams}\relax -%\DTLnewdbentry{marks}{StudentNo}{105987}\relax -%\DTLnewdbentry{marks}{Assignment 1}{52}\relax -%\DTLnewdbentry{marks}{Assignment 2}{48}\relax -%\DTLnewdbentry{marks}{Assignment 3}{57}\relax -%\DTLnewrow{marks}\relax -%\DTLnewdbentry{marks}{FirstName}{Roger}\relax -%\DTLnewdbentry{marks}{Surname}{Brady}\relax -%\DTLnewdbentry{marks}{StudentNo}{106872}\relax -%\DTLnewdbentry{marks}{Assignment 1}{58}\relax -%\DTLnewdbentry{marks}{Assignment 2}{60}\relax -%\DTLnewdbentry{marks}{Assignment 3}{62}\relax -%\DTLnewrow{marks}\relax -%\DTLnewdbentry{marks}{FirstName}{Clare}\relax -%\DTLnewdbentry{marks}{Surname}{Verdon}\relax -%\DTLnewdbentry{marks}{StudentNo}{104356}\relax -%\DTLnewdbentry{marks}{Assignment 1}{45}\relax -%\DTLnewdbentry{marks}{Assignment 2}{50}\relax -%\DTLnewdbentry{marks}{Assignment 3}{48}\relax -%\begin{ttfamily}\setlength{\parindent}{0pt}\par -%Surname,FirstName,StudentNo,Assignment 1,Assignment 2,Assignment 3 -% -%\DTLforeach{marks}{\surname=Surname,\firstname=FirstName,\regNo -%=StudentNo,\assignI=Assignment 1,\assignII -%=Assignment 2,\assignIII=Assignment 3}{\relax -%\char`\"\surname\char`\",\DTLifstringeq{\firstname}{Zoe}{Z\string\"oe}{\firstname},\regNo,\assignI,\assignII,\assignIII\par -%} -%\end{ttfamily}\par\noindent -%First load this into a database called "marks": -%\begin{verbatim} -%\DTLloaddb{marks}{marks.csv} -%\end{verbatim} -%Suppose now I want to compute the average mark for each -%student, and append this to the database. I can do this as -%follows: -%\begin{verbatim} -%\DTLforeach{marks}{% -%\assignI=Assignment 1,% -%\assignII=Assignment 2,% -%\assignIII=Assignment 3}{% -%\DTLmeanforall{\theMean}{\assignI,\assignII,\assignIII}% -%\DTLappendtorow{Average}{\theMean}} -%\end{verbatim} -%\DTLforeach{marks}{\assignI=Assignment 1,\assignII -%=Assignment 2,\assignIII=Assignment 3}{\relax -%\DTLmeanforall{\theMean}{\assignI,\assignII,\assignIII}% -%\DTLappendtorow{Average}{\theMean}}\relax -%For each row in the "marks" database, I now have an extra key -%called "Average" that contains the average mark over all three -%assignments for a given student. I can now put this data into -%a table: -%\begin{verbatim} -%\begin{table}[htbp] -%\caption{Student marks} -%\centering -%\begin{tabular}{llcccc} -%\bfseries Surname & \bfseries First Name & -%\bfseries Assign 1 & -%\bfseries Assign 2 & -%\bfseries Assign 3 & -%\bfseries Average Mark% -%\DTLforeach{marks}{\surname=Surname,\firstname=FirstName,\average -%=Average,\assignI=Assignment 1,\assignII=Assignment 2,\assignIII -%=Assignment 3}{\\\surname -%& \firstname & \assignI & \assignII & \assignIII & -%\DTLround{\average}{\average}{2}\average}\relax -%\end{tabular} -%\end{table} -%\end{verbatim} -%This produces \autoref{tab:meanmarks}. -% -%Note that if I only wanted the averages for the table and nothing -%else, I could simply have computed the average in each row of the -%table and displayed it without adding the information to the -%database, however I am going to reuse this information in -%\autoref{ex:multibar}, so adding it to the database means that -%I don't need to recompute the mean. -% -%\begin{table}[htbp] -%\caption[Student marks (with averages)]{Student -%marks}\label{tab:meanmarks} -%\centering -%\begin{tabular}{llcccc} -%\bfseries Surname & \bfseries First Name & -%\bfseries Assign 1 & -%\bfseries Assign 2 & -%\bfseries Assign 3 & -%\bfseries Average Mark\relax -%\DTLforeach{marks}{\surname=Surname,\firstname=FirstName,\average -%=Average,\assignI=Assignment 1,\assignII=Assignment 2,\assignIII -%=Assignment 3}{\\\surname -%& \firstname & \assignI & \assignII & \assignIII & -%\DTLround{\average}{\average}{2}\average}\relax -%\end{tabular} -%\end{table} -% -%\end{example} -% -%\subsection{Arithmetical Computations on Database Entries} -% -%The commands used in \autoref{sec:fp} can be used on database -%entries. You can, of course, directly use the commands provided -%by the \sty{fp} package if you know that the values are in the -%correct format (i.e.\ no currency symbols, no number group -%separators and a full stop as the decimal point) but if this is -%not the case, then you should use the commands described in -%\autoref{sec:fp}. If you want to use a command provided by the -%\sty{fp} package, that does not have a wrapper function in -%\sty{datatool}, then you will need to convert the value using -%\ics{DTLconverttodecimal}, and convert it back using either -%\ics{DTLdecimaltolocale} or \ics{DTLdecimaltocurrency}. -% -%\begin{example}{Arithmetical Computations}{ex:mean} -%In this example, I am going to produce a table similar to -%\autoref{tab:scores}, except that I want to add an extra row at the -%end which contains the average score. -%\begin{verbatim} -%\begin{table}[htbp] -%\caption{Student scores}\label{tab:mean} -%\centering -%\def\total{0}% -%\begin{tabular}{llr} -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Score (\%)% -%\DTLforeach{scores}{% -%\firstname=FirstName,\surname=Surname,\score=Score}{% -%\\ -%\firstname & \surname & -%\DTLgadd{\total}{\score}{\total}% -%\score -%}\\ -%\multicolumn{2}{l}{\bfseries Average Score} & -%\DTLsavelastrowcount{\n}% -%\DTLdiv{\average}{\total}{\n}% -%\DTLround{\average}{\average}{2}% -%\average -%\end{tabular} -%\end{table} -%\end{verbatim} -%This produces \autoref{tab:mean}. -%\textbf{Notes:} -%\begin{itemize} -%\item I had to use \ics{DTLgadd} rather than \ics{DTLadd} since it -%occurs within a \env{tabular} environment which puts each entry -%in a local scope. -% -%\item I used \ics{DTLsavelastrowcount} to store the number of -%rows produced by \ics{DTLforeach} in the control sequence \cs{n}. -% -%\item I used \ics{DTLround} to round the average score to 2 decimal -%places. -%\end{itemize} -% -%\begin{table}[htbp] -%\caption[Student scores (using arithmetic computations)]{Student -%scores}\label{tab:mean} -%\centering -%\def\total{0}\relax -%\begin{tabular}{llr} -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Score (\%)\relax -%\DTLforeach{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax -%\\ -%\firstname & \surname & -%\DTLgadd{\total}{\score}{\total}\relax -%\score -%}\\ -%\multicolumn{2}{l}{\bfseries Average Score} & -%\DTLsavelastrowcount{\n}\relax -%\DTLdiv{\average}{\total}{\n}\relax -%\DTLround{\average}{\average}{2}\relax -%\average -%\end{tabular} -%\end{table} -%\end{example} -% -%\begin{definition}[\DescribeMacro{\DTLsumforkeys}]% -%\cs{DTLsumforkeys}\oarg{condition}\oarg{assign list}\marg{db list}\marg{key list}\marg{cmd} -%\end{definition} -%This command sums all the entries over all the databases listed in -%the comma separated list of database names \meta{db list} for each -%key in \meta{key list} where the condition given by \meta{condition} -%is true. The second optional argument \meta{assign list} is the same -%as the assignment list used by \ics{DTLforeach}, so that you can use -%the information in \meta{condition}. The result is stored in -%\meta{cmd} which must be a control sequence. For example: -%\begin{verbatim} -%\DTLsumforkeys{scores}{Score}{\total} -%\end{verbatim} -%sets \cs{total} to the sum of all the scores in the database -%called "scores". -% -%\begin{definition}[\DescribeMacro{\DTLsumcolumn}]% -%\cs{DTLsumcolumn}\marg{db}\marg{key}\marg{cmd} -%\end{definition} -%This is a faster version of \cs{DTLsumforkeys} that only sums -%the entries in a single column (specified by \meta{key}) for -%a single database (specified by \meta{db}) and doesn't provide any -%filtering. The result is stored in \meta{cmd} which must be -%a control sequence. -% -%\begin{definition}[\DescribeMacro{\DTLmeanforkeys}]% -%\cs{DTLmeanforkeys}\oarg{condition}\oarg{assign list}\marg{db list}\marg{key list}\marg{cmd} -%\end{definition} -%This command computes the arithmetic mean of all the entries over -%all the databases listed in \meta{db list} for all keys in \meta{key -%list} where the condition given by \meta{condition} is true. The -%second optional argument \meta{assign list} is the same as the -%assignment list used by \ics{DTLforeach}, so that you can use the -%information in \meta{condition}. The result is stored in \meta{cmd} -%which must be a control sequence. For example: -%\begin{verbatim} -%\DTLmeanforkeys{scores}{Score}{\average} -%\end{verbatim} -%sets \cs{average} to the mean of all the scores in the database -%called "scores". -% -%\begin{definition}[\DescribeMacro{\DTLmeanforcolumn}]% -%\cs{DTLmeanforcolumn}\marg{db}\marg{key}\marg{cmd} -%\end{definition} -%This is a faster version of \cs{DTLmeanforkeys} that only computes -%the mean for a single column (specified by \meta{key}) for -%a single database (specified by \meta{db}) and doesn't provide any -%filtering. The result is stored in \meta{cmd} which must be -%a control sequence. -% -%\begin{definition}[\DescribeMacro{\DTLvarianceforkeys}]% -%\cs{DTLvarianceforkeys}\oarg{condition}\oarg{assign list}\marg{db list}\marg{key list}\marg{cmd} -%\end{definition} -%This command computes the variance of all the entries over all the -%databases listed in \meta{db list} for all keys in \meta{key list} -%where the condition given by \meta{condition} is true. The second -%optional argument \meta{assign list} is the same as the assignment -%list used by \ics{DTLforeach}, so that you can use the information -%in \meta{condition}. The result is stored in \meta{cmd} which must -%be a control sequence. -% -%\begin{definition}[\DescribeMacro{\DTLvarianceforcolumn}]% -%\cs{DTLvarianceforcolumn}\marg{db}\marg{key}\marg{cmd} -%\end{definition} -%This is a faster version of \cs{DTLvarianceforkeys} that only -%computes the variance for a single column (specified by \meta{key}) -%for a single database (specified by \meta{db}) and doesn't provide -%any filtering. The result is stored in \meta{cmd} which must be a -%control sequence. -% -%\begin{definition}[\DescribeMacro{\DTLsdforkeys}]% -%\cs{DTLsdforkeys}\oarg{condition}\oarg{assign list}\marg{db list}\marg{key list}\marg{cmd} -%\end{definition} -%This command computes the standard deviation of all the entries over -%all the databases listed in \meta{db list} for all keys in \meta{key -%list} where the condition given by \meta{condition} is true. The -%second optional argument \meta{assign list} is the same as the -%assignment list used by \ics{DTLforeach}, so that you can use the -%information in \meta{condition}. The result is stored in \meta{cmd} -%which must be a control sequence. -% -%\begin{definition}[\DescribeMacro{\DTLsdforcolumn}]% -%\cs{DTLsdforcolumn}\marg{db}\marg{key}\marg{cmd} -%\end{definition} -%This is a faster version of \cs{DTLsdforkeys} that only computes the -%standard deviation for a single column (specified by \meta{key}) for -%a single database (specified by \meta{db}) and doesn't provide any -%filtering. The result is stored in \meta{cmd} which must be a -%control sequence. -% -%\begin{definition}[\DescribeMacro{\DTLminforkeys}]% -%\cs{DTLminforkeys}\oarg{condition}\oarg{assign list}\marg{db list}\marg{key list}\marg{cmd} -%\end{definition} -%This command determines the minimum value over all entries for all -%keys in \meta{key list} over all the databases listed in \meta{db -%list} where \meta{condition} is true. The second optional argument -%\meta{assign list} is the same as the assignment list used by -%\ics{DTLforeach}, so that you can use the information in -%\meta{condition}. The result is stored in \meta{cmd}, which must be -%a control sequence. For example -%\begin{verbatim} -%\DTLminforkeys{scores}{Score}{\theMin} -%\end{verbatim} -%sets \cs{theMin} to the minimum score in the database. -% -%\begin{definition}[\DescribeMacro{\DTLminforcolumn}]% -%\cs{DTLminforcolumn}\marg{db}\marg{key}\marg{cmd} -%\end{definition} -%This is a faster version of \cs{DTLminforkeys} that only computes -%the minimum for a single column (specified by \meta{key}) for -%a single database (specified by \meta{db}) and doesn't provide any -%filtering. The result is stored in \meta{cmd} which must be -%a control sequence. +%\date{2012-07-18} +%\maketitle % -%\begin{definition}[\DescribeMacro{\DTLmaxforkeys}]% -%\cs{DTLmaxforkeys}\oarg{condition}\oarg{assign list}\marg{db list}\marg{key list}\marg{cmd} -%\end{definition} -%This command determines the maximum value over all entries for all -%keys in \meta{key list} over all the databases listed in \meta{db -%list} where \meta{condition} is true. The second optional argument -%\meta{assign list} is the same as the assignment list used by -%\ics{DTLforeach}, so that you can use the information in -%\meta{condition}. The result is stored in \meta{cmd}, which must be -%a control sequence. For example -%\begin{verbatim} -%\DTLminforkeys{scores}{Score}{\theMax} -%\end{verbatim} -%sets \cs{theMax} to the minimum score in the database. +%\pagenumbering{roman} % -%\begin{definition}[\DescribeMacro{\DTLmaxforcolumn}]% -%\cs{DTLmaxforcolumn}\marg{db}\marg{key}\marg{cmd} -%\end{definition} -%This is a faster version of \cs{DTLmaxforkeys} that only computes -%the maximum for a single column (specified by \meta{key}) for -%a single database (specified by \meta{db}) and doesn't provide any -%filtering. The result is stored in \meta{cmd} which must be -%a control sequence. +%This is the documented code for the \styfmt{datatool} bundle. See +%\url{datatool-user.pdf} for the main user manual. % -%\begin{definition}[\DescribeMacro{\DTLcomputebounds}]% -%\cs{DTLcomputebounds}\marg{db list}\marg{x key}\marg{y key}\marg{minX cmd}\marg{minY cmd}\marg{maxX cmd}\marg{maxY cmd} -%\end{definition} -%Computes the maximum and minimum $x$ and $y$ values over all -%the databases listed in \meta{db list} where the $x$ value -%is given by \meta{x key} and the $y$ value is given by -%\meta{y key}. The results are stored in \meta{minX cmd}, -%\meta{minY cmd}, \meta{maxX cmd} and \meta{maxY cmd}. +%\clearpage +%\pdfbookmark[0]{Contents}{contents} +%\tableofcontents % -%\begin{example}{Mail Merging}{ex:mailmerging} -%This example uses the database given in \autoref{ex:scores} and -%uses \ics{DTLmeanforkeys} to determine the average score. A letter -%is then created for each student to inform them of their score -%and the class average. +%\pagenumbering{arabic} % -%\begin{verbatim} -%\documentclass{letter} -% -%\usepackage{datatool} -% -%\begin{document} -% % load database -%\DTLloaddb{scores}{studentscores.csv} -% % compute arithmetic mean for key `Score' -%\DTLmeanforkeys{scores}{Score}{\average} -% % Round the average to 2 decimal places -%\DTLround{\average}{\average}{2} -% % Save the highest score in \maxscore -%\DTLmaxforkeys{scores}{Score}{\maxscore} -% -%\DTLforeach{scores}{\firstname=FirstName,\surname=Surname,% -%\score=Score}{% -%\begin{letter}{} -%\opening{Dear \firstname\ \surname} -% -%\DTLifnumgt{\score}{60}{Congratulations you}{You} achieved a score -%of \score\% which was \DTLifnumgt{\score}{\average}{above}{below} -%the average of \average\%. \DTLifnumeq{\score}{\maxscore}{You -%achieved the highest score}{The top score was \maxscore}. -% -%\closing{Yours Sincerely} -%\end{letter} +%\StopEventually{% +% \clearpage\phantomsection +% \addcontentsline{toc}{chapter}{Index}\PrintIndex +% \clearpage\phantomsection +% \addcontentsline{toc}{chapter}{History}\PrintChanges %} -%\end{document} -%\end{verbatim} % -%To determine a person's gender when mail merging, see -%\autoref{sec:person}. -%\end{example} -% -%\subsection{Sorting a Database} -%\label{sec:sort} -% -%\begin{definition}[\DescribeMacro{\DTLsort}]% -%\cs{DTLsort}\oarg{replacement key list}\marg{sort criteria}\marg{db name} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLsort*}]% -%\cs{DTLsort*}\oarg{replacement key list}\marg{sort criteria}\marg{db name} -%\end{definition} -%This will sort the database called \meta{db name} according to -%the criteria given by \meta{sort criteria}, which must be a -%comma separated list of keys and optionally "="\meta{order}, where -%\meta{order} is either "ascending" or "descending". If the order -%is omitted, "ascending" is assumed. The database keeps track of -%the data type for a given key, and uses this to determine whether -%an alphabetical or numerical sort is required. (String comparisons -%are made using the command \cs{dtlcompare} or \cs{dtlicompare} -%described in \autoref{src:dtlcompare}.) -% -%The optional argument \meta{replacement key list} is a list of -%keys to use if the current key given in \meta{sort criteria} -%is null for a given entry. Null keys are unlikely to occur if -%you have loaded the database from an external ASCII file, but -%may occur if the database is created using \cs{DTLnewdb}, -%\cs{DTLnewrow} and \cs{DTLnewdbentry}. For example: -%\begin{verbatim} -%\DTLsort[Editor,Organization]{Author}{mydata} -%\end{verbatim} -%will sort according to the "Author" key, but if that key is missing -%for a given row of the database, the "Editor" key will be used, -%and if the "Editor" key is missing, it will use the "Organization" -%key. Note that this is not the same as: -%\begin{verbatim} -%\DTLsort{Author,Editor,Organization}{mydata} -%\end{verbatim} -%which will first compare the "Author" keys, but if the author names -%are the same, it will then compare the "Editor" keys, and if the -%editor names are also the same, it will then compare the -%"Organization" keys. -% -%The unstarred version uses a case sensitive comparison for strings, -%whereas the starred version ignores the case when comparing strings. -%Note that the case sensitive comparison orders uppercase characters -%before lowercase characters, so the letter B is considered to be -%lower than the letter a. -% -%\begin{example}{Sorting a Database}{ex:sort} -%This example uses the database called "scores" defined in -%\autoref{ex:scores}. First, I am going to sort the database -%according to the student scores in descending order (highest to -%lowest) and display the database in a table -%\begin{verbatim} -%\begin{table}[htbp] -%\caption{Student scores (sorted by score)} -%\centering -%\DTLsort{Score=descending}{scores}% -%\begin{tabular}{llr} -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Score (\%)% -%\DTLforeach{scores}{% -%\firstname=FirstName,\surname=Surname,\score=Score}{% -%\\ -%\firstname & \surname & \score} -%\end{tabular} -%\end{table} -%\end{verbatim} -%This produces \autoref{tab:sortscores}. -% -%\begin{table}[htbp] -%\caption{Student scores (sorted by score)}\label{tab:sortscores} -%\centering -%\DTLsort{Score=descending}{scores}\relax -%\begin{tabular}{llr} -%\bfseries First Name & -%\bfseries Surname & -%\bfseries Score (\%)\relax -%\DTLforeach{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax -%\\ -%\firstname & \surname & \score} -%\end{tabular} -%\end{table} -% -%Now I am going to sort the database according to -%surname and then first name, and display it in a table. Note that -%since I want to sort in ascending order, I can omit the -%"=ascending" part of the sort criteria. I have also decided to -%reverse the first and second columns, so that the surname is -%in the first column. -%\begin{verbatim} -%\begin{table}[htbp] -%\caption{Student scores (sorted by name)} -%\centering -%\DTLsort{Surname,FirstName}{scores}% -%\begin{tabular}{llr} -%\bfseries Surname & -%\bfseries First Name & -%\bfseries Score (\%)% -%\DTLforeach{scores}{% -%\firstname=FirstName,\surname=Surname,\score=Score}{% -%\\ -%\surname & \firstname & \score} -%\end{tabular} -%\end{table} -%\end{verbatim} -%This produces \autoref{tab:sortname}. -%\begin{table}[htbp] -%\caption{Student scores (sorted by name)}\label{tab:sortname} -%\centering -%\DTLsort{Surname,FirstName}{scores}\relax -%\begin{tabular}{llr} -%\bfseries Surname & -%\bfseries First Name & -%\bfseries Score (\%)\relax -%\DTLforeach{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax -%\\ -%\surname & \firstname & \score} -%\end{tabular} -%\end{table} % -%Now suppose I add two new students to the database: -%\begin{verbatim} -%\DTLnewrow{scores}% -%\DTLnewdbentry{scores}{Surname}{van der Mere}% -%\DTLnewdbentry{scores}{FirstName}{Henk}% -%\DTLnewdbentry{scores}{Score}{71}% -%\DTLnewrow{scores}% -%\DTLnewdbentry{scores}{Surname}{de la Mere}% -%\DTLnewdbentry{scores}{FirstName}{Jos}% -%\DTLnewdbentry{scores}{Score}{58}% -%\end{verbatim} -%\DTLnewrow{scores} -%\DTLnewdbentry{scores}{Surname}{van der Mere}\relax -%\DTLnewdbentry{scores}{FirstName}{Henk}\relax -%\DTLnewdbentry{scores}{Score}{71}\relax -%\DTLnewrow{scores}\relax -%\DTLnewdbentry{scores}{Surname}{de la Mere}\relax -%\DTLnewdbentry{scores}{FirstName}{Jos}\relax -%\DTLnewdbentry{scores}{Score}{58}\relax -%and again I try sorting the database, and displaying the contents -%as a table: -%\begin{verbatim} -%\begin{table}[htbp] -%\caption{Student scores (case sensitive sort)} -%\centering -%\DTLsort{Surname,FirstName}{scores}% -%\begin{tabular}{llr} -%\bfseries Surname & -%\bfseries First Name & -%\bfseries Score (\%)% -%\DTLforeach{scores}{% -%\firstname=FirstName,\surname=Surname,\score=Score}{% -%\\ -%\surname & \firstname & \score} -%\end{tabular} -%\end{table} -%\end{verbatim} -%This produces \autoref{tab:sortname2}. Notice that the surnames -%aren't correctly ordered. This is because a case-sensitive -%sort was used. Changing \cs{DTLsort} to \cs{DTLsort*} in the -%above code produces \autoref{tab:sortname3}. -% -%\begin{table}[htbp] -%\caption{Student scores (case sensitive sort)}\label{tab:sortname2} -%\centering -%\DTLsort{Surname,FirstName}{scores}\relax -%\begin{tabular}{llr} -%\bfseries Surname & -%\bfseries First Name & -%\bfseries Score (\%)\relax -%\DTLforeach{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax -%\\ -%\surname & \firstname & \score} -%\end{tabular} -%\end{table} -% -%\begin{table}[htbp] -%\caption{Student scores (case ignored when -%sorting)}\label{tab:sortname3} -%\centering -%\DTLsort*{Surname,FirstName}{scores}\relax -%\begin{tabular}{llr} -%\bfseries Surname & -%\bfseries First Name & -%\bfseries Score (\%)\relax -%\DTLforeach{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax -%\\ -%\surname & \firstname & \score} -%\end{tabular} -%\end{table} -% -%\end{example} -% -%\begin{example}{Influencing the sort order}{ex:sortswitchargs} -%Consider the data displayed in \autoref{tab:sortname3}, suppose that -%you want the names ``van der Mere'' and ``de la Mere'' sorted -%according to the actual surname ``Mere'' rather than by the ``von -%part''. There are two ways you can do this: firstly, you could store -%the von part in a separate field, and then sort by surname, then von -%part, then first name, or you could define a command called, say, -%\cs{switchargs}, as follows: -%\begin{verbatim} -%\newcommand*{\switchargs}[2]{#2#1} -%\end{verbatim} -%\newcommand*{\switchargs}[2]{#2#1}\relax -%then store the data as: -%\begin{verbatim} -%FirstName,Surname,StudentNo,Score -%John,"Smith, Jr",102689,68 -%Jane,Brown,102647,75 -%Andy,Brown,103569,42 -%Z\"oe,Adams,105987,52 -%Roger,Brady,106872,58 -%Clare,Verdon,104356,45 -%Henk,\switchargs{Mere}{van der },106789,71 -%Jos,\switchargs{Mere}{de la },104256,58 -%\end{verbatim} -%\DTLnewdb{scores2}\relax -%\DTLnewrow{scores2}\relax -%\DTLnewdbentry{scores2}{FirstName}{John}\relax -%\DTLnewdbentry{scores2}{Surname}{Smith, Jr}\relax -%\DTLnewdbentry{scores2}{StudentNo}{102689}\relax -%\DTLnewdbentry{scores2}{Score}{68}\relax -%\DTLnewrow{scores2}\relax -%\DTLnewdbentry{scores2}{FirstName}{Jane}\relax -%\DTLnewdbentry{scores2}{Surname}{Brown}\relax -%\DTLnewdbentry{scores2}{StudentNo}{102647}\relax -%\DTLnewdbentry{scores2}{Score}{75}\relax -%\DTLnewrow{scores2}\relax -%\DTLnewdbentry{scores2}{FirstName}{Andy}\relax -%\DTLnewdbentry{scores2}{Surname}{Brown}\relax -%\DTLnewdbentry{scores2}{StudentNo}{103569}\relax -%\DTLnewdbentry{scores2}{Score}{42}\relax -%\DTLnewrow{scores2}\relax -%\DTLnewdbentry{scores2}{FirstName}{Z\"oe}\relax -%\DTLnewdbentry{scores2}{Score}{52}\relax -%\DTLnewdbentry{scores2}{StudentNo}{105987}\relax -%\DTLnewdbentry{scores2}{Surname}{Adams}\relax -%\DTLnewrow{scores2}\relax -%\DTLnewdbentry{scores2}{FirstName}{Roger}\relax -%\DTLnewdbentry{scores2}{Score}{58}\relax -%\DTLnewdbentry{scores2}{StudentNo}{106872}\relax -%\DTLnewdbentry{scores2}{Surname}{Brady}\relax -%\DTLnewrow{scores2}\relax -%\DTLnewdbentry{scores2}{FirstName}{Clare}\relax -%\DTLnewdbentry{scores2}{Score}{45}\relax -%\DTLnewdbentry{scores2}{StudentNo}{104356}\relax -%\DTLnewdbentry{scores2}{Surname}{Verdon}\relax -%\DTLnewrow{scores2} -%\DTLnewdbentry{scores2}{Surname}{\switchargs{Mere}{van der }}\relax -%\DTLnewdbentry{scores2}{FirstName}{Henk}\relax -%\DTLnewdbentry{scores2}{Score}{71}\relax -%\DTLnewrow{scores2}\relax -%\DTLnewdbentry{scores2}{Surname}{\switchargs{Mere}{de la }}\relax -%\DTLnewdbentry{scores2}{FirstName}{Jos}\relax -%\DTLnewdbentry{scores2}{Score}{58}\relax -%Now sort the data, and put it in table (this is the same code -%as in the previous example: -%\begin{verbatim} -%\begin{table}[htbp] -%\caption{Student scores (influencing the sort order)} -%\centering -%\DTLsort*{Surname,FirstName}{scores}% -%\begin{tabular}{llr} -%\bfseries Surname & -%\bfseries First Name & -%\bfseries Score (\%)% -%\DTLforeach{scores}{% -%\firstname=FirstName,\surname=Surname,\score=Score}{% -%\\ -%\surname & \firstname & \score} -%\end{tabular} -%\end{table} -%\end{verbatim} -%This produces \autoref{tab:influencesort}. -% -%\begin{table}[htbp] -%\caption{Student scores (influencing the sort order)}\label{tab:influencesort} -%\centering -%\DTLsort*{Surname,FirstName}{scores2}\relax -%\begin{tabular}{llr} -%\bfseries Surname & -%\bfseries First Name & -%\bfseries Score (\%)\relax -%\DTLforeach{scores2}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax -%\\ -%\surname & \firstname & \score} -%\end{tabular} -%\end{table} -% -%\end{example} % -%\subsection{Saving a Database to an External File} -%\label{sec:savedb} -% -%\begin{definition}[\DescribeMacro{\DTLsavedb}]% -%\cs{DTLsavedb}\marg{db name}\marg{filename} -%\end{definition} -%This writes the database called \meta{db name} to a file called -%\meta{filename}. The separator and delimiter characters used -%are as given by \ics{DTLsetseparator} (or \ics{DTLsettabseparator}) -%and \ics{DTLsetdelimiter}. For example: -%\begin{verbatim} -%\DTLsettabdelimiter -%\DTLsavedb{scores}{scores.txt} -%\end{verbatim} -%will create a file called "scores.txt" and will save the data in a -%tab separated format. (The delimiters will only be used if a -%given entry contains the separator character.) -% -%\begin{definition}[\DescribeMacro{\DTLsavetexdb}]% -%\cs{DTLsavetexdb}\marg{db name}\marg{filename} -%\end{definition} -%This writes the database called \meta{db name} to a \LaTeX\ file -%called \meta{filename}, where the database is stored as -%a combination of \ics{DTLnewdb}, \ics{DTLnewrow} and -%\ics{DTLnewdbentry} commands. -% -%\subsection{Deleting or Clearing a Database}\label{sec:deletedb} -% -%A database can be cleared or deleted when its contents are no -%longer required. -%\begin{definition}[\DescribeMacro{\DTLcleardb}] -%\cs{DTLcleardb}\marg{db name} -%\end{definition} -%Clears the database given by \meta{db name}. The database is emptied -%but remains defined. -% -%\begin{definition}[\DescribeMacro{\DTLdeletedb}] -%\cs{DTLdeletedb}\marg{db name} -%\end{definition} -%Deletes (undefines) the database given by \meta{db name}. -% -%\subsection{Advanced Database Commands} -% -%This section describes more advanced commands. Further details -%can be found in \autoref{sec:code:datatool}. +%\iffalse +% \begin{macrocode} +%<*datatool-base.sty> +% \end{macrocode} +%\fi +%\chapter{datatool-base.sty} +%\label{sec:code:datatool-base} +% This package provides all the basic commands needed by various +% packages in the \styfmt{datatool} bundle. % -%\begin{definition}[\DescribeMacro{\DTLgetdatatype}] -%\cs{DTLgetdatatype}\marg{cs}\marg{db}\marg{key} -%\end{definition} -%Gets the data type for the given key \meta{key} for the database -%given by \meta{db}. The data type is stored in \meta{cs} which -%must be a command name. The type will be one of: -%\begin{itemize} -%\item\DescribeMacro{\DTLunsettype}\cs{DTLunsettype} (not set), -%\item\DescribeMacro{\DTLstringtype}\cs{DTLstringtype} (string), -%\item\DescribeMacro{\DTLinttype}\cs{DTLinttype} (integer), -%\item\DescribeMacro{\DTLrealtype}\cs{DTLrealtype} (real number) or -%\item\DescribeMacro{\DTLcurrencytype}\cs{DTLcurrenttype} (currency). -%\end{itemize} -% -%\begin{definition}[\DescribeMacro{\dtlforeachkey}]% -%\cs{dtlforeachkey}(\meta{key cs},\meta{col cs},\meta{type -%cs},\meta{header cs})\cs{in}\marg{db}\cs{do}\marg{body} -%\end{definition} -%This iterates through all the keys in the database given by -%\meta{db}. In each iteration, \meta{key cs} is set to the key, -%\meta{col cs} is set to the column index, \meta{type cs} is set to -%the data type (as for \cs{DTLgetdatatype}), \meta{header cs} is set -%to the header for that column, and then \meta{body} is done. Note -%that \meta{key cs}, \meta{col cs}, \meta{type cs} and \meta{header -%cs} must all be control sequences. No check is performed to -%determine if that control sequence already exists, and the control -%sequences are defined globally (since it's likely that -%\cs{dtlforeachkey} may be used within a \env{tabular} environment), -%so you need to make sure you don't override an existing command of -%the same name. -% -%\begin{definition}[\DescribeMacro{\dtlforcolumn}]% -%\cs{dtlforcolumn}\marg{cs}\marg{db}\marg{key}\marg{body} -%\end{definition} -%This iterates through the column given by \meta{key} in the -%database given by \meta{db} and applies \meta{body}. In each -%iteration, \meta{cs} (which must be a control sequence) is set to -%the current element in the column and may be used in \meta{body}. -%Alternatively, if you want to identify the column by its index -%rather than its key, use: -%\begin{definition}[\DescribeMacro{\dtlforcolumnindex}]% -%\cs{dtlforcolumnindex}\marg{cs}\marg{db}\marg{col index}\marg{body} -%\end{definition} +% \begin{macrocode} +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{datatool-base}[2012/07/18 v2.10 (NLCT)] +% \end{macrocode} +% Required packages: +% \begin{macrocode} +\RequirePackage{etoolbox} +\RequirePackage{amsmath} +\RequirePackage{xkeyval} +\RequirePackage{xfor} +\RequirePackage{ifthen} +% \end{macrocode} +% Version of \isty{substr} required that fixes +% \cs{su@IfSubStringInString} +% \begin{macrocode} +\RequirePackage{substr}[2009/10/20] +% \end{macrocode} % -%\begin{definition}[\DescribeMacro{\DTLifdbexists}] -%\cs{DTLifdbexists}\marg{db name}\marg{true part}\marg{false part} -%\end{definition} -%Determines if the database given by \meta{db name} exists. +%\section{Package Options} % -%\begin{definition}[\DescribeMacro{\DTLifhaskey}] -%\cs{DTLifhaskey}\marg{db name}\marg{key}\marg{true part}\marg{false part} -%\end{definition} -%This determines if the database given by \meta{db name} has -%any entries with the key given by \meta{key}. If so, it does -%\meta{true part} otherwise it does \meta{false part}. +%\begin{option}{verbose} +% Define key for package option \pkgopt{verbose}. (This also +% switches the \sty{fp} messages on/off if \sty{datatool-fp} used.) +% This boolean may already have been defined if \sty{datatool} has +% been loaded. +% \begin{macrocode} +\ifundef{\ifdtlverbose} +{ + \define@boolkey{datatool-base.sty}[dtl]{verbose}[true]{} +}% +{} +% \end{macrocode} +%\end{option} +%\begin{option}{math} +% Determine whether to use \sty{fp} or \sty{pgfmath} for the +% arithmetic commands. The default is to use \sty{fp}. +% \begin{macrocode} +\define@choicekey{datatool-base.sty}{math}[\val\nr]{fp,pgfmath}{% + \renewcommand*\@dtl@mathprocessor{#1}% +} +% \end{macrocode} +%\end{option} +%\begin{macro}{\@dtl@mathprocessor} +% \begin{macrocode} +\providecommand*{\@dtl@mathprocessor}{fp} +% \end{macrocode} +%\end{macro} % -%Each key has an associated column index. This can be obtained -%using: -%\begin{definition}[\DescribeMacro{\DTLgetcolumnindex}] -%\cs{DTLgetcolumnindex}\marg{cs}\marg{db}\marg{key} -%\end{definition} -%where \meta{cs} is a command name, \meta{db} is the database label -%and \meta{key} is the key. The column index is stored in -%\meta{cs}. +% Process options: +% \begin{macrocode} +\ProcessOptionsX +% \end{macrocode} % -%You can also do the reverse and find the key associated with a -%given column index: -%\begin{definition}[\DescribeMacro{\DTLgetkeyforcolumn}] -%\cs{DTLgetkeyforcolumn}\marg{key cs}\marg{db}\marg{column index} -%\end{definition} -%The key is stored in \meta{key cs} (which must be a command name). +% Load package dealing with numerical processes: +% \begin{macrocode} +\RequirePackage{datatool-\@dtl@mathprocessor} +% \end{macrocode} % -%There is also a full expandable way of obtaining the column -%index, but note that no check is performed to determine -%if the database exists, or if it contains the given key: -%\begin{definition}[\DescribeMacro{\dtlcolumnindex}] -%\cs{dtlcolumnindex}\marg{db name}\marg{key} -%\end{definition} +%\section{Utilities} % -%\begin{definition}[\DescribeMacro{\DTLgetkeydata}] -%\cs{DTLgetkeydata}\marg{key}\marg{db}\marg{col cs}\marg{type cs}\marg{header cs} +%\begin{macro}{\dtl@message} +%\begin{definition} +%\cs{dtl@message}\marg{message string} %\end{definition} -%Gets data for given key in database \meta{db}: the column index is -%stored in \meta{col cs} (as \cs{DTLgetcolumnindex}), the type is -%stored in \meta{type cs} (as \cs{DTLgetdatatype}) and the header -%is stored in \meta{header cs}. +% Displays message only if the verbose option is set. +% \begin{macrocode} +\newcommand*{\dtl@message}[1]{% + \ifdtlverbose\typeout{#1}\fi +} +% \end{macrocode} +%\end{macro} % -%\begin{definition}[\DescribeMacro{\DTLgetvalue}] -%\cs{DTLgetvalue}\marg{cs}\marg{db}\marg{r}\marg{c} -%\end{definition} -%This gets the value for row given by index \meta{r} and column -%given by \meta{c} for the database \meta{db} and stores it in -%\meta{cs} which must be a command name. If you want to get the -%value by key rather than column index you can use -%\cs{dtlcolumnindex}. For example, the following gets the value -%for row~3 with key \texttt{Surname} from the database -%\texttt{data} and stores in \cs{myval}: -%\begin{verbatim} -%\DTLgetvalue{\myval}{data}{3}{\dtlcolumnindex{data}{Surname}} -%\end{verbatim} +%\begin{macro}{\@dtl@toks} +% \begin{macrocode} +\newtoks\@dtl@toks +% \end{macrocode} +%\end{macro} % -%\begin{definition}[\DescribeMacro{\DTLgetlocation}] -%\cs{DTLgetlocation}\marg{row cs}\marg{column cs}\marg{database}% -%\marg{value} +%\begin{macro}{\@dtl@tmpcount} +% Define temporary count register +% \begin{macrocode} +\newcount\@dtl@tmpcount +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtl@tmplength} +% Define temporary length register: +% \begin{macrocode} +\newlength\dtl@tmplength +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtl@ifsingle} +%\begin{definition} +%\cs{dtl@ifsingle}\marg{arg}\marg{true part}\marg{false part} %\end{definition} -%Assigns \meta{row cs} and \meta{column cs} to the indices of the -%first entry in \meta{database} that matches \meta{value}. +% If there is only one object in \meta{arg} (without expansion) +% do \meta{true part}, otherwise do false part. +% \begin{macrocode} +\newcommand{\dtl@ifsingle}[3]{% + \def\@dtl@arg{#1}% + \ifdefempty{\@dtl@arg}% + {% + #3% + }% + {% + \@dtl@ifsingle#1\@nil{#2}{#3}% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\@dtl@ifsingle} +% \begin{macrocode} +\def\@dtl@ifsingle#1#2\@nil#3#4{% + \def\dtl@sg@arg{#2}% + \ifdefempty{\dtl@sg@arg}% + {% + #3% + }% + {% + #4% + }% +} +% \end{macrocode} +%\end{macro} % -%\begin{definition}[\DescribeMacro{\DTLgetvalueforkey}] -%\cs{DTLgetvalueforkey}\marg{cmd}\marg{key}\marg{db name}\marg{ref -% key}\marg{ref value} -%\end{definition} -%This (globally) sets \meta{cmd} (a control sequence) to the -%value of the key specified by \meta{key} in the first row -%of the database called \meta{db name} which contains the key -%\meta{ref key} which has the value \meta{value}. +%\begin{macro}{\long@collect@body} +% Need long versions of \isty{amsmath}'s \cs{collect@body}. These macros are +% adapted from the macros defined by \sty{amsmath}. +% \begin{macrocode} +\long\def\long@collect@body#1{% + \@envbody{\@xp#1\@xp{\the\@envbody}}% + \edef\process@envbody{\the\@envbody\@nx\end{\@currenvir}}% + \@envbody\@emptytoks \def\begin@stack{b}% + \begingroup + \@xp\let\csname\@currenvir\endcsname\long@collect@@body + \edef\process@envbody{\@xp\@nx\csname\@currenvir\endcsname}% + \process@envbody +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\long@addto@envbody} +%\changes{2.10}{2012-07-18}{new} +% Adapted from \isty{amsmath}'s \cs{addto@envbody} +% \begin{macrocode} +\long\def\long@addto@envbody#1{% + \toks@{#1}% + \edef\@dtl@tmp{\the\@envbody\the\toks@}% + \global\@envbody\@xp{\@dtl@tmp}% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\long@collect@@body} +%\changes{2.10}{2012-07-18}{new} +% Adapted from \isty{amsmath}'s \cs{collect@body} +% \begin{macrocode} +\long\def\long@collect@@body#1\end#2{% + \protected@edef\begin@stack{% + \long@push@begins#1\begin\end \@xp\@gobble\begin@stack + }% + \ifx\@empty\begin@stack + \endgroup + \@checkend{#2}% + \long@addto@envbody{#1}% + \else + \long@addto@envbody{#1\end{#2}}% + \fi + \process@envbody +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\long@push@begins} +%\changes{2.10}{2012-07-16}{new} +%Adapted from \isty{amsmath}'s \cs{push@begins} +% \begin{macrocode} +\long\def\long@push@begins#1\begin#2{% + \ifx\end#2\else b\@xp\long@push@begins\fi +} +% \end{macrocode} +%\end{macro} % -%Two rows can be swapped using: -%\begin{definition}[\DescribeMacro{\DTLswaprows}]% -%\cs{DTLswaprows}\marg{db name}\marg{row1 index}\marg{row2 index} -%\end{definition} -%where \meta{row1 index} and \meta{row2 index} are the indices -%of the rows to be swapped. For example: -%\begin{verbatim} -%\DTLswaprows{scores}{3}{5} -%\end{verbatim} -%will swap the third and fifth rows. +%\subsection{General List Utilities} % -%\begin{definition}[\DescribeMacro{\DTLifinlist}] +%\begin{macro}{\DTLifinlist} +%\begin{definition} %\cs{DTLifinlist}\marg{element}\marg{list}\marg{true part}\marg{false part} %\end{definition} -%If \meta{element} is contained in the comma-separated list given -%by \meta{list}, then do \meta{true part} otherwise do false -%part. (Does a one level expansion on \meta{list}, but no -%expansion on \meta{element}.) -% -%\section{Pie Charts (\texorpdfstring{\sty{datapie}}{datapie} package)} -% -%The \sty{datapie} package is not loaded by the \sty{datatool} package, -%so you need to explicitly load \sty{datapie} if you want to use any of the -%commands defined in this section. You will also need to have the -%\sty{pgf}/\sty{tikz} packages installed. The \sty{datapie} package -%may be given the following options: -%\begin{description} -%\item[{\pkgopt[datapie]{color}}] Colour option (default). -%\item[{\pkgopt[datapie]{gray}}] Grey scale option. -%\item[{\pkgopt[datapie]{rotateinner}}] -%Rotate inner labels so that they are aligned -%with the pie chart radial axis. -%\item[{\pkgopt[datapie]{norotateinner}}] -%Don't rotate inner labels (default). -%\item[{\pkgopt[datapie]{rotateouter}}] -%Rotate outer labels so that they are aligned -%with the pie chart radial axis. -%\item[{\pkgopt[datapie]{norotateouter}}] -%Don't rotate outer labels (default). -%\end{description} -% -%Numerical information contained in a database created by the -%\sty{datatool} package can be converted into a pie chart using -%\begin{definition}[\DescribeMacro{\DTLpiechart}]% -%\cs{DTLpiechart}\oarg{condition}\marg{settings list}\marg{db name}\marg{values} -%\end{definition}\noindent -%where \meta{db name} is the name of the database, and -%\meta{condition} has the same form as the optional argument -%to \ics{DTLforeach} described in \autoref{sec:dbforeach}. If -%\meta{condition} is false, that information is omitted from the -%construction of the pie chart. The argument \meta{values} is a -%comma separated list of \meta{cmd}"="\meta{key} pairs, the same -%as that required by the penultimate argument of \ics{DTLforeach}. -%The \meta{settings list} is a comma separated list of -%\meta{setting}=\meta{value} pairs, where \meta{setting} can be any of -%the following: -%\begin{description} -%\item[\setting{DTLpiechart}{variable}] -%This specifies the control sequence to use that -%contains the value used to construct the pie chart. The control -%sequence must be one of the control sequences to appear in -%the assignment list \meta{values}. This setting is required. -% -%\item[\setting{DTLpiechart}{start}] -%This is the starting angle of the first segment. The -%value is 0 by default. -% -%\item[\setting{DTLpiechart}{radius}] -%This is the radius of the pie chart. The default value -%is 2cm. -% -%\item[\setting{DTLpiechart}{innerratio}] -%The distance from the centre of the -%pie chart to the point where the inner labels are placed is given -%by this value multiplied by the ratio. The default value is 0.5. -% -%\item[\setting{DTLpiechart}{outerratio}] -%The distance from the centre of the -%pie chart to the point where the outer labels are placed is given -%by this value multiplied by the ratio. The default value is 1.25. -% -%\item[\setting{DTLpiechart}{cutawayratio}] -%The distance from the centre of the pie chart -%to the point of cutaway segments is given by this value multiplied -%by the ratio. The default value is 0.2. -% -%\item[\setting{DTLpiechart}{inneroffset}] -%This is the absolute distance from the centre -%of the pie chart to the point where the inner labels are placed. -%You should use only one or other of \setting{DTLpiechart}{innerratio} -%and \setting{DTLpiechart}{inneroffset}, not both. If you also want to -%specify the radius, you must use \setting{DTLpiechart}{ratio} -%before \setting{DTLpiechart}{inneroffset}. If omitted, the inner -%offset is obtained from the ratio multiplied by the -%\setting{DTLpiechart}{innerratio} value. -% -%\item[\setting{DTLpiechart}{outeroffset}] -%This is the absolute distance from the centre -%of the pie chart to the point where the outer labels are placed. -%You should use only one or other of \setting{DTLpiechart}{outerratio} -%and \setting{DTLpiechart}{outeroffset}, not both. If you also want to -%specify the radius, you must use \setting{DTLpiechart}{ratio} -%before \setting{DTLpiechart}{outeroffset}. If omitted, the outer -%offset is obtained from the ratio multiplied by the -%\setting{DTLpiechart}{outerratio} value. -% -%\item[\setting{DTLpiechart}{cutawayoffset}] -%This is the absolute distance from the centre of -%the pie chart to the point of the cutaway segments. You should use -%only one or other of \setting{DTLpiechart}{cutawayratio} and -%\setting{DTLpiechart}{cutawayoffset}, not both. If -%you also want to specify the radius, you must use -%\setting{DTLpiechart}{ratio} before -%\setting{DTLpiechart}{cutawayoffset}. If omitted, the cutaway offset -%is obtained from the ratio multiplied by the -%\setting{DTLpiechart}{cutawayratio} value. -% -%\item[\setting{DTLpiechart}{cutaway}] -%This is a list of cutaway segments. This should be -%a comma separated list of individual numbers, or number ranges -%(separated by a dash). For example "cutaway={1,3}" will separate -%the first and third segments from the rest of the pie chart, offset -%by the value of the \setting{DTLpiechart}{cutawayoffset} setting, -%whereas "cutaway={1-3}" will separate the -%first three segments from the rest of the pie chart. If omitted, -%the pie chart will be whole. -% -%\item[\setting{DTLpiechart}{innerlabel}] -%The value of this is positioned in the middle of each segment at a -%distance of \setting{DTLpiechart}{inneroffset} from the centre -%of the pie chart. The default is the same as the value of -%\setting{DTLpiechart}{variable}. -% -%\item[\setting{DTLpiechart}{outerlabel}] -%The value of this is positioned at a distance of -%\setting{DTLpiechart}{outeroffset} from the centre of the pie chart. -%The default is empty. -% -%\item[\setting{DTLpiechart}{rotateinner}] This is a boolean setting, -%so it can only take the values "true" and "false". If the value is -%omitted "true" is assumed. If true, the inner labels are rotated -%along the spokes of the pie chart, otherwise the inner labels are not -%rotated. There are analogous package options -%\pkgopt[datapie]{rotateinner} and \pkgopt[datapie]{norotateinner}. -% -%\item[\setting{DTLpiechart}{rotateouter}] -%This is a boolean setting, so it can only take -%the values "true" and "false". If the value is omitted "true" is -%assumed. If true, the outer labels are rotated along the spokes of -%the pie chart, otherwise the outer labels are not rotated. -%There are analogous package options -%\pkgopt[datapie]{rotateouter} and \pkgopt[datapie]{norotateouter}. -% -%\end{description} -% -%\begin{example}{A Pie Chart}{ex:piechart} -%This example loads data from a file called "fruit.csv" which contains -%the following: -%\begin{verbatim} -%Name,Quantity -%"Apples",30 -%"Pears",25 -%"Lemons,Limes",40.5 -%"Peaches",34.5 -%"Cherries",20 -%\end{verbatim} -%First load the data: -%\begin{verbatim} -%\DTLloaddb{fruit}{fruit.csv} -%\end{verbatim} -%\DTLnewdb{fruit}\relax -%\DTLnewrow{fruit}\relax -%\DTLnewdbentry{fruit}{Name}{Apples}\relax -%\DTLnewdbentry{fruit}{Quantity}{30}\relax -%\DTLnewrow{fruit}\relax -%\DTLnewdbentry{fruit}{Name}{Pears}\relax -%\DTLnewdbentry{fruit}{Quantity}{25}\relax -%\DTLnewrow{fruit}\relax -%\DTLnewdbentry{fruit}{Name}{Lemons,Limes}\relax -%\DTLnewdbentry{fruit}{Quantity}{40.5}\relax -%\DTLnewrow{fruit}\relax -%\DTLnewdbentry{fruit}{Name}{Peaches}\relax -%\DTLnewdbentry{fruit}{Quantity}{34.5}\relax -%\DTLnewrow{fruit}\relax -%\DTLnewdbentry{fruit}{Name}{Cherries}\relax -%\DTLnewdbentry{fruit}{Quantity}{20}\relax -%Now create a pie chart in a figure: -%\begin{verbatim} -%\begin{figure}[htbp] -%\centering -%\DTLpiechart{variable=\quantity}{fruit}{\name=Name,\quantity=Quantity} -%\caption{A pie chart} -%\end{figure} -%\end{verbatim} -%This creates \autoref{fig:piechart}. -% -%\begin{figure}[htbp] -%\centering -%\DTLpiechart{variable=\quantity}{fruit}{\name=Name,\quantity=Quantity} -%\caption{A pie chart} -%\label{fig:piechart} -%\end{figure} -% -%There are no outer labels by default, but they can be set -%using the \setting{DTLpiechart}{outerlabel} setting. -%The following sets the outer label to the value of the "Name" key: -%\begin{verbatim} -%\begin{figure}[htbp] -%\centering -%\DTLpiechart{variable=\quantity,outerlabel=\name}{fruit}{% -%\name=Name,\quantity=Quantity} -%\caption{A pie chart (outer labels set)} -%\end{figure} -%\end{verbatim} -%This creates \autoref{fig:piechartouter}. -% -%\begin{figure}[htbp] -%\centering -%\DTLpiechart{variable=\quantity,outerlabel=\name}{fruit} -%{\name=Name,\quantity=Quantity} -%\caption{A pie chart (outer labels set)} -%\label{fig:piechartouter} -%\end{figure} -% -%You may prefer the labels to be rotated. The following -%switches on the rotation for the inner and outer labels: -%\begin{verbatim} -%\begin{figure}[htbp] -%\centering -%\DTLpiechart{variable=\quantity,outerlabel=\name,% -%rotateinner,rotateouter}{fruit}{% -%\name=Name,\quantity=Quantity} -%\caption{A pie chart (rotation enabled)} -%\end{figure} -%\end{verbatim} -%This creates \autoref{fig:piechartrot}. -% -%\begin{figure}[htbp] -%\centering -%\DTLpiechart{variable=\quantity,outerlabel=\name -%,rotateinner,rotateouter}{fruit} -%{\name=Name,\quantity=Quantity} -%\caption{A pie chart (rotation enabled)} -%\label{fig:piechartrot} -%\end{figure} -%\end{example} -% -%\begin{example}{Separating Segments from the Pie Chart}{ex:cutaway} -%You may want to separate one or more segments from the pie chart, -%perhaps to emphasize them. You can do this using the -%\setting{DTLpiechart}{cutaway} -%setting. The following separates the first and third segments -%from the pie chart: -%\begin{verbatim} -%\begin{figure}[htbp] -%\centering -%\DTLpiechart{variable=\quantity,outerlabel=\name,% -%cutaway={1,3}}{fruit}{% -%\name=Name,\quantity=Quantity} -%\caption{A pie chart with cutaway segments} -%\end{figure} -%\end{verbatim} -%This produces \autoref{fig:piecutaway}. -% -%\begin{figure}[htbp] -%\centering -%\DTLpiechart{variable=\quantity,outerlabel=\name -%,cutaway={1,3}}{fruit}{\name=Name,\quantity=Quantity} -%\caption{A pie chart with cutaway segments} -%\label{fig:piecutaway} -%\end{figure} -% -%Alternatively I can specify a range of segments. The following -%separates the first two segments: -%\begin{verbatim} -%\begin{figure}[htbp] -%\centering -%\DTLpiechart{variable=\quantity,outerlabel=\name,% -%cutaway={1-2}}{fruit}{% -%\name=Name,\quantity=Quantity} -%\caption{A pie chart with cutaway segments (\texttt{cutaway=\{1-2\}})} -%\end{figure} -%\end{verbatim} -%This produces \autoref{fig:piecutaway2}. -% -%\begin{figure}[htbp] -%\centering -%\DTLpiechart{variable=\quantity,outerlabel=\name -%,cutaway={1-2}}{fruit}{\name=Name,\quantity=Quantity} -%\caption{A pie chart with cutaway segments (\texttt{cutaway=\{1-2\}})} -%\label{fig:piecutaway2} -%\end{figure} -% -%Notice the difference between \autoref{fig:piecutaway2} and -%\autoref{fig:piecutaway3} which was produced using: -%\begin{verbatim} -%\begin{figure}[htbp] -%\centering -%\DTLpiechart{variable=\quantity,outerlabel=\name,% -%cutaway={1,2}}{fruit}{% -%\name=Name,\quantity=Quantity} -%\caption{A pie chart with cutaway segments (\texttt{cutaway=\{1,2\}})} -%\end{figure} -%\end{verbatim} -% -%\begin{figure}[htbp] -%\centering -%\DTLpiechart{variable=\quantity,outerlabel=\name -%,cutaway={1,2}}{fruit}{\name=Name,\quantity=Quantity} -%\caption{A pie chart with cutaway segments (\texttt{cutaway=\{1,2\}})} -%\label{fig:piecutaway3} -%\end{figure} -% -%\end{example} -% -%\subsection{Pie Chart Variables} -% -%\begin{definition}[\DescribeMacro{\DTLpievariable}]% -%\cs{DTLpievariable} -%\end{definition} -%This command is set to the variable given by the -%\setting{DTLpiechart}{variable} setting in the \meta{settings list} -%argument of \cs{DTLpiechart}. The \setting{DTLpiechart}{innerlabel} -%is set to \cs{DTLpievariable} by default. -% -%\begin{definition}[\DescribeMacro{\DTLpiepercent}]% -%\cs{DTLpiepercent} -%\end{definition} -%This command is set to the percentage value of \cs{DTLpievariable}. -%The percentage value is rounded to \meta{n} digits, where \meta{n} -%is the value of the \LaTeX\ counter -%\desctr{DTLpieroundvar}. -% -%\begin{example}{Changing the Inner and Outer Labels}{ex:pielabels} -%This example uses the database defined in \autoref{ex:piechart}. -%The inner label is now set to the percentage value, rather than -%the actual value, and the outer label is set to the name with -%the actual value in parentheses. -%\begin{verbatim} -%\begin{figure}[htbp] -%\centering -%\DTLpiechart{variable=\quantity,% -%innerlabel={\DTLpiepercent\%},% -%outerlabel={\name\ (\DTLpievariable)}}{fruit}{% -%\name=Name,\quantity=Quantity} -%\caption{A pie chart (changing the labels)} -%\end{figure} -%\end{verbatim} -%This produces \autoref{fig:piechartlabels}. -% -%\begin{figure}[htbp] -%\centering -%\DTLpiechart{variable=\quantity,innerlabel={\DTLpiepercent -%\%},outerlabel={\name\ (\DTLpievariable)}}{fruit}{\name=Name,\quantity=Quantity} -%\caption{A pie chart (changing the labels)} -%\label{fig:piechartlabels} -%\end{figure} -%\end{example} -% -%\subsection{Pie Chart Label Formatting} -% -%\begin{definition}[\DescribeMacro{\DTLdisplayinnerlabel}]% -%\cs{DTLdisplayinnerlabel}\marg{text} -%\end{definition} -%This governs how the inner label is formatted, where \meta{text} -%is the text of the inner label. The default is to just do \meta{text}. -% -%\begin{definition}[\DescribeMacro{\DTLdisplayouterlabel}]% -%\cs{DTLdisplayouterlabel}\marg{text} -%\end{definition} -%This governs how the outer label is formatted, where \meta{text} -%is the text of the outer label. The default is to just do \meta{text}. -% -%\begin{example}{Changing the Inner and Outer Label -%Format}{ex:pielabelformat} -%This example extends \autoref{ex:pielabels}. -%The inner and outer labels are now both typeset in a sans-serif -%font: -%\begin{verbatim} -%\begin{figure}[htbp] -%\centering -%\renewcommand*{\DTLdisplayinnerlabel}[1]{\textsf{#1}} -%\renewcommand*{\DTLdisplayouterlabel}[1]{\textsf{#1}} -%\DTLpiechart{variable=\quantity,% -%innerlabel={\DTLpiepercent\%},% -%outerlabel={\name\ (\DTLpievariable)}}{fruit}{% -%\name=Name,\quantity=Quantity} -%\caption{A pie chart (changing the label format)} -%\end{figure} -%\end{verbatim} -%This produces \autoref{fig:piechartlabelformat}. -% -%\begin{figure}[htbp] -%\centering -%\renewcommand*{\DTLdisplayinnerlabel}[1]{\textsf{#1}} -%\renewcommand*{\DTLdisplayouterlabel}[1]{\textsf{#1}} -%\DTLpiechart{variable=\quantity,innerlabel={\DTLpiepercent -%\%},outerlabel={\name\ (\DTLpievariable)}}{fruit}{\name=Name,\quantity=Quantity} -%\caption{A pie chart (changing the label format)} -%\label{fig:piechartlabelformat} -%\end{figure} -%\end{example} -% -%\subsection{Pie Chart Colours} -% -%The \sty{datapie} package predefines colours for the first -%eight segments of the pie chart. If you require more than -%eight segments or if you want to change the default colours, you -%will need to use -%\begin{definition}[\DescribeMacro{\DTLsetpiesegmentcolor}]% -%\cs{DTLsetpiesegmentcolor}\marg{n}\marg{color} -%\end{definition}\noindent -%The first argument \meta{n} is the segment index (starting from 1), -%and the second argument \meta{color} is a colour specifier as used -%in commands such as \cs{color}. -% -%It is a good idea to set the colours so that each segment colour -%is somehow relevant to whatever the segment represents. For -%example, in the previous examples of pie charts depicting fruit, -%some of default colours were inappropriate. Whilst red is -%appropriate for apples and green is appropriate for pears, blue -%doesn't really correspond to lemons or limes. -% -%\begin{definition}[\DescribeMacro{\DTLdopiesegmentcolor}]% -%\cs{DTLdopiesegmentcolor}\meta{n} -%\end{definition} -%This sets the current text colour to that of the \meta{n}th -%segment. -% -%\begin{definition}[\DescribeMacro{\DTLdocurrentpiesegmentcolor}]% -%\cs{DTLdocurrentpiesegmentcolor} -%\end{definition} -%This sets the current text colour to that of the current pie -%segment. This command may only be used within a pie chart, or -%within the body of \ics{DTLforeach}. -% -%\begin{definition}[\DescribeMacro{\DTLpieoutlinecolor}]% -%\cs{DTLpieoutlinecolor} -%\end{definition} -%This sets the outline colour for the pie chart. The default is -%black. -% -%\begin{definition}[\DescribeMacro{\DTLpieoutlinewidth}]% -%\cs{DTLpieoutlinewidth} -%\end{definition} -%This is a length that governs the line width of the outline. The -%default value is 0pt, but can be changed using \cs{setlength}. -%The outline is only drawn if \cs{DTLpieoutlinewidth} is greater -%than 0pt. -% -%\begin{example}{Pie Segment Colours}{ex:piecolours} -%This example extends \autoref{ex:pielabelformat}. -%It sets the outline thickness to 2pt, and -%the outer label is now set in the same colour as the fill colour -%of the segment to which it belongs. The third segment (lemons and -%limes) is set to yellow and the fourth segment (peaches) is set -%to pink. In addition, a legend is created using \ics{DTLforeach}. -%\begin{verbatim} -%\begin{figure}[htbp] -%\centering -%\setlength{\DTLpieoutlinewidth}{2pt} -%\DTLsetpiesegmentcolor{3}{yellow} -%\DTLsetpiesegmentcolor{4}{pink} -%\renewcommand*{\DTLdisplayinnerlabel}[1]{\textsf{#1}} -%\renewcommand*{\DTLdisplayouterlabel}[1]{% -%\DTLdocurrentpiesegmentcolor -%\textsf{\shortstack{#1}}} -%\DTLpiechart{variable=\quantity,% -%innerlabel={\DTLpiepercent\%},% -%outerlabel={\name\\(\DTLpievariable)}}{fruit}{% -%\name=Name,\quantity=Quantity} -%\begin{tabular}[b]{ll} -%\DTLforeach{fruit}{\name=Name}{\DTLiffirstrow{}{\\}% -%\DTLdocurrentpiesegmentcolor\rule{10pt}{10pt} & -%\name -%} -%\end{tabular} -%\caption{A pie chart (using segment colours and outline)} -%\end{figure} -%\end{verbatim} -%This produces \autoref{fig:piesegcolour}. (The format of the -%outer label has been changed to use \cs{shortstack} to -%prevent the outer labels from taking up so much horizontal -%space. The \setting{DTLpiechart}{outerlabel} setting has also been -%modified to use "\\" after the name to move the percentage value onto -%the next row.) -% -%\begin{figure}[htbp] -%\centering -%\setlength{\DTLpieoutlinewidth}{2pt} -%\DTLsetpiesegmentcolor{3}{yellow} -%\DTLsetpiesegmentcolor{4}{pink} -%\renewcommand*{\DTLdisplayinnerlabel}[1]{\textsf{#1}} -%\renewcommand*{\DTLdisplayouterlabel}[1]{\relax -%\DTLdocurrentpiesegmentcolor -%\textsf{\shortstack{#1}}} -%\DTLpiechart{variable=\quantity,innerlabel={\DTLpiepercent -%\%},outerlabel={\name\\(\DTLpievariable)}}{fruit}{\name=Name,\quantity=Quantity} -%\begin{tabular}[b]{ll} -%\DTLforeach{fruit}{\name=Name}{\DTLiffirstrow{}{\\}\relax -%\DTLdocurrentpiesegmentcolor\rule{10pt}{10pt} & -%\name -%} -%\end{tabular} -%\caption{A pie chart (using segment colours and outline)} -%\label{fig:piesegcolour} -%\end{figure} -%\end{example} -% -%\subsection{Adding Extra Commands Before and After the Pie Chart} -% -%The pie charts created using \ics{DTLpiechart} are placed inside -%a \env{tikzpicture} environment (defined by the \sty{tikz} package). -% -%\begin{definition}[\DescribeMacro{\DTLpieatbegintikz}]% -%\cs{DTLpieatbegintikz} -%\end{definition} -%The macro \cs{DTLpieatbegintikz} is called at the start of the -%\env{tikzpicture} environment, allowing you to change the -%\env{tikzpicture} settings. By default \cs{DTLpieatbegintikz} -%does nothing, but you can redefine it to, say, scale the pie -%chart (but be careful not to distort the chart). -% -%\begin{definition}[\DescribeMacro{\DTLpieatendtikz}]% -%\cs{DTLpieatendtikz} -%\end{definition} -%The macro \cs{DTLpieatendtikz} is called at the end of the -%\env{tikzpicture} environment, allowing you add additional -%graphics to the pie chart. This does nothing by default. -% -%\begin{example}{Adding Information to the Pie Chart}{ex:piescale} -%This example modifies \autoref{ex:piechart}. It redefines -%\cs{DTLpieatendtikz} to add an annotated arrow. -%\begin{verbatim} -%\begin{figure}[htbp] -%\centering -%\renewcommand*{\DTLpieatendtikz}{% -%\draw[<-] (45:1.5cm) -- (40:2.5cm)node[right]{Apples};} -%\DTLpiechart{variable=\quantity}{fruit}{% -%\name=Name,\quantity=Quantity} -%\caption{An annotated pie chart} -%\end{figure} -%\end{verbatim} -%This produces \autoref{fig:pieannote}. (Note that the centre -%of the pie chart is the origin of the TikZ picture.) -% -%\begin{figure}[htbp] -%\centering -%\renewcommand*{\DTLpieatendtikz}{% -%\draw[<-] (45:1.5cm) -- (40:2.5cm)node[right]{Apples};} -%\DTLpiechart{variable=\quantity}{fruit}{\name=Name,\quantity=Quantity} -%\caption{An annotated pie chart} -%\label{fig:pieannote} -%\end{figure} -%\end{example} -% -%\section{Scatter and Line Plots (\texorpdfstring{\sty{dataplot}}{dataplot} -%package)} -% -%The \sty{dataplot} package provides commands for creating -%scatter or line plots from databases. It uses the pgf/TikZ plot -%handler library to create the plots. See the \sty{pgf} manual for -%more detail on pgf streams and plot handles. The \sty{dataplot} -%package is not loaded by \sty{datatool} so if you want to use -%it you need to load it explicitly using "\usepackage{dataplot}". -% -% -%\begin{definition}[\DescribeMacro{\DTLplot}]% -%\cs{DTLplot}\oarg{condition}\marg{db list}\marg{settings} -%\end{definition} -%This command creates a plot (inside a \env{tikzpicture} environment) -%of all the data given in the databases listed in \meta{db list}, -%which should be a comma separated list of database names. -%The optional argument \meta{condition} is the same as that for -%\ics{DTLforeach}. The \meta{settings} argument is a comma separated -%list of \meta{setting}"="\meta{value} pairs. There are two settings -%that must be specified \setting{DTLplot}{x} and \setting{DTLplot}{y}. -%The other settings are optional. Note that any value that contains -%a comma, must be enclosed in braces. For example -%"colors={red,cyan,blue}". Note where any setting requires -%a number, or list of numbers (such as \setting{DTLplot}{bounds}) -%the number must be supplied in standard decimal notation (i.e.\ -%no currency, no number groups, and a full stop as the decimal -%point). Available settings are as follows: -%\begin{description} -%\item[\setting{DTLplot}{x}] The database key -%that specifies the $x$ co-ordinates. This setting is required. -% -%\item[\setting{DTLplot}{y}] The database key that specifies -%the $y$ co-ordinates. This setting is required. -% -%\item[\setting{DTLplot}{markcolors}] A comma separated list of colour -%names for the markers. An empty value will use the current colour. -% -%\item[\setting{DTLplot}{linecolors}] A comma separated list of colour -%names for the plot lines. An empty value will use the current colour. -% -%\item[\setting{DTLplot}{colors}] A comma separated list of colour -%names for the lines and markers. -% -%\item[\setting{DTLplot}{marks}] A comma separated list of -%code to generate plot marks. (This should typically be a list -%of \cs{pgfuseplotmark} commands, see the \sty{pgf} manual for -%further details.) You may use \cs{relax} as an element -%of the list to suppress markers for the corresponding plot. -%For example: "marks={\pgfuseplotmark{o},\relax}" will use an -%open circle marker for the first database, and no markers for the -%second database listed in \meta{db list}. -% -%\item[\setting{DTLplot}{lines}] A comma separated list of -%line style settings. (This should typically be a list of -%\cs{pgfsetdash} commands, see the \sty{pgf} manual for -%further details on how to set the line style.) An empty value -%will use the current line style. -%You may use \cs{relax} as an element -%of the list to suppress line for the corresponding plot. -%For example: "lines={\relax,\pgfsetdash{}{0pt}}" -%will have no lines for the first database, and a solid line -%for the second database listed in \meta{db list}. -% -%\item[\setting{DTLplot}{width}] The width of the plot. This must -%be a length. The plot width does not include outer tick marks or -%labels. -% -%\item[\setting{DTLplot}{height}] The height of the plot. This must -%be a length. The plot height does not include outer tick marks -%or labels. -% -%\item[\setting{DTLplot}{style}] This setting governs whether -%to use lines or markers in the plot, and may take one of -%the following values: "both" (lines and markers), -%"lines" (only lines) or "markers" (only markers). The default is -%"markers". -% -%\item[\setting{DTLplot}{axes}] This setting governs whether -%to display the axes, and may take one of -%the following values: "both", "x", "y" or "none". If no value -%is specified, "both" is assumed. -% -%\item[\setting{DTLplot}{box}] This setting governs whether -%or not to surround the plot in a box. It is a boolean setting, -%taking only the values "true" and "false". If no value is -%specified, "true" is assumed. -% -%\item[\setting{DTLplot}{xtics}] This setting governs whether -%or not to display the $x$ tick marks. It is a boolean setting, -%taking only the values "true" and "false". If no value is -%specified "true" is assumed. If the \setting{DTLplot}{axes} -%setting is set to "both" or "x", this value will automatically -%be set to "true", otherwise it will be set to "false". -% -%\item[\setting{DTLplot}{ytics}] This setting governs whether -%or not to display the $y$ ticks. It is a boolean setting, -%taking only the values "true" and "false". If no value is -%specified "true" is assumed. If the \setting{DTLplot}{axes} -%setting is set to "both" or "y", this value will automatically -%be set to "true", otherwise it will be set to "false". -% -% -%\item[\setting{DTLplot}{xminortics}] This setting governs whether -%or not to display the $x$ minor tick marks. It is a boolean -%setting, taking only the values "true" and "false". If no value is -%specified "true" is assumed. This setting also sets the -%$x$ major tick marks on if the value is "true". -% -%\item[\setting{DTLplot}{yminortics}] This setting governs whether -%or not to display the $y$ minor tick marks. It is a boolean -%setting, taking only the values "true" and "false". If no value is -%specified "true" is assumed. This setting also sets the -%$y$ major tick marks on if the value is "true". -% -%\item[\setting{DTLplot}{xticdir}] This sets the $x$ tick direction, -%and may only take the values "in" or "out". -% -%\item[\setting{DTLplot}{yticdir}] This sets the $y$ tick direction, -%and may only take the values "in" or "out". -% -%\item[\setting{DTLplot}{ticdir}] This sets the $x$ and $y$ tick -%direction, and may only take the values "in" or "out". -% -%\item[\setting{DTLplot}{bounds}] The value must be in the form -%\meta{min x}","\meta{min y}","\meta{max x}","\meta{max y}. This -%sets the graph bounds to the given values. If omitted the -%bounds are computed from the maximum and minimum values of the -%data. For example -%\begin{verbatim} -%\DTLplot{data1,data2}{x=Height,y=Weight,bounds={0,0,10,20}} -%\end{verbatim} -%Note that the \setting{DTLplot}{bounds} setting overrides -%the \setting{DTLplot}{minx}, \setting{DTLplot}{maxx}, -%\setting{DTLplot}{miny} and \setting{DTLplot}{maxy} settings. -% -%\item[\setting{DTLplot}{minx}] The value is the minimum value -%of the $x$ axis. -% -%\item[\setting{DTLplot}{miny}] The value is the minimum value -%of the $y$ axis. -% -%\item[\setting{DTLplot}{maxx}] The value is the maximum value -%of the $x$ axis. -% -%\item[\setting{DTLplot}{maxy}] The value is the maximum value -%of the $y$ axis. -% -%\item[\setting{DTLplot}{xticpoints}] The value must be a comma -%separated list of decimal numbers indicating where to put the -%$x$ tick marks. If omitted, the $x$ tick marks are placed at -%equal intervals along the $x$ axis such that each interval is -%not less than the length given by \ics{DTLmintickgap}. -%This setting overrides \setting{DTLplot}{xticgap}. -% -%\item[\setting{DTLplot}{xticgap}] This value specifies the -%gap between the $x$ tick marks. -% -%\item[\setting{DTLplot}{yticpoints}] The value must be a comma -%separated list of decimal numbers indicating where to put the -%$y$ tick marks. If omitted, the $y$ tick marks are placed at -%equal intervals along the $y$ axis such that each interval is -%not less than the length given by \ics{DTLmintickgap}. -%This setting overrides \setting{DTLplot}{yticgap}. -% -%\item[\setting{DTLplot}{yticgap}] This value specifies the -%gap between the $y$ tick marks. -% -%\item[\setting{DTLplot}{grid}] This is a boolean value that -%specifies whether or not to display the grid. If no value -%is given, "true" is assumed. The minor grid lines are only -%displayed if the minor tick marks are set. -% -%\item[\setting{DTLplot}{xticlabels}] The value must be a comma -%separated list of labels for each $x$ tick mark. If omitted, -%the labels are the value of the $x$ tick position, rounded -%\meta{n} digits after the decimal point, where \meta{n} is -%given by the value of the counter \ctr{DTLplotroundXvar}. -% -%\item[\setting{DTLplot}{yticlabels}] The value must be a comma -%separated list of labels for each $y$ tick mark. If omitted, -%the labels are the value of the $y$ tick position, rounded -%\meta{n} digits after the decimal point, where \meta{n} is -%given by the value of the counter \ctr{DTLplotroundYvar}. -% -%\item[\setting{DTLplot}{xlabel}] The value is the label for -%the $x$ axis. If omitted, the axis has no label. -% -%\item[\setting{DTLplot}{ylabel}] The value is the label for -%the $y$ axis. If omitted, the axis has no label. -% -%\item[\setting{DTLplot}{legend}] This setting governs whether -%or not to display the legend, and where it should be displayed. -%It may take one of the following values "none" (don't display -%the legend), "north", "northeast", "east", "southeast", "south", -%"southwest", "west" or "northwest". If the value is omitted, -%"northeast" is assumed. -% -%\item[\setting{DTLplot}{legendlabels}] The value must be a comma -%separated list of labels for the legend. If omitted, the database -%names are used. -% -%\end{description} -% -%\begin{example}{A Basic Graph}{ex:basicplot} -%Suppose you have a file called "groupa.csv" that contains the -%following: -%\DTLnewdb{groupa}\relax -%\DTLnewrow{groupa}\relax -%\DTLnewdbentry{groupa}{Height}{1.55}\relax -%\DTLnewdbentry{groupa}{Weight}{45.4}\relax -%\DTLnewrow{groupa}\relax -%\DTLnewdbentry{groupa}{Height}{1.54}\relax -%\DTLnewdbentry{groupa}{Weight}{48.0}\relax -%\DTLnewrow{groupa}\relax -%\DTLnewdbentry{groupa}{Height}{1.56}\relax -%\DTLnewdbentry{groupa}{Weight}{58.0}\relax -%\DTLnewrow{groupa}\relax -%\DTLnewdbentry{groupa}{Height}{1.56}\relax -%\DTLnewdbentry{groupa}{Weight}{50.2}\relax -%\DTLnewrow{groupa}\relax -%\DTLnewdbentry{groupa}{Height}{1.57}\relax -%\DTLnewdbentry{groupa}{Weight}{46.0}\relax -%\DTLnewrow{groupa}\relax -%\DTLnewdbentry{groupa}{Height}{1.58}\relax -%\DTLnewdbentry{groupa}{Weight}{48.3}\relax -%\DTLnewrow{groupa}\relax -%\DTLnewdbentry{groupa}{Height}{1.59}\relax -%\DTLnewdbentry{groupa}{Weight}{56.5}\relax -%\DTLnewrow{groupa}\relax -%\DTLnewdbentry{groupa}{Height}{1.59}\relax -%\DTLnewdbentry{groupa}{Weight}{58.1}\relax -%\DTLnewrow{groupa}\relax -%\DTLnewdbentry{groupa}{Height}{1.60}\relax -%\DTLnewdbentry{groupa}{Weight}{60.9}\relax -%\DTLnewrow{groupa}\relax -%\DTLnewdbentry{groupa}{Height}{1.62}\relax -%\DTLnewdbentry{groupa}{Weight}{56.3}\relax -%\begin{ttfamily}\obeylines\setlength{\parindent}{0pt} -%Height,Weight -%\DTLforeach{groupa}{\x=Height,\y=Weight}{\x,\y -%}\end{ttfamily}\par\noindent -%First load this into a database called "groupa": -%\begin{verbatim} -%\DTLloaddb{groupa}{groupa.csv} -%\end{verbatim} -%The data can now be converted into a scatter plot as follows: -%\begin{verbatim} -%\begin{figure}[htbp] -%\centering -%\DTLplot{groupa}{x=Height,y=Weight} -%\caption{A scatter plot} -%\end{figure} -%\end{verbatim} -%This produces \autoref{fig:basicplot}. -% -%\begin{figure}[htbp] -%\centering -%\DTLplot{groupa}{x=Height,y=Weight} -%\caption{A scatter plot} -%\label{fig:basicplot} -%\end{figure} -% -%Alternatively, you can use the \setting{DTLplot}{style} setting -%to change it into a line plot: -%\begin{verbatim} -%\begin{figure}[htbp] -%\centering -%\DTLplot{groupa}{x=Height,y=Weight,style=lines} -%\caption{A line plot} -%\end{figure} -%\end{verbatim} -%This produces \autoref{fig:basiclineplot}. -% -%\begin{figure}[htbp] -%\centering -%\DTLplot{groupa}{x=Height,y=Weight,style=lines} -%\caption{A line plot} -%\label{fig:basiclineplot} -%\end{figure} -%\end{example} -% -%\begin{example}{Plotting Multiple Data Sets}{ex:2db} -%In this example, I shall use the database called "groupa" defined -%in \autoref{ex:basicplot}, and another database called "groupb" -%which is loaded from the file "groupb.csv" which contains the -%following: -%\DTLnewdb{groupb} -%\DTLnewrow{groupb}\relax -%\DTLnewdbentry{groupb}{Height}{1.54}\relax -%\DTLnewdbentry{groupb}{Weight}{48.4}\relax -%\DTLnewrow{groupb}\relax -%\DTLnewdbentry{groupb}{Height}{1.54}\relax -%\DTLnewdbentry{groupb}{Weight}{42.0}\relax -%\DTLnewrow{groupb}\relax -%\DTLnewdbentry{groupb}{Height}{1.55}\relax -%\DTLnewdbentry{groupb}{Weight}{64.0}\relax -%\DTLnewrow{groupb}\relax -%\DTLnewdbentry{groupb}{Height}{1.56}\relax -%\DTLnewdbentry{groupb}{Weight}{58.2}\relax -%\DTLnewrow{groupb}\relax -%\DTLnewdbentry{groupb}{Height}{1.56}\relax -%\DTLnewdbentry{groupb}{Weight}{49.0}\relax -%\DTLnewrow{groupb}\relax -%\DTLnewdbentry{groupb}{Height}{1.57}\relax -%\DTLnewdbentry{groupb}{Weight}{40.3}\relax -%\DTLnewrow{groupb}\relax -%\DTLnewdbentry{groupb}{Height}{1.58}\relax -%\DTLnewdbentry{groupb}{Weight}{51.5}\relax -%\DTLnewrow{groupb}\relax -%\DTLnewdbentry{groupb}{Height}{1.58}\relax -%\DTLnewdbentry{groupb}{Weight}{63.1}\relax -%\DTLnewrow{groupb}\relax -%\DTLnewdbentry{groupb}{Height}{1.59}\relax -%\DTLnewdbentry{groupb}{Weight}{74.9}\relax -%\DTLnewrow{groupb}\relax -%\DTLnewdbentry{groupb}{Height}{1.59}\relax -%\DTLnewdbentry{groupb}{Weight}{59.3}\relax -%\begin{ttfamily}\obeylines\setlength{\parindent}{0pt} -%Height,Weight -%\DTLforeach{groupb}{\x=Height,\y=Weight}{\x,\y -%}\end{ttfamily}\par\noindent -%First load this into a database called "groupb": -%\begin{verbatim} -%\DTLloaddb{groupb}{groupb.csv} -%\end{verbatim} -%I can now plot both groups in the same graph, but I want a smaller -%graph than \autoref{fig:basicplot} and \autoref{fig:basiclineplot}, -%so I am going to set the plot width and height to 3in: -%\begin{verbatim} -%\begin{figure}[htbp] -%\centering -%\DTLplot{groupa,groupb}{x=Height,y=Weight,width=3in,height=3in} -%\caption{A scatter plot} -%\end{figure} -%\end{verbatim} -%This produces \autoref{fig:2db}. -% -%\begin{figure}[htbp] -%\centering -%\DTLplot{groupa,groupb}{x=Height,y=Weight,width=3in,height=3in} -%\caption[A scatter plot (multiple datasets)]{A scatter plot} -%\label{fig:2db} -%\end{figure} -% -%Now let's add a legend using the \setting{DTLplot}{legend} setting, -%with the legend labels "Group A" and "Group B", -%and set the $x$ tick intervals using \setting{DTLplot}{xticpoints} -%setting. I am also going to set the $x$ axis label to -%"Height (m)" and the $y$ axis label to "Weight (kg)", and place -%a box around the plot. -%\begin{verbatim} -%\begin{figure}[htbp] -%\centering -%\DTLplot{groupa,groupb}{x=Height,y=Weight, -%width=3in,height=3in,legend,legendlabels={Group A,Group B}, -%xlabel={Height (m)},ylabel={Weight (kg)},box, -%xticpoints={1.54,1.55,1.56,1.57,1.58,1.59,1.60,1.61,1.62}} -%\caption{A scatter plot} -%\end{figure} -%\end{verbatim} -%This produces \autoref{fig:legend}. -% -%\begin{figure}[htbp] -%\centering -%\DTLplot{groupa,groupb}{x=Height,y=Weight,legend, -%width=3in,height=3in,legendlabels={Group A,Group B}, -%xlabel={Height (m)},ylabel={Weight (kg)},box, -%xticpoints={1.54,1.55,1.56,1.57,1.58,1.59,1.60,1.61,1.62}} -%\caption[A scatter plot (with a legend)]{A scatter plot} -%\label{fig:legend} -%\end{figure} -%\end{example} -% -%\subsection{Adding Information to the Plot} -% -%The \sty{datatool} package provides two hooks used at the beginning -%and end of the \env{tikzpicture} environment: -%\begin{definition}[\DescribeMacro{\DTLplotatbegintikz}]% -%\cs{DTLplotatbegintikz} -%\end{definition}\noindent -%and -%\begin{definition}[\DescribeMacro{\DTLplotatendtikz}]% -%\cs{DTLplotatendtikz} -%\end{definition} -%They are both defined to do nothing by default, but can be redefined -%to add commands to the image. The unit vectors are set prior to -%using these hooks, so you can use the same co-ordinates as those -%in the data sets. -% -%\begin{definition}[\DescribeMacro{\DTLaddtoplotlegend}]% -%\cs{DTLaddtoplotlegend}\marg{marker}\marg{line style}\marg{text} -%\end{definition} -%This adds a new row to the plot legend where \meta{marker} is -%code to produce the marker, \meta{line style} is code to set -%the line style and \meta{text} is a textual label. You can -%use \cs{relax} to suppress the marker or line. For example: -%\begin{verbatim} -%\DTLaddtoplotlegend{\pgfuseplotmark{x}}{\relax}{Some Data} -%\end{verbatim} -%Note that the legend is plotted before \cs{DTLplotatendtikz}, -%so if you want to add information to the legend you will need -%to do the in \cs{DTLplotatstarttikz}. -% -%\begin{example}{Adding Information to a Plot}{ex:addtoplot} -%Returning to the plots created in \autoref{ex:2db}, suppose -%I now want to annotate the plot, say I want to draw your notice -%to a particular point, say the point (1.58,48.3), then I can -%redefine \cs{DTLplotatendtikz} to draw an annotated arrow to -%that point: -%\begin{verbatim} -%\renewcommand*{\DTLplotatendtikz}{% -%\draw[<-,line width=1pt] (1.58,48.3) -- (1.6,43) -% node[below]{interesting point}; -%} -%\end{verbatim} -%So \autoref{fig:legend} now looks like \autoref{fig:annote}. -%(Obviously, \cs{DTLplotatendtikz} needs to be redefined before -%using \cs{DTLplot}.) -% -%\begin{figure}[htbp] -%\renewcommand*{\DTLplotatendtikz}{% -%\draw[<-,line width=1pt] (1.58,48.3) -- (1.6,43) -% node[below]{interesting point}; -%} -%\centering -%\DTLplot{groupa,groupb}{x=Height,y=Weight,legend, -%width=3in,height=3in,legendlabels={Group A,Group B},box, -%xlabel={Height (m)},ylabel={Weight (kg)}, -%xticpoints={1.54,1.55,1.56,1.57,1.58,1.59,1.60,1.61,1.62}} -%\caption[A scatter plot (using the end plot hook to annotate the -%plot)]{A scatter plot} -% -%\label{fig:annote} -%\end{figure} -%\end{example} -% -%\subsection{Global Plot Settings} -% -%\subsubsection{Lengths} -%This section describes the lengths that govern the appearance of -%the plot created using \ics{DTLplot}. These lengths can be -%changed using \cs{setlength}. -% -%\begin{definition}[\DescribeMacro{\DTLplotwidth}]% -%\cs{DTLplotwidth} -%\end{definition} -%This length governs the length of the $x$ axis. Note that the plot -%width does not include any outer tick marks or labels. The default -%value is 4in. -% -%\begin{definition}[\DescribeMacro{\DTLplotheight}]% -%\cs{DTLplotheight} -%\end{definition} -%This length governs the length of the $y$ axis. Note that the plot -%height does not include any outer tick marks or labels. The default -%value is 4in -% -%\begin{definition}[\DescribeMacro{\DTLticklength}]% -%\cs{DTLticklength} -%\end{definition} -%This governs the length of the tick marks. The default value is -%5pt. -% -%\begin{definition}[\DescribeMacro{\DTLminorticklength}]% -%\cs{DTLminorticklength} -%\end{definition} -%This governs the length of the minor tick marks. The default value is -%2pt. -% -%\begin{definition}[\DescribeMacro{\DTLticklabeloffset}]% -%\cs{DTLticklabeloffset} -%\end{definition} -%This governs the distance from the axis to the tick labels. The -%default value is 8pt. -% -%\begin{definition}[\DescribeMacro{\DTLmintickgap}]% -%\cs{DTLmintickgap} -%\end{definition} -%This is the minimum distance allowed between tick marks. If the -%plot width or height is less than this distance there will only -%be tick marks at either end of the axis. The default value is -%20pt. -% -%\begin{definition}[\DescribeMacro{\DTLlegendxoffset}]% -%\cs{DTLlegendxoffset} -%\end{definition} -%This is the horizontal distance from the border of the plot to the -%outer border of the legend. The default value is 10pt. -% -%\begin{definition}[\DescribeMacro{\DTLlegendyoffset}]% -%\cs{DTLlegendyoffset} -%\end{definition} -%This is the vertical distance from the border of the plot to the -%outer border of the legend. The default value is 10pt. -% -%\subsubsection{Counters} -%These counters govern the appearance of plots -%created using \ics{DTLplot}. The value of the counters can be -%changed using \cs{setcounter}. -% -%\begin{definition}[\DescribeCounter{DTLplotroundXvar}] -%\ctrfmt{DTLplotroundXvar} -%\end{definition} -%Unless you specify your own tick labels, the $x$ tick labels will -%be given by the tick points rounded to \meta{n} digits after the -%decimal point, where \meta{n} is the value of the counter -%\ctrfmt{DTLplotroundXvar}. -% -%\begin{definition}[\DescribeCounter{DTLplotroundYvar}] -%\ctrfmt{DTLplotroundYvar} -%\end{definition} -%Unless you specify your own tick labels, the $y$ tick labels will -%be given by the tick points rounded to \meta{n} digits after the -%decimal point, where \meta{n} is the value of the counter -%\ctrfmt{DTLplotroundYvar}. -% -%\subsubsection{Macros} -%These macros govern the appearance of plots created using -%\ics{DTLplot}. They can be changed using \cs{renewcommand}. -% -%\begin{definition}[\DescribeMacro{\DTLplotmarks}]% -%\cs{DTLplotmarks} -%\end{definition} -%This must be a comma separated list of \sty{pgf} code to create the -%plot marks. \ics{DTLplot} cycles through this list for each -%database listed. The \sty{pgf} package provides convenient commands -%for generating plots using \cs{pgfuseplotmark}. See the \sty{pgf} -%manual for more details. -% -%\begin{definition}[\DescribeMacro{\DTLplotmarkcolors}]% -%\cs{DTLplotmarkcolors} -%\end{definition} -%This must be a comma separated list of defined colours to apply to the -%plot marks. \ics{DTLplot} cycles through this list for each database -%listed. If this macro is set to empty, the current colour will -%be used instead. -% -%\begin{definition}[\DescribeMacro{\DTLplotlines}]% -%\cs{DTLplotlines} -%\end{definition} -%This must be a comma separated list of \sty{pgf} code to set the -%style of the plot lines. \ics{DTLplot} cycles through this list for -%each database listed. Dash patterns can be set using \cs{pgfsetdash}, -%see the \sty{pgf} manual for more details. If \cs{DTLplotlines} is -%set to empty the current line style will be used instead. -% -%\begin{definition}[\DescribeMacro{\DTLplotlinecolors}]% -%\cs{DTLplotlinecolors} -%\end{definition} -%This must be a comma separated list of defined colours to apply to the -%plot lines. \cs{DTLplot} cycles through this list for each database -%listed. If this macro is set to empty, the current colour will -%be used instead. The default is the same as \cs{DTLplotmarkcolors}. -% -%\begin{definition}[\DescribeMacro{\DTLXAxisStyle}]% -%\cs{DTLXAxisStyle} -%\end{definition} -%This governs the style of the $x$ axis. It is passed as the optional -%argument to the TikZ \cs{draw} command. By default it is just "-" -%which is a solid line style with no start or end arrows. The $x$ -%axis line starts from the bottom left corner of the plot and extends -%to the bottom right corner of the plot. So if you want the $x$ axis -%to have an arrow head at the right end, you can do: -%\begin{verbatim} -%\renewcommand*{\DTLXAxisStyle}{->} -%\end{verbatim} -% -%\begin{definition}[\DescribeMacro{\DTLYAxisStyle}]% -%\cs{DTLYAxisStyle} -%\end{definition} -%This governs the style of the $y$ axis. It is analogous to -%\cs{DTLXAxisStyle} described above. -% -%\begin{definition}[\DescribeMacro{\DTLmajorgridstyle}]% -%\cs{DTLmajorgridstyle} -%\end{definition} -%This specifies the format of the major grid lines. -%It may be set to any TikZ setting that you can pass to the -%optional argument of \cs{draw}. The default value is -%"color=gray,-" which indicates a grey solid line. -% -%\begin{definition}[\DescribeMacro{\DTLminorgridstyle}]% -%\cs{DTLminorgridstyle} -%\end{definition} -%This specifies the format of the minor grid lines. -%It may be set to any TikZ setting that you can pass to the -%optional argument of \cs{draw}. The default value is -%"color=gray,loosely dotted" which indicates a grey dotted line. -% -%\begin{definition}[\DescribeMacro{\DTLformatlegend}]% -%\cs{DTLformatlegend}\marg{legend} -%\end{definition} -%This formats the entire legend, which is passed as the argument. -%The default is to set the legend with -%a white background, a black frame. -% -%\subsection{Adding to a Plot Stream} -% -%\begin{definition}[\DescribeMacro{\DTLplotstream}]% -%\cs{DTLplotstream}\oarg{condition}\marg{db name}\marg{x key}\marg{y key} -%\end{definition} -%This adds points to a stream from the database called \meta{db name} -%where the $x$ co-ordinates are given by the key \meta{x key} -%and the $y$ co-ordinates are given by the key \meta{y key}. -%(\ics{DTLconverttodecimal} is used to convert locale dependent -%values to a standard decimal that is recognised by the -%\sty{pgf} package.) -%The optional argument \meta{condition} is the same as that -%for \ics{DTLforeach}. -% -%\begin{example}{Adding to a Plot Stream}{ex:plotstream} -%Suppose you have a CSV file called "data.csv" containing the -%following: -%\begin{verbatim} -%x,y -%0,0 -%1,1 -%2,0.5 -%1.5,0.3 -%\end{verbatim} -%\DTLnewdb{data}\relax -%\DTLnewrow{data}\relax -%\DTLnewdbentry{data}{x}{0}\relax -%\DTLnewdbentry{data}{y}{0}\relax -%\DTLnewrow{data}\relax -%\DTLnewdbentry{data}{x}{1}\relax -%\DTLnewdbentry{data}{y}{1}\relax -%\DTLnewrow{data}\relax -%\DTLnewdbentry{data}{x}{2}\relax -%\DTLnewdbentry{data}{y}{0.5}\relax -%\DTLnewrow{data}\relax -%\DTLnewdbentry{data}{x}{1.5}\relax -%\DTLnewdbentry{data}{y}{0.3}\relax -%First load the file into a database called "data": -%\begin{verbatim} -%\DTLloaddb{data}{data.csv} -%\end{verbatim} -%Now create a figure containing this data: -%\begin{verbatim} -%\begin{figure}[tbhp] -%\centering -%\begin{tikzpicture} -%\pgfplothandlermark{\pgfuseplotmark{o}} -%\pgfplotstreamstart -%\DTLplotstream{data}{x}{y}% -%\pgfplotstreamend -%\pgfusepath{stroke} -%\end{tikzpicture} -%\caption{Adding to a plot stream} -%\end{figure} -%\end{verbatim} -%This produces \autoref{fig:plotstream}. -% -%\begin{figure}[tbhp] -%\centering -%\begin{tikzpicture} -%\pgfplothandlermark{\pgfuseplotmark{o}} -%\pgfplotstreamstart -%\DTLplotstream{data}{x}{y}% -%\pgfplotstreamend -%\pgfusepath{stroke} -%\end{tikzpicture} -%\caption{Adding to a plot stream} -%\label{fig:plotstream} -%\end{figure} -%\end{example} -% -%\begin{example}{Plotting Multiple Keys in the Same -%Database}{ex:multikey} -%Suppose I have conducted two time to growth experiments. For each -%experiment, I have recorded the log count at set times, and I have -%recorded this information in the same data file called, say, -%"growth.csv" which contains the following: -%\begin{verbatim} -%Time,Experiment 1,Experiment 2 -%0,3.73,3.6 -%23,3.67,3.7 -%60,4.9,3.8 -%\end{verbatim} -%\DTLnewdb{growth}\DTLnewrow{growth}\relax -%\DTLnewdbentry{growth}{Time}{0}\relax -%\DTLnewdbentry{growth}{Experiment 1}{3.73}\relax -%\DTLnewdbentry{growth}{Experiment 2}{3.6}\relax -%\DTLnewrow{growth}\relax -%\DTLnewdbentry{growth}{Time}{23}\relax -%\DTLnewdbentry{growth}{Experiment 1}{3.67}\relax -%\DTLnewdbentry{growth}{Experiment 2}{3.7}\relax -%\DTLnewrow{growth}\relax -%\DTLnewdbentry{growth}{Time}{60}\relax -%\DTLnewdbentry{growth}{Experiment 1}{4.9}\relax -%\DTLnewdbentry{growth}{Experiment 2}{3.8}\relax -%I can load the data into a database using: -%\begin{verbatim} -%\DTLloaddb{growth}{growth.csv} -%\end{verbatim} -%However, I'd like to plot both results on the same graph. Since they -%are contained in the same database, I can't use the method I used -%in \autoref{ex:2db}. Instead I can use a combination of -%\ics{DTLplot} and \ics{DTLplotstream}: -%\begin{verbatim} -%\begin{figure}[tbhp] -%\centering -% % computer bounds -%\DTLminforkeys{growth}{Time}{\minX} -%\DTLminforkeys{growth}{Experiment 1,Experiment 2}{\minY} -%\DTLmaxforkeys{growth}{Time}{\maxX} -%\DTLmaxforkeys{growth}{Experiment 1,Experiment 2}{\maxY} -% % round x tick labels -%\setcounter{DTLplotroundXvar}{0} -% % redefine \DTLplotatbegintikz to plot the data for Experiment 1 -%\renewcommand*{\DTLplotatbegintikz}{% -% % set plot mark -%\pgfplothandlermark{\color{green}\pgfuseplotmark{x}} -% % start plot stream -%\pgfplotstreamstart -% % add data from Experiment 1 to plot stream -%\DTLplotstream{growth}{Time}{Experiment 1}% -% % end plot stream -%\pgfplotstreamend -% % stroke path -%\pgfusepath{stroke} -% % add information to legend (no line is require so use \relax) -%\DTLaddtoplotlegend{\color{green}% -%\pgfuseplotmark{x}}{\relax}{Experiment 1} -%} -% % now plot the data for Experiment 2 -%\DTLplot{growth}{x=Time,y=Experiment 2,legend, -%width=3in,height=3in,bounds={\minX,\minY,\maxX,\maxY}, -%xlabel={Time},ylabel={Log Count}, -%legendlabels={Experiment 2}} -%\caption{Time to growth data} -%\end{figure} -%\end{verbatim} -%This produces \autoref{fig:multikey}. -%Notes: -%\begin{itemize} -%\item I redefined \ics{DTLplotatbegintikz} in order to add -%the new plot to the legend, since \ics{DTLplotatendtikz} is -%used after the legend is plotted. The $x$ and $y$ unit vectors -%are set before \ics{DTLplotatbegintikz} so I don't need to -%worry about the co-ordinates. -%\item I set the counter \ctr{DTLplotroundXvar} to zero -%otherwise the $x$ axis would have looked too cluttered. -%\item I have used \ics{DTLminforkeys} and \ics{DTLmaxforkeys} to -%determine the bounds since \ics{DTLplot} won't take the data -%for Experiment 1 into account when computing the bounds. -%\end{itemize} -% -%\begin{figure}[htbp] -%\DTLminforkeys{growth}{Time}{\minX} -%\DTLminforkeys{growth}{Experiment 1,Experiment 2}{\minY} -%\DTLmaxforkeys{growth}{Time}{\maxX} -%\DTLmaxforkeys{growth}{Experiment 1,Experiment 2}{\maxY} -%\setcounter{DTLplotroundXvar}{0} -%\renewcommand*{\DTLplotatbegintikz}{% -%\pgfplothandlermark{\color{green}\pgfuseplotmark{x}} -%\pgfplotstreamstart -%\DTLplotstream{growth}{Time}{Experiment 1}% -%\pgfplotstreamend -%\pgfusepath{stroke} -%\DTLaddtoplotlegend{\color{green}\pgfuseplotmark{x}}{\relax}{Experiment 1} -%} -%\centering -%\DTLplot{growth}{x=Time,y=Experiment 2,legend, -%width=3in,height=3in,bounds={\minX,\minY,\maxX,\maxY}, -%xlabel={Time},ylabel={Log Count}, -%legendlabels={Experiment 2}} -%\caption[Time to growth data (plotting from the same database using -%different keys)]{Time to growth data} -%\label{fig:multikey} -%\end{figure} -%\end{example} -% -%\section{Bar Charts (\texorpdfstring{\sty{databar}}{databar} -%package)} -% -%The \sty{databar} package provides commands for creating bar charts. -%It is not loaded by the \sty{datatool} package, so if you want to -%use it you will need to load it explicitly using -%"\usepackage{databar}". You must also have the \sty{pgf} package -%installed. -% -%Bar charts can either be vertical or horizontal, the default is -%vertical. In this section the $x$ axis refers to the horizontal -%axis when plotting a vertical bar chart and to the vertical axis -%when plotting a horizontal bar chart. The $x$ axis units are in -%increments of one bar. The $y$ axis refers to the vertical axis -%when plotting a vertical bar chart and to the horizontal axis when -%plotting a horizontal bar chart. The $y$ axis uses the same -%co-ordinates as the data. The bars may have an upper and lower -%label. In a vertical bar chart, the lower label is placed below -%the $x$ axis and the upper label is placed above the top of the bar. -%In a horizontal bar chart, the lower label is placed to the left of -%the $x$ axis and the upper label is placed to the right of the -%end of the bar. (This is actually a misnomer as it is possible -%for the ``upper'' label to be below the ``lower'' label if a -%bar has a negative value, however the bars are considered to -%be anchored on the $x$ axis, and the other end of the bar is -%considered to be the ``upper'' end, regardless of its -%direction.) -% -%The \sty{databar} package options are as follows: -%\begin{description} -%\item[{\pkgopt[databar]{color}}] Created coloured bar charts -%(default). -% -%\item[{\pkgopt[databar]{gray}}] Created grey scale bar charts. -% -%\item[{\pkgopt[databar]{vertical}}] Created vertical bar charts -%(default). -% -%\item[{\pkgopt[databar]{horizontal}}] Created horizontal bar charts. -%\end{description} -% -% -% -%\begin{definition}[\DescribeMacro{\DTLbarchart}]% -%\cs{DTLbarchart}\oarg{condition}\marg{db name}\marg{settings}\marg{values} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLmultibarchart}]% -%\cs{DTLmultibarchart}\oarg{condition}\marg{db name}\marg{settings}\marg{values} -%\end{definition} -%These commands both create a bar chart from the information in -%the database \meta{db name}, where \meta{condition} is the same -%as the optional argument for \ics{DTLforeach} described in -%\autoref{sec:dbforeach}, and \meta{values} is the same as the -%penultimate argument of \ics{DTLforeach}. The \meta{settings} -%argument is a \meta{setting}"="\meta{value} list of settings. The -%first command, \cs{DLTbarchart}, will draw a bar chart for a -%given column of data in the database, whereas the second command, -%\cs{DTLmultibarchart}, will draw a bar chart that is divided into -%groups of bars where each bar within a group represents data from -%several columns of a given row in the database. -% -%The \setting{DTLbarchart}{variable} setting is -%required for \cs{DTLbarchart} and the -%\setting{DTLmultibarchart}{variables}, the other settings are -%optional (though some may only be used for one of -%\cs{DTLbarchart} and \cs{DLTmultibarchart}), and are as follows: -% -%\begin{description} -%\item[\setting{DTLbarchart}{variable}] -%This specifies the control sequence to use that -%contains the value used to construct the bar chart. The control -%sequence must be one of the control sequences to appear in -%the assignment list \meta{values}. This setting is required -%for \cs{DTLbarchart}, and is unavailable for \cs{DTLmultibarchart}. -% -%\item[\setting{DTLmultibarchart}{variables}] -%This specifies a list of control sequences to use which -%contain the values used to construct the bar chart. Each control -%sequence must be one of the control sequences to appear in -%the assignment list \meta{values}. This setting is required -%for \cs{DTLmultibarchart}, and is unavailable for -%\cs{DTLbarchart}. -% -%\item[\setting{DTLbarchart,DTLmultibarchart}{max}] -%This specifies the maximum value on the $y$ axis. (This should -%be a standard decimal value.) -% -%\item[\setting{DTLbarchart,DTLmultibarchart}{length}] -%This specifies the overall length of the $y$ axis, and must -%be a dimension. -% -%\item[\setting{DTLbarchart,DTLmultibarchart}{maxdepth}] -%This must be a zero or negative number. It specifies the maximum -%depth of the $y$ axis. (This should be a standard decimal value.) -% -%\item[\setting{DTLbarchart,DTLmultibarchart}{axes}] -%This setting specifies which axes to display. This may take one -%of the following values: "both", "x", "y" or "none". -% -%\item[\setting{DTLbarchart,DTLmultibarchart}{barlabel}] -%This setting specifies the lower bar label. When used with -%\cs{DTLmultibarchart} it indicates the group label. -% -%\item[\setting{DTLmultibarchart}{multibarlabels}] -%This setting should contain a comma separated list of labels -%for each bar within a group for \cs{DTLmultibarchart}. This -%setting is not available for \cs{DTLbarchart}. -% -%\item[\setting{DTLbarchart}{upperbarlabel}] -%This setting specifies the upper bar label. This setting -%is not available for \cs{DTLmultibarchart}. -% -%\item[\setting{DTLmultibarchart}{uppermultibarlabels}] -%This setting must be a comma separated list of upper bar -%labels for each bar within a group. This setting is not -%available for \cs{DTLbarchart}. -% -%\item[\setting{DTLbarchart,DTLmultibarchart}{yticpoints}] -%This must be a comma separated list of tick locations for the -%$y$ axis. (These should be standard decimal values.) -%This setting overrides \setting{DTLbarchart}{yticgap}. -% -%\item[\setting{DTLbarchart,DTLmultibarchart}{yticgap}] -%This specifies the gap between the $y$ tick marks. (This should -%be a standard decimal value.) -% -%\item[\setting{DTLbarchart,DTLmultibarchart}{yticlabels}] -%This must be a comma separated list of tick labels for the -%$y$ axis. -% -%\item[\setting{DTLbarchart,DTLmultibarchart}{ylabel}] -%This specifies the label for the $y$ axis. -% -%\item[\setting{DTLmultibarchart}{groupgap}] This specifies -%the gap between groups when using \cs{DTLmultibarchart}. -%This value is given as a multiple of the bar width. The -%default value is 1, which indicates a gap of one bar width. -%This setting is not available for \cs{DTLbarchart}. -% -%\item[\setting{DTLbarchart,DTLmultibarchart}{verticalbars}] -%This is a boolean setting, so it can only take the values -%"true" (do a vertical bar chart) or "false" (do a horizontal -%bar chart). If the value is omitted, "true" is assumed. -%\end{description} -% -%\begin{example}{A Basic Bar Chart}{ex:barchart} -%Recall \autoref{ex:piechart} defined a database called "fruit". -%This example will be using that database to plot a bar chart. -%The following plots a basic vertical bar chart: -%\begin{verbatim} -%\begin{figure}[htbp] -%\centering -%\DTLbarchart{variable=\theQuantity}{fruit}{\theQuantity=Quantity} -%\caption{A basic bar chart} -%\end{figure} -%\end{verbatim} -%This produces \autoref{fig:barchart}. -% -%\begin{figure}[htbp] -%\centering -%\DTLbarchart{variable=\theQuantity}{fruit}{\theQuantity=Quantity} -%\caption{A basic bar chart} -%\label{fig:barchart} -%\end{figure} -%\end{example} -% -%\subsection{Changing the Appearance of a Bar Chart} -% -% -%\begin{definition}[\DescribeMacro{\DTLbarchartlength}]% -%\cs{DTLbarchartlength} -%\end{definition} -%This specifies the total length of the $y$ axis. You must use -%\cs{setlength} to change this value. The default value is 3in. -% -%\begin{definition}[\DescribeMacro{\DTLbarwidth}]% -%\cs{DTLbarwidth} -%\end{definition} -%This specifies the width of each bar. You must use \cs{setlength} -%to change this value. The default value is 1cm. -% -%\begin{definition}[\DescribeMacro{\DTLbarlabeloffset}]% -%\cs{DTLbarlabeloffset} -%\end{definition} -%This specifies the distance from the $x$ axis to the lower bar label. -%You must use \cs{setlength} to change this value. The default value -%is 10pt. -% -%\begin{definition}[\DescribeCounter{DTLbarroundvar}] -%\ctrfmt{DTLbarroundvar} -%\end{definition} -%The $y$ tick labels are rounded to \meta{n} digits after the -%decimal point, where \meta{n} is given by the value of the -%counter \ctrfmt{DTLbarroundvar}. You must use \cs{setcounter} -%to change this value. -% -%\begin{definition}[\DescribeMacro{\DTLsetbarcolor}]% -%\cs{DTLsetbarcolor}\marg{n}\marg{color} -%\end{definition} -%This sets the \meta{n}th bar colour to \meta{color}. -%Only the first eight bars have a colour defined by default. If you -%need more than eight bars, you will need to define more bar colours. -%It is recommended that you set the colour of each bar to -%correspond with whatever the bar represents. -% -%\begin{definition}[\DescribeMacro{\DTLdobarcolor}]% -%\cs{DTLdobarcolor}\marg{n} -%\end{definition} -%This sets the current colour to the colour of the \meta{n}th bar. -% -%\begin{definition}[\DescribeMacro{\DTLbaroutlinecolor}]% -%\cs{DTLbaroutlinecolor} -%\end{definition} -%This macro contains the colour of the bar outlines. This defaults -%to "black". -% -%\begin{definition}[\DescribeMacro{\DTLbaroutlinewidth}]% -%\cs{DTLbaroutlinewidth} -%\end{definition} -%This length specifies the line width for the bar outlines. If it -%is 0pt, the outline is not drawn. The default value is 0pt. -% -% -%\begin{definition}[\DescribeMacro{\DTLbaratbegintikz}]% -%\cs{DTLbaratbegintikz} -%\end{definition} -%This specifies any additional commands to add to the start of -%the plot. It defaults to nothing, and is called after the -%unit vectors are set. -% -%\begin{definition}[\DescribeMacro{\DTLbaratendtikz}]% -%\cs{DTLbaratendtikz} -%\end{definition} -%This specifies any additional commands to add to the end of -%the plot. It defaults to nothing. -% -%\begin{definition}[\DescribeMacro{\DTLeverybarhook}]% -%\cs{DTLeverybarhook} -%\end{definition} -%The specifies code to apply at every bar. Within the definition -%of \cs{DTLeverybarhook} you can use the commands -%\DescribeMacro{\DTLstartpt}\cs{DTLstartpt} (the start -%of the bar), \DescribeMacro{\DTLmidpt}\cs{DTLmidpt} -%(the mid point of the bar) and -%\DescribeMacro{\DTLendpt}\cs{DTLendpt} (the end of the bar). For -%example (using the earlier "fruit" database): -%\begin{verbatim} -%\renewcommand*{\DTLeverybarhook}{% -%\pgftext[at=\DTLmidpt]{\insertName\space(\insertValue)}% -%} -%\DTLbarchart{variable=\insertValue,axes=both, -%ylabel=Quantity,max=50,verticalbars=false -%}% -%{fruit}{\insertValue=Value,\insertName=Name} -%\end{verbatim} -%This puts the name followed by the quantity in brackets in the -%middle of the bar. -% -%\begin{definition}[\DescribeMacro{\ifDTLverticalbars}]% -%\cs{ifDTLverticalbars} -%\end{definition} -%This conditional governs whether the chart uses vertical or -%horizontal bars. -% -%\begin{definition}[\DescribeMacro{\DTLbarXlabelalign}]% -%\cs{DTLbarXlabelalign} -%\end{definition} -%This specifies the text alignment of the lower bar labels. This -%defaults to "left,rotate=-90" if you use the \pkgopt[databar]{vertical} -%package option or the \setting{DTLbarchart}{verticalbars} setting, -%and defaults to "right" if you use the \pkgopt[databar]{horizontal} -%package option or the \setting{DTLbarchart}{verticalbars}"=false" -%setting. -% -%\begin{definition}[\DescribeMacro{\DTLbarYticklabelalign}]% -%\cs{DTLbarYlabelalign} -%\end{definition} -%This specifies the text alignment of the $y$ axis labels. This -%defaults to "right" for vertical bar charts and "center" for -%horizontal bar charts. -% -%\begin{definition}[\DescribeMacro{\DTLbardisplayYticklabel}]% -%\cs{DTLbardisplayYticklabel}\marg{text} -%\end{definition} -%This specifies how to display the $y$ tick label. The argument -%is the tick label. -% -%\begin{definition}[\DescribeMacro{\DTLdisplaylowerbarlabel}]% -%\cs{DTLdisplaylowerbarlabel}\marg{text} -%\end{definition} -%This specifies how to display the lower bar label for -%\cs{DTLbarchart} and the lower bar group label for -%\cs{DTLmultibarchart}. The argument is the label. -% -%\begin{definition}[\DescribeMacro{\DTLdisplaylowermultibarlabel}]% -%\cs{DTLdisplaylowermultibarlabel}\marg{text} -%\end{definition} -%This specifies how to display the lower bar label for -%\cs{DTLmultibarchart}. The argument is the label. This -%command is ignored by \cs{DTLbarchart}. -% -%\begin{definition}[\DescribeMacro{\DTLdisplayupperbarlabel}]% -%\cs{DTLdisplayupperbarlabel}\marg{text} -%\end{definition} -%This specifies how to display the upper bar label for -%\cs{DTLbarchart} and the upper bar group label for -%\cs{DTLmultibarchart}. The argument is the label. -% -%\begin{definition}[\DescribeMacro{\DTLdisplayuppermultibarlabel}]% -%\cs{DTLdisplayuppermultibarlabel}\marg{text} -%\end{definition} -%This specifies how to display the upper bar label for -%\cs{DTLmultibarchart}. The argument is the label. This -%command is ignored by \cs{DTLbarchart}. -% -%\begin{example}{A Labelled Bar Chart}{ex:annotebarchart} -%This example extends \autoref{ex:barchart} so that the chart is -%a bit more informative (which is after all the whole point of -%a chart). This chart now has a label below each bar, as well -%as a label above the bar. The lower label uses the value of the -%"Name" key, and the upper label uses the quantity. I have also -%set the outline width so each bar has a border. -%\begin{verbatim} -%\begin{figure}[htbp] -%\setlength{\DTLbaroutlinewidth}{1pt} -%\centering -%\DTLbarchart{variable=\theQuantity,barlabel=\theName,% -%upperbarlabel=\theQuantity}{fruit}{% -%\theQuantity=Quantity,\theName=Name} -%\caption{A bar chart} -%\end{figure} -%\end{verbatim} -%This produces \autoref{fig:annotebarchart}. -% -%\begin{figure}[htbp] -%\centering -%\setlength{\DTLbaroutlinewidth}{1pt} -%\DTLbarchart{variable=\theQuantity,barlabel=\theName, -%upperbarlabel=\theQuantity}{fruit}{\theQuantity=Quantity,\theName=Name} -%\caption[A bar chart (labelled)]{A bar chart} -%\label{fig:annotebarchart} -%\end{figure} -%\end{example} -% -%\begin{example}{Profit/Loss Bar Chart}{ex:profit} -%Suppose I have a file called "profits.csv" that looks like: -%\DTLnewdb{profits} -%\DTLnewrow{profits} -%\DTLnewdbentry{profits}{Year}{2000}\relax -%\DTLnewdbentry{profits}{Profit}{\protect\pounds2,525}\relax -%\DTLnewrow{profits} -%\DTLnewdbentry{profits}{Year}{2001}\relax -%\DTLnewdbentry{profits}{Profit}{\protect\pounds3,752}\relax -%\DTLnewrow{profits} -%\DTLnewdbentry{profits}{Year}{2002}\relax -%\DTLnewdbentry{profits}{Profit}{-\protect\pounds1,520}\relax -%\DTLnewrow{profits} -%\DTLnewdbentry{profits}{Year}{2003}\relax -%\DTLnewdbentry{profits}{Profit}{\protect\pounds1,270}\relax -%\begin{verbatim} -%Year,Profit -%2000,\pounds2,535 -%2001,\pounds3,752 -%2002,-\pounds1,520 -%2003,\pounds1,270 -%\end{verbatim} -%First I can load this file into a database called "profits": -%\begin{verbatim} -%\DTLloaddb{profits}{profits.csv} -%\end{verbatim} -%Now I can plot the data as a bar chart: -%\begin{verbatim} -%\begin{figure}[htbp] -%\centering -% % Set the width of each bar to 10pt -%\setlength{\DTLbarwidth}{10pt} -% % Set the outline width to 1pt -%\setlength{\DTLbaroutlinewidth}{1pt} -% % Round the $y$ tick labels to integers -%\setcounter{DTLbarroundvar}{0} -% % Adjust the tick label offset -%\setlength{\DTLticklabeloffset}{20pt} -% % Change the y tick label alignment -%\renewcommand*{\DTLbarYticklabelalign}{left} -% % Rotate the y tick labels -%\renewcommand*{\DTLbardisplayYticklabel}[1]{\rotatebox{-45}{#1}} -% % Set the bar colours depending on the value of \theProfit -%\DTLforeach{profits}{\theProfit=Profit}{% -%\ifthenelse{\DTLislt{\theProfit}{0}} -%{\DTLsetbarcolor{\DTLcurrentindex}{red}} -%{\DTLsetbarcolor{\DTLcurrentindex}{blue}}} -% % Do the bar chart -%\DTLbarchart{variable=\theProfit,upperbarlabel=\theYear, -%ylabel={Profit/Loss (\pounds)},verticalbars=false, -%maxdepth=-2000,max=4000}{profits} -%{\theProfit=Profit,\theYear=Year} -%\caption{Profits for 2000--2003} -%\end{figure} -%\end{verbatim} -%This produces \autoref{fig:profits}. Notes: -%\begin{enumerate} -%\item This example uses \cs{rotatebox}, so the \sty{graphics} -%or \sty{graphicx} package is required. -%\item The $y$ tick labels are too wide to fit horizontally -%so they have been rotated to avoid overlapping with their -%neighbour. -%\item Rotating the $y$ tick labels puts them too close to -%the $y$ axis, so \ics{DTLticklabeloffset} is made larger to -%compensate. -%\item Remember not to use \cs{year} as an assignment command -%as this command already exists! -%\item Before the bar chart is created I have iterated through -%the database, setting the bar colour to red or blue -%depending on the value of \cs{theProfit}. -%\end{enumerate} -% -%Both \cs{DTLbarchart} and \cs{DTLmultibarchart} set the following -%macros, which may be used in \cs{DTLbaratbegintikz} and -%\cs{DTLbaratendtikz}: -%\begin{definition}[\DescribeMacro{\DTLbarchartwidth}]% -%\cs{DTLbarchartwidth} -%\end{definition} -%This is the overall width of the bar chart. In the case of -%\cs{DTLbarchart} this is just the number of bars. In the case -%of \cs{DTLmultibarchart} it is computed as: -%\begin{displaymath} -%m \times n + (m-1)\times g -%\end{displaymath} -%where $m$ is the number of bar groups (i.e.\ the number of rows -%of data), $n$ is the number of bars within a group (i.e.\ -%the number of commands listed in the -%\setting{DTLmultibarchart}{variables}) setting and $g$ is the -%group gap (as specified by the \setting{DTLmultibarchart}{groupgap} setting). -% -%\begin{definition}[\DescribeMacro{\DTLnegextent}]% -%\cs{DTLnegextent} -%\end{definition} -%This is set to the negative extent of the bar chart. (This value -%may either be zero or negative, and corresponds to the -%\setting{DTLbarchart,DTLmultibarchart}{maxdepth} setting.) -% -%\begin{definition}[\DescribeMacro{\DTLbarmax}]% -%\cs{DTLbarmax} -%\end{definition} -%This is set to the maximum extent of the bar chart. (This value -%corresponds to the -%\setting{DTLbarchart,DTLmultibarchart}{max} setting.) -% -%\begin{figure}[htbp] -%\centering -%\setlength{\DTLbarwidth}{10pt} -%\setlength{\DTLbaroutlinewidth}{1pt} -%\setlength{\DTLticklabeloffset}{20pt} -%\setcounter{DTLbarroundvar}{0} -%\renewcommand*{\DTLbarYticklabelalign}{left} -%\renewcommand*{\DTLbardisplayYticklabel}[1]{\rotatebox{-45}{#1}} -%\DTLforeach{profits}{\theProfit=Profit}{\relax -%\ifthenelse{\DTLislt{\theProfit}{0}} -%{\DTLsetbarcolor{\DTLcurrentindex}{red}} -%{\DTLsetbarcolor{\DTLcurrentindex}{blue}}} -%\DTLbarchart{variable=\theProfit,upperbarlabel=\theYear, -%ylabel={Profit/Loss (\pounds)},verticalbars=false, -%maxdepth=-2000,max=4000 -%}{profits} -%{\theProfit=Profit,\theYear=Year} -%\caption[Profits for 2000--2003 (a horizontal bar chart)]{Profits for -%2000--2003} -%\label{fig:profits} -%\end{figure} -% -%\end{example} -% -%\begin{example}{A Multi-Bar Chart}{ex:multibar} -%This example uses the "marks" database described in -%\autoref{ex:editdb}. -%Recall that this database stores student marks for three -%assignments. The keys for the assignment marks are -%\texttt{Assignment 1}, \texttt{Assignment 2} and -%\texttt{Assignment 3}, respectively. I can convert this -%data into a bar chart using the following: -%\begin{verbatim} -%\begin{figure}[htbp] -%\centering -%\DTLmultibarchart{variables={\assignI,\assignII,\assignIII}, -%barwidth=10pt,uppermultibarlabels={\assignI,\assignII,\assignIII}, -%barlabel={\firstname\ \surname}}{marks}{% -%\surname=Surname,\firstname=FirstName,\assignI=Assignment 1,% -%\assignII=Assignment 2,\assignIII=Assignment 3} -%\caption{Student marks} -%\end{figure} -%\end{verbatim} -%This produces \autoref{fig:multibar}. Notes: -%\begin{enumerate} -%\item I used "variables={\assignI,\assignII,\assignIII}" to -%set the variable to use for each bar within a group. This means -%that there will be three bars in each group. -%\item I have set the bar width to 10pt, otherwise the chart -%will be too wide. -%\item I used "uppermultibarlabels={\assignI,\assignII,\assignIII}" -%to set the upper labels for each bar within a group. This -%will print the assignment mark above the relevant bar. -%\item I used "barlabel={\firstname\ \surname}" to place the -%student's name below the group corresponding to that student. -%\end{enumerate} -% -%\begin{figure}[htbp] -%\centering -%\DTLmultibarchart{variables={\assignI,\assignII,\assignIII}, -%barwidth=10pt,uppermultibarlabels={\assignI,\assignII,\assignIII}, -%barlabel={\firstname\ \surname}}{marks} -%{\surname=Surname,\firstname=FirstName,\assignI=Assignment 1,\assignII=Assignment 2,\assignIII=Assignment 3} -%\caption[Student marks (a multi-bar chart)]{Student -%marks}\label{fig:multibar} -%\end{figure} -% -%Recall that \autoref{ex:editdb} computed the average score over -%for each student, and saved it with the key "Average". This -%information can be added to the bar chart. It might also be -%useful to compute the average over all students and add this -%information to the chart. This is done as follows: -%\begin{verbatim} -% \begin{figure}[htbp] -% \centering -% % compute the overall mean -% \DTLmeanforkeys{marks}{Average}{\overallmean} -% % round it to 2 decimal places -% \DTLround{\overallmean}{\overallmean}{2} -% % draw a grey dotted line indicating the overall mean -% % covering the entire width of the bar chart -% \renewcommand*{\DTLbaratendtikz}{% -% \draw[lightgray,loosely dotted] (0,\overallmean) -- -% (\DTLbarchartwidth,\overallmean) -% node[right,black]{Average (\overallmean)};} -% % Set the lower bar labels to draw a brace across the current -% % group, along with the student's name and average score -% \renewcommand*{\DTLdisplaylowerbarlabel}[1]{% -% \tikz[baseline=(current bounding box.center)]{ -% \draw[snake=brace,rotate=-90](0,0) -- (\DTLbargroupwidth,0);} -% \DTLround{\theMean}{\theMean}{2}% -% \shortstack{#1\\(Average: \theMean)}} -% % draw the bar chart -% \DTLmultibarchart{variables={\assignI,\assignII,\assignIII}, -% barwidth=10pt,uppermultibarlabels={\assignI,\assignII,\assignIII}, -% barlabel={\firstname\ \surname}}{marks} -% {\surname=Surname,\firstname=FirstName,\assignI=Assignment 1,% -% \assignII=Assignment 2,\assignIII=Assignment 3,\theMean=Average} -% \caption{Student marks} -% \end{figure} -%\end{verbatim} -%which produces \autoref{fig:multibarmean}. Notes: -%\begin{enumerate} -%\item I've used the TikZ snake library to create a brace, so -%I need to put -%\begin{verbatim} -%\usetikzlibrary{snakes} -%\end{verbatim} -%in the preamble. See the \sty{pgf} manual for more details on -%how to use this library. -% -%\item I used \ics{DTLbargroupwidth} to indicate the width of -%each bar group. -% -%\item I used \ics{DTLbarchartwidth} to indicate the width of the -%entire bar chart -%\end{enumerate} -% -%\begin{figure}[htbp] -%\centering -%\DTLmeanforkeys{marks}{Average}{\overallmean} -%\DTLround{\overallmean}{\overallmean}{2} -%\renewcommand*{\DTLbaratendtikz}{\draw[lightgray,loosely dotted] (0,\overallmean) -- -%(\DTLbarchartwidth,\overallmean) node[right,black]{Average (\overallmean)};} -%\renewcommand*{\DTLdisplaylowerbarlabel}[1]{\relax -%\tikz[baseline=(current bounding box.center)]{ -%\draw[snake=brace,rotate=-90](0,0) -- (\DTLbargroupwidth,0);} -%\DTLround{\theMean}{\theMean}{2}\relax -%\shortstack{#1\\(Average: \theMean)}} -%\DTLmultibarchart{variables={\assignI,\assignII,\assignIII}, -%barwidth=10pt,uppermultibarlabels={\assignI,\assignII,\assignIII}, -%barlabel={\firstname\ \surname}}{marks} -%{\surname=Surname,\firstname=FirstName,\assignI=Assignment 1,\assignII=Assignment 2,\assignIII=Assignment 3,\theMean=Average} -%\caption[Student marks (annotating a bar chart)]{Student marks} -%\label{fig:multibarmean} -%\end{figure} -%\end{example} -% -%\section{Converting a \texorpdfstring{\BibTeX}{BibTeX} database -%into a \texorpdfstring{\sty{datatool}}{datatool} database -%(\texorpdfstring{\sty{databib}}{databib} package)} -%\label{sec:databib} -% -%The \sty{databib} package provides the means of converting a \BibTeX\ -%database into a \sty{datatool} database. The database can then be -%sorted using \cs{DTLsort}, described in \autoref{sec:sort}. -%For example, you may want to sort the bibliography in -%reverse chronological order. Once you have sorted the bibliography, -%you can display it using \cs{DTLbibliography}, described in -%\autoref{sec:thebib}, or you can iterate through the database -%using \cs{DTLforeachbib}, described in \autoref{sec:foreachbib}. -% -%Note that the \sty{databib} -%package is not automatically loaded by \sty{datatool}, so if -%you want to use it, you must load it using -%"\usepackage{databib}". -% -%\importantpar The purpose of this package is to provide a means for -%authors to format their own bibliography style where there is no -%bibliography style file available that produces the desired results. -%The \cs{DTLsort} macro uses a much less efficient sorting algorithm -%than \BibTeX, and loading the bibliography as a \sty{datatool} -%database is much slower than loading a standard \ext{bbl} file. If -%you have a large database, and you are worried that \LaTeX\ may have -%become stuck, try using the \pkgopt{verbose} option to \sty{datatool} -%or use the command \cs{dtlverbosetrue}. This will print informative -%messages to the console and transcript file, to let you know what's -%going on. -% -%\subsection{\texorpdfstring{\BibTeX}{BibTeX}: An Overview} -%\label{sec:bibtex} -%This document assumes that you have at least some passing -%familiarity with \BibTeX, but here follows a brief refresher. -% -%\BibTeX\ is an external application used in conjunction with \LaTeX. -%When you run \BibTeX, you need to specify the name of the document's -%auxiliary file (without the \ext{aux} extension). \BibTeX\ then reads -%this file and looks for the commands \cs{bibstyle} (which indicates -%which bibliography style (\ext{bst}) file to load), \cs{bibdata} -%(which indicates which bibliography database (\ext{bib}) files to -%load) and \cs{citation} (produced by \cs{cite} and \cs{nocite}, which -%indicates which entries should be included in the bibliography). -%\BibTeX\ then creates a file with the extension \ext{bbl} which -%contains the bibliography, formatted according to the layout defined -%in the bibliography style file. -% -%In general, given a document called, say, \texttt{mydoc.tex}, you -%will have to perform the following steps to ensure that the -%bibliography and all citations are up-to-date: -%\begin{enumerate} -%\item -%\begin{verbatim} -%latex mydoc -%\end{verbatim} -%This writes the citation information to the auxiliary file. -%The bibliography currently doesn't exists, so it isn't displayed. -%Citations will appear in the document as ?? since the internal -%cross-references don't exist yet. -% -%\item -%\begin{verbatim} -%bibtex mydoc -%\end{verbatim} -%This reads the auxiliary file, and creates a file with the extension -%\ext{bbl} which typically contains the typeset bibliography. -% -%\item -%\begin{verbatim} -%latex mydoc -%\end{verbatim} -%Now that the \ext{bbl} file exists, the bibliography can be input -%into the document. The internal cross-referencing information for the -%bibliography can now be written to the auxiliary file. -% -%\item -%\begin{verbatim} -%latex mydoc -%\end{verbatim} -%The cross-referencing information can be read from the auxiliary -%file. -%\end{enumerate} -% -%\subsubsection{\texorpdfstring{\BibTeX}{BibTeX} database} -% -%The bibliographic data required by \BibTeX\ must be stored in -%a file with the extension \ext{bib}, where each entry is stored -%in the form:\par\vskip\baselineskip\noindent -%{\obeylines -%\noindent\texttt{@}\meta{entry\_type}\verb|{|\meta{cite\_key}\texttt, -% \meta{field\_name} \texttt{=} \char`\"\meta{value}\char`\"\texttt, -% \mbox{}\vdots -% \meta{field\_name} \texttt{=} \char`\"\meta{value}\char`\" -%\noindent\verb|}| -%} -%\par\vskip\baselineskip\noindent -%Note that curly braces "{" and "}" may be used instead of \verb|"| -%and \verb|"|. -% -%The entry type, given by \meta{entry\_type} above, indicates -%the type of document. This may be one of: "article", "book", -%"booklet", "inbook", "incollection", "inproceedings"\footnote -%{Note that \texttt{conference} is a synonym for \texttt{inproceedings}.}, -%"manual", -%"mastersthesis", "misc", "phdthesis", "proceedings", \linebreak -%"techreport" or "unpublished". -% -%The \meta{cite\_key} above is a unique label identifying this -%entry, and is the label used in the argument of \cs{cite} or -%\cs{nocite}. The available fields depends on the entry type, for -%example, the field "journal" is required for the "article" entry -%type, but is ignored for the "inproceedings" entry type. The standard -%fields are: "address", "author", "booktitle", "chapter", "edition", -%"editor", "howpublished", "institution", "journal", "key", "month", -%"note", "number", "organization", "pages", "publisher", "school", -%"series", "title", "type", "volume" and "year". -% -%Author and editor names must be entered in one of the following -%ways: -%\begin{enumerate} -%\item \meta{First names} \meta{von part} \meta{Surname}, \meta{Jr part} -% -%The \meta{von part} is optional and is identified by the name(s) -%starting with lowercase letters. The final comma followed by -%\meta{Jr part} is also optional. Examples: -%\begin{verbatim} -%author = "Henry James de Vere" -%\end{verbatim} -%In the above, the first names are Henry James, the ``von part'' is -%de and the surname is Vere. There is no ``junior part''. -%\begin{verbatim} -%author = "Mary-Jane Brown, Jr" -%\end{verbatim} -%In the above, the first name is Mary-Jane, there is no von part, -%the surname is Brown and the junior part is Jr. -%\begin{verbatim} -%author = "Peter {Murphy Allen}" -%\end{verbatim} -%In the above, the first name is Peter, and the surname is Murphy -%Allen. Note that in this case, the surname must be grouped, otherwise -%Murphy would be considered part of the forename. -%\begin{verbatim} -%author = "Maria Eliza {\uppercase{d}e La} Cruz" -%\end{verbatim} -%In the above, the first name is Maria Eliza, the von part is -%De La, and the surname is Cruz. In this case, the von part starts -%with an uppercase letter, but specifying -%\begin{verbatim} -%author = "Maria Eliza De La Cruz" -%\end{verbatim} -%would make \BibTeX\ incorrectly classify ``Maria Eliza De La'' as -%the first names, and the von part would be empty. Since \BibTeX\ -%doesn't understand \LaTeX\ commands, using "{\uppercase{d}e La}" -%will trick \BibTeX\ into thinking that it starts with a lower -%case letter. -% -%\item \meta{von part} \meta{Surname}, \meta{Forenames} -% -%Again the \meta{von part} is optional, and is determined by the -%case of the first letter. For example: -%\begin{verbatim} -%author = "de Vere, Henry James" -%\end{verbatim} -%\end{enumerate} -% -%Multiple authors or editors should be separated by the key word -%"and", for example: -%\begin{verbatim} -%author = "Michel Goossens and Frank Mittlebach and Alexander Samarin" -%\end{verbatim} -% -%Below is an example of a book entry: -%\begin{verbatim} -%@book{latexcomp, -% title = "The \LaTeX\ Companion", -% author = "Michel Goossens and Frank Mittlebach and -% Alexander Samarin", -% publisher = "Addison-Wesley", -% year = 1994 -%} -%\end{verbatim} -%Note that numbers may be entered without delimiters, as in "year = 1994". -%There are also some predefined strings, including those for the month -%names. You should always use these strings instead of the actual -%month name, as the way the month name is displayed depends on the -%bibliography style. For example: -%\begin{verbatim} -%@article{Cawley2007b, -%author = "Gavin C. Cawley and Nicola L. C. Talbot", -%title = "Preventing over-fitting in model selection via {B}ayesian -% regularisation of the hyper-parameters", -%journal = "Journal of Machine Learning Research", -%volume = 8, -%pages = "841--861", -%month = APR, -%year = 2007 -%} -%\end{verbatim} -% -%You can concatenate strings using the "#" character, for example: -%\begin{verbatim} -%month = JUL # "~31~--~" # AUG # "~4", -%\end{verbatim} -%Depending on the bibliography style, this may be displayed as: -%July~31~--~August~4, or it may be displayed as: -%Jul~31~--~Aug~4. For further information, see~\cite{Goossens}. -% -%\subsection{Loading a \texorpdfstring{\sty{databib}}{databib} -%database} -%\label{sec:loadbbl} -% -%The \sty{databib} package always requires the \texttt{databib.bst} -%bibliography style file (which is supplied with this bundle). -%You need to use \cs{cite} or \cs{nocite} as usual. If you want to -%add all entries in the \ext{bib} file to the \sty{datatool} database, -%you can use "\nocite{*}". -% -%\begin{definition}[\DescribeMacro{\DTLloadbbl}]% -%\cs{DTLloadbbl}\oarg{bbl name}\marg{db name}\marg{bib list} -%\end{definition} -%This command performs several functions: -% -%\begin{enumerate} -%\item it writes the following line in the auxiliary file: -%\begin{verbatim} -%\bibstyle{databib} -%\end{verbatim} -%which tells \BibTeX\ to use the \texttt{databib.bst} -%\BibTeX\ style file, -% -%\item it writes \cs{bibdata}\marg{bib list} to the -%auxiliary file, which tells \BibTeX\ which \ext{bib} files to use, -% -%\item it creates a \sty{datatool} database called \meta{db name}, -% -%\item it loads the file \meta{bbl name} if it exists. (The value -%defaults to \cs{jobname}".bbl", which is the usual name for -%a \ext{bbl} file.) If the \ext{bbl} file doesn't exist, the -%database \meta{db name} will remain empty. -%\end{enumerate} -% -%You then need to run your document through \LaTeX\ (or PDF\LaTeX) -%and then run \BibTeX\ on the auxiliary file, as described in -%\autoref{sec:bibtex}. This will create a \ext{bbl} file which -%contains all the commands required to add the bibliography information -%to the \sty{datatool} database called \meta{db name}. The next -%time you \LaTeX\ your document, this file will be read, and the -%information will be added to \meta{db name}. -% -%\importantpar Note that -%\cs{DTLloadbbl} doesn't generate any text. Once you have loaded -%the data, you can display the bibliography uses -%\cs{DTLbibliography} (described below) or you can iterate -%through it using \cs{DTLforeachbibentry} described in -%\autoref{sec:foreachbib}. -% -%Note that the \texttt{databib.bst} \BibTeX\ style file provides -%the following additional fields: "isbn", "doi", "pubmed", "url" -%and "abstract". -%However these fields are ignored by the three predefined -%\sty{databib} styles ("plain", "abbrv" and "alpha"). If you -%want these fields to be displayed in the bibliography you will -%need to modify the bibliography style (see \autoref{sec:modbibstyle}). -% -%\subsection{Displaying a \texorpdfstring{\sty{databib}}{databib} -%database} -%\label{sec:thebib} -% -%A \sty{databib} database which has been loaded using -%\cs{DTLloadbbl} (described in \autoref{sec:loadbbl}) can be -%displayed using: -%\begin{definition}[\DescribeMacro{\DTLbibliography}] -%\cs{DTLbibliography}\oarg{conditions}\marg{db name} -%\end{definition}\noindent -%where \meta{db name} is the name of the database. -% -%Within the optional argument \meta{condition}, you may use any of the -%commands that may be used within the optional argument of -%\cs{DTLforeach} \emph{In addition}, you may use the following -%commands: -% -%\begin{definition}[\DescribeMacro{\DTLbibfieldexists}]% -%\cs{DTLbibfieldexists}\marg{field label} -%\end{definition} -%This tests whether the field with the given label exists for the -%current entry. -%The field label may be one of: "Address", "Author", -%"BookTitle", "Chapter", "Edition", "Editor", "HowPublished", -%"Institution", "Journal", "Key", "Month", "Note", "Number", -%"Organization", "Pages", "Publisher", "School", "Series", -%"Title", "Type", "Volume", "Year", "ISBN", "DOI", "PubMed", -%"Abstract" or "Url". -% -%For example, suppose you have loaded a \sty{databib} database -%called "mybib" using \cs{DTLloadbbl} (described in -%\autoref{sec:loadbbl}) then the following bibliography will only -%include those entries which have a "Year" field: -%\begin{verbatim} -%\DTLbibliography[\DTLbibfieldexists{Year}]{mybib} -%\end{verbatim} -% -%\begin{definition}[\DescribeMacro{\DTLbibfieldiseq}]% -%\cs{DTLbibfieldiseq}\marg{field label}\marg{value} -%\end{definition} -%This tests whether the value of the field given by -%\meta{field label} equals \meta{value}. If the field doesn't -%exist for the current entry, this evaluates to false. -%For example, the following will produce a bibliography which -%only contains entries which have the "Year" field set to 2004: -%\begin{verbatim} -%\DTLbibliography[\DTLbibfieldiseq{Year}{2004}]{mybib} -%\end{verbatim} -% -%\begin{definition}[\DescribeMacro{\DTLbibfieldcontains}]% -%\cs{DTLbibfieldcontains}\marg{field label}\marg{sub string} -%\end{definition} -%This tests whether the value of the field given by \meta{field label} -%contains \meta{sub string}. For example, the following will produce -%a bibliography which only contains entries where the author field -%contains the name "Knuth": -%\begin{verbatim} -%\DTLbibliography[\DTLbibfieldcontains{Author}{Knuth}]{mybib} -%\end{verbatim} -% -%\begin{definition}[\DescribeMacro{\DTLbibfieldislt}]% -%\cs{DTLbibfieldislt}\marg{field label}\marg{value} -%\end{definition} -%This tests whether the value of the field given by \meta{field label} -%is less than \meta{value}. If the field doesn't exist for the -%current entry, this evaluates to false. -%For example, the following will produce a bibliography which only -%contains entries whose "Year" field is less than 1983: -%\begin{verbatim} -%\DTLbibliography[\DTLbibfieldislt{Year}{1983}]{mybib} -%\end{verbatim} -% -%\begin{definition}[\DescribeMacro{\DTLbibfieldisle}]% -%\cs{DTLbibfieldisle}\marg{field label}\marg{value} -%\end{definition} -%This tests whether the value of the field given by \meta{field label} -%is less than or equal to \meta{value}. If the field doesn't exist -%for the current entry, this evaluates to false. -%For example, the following will produce a bibliography which only -%contains entries whose "Year" field is less than or equal to 1983: -%\begin{verbatim} -%\DTLbibliography[\DTLbibfieldisle{Year}{1983}]{mybib} -%\end{verbatim} -% -%\begin{definition}[\DescribeMacro{\DTLbibfieldisgt}]% -%\cs{DTLbibfieldisgt}\marg{field label}\marg{value} -%\end{definition} -%This tests whether the value of the field given by \meta{field label} -%is greater than \meta{value}. If the field doesn't exist for the -%current entry, this evaluates to false. -%For example, the following will produce a bibliography which only -%contains entries whose "Year" field is greater than 1983: -%\begin{verbatim} -%\DTLbibliography[\DTLbibfieldisgt{Year}{1983}]{mybib} -%\end{verbatim} -% -%\begin{definition}[\DescribeMacro{\DTLbibfieldisge}]% -%\cs{DTLbibfieldisge}\marg{field label}\marg{value} -%\end{definition} -%This tests whether the value of the field given by \meta{field label} -%is greater than or equal to \meta{value}. If the field doesn't exist -%for the current entry, this evaluates to false. -%For example, the following will produce a bibliography which only -%contains entries whose "Year" field is greater than or equal to 1983: -%\begin{verbatim} -%\DTLbibliography[\DTLbibfieldisge{Year}{1983}]{mybib} -%\end{verbatim} -% -%Note that \cs{DTLbibliography} uses \cs{DTLforeachbibentry} -%(described in \autoref{sec:foreachbib}) so you may also use -%test the value of the counter \ctr{DTLbibrow} within -%\meta{conditions}. You may also use the boolean commands defined -%by the \sty{ifthen} package, such as \ics{not}. -% -%\begin{example}{Creating a list of publications since a given year}{ex:bibsince2000} -%Suppose my boss has asked me to produce a list of my -%publications in reverse chronological order, but doesn't want any -%publications published prior -%to the year 2000. I have a file called "nlct.bib" which contains -%all my publications which I keep in the directory -%\verb!$HOME/texmf/bibtex/bib/!. I could look through this file, -%work out the labels for all the publications whose year field -%is greater or equal to 2000, and -%create a file with a \cs{nocite} command containing all those labels -%in a comma separated list in reverse chronological order, -%but I really can't be bothered to do that. -%Instead, I can create the following document: -%\begin{verbatim} -%\documentclass{article} -%\usepackage{databib} -%\begin{document} -%\nocite{*} -%\DTLloadbbl{mybib}{nlct} -%\DTLsort{Year=descending,Month=descending}{mybib} -%\DTLbibliography[\DTLbibfieldisge{Year}{2000}]{mybib} -%\end{document} -%\end{verbatim} -%Suppose I save this file as "mypubs.tex", then I need to do: -%\begin{verbatim} -%latex mypubs -%bibtex mypubs -%latex mypubs -%\end{verbatim} -%Notes: -%\begin{enumerate} -%\item "\nocite{*}" is used to add all the citations in the -%bibliography file ("nlct.bib" in this case) to the \sty{databib} -%database. -% -%\item "\DTLloadbbl{mybib}{nlct}" does the following: -%\begin{enumerate} -%\item writes the line -%\begin{verbatim} -%\bibstyle{databib} -%\end{verbatim} -%to the auxiliary file. This tells \BibTeX\ to use "databib.bst" -%(which is supplied with this package). You therefore shouldn't -%use \cs{bibliographystyle}. -% -%\item writes the line -%\begin{verbatim} -%\bibdata{nlct} -%\end{verbatim} -%to the auxiliary file. This tells \BibTeX\ that the bibliography -%data is stored in the file "nlct.bib". Since I have placed this -%file in \TeX's search path, \BibTeX\ will be able to find it. -% -%\item creates a \sty{datatool} database called "mybib". -% -%\item if the \ext{bbl} file ("mypubs.bbl" in this example) exists, -%it loads this file (which adds the bibliography data to the -%database), otherwise it does nothing further. -% -%\end{enumerate} -% -%\item In my \BibTeX\ database ("nlct.bib" in this example), I -%have remembered to use the \BibTeX\ month macros: "jan", "feb" -%etc. This means that the months are stored in the database in -%the form \cs{DTLmonthname}\marg{nn}, where \meta{nn} is a two -%digit number from 01 to 12. \cs{DTLsort} ignores command names -%when it compares strings, which means I can not only sort by -%year, but also by month\footnote{as long as I haven't put anything -%before the month name in the bibliography file, e.g.\ -%\mbox{\texttt{month = "2~" \# apr}} will sort by 2~03, instead of -%03}. -% -%\item Once I have loaded and sorted my database, I can then -%display it using \cs{DTLbibliography}. This uses the style -%given by the \sty{databib} \pkgopt[databib]{style} package option, -%or the \cs{DTLbibliographystyle} command, both of which are -%described in \autoref{sec:bibstyle}. -% -%\item I have filtered the bibliography using the optional -%argument\linebreak "[\DTLbibfieldisge{Year}{2000}]", which checks if the -%year field of the current entry is greater than or equal to -%2000. (Note that if an entry has no year field, the condition -%evaluates to false, and the entry will be omitted from the -%bibliography.) -% -%\item If the bibliography database is large, sorting and creating -%the bibliography may take a while. Using \sty{databib} is much -%slower than using a standard \BibTeX\ style file. -%\end{enumerate} -%\end{example} -% -%\begin{example}{Creating a list of my 10 most recent -%publications}{ex:top10bib} -%Suppose now my boss has asked me to produce a list of my ten most -%recent publications (in reverse chronological order). -%As in the previous example, I have a file called "nlct.bib" -%which contains all my publications. I can create the required -%document as follows: -%\begin{verbatim} -%\documentclass{article} -%\usepackage{databib} -%\begin{document} -%\nocite{*} -%\DTLloadbbl{mybib}{nlct} -%\DTLsort{Year=descending,Month=descending}{mybib} -%\DTLbibliography[\value{DTLbibrow}<11]{mybib} -%\end{document} -%\end{verbatim} -%\end{example} -% -%\subsection{Changing the bibliography style} -%\label{sec:bibstyle} -%The style of the bibliography produced using \cs{DTLbibliography} -%depends on the \pkgopt[databib]{style} -%package option, or can be set using -%\begin{definition}[\DescribeMacro{\DTLbibliographystyle}]% -%\cs{DTLbibliographystyle}\marg{style} -%\end{definition} -%Note that this is \emph{not} the same as \cs{bibliographystyle}, -%as the \sty{databib} package uses its custom \texttt{databib.bst} -%bibliography style file. -% -%Example: -%\begin{verbatim} -%\usepackage[style=plain]{databib} -%\end{verbatim} -%This sets the plain bibliography style. This is, in fact, the -%default style, so it need not be specified. -% -%Available styles are: "plain", "abbrv" and "alpha". These are similar to the -%standard \BibTeX\ styles of the same name, but are by no means -%identical. The most notable difference is that these styles -%do not sort the bibliography. It is up to you to sort the -%bibliography using \cs{DTLsort} (described in \autoref{sec:sort}). -% -%\subsubsection{Modifying an existing style} -%\label{sec:modbibstyle} -% -%This section describes some of the commands which are used to -%format the bibliography. You can choose whichever predefined -%style best fits your required style, and then modify the commands -%described in this section. A description of the remaining -%commands not listed in this section can be found in -%\autoref{sec:src:bibnames}, \autoref{sec:src:displaybib} -%and \autoref{sec:src:bibstyle}. -% -%\begin{definition}[\DescribeMacro{\DTLformatauthor}]% -%\cs{DTLformatauthor}\marg{von part}\marg{surname}\marg{jr part}\marg{forenames} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLformateditor}]% -%\cs{DTLformateditor}\marg{von part}\marg{surname}\marg{jr part}\marg{forenames} -%\end{definition} -%These commands are used to format an author/editor's name, -%respectively. The list of authors and editors are stored in -%the \sty{databib} database as a comma separated list of -%\marg{von part}\marg{surname}\marg{jr part}\marg{forenames} -%data. This ensures that when you sort on the Author or Editor -%field, the names will be sorted by the first author or editor's -%surname. -% -%Within \cs{DTLformatauthor} and \cs{DTLformateditor}, you may -%use the following commands: -%\begin{definition}[\DescribeMacro{\DTLformatforenames}]% -%\cs{DTLformatforenames}\marg{forenames} -%\end{definition} -%This is used by the "plain" style to display the author's -%forenames\footnote{It also checks -%whether \meta{forenames} ends with a full stop using -%\cs{DTLcheckendsperiod} to prevent a sentence ending full stop -%from following an abbreviation full stop}. -% -%\begin{definition}[\DescribeMacro{\DTLformatabbrvforenames}]% -%\cs{DTLformatabbrvforenames}\marg{forenames} -%\end{definition} -%This is used by the "abbrv" style to display the author's -%initials (which are determined from \meta{forenames}). -%Note that if any of the authors has a name starting with an -%accent, the accented letter must be grouped in order for this -%command to work. For example: -%\begin{verbatim} -%author = "{\'E}lise {\"E}awyn Edwards", -%\end{verbatim} -%The initials are formed using \cs{DTLstoreinitials} described -%in \autoref{sec:strings}, so if you want to change the way the -%initials are displayed (e.g.\ put a space between them) you will -%need to redefine the commands used by \cs{DTLstoreinitials} (such -%as \cs{DTLbetweeninitials}). -% -%\begin{definition}[\DescribeMacro{\DTLformatsurname}]% -%\cs{DTLformatsurname}\marg{surname} -%\end{definition} -%This displays its argument by default\footnote{It also checks -%whether the surname ends with a full stop using -%\cs{DTLcheckendsperiod}}. -% -%\begin{definition}[\DescribeMacro{\DTLformatvon}]% -%\cs{DTLformatvon}\marg{von part} -%\end{definition} -%If the \meta{von part} is empty, this command does nothing, -%otherwise it displays its argument followed by a -%non-breakable space. -%\begin{definition}[\DescribeMacro{\DTLformatjr}]% -%\cs{DTLformatjr}\marg{jr part} -%\end{definition} -%If the \meta{jr part} is empty, this command displays nothing, -%otherwise it displays a comma followed by its argument\footnote -%{again, it also checks \meta{jr part} to determine if it ends -%with a full stop}. -% -%For example, suppose you want the author's surname to appear -%first in small capitals, followed by a comma and the forenames. This -%can be achieved by redefining \cs{DTLformatauthor} as follows: -%\begin{verbatim} -%\renewcommand*{\DTLformatauthor}[4]{% -%\textsc{\DTLformatvon{#1}% -%\DTLformatsurname{#2}\DTLformatjr{#3}}, -%\DTLformatforenames{#4}% -%} -%\end{verbatim} -% -%\begin{definition}[\DescribeCounter{DTLmaxauthors}] -%\ctrfmt{DTLmaxauthors} -%\end{definition} -%The counter \ctrfmt{DTLmaxauthors} is used to determine the -%maximum number of authors to display for a given entry. If the -%entry's author list contains more than that number of authors, -%\cs{etalname} is used, the definition of which is given in -%\autoref{sec:src:bibnames}. The default value of -%\ctrfmt{DTLmaxauthors} is \theDTLmaxauthors. -% -%\begin{definition}[\DescribeCounter{DTLmaxeditors}] -%\ctrfmt{DTLmaxeditors} -%\end{definition} -%The \ctrfmt{DTLmaxeditors} counter is analogous to the -%\ctrfmt{DTLmaxauthors} counter. It is used to determine the -%maximum number of editor names to display. The default value -%of \ctrfmt{DTLmaxeditors} is \theDTLmaxeditors. -% -%\DescribeMacro{\DTLandlast} -%Within a list of author or editor names, \cs{DTLandlast} is -%used between the last two names, otherwise -%\DescribeMacro{\DTLandnotlast}\cs{DTLandnotlast} is used between -%names. -%However, if there are only two author or editor names, -%\DescribeMacro{\DTLtwoand}\cs{DTLtwoand} -%is used instead of \cs{DTLandlast}. -% -%\DescribeMacro{\DTLendbibitem} -%The command \cs{DTLendbibitem} is a hook provided to add -%additional information at the end of each bibliography item. -%This does nothing by default, but if you want to display the -%additional fields provided by the "databib.bst" style file, -%you can redefine \cs{DTLendbibitem} so that it displays a -%particular field, if it is defined. Within this command, you -%may use the commands \cs{DTLbibfield}, \cs{DTLifbibfieldexist} -%and \cs{DTLifanybibfieldexist}, which are described in -%\autoref{sec:foreachbib}. For example, if you have used the -%"abstract" field in any of your entries, you can display the -%abstract as follows: -%\begin{verbatim} -%\renewcommand{\DTLendbibitem}{% -%\DTLifbibfieldexists{Abstract}{\DTLpar\textbf{Abstract} -%\begin{quote}\DTLbibfield{Abstract}\end{quote}}{}} -%\end{verbatim} -%(Note that \cs{DTLpar} needs to be used instead of -%\cs{par}.) -% -%\begin{example}{Compact bibliography}{ex:compactbib} -%Suppose I don't have much space in my document, and I need to -%produce a compact bibliography. Firstly, I can use the -%bibliography style "abbrv", either through the package option: -%\begin{verbatim} -%\usepackage[style=abbrv]{databib} -%\end{verbatim} -%or using: -%\begin{verbatim} -%\DTLbibliographystyle{abbrv} -%\end{verbatim} -%Once I have set the style, I can further modify it thus: -%\begin{verbatim} -%\renewcommand*{\andname}{\&} -%\renewcommand*{\editorname}{ed.} -%\renewcommand*{\editorsname}{eds.} -%\renewcommand*{\pagesname}{pp.} -%\renewcommand*{\pagename}{p.} -%\renewcommand*{\volumename}{vol.} -%\renewcommand*{\numbername}{no.} -%\renewcommand*{\editionname}{ed.} -%\renewcommand*{\techreportname}{T.R.} -%\renewcommand*{\mscthesisname}{MSc thesis} -%\end{verbatim} -%Now I can load\footnote{I can load the bibliography earlier, but -%obviously the bibliography should only be displayed after the -%bibliography styles have been set, otherwise they will have no -%effect} and display the bibliography: -%\begin{verbatim} -% % create a database called mybib from the information given -% % in mybib1.bib and mybib2.bib -% \DTLloadbbl{mybib}{mybib1,mybib2} -% % display the bibliography -% \DTLbibliography{mybib} -%\end{verbatim} -%\end{example} -% -%\begin{example}{Highlighting a given author}{ex:highlightauthor} -%Suppose my boss wants me to produce a list of all my publications -%(which I have stored in the file "nlct.bib", as in -%\autoref{ex:bibsince2000}). Most of my -%publications have multiple co-authors, but suppose my boss would -%like me to highlight my name so that when he skims through -%the document, he can easily see my name in the list of -%co-authors. I can do this by redefining \cs{DTLformatauthor} -%so that it checks if the given surname matches mine. (This -%assumes that none of the other co-author's share my surname.) -%\begin{verbatim} -%\renewcommand*{\DTLformatauthor}[4]{% -%{\DTLifstringeq{#2}{Talbot}{\bfseries }{}% -%\DTLformatforenames{#4} -%\DTLformatvon{#1}% -%\DTLformatsurname{#2}% -%\DTLformatjr{#3}}} -%\end{verbatim} -%Notes: -%\begin{enumerate} -%\item I have used \cs{DTLifstringeq} (described in -%\autoref{sec:ifconditions}) to perform the string comparison. -%\item If one or more of my co-authors shared the same surname as -%me, I would also have had to check the first name, however there -%is regrettably a lack of consistency in my \ext{bib} file when -%it comes to my forenames. Sometimes my name is given as -%\texttt{Nicola L. C. Talbot}, sometimes the middle initials -%are omitted, \texttt{Nicola Talbot}, or sometimes, just initials -%are used, \texttt{N. L. C. Talbot}. This can cause problems -%when checking the forenames, but as long as the other authors -%who share the same surname as me, don't also share the same -%first initial, I can use \cs{DTLifStartsWith} or \cs{DTLisPrefix}, -%which are described in \autoref{sec:ifconditions} and -%\autoref{sec:ifthen}, respectively. Using the first approach -%I can do: -%\begin{verbatim} -%\renewcommand*{\DTLformatauthor}[4]{% -%{\DTLifstringeq{#2}{Talbot}{\DTLifStartsWith{#4}{N}{\bfseries }{}}{}% -%\DTLformatforenames{#4} -%\DTLformatvon{#1}% -%\DTLformatsurname{#2}% -%\DTLformatjr{#3}}} -%\end{verbatim} -%Using the second approach I can do: -%\begin{verbatim} -%\renewcommand*{\DTLformatauthor}[4]{% -%{\ifthenelse{\DTLiseq{#2}{Talbot}\and -%\DTLisPrefix{#4}{N}}{\bfseries }{}% -%\DTLformatforenames{#4} -%\DTLformatvon{#1}% -%\DTLformatsurname{#2}% -%\DTLformatjr{#3}}} -%\end{verbatim} -% -%\item I have used a group to localise the effect of \cs{bfseries}. -%\end{enumerate} -%\end{example} -% -%\subsection{Iterating through a -%\texorpdfstring{\sty{databib}}{databib} database} -%\label{sec:foreachbib} -% -%\cs{DTLbibliography} (described in \autoref{sec:thebib}) may still -%not meet your needs. For example, you may be required -%to list journal papers and conference proceedings in separate -%sections. In which case, you may find it easier to iterate through -%the bibliography using: -%\begin{definition}[\DescribeMacro{\DTLforeachbib}]% -%\cs{DTLforeachbib}\oarg{condition}\marg{db name}\marg{text} -%\end{definition} -%\begin{definition}[\DescribeMacro{\DTLforeachbib*}]% -%\cs{DTLforeachbib*}\oarg{condition}\marg{db name}\marg{text} -%\end{definition} -%This iterates through the \sty{databib} database called -%\meta{db name} and does \meta{text} if \meta{condition} is met. -%As with \cs{DTLforeach}, the starred version is read-only. -% -%For each row of the database, the following commands are set: -%\begin{itemize} -%\item \cs{DBIBcitekey} \DescribeMacro{\DBIBcitekey}This is the -%unique label which identifies the current entry (as used in the -%argument of \cs{cite} and \cs{nocite}). -% -%\item \cs{DBIBentrytype} \DescribeMacro{\DBIBentrytype}This -%is the current entry type, and will be one of: "article", "book", -%"booklet", "inbook", "incollection", "inproceedings", -%"manual", "mastersthesis", "misc", "phdthesis", "proceedings", -%"techreport" or "unpublished". (Note that even if you used the -%entry type "conference" in your \ext{bib} file, its entry type -%will be set to "inproceedings"). -%\end{itemize} -% -%The remaining fields may be accessed using: -%\begin{definition}[\DescribeMacro{\DTLbibfield}]% -%\cs{DTLbibfield}\marg{field label} -%\end{definition}\noindent -%where \meta{field label} may be one of: "Address", "Author", -%"BookTitle", "Chapter", "Edition", "Editor", "HowPublished", -%"Institution", "Journal", "Key", "Month", "Note", "Number", -%"Organization", "Pages", "Publisher", "School", "Series", -%"Title", "Type", "Volume", "Year", "ISBN", "DOI", "PubMed", -%"Abstract" or "Url". -% -%You can determine if a field exists for a given entry using -%\begin{definition}[\DescribeMacro{\DTLifbibfieldexists}]% -%\cs{DTLifbibfieldexists}\marg{field label}\marg{true part}\marg{false -%part} -%\end{definition} -%If the field given by \meta{field label} exists for the current -%bibliography entry, it does \meta{true part}, otherwise it -%does \meta{false part}. -% -%\begin{definition}[\DescribeMacro{\DTLifbibanyfieldexists}]% -%\cs{DTLifanybibfieldexists}\marg{field label list}\marg{true -%part}\marg{false part} -%\end{definition} -%This is similar to \cs{DTLifbibfieldexists} except that the -%first argument is a list of field names. If one or more of -%the fields given in \meta{field label list} exists for the -%current bibliography item, this does \meta{true part}, otherwise -%it does \meta{false part}. -% -%\begin{definition}[\DescribeMacro{\DTLformatbibentry}]% -%\cs{DTLformatbibentry} -%\end{definition} -%This formats the bibliography entry for the current row. It -%checks for the existence of the command -%\cs{DTLformat}\meta{entry type}, where \meta{entry type} -%is given by \cs{DBIBentrytype}. These commands are defined -%by the bibliography style. -% -%\begin{definition}[\DescribeMacro{\DTLcomputewidestbibentry}]% -%\cs{DTLcomputewidestbibentry}\marg{conditions}\marg{db -%name}\marg{bib label}\marg{cmd} -%\end{definition} -%This computes the widest bibliography entry over all entries -%satisfying \meta{conditions} in the database \meta{db name}, -%where the label is given by \meta{bib label}, and the result -%is stored in \meta{cmd}, which may then be used in the -%argument of the \env{thebibliography} environment. -% -%The counter \desctr{DTLbibrow} keeps track of the current -%bibliography entry. This is reset at the start of each -%\cs{DTLforeachbib} and is incremented if \meta{conditions} -%is met. -% -%Within the optional argument \meta{condition}, you may use any of the -%commands that may be used within the optional argument of -%\cs{DTLbibliography}, described in \autoref{sec:thebib}. -% -%\begin{example}{Separate List of Journals and Conference Papers}{ex:jcbib} -%Suppose now my boss has decided that I need to produce a list -%of all my publications, but they need to be separated so that -%all the journal papers appear in one section, and all the -%conference papers appear in another section. The journal papers -%need to be labelled [J1], [J2] and so on, while the conference -%papers need to be labelled [C1], [C2] and so on. (My boss isn't -%interested in any of my other publications!) Again, all my -%publications are stored in the \BibTeX\ database "nlct.bib". The -%following creates the required document: -%\begin{verbatim} -%\documentclass{article} -%\usepackage{databib} -%\begin{document} -%\nocite{*} -%\DTLloadbbl{mybib}{nlct} -% -%\renewcommand*{\refname}{Journal Papers} -%\DTLcomputewidestbibentry{\equal{\DBIBentrytype}{article}} -%{mybib}{J\theDTLbibrow}{\widest} -% -%\begin{thebibliography}{\widest} -%\DTLforeachbibentry[\equal{\DBIBentrytype}{article}]{mybib}{% -%\bibitem[J\theDTLbibrow]{\DBIBcitekey} \DTLformatbibentry} -%\end{thebibliography} -% -%\renewcommand*{\refname}{Conference Papers} -%\DTLcomputewidestbibentry{\equal{\DBIBentrytype}{inproceedings}} -%{mybib}{C\theDTLbibrow}{\widest} -% -%\begin{thebibliography}{\widest} -%\DTLforeachbibentry[\equal{\DBIBentrytype}{inproceedings}]{mybib}{% -%\bibitem[C\theDTLbibrow]{\DBIBcitekey} \DTLformatbibentry} -%\end{thebibliography} -% -%\end{document} -%\end{verbatim} -%\end{example} -% -%\subsection{Multiple Bibliographies} -%\label{sec:multibib} -% -%It is possible to have more than one bibliography in a document, -%but it then becomes necessary to have a separate auxiliary file -%for each bibliography, and each auxiliary file must then be -%passed to \BibTeX. In order to do this, you need to use -%\begin{definition}[\DescribeMacro{\DTLmultibibs}]% -%\cs{DTLmultibibs}\marg{name list} -%\end{definition} -%where \meta{name list} is a comma separated list of names, -%\meta{name}. For each \meta{name}, this command creates an -%auxiliary file called \meta{name}".aux" (note that this -%command may only be used in the preamble). -% -%When you want to cite an entry for a given bibliography named -%in \cs{DTLmultibibs}, you must use: -%\begin{definition}[\DescribeMacro{\DTLcite}]% -%\cs{DTLcite}\oarg{text}\marg{mbib}\marg{cite key list} -%\end{definition}\noindent -%This is analogous to \cs{cite}\oarg{text}\marg{cite key list}, -%but writes the \cs{citation} command to \meta{mbib}".aux" instead -%of to the document's main auxiliary file. It also ensures that -%the cross-referencing labels are based on \meta{mbib}, to allow -%you to have the same reference in more than one bibliography -%without incurring a ``multiply defined'' warning message. Note -%that you can still use \cs{cite} to add citation information to -%the main auxiliary file. -% -%If you want to add an entry to the bibliography without producing -%any text, you can use -%\begin{definition}[\DescribeMacro{\DTLnocite}] -%\cs{DTLnocite}\marg{mbib}\marg{cite key list} -%\end{definition}\noindent -%which is analogous to \cs{nocite}\marg{cite key list}, where -%again the citation information is written to \meta{mbib}".aux" -%instead of the document's main auxiliary file. -% -%Note that for both \cs{DTLcite} and \cs{DTLnocite} the -%\meta{mbib} part must be one of the names listed in -%\cs{DTLmultibibs}. -% -%\begin{definition}[\DescribeMacro{\DTLloadmbbl}]% -%\cs{DTLloadmbbl}\marg{mbib}\marg{db name}\marg{bib list} -%\end{definition} -%This is analogous to \cs{DTLloadbbl}\marg{db name}\marg{bib list} -%described in \autoref{sec:loadbbl}. (Again \meta{mbib} must be -%one of the names listed in \cs{DTLmultibibs}.) This creates -%a new \sty{datatool} database called \meta{db name} and loads the -%bibliography information from \meta{mbib}".bbl" (if it exists). -% -%\begin{definition}[\DescribeMacro{\DTLmbibliography}]% -%\cs{DTLmbibliography}\oarg{condition}\marg{mbib}\marg{db name} -%\end{definition} -%This is analogous to \cs{DTLbibliography}\oarg{condition}\marg{db name}, -%but is required when displaying a bibliography in which elements have -%been cited using \cs{DTLcite} and \cs{DTLnocite}. -% -%\begin{example}{Multiple Bibliographies}{ex:multibib} -%Suppose I need to create a document which contains a section listing -%all my publications, but I also need to have separate sections -%covering each of my research topics, with a mini-bibliography -%at the end of each section. As in the earlier examples, all my -%publications are stored in the file "nlct.bib" which is somewhere -%on \TeX's path. Note that there will be some duplication as the -%references in the mini-bibliographies will also appear in the -%main bibliography at the end of the document, but using -%\cs{DTLcite} and \cs{DTLmbibliography} ensures that all the -%cross-referencing labels (and hyperlinks if they are enabled) -%are unique. -%\begin{verbatim} -%\documentclass{article} -%\usepackage{databib} -%\DTLmultibibs{kernel,food} -%\begin{document} -%\section{Kernel methods} -%In this section I'm going to describe some research work into -%kernel methods, and in the process I'm going to cite some related -%papers \DTLcite{kernel}{Cawley2007a,Cawley2006a}. -% -%\DTLloadmbbl{kernel}{kernelDB}{nlct} -%\DTLmbibliography{kernel}{kernelDB} -% -%\section{Food research} -% -%In this section I'm going to describe some research work -%in the area of food safety, and in the process, I'm going -%to cite some related papers \DTLcite{food}{Peck1999,Barker1999a} -% -%\DTLloadmbbl{food}{foodDB}{nlct} -%\DTLmbibliography{food}{foodDB} -% -%\cite{*} -%\renewcommand{\refname}{Complete List of Publications} -%\DTLloadbbl{fullDB}{nlct} -%\DTLbibliography{fullDB} -%\end{document} -%\end{verbatim} -%Notes: -%\begin{enumerate} -%\item This will create the files "kernel.aux" and "food.aux". -%These will have to be passed to \BibTeX, in addition to the -%documents main auxiliary file. So, if my document is called -%"researchwork.tex", then I need to do: -%\begin{verbatim} -%latex researchwork -%bibtex researchwork -%bibtex kernel -%bibtex food -%latex researchwork -%latex researchwork -%\end{verbatim} -% -%\item "\cite{*}" is used to add all the entries in the bib file -%to the main bibliography database. As before, \cs{DTLloadbbl} -%and \cs{DTLbibliography} are used to load and display the main -%bibliography. -%\end{enumerate} -%\end{example} -% -%\importantpar Don't try to directly input the ".bbl" file using -%\cs{input} (or \cs{include}) instead of using \cs{DTLloadbbl} -%or \cs{DTLloadmbbl} as these commands store the name of the required -%database and initialise the database before loading the -%\texttt{.bbl} file. Similarly, don't just copy the contents of -%the ".bbl" file into your document without first defining the -%database using \ics{DTLnewdb} and setting \ics{DTLBIBdbname} to -%the name of the database. -% -%\section{Referencing People (\sty{person} package)} -%\label{sec:person} -% -%Sometimes when mail-merging, it may be necessary to reference a -%person by their pronoun which can lead to the cumbersome and -%impersonal ``he/she'' construct. The \sty{person} package -%allows you to define a person by their full name, familiar name and -%gender. You can then use the commands described in -%\autoref{sec:refperson} to produce the appropriate pronoun. -% -%This can also be useful for other types of documents, such as an -%order of service for a baptism or funeral. Since the -%document is much the same from one person to the next, documents of -%this nature are frequently simply copied and a search and replace -%edit is used to change the relevant text. However this can lead to -%errors (especially if the previous person's name was Mary!) With -%the \sty{person} package, you need only change the definition of -%the person by modifying the arguments of \cs{newperson}. -% -%\subsection{Defining and Undefining People} -% -%A person is defined (globally) using the command: -%\begin{definition}[\DescribeMacro{\newperson}] -%\cs{newperson}\oarg{label}\marg{full name}\marg{familiar name}\marg{gender} -%\end{definition} -%The optional argument is a unique label identifying this person, -%in the event that there is more than one person. If \meta{label} -%is omitted \texttt{anon} is used. (This is also the case for -%subsequent commands that take an optional label.) -%The gender may be any of those given by -%\begin{definition}[\DescribeMacro{\malelabels}] -%\cs{malelabels} -%\end{definition} -%or -%\begin{definition}[\DescribeMacro{\femalelabels}] -%\cs{femalelabels} -%\end{definition} -%The default definition of \cs{malelabels} is \texttt{\malelabels} -%and the default definition of \cs{femalelabels} is -%\texttt{\femalelabels}. You can add extra identifiers using -%\begin{definition}[\DescribeMacro{\addmalelabel}] -%\cs{addmalelabel}\marg{identifier} -%\end{definition} -%or -%\begin{definition}[\DescribeMacro{\addfemalelabel}] -%\cs{addfemalelabel}\marg{identifier} -%\end{definition} -%For example: -%\begin{verbatim} -%\addmalelabel{boy} -%\addfemalelabel{girl} -%\end{verbatim} -% -%The total number of defined people is given by: -%\begin{definition}[\DescribeMacro{\thepeople}] -%\cs{thepeople} -%\end{definition} -% -%A person can be undefined using: -%\begin{definition}[\DescribeMacro{\removeperson}] -%\cs{removeperson}\oarg{label} -%\end{definition} -%where the person is given by \meta{label}. -% -%If more than one person has been defined, they can all be -%removed using: -%\begin{definition}[\DescribeMacro{\removeallpeople}] -%\cs{removeallpeople} -%\end{definition} -%or you can remove a subset using: -%\begin{definition}[\DescribeMacro{\removepeople}] -%\cs{removepeople}\marg{list} -%\end{definition} -%where \meta{list} is a comma-separated list of labels. -% -%\subsection{Displaying Information} -%\label{sec:refperson} -% -%Once a person has been defined, you can display their name using: -%\begin{definition}[\DescribeMacro{\personfullname}] -%\cs{personfullname}\oarg{label} -%\end{definition} -%where \meta{label} is the unique label used in the optional -%argument to \cs{newperson}. The person's familiar name is displayed -%using: -%\begin{definition}[\DescribeMacro{\personname}] -%\cs{personname}\oarg{label} -%\end{definition} -%The person's pronoun (``he'' or ``she'') is displayed using: -%\begin{definition}[\DescribeMacro{\personpronoun}] -%\cs{personpronoun}\oarg{label} -%\end{definition} -%The objective pronoun (``him'' or ``her'') is displayed using: -%\begin{definition}[\DescribeMacro{\personobjpronoun}] -%\cs{personobjpronoun}\oarg{label} -%\end{definition} -%The possessive adjective (``his'' or ``her'') is displayed using: -%\begin{definition}[\DescribeMacro{\personpossadj}] -%\cs{personpossadj}\oarg{label} -%\end{definition} -%The possessive pronoun ``his'' or ``hers'' is displayed using: -%\begin{definition}[\DescribeMacro{\personposspronoun}] -%\cs{personposspronoun}\oarg{label} -%\end{definition} -%The person's relationship to their parent (``son'' or ``daughter'') -%is displayed using: -%\begin{definition}[\DescribeMacro{\personchild}] -%\cs{personchild}\oarg{label} -%\end{definition} -%The person's relationship to their child (``mother'' or ``father'') -%is displayed using: -%\begin{definition}[\DescribeMacro{\personparent}] -%\cs{personparent}\oarg{label} -%\end{definition} -%The person's relationship to their sibling (``brother'' or -%``sister'') is displayed using: -%\begin{definition}[\DescribeMacro{\personsibling}] -%\cs{personsibling}\oarg{label} -%\end{definition} -% -%If the word occurs at the start of a sentence, you will need one -%of the following commands, which are as the above, except the -%first letter is converted to upper case: -%\begin{definition}[\DescribeMacro{\Personpronoun}] -%\cs{Personpronoun}\oarg{label} -%\end{definition} -%\begin{definition}[\DescribeMacro{\Personobjpronoun}] -%\cs{Personobjpronoun}\oarg{label} -%\end{definition} -%\begin{definition}[\DescribeMacro{\Personpossadj}] -%\cs{Personpossadj}\oarg{label} -%\end{definition} -%\begin{definition}[\DescribeMacro{\Personposspronoun}] -%\cs{Personposspronoun}\oarg{label} -%\end{definition} -%\begin{definition}[\DescribeMacro{\Personchild}] -%\cs{Personchild}\oarg{label} -%\end{definition} -%\begin{definition}[\DescribeMacro{\Personparent}] -%\cs{Personparent}\oarg{label} -%\end{definition} -%\begin{definition}[\DescribeMacro{\Personsibling}] -%\cs{Personsibling}\oarg{label} -%\end{definition} -% -%\begin{example}{Order of Service (Memorial)}{ex:memorial} -%This example is for a memorial order of service. -% -%\begin{verbatim} -%\documentclass{article} -% -%\usepackage{person} -% -%\newperson{Jane Doe}{Jane}{female} -% -%\begin{document} -%\begin{center} -%\Large -%In Memory of \personfullname -%\end{center} -% -%We are gathered here to remember our \personsibling\ \personname. -%\Personpronoun\ will be much missed, and \personpossadj\ -%family are in our prayers. -%\end{document} -%\end{verbatim} -% -%\newperson{Jane Doe}{Jane}{female} -%\begin{center} -%\Large -%In Memory of \personfullname -%\end{center} -% -%We are gathered here to remember our \personsibling\ \personname. -%\Personpronoun\ will be much missed, and \personpossadj\ -%family are in our prayers. -%\removeperson -% -%\end{example} -% -%If there is more than one person, you will need to use the -%optional argument \meta{label} to \cs{newperson} to uniquely -%identify each person. You can then list all of the people's full -%or familiar names using: -%\begin{definition}[\DescribeMacro{\peoplefullname}] -%\cs{peoplefullname} -%\end{definition} -%\begin{definition}[\DescribeMacro{\peoplename}] -%\cs{peoplename} -%\end{definition} -%Note that if there is only one person defined, these commands behave -%the same as \cs{personfullname}\oarg{label} and -%\cs{personname}[\meta{label}]. -% -%Similarly for the pronouns: -%\begin{definition}[\DescribeMacro{\peoplepronoun}] -%\cs{peoplepronoun} -%\end{definition} -%\begin{definition}[\DescribeMacro{\Peoplepronoun}] -%\cs{Peoplepronoun} -%\end{definition} -%\begin{definition}[\DescribeMacro{\peopleobjpronoun}] -%\cs{peopleobjpronoun} -%\end{definition} -%\begin{definition}[\DescribeMacro{\Peopleobjpronoun}] -%\cs{Peopleobjpronoun} -%\end{definition} -%\begin{definition}[\DescribeMacro{\peoplepossadj}] -%\cs{peoplepossadj} -%\end{definition} -%\begin{definition}[\DescribeMacro{\Peoplepossadj}] -%\cs{Peoplepossadj} -%\end{definition} -%\begin{definition}[\DescribeMacro{\peopleposspronoun}] -%\cs{peopleposspronoun} -%\end{definition} -%\begin{definition}[\DescribeMacro{\Peopleposspronoun}] -%\cs{Peopleposspronoun} -%\end{definition} -%where, again, if only one person has been defined, each of these -%commands is equivalent to -%\cs{person}\ldots\oarg{label} or -%\cs{Person}\ldots\oarg{label}. If more than -%one person has been defined, these commands will display -%they/them/their/theirs or They/Them/Their/Theirs, as appropriate. -% -%Likewise for relationship commands: -%\begin{definition}[\DescribeMacro{\peoplechild}] -%\cs{peoplechild} -%\end{definition} -%\begin{definition}[\DescribeMacro{\Peoplechild}] -%\cs{Peoplechild} -%\end{definition} -%\begin{definition}[\DescribeMacro{\peopleparent}] -%\cs{peopleparent} -%\end{definition} -%\begin{definition}[\DescribeMacro{\Peopleparent}] -%\cs{Peopleparent} -%\end{definition} -%\begin{definition}[\DescribeMacro{\peoplesibling}] -%\cs{peoplesibling} -%\end{definition} -%\begin{definition}[\DescribeMacro{\Peoplesibling}] -%\cs{Peoplesibling} -%\end{definition} -% -%\begin{example}{Order of Service (Baptism)}{ex:baptism} -%In this example two people are defined. -%\begin{verbatim} -%\documentclass{article} -% -%\usepackage{person} -% -%\newperson[john]{John Joseph}{John}{male} -%\newperson[jane]{Jane Mary}{Jane}{female} -% -%\begin{document} -%\begin{center} -%\Large -%Baptism of \peoplefullname. -%\end{center} -% -%Today we welcome \peoplename\ into God's family, may He guide -%and protect \peopleobjpronoun. -%\end{document} -%\end{verbatim} -% -%This is produces the following text: -% -%\newperson[john]{John Joseph}{John}{male} -%\newperson[jane]{Jane Mary}{Jane}{female} -% -%\begin{center} -%\Large -%Baptism of \peoplefullname. -%\end{center} -% -%Today we welcome \peoplename\ into God's family, may He guide -%and protect \peopleobjpronoun. -%\removeallpeople -%\end{example} -% -%\begin{example}{Mail Merging Using Appropriate Gender}{ex:personmerge} -%In this example I have a CSV file called \texttt{students.csv} -%containing the following: -%\begin{verbatim} -%FirstName,Surname,Gender,Parent,Address -%John,"Smith, Jr",M,Mr and Mrs Smith,1 The Street\\Newtown -%Jane,Brown,F,Ms Brown,2 The Avenue\\Oldtown -%Andy,Brown,male,Mr Brown and Miss Sepia,3 The Road\\Newtown -%Z\"oe,Adams,f,Mr and Mrs Adams,5 The Street\\Newtown -%Roger,Brady,m,Mrs Brady,6 The Avenue\\Oldtowm -%Clare,Vernon,female,Mr Vernon,7 The Close\\Anytown -%\end{verbatim} -%Suppose I have to write to each student's parents regarding their -%child. I can load the information using \ics{DTLloaddb} (described -%in \autoref{sec:loaddb}). I can then iterate through the database -%and define the student as a person and use the commands defined in -%the \sty{person} package to display the correct gender related text. -%I could give each person a unique label based on the row count -%(\ics{DTLcurrentindex}), but since I don't need to reuse the -%information, I can use the default "anon" label and undefine the -%person when no longer required. -% -%Note that in the CSV file, the gender label isn't consistent. -%For some students the gender is identified by a single letter -%(``m'' or ``f'') and for others the gender is identified by a -%complete word (``male'' or ``female''). There's also no regard -%for case. This doesn't matter to \ics{newperson} as all the -%identifiers used are listed in \ics{malelabels} and -%\ics{femalelabels}. -% -%The following is an example letter sent to all parents: -%\begin{verbatim} -%\documentclass{letter} -%\usepackage{person} -% -%% load student information from file "students.csv" -%\DTLloaddb{students}{students.csv} -%\begin{document} -%% Iterate through the student database: -%\DTLforeach{students}{\FirstName=FirstName,\Surname=Surname,% -%\Gender=Gender,\Parent=Parent,\Address=Address}{% -%% Define "anon": -% \newperson{\FirstName\space\Surname}{\FirstName}{\Gender}% -%% Do the letter: -% \begin{letter}{\Parent\\\Address} -% \opening{Dear \Parent} -% Your \personchild\ \personname\ has been awarded a -% place. We look forward to seeing \personobjpronoun\ -% on \personpossadj\ arrival. -% \closing{Yours Sincerely} -% \end{letter} -%% Undefine "anon": -% \removeperson -%} -%\end{document} -%\end{verbatim} -% -%The body of the first letter appears as follows: -%\newperson{John Smith Jr}{John}{m} -%\par\vskip\baselineskip -% -% Your \personchild\ \personname\ has been awarded a -% place. We look forward to seeing \personobjpronoun\ -% on \personpossadj\ arrival. -% -%\removeperson -%\par\vskip\baselineskip -%Whereas the body of the second letter appears as follows: -%\newperson{Jane Brown}{Jane}{f} -%\par\vskip\baselineskip -% -% Your \personchild\ \personname\ has been awarded a -% place. We look forward to seeing \personobjpronoun\ -% on \personpossadj\ arrival. -% -%\removeperson -%\end{example} -% -%\subsection{Advanced Commands} -% -%This section describes additional commands provided by the -%\sty{person} package. More detail can be found in -%\autoref{sec:code:person}. -% -%\subsubsection{Conditionals} -% -%\begin{definition}[\DescribeMacro{\ifpersonexists}] -%\cs{ifpersonexists}\marg{label}\marg{true part}\marg{false part} -%\end{definition} -%Tests if the person identified by \meta{label} has been defined. -%If true, do \meta{true part} otherwise do \meta{false part}. -% -%\begin{definition}[\DescribeMacro{\ifmale}] -%\cs{ifmale}\marg{label}\marg{true part}\marg{false part} -%\end{definition} -%Test if the person identified by \meta{label} is male. -%If true, do \meta{true part} otherwise do \meta{false part}. -% -%\begin{definition}[\DescribeMacro{\iffemale}] -%\cs{iffemale}\marg{label}\marg{true part}\marg{false part} -%\end{definition} -%Test if the person identified by \meta{label} is female. -%If true, do \meta{true part} otherwise do \meta{false part}. -% -%\begin{definition}[\DescribeMacro{\ifallmale}] -%\cs{ifallmale}\oarg{label list}\marg{true part}\marg{false part} -%\end{definition} -%Tests if all the people listed in \meta{label list} are male. -%If true, do \meta{true part} otherwise do \meta{false part}. -%If \meta{label list} is omitted, applied to all defined people. -%\begin{definition}[\DescribeMacro{\ifallfemale}] -%\cs{ifallfemale}\oarg{label list}\marg{true part}\marg{false part} -%\end{definition} -%Likewise to test if all the people tested are female. -% -%To determine if a string is an allowed male label: -%\begin{definition}[\DescribeMacro{\ifmalelabel}] -%\cs{ifmalelabel}\marg{identifier}\marg{true part}\marg{false part} -%\end{definition} -%where \meta{identifier} is the string to be tested. If true, do -%\meta{true part} otherwise do \meta{false part}. -%For example: -%\begin{verbatim} -%\def\gender{M} -%\ifmalelabel{\gender}{male}{not male} -%\end{verbatim} -%Similarly to for an allowed female label: -%\begin{definition}[\DescribeMacro{\iffemalelabel}] -%\cs{iffemalelabel}\marg{identifier}\marg{true part}\marg{false part} -%\end{definition} -%For example: -%\begin{verbatim} -%\ifmalelabel{\gender}{Male}{% -% \iffemalelabel{\gender}{Female}% -% {Undefined Gender}% -%} -%\end{verbatim} -% -%\subsubsection{Iterating Through Defined People} +% If \meta{element} is contained in the comma-separated list given +% by \meta{list}, then do \meta{true part} otherwise do false +% part. (Does a one level expansion on \meta{list}, but no +% expansion on \meta{element}.) +% \begin{macrocode} +\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 +% not found + #4% + \else +% found + #3% + \fi +} +% \end{macrocode} +%\end{macro} % -%You can iterate through all defined people using: -%\begin{definition}[\DescribeMacro{\foreachperson}] -%\cs{foreachperson}(\meta{name cs},\meta{full name cs},\meta{gender cs},\meta{label cs})\cs{do}\marg{body} -%\end{definition} -%At each iteration, \meta{name cs}, \meta{full name cs}, -%\meta{gender cs} and \meta{label cs} are set to the current person's -%name, full name, gender and label, respectively. (These arguments -%must all be command names.) Note that the gender is set to -%the definition of \DescribeMacro{\malename}\cs{malename} or -%\DescribeMacro{\femalename}\cs{femalename}, as appropriate.\footnote{Predefined names provided by the \sty{person} package are described -%in \autoref{sec:code:peoplenames}.} Once these -%commands are set, \meta{body} is applied. +%\begin{macro}{\DTLnumitemsinlist} +%\cs{DTLnumitemsinlist}\marg{list}\marg{cmd} +%\end{macro} +% Counts number of non-empty elements in list and stores result in control +% sequence \meta{cmd}. +% \begin{macrocode} +\newcommand*{\DTLnumitemsinlist}[2]{% + \@dtl@tmpcount=0\relax + \@for\@dtl@element:=#1\do{% + \ifdefempty{\@dtl@element}% + {}% + {\advance\@dtl@tmpcount by 1\relax}% + }% + \edef#2{\number\@dtl@tmpcount}% +} +% \end{macrocode} % -%If you only want to iterate through a subset of defined people, -%you can use: +%\begin{macro}{\dtl@choplast} %\begin{definition} -%\cs{foreachperson}(\meta{name cs},\meta{full name cs},\meta{gender cs},\meta{label cs})\cs{in}\marg{list}\cs{do}\marg{body} -%\end{definition} -%where \meta{list} is a comma-separated list of labels. -% -%\subsubsection{Accessing Individual Information} -% -%\begin{definition}[\DescribeMacro{\getpersongender}] -%\cs{getpersongender}\marg{cs}\marg{label} -%\end{definition} -%Gets the gender of the person identified by \meta{label} and -%stores in \meta{cs} (which must be a command name). This -%sets \meta{cs} to the definition of \ics{malename} or -%\ics{femalename} as appropriate. -% -%\begin{definition}[\DescribeMacro{\getpersonname}] -%\cs{getpersonname}\marg{cs}\marg{label} -%\end{definition} -%Gets the name of the person identified by \meta{label} and -%stores in \meta{cs} (which must be a command name). -% -%\begin{definition}[\DescribeMacro{\getpersonfullname}] -%\cs{getpersonfullname}\marg{cs}\marg{label} +% \cs{dtl@choplast}\marg{list}\marg{rest}\marg{last} %\end{definition} -%Gets the full name of the person identified by \meta{label} and -%stores in \meta{cs} (which must be a command name). -% -% \StopEventually{\clearpage\phantomsection -%\addcontentsline{toc}{section}{\refname} -% \DTLbibliography{docbib} -%\addcontentsline{toc}{section}{Acknowledgements} -%\section*{Acknowledgements} -% -%Many thanks to Morten~H\o gholm for suggesting a much more -%efficient way of storing the information in databases which -%has significantly improved the time it takes to \LaTeX\ documents -%containing large databases. -% -%\phantomsection -%\addcontentsline{toc}{section}{Change History}\PrintChanges -%\clearpage -%\phantomsection -%\addcontentsline{toc}{section}{Index}\PrintIndex -%} -% -% -% -%\section{datatool.sty} -%\iffalse +% Chops the last element off a comma separated list, putting the +% last element in the control sequence \meta{last} and putting +% the rest in the control sequence \meta{rest}. The control +% sequence \meta{list} is unchanged. If the list is empty, both +% \meta{last} and \meta{rest} will be empty. % \begin{macrocode} -%<*datatool.sty> +\newcommand*{\dtl@choplast}[3]{% % \end{macrocode} -%\fi -%\label{sec:code:datatool} -%\subsection{Package Declaration} +% Set \meta{rest} to empty: % \begin{macrocode} -\NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{datatool}[2009/11/15 v2.03 (NLCT)] + \let#2\@empty % \end{macrocode} -% Load required packages: +% Set \meta{last} to empty: % \begin{macrocode} -\RequirePackage{xkeyval} -\RequirePackage{ifthen} -\RequirePackage{xfor} -\RequirePackage{fp} -\RequirePackage{substr} + \let#3\@empty % \end{macrocode} -%\changes{2.0}{2009 February 27}{added etex as a required package} +% Iterate through \meta{list}: % \begin{macrocode} -\RequirePackage{etex} + \@for\@dtl@element:=#1\do{% + \ifdefempty{#3}% + {% % \end{macrocode} -% -%\subsection{Package Options} -%\begin{macro}{\@dtl@separator} -% The data separator character (comma by default) is stored in -% \cs{@dtl@separator}. -% This is the separator used in external data files, not in the -% \LaTeX\ code, which always uses a comma separator. +% First iteration, don't set \meta{rest}. % \begin{macrocode} -\newcommand*{\@dtl@separator}{,} + }% + {% + \ifdefempty{#2}% + {% % \end{macrocode} -%\end{macro} -%\begin{macro}{\DTLsetseparator} -%\begin{definition} -%\cs{DTLsetseparator}\marg{char} -%\end{definition} -% The sets \cs{@dtl@separator}, and constructs the relevent macros -% that require this character to be hardcoded into their definition. +% Second iteration, set \meta{rest} to \meta{last} (which is +% currently set to the previous value: % \begin{macrocode} -\newcommand*{\DTLsetseparator}[1]{% -\renewcommand*{\@dtl@separator}{#1}% -\@dtl@construct@lopoffs -} + \expandafter\toks@\expandafter{#3}% + \edef#2{{\the\toks@}}% + }% + {% % \end{macrocode} -%\end{macro} -%\begin{macro}{\DTLsettabseparator} -%\cs{DTLsettabseparator} makes it easier to set a tab separator. +% Subsequent iterations, set \meta{rest} to \meta{rest},\meta{last} +% (\meta{last} is currently set to the previous value): % \begin{macrocode} -\begingroup -\catcode`\ 12 -\gdef\DTLsettabseparator{% - \catcode`\ 12 - \DTLsetseparator{ }% + \expandafter\toks@\expandafter{#3}% + \expandafter\@dtl@toks\expandafter{#2}% + \edef#2{\the\@dtl@toks,{\the\toks@}}% + }% + }% +% \end{macrocode} +% Now set \meta{last} to current element. +% \begin{macrocode} + \let#3=\@dtl@element% + }% } -\endgroup % \end{macrocode} %\end{macro} % -%\begin{macro}{\@dtl@delimiter} -% The data delimiter character (double quote by default) is stored -% in \cs{@dtl@delimiter}. This is used in external data files, not -% in the \LaTeX\ code. +%\begin{macro}{\dtl@chopfirst} +%\begin{definition} +% \cs{dtl@chopfirst}\marg{list}\marg{first}\marg{rest} +%\end{definition} +% Chops first element off \meta{list} and store in \meta{first}. +% The remainder of the list is stored in \meta{rest}. (\meta{list} +% remains unchanged.) % \begin{macrocode} -\begingroup -\catcode`\"12\relax -\gdef\@dtl@delimiter{"} -\endgroup +\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 +} % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLsetdelimiter} +% +%\begin{macro}{\dtl@sortlist} %\begin{definition} -%\cs{DTLsetdelimiter}\marg{char} +% \cs{dtl@sortlist}\marg{list}\marg{criteria cmd} %\end{definition} -% This sets the delimiter. +% Performs an insertion sort on \meta{list}, where \meta{criteria cmd} +% is a macro which takes two arguments \meta{a} and \meta{b}. +% \meta{criteria cmd} must set the count register \cs{dtl@sortresult} +% to either -1 (\meta{a} less than \meta{b}), 0 (\meta{a} is +% equal to \meta{b}) or 1 (\meta{a} is greater than \meta{b}.) % \begin{macrocode} -\newcommand*\DTLsetdelimiter[1]{% -\renewcommand*{\@dtl@delimiter}{#1}% -\@dtl@construct@lopoffs} +\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 +} % \end{macrocode} %\end{macro} % -%\begin{macro}{\@dtl@construct@lopoff} +%\begin{macro}{\dtl@insertinto} %\begin{definition} -%\cs{@dtl@construct@lopoff}\meta{separator char}\meta{delimiter char} +% \cs{dtl@insertinto}\marg{element}\marg{sorted-list}\marg{criteria cmd} %\end{definition} -% This defines -%\begin{definition} -% \cs{@dtl@lopoff}\meta{first element}\meta{sep}\meta{rest of list}\cs{to}\meta{cmd1}\meta{cmd2} -%\end{definition}\noindent -%for the current separator and delimiter. +% Inserts \meta{element} into the sorted list \meta{sorted-list} +% according to the criteria given by \meta{criteria cmd} (see above.) % \begin{macrocode} -\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 -}} +\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 + \ifdefempty{\@dtl@newsortedlist}% + {% + \expandafter\toks@\expandafter{\@dtl@newstuff}% + \edef\@dtl@newsortedlist{\the\toks@}% + }% + {% + \expandafter\toks@\expandafter{\@dtl@newsortedlist}% + \expandafter\@dtl@toks\expandafter{\@dtl@newstuff}% + \edef\@dtl@newsortedlist{\the\toks@,\the\@dtl@toks}% + }% + \@endforfalse + }% + \ifdefempty{\@dtl@newsortedlist}% + {% + \@dtl@toks{#1}% + \edef\@dtl@newsortedlist{{\the\@dtl@toks}}% + }% + {% + \if@dtl@insertdone + \else + \expandafter\toks@\expandafter{\@dtl@newsortedlist}% + \@dtl@toks{#1}% + \edef\@dtl@newsortedlist{\the\toks@,{\the\@dtl@toks}}% + \fi + }% + \global\let#2=\@dtl@newsortedlist +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\if@dtl@insertdone} +% Define conditional to indicate whether the new entry has +% been inserted into the sorted list. +% \begin{macrocode} +\newif\if@dtl@insertdone +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtl@sortresult} +% Define \cs{dtl@sortresult} to be set by comparison macro. +% \begin{macrocode} +\newcount\dtl@sortresult % \end{macrocode} %\end{macro} % -%\begin{macro}{\@dtl@construct@qlopoff} +% \subsection{General Token Utilities} +%\begin{macro}{\toks@gput@right@cx} %\begin{definition} -% \cs{@dtl@construct@qlopoff}\meta{separator char}\meta{delimiter char} +%\cs{toks@gput@right@cx}\marg{toks name}\marg{stuff} %\end{definition} -% This constructs \cs{@dtl@qlopoff} to be used -% when the entry is surrounded by the current delimiter value. +% Globally appends stuff to token register \cs{}\meta{toks name} % \begin{macrocode} -\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}% -}} +\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}% +} % \end{macrocode} %\end{macro} -%\begin{macro}{\@dtl@construct@lop@ff} +%\begin{macro}{\toks@gconcat@middle@cx} %\begin{definition} -% \cs{@dtl@construct@lop@ff}\meta{separator char} +%\cs{toks@gconcat@middle@cx}\marg{toks name}\marg{before toks}\marg{stuff}\marg{after toks} %\end{definition} -% This constructs \cs{@dtl@lop@ff} to be used when -% the entry isn't surrouded by the delimiter. +% Globally sets token register \cs{}\meta{toks name} to +% the contents of \meta{before toks} concatenated with +% \meta{stuff} (expanded) and the contents of \meta{after toks} % \begin{macrocode} -\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{\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}% +} % \end{macrocode} %\end{macro} % -%\begin{macro}{\@dtl@construct@lopoffs} -%\begin{definition} -%\cs{@dtl@construct@lopoffs} -%\end{definition} -% This constructs all the lopoff macros -% using the given separator and delimiter characters. +%\section{Locale Dependent Information} +% +%\begin{macro}{\@dtl@numgrpsepcount} +% Define count register to count the digits between the number +% group separators. % \begin{macrocode} -\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}% -} +\newcount\@dtl@numgrpsepcount % \end{macrocode} %\end{macro} +% %\begin{macro}{\@dtl@decimal} % The current decimal character is stored in \cs{@dtl@decimal}. % \begin{macrocode} @@ -8117,10 +581,11 @@ options>#2=\textsf{#2}|hyperpage}} % characters. % \begin{macrocode} \newcommand*{\DTLsetnumberchars}[2]{% -\renewcommand*{\@dtl@numbergroupchar}{#1}% -\renewcommand*{\@dtl@decimal}{#2}% -\@dtl@construct@getnums -\@dtl@construct@stripnumgrpchar{#1}} + \renewcommand*{\@dtl@numbergroupchar}{#1}% + \renewcommand*{\@dtl@decimal}{#2}% + \@dtl@construct@getnums + \@dtl@construct@stripnumgrpchar{#1}% +} % \end{macrocode} %\end{macro} % @@ -8132,7 +597,7 @@ options>#2=\textsf{#2}|hyperpage}} % fractional parts from a real number using the decimal character % \meta{char}. % -%\begin{definition} +%\begin{definition}[\DescribeMacro{\DTLconverttodecimal}] % \cs{DTLconverttodecimal}\marg{num}\marg{cmd} %\end{definition} % \cs{DTLconverttodecimal} will convert locale dependent \meta{num} @@ -8143,32 +608,39 @@ options>#2=\textsf{#2}|hyperpage}} % as they form part of the command definitions. % \begin{macrocode} \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}}% + \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\ifdefempty{\noexpand\@dtl@org@currency}% + {% + }% + {% + \noexpand\let\noexpand\@dtl@currency\noexpand\@dtl@org@currency + }% + \noexpand\expandafter + \noexpand\@dtl@getintfrac\noexpand\@dtl@tmp#1\noexpand\relax + \noexpand\edef##2{\noexpand\@dtl@intpart.\noexpand\@dtl@fracpart}% + }% } % \end{macrocode} %\end{macro} @@ -8177,7 +649,8 @@ options>#2=\textsf{#2}|hyperpage}} % decimal character: % \begin{macrocode} \newcommand*{\@dtl@construct@getnums}{% -\expandafter\@dtl@construct@getintfrac\expandafter{\@dtl@decimal}} + \expandafter\@dtl@construct@getintfrac\expandafter{\@dtl@decimal}% +} % \end{macrocode} %\end{macro} % @@ -8187,57 +660,57 @@ options>#2=\textsf{#2}|hyperpage}} % Sets \cs{@dtl@intpart}. % \begin{macrocode} \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}% + \@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}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@dtl@get@int@part} % \begin{macrocode} \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\$% + \def\@dtl@argi{#1}% + \def\@dtl@argii{#2}% + \ifx\protect#1\relax% \let\@dtl@get@nextintpart=\@dtl@get@int@part \else - \ifx-#1% - \multiply\@dtl@tmpcount by -1\relax + \expandafter\ifx\@dtl@argi\$% \let\@dtl@get@nextintpart=\@dtl@get@int@part \else - \if\@dtl@argi+% + \ifx-#1% + \multiply\@dtl@tmpcount by -1\relax \let\@dtl@get@nextintpart=\@dtl@get@int@part \else - \def\@dtl@intpart{#1}% - \ifx.\@dtl@argii - \let\@dtl@get@nextintpart=\@gobble + \if\@dtl@argi+% + \let\@dtl@get@nextintpart=\@dtl@get@int@part \else - \let\@dtl@get@nextintpart=\@dtl@get@next@intpart + \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 -\fi -\@dtl@get@nextintpart#2\relax + \@dtl@get@nextintpart#2\relax } % \end{macrocode} %\end{macro} %\begin{macro}{\@dtl@get@next@intpart} % \begin{macrocode} \def\@dtl@get@next@intpart#1.\relax{% -\edef\@dtl@intpart{\@dtl@intpart#1}% + \edef\@dtl@intpart{\@dtl@intpart#1}% } % \end{macrocode} %\end{macro} @@ -8249,9 +722,9 @@ options>#2=\textsf{#2}|hyperpage}} % Chops trailing zeroes from number given by \meta{cmd}. % \begin{macrocode} \newcommand*{\@dtl@choptrailingzeroes}[1]{% -\def\@dtl@tmpcpz{}% -\expandafter\@dtl@chop@trailingzeroes#1\@nil% -\let#1=\@dtl@tmpcpz + \def\@dtl@tmpcpz{}% + \expandafter\@dtl@chop@trailingzeroes#1\@nil% + \let#1=\@dtl@tmpcpz } % \end{macrocode} %\end{macro} @@ -8262,14 +735,16 @@ options>#2=\textsf{#2}|hyperpage}} % number is put in this control sequence.) % \begin{macrocode} \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 + \dtlifnumeq{#2}{0}% + {% + \edef\@dtl@tmpcpz{\@dtl@tmpcpz#1}% + \let\@dtl@chopzeroesnext=\@dtl@gobbletonil + }% + {% + \edef\@dtl@tmpcpz{\@dtl@tmpcpz#1}% + \let\@dtl@chopzeroesnext=\@dtl@chop@trailingzeroes + }% + \@dtl@chopzeroesnext#2\@nil } % \end{macrocode} %\end{macro} @@ -8288,13 +763,15 @@ options>#2=\textsf{#2}|hyperpage}} % number is in decimal format with full stop as decimal point.) % \begin{macrocode} \newcommand*{\dtl@truncatedecimal}[1]{% -\expandafter\@dtl@truncatedecimal#1.\@nil#1} + \expandafter\@dtl@truncatedecimal#1.\@nil#1% +} % \end{macrocode} %\end{macro} %\begin{macro}{\@dtl@truncatedecimal} % \begin{macrocode} \def\@dtl@truncatedecimal#1.#2\@nil#3{% -\def#3{#1}} + \def#3{#1}% +} % \end{macrocode} %\end{macro} % @@ -8306,12 +783,13 @@ options>#2=\textsf{#2}|hyperpage}} % \meta{cmd}. % \begin{macrocode} \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 + \def\@dtl@stripped{}% + \edef\@dtl@do@stripnumgrpchar{% + \noexpand\@@dtl@strip@numgrpchar#1\@dtl@numbergroupchar + \noexpand\relax + }% + \@dtl@do@stripnumgrpchar + \let#1=\@dtl@stripped } % \end{macrocode} %\end{macro} @@ -8320,19 +798,21 @@ options>#2=\textsf{#2}|hyperpage}} % The following macro constructs \cs{@@dtl@strip@numgrpchar}. % \begin{macrocode} \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 -}% + \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 + }% } % \end{macrocode} %\end{macro} @@ -8346,13 +826,15 @@ options>#2=\textsf{#2}|hyperpage}} % a control sequence. % \begin{macrocode} \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 + \edef\@dtl@tmpdtl{#1}% + \expandafter\@dtl@decimaltolocale\@dtl@tmpdtl.\relax + \dtlifnumeq{\@dtl@fracpart}{0}% + {% + \edef#2{\@dtl@intpart}% + }% + {% + \edef#2{\@dtl@intpart\@dtl@decimal\@dtl@fracpart}% + }% } % \end{macrocode} %\end{macro} @@ -8360,30 +842,30 @@ options>#2=\textsf{#2}|hyperpage}} % Convert the integer part (store in \cs{@dtl@intpart}) % \begin{macrocode} \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 + \@dtl@decimaltolocaleint{#1}% + \def\@dtl@fracpart{#2}% + \ifx\@dtl@fracpart\@empty + \def\@dtl@fracpart{0}% + \else + \@dtl@decimaltolocalefrac#2\relax + \fi } % \end{macrocode} %\end{macro} %\begin{macro}{\@dtl@decimaltolocaleint} % \begin{macrocode} \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 + \@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 } % \end{macrocode} %\end{macro} @@ -8392,36 +874,36 @@ options>#2=\textsf{#2}|hyperpage}} % (increments \cs{@dtl@tmpcount}.) % \begin{macrocode} \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 + \advance\@dtl@tmpcount by 1\relax + \ifx.#2\relax + \let\@dtl@countnext=\@gobble + \else + \let\@dtl@countnext=\@dtl@countdigits + \fi + \@dtl@countnext#2\relax } % \end{macrocode} %\end{macro} %\begin{macro}{\@dtl@decimal@to@localeint} % \begin{macrocode} \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 + \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 } % \end{macrocode} %\end{macro} @@ -8431,8 +913,8 @@ options>#2=\textsf{#2}|hyperpage}} % \begin{macrocode} % \end{macrocode} \def\@dtl@decimaltolocalefrac#1.\relax{% -\def\@dtl@fracpart{#1}% -\@dtl@choptrailingzeroes{\@dtl@fracpart}% + \def\@dtl@fracpart{#1}% + \@dtl@choptrailingzeroes{\@dtl@fracpart}% } %\end{macro} % @@ -8445,120 +927,1282 @@ options>#2=\textsf{#2}|hyperpage}} % a control sequence. % \begin{macrocode} \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 + \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}% + \dtlifnumeq{\@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 + }% + {% + \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 + }% } % \end{macrocode} %\end{macro} % % Set the defaults: % \begin{macrocode} -\@dtl@construct@lopoffs \@dtl@construct@getnums \expandafter\@dtl@construct@stripnumgrpchar\expandafter -{\@dtl@numbergroupchar} + {\@dtl@numbergroupchar} % \end{macrocode} -% Define key for package option \pkgopt{separator}. +% +%\subsection{Currencies} +%\begin{macro}{\@dtl@currencies} +% \cs{@dtl@currencies} stores all known currencies. % \begin{macrocode} -\define@key{datatool.sty}{separator}{% -\DTLsetseparator{#1}} +\newcommand*{\@dtl@currencies}{\$,\pounds} % \end{macrocode} -% Define key for package option \pkgopt{delimiter}. +%\end{macro} +%\begin{macro}{\DTLnewcurrencysymbol} +%\begin{definition} +% \cs{DTLaddcurrency}\marg{symbol} +%\end{definition} +% Adds \meta{symbol} to the list of known currencies % \begin{macrocode} -\define@key{datatool.sty}{delimiter}{% -\DTLsetdelimiter{#1}} +\newcommand*{\DTLnewcurrencysymbol}[1]{% + \expandafter\toks@\expandafter{\@dtl@currencies}% + \@dtl@toks{#1}% + \edef\@dtl@currencies{\the\@dtl@toks,\the\toks@}% +} % \end{macrocode} -% Define key for package option \pkgopt{verbose}. (This also -% switches the \sty{fp} messages on/off) +%\end{macro} +% If any of the following currency commands have been defined, +% add them to the list: % \begin{macrocode} -\define@boolkey{datatool.sty}[dtl]{verbose}[true]{% -\ifdtlverbose \FPmessagestrue\else \FPmessagesfalse\fi} +\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}}% +} % \end{macrocode} -%\begin{macro}{\dtl@message} +%\begin{macro}{\@dtl@standardize@currency} %\begin{definition} -%\cs{dtl@message}\marg{message string} +%\cs{@dtl@standardize@currency}\marg{cmd} %\end{definition} -% Displays message only if the verbose option is set. +% Substitutes the first currency symbol found in \meta{cmd} +% with "\$". This is used when testing text to determine +% if it is currency. The original currency symbol is stored +% in \cs{@dtl@org@currency}, so that it can be replaced later. +% If no currency symbol is found, \cs{@dtl@org@currency} will +% be empty. % \begin{macrocode} -\newcommand*{\dtl@message}[1]{% -\ifdtlverbose\typeout{#1}\fi} +\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 + \ifdefempty{\@dtl@replaced}% + {% + }% + {% + \let\@dtl@org@currency=\@dtl@replaced + \@endfortrue + }% + }% + \@endforfalse +} % \end{macrocode} %\end{macro} -% Process package options: +% +%\begin{macro}{\@dtl@currency} +%\cs{@dtl@currency} is set by \cs{DTLlocaltodecimal} and +%\cs{@dtl@checknumerical}. It is used by \cs{DTLdecimaltocurrency}. +% Set to "\$" by default. % \begin{macrocode} -\ProcessOptionsX +\newcommand*{\@dtl@currency}{\$} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLsetdefaultcurrency} +%\cs{DTLsetdefaultcurrency}\marg{symbol} sets the default currency. +% \begin{macrocode} +\newcommand*{\DTLsetdefaultcurrency}[1]{% + \renewcommand*{\@dtl@currency}{#1}% +} % \end{macrocode} +%\end{macro} % -%\begin{macro}{\DTLpar} -% Many of the commands used by this package are short commands. -% This means that you can't use \cs{par} -% in the data. To get around this, define the robust command -% \cs{DTLpar} to use instead. +% \section{Floating Point Arithmetic} +% The commands defined in this section all use the equivalent +% commands provided by the \sty{fp} or \sty{pgfmath} packages, but +% first convert the decimal number into the required format. +% +%\begin{macro}{\DTLadd} +%\begin{definition} +% \cs{DTLadd}\marg{cmd}\marg{num1}\marg{num2} +%\end{definition} +% Sets \meta{cmd} = \meta{num1} + \meta{num2} % \begin{macrocode} -\DeclareRobustCommand\DTLpar{\@par} +\newcommand*{\DTLadd}[3]{% + \DTLconverttodecimal{#2}{\@dtl@numi}% + \DTLconverttodecimal{#3}{\@dtl@numii}% + \dtladd{\@dtl@tmp}{\@dtl@numi}{\@dtl@numii}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@tmp}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLgadd} +% Global version +% \begin{macrocode} +\newcommand*{\DTLgadd}[3]{% + \DTLadd{\@dtl@tmpii}{#2}{#3}% + \global\let#1=\@dtl@tmpii +} % \end{macrocode} %\end{macro} % -% \subsection{Determining Data Types} -% The control sequence \cs{@dtl@checknumerical} checks the data -% type of its argument, and sets \cs{@dtl@datatype} to 0 if -% the argument is a string, 1 if the argument is an integer -% or 2 if the argument is a real number. First define -% \cs{@dtl@datatype}: -%\begin{macro}{\@dtl@datatype} +%\begin{macro}{\DTLaddall} +%\begin{definition} +%\cs{DTLaddall}\marg{cmd}\marg{num list} +%\end{definition} +% Sums all the values in \meta{num list} and stores in +% \meta{cmd} which must be a control sequence. +%\changes{1.01}{2007 Aug 17}{removed extraneous space} % \begin{macrocode} -\newcount\@dtl@datatype +\newcommand*{\DTLaddall}[2]{% + \def\@dtl@sum{0}% + \@for\dtl@thisval:=#2\do{% + \expandafter\DTLconverttodecimal\expandafter{\dtl@thisval}{\@dtl@num}% + \dtladd{\@dtl@sum}{\@dtl@sum}{\@dtl@num}% + }% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@sum}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@sum}{#1}% + }% +} % \end{macrocode} %\end{macro} -%\begin{macro}{\@dtl@tmpcount} -% Define temporary count register +%\begin{macro}{\DTLgaddall} +%\begin{definition} +%\cs{DTLgaddall}\marg{cmd}\marg{num list} +%\end{definition} +% Global version % \begin{macrocode} -\newcount\@dtl@tmpcount +\newcommand*{\DTLgaddall}[2]{% + \DTLaddall{\@dtl@tmpi}{#2}% + \global\let#1=\@dtl@tmpi +} % \end{macrocode} %\end{macro} -%\begin{macro}{\dtl@tmplength} -% Define temporary length register: +% +%\begin{macro}{\DTLsub} +%\begin{definition} +% \cs{DTLsub}\marg{cmd}\marg{num1}\marg{num2} +%\end{definition} +% Sets \meta{cmd} = \meta{num1} - \meta{num2} % \begin{macrocode} -\newlength\dtl@tmplength +\newcommand*{\DTLsub}[3]{% + \DTLconverttodecimal{#2}{\@dtl@numi}% + \DTLconverttodecimal{#3}{\@dtl@numii}% + \dtlsub{\@dtl@tmp}{\@dtl@numi}{\@dtl@numii}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@tmp}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLgsub} +% Global version +% \begin{macrocode} +\newcommand*{\DTLgsub}[3]{% + \DTLsub{\@dtl@tmpii}{#2}{#3}% + \global\let#1=\@dtl@tmpii +} % \end{macrocode} %\end{macro} % -%\begin{macro}{\@dtl@numgrpsepcount} -% Define count register to count the digits between the number -% group separators. +%\begin{macro}{\DTLmul} +%\begin{definition} +% \cs{DTLmul}\marg{cmd}\marg{num1}\marg{num2} +%\end{definition} +% Sets \meta{cmd} = \meta{num1} $\times$ \meta{num2} % \begin{macrocode} -\newcount\@dtl@numgrpsepcount +\newcommand*{\DTLmul}[3]{% + \let\@dtl@thisreplaced=\@empty + \DTLconverttodecimal{#2}{\@dtl@numi}% + \ifdefempty{\@dtl@replaced}% + {% + }% + {% + \let\@dtl@thisreplaced=\@dtl@replaced + }% + \DTLconverttodecimal{#3}{\@dtl@numii}% + \ifdefempty{\@dtl@replaced}% + {% + }% + {% + \let\@dtl@thisreplaced=\@dtl@replaced + }% + \dtlmul{\@dtl@tmp}{\@dtl@numi}{\@dtl@numii}% + \ifdefempty{\@dtl@thisreplaced}% + {% + \DTLdecimaltolocale{\@dtl@tmp}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLgmul} +% Global version +% \begin{macrocode} +\newcommand*{\DTLgmul}[3]{% + \DTLmul{\@dtl@tmpii}{#2}{#3}% + \global\let#1=\@dtl@tmpii +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLdiv} +%\begin{definition} +% \cs{DTLdiv}\marg{cmd}\marg{num1}\marg{num2} +%\end{definition} +% Sets \meta{cmd} = \meta{num1} / \meta{num2} +% \begin{macrocode} +\newcommand*{\DTLdiv}[3]{% + \let\@dtl@thisreplaced=\@empty + \DTLconverttodecimal{#2}{\@dtl@numi}% + \ifdefempty{\@dtl@replaced}% + {% + }% + {% + \let\@dtl@thisreplaced=\@dtl@replaced + }% + \DTLconverttodecimal{#3}{\@dtl@numii}% + \dtldiv{\@dtl@tmp}{\@dtl@numi}{\@dtl@numii}% + \ifdefempty{\@dtl@thisreplaced}% + {% + \DTLdecimaltolocale{\@dtl@tmp}{#1}% + }% + {% + \ifdefequal{\@dtl@thisreplaced}{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@tmp}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + }% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLgdiv} +% Global version +% \begin{macrocode} +\newcommand*{\DTLgdiv}[3]{% + \DTLdiv{\@dtl@tmpii}{#2}{#3}% + \global\let#1=\@dtl@tmpii +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLabs} +%\begin{definition} +% \cs{DTLabs}\marg{cmd}\marg{num} +%\end{definition} +% Sets \meta{cmd} = abs(\meta{num}) +% \begin{macrocode} +\newcommand*{\DTLabs}[2]{% + \DTLconverttodecimal{#2}{\@dtl@numi}% + \dtlabs{\@dtl@tmp}{\@dtl@numi}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@tmp}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLgabs} +% Global version +% \begin{macrocode} +\newcommand*{\DTLgabs}[2]{% + \DTLabs{\@dtl@tmpii}{#2}% + \global\let#1=\@dtl@tmpii +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLneg} +%\begin{definition} +% \cs{DTLneg}\marg{cmd}\marg{num} +%\end{definition} +% Sets \meta{cmd} = -\meta{num} +% \begin{macrocode} +\newcommand*{\DTLneg}[2]{% + \DTLconverttodecimal{#2}{\@dtl@numi}% + \dtlneg{\@dtl@tmp}{\@dtl@numi}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@tmp}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLgneg} +% Global version +% \begin{macrocode} +\newcommand*{\DTLgneg}[2]{% + \DTLneg{\@dtl@tmpii}{#2}% + \global\let#1=\@dtl@tmpii +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLsqrt} +%\begin{definition} +% \cs{DTLsqrt}\marg{cmd}\marg{num} +%\end{definition} +% Sets \meta{cmd} = sqrt(\meta{num}) +% \begin{macrocode} +\newcommand*{\DTLsqrt}[2]{% + \DTLconverttodecimal{#2}{\@dtl@numi}% + \dtlroot{\@dtl@tmpi}{\@dtl@numi}{2}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@tmpi}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@tmpi}{#1}% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLgsqrt} +% Global version +% \begin{macrocode} +\newcommand*{\DTLgsqrt}[2]{% +\DTLsqrt{\@dtl@tmpii}{#2}% +\global\let#1=\@dtl@tmpii +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLmin} +%\begin{definition} +% \cs{DTLmin}\marg{cmd}\marg{num1}\marg{num2} +%\end{definition} +% Sets \meta{cmd} = min(\meta{num1}, \meta{num2}) +% \begin{macrocode} +\newcommand*{\DTLmin}[3]{% + \DTLconverttodecimal{#2}{\@dtl@numi}% + \DTLconverttodecimal{#3}{\@dtl@numii}% + \dtlifnumlt{\@dtl@numi}{\@dtl@numii}% + {% + \dtl@ifsingle{#2}% + {\let#1=#2}% + {\def#1{#2}}% + }% + {% + \dtl@ifsingle{#3}% + {\let#1=#3}% + {\def#1{#3}}% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLgmin} +% Global version +% \begin{macrocode} +\newcommand*{\DTLgmin}[3]{% + \DTLmin{\@dtl@tmpii}{#2}{#3}% + \global\let#1=\@dtl@tmpii +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLminall} +%\begin{definition} +%\cs{DTLminall}\marg{cmd}\marg{num list} +%\end{definition} +% Finds the minimum value in \meta{num list} and stores in +% \meta{cmd} which must be a control sequence. +%\changes{1.01}{2007 Aug 17}{removed extraneous space} +% \begin{macrocode} +\newcommand*{\DTLminall}[2]{% + \let\@dtl@min=\@empty + \@for\dtl@thisval:=#2\do{% + \expandafter\DTLconverttodecimal\expandafter{\dtl@thisval}{\@dtl@num}% + \ifdefempty{\@dtl@min}% + {% + \let\@dtl@min=\@dtl@num + }% + {% + \dtlmin{\@dtl@min}{\@dtl@min}{\@dtl@num}% + }% + }% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@min}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@min}{#1}% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLgminall} +%\begin{definition} +%\cs{DTLgminall}\marg{cmd}\marg{num list} +%\end{definition} +% Global version +% \begin{macrocode} +\newcommand*{\DTLgminall}[2]{% + \DTLminall{\@dtl@tmpi}{#2}% + \global\let#1=\@dtl@tmpi +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLmax} +%\begin{definition} +% \cs{DTLmax}\marg{cmd}\marg{num1}\marg{num2} +%\end{definition} +% Sets \meta{cmd} = max(\meta{num1}, \meta{num2}) +% \begin{macrocode} +\newcommand*{\DTLmax}[3]{% + \DTLconverttodecimal{#2}{\@dtl@numi}% + \DTLconverttodecimal{#3}{\@dtl@numii}% + \dtlmax{\@dtl@tmp}{\@dtl@numi}{\@dtl@numii}% + \dtlifnumgt{\@dtl@numi}{\@dtl@numii}% + {% + \dtl@ifsingle{#2}% + {\let#1=#2}% + {\def#1{#2}}% + }% + {% + \dtl@ifsingle{#3}% + {\let#1=#3}% + {\def#1{#3}}% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLgmax} +% Global version +% \begin{macrocode} +\newcommand*{\DTLgmax}[3]{% + \DTLmax{\@dtl@tmpii}{#2}{#3}% + \global\let#1=\@dtl@tmpii +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLmaxall} +%\begin{definition} +%\cs{DTLmaxall}\marg{cmd}\marg{num list} +%\end{definition} +% Finds the maximum value in \meta{num list} and stores in +% \meta{cmd} which must be a control sequence. +%\changes{1.01}{2007 Aug 17}{removed extraneous space} +% \begin{macrocode} +\newcommand*{\DTLmaxall}[2]{% + \let\@dtl@max=\@empty + \@for\dtl@thisval:=#2\do{% + \expandafter\DTLconverttodecimal\expandafter{\dtl@thisval}{\@dtl@num}% + \ifdefempty{\@dtl@max}% + {% + \let\@dtl@max\@dtl@num + }% + {% + \dtlmax{\@dtl@max}{\@dtl@max}{\@dtl@num}% + }% + }% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@max}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@max}{#1}% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLgmaxall} +%\begin{definition} +%\cs{DTLgmaxall}\marg{cmd}\marg{num list} +%\end{definition} +% Global version +% \begin{macrocode} +\newcommand*{\DTLgmaxall}[2]{% +\DTLmaxall{\@dtl@tmpi}{#2}% +\global\let#1=\@dtl@tmpi +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLmeanforall} +%\begin{definition} +%\cs{DTLmeanforall}\marg{cmd}\marg{num list} +%\end{definition} +% Computes the arithmetic mean of all the values in \meta{num list} +% and stores in \meta{cmd} which must be a control sequence. +%\changes{1.01}{2007 Aug 17}{removed extraneous space} +% \begin{macrocode} +\newcommand*{\DTLmeanforall}[2]{% + \def\@dtl@mean{0}% + \def\@dtl@n{0}% + \@for\dtl@thisval:=#2\do{% + \expandafter\DTLconverttodecimal\expandafter{\dtl@thisval}{\@dtl@num}% + \dtladd{\@dtl@mean}{\@dtl@mean}{\@dtl@num}% + \dtladd{\@dtl@n}{\@dtl@n}{1}% + }% + \dtldiv{\@dtl@mean}{\@dtl@mean}{\@dtl@n}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@mean}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@mean}{#1}% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLgmeanforall} +%\begin{definition} +%\cs{DTLgmeanforall}\marg{cmd}\marg{num list} +%\end{definition} +% Global version +% \begin{macrocode} +\newcommand*{\DTLgmeanforall}[2]{% + \DTLmeanforall{\@dtl@tmpi}{#2}% + \global\let#1=\@dtl@tmpi +} % \end{macrocode} %\end{macro} % +%\begin{macro}{\DTLvarianceforall} +%\begin{definition} +%\cs{DTLvarianceforall}\marg{cmd}\marg{num list} +%\end{definition} +% Computes the variance of all the values in \meta{num list} +% and stores in \meta{cmd} which must be a control sequence. +%\changes{1.01}{2007 Aug 17}{fixed bug} +%\changes{1.01}{2007 Aug 17}{removed extraneous space} +% \begin{macrocode} +\newcommand*{\DTLvarianceforall}[2]{% + \def\@dtl@mean{0}% + \def\@dtl@n{0}% + \let\@dtl@decvals=\@empty + \@for\dtl@thisval:=#2\do{% + \expandafter\DTLconverttodecimal\expandafter{\dtl@thisval}{\@dtl@num}% + \ifdefempty{\@dtl@decvals}% + {% + \let\@dtl@decvals=\@dtl@num + }% + {% + \expandafter\toks@\expandafter{\@dtl@decvals}% + \edef\@dtl@decvals{\the\toks@,\@dtl@num}% + }% + \dtladd{\@dtl@mean}{\@dtl@mean}{\@dtl@num}% + \dtladd{\@dtl@n}{\@dtl@n}{1}% + }% + \dtldiv{\@dtl@mean}{\@dtl@mean}{\@dtl@n}% + \def\@dtl@var{0}% + \@for\@dtl@num:=\@dtl@decvals\do{% + \dtlsub{\@dtl@diff}{\@dtl@num}{\@dtl@mean}% + \dtlmul{\@dtl@diff}{\@dtl@diff}{\@dtl@diff}% + \dtladd{\@dtl@var}{\@dtl@var}{\@dtl@diff}% + }% + \dtldiv{\@dtl@var}{\@dtl@var}{\@dtl@n}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@var}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@var}{#1}% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLgvarianceforall} +%\begin{definition} +%\cs{DTLgvarianceforall}\marg{cmd}\marg{num list} +%\end{definition} +% Global version +% \begin{macrocode} +\newcommand*{\DTLgvarianceforall}[2]{% + \DTLvarianceforall{\@dtl@tmpi}{#2}% + \global\let#1=\@dtl@tmpi +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLsdforall} +%\begin{definition} +%\cs{DTLsdforall}\marg{cmd}\marg{num list} +%\end{definition} +% Computes the standard deviation of all the values in \meta{num list} +% and stores in \meta{cmd} which must be a control sequence. +%\changes{1.01}{2007 Aug 17}{fixed bug} +%\changes{1.01}{2007 Aug 17}{removed extraneous space} +% \begin{macrocode} +\newcommand*{\DTLsdforall}[2]{% + \def\@dtl@mean{0}% + \def\@dtl@n{0}% + \let\@dtl@decvals=\@empty + \@for\dtl@thisval:=#2\do{% + \expandafter\DTLconverttodecimal\expandafter{\dtl@thisval}{\@dtl@num}% + \ifdefempty{\@dtl@decvals}% + {% + \let\@dtl@decvals=\@dtl@num + }% + {% + \expandafter\toks@\expandafter{\@dtl@decvals}% + \edef\@dtl@decvals{\the\toks@,\@dtl@num}% + }% + \dtladd{\@dtl@mean}{\@dtl@mean}{\@dtl@num}% + \dtladd{\@dtl@n}{\@dtl@n}{1}% + }% + \dtldiv{\@dtl@mean}{\@dtl@mean}{\@dtl@n}% + \def\@dtl@sd{0}% + \@for\@dtl@num:=\@dtl@decvals\do{% + \dtlsub{\@dtl@diff}{\@dtl@num}{\@dtl@mean}% + \dtlmul{\@dtl@diff}{\@dtl@diff}{\@dtl@diff}% + \dtladd{\@dtl@sd}{\@dtl@sd}{\@dtl@diff}% + }% + \dtldiv{\@dtl@sd}{\@dtl@sd}{\@dtl@n}% + \dtlroot{\@dtl@sd}{\@dtl@sd}{2}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@sd}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@sd}{#1}% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLgsdforall} +%\begin{definition} +%\cs{DTLgsdforall}\marg{cmd}\marg{num list} +%\end{definition} +% Global version +% \begin{macrocode} +\newcommand*{\DTLgsdforall}[2]{% + \DTLsdforall{\@dtl@tmpi}{#2}% + \global\let#1=\@dtl@tmpi +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLround} +%\begin{definition} +% \cs{DTLround}\marg{cmd}\marg{num}\marg{num digits} +%\end{definition} +% Sets \meta{cmd} to \meta{num} rounded to \meta{num digits} +% digits after the decimal character. +% \begin{macrocode} +\newcommand*{\DTLround}[3]{% + \DTLconverttodecimal{#2}{\@dtl@numi}% + \dtlround{\@dtl@tmp}{\@dtl@numi}{#3}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@tmp}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLground} +% Global version +% \begin{macrocode} +\newcommand*{\DTLground}[3]{% + \DTLround{\@dtl@tmpii}{#2}{#3}% + \global\let#1=\@dtl@tmpii +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLtrunc} +%\begin{definition} +% \cs{DTLtrunc}\marg{cmd}\marg{num}\marg{num digits} +%\end{definition} +% Sets \meta{cmd} to \meta{num} truncated to \meta{num digits} +% digits after the decimal character. +% \begin{macrocode} +\newcommand*{\DTLtrunc}[3]{% + \DTLconverttodecimal{#2}{\@dtl@numi}% + \dtltrunc{\@dtl@tmp}{\@dtl@numi}{#3}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@tmp}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLgtrunc} +% Global version +% \begin{macrocode} +\newcommand*{\DTLgtrunc}[3]{% + \DTLtrunc{\@dtl@tmpii}{#2}{#3}% + \global\let#1=\@dtl@tmpii +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLclip} +%\begin{definition} +% \cs{DTLclip}\marg{cmd}\marg{num} +%\end{definition} +% Sets \meta{cmd} to \meta{num} with all unnecessary 0's removed. +% \begin{macrocode} +\newcommand*{\DTLclip}[2]{% + \DTLconverttodecimal{#2}{\@dtl@numi}% + \dtlclip{\@dtl@tmp}{\@dtl@numi}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@tmp}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLgclip} +% Global version +% \begin{macrocode} +\newcommand*{\DTLgclip}[3]{% + \DTLclip{\@dtl@tmpii}{#2}% + \global\let#1=\@dtl@tmpii +} +% \end{macrocode} +%\end{macro} +% +%\section{String Macros} +%\begin{macro}{\DTLinitials} +%\begin{definition} +%\cs{DTLinitials}\marg{string} +%\end{definition} +% Convert a string into initials. +% (Any "~" character found is first converted into a space.) +%\changes{1.01}{2007 Aug 17}{now works with unbreakable space symbol} +%\changes{1.01}{2007 Aug 17}{now uses \cs{DTLinitialhyphen}} +% \begin{macrocode} +\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 +}% +% \end{macrocode} +%\end{macro} +% The following substitutes "\protect \nobreakspace {}" with +% a space. (Note that in this case the space following +% "\nobreakspace" forms part of the command.) +% \begin{macrocode} +\edef\dtl@construct@subnobrsp{% +% \end{macrocode} +% Define \ics{@dtl@subnobrsp} +% \begin{macrocode} + \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 + }% +% \end{macrocode} +% Define \ics{dtl@subnobrsp} +% \begin{macrocode} + \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 +% \end{macrocode} +% +%\begin{macro}{\DTLstoreinitials} +%\begin{definition} +%\cs{DTLstoreinitials}\marg{string}\marg{cmd} +%\end{definition} +% Convert a string into initials and store in \meta{cmd}. +% (Any "~" character found is first converted into a space.) +%\changes{1.01}{2007 Aug 17}{now works with unbreakable space symbol} +%\changes{1.01}{2007 Aug 17}{now uses \cs{DTLinitialhyphen}} +% \begin{macrocode} +\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 +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtl@initials} +% \begin{macrocode} +\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 +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\@dtl@initials} +% \begin{macrocode} +\def\@dtl@initials#1#2 #3{% + \dtl@initialshyphen#2-{}\dtl@endhyp + \expandafter\@dtl@toks\expandafter{\dtl@initialscmd}% + \toks@{#1}% + \ifdefempty{\dtl@inithyphen}% + {% + }% + {% + \edef\dtl@initialscmd{\the\@dtl@toks\the\toks@}% + \expandafter\@dtl@toks\expandafter{\dtl@initialscmd}% + \expandafter\toks@\expandafter{\dtl@inithyphen}% + }% + \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}% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtl@initialshyphen} +% \begin{macrocode} +\def\dtl@initialshyphen#1-#2#3\dtl@endhyp{% + \def\dtl@inithyphen{#2}% + \ifdefempty{\dtl@inithyphen}% + {% + }% + {% + \edef\dtl@inithyphen{% + \DTLafterinitialbeforehyphen\DTLinitialhyphen#2}% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLafterinitials} +% Defines what to do after the final initial. +% \begin{macrocode} +\newcommand*{\DTLafterinitials}{.} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLbetweeninitials} +% Defines what to do between initials. +% \begin{macrocode} +\newcommand*{\DTLbetweeninitials}{.} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLafterinitialbeforehyphen} +% Defines what to do before a hyphen. +% \begin{macrocode} +\newcommand*{\DTLafterinitialbeforehyphen}{.} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLinitialhyphen} +%Defines what to do at the hyphen +%\changes{1.01}{2007 Aug 17}{new} +% \begin{macrocode} +\newcommand*{\DTLinitialhyphen}{-} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLifAllUpperCase} +%\begin{definition} +%\cs{DTLifAllUpperCase}\marg{string}\marg{true part}\marg{false part} +%\end{definition} +% If \meta{string} only contains uppercase characters do \meta{true +%part}, otherwise do \meta{false part}. +% \begin{macrocode} +\newcommand*{\DTLifAllUpperCase}[3]{% + \protected@edef\dtl@tuc{#1}% + \expandafter\dtl@testifuppercase\dtl@tuc\@nil\relax + \if@dtl@condition#2\else#3\fi +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtl@testifalluppercase} +% \begin{macrocode} +\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 +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtl@test@ifalluppercase} +% \begin{macrocode} +\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 + }% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLifAllLowerCase} +%\begin{definition} +%\cs{DTLifAllLowerCase}\marg{string}\marg{true part}\marg{false part} +%\end{definition} +% If \meta{string} only contains lowercase characters do \meta{true +%part}, otherwise do \meta{false part}. +% \begin{macrocode} +\newcommand*{\DTLifAllLowerCase}[3]{% + \protected@edef\dtl@tlc{#1}% + \expandafter\dtl@testiflowercase\dtl@tlc\@nil\relax + \if@dtl@condition#2\else#3\fi +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtl@testifalllowercase} +% \begin{macrocode} +\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 +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtl@test@ifalllowercase} +% \begin{macrocode} +\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 + }% + }% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLsubstitute} +%\begin{definition} +%\cs{DTLsubstitute}\marg{cmd}\marg{original}\marg{replacement} +%\end{definition} +% Substitutes first occurrence of \meta{original} with +% \marg{replacement} within the string given by \meta{cmd} +% \begin{macrocode} +\newcommand{\DTLsubstitute}[3]{% + \expandafter\DTLsplitstring\expandafter + {#1}{#2}{\@dtl@beforepart}{\@dtl@afterpart}% + \ifdefempty{\@dtl@replaced}% + {% + }% + {% + \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}% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLsplitstring} +%\begin{definition} +%\cs{DTLsplitstring}\marg{string}\marg{split text}\marg{before +%cmd}\marg{after cmd} +%\end{definition} +% Splits string at \meta{split text} stores the pre split text +% in \meta{before cmd} and the post split text in \meta{after cmd}. +%\changes{1.01}{2007 Aug 17}{new} +% \begin{macrocode} +\newcommand*{\DTLsplitstring}[4]{% + \def\dtl@splitstr##1#2##2\@nil{% + \def#3{##1}% + \def#4{##2}% + \ifdefempty{#4}% + {% + \let\@dtl@replaced=\@empty + }% + {% + \def\@dtl@replaced{#2}% + \dtl@split@str##2\@nil + }% + }% + \def\dtl@split@str##1#2\@nil{% + \def#4{##1}}% + \dtl@splitstr#1#2\@nil +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLsubstituteall} +%\begin{definition} +%\cs{DTLsubstituteall}\marg{cmd}\marg{original}\marg{replacement} +%\end{definition} +% Substitutes all occurrences of \meta{original} with +% \marg{replacement} within the string given by \meta{cmd} +%\changes{1.01}{2007 Aug 17}{fixed bug caused when certain commands +% occur in the string} +%\changes{2.10}{2012-07-18}{added \cs{long}} +% \begin{macrocode} +\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}% + \long\edef#1{\the\toks@\the\@dtl@toks}% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\@dtl@dosubstitute} +% Recursive substitution macro. +% \begin{macrocode} +\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}% + \ifdefempty{\@dtl@replaced}% + {% + \let\@dtl@dosubstnext=\@dtl@dosubstitutenoop + }% + {% + \expandafter\toks@\expandafter{\@dtl@splitsubstr}% + \@dtl@toks{#2}% + \edef\@dtl@splitsubstr{\the\toks@\the\@dtl@toks}% + \let\@dtl@dosubstnext=\@dtl@dosubstitute + }% + \@dtl@dosubstnext{#1}{#2}% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\@dtl@dosubstitutenoop} +% Terminates recursive substitution macro. +% \begin{macrocode} +\def\@dtl@dosubstitutenoop#1#2{} +% \end{macrocode} +%\end{macro} +% +%\section{Conditionals} +% +%\begin{macro}{\if@dtl@condition} +% \begin{macrocode} +\newif\if@dtl@condition +% \end{macrocode} +%\end{macro} +% +% \subsection{Determining Data Types} +% The control sequence \cs{@dtl@checknumerical} checks the data +% type of its argument, and sets \cs{@dtl@datatype} to 0 if +% the argument is a string, 1 if the argument is an integer +% or 2 if the argument is a real number. First define +% \cs{@dtl@datatype}: +%\begin{macro}{\@dtl@datatype} +% \begin{macrocode} +\newcount\@dtl@datatype +% \end{macrocode} +%\end{macro} %\begin{macro}{\@dtl@checknumerical} %\begin{definition} %\cs{@dtl@checknumerical}\marg{arg} @@ -8568,33 +2212,37 @@ options>#2=\textsf{#2}|hyperpage}} % Sets \cs{@dtl@datatype}, as described above. % \begin{macrocode} \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 + \@dtl@numgrpsepfalse + \def\@dtl@tmp{#1}% + \ifstrempty{#1}% + {% + \@dtl@datatype=0\relax + }% + {% + \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 + \ifdefempty{\@dtl@org@currency}% + {% + }% + {% + \let\@dtl@currency\@dtl@org@currency + }% + \expandafter\@dtl@checknumericalstart\@dtl@tmp\@nil\@nil + }% + \ifnum\@dtl@numgrpsepcount>-1\relax + \if@dtl@numgrpsep + \ifnum\@dtl@numgrpsepcount=3\relax + \else + \@dtl@datatype=0\relax + \fi \fi \fi -\fi } % \end{macrocode} %\end{macro} @@ -8603,44 +2251,50 @@ options>#2=\textsf{#2}|hyperpage}} % it's a plus or minus sign. % \begin{macrocode} \def\@dtl@checknumericalstart#1#2\@nil\@nil{% -\ifx#1\protect +\ifx#1\protect\relax \@dtl@checknumericalstart#2\@nil\@nil\relax \else \ifx-#1\relax \def\@dtl@tmp{#2}% - \ifx\@empty\@dtl@tmp + \ifdefempty{\@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 + \ifdefempty{\@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 + \ifdefempty{\@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 @@ -8658,54 +2312,20 @@ options>#2=\textsf{#2}|hyperpage}} %\end{macro} %\begin{macro}{\@dtl@ifDigitOrDecimalSep} % Check if argument is either a digit or the decimal separator. +% Rewrite provided by Bruno Le Floch. %\changes{1.01}{2007 Aug 17}{new} +%\changes{2.10}{2012-07-18}{Rewritten} % \begin{macrocode} \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 + \ifnum 9<1\noexpand#1\relax + #2% + \else + \expandafter\ifx\@dtl@decimal#1\relax + #2% + \else + #3% + \fi + \fi } % \end{macrocode} %\end{macro} @@ -8799,8 +2419,8 @@ options>#2=\textsf{#2}|hyperpage}} % otherwise do third argument. % \begin{macrocode} \newcommand{\DTLifreal}[3]{% -\@dtl@checknumerical{#1}% -\ifnum\@dtl@datatype=2\relax #2\else #3\fi + \@dtl@checknumerical{#1}% + \ifnum\@dtl@datatype=2\relax #2\else #3\fi } % \end{macrocode} %\end{macro} @@ -8814,8 +2434,8 @@ options>#2=\textsf{#2}|hyperpage}} % otherwise do third argument. % \begin{macrocode} \newcommand{\DTLifint}[3]{% -\@dtl@checknumerical{#1}% -\ifnum\@dtl@datatype=1\relax #2\else #3\fi + \@dtl@checknumerical{#1}% + \ifnum\@dtl@datatype=1\relax #2\else #3\fi } % \end{macrocode} %\end{macro} @@ -8829,8 +2449,8 @@ options>#2=\textsf{#2}|hyperpage}} % otherwise do third argument. % \begin{macrocode} \newcommand{\DTLifstring}[3]{% -\@dtl@checknumerical{#1}% -\ifnum\@dtl@datatype=0\relax #2\else #3\fi + \@dtl@checknumerical{#1}% + \ifnum\@dtl@datatype=0\relax #2\else #3\fi } % \end{macrocode} %\end{macro} @@ -8844,8 +2464,8 @@ options>#2=\textsf{#2}|hyperpage}} % otherwise do third argument. % \begin{macrocode} \newcommand{\DTLifcurrency}[3]{% -\@dtl@checknumerical{#1}% -\ifnum\@dtl@datatype=3\relax #2\else #3\fi + \@dtl@checknumerical{#1}% + \ifnum\@dtl@datatype=3\relax #2\else #3\fi } % \end{macrocode} %\end{macro} @@ -8860,12 +2480,12 @@ options>#2=\textsf{#2}|hyperpage}} % do fourth argument. % \begin{macrocode} \newcommand*{\DTLifcurrencyunit}[4]{% -\@dtl@checknumerical{#1}% -\ifnum\@dtl@datatype=3\relax - \ifthenelse{\equal{\@dtl@org@currency}{#2}}{#3}{#4}% -\else - #4% -\fi + \@dtl@checknumerical{#1}% + \ifnum\@dtl@datatype=3\relax + \ifthenelse{\equal{\@dtl@org@currency}{#2}}{#3}{#4}% + \else + #4% + \fi } % \end{macrocode} %\end{macro} @@ -8881,16 +2501,16 @@ options>#2=\textsf{#2}|hyperpage}} %case}. % \begin{macrocode} \newcommand{\DTLifcasedatatype}[5]{% -\@dtl@checknumerical{#1}% -\ifcase\@dtl@datatype - #2% string -\or - #3% integer -\or - #4% number -\or - #5% currency -\fi + \@dtl@checknumerical{#1}% + \ifcase\@dtl@datatype + #2% string + \or + #3% integer + \or + #4% number + \or + #5% currency + \fi } % \end{macrocode} %\end{macro} @@ -8903,21 +2523,21 @@ options>#2=\textsf{#2}|hyperpage}} % the conditional \cs{if@dtl@condition}. % \begin{macrocode} \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 + \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 } % \end{macrocode} %\end{macro} @@ -8928,16 +2548,19 @@ options>#2=\textsf{#2}|hyperpage}} %\end{definition} % Determines if \marg{num1} $<$ \marg{num2}. Both numbers % need to have the decimal separator changed to a dot -% to ensure that it works with \cs{FPiflt} +% to ensure that it works with \cs{dtlifnumlt} +%\changes{2.10}{2012-07-18}{changed \cs{FPiflt} to \cs{dtlifnumlt}} % \begin{macrocode} \newcommand*{\DTLifnumlt}[4]{% \DTLconverttodecimal{#1}{\@dtl@numi}% \DTLconverttodecimal{#2}{\@dtl@numii}% - \FPiflt{\@dtl@numi}{\@dtl@numii}% - #3% - \else - #4% - \fi + \dtlifnumlt{\@dtl@numi}{\@dtl@numii}% + {% + #3% + }% + {% + #4% + }% } % \end{macrocode} %\end{macro} @@ -9056,87 +2679,99 @@ options>#2=\textsf{#2}|hyperpage}} % longer using compare.tex)} % \begin{macrocode} \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 + \dtl@subnobrsp{#2}{\@dtl@argA}% + \dtl@subnobrsp{#3}{\@dtl@argB}% + \ifdefempty{\@dtl@argA}% + {% + \ifdefempty{\@dtl@argB}% + {% + #1=0\relax + }% + {% + #1=-1\relax + }% + }% + {% + \ifdefempty{\@dtl@argB}% + {% + #1=1\relax + }% + {% + \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@codeA<\dtl@codeB - #1=-1\relax + \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 + \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 + \ifnum\dtl@codeA>\dtl@codeB + #1=1\relax + \else + \ifdefempty{\dtl@restA}% + {% + \ifdefempty{\dtl@restB}% + {% + #1=0\relax + }% + {% + #1=-1\relax + }% + }% + {% + \ifdefempty{\restB}% + {% + #1=1\relax + }% + {% + \protected@edef\dtl@donext{% + \noexpand\dtlcompare + {\noexpand#1}{\dtl@restA}{\dtl@restB}}% + \dtl@donext + }% + }% + \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 + }{% + \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 + }% } % \end{macrocode} %\end{macro} @@ -9145,12 +2780,14 @@ options>#2=\textsf{#2}|hyperpage}} % is stored in \cs{dtl@rest}. % \begin{macrocode} \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 + \def\dtl@first{#1}% + \ifdefempty{\dtl@first}% + {% + \def\dtl@rest{#2}% + }% + {% + \dtl@ifsingle{#1}{\def\dtl@rest{#2}}{\dtl@getfirst#1#2\end}% + }% } % \end{macrocode} %\end{macro} @@ -9169,24 +2806,25 @@ options>#2=\textsf{#2}|hyperpage}} % to the character code of the space character. % \begin{macrocode} \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 + \ifstrempty{#1}% + {% + #2=-1\relax + }% + {% + \ifx#1\space\relax #2=`\ \relax \else - \ifcat\noexpand#1\relax% - #2=-1\relax + \ifx#1~\relax + #2=`\ \relax \else - #2=`#1\relax + \ifcat\noexpand#1\relax + #2=-1\relax + \else + #2=`#1\relax + \fi \fi \fi - \fi -\fi + }% } % \end{macrocode} %\end{macro} @@ -9201,24 +2839,25 @@ options>#2=\textsf{#2}|hyperpage}} % \cs{dtl@setcharcode}. % \begin{macrocode} \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 + \ifstrempty{#1}% + {% + #2=-1\relax + }% + {% + \ifx#1\space\relax #2=`\ \relax \else - \ifcat\noexpand#1\relax% - #2=-1\relax + \ifx#1~\relax + #2=`\ \relax \else - #2=\lccode`#1\relax + \ifcat\noexpand#1\relax% + #2=-1\relax + \else + #2=\lccode`#1\relax + \fi \fi \fi - \fi -\fi + }% } % \end{macrocode} %\end{macro} @@ -9230,87 +2869,99 @@ options>#2=\textsf{#2}|hyperpage}} %\changes{1.01}{2007 Aug 17}{new} % \begin{macrocode} \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 + \dtl@subnobrsp{#2}{\@dtl@argA}% + \dtl@subnobrsp{#3}{\@dtl@argB}% + \ifdefempty{\@dtl@argA}% + {% + \ifdefempty{\@dtl@argB}% + {% + #1=0\relax + }% + {% + #1=-1\relax + }% + }% + {% + \ifdefempty{\@dtl@argB}% + {% + #1=1\relax + }% + {% + \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@codeA<\dtl@codeB - #1=-1\relax + \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 + \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 + \ifnum\dtl@codeA>\dtl@codeB + #1=1\relax + \else + \ifdefempty{\dtl@restA}% + {% + \ifdefempty{\dtl@restB}% + {% + #1=0\relax + }% + {% + #1=-1\relax + }% + }% + {% + \ifdefempty{\restB}% + {% + #1=1\relax + }% + {% + \protected@edef\dtl@donext{% + \noexpand\dtlicompare + {\noexpand#1}{\dtl@restA}{\dtl@restB}}% + \dtl@donext + }% + }% + \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 + }{% + \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 + }% } % \end{macrocode} %\end{macro} @@ -9327,27 +2978,27 @@ options>#2=\textsf{#2}|hyperpage}} % Unstarred version % \begin{macrocode} \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 + \protected@edef\@dtl@tmpcmp{% + \noexpand\dtlcompare{\noexpand\@dtl@tmpcount}{#1}{#2}}% + \@dtl@tmpcmp + \ifnum\@dtl@tmpcount<0\relax + #3% + \else + #4% + \fi } % \end{macrocode} % Starred version % \begin{macrocode} \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 + \protected@edef\@dtl@tmpcmp{% + \noexpand\dtlicompare{\noexpand\@dtl@tmpcount}{#1}{#2}}% + \@dtl@tmpcmp + \ifnum\@dtl@tmpcount<0\relax + #3% + \else + #4% + \fi } % \end{macrocode} %\end{macro} @@ -9366,23 +3017,23 @@ options>#2=\textsf{#2}|hyperpage}} % Unstarred version % \begin{macrocode} \newcommand*{\@DTLiflt}[4]{% -\dtl@testbothnumerical{#1}{#2}% -\if@dtl@condition - \DTLifnumlt{#1}{#2}{#3}{#4}% -\else - \@DTLifstringlt{#1}{#2}{#3}{#4}% -\fi + \dtl@testbothnumerical{#1}{#2}% + \if@dtl@condition + \DTLifnumlt{#1}{#2}{#3}{#4}% + \else + \@DTLifstringlt{#1}{#2}{#3}{#4}% + \fi } % \end{macrocode} % Starred version % \begin{macrocode} \newcommand*{\@sDTLiflt}[4]{% -\dtl@testbothnumerical{#1}{#2}% -\if@dtl@condition - \DTLifnumlt{#1}{#2}{#3}{#4}% -\else - \@sDTLifstringlt{#1}{#2}{#3}{#4}% -\fi + \dtl@testbothnumerical{#1}{#2}% + \if@dtl@condition + \DTLifnumlt{#1}{#2}{#3}{#4}% + \else + \@sDTLifstringlt{#1}{#2}{#3}{#4}% + \fi } % \end{macrocode} %\end{macro} @@ -9393,16 +3044,19 @@ options>#2=\textsf{#2}|hyperpage}} %\end{definition} % Determines if \marg{num1} $>$ \marg{num2}. Both numbers % need to have the decimal separator changed to a dot -% to ensure that it works with \cs{FPifgt} +% to ensure that it works with \cs{dtlifnumgt} +%\changes{2.10}{2012-07-18}{changed \cs{FPifgt} to \cs{dtlifnumgt}} % \begin{macrocode} \newcommand*{\DTLifnumgt}[4]{% \DTLconverttodecimal{#1}{\@dtl@numi}% \DTLconverttodecimal{#2}{\@dtl@numii}% - \FPifgt{\@dtl@numi}{\@dtl@numii}% - #3% - \else - #4% - \fi + \dtlifnumgt{\@dtl@numi}{\@dtl@numii}% + {% + #3% + }% + {% + #4% + }% } % \end{macrocode} %\end{macro} @@ -9419,27 +3073,27 @@ options>#2=\textsf{#2}|hyperpage}} % Unstarred version % \begin{macrocode} \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 + \protected@edef\@dtl@tmpcmp{% + \noexpand\dtlcompare{\noexpand\@dtl@tmpcount}{#1}{#2}}% + \@dtl@tmpcmp + \ifnum\@dtl@tmpcount>0\relax + #3% + \else + #4% + \fi } % \end{macrocode} % Starred version % \begin{macrocode} \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 + \protected@edef\@dtl@tmpcmp{% + \noexpand\dtlicompare{\noexpand\@dtl@tmpcount}{#1}{#2}}% + \@dtl@tmpcmp + \ifnum\@dtl@tmpcount>0\relax + #3% + \else + #4% + \fi } % \end{macrocode} %\end{macro} @@ -9457,23 +3111,23 @@ options>#2=\textsf{#2}|hyperpage}} % Unstarred version % \begin{macrocode} \newcommand*{\@DTLifgt}[4]{% -\dtl@testbothnumerical{#1}{#2}% -\if@dtl@condition - \DTLifnumgt{#1}{#2}{#3}{#4}% -\else - \@DTLifstringgt{#1}{#2}{#3}{#4}% -\fi + \dtl@testbothnumerical{#1}{#2}% + \if@dtl@condition + \DTLifnumgt{#1}{#2}{#3}{#4}% + \else + \@DTLifstringgt{#1}{#2}{#3}{#4}% + \fi } % \end{macrocode} % Starred version % \begin{macrocode} \newcommand*{\@sDTLifgt}[4]{% -\dtl@testbothnumerical{#1}{#2}% -\if@dtl@condition - \DTLifnumgt{#1}{#2}{#3}{#4}% -\else - \@sDTLifstringgt{#1}{#2}{#3}{#4}% -\fi + \dtl@testbothnumerical{#1}{#2}% + \if@dtl@condition + \DTLifnumgt{#1}{#2}{#3}{#4}% + \else + \@sDTLifstringgt{#1}{#2}{#3}{#4}% + \fi } % \end{macrocode} %\end{macro} @@ -9484,16 +3138,19 @@ options>#2=\textsf{#2}|hyperpage}} %\end{definition} % Determines if \marg{num1} = \marg{num2}. Both numbers % need to have the decimal separator changed to a dot -% to ensure that it works with \cs{FPifeq} +% to ensure that it works with \cs{dtlifnumeq} +%\changes{2.10}{2012-07-18}{changed \cs{FPifeq} to \cs{dtlifnumeq}} % \begin{macrocode} \newcommand*{\DTLifnumeq}[4]{% \DTLconverttodecimal{#1}{\@dtl@numi}% \DTLconverttodecimal{#2}{\@dtl@numii}% - \FPifeq{\@dtl@numi}{\@dtl@numii}% - #3% - \else - #4% - \fi + \dtlifnumeq{\@dtl@numi}{\@dtl@numii}% + {% + #3% + }% + {% + #4% + }% } % \end{macrocode} %\end{macro} @@ -9510,27 +3167,27 @@ options>#2=\textsf{#2}|hyperpage}} % Unstarred version % \begin{macrocode} \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 + \protected@edef\@dtl@tmpcmp{% + \noexpand\dtlcompare{\noexpand\@dtl@tmpcount}{#1}{#2}}% + \@dtl@tmpcmp + \ifnum\@dtl@tmpcount=0\relax + #3% + \else + #4% + \fi } % \end{macrocode} % Starred version % \begin{macrocode} \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 + \protected@edef\@dtl@tmpcmp{% + \noexpand\dtlicompare{\noexpand\@dtl@tmpcount}{#1}{#2}}% + \@dtl@tmpcmp + \ifnum\@dtl@tmpcount=0\relax + #3% + \else + #4% + \fi } % \end{macrocode} %\end{macro} @@ -9548,23 +3205,23 @@ options>#2=\textsf{#2}|hyperpage}} % Unstarred version % \begin{macrocode} \newcommand*{\@DTLifeq}[4]{% -\dtl@testbothnumerical{#1}{#2}% -\if@dtl@condition - \DTLifnumeq{#1}{#2}{#3}{#4}% -\else - \@DTLifstringeq{#1}{#2}{#3}{#4}% -\fi + \dtl@testbothnumerical{#1}{#2}% + \if@dtl@condition + \DTLifnumeq{#1}{#2}{#3}{#4}% + \else + \@DTLifstringeq{#1}{#2}{#3}{#4}% + \fi } % \end{macrocode} % Starred version % \begin{macrocode} \newcommand*{\@sDTLifeq}[4]{% -\dtl@testbothnumerical{#1}{#2}% -\if@dtl@condition - \DTLifnumeq{#1}{#2}{#3}{#4}% -\else - \@sDTLifstringeq{#1}{#2}{#3}{#4}% -\fi + \dtl@testbothnumerical{#1}{#2}% + \if@dtl@condition + \DTLifnumeq{#1}{#2}{#3}{#4}% + \else + \@sDTLifstringeq{#1}{#2}{#3}{#4}% + \fi } % \end{macrocode} %\end{macro} @@ -9579,43 +3236,47 @@ options>#2=\textsf{#2}|hyperpage}} %\changes{1.01}{2007 Aug 17}{new} % \begin{macrocode} \newcommand*{\DTLifSubString}[4]{% -\protected@edef\@dtl@tmp{\noexpand\dtl@testifsubstring -{#1}{#2}}% -\@dtl@tmp -\if@dtl@condition - #3% -\else - #4% -\fi + \protected@edef\@dtl@tmp{\noexpand\dtl@testifsubstring + {#1}{#2}}% + \@dtl@tmp + \if@dtl@condition + #3% + \else + #4% + \fi } % \end{macrocode} %\end{macro} %\begin{macro}{\dtl@testifsubstring} % \begin{macrocode} \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 + \dtl@subnobrsp{#1}{\@dtl@argA}% + \dtl@subnobrsp{#2}{\@dtl@argB}% + \ifdefempty{\@dtl@argB}% + {% + \@dtl@conditiontrue + }% + {% + \ifdefempty{\@dtl@argA}% + {% + \@dtl@conditionfalse + }% + {% + \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 + }% + }% } % \end{macrocode} %\end{macro} @@ -9630,14 +3291,14 @@ options>#2=\textsf{#2}|hyperpage}} %\changes{1.01}{2007 Aug 17}{new} % \begin{macrocode} \newcommand*{\DTLifStartsWith}[4]{% -\@dtl@conditionfalse -\protected@edef\@dtl@tmp{\noexpand\dtl@teststartswith{#1}{#2}}% -\@dtl@tmp -\if@dtl@condition - #3% -\else - #4% -\fi + \@dtl@conditionfalse + \protected@edef\@dtl@tmp{\noexpand\dtl@teststartswith{#1}{#2}}% + \@dtl@tmp + \if@dtl@condition + #3% + \else + #4% + \fi } % \end{macrocode} %\end{macro} @@ -9650,69 +3311,75 @@ options>#2=\textsf{#2}|hyperpage}} % \cs{if@dtl@condition}. % \begin{macrocode} \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 + \dtl@subnobrsp{#1}{\@dtl@argA}% + \dtl@subnobrsp{#2}{\@dtl@argB}% + \ifdefempty{\@dtl@argA}% + {% + \ifdefempty{\@dtl@argB}% + {% + \@dtl@conditiontrue + }% + {% + \@dtl@conditionfalse + }% + }% + {% + \ifdefempty{\@dtl@argB}% + {% + \@dtl@conditiontrue + }% + {% + \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@codeA=\dtl@codeB - \protected@edef\dtl@donext{% - \noexpand\dtl@teststartswith{\dtl@restA}{\dtl@restB}}% - \dtl@donext + \ifnum\dtl@codeB=-1\relax + \protected@edef\dtl@donext{% + \noexpand\dtl@teststartswith + {\dtl@firstA\dtl@restA}{\dtl@restB}}% + \dtl@donext \else - \@dtl@conditionfalse + \ifnum\dtl@codeA=\dtl@codeB + \protected@edef\dtl@donext{% + \noexpand\dtl@teststartswith{\dtl@restA}{\dtl@restB}}% + \dtl@donext + \else + \@dtl@conditionfalse + \fi \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}}% + }{% + \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 + }% } % \end{macrocode} %\end{macro} @@ -9724,10 +3391,10 @@ options>#2=\textsf{#2}|hyperpage}} % Determines if \meta{min} $\leq$ \meta{num} $\leq$ \meta{max}. % \begin{macrocode} \newcommand*{\DTLifnumclosedbetween}[5]{% -\DTLconverttodecimal{#1}{\@dtl@numi}% -\DTLconverttodecimal{#2}{\@dtl@numii}% -\DTLconverttodecimal{#3}{\@dtl@numiii}% -\DTLifFPclosedbetween{\@dtl@numi}{\@dtl@numii}{\@dtl@numiii}{#4}{#5}% + \DTLconverttodecimal{#1}{\@dtl@numi}% + \DTLconverttodecimal{#2}{\@dtl@numii}% + \DTLconverttodecimal{#3}{\@dtl@numiii}% + \DTLifFPclosedbetween{\@dtl@numi}{\@dtl@numii}{\@dtl@numiii}{#4}{#5}% } % \end{macrocode} %\end{macro} @@ -9740,52 +3407,53 @@ options>#2=\textsf{#2}|hyperpage}} %\changes{1.01}{2007 Aug 17}{added starred version} % \begin{macrocode} \newcommand*{\DTLifstringclosedbetween}{% -\@ifstar\@sDTLifstringclosedbetween\@DTLifstringclosedbetween} + \@ifstar\@sDTLifstringclosedbetween\@DTLifstringclosedbetween +} % \end{macrocode} % Unstarred version % \begin{macrocode} \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}}% + \noexpand\dtlcompare{\noexpand\@dtl@tmpcount}{#1}{#2}}% \@dtl@tmpcmp - \ifnum\@dtl@tmpcount>0\relax + \let\@dtl@dovalue\relax + \ifnum\@dtl@tmpcount<0\relax \def\@dtl@dovalue{#5}% - \else - \def\@dtl@dovalue{#4}% \fi -\fi -\@dtl@dovalue + \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 } % \end{macrocode} % Starred version % \begin{macrocode} \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}}% + \noexpand\dtlicompare{\noexpand\@dtl@tmpcount}{#1}{#2}}% \@dtl@tmpcmp - \ifnum\@dtl@tmpcount>0\relax + \let\@dtl@dovalue\relax + \ifnum\@dtl@tmpcount<0\relax \def\@dtl@dovalue{#5}% - \else - \def\@dtl@dovalue{#4}% \fi -\fi -\@dtl@dovalue + \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 } % \end{macrocode} %\end{macro} @@ -9800,44 +3468,45 @@ options>#2=\textsf{#2}|hyperpage}} %\changes{1.01}{2007 Aug 17}{added starred version} % \begin{macrocode} \newcommand*{\DTLifclosedbetween}{% -\@ifstar\@sDTLifclosedbetween\@DTLifclosedbetween} + \@ifstar\@sDTLifclosedbetween\@DTLifclosedbetween +} % \end{macrocode} % Unstarred version % \begin{macrocode} \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}% + \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 -\else - \@DTLifstringclosedbetween{#1}{#2}{#3}{#4}{#5}% -\fi } % \end{macrocode} % Starred version % \begin{macrocode} \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}% + \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 -\else - \@sDTLifstringclosedbetween{#1}{#2}{#3}{#4}{#5}% -\fi } % \end{macrocode} %\end{macro} @@ -9849,10 +3518,10 @@ options>#2=\textsf{#2}|hyperpage}} % Determines if \meta{min} $<$ \meta{num} $<$ \meta{max}. % \begin{macrocode} \newcommand*{\DTLifnumopenbetween}[5]{% -\DTLconverttodecimal{#1}{\@dtl@numi}% -\DTLconverttodecimal{#2}{\@dtl@numii}% -\DTLconverttodecimal{#3}{\@dtl@numiii}% -\DTLifFPopenbetween{\@dtl@numi}{\@dtl@numii}{\@dtl@numiii}{#4}{#5}% + \DTLconverttodecimal{#1}{\@dtl@numi}% + \DTLconverttodecimal{#2}{\@dtl@numii}% + \DTLconverttodecimal{#3}{\@dtl@numiii}% + \DTLifFPopenbetween{\@dtl@numi}{\@dtl@numii}{\@dtl@numiii}{#4}{#5}% } % \end{macrocode} %\end{macro} @@ -9865,54 +3534,55 @@ options>#2=\textsf{#2}|hyperpage}} %\changes{1.01}{2007 Aug 17}{added starred version} % \begin{macrocode} \newcommand*{\DTLifstringopenbetween}{% -\@ifstar\@sDTLifstringopenbetween\@DTLifstringopenbetween} + \@ifstar\@sDTLifstringopenbetween\@DTLifstringopenbetween +} % \end{macrocode} % Unstarred version: % \begin{macrocode} \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}}% + \noexpand\dtlcompare{\noexpand\@dtl@tmpcount}{#1}{#2}}% \@dtl@tmpcmp - \ifnum\@dtl@tmpcount<0\relax - \def\@dtl@dovalue{#4}% + \let\@dtl@dovalue\relax + \ifnum\@dtl@tmpcount>0\relax \else \def\@dtl@dovalue{#5}% \fi -\fi -\@dtl@dovalue + \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 } % \end{macrocode} % Starred version % \begin{macrocode} \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}}% + \noexpand\dtlicompare{\noexpand\@dtl@tmpcount}{#1}{#2}}% \@dtl@tmpcmp - \ifnum\@dtl@tmpcount<0\relax - \def\@dtl@dovalue{#4}% + \let\@dtl@dovalue\relax + \ifnum\@dtl@tmpcount>0\relax \else \def\@dtl@dovalue{#5}% \fi -\fi -\@dtl@dovalue + \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 } % \end{macrocode} %\end{macro} @@ -9927,44 +3597,45 @@ options>#2=\textsf{#2}|hyperpage}} %\changes{1.01}{2007 Aug 17}{added starred version} % \begin{macrocode} \newcommand*{\DTLifopenbetween}{% -\@ifstar\@sDTLifopenbetween\@DTLifopenbetween} + \@ifstar\@sDTLifopenbetween\@DTLifopenbetween +} % \end{macrocode} % Unstarred version % \begin{macrocode} \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}% + \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 -\else - \@DTLifstringopenbetween{#1}{#2}{#3}{#4}{#5}% -\fi } % \end{macrocode} % Starred version % \begin{macrocode} \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}% + \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 -\else - \@sDTLifstringopenbetween{#1}{#2}{#3}{#4}{#5}% -\fi } % \end{macrocode} %\end{macro} @@ -9975,22 +3646,9 @@ options>#2=\textsf{#2}|hyperpage}} %\end{definition} % Determines if \meta{min} $<$ \meta{num} $<$ \meta{max} where % all arguments are in standard fixed point notation. +% (Command name maintained for backward compatibility.) % \begin{macrocode} -\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 -} +\let\DTLifFPopenbetween\dtlifnumopenbetween % \end{macrocode} %\end{macro} % @@ -9999,98 +3657,16 @@ options>#2=\textsf{#2}|hyperpage}} %\cs{DTLifFPclosedbetween}\marg{num}\marg{min}\marg{max}\marg{true part}\marg{false part} %\end{definition} % Determines if \meta{min} $\leq$ \meta{num} $\leq$ \meta{max}. +% (Command name maintained for backward compatibility.) % \begin{macrocode} -\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 -} -% \end{macrocode} -%\end{macro} -% -% The following conditionals are only meant to be used within -% \cs{DTLforeach} as they depend on the counter -% \texttt{DTLrow}\meta{n}. -% -%\begin{macro}{\DTLiffirstrow} -%\begin{definition} -%\cs{DTLiffirstrow}\marg{true part}\marg{false part} -%\end{definition} -% Test if the current row is the first row. (This takes -% \meta{condition}, the optional argument of \cs{DTLforeach}, -% into account, so it may not correspond to row~1 of the -% database.) Can only be used in \cs{DTLforeachrow}. -%\changes{2.0}{2009 February 27}{modified to have different -% definition depending on location} -% \begin{macrocode} -\newcommand{\DTLiffirstrow}[2]{% - \PackageError{datatool}{\string\DTLiffirstrow\space can only - be used inside \string\DTLforeach}{}% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLiflastrow} -%\begin{definition} -%\cs{DTLiflastrow}\marg{true part}\marg{false part} -%\end{definition} -% Checks if the current row is the last row of the database. -% It doesn't take the condition (the optional argument of -% \cs{DTLforeach}) into account, so its possible it may never -% do \meta{true part}, as the last row of the database may not -% meet the condition. It is therefore not very useful and is -% confusing since it behaves differently to \cs{DTLiffirstrow} -% which does take the condition into account, so I have removed -% its description from the main part of the manual. If you need -% to use the optional argument of \cs{DTLforeach}, you will first -% have to iterate through the database to count up the number -% of rows which meet the condition, and then do another pass, -% checking if the current row has reached that number. -%\changes{1.01}{2007 Aug 17}{fixed bug} -%\changes{2.0}{2009 February 27}{modified to have different -% definition depending on location} -% \begin{macrocode} -\newcommand{\DTLiflastrow}[2]{% - \PackageError{datatool}{\string\DTLiflastrow\space can only - be used inside \string\DTLforeach}{}% -} +\let\DTLifFPclosedbetween\dtlifnumclosedbetween % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLifoddrow} -%\begin{definition} -%\cs{DTLifoddrow}\marg{true part}\marg{false part} -%\end{definition} -% Determines whether the current row is odd (takes the optional -% argument of \cs{DTLforeach} into account.) -%\changes{2.0}{2009 February 27}{modified to have different -% definition depending on location} -% \begin{macrocode} -\newcommand{\DTLifoddrow}[2]{% - \PackageError{datatool}{\string\DTLifoddrow\space can only - be used inside \string\DTLforeach}{}% -} -% \end{macrocode} -%\end{macro} % -% \subsection{ifthen Conditionals} +%\subsection{ifthen Conditionals} % The following commands provide conditionals \cs{DTLis}\ldots\ -% which can be used in \cs{ifthenelse}. First need to define -% a new conditional: -%\begin{macro}{\if@dtl@condition} -% \begin{macrocode} -\newif\if@dtl@condition -% \end{macrocode} -%\end{macro} +% which can be used in \cs{ifthenelse}. % %\begin{macro}{\dtl@testlt} % Command to test if first argument is less than second argument. @@ -10099,7 +3675,8 @@ options>#2=\textsf{#2}|hyperpage}} % This sets \cs{if@dtl@condition}. % \begin{macrocode} \newcommand*{\dtl@testlt}[2]{% -\DTLiflt{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} + \DTLiflt{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}% +} % \end{macrocode} %\end{macro} % @@ -10107,7 +3684,8 @@ options>#2=\textsf{#2}|hyperpage}} % Provide conditional command for use in \cs{ifthenelse} % \begin{macrocode} \newcommand*{\DTLislt}[2]{% -\TE@throw\noexpand\dtl@testlt{#1}{#2}\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testlt{#1}{#2}\noexpand\if@dtl@condition +} % \end{macrocode} %\end{macro} % @@ -10118,7 +3696,8 @@ options>#2=\textsf{#2}|hyperpage}} % This sets \cs{if@dtl@condition}. % \begin{macrocode} \newcommand*{\dtl@testiclt}[2]{% -\@sDTLiflt{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} + \@sDTLiflt{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}% +} % \end{macrocode} %\end{macro} % @@ -10127,33 +3706,37 @@ options>#2=\textsf{#2}|hyperpage}} %\changes{1.01}{2007 Aug 17}{new} % \begin{macrocode} \newcommand*{\DTLisilt}[2]{% -\TE@throw\noexpand\dtl@testiclt{#1}{#2}\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testiclt{#1}{#2}\noexpand\if@dtl@condition +} % \end{macrocode} %\end{macro} % %\begin{macro}{\dtl@testgt} -% Command to test if first number is greater than second number. +% Command to test if first argument is greater than second argument. % This sets \cs{if@dtl@condition}. % \begin{macrocode} \newcommand*{\dtl@testgt}[2]{% -\DTLifgt{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} + \DTLifgt{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}% +} % \end{macrocode} %\end{macro} %\begin{macro}{\DTLisgt} % Provide conditional command for use in \cs{ifthenelse} % \begin{macrocode} \newcommand*{\DTLisgt}[2]{% -\TE@throw\noexpand\dtl@testgt{#1}{#2}\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testgt{#1}{#2}\noexpand\if@dtl@condition +} % \end{macrocode} %\end{macro} % %\begin{macro}{\dtl@testicgt} -% Command to test if first number is greater than second number +% Command to test if first argument is greater than second argument % (ignores case). % This sets \cs{if@dtl@condition}. % \begin{macrocode} \newcommand*{\dtl@testicgt}[2]{% -\@sDTLifgt{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} + \@sDTLifgt{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}% +} % \end{macrocode} %\end{macro} %\begin{macro}{\DTLisigt} @@ -10161,23 +3744,26 @@ options>#2=\textsf{#2}|hyperpage}} %\changes{1.01}{2007 Aug 17}{new} % \begin{macrocode} \newcommand*{\DTLisigt}[2]{% -\TE@throw\noexpand\dtl@testicgt{#1}{#2}\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testicgt{#1}{#2}\noexpand\if@dtl@condition +} % \end{macrocode} %\end{macro} % %\begin{macro}{\dtl@testeq} -% Command to test if first number is equal to the second number. +% Command to test if first argument is equal to the second argument. % This sets \cs{if@dtl@condition}. % \begin{macrocode} \newcommand*{\dtl@testeq}[2]{% -\DTLifeq{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} + \DTLifeq{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}% +} % \end{macrocode} %\end{macro} %\begin{macro}{\DTLiseq} % Provide conditional command for use in \cs{ifthenelse} % \begin{macrocode} \newcommand*{\DTLiseq}[2]{% -\TE@throw\noexpand\dtl@testeq{#1}{#2}\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testeq{#1}{#2}\noexpand\if@dtl@condition +} % \end{macrocode} %\end{macro} % @@ -10187,7 +3773,8 @@ options>#2=\textsf{#2}|hyperpage}} % This sets \cs{if@dtl@condition}. % \begin{macrocode} \newcommand*{\dtl@testiceq}[2]{% -\@sDTLifeq{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} + \@sDTLifeq{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}% +} % \end{macrocode} %\end{macro} %\begin{macro}{\DTLisieq} @@ -10195,7 +3782,8 @@ options>#2=\textsf{#2}|hyperpage}} %\changes{1.01}{2007 Aug 17}{new} % \begin{macrocode} \newcommand*{\DTLisieq}[2]{% -\TE@throw\noexpand\dtl@testiceq{#1}{#2}\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testiceq{#1}{#2}\noexpand\if@dtl@condition +} % \end{macrocode} %\end{macro} % @@ -10204,8 +3792,9 @@ options>#2=\textsf{#2}|hyperpage}} %\changes{1.01}{2007 Aug 17}{new} % \begin{macrocode} \newcommand*{\DTLisSubString}[2]{% -\TE@throw\noexpand\dtl@testifsubstring{#1}{#2}% -\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testifsubstring{#1}{#2}% + \noexpand\if@dtl@condition +} % \end{macrocode} %\end{macro} % @@ -10214,8 +3803,52 @@ options>#2=\textsf{#2}|hyperpage}} %\changes{1.01}{2007 Aug 17}{new} % \begin{macrocode} \newcommand*{\DTLisPrefix}[2]{% -\TE@throw\noexpand\dtl@teststartswith{#1}{#2}% -\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@teststartswith{#1}{#2}% + \noexpand\if@dtl@condition +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtl@testnumclosedbetween} +% Command to test if first number lies between second and third +% numbers. (End points included, all arguments are fixed point +% numbers in standard format.) This sets \cs{if@dtl@condition}. +% \begin{macrocode} +\newcommand*{\dtl@testnumclosedbetween}[3]{% + \DTLifnumclosedbetween{#1}{#2}{#3}% + {\@dtl@conditiontrue}{\@dtl@conditionfalse}% +} +% \end{macrocode} +%\end{macro} +% +% Provide conditional command for use in \cs{ifthenelse} +%\begin{macro}{\DTLisnumclosedbetween} +% \begin{macrocode} +\newcommand*{\DTLisnumclosedbetween}[3]{% + \TE@throw\noexpand\dtl@testnumclosedbetween{#1}{#2}{#3}% + \noexpand\if@dtl@condition +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtl@testnumopenbetween} +% Command to test if first number lies between second and third +% numbers. (End points excluded, all arguments are fixed point +% numbers in standard format.) This sets \cs{if@dtl@condition}. +% \begin{macrocode} +\newcommand*{\dtl@testnumopenbetween}[3]{% + \DTLifnumopenbetween{#1}{#2}{#3}% + {\@dtl@conditiontrue}{\@dtl@conditionfalse}% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLisnumopenbetween} +% Provide conditional command for use in \cs{ifthenelse} +% \begin{macrocode} +\newcommand*{\DTLisnumopenbetween}[3]{% + \TE@throw\noexpand\dtl@testnumopenbetween{#1}{#2}{#3}% + \noexpand\if@dtl@condition +} % \end{macrocode} %\end{macro} % @@ -10225,15 +3858,18 @@ options>#2=\textsf{#2}|hyperpage}} % This sets \cs{if@dtl@condition}. % \begin{macrocode} \newcommand*{\dtl@testclosedbetween}[3]{% -\DTLifclosedbetween{#1}{#2}{#3}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} + \DTLifclosedbetween{#1}{#2}{#3}% + {\@dtl@conditiontrue}{\@dtl@conditionfalse}% +} % \end{macrocode} %\end{macro} %\begin{macro}{\DTLisclosedbetween} % Provide conditional command for use in \cs{ifthenelse} % \begin{macrocode} \newcommand*{\DTLisclosedbetween}[3]{% -\TE@throw\noexpand\dtl@testclosedbetween{#1}{#2}{#3}% -\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testclosedbetween{#1}{#2}{#3}% + \noexpand\if@dtl@condition +} % \end{macrocode} %\end{macro} % @@ -10243,7 +3879,9 @@ options>#2=\textsf{#2}|hyperpage}} % This sets \cs{if@dtl@condition}. % \begin{macrocode} \newcommand*{\dtl@testiclosedbetween}[3]{% -\@sDTLifclosedbetween{#1}{#2}{#3}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} + \@sDTLifclosedbetween{#1}{#2}{#3}% + {\@dtl@conditiontrue}{\@dtl@conditionfalse}% +} % \end{macrocode} %\end{macro} %\begin{macro}{\DTLisiclosedbetween} @@ -10251,8 +3889,9 @@ options>#2=\textsf{#2}|hyperpage}} %\changes{1.01}{2007 Aug 17}{new} % \begin{macrocode} \newcommand*{\DTLisiclosedbetween}[3]{% -\TE@throw\noexpand\dtl@testiclosedbetween{#1}{#2}{#3}% -\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testiclosedbetween{#1}{#2}{#3}% + \noexpand\if@dtl@condition +} % \end{macrocode} %\end{macro} % @@ -10262,16 +3901,18 @@ options>#2=\textsf{#2}|hyperpage}} % This sets \cs{if@dtl@condition}. % \begin{macrocode} \newcommand*{\dtl@testopenbetween}[3]{% -\DTLifopenbetween{#1}{#2}{#3}{\@dtl@conditiontrue -}{\@dtl@conditionfalse}} + \DTLifopenbetween{#1}{#2}{#3}% + {\@dtl@conditiontrue}{\@dtl@conditionfalse}% +} % \end{macrocode} %\end{macro} %\begin{macro}{\DTLisopenbetween} % Provide conditional command for use in \cs{ifthenelse} % \begin{macrocode} \newcommand*{\DTLisopenbetween}[3]{% -\TE@throw\noexpand\dtl@testopenbetween{#1}{#2}{#3}% -\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testopenbetween{#1}{#2}{#3}% + \noexpand\if@dtl@condition +} % \end{macrocode} %\end{macro} % @@ -10281,8 +3922,9 @@ options>#2=\textsf{#2}|hyperpage}} % This sets \cs{if@dtl@condition}. % \begin{macrocode} \newcommand*{\dtl@testiopenbetween}[3]{% -\@sDTLifopenbetween{#1}{#2}{#3}{\@dtl@conditiontrue -}{\@dtl@conditionfalse}} + \@sDTLifopenbetween{#1}{#2}{#3}% + {\@dtl@conditiontrue}{\@dtl@conditionfalse}% +} % \end{macrocode} %\end{macro} %\begin{macro}{\DTLisiopenbetween} @@ -10290,27 +3932,16 @@ options>#2=\textsf{#2}|hyperpage}} %\changes{1.01}{2007 Aug 17}{new} % \begin{macrocode} \newcommand*{\DTLisiopenbetween}[3]{% -\TE@throw\noexpand\dtl@testiopenbetween{#1}{#2}{#3}% -\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testiopenbetween{#1}{#2}{#3}% + \noexpand\if@dtl@condition +} % \end{macrocode} %\end{macro} % -%\begin{macro}{\dtl@testclosedbetween} -% Command to test if first number lies between second and third -% numbers. (End points included, all arguments are fixed point -% numbers in standard format.) This sets \cs{if@dtl@condition}. -% \begin{macrocode} -\newcommand*{\dtl@testFPclosedbetween}[3]{% -\DTLifFPclosedbetween{#1}{#2}{#3}% -{\@dtl@conditiontrue}{\@dtl@conditionfalse}} -% \end{macrocode} -%\end{macro} -% Provide conditional command for use in \cs{ifthenelse} %\begin{macro}{\DTLisFPclosedbetween} +% Keep old command name for backwards compatibility: % \begin{macrocode} -\newcommand*{\DTLisFPclosedbetween}[3]{% -\TE@throw\noexpand\dtl@testFPclosedbetween{#1}{#2}{#3}% -\noexpand\if@dtl@condition} +\let\DTLisFPclosedbetween\DTLisnumclosedbetween % \end{macrocode} %\end{macro} % @@ -10320,15 +3951,18 @@ options>#2=\textsf{#2}|hyperpage}} % numbers in standard format.) This sets \cs{if@dtl@condition}. % \begin{macrocode} \newcommand*{\dtl@testFPopenbetween}[3]{% -\DTLifFPopenbetween{#1}{#2}{#3}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} + \DTLifFPopenbetween{#1}{#2}{#3}% + {\@dtl@conditiontrue}{\@dtl@conditionfalse}% +} % \end{macrocode} %\end{macro} %\begin{macro}{\DTLisFPopenbetween} % Provide conditional command for use in \cs{ifthenelse} % \begin{macrocode} \newcommand*{\DTLisFPopenbetween}[3]{% -\TE@throw\noexpand\dtl@testFPopenbetween{#1}{#2}{#3}% -\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testFPopenbetween{#1}{#2}{#3}% + \noexpand\if@dtl@condition +} % \end{macrocode} %\end{macro} % @@ -10338,15 +3972,23 @@ options>#2=\textsf{#2}|hyperpage}} % This sets \cs{if@dtl@condition}. % \begin{macrocode} \newcommand*{\dtl@testFPislt}[2]{% -\FPiflt{#1}{#2}\@dtl@conditiontrue\else\@dtl@conditionfalse\fi} + \dtlifnumlt{#1}{#2}% + {% + \@dtl@conditiontrue + }% + {% + \@dtl@conditionfalse + }% +} % \end{macrocode} %\end{macro} %\begin{macro}{\DTLisFPlt} % Provide conditional command for use in \cs{ifthenelse} % \begin{macrocode} \newcommand*{\DTLisFPlt}[2]{% -\TE@throw\noexpand\dtl@testFPislt{#1}{#2}% -\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testFPislt{#1}{#2}% + \noexpand\if@dtl@condition +} % \end{macrocode} %\end{macro} % @@ -10356,15 +3998,23 @@ options>#2=\textsf{#2}|hyperpage}} % This sets \cs{if@dtl@condition}. % \begin{macrocode} \newcommand*{\dtl@testFPisgt}[2]{% -\FPifgt{#1}{#2}\@dtl@conditiontrue\else\@dtl@conditionfalse\fi} + \dtlifnumgt{#1}{#2}% + {% + \@dtl@conditiontrue + }% + {% + \@dtl@conditionfalse + }% +} % \end{macrocode} %\end{macro} %\begin{macro}{\DTLisFPgt} % Provide conditional command for use in \cs{ifthenelse} % \begin{macrocode} \newcommand*{\DTLisFPgt}[2]{% -\TE@throw\noexpand\dtl@testFPisgt{#1}{#2}% -\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testFPisgt{#1}{#2}% + \noexpand\if@dtl@condition +} % \end{macrocode} %\end{macro} % @@ -10373,15 +4023,23 @@ options>#2=\textsf{#2}|hyperpage}} % are in standard decimal format % \begin{macrocode} \newcommand*{\dtl@testFPiseq}[2]{% -\FPifeq{#1}{#2}\@dtl@conditiontrue\else\@dtl@conditionfalse\fi} + \dtlifnumeq{#1}{#2}% + {% + \@dtl@conditiontrue + }% + {% + \@dtl@conditionfalse + }% +} % \end{macrocode} %\end{macro} %\begin{macro}{\DTLisFPeq} % Provide conditional command for use in \cs{ifthenelse} % \begin{macrocode} \newcommand*{\DTLisFPeq}[2]{% -\TE@throw\noexpand\dtl@testFPiseq{#1}{#2}% -\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testFPiseq{#1}{#2}% + \noexpand\if@dtl@condition +} % \end{macrocode} %\end{macro} % @@ -10391,11 +4049,17 @@ options>#2=\textsf{#2}|hyperpage}} % This sets \cs{if@dtl@condition}. % \begin{macrocode} \newcommand*{\dtl@testFPislteq}[2]{% -\FPiflt{#1}{#2}\@dtl@conditiontrue\else\@dtl@conditionfalse\fi -\if@dtl@condition -\else - \dtl@testFPiseq{#1}{#2}% -\fi + \dtlifnumlt{#1}{#2}% + {% + \@dtl@conditiontrue + }% + {% + \@dtl@conditionfalse + }% + \if@dtl@condition + \else + \dtl@testFPiseq{#1}{#2}% + \fi } % \end{macrocode} %\end{macro} @@ -10403,8 +4067,9 @@ options>#2=\textsf{#2}|hyperpage}} % Provide conditional command for use in \cs{ifthenelse} % \begin{macrocode} \newcommand*{\DTLisFPlteq}[2]{% -\TE@throw\noexpand\dtl@testFPislteq{#1}{#2}% -\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testFPislteq{#1}{#2}% + \noexpand\if@dtl@condition +} % \end{macrocode} %\end{macro} % @@ -10414,11 +4079,17 @@ options>#2=\textsf{#2}|hyperpage}} % This sets \cs{if@dtl@condition}. % \begin{macrocode} \newcommand*{\dtl@testFPisgteq}[2]{% -\FPifgt{#1}{#2}\@dtl@conditiontrue\else\@dtl@conditionfalse\fi -\if@dtl@condition -\else - \dtl@testFPiseq{#1}{#2}% -\fi + \dtlifnumgt{#1}{#2}% + {% + \@dtl@conditiontrue + }% + {% + \@dtl@conditionfalse + }% + \if@dtl@condition + \else + \dtl@testFPiseq{#1}{#2}% + \fi } % \end{macrocode} %\end{macro} @@ -10426,8 +4097,8 @@ options>#2=\textsf{#2}|hyperpage}} % Provide conditional command for use in \cs{ifthenelse} % \begin{macrocode} \newcommand*{\DTLisFPgteq}[2]{% -\TE@throw\noexpand\dtl@testFPisgteq{#1}{#2}% -\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testFPisgteq{#1}{#2}% + \noexpand\if@dtl@condition} % \end{macrocode} %\end{macro} % @@ -10436,14 +4107,14 @@ options>#2=\textsf{#2}|hyperpage}} % \cs{if@dtl@condition} % \begin{macrocode} \newcommand*{\dtl@teststring}[1]{% -\DTLifstring{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} + \DTLifstring{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} % \end{macrocode} %\end{macro} %\begin{macro}{\DTLisstring} % Provide conditional command for use in \cs{ifthenelse} % \begin{macrocode} \newcommand*{\DTLisstring}[1]{% -\TE@throw\noexpand\dtl@teststring{#1}\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@teststring{#1}\noexpand\if@dtl@condition} % \end{macrocode} %\end{macro} % @@ -10452,7 +4123,7 @@ options>#2=\textsf{#2}|hyperpage}} % \cs{if@dtl@condition} % \begin{macrocode} \newcommand*{\dtl@testnumerical}[1]{% -\DTLifnumerical{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}% + \DTLifnumerical{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}% } % \end{macrocode} %\end{macro} @@ -10460,7 +4131,7 @@ options>#2=\textsf{#2}|hyperpage}} % Provide conditional command for use in \cs{ifthenelse} % \begin{macrocode} \newcommand*{\DTLisnumerical}[1]{% -\TE@throw\noexpand\dtl@testnumerical{#1}\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testnumerical{#1}\noexpand\if@dtl@condition} % \end{macrocode} %\end{macro} % @@ -10469,14 +4140,14 @@ options>#2=\textsf{#2}|hyperpage}} % \cs{if@dtl@condition} % \begin{macrocode} \newcommand*{\dtl@testint}[1]{% -\DTLifint{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} + \DTLifint{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} % \end{macrocode} %\end{macro} %\begin{macro}{\DTLisint} % Provide conditional command for use in \cs{ifthenelse} % \begin{macrocode} \newcommand*{\DTLisint}[1]{% -\TE@throw\noexpand\dtl@testint{#1}\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testint{#1}\noexpand\if@dtl@condition} % \end{macrocode} %\end{macro} % @@ -10485,14 +4156,14 @@ options>#2=\textsf{#2}|hyperpage}} % \cs{if@dtl@condition} % \begin{macrocode} \newcommand*{\dtl@testreal}[1]{% -\DTLifreal{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} + \DTLifreal{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} % \end{macrocode} %\end{macro} %\begin{macro}{\DTLisreal} % Provide conditional command for use in \cs{ifthenelse} % \begin{macrocode} \newcommand*{\DTLisreal}[1]{% -\TE@throw\noexpand\dtl@testreal{#1}\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testreal{#1}\noexpand\if@dtl@condition} % \end{macrocode} %\end{macro} % @@ -10501,14 +4172,14 @@ options>#2=\textsf{#2}|hyperpage}} % \cs{if@dtl@condition} % \begin{macrocode} \newcommand*{\dtl@testcurrency}[1]{% -\DTLifcurrency{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} + \DTLifcurrency{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} % \end{macrocode} %\end{macro} %\begin{macro}{\DTLiscurrency} % Provide conditional command for use in \cs{ifthenelse} % \begin{macrocode} \newcommand*{\DTLiscurrency}[1]{% -\TE@throw\noexpand\dtl@testcurrency{#1}\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testcurrency{#1}\noexpand\if@dtl@condition} % \end{macrocode} %\end{macro} % @@ -10517,19 +4188,948 @@ options>#2=\textsf{#2}|hyperpage}} % \cs{if@dtl@condition} % \begin{macrocode} \newcommand*{\dtl@testcurrencyunit}[2]{% -\DTLifcurrencyunit{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} + \DTLifcurrencyunit{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} % \end{macrocode} %\end{macro} %\begin{macro}{\DTLiscurrencyunit} % Provide conditional command for use in \cs{ifthenelse} % \begin{macrocode} \newcommand*{\DTLiscurrencyunit}[2]{% -\TE@throw\noexpand\dtl@testcurrencyunit{#1}{#2}% -\noexpand\if@dtl@condition} + \TE@throw\noexpand\dtl@testcurrencyunit{#1}{#2}% + \noexpand\if@dtl@condition +} % \end{macrocode} %\end{macro} % -% \subsection{Defining New Databases} +%\section{Loops} +%\begin{macro}{\dtlbreak} +% Break out of loop at the end of current iteration. +% \begin{macrocode} +\newcommand*{\dtlbreak}{% + \PackageError{datatool}{Can't break out of anything}{}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlforint} +%\begin{definition} +%\cs{dtlforint}\meta{ct}=\meta{start}\cs{to}\meta{end}\cs{step}% +%\meta{inc}\cs{do}\marg{body} +%\end{definition} +% \meta{ct} is a count register, \meta{start}, \meta{end} and +% \meta{inc} are integers. +% Group if nested or use \cs{dtlgforint}. +% An infinite loop may result if \meta{inc}$=0$ and +% \meta{start} $\le$ \meta{end} and \cs{dtlbreak} isn't used. +% \begin{macrocode} +\long\def\dtlforint#1=#2\to#3\step#4\do#5{% +% \end{macrocode} +% Make a copy of old version of break function +% \begin{macrocode} + \let\@dtl@orgbreak\dtlbreak + \def\@dtl@endloophook{}% +% \end{macrocode} +% Setup break function for the loop (sets \meta{ct} to \meta{end} +% at the end of the current iteration). +% \begin{macrocode} + \def\dtlbreak{\def\@dtl@endloophook{#1=#3}}% +% \end{macrocode} +% Initialise \meta{ct} +% \begin{macrocode} + #1=#2\relax +% \end{macrocode} +% Check if the steps are positive or negative. +% \begin{macrocode} + \ifnum#4<0\relax +% \end{macrocode} +% Counting down +% \begin{macrocode} + \whiledo{\(#1>#3\)\TE@or\(#1=#3\)}% + {% + #5% + \@dtl@endloophook + \advance#1 by #4\relax + }% + \else +% \end{macrocode} +% Counting up +% \begin{macrocode} + \whiledo{\(#1<#3\)\TE@or\(#1=#3\)}% + {% + #5% + \@dtl@endloophook + \advance#1 by #4\relax + }% + \fi +% \end{macrocode} +% Restore break function. +% \begin{macrocode} + \let\dtlbreak\@dtl@orgbreak +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@dtl@foreach@level} +% Count register to keep track of global nested loops. +% \begin{macrocode} +\newcount\@dtl@foreach@level +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlgforint} +%\begin{definition} +%\cs{dtlgforint}\meta{ct}=\meta{start}\cs{to}\meta{end}\cs{step}% +%\meta{inc}\cs{do}\marg{body} +%\end{definition} +% \meta{ct} is a count register, \meta{start}, \meta{end} and +% \meta{inc} are integers. +% An infinite loop may result if \meta{inc}=0 and \meta{start} $\le$ +% \meta{end} and \cs{dtlbreak} isn't used. +% \begin{macrocode} +\long\def\dtlgforint#1=#2\to#3\step#4\do#5{% +% \end{macrocode} +% Initialise +% \begin{macrocode} + \global#1=#2\relax +% \end{macrocode} +% Increment level counter to allow for nested loops +% \begin{macrocode} + \global\advance\@dtl@foreach@level by 1\relax +% \end{macrocode} +% Set up end loop hook +% \begin{macrocode} + \expandafter\global\expandafter + \let\csname @dtl@endhook@\the\@dtl@foreach@level\endcsname + \relax +% \end{macrocode} +% Set up the break function: +% Copy current definition +% \begin{macrocode} + \expandafter\global\expandafter + \let\csname @dtl@break@\the\@dtl@foreach@level\endcsname + \dtlbreak +% \end{macrocode} +% Set up definition for this level (sets <ct> to <end> at the end +% of the current iteration). +% \begin{macrocode} + \gdef\dtlbreak{\expandafter + \gdef\csname @dtl@endhook@\the\@dtl@foreach@level\endcsname{% + #1=#3}}% +% \end{macrocode} +% check the direction +% \begin{macrocode} + \ifnum#4<0\relax +% \end{macrocode} +% Counting down +% \begin{macrocode} + \whiledo{\(#1>#3\)\TE@or\(#1=#3\)}% + {% + #5% + \csname @dtl@endhook@\the\@dtl@foreach@level\endcsname + \global\advance#1 by #4\relax + }% + \else +% \end{macrocode} +% Counting up (or 0 increments) +% \begin{macrocode} + \whiledo{\(#1<#3\)\TE@or\(#1=#3\)}% + {% + #5% + \csname @dtl@endhook@\the\@dtl@foreach@level\endcsname + \global\advance#1 by #4\relax + }% + \fi +% \end{macrocode} +% Restore break function +% \begin{macrocode} + \expandafter\global\expandafter\let\expandafter\dtlbreak + \csname @dtl@break@\the\@dtl@foreach@level\endcsname +% \end{macrocode} +% Decrement level counter +% \begin{macrocode} + \global\advance\@dtl@foreach@level by -1\relax +} +% \end{macrocode} +%\end{macro} +% +%\begin{environment}{dtlenvgforint} +% Environment form (contents are gathered, so verbatim can't be +% used): +% \begin{macrocode} +\newenvironment{dtlenvgforint}[1]% +{% + \def\@dtlenvgforint@arg{#1}% + \long@collect@body\@do@dtlenvgforint +}% +{} +\newcommand{\@do@dtlenvgforint}[1]{% + \expandafter\dtlgforint\@dtlenvgforint@arg\do{#1}% +} +% \end{macrocode} +%\end{environment} +%\iffalse +% \begin{macrocode} +%</datatool-base.sty> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%<*datatool-fp.sty> +% \end{macrocode} +%\fi +%\chapter{datatool-fp.sty}\label{sec:code:datatool-fp} +% Definitions of fixed-point commands that use the \sty{fp} package. +% \begin{macrocode} +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{datatool-fp}[2012/07/18 v2.10 (NLCT)] +% \end{macrocode} +% Required packages: +% \begin{macrocode} +\RequirePackage{xkeyval} +\RequirePackage{fp} +\RequirePackage{datatool-base} +% \end{macrocode} +%\begin{option}{verbose} +% Switch \sty{fp} messages on or off +% \begin{macrocode} +\define@choicekey{datatool-fp}{verbose}[\val\nr]{true,false}[true]{% + \ifcase\nr\relax + \FPmessagestrue + \or + \FPmessagesfalse + \fi +} +\let\ifFPmessages\ifdtlverbose +% \end{macrocode} +%\end{option} +% +% Process package options: +% \begin{macrocode} +\ProcessOptionsX +% \end{macrocode} +% +% Define commands that are needed before loading +% \sty{datatool-base}: +% \begin{macrocode} +\providecommand*{\@dtl@mathprocessor}{fp} +% \end{macrocode} +%\begin{macro}{\dtlifnumeq} +%\begin{definition} +%\cs{dtlifnumeq}\marg{num1}\marg{num2}\marg{true part}\marg{false +%part} +%\end{definition} +% Does \meta{true part} if \meta{num1}=\meta{num2}, otherwise does +% \meta{false part}. The numbers must use a full stop as the decimal +% character and no number group separator. +% \begin{macrocode} +\newcommand*{\dtlifnumeq}[4]{% + \FPifeq{#1}{#2}% + #3% + \else + #4% + \fi +} +% \end{macrocode} +%\end{macro} +% +% If \pkgopt{verbose} option set, switch on \pkgopt{verbose} for +% \sty{datatool-base} as well: +% \begin{macrocode} +\let\ifdtlverbose\ifFPmessages +% \end{macrocode} +% +%\section{Comparison Commands} +% +%\begin{macro}{\dtlifnumlt} +%\begin{definition} +%\cs{dtlifnumlt}\marg{num1}\marg{num2}\marg{true part}\marg{false +%part} +%\end{definition} +% Does \meta{true part} if \meta{num1} \textless \meta{num2}, otherwise does +% \meta{false part}. The numbers must use a full stop as the decimal +% character and no number group separator. +% \begin{macrocode} +\newcommand*{\dtlifnumlt}[4]{% + \FPiflt{#1}{#2}% + #3% + \else + #4% + \fi +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlifnumgt} +%\begin{definition} +%\cs{dtlifnumgt}\marg{num1}\marg{num2}\marg{true part}\marg{false +%part} +%\end{definition} +% Does \meta{true part} if \meta{num1} \textgreater \meta{num2}, otherwise does +% \meta{false part}. The numbers must use a full stop as the decimal +% character and no number group separator. +% \begin{macrocode} +\newcommand*{\dtlifnumgt}[4]{% + \FPifgt{#1}{#2}% + #3% + \else + #4% + \fi +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlifnumopenbetween} +%\begin{definition} +%\cs{dtlifnumopenbetween}\marg{num}\marg{min}\marg{max}\marg{true part}\marg{false part} +%\end{definition} +% Determines if \meta{min} $<$ \meta{num} $<$ \meta{max} where +% all arguments are in standard fixed point notation. +% \begin{macrocode} +\newcommand*{\dtlifnumopenbetween}[5]{% + \let\@dtl@dovalue\relax + \dtlifnumgt{#1}{#2}% + {}% + {% + \def\@dtl@dovalue{#5}% + }% + \dtlifnumlt{#1}{#3}% + {% + \ifx\@dtl@dovalue\relax + \def\@dtl@dovalue{#4}% + \fi + }% + {% + \def\@dtl@dovalue{#5}% + }% + \@dtl@dovalue +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlifnumclosedbetween} +%\begin{definition} +%\cs{dtlifnumclosedbetween}\marg{num}\marg{min}\marg{max}\marg{true part}\marg{false part} +%\end{definition} +% Determines if \meta{min} $\leq$ \meta{num} $\leq$ \meta{max} where +% all arguments are in standard fixed point notation. +% \begin{macrocode} +\newcommand*{\dtlifnumclosedbetween}[5]{% + \let\@dtl@dovalue\relax + \dtlifnumgt{#1}{#2}% + {}% + {% + \dtlifnumeq{#1}{#2}% + {% + \def\@dtl@dovalue{#4}% + }% + {% + \def\@dtl@dovalue{#5}% + }% + }% + \dtlifnumlt{#1}{#3}% + {% + \ifx\@dtl@dovalue\relax + \def\@dtl@dovalue{#4}% + \fi + }% + {% + \dtlifnumeq{#1}{#3}% + {% + \def\@dtl@dovalue{#4}% + }% + {% + \def\@dtl@dovalue{#5}% + }% + }% + \@dtl@dovalue +} +% \end{macrocode} +%\end{macro} +% +%\section{Functions} +% +%\begin{macro}{\dtladd} +% Adds two numbers using fp. +% \begin{macrocode} +\newcommand*{\dtladd}[3]{% + \FPadd{#1}{#2}{#3}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlsub} +% Subtracts two numbers using fp. +% \begin{macrocode} +\newcommand*{\dtlsub}[3]{% + \FPsub{#1}{#2}{#3}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlmul} +% Multiplies two numbers using fp. +% \begin{macrocode} +\newcommand*{\dtlmul}[3]{% + \FPmul{#1}{#2}{#3}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtldiv} +% Divides two numbers using fp. +% \begin{macrocode} +\newcommand*{\dtldiv}[3]{% + \FPdiv{#1}{#2}{#3}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlroot} +% Square root using fp. +% \begin{macrocode} +\newcommand*{\dtlroot}[2]{% + \FProot{#1}{#2}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlround} +% Rounds using fp. +% \begin{macrocode} +\newcommand*{\dtlround}[3]{% + \FPround{#1}{#2}{#3}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtltrunc} +% Truncates using fp. +% (Third argument is the number of digits.) +% \begin{macrocode} +\newcommand*{\dtltrunc}[3]{% + \FPtrunc{#1}{#2}{#3}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlclip} +% \begin{macrocode} +\newcommand*{\dtlclip}[2]{% + \FPclip{#1}{#2}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlmin} +% Minimum of two numbers using fp. +% \begin{macrocode} +\newcommand*{\dtlmin}[3]{% + \FPmin{#1}{#2}{#3}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlmax} +% Maximum of two numbers using fp. +% \begin{macrocode} +\newcommand*{\dtlmax}[3]{% + \FPmax{#1}{#2}{#3}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlabs} +% Absolute value using fp. +% \begin{macrocode} +\newcommand*{\dtlabs}[2]{% + \FPabs{#1}{#2}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlneg} +% Negative of a value using fp. +% \begin{macrocode} +\newcommand*{\dtlneg}[2]{% + \FPneg{#1}{#2}% +} +% \end{macrocode} +%\end{macro} +% +%\iffalse +% \begin{macrocode} +%</datatool-fp.sty> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%<*datatool-pgfmath.sty> +% \end{macrocode} +%\fi +%\chapter{datatool-pgfmath.sty}\label{sec:code:datatool-pgfmath} +% Definitions of fixed-point commands that use the \sty{pgfmath} package. +% \begin{macrocode} +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{datatool-pgfmath}[2012/07/18 v2.10 (NLCT)] +% \end{macrocode} +% Required packages: +% \begin{macrocode} +\RequirePackage{xkeyval} +\RequirePackage{pgfrcs,pgfkeys,pgfmath} +% \end{macrocode} +% +% Process package options: +% \begin{macrocode} +\ProcessOptionsX +% \end{macrocode} +% +% Define commands that are needed before loading +% \sty{datatool-base}: +% \begin{macrocode} +\providecommand*{\@dtl@mathprocessor}{pgfmath} +% \end{macrocode} +%\begin{macro}{\dtlifnumeq} +%\begin{definition} +%\cs{dtlifnumeq}\marg{num1}\marg{num2}\marg{true part}\marg{false +%part} +%\end{definition} +% Does \meta{true part} if \meta{num1}=\meta{num2}, otherwise does +% \meta{false part}. The numbers must use a full stop as the decimal +% character and no number group separator. +% \begin{macrocode} +\newcommand*{\dtlifnumeq}[4]{% + \pgfmathifthenelse{#1==#2}{"#3"}{"#4"}% + \pgfmathresult +} +% \end{macrocode} +%\end{macro} +% +% Load base package: +% \begin{macrocode} +\RequirePackage{datatool-base} +% \end{macrocode} +% +%\section{Comparison Commands} +%\begin{macro}{\dtlifnumlt} +%\begin{definition} +%\cs{dtlifnumlt}\marg{num1}\marg{num2}\marg{true part}\marg{false +%part} +%\end{definition} +% Does \meta{true part} if \meta{num1} \textless \meta{num2}, otherwise does +% \meta{false part}. The numbers must use a full stop as the decimal +% character and no number group separator. +% \begin{macrocode} +\newcommand*{\dtlifnumlt}[4]{% + \pgfmathifthenelse{#1 < #2}{"#3"}{"#4"}% + \pgfmathresult +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlifnumgt} +%\begin{definition} +%\cs{dtlifnumgt}\marg{num1}\marg{num2}\marg{true part}\marg{false +%part} +%\end{definition} +% Does \meta{true part} if \meta{num1} \textgreater \meta{num2}, otherwise does +% \meta{false part}. The numbers must use a full stop as the decimal +% character and no number group separator. +% \begin{macrocode} +\newcommand*{\dtlifnumgt}[4]{% + \pgfmathifthenelse{#1 > #2}{"#3"}{"#4"}% + \pgfmathresult +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlifnumopenbetween} +%\begin{definition} +%\cs{dtlifnumopenbetween}\marg{num}\marg{min}\marg{max}\marg{true part}\marg{false part} +%\end{definition} +% Determines if \meta{min} $<$ \meta{num} $<$ \meta{max} where +% all numerical arguments are in standard fixed point notation. +% \begin{macrocode} +\newcommand*{\dtlifnumopenbetween}[5]{% + \pgfmathifthenelse{(#2 < #1) && (#1 < #3)}{"#4"}{"#5"}% + \pgfmathresult +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlifnumclosedbetween} +%\begin{definition} +%\cs{dtlifnumclosedbetween}\marg{num}\marg{min}\marg{max}\marg{true part}\marg{false part} +%\end{definition} +% Determines if \meta{min} $\leq$ \meta{num} $\leq$ \meta{max} where +% all numerical arguments are in standard fixed point notation. +% \begin{macrocode} +\newcommand*{\dtlifnumclosedbetween}[5]{% + \pgfmathifthenelse{(#2 <= #1) && (#1 <= #3)}{"#4"}{"#5"}% + \pgfmathresult +} +% \end{macrocode} +%\end{macro} +% +%\section{Functions} +%\begin{macro}{\dtladd} +% Adds two numbers using PGF math engine. +% \begin{macrocode} +\newcommand*{\dtladd}[3]{% + \pgfmathadd{#2}{#3}% + \let#1\pgfmathresult +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlsub} +% Subtracts two numbers using PGF math engine. +% \begin{macrocode} +\newcommand*{\dtlsub}[3]{% + \pgfmathsubtract{#2}{#3}% + \let#1\pgfmathresult +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlmul} +% Multiplies two numbers using PGF math engine. +% \begin{macrocode} +\newcommand*{\dtlmul}[3]{% + \pgfmathmultiply{#2}{#3}% + \let#1\pgfmathresult +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtldiv} +% Divides two numbers using PGF math engine. +% \begin{macrocode} +\newcommand*{\dtldiv}[3]{% + \pgfmathdivide{#2}{#3}% + \let#1\pgfmathresult +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlroot} +% Square root using PGF math engine. +% \begin{macrocode} +\newcommand*{\dtlroot}[2]{% + \pgfmathsqrt{#2}% + \let#1\pgfmathresult +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlround} +% Rounds using PGF math engine. +% \begin{macrocode} +\newcommand*{\dtlround}[3]{% + \pgfmathparse{10^#3}% + \let\dtl@tmpshift\pgfmathresult + \pgfmathparse{round(#2 * \dtl@tmpshift) / \dtl@tmpshift}% + \let#1\pgfmathresult +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtltrunc} +% Truncates using PGF math engine. +% (Third argument is the number of digits.) +% \begin{macrocode} +\newcommand*{\dtltrunc}[3]{% + \pgfmathparse{10^#3}% + \let\dtl@tmpshift\pgfmathresult + \pgfmathparse{floor(#2 * \dtl@tmpshift) / \dtl@tmpshift}% + \let#1\pgfmathresult +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlclip} +% There isn't a clip in pgfmath as it seems to automatically clip. +% \begin{macrocode} +\newcommand*{\dtlclip}[2]{% + \edef#1{#2}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlmin} +% Minimum of two numbers using PGF math engine. +% \begin{macrocode} +\newcommand*{\dtlmin}[3]{% + \pgfmathmin{#2}{#3}% + \let#1\pgfmathresult +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlmax} +% Maximum of two numbers using PGF math engine. +% \begin{macrocode} +\newcommand*{\dtlmax}[3]{% + \pgfmathmax{#2}{#3}% + \let#1\pgfmathresult +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlabs} +% Absolute value using PGF math engine. +% \begin{macrocode} +\newcommand*{\dtlabs}[2]{% + \pgfmathabs{#2}% + \let#1\pgfmathresult +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlneg} +% Negative of a value using PGF math engine. +% \begin{macrocode} +\newcommand*{\dtlneg}[2]{% + \pgfmathmul{-1}{#2}% + \let#1\pgfmathresult +} +% \end{macrocode} +%\end{macro} +% +%\iffalse +% \begin{macrocode} +%</datatool-pgfmath.sty> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%<*datatool.sty> +% \end{macrocode} +%\fi +%\chapter{datatool.sty} +%\label{sec:code:datatool} +%\section{Package Declaration} +% \begin{macrocode} +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{datatool}[2012/07/18 v2.10 (NLCT)] +% \end{macrocode} +% Load required packages: +% \begin{macrocode} +\RequirePackage{xkeyval} +\RequirePackage{ifthen} +\RequirePackage{xfor} +\RequirePackage{substr} +% \end{macrocode} +%\changes{2.0}{2009 February 27}{added etex as a required package} +% \begin{macrocode} +\RequirePackage{etex} +% \end{macrocode} +% +%\section{Package Options} +%\begin{macro}{\@dtl@separator} +% The data separator character (comma by default) is stored in +% \cs{@dtl@separator}. +% This is the separator used in external data files, not in the +% \LaTeX\ code, which always uses a comma separator. +% \begin{macrocode} +\newcommand*{\@dtl@separator}{,} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLsetseparator} +%\begin{definition} +%\cs{DTLsetseparator}\marg{char} +%\end{definition} +% The sets \cs{@dtl@separator}, and constructs the relevent macros +% that require this character to be hardcoded into their definition. +% \begin{macrocode} +\newcommand*{\DTLsetseparator}[1]{% + \renewcommand*{\@dtl@separator}{#1}% + \@dtl@construct@lopoffs +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLsettabseparator} +%\cs{DTLsettabseparator} makes it easier to set a tab separator. +%\changes{2.10}{2012-07-18}{changed tab character to +%\texttt{\textasciicircum\textasciicircum I}} +% \begin{macrocode} +\begingroup +\catcode`\^^I12 +\gdef\DTLsettabseparator{% + \catcode`\^^I12 + \DTLsetseparator{^^I}% +} +\endgroup +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@dtl@delimiter} +% The data delimiter character (double quote by default) is stored +% in \cs{@dtl@delimiter}. This is used in external data files, not +% in the \LaTeX\ code. +% \begin{macrocode} +\begingroup +\catcode`\"12\relax +\gdef\@dtl@delimiter{"} +\endgroup +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLsetdelimiter} +%\begin{definition} +%\cs{DTLsetdelimiter}\marg{char} +%\end{definition} +% This sets the delimiter. +% \begin{macrocode} +\newcommand*\DTLsetdelimiter[1]{% + \renewcommand*{\@dtl@delimiter}{#1}% + \@dtl@construct@lopoffs +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@dtl@construct@lopoff} +%\begin{definition} +%\cs{@dtl@construct@lopoff}\meta{separator char}\meta{delimiter char} +%\end{definition} +% This defines +%\begin{definition} +% \cs{@dtl@lopoff}\meta{first element}\meta{sep}\meta{rest of list}\cs{to}\meta{cmd1}\meta{cmd2} +%\end{definition} +%for the current separator and delimiter. +% \begin{macrocode} +\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 + }% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@dtl@construct@qlopoff} +%\begin{definition} +% \cs{@dtl@construct@qlopoff}\meta{separator char}\meta{delimiter char} +%\end{definition} +% This constructs \cs{@dtl@qlopoff} to be used +% when the entry is surrounded by the current delimiter value. +% \begin{macrocode} +\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}% +% \end{macrocode} +% Replace any escaped delimiters +%\changes{2.10}{2012-07-18}{Added code to replace escaped delimiters} +% \begin{macrocode} + \noexpand\DTLsubstituteall{##4}{#2#2}{#2}% + \noexpand\edef\noexpand\@dtl@dosubs{% + \noexpand\noexpand\noexpand\DTLsubstituteall{\noexpand\noexpand##4}% + {\noexpand\expandafter\noexpand\noexpand\noexpand\csname#2\noexpand\endcsname#2}% + {\noexpand\expandafter\noexpand\noexpand\noexpand\csname#2\noexpand\endcsname}% + }% + \noexpand\@dtl@dosubs + \noexpand\def##3{#1##2}% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\@dtl@construct@lop@ff} +%\begin{definition} +% \cs{@dtl@construct@lop@ff}\meta{separator char} +%\end{definition} +% This constructs \cs{@dtl@lop@ff} to be used when +% the entry isn't surrouded by the delimiter. +% \begin{macrocode} +\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}% + }% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@dtl@construct@lopoffs} +%\begin{definition} +%\cs{@dtl@construct@lopoffs} +%\end{definition} +% This constructs all the lopoff macros +% using the given separator and delimiter characters. +% \begin{macrocode} +\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}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{option}{separator} +% Define separator used in external data files. +% \begin{macrocode} +\define@key{datatool.sty}{separator}{% + \DTLsetseparator{#1}% +} +% \end{macrocode} +%\end{option} +% +%\begin{option}{delimiter} +% Define delimiter used in external data files. +% \begin{macrocode} +\define@key{datatool.sty}{delimiter}{% + \DTLsetdelimiter{#1}% +} +% \end{macrocode} +%\end{option} +% +%\begin{option}{verbose} +% \begin{macrocode} +\define@boolkey{datatool.sty}[dtl]{verbose}[true]{} +% \end{macrocode} +%\end{option} +% +%\begin{option}{math} +% Determine whether to use \sty{fp} or \sty{pgfmath} for the +% arithmetic commands. The default is to use \sty{fp}. +% \begin{macrocode} +\define@choicekey{datatool.sty}{math}[\val\nr]{fp,pgfmath}{% + \renewcommand*\@dtl@mathprocessor{#1}% +} +\newcommand*{\@dtl@mathprocessor}{fp} +% \end{macrocode} +%\end{option} +% +% Process package options: +% \begin{macrocode} +\ProcessOptionsX +% \end{macrocode} +% +% Set the defaults: +% \begin{macrocode} +\@dtl@construct@lopoffs +% \end{macrocode} +% +% Load base package: +% \begin{macrocode} +\RequirePackage{datatool-base} +% \end{macrocode} +% +%\begin{macro}{\DTLpar} +% Many of the commands used by this package are short commands. +% This means that you can't use \cs{par} +% in the data. To get around this, define the robust command +% \cs{DTLpar} to use instead. +% \begin{macrocode} +\DeclareRobustCommand\DTLpar{\@par} +% \end{macrocode} +%\end{macro} +% +% \section{Defining New Databases} % As from v2.0, the internal structure of the database has changed % to make it more efficient.\footnote{Thanks to Morten H\o gholm % for the suggestion.} The database is now stored in a token @@ -10676,7 +5276,8 @@ options>#2=\textsf{#2}|hyperpage}} % (Doesn't check if database exists.) % \begin{macrocode} \newcommand*{\DTLrowcount}[1]{% -\expandafter\number\csname dtlrows@#1\endcsname} + \expandafter\number\csname dtlrows@#1\endcsname +} % \end{macrocode} %\end{macro} % @@ -10689,7 +5290,8 @@ options>#2=\textsf{#2}|hyperpage}} %\changes{2.0}{2009 February 27}{new}% % \begin{macrocode} \newcommand*{\DTLcolumncount}[1]{% -\expandafter\number\csname dtlcols@#1\endcsname} + \expandafter\number\csname dtlcols@#1\endcsname +} % \end{macrocode} %\end{macro} % @@ -10989,6 +5591,7 @@ options>#2=\textsf{#2}|hyperpage}} %\end{macro} %\begin{macro}{\@dtl@getkeyforcolumn} % Column index must be fully expanded before use. +%\changes{2.10}{2012-07-18}{fixed bug} % \begin{macrocode} \newcommand*{\@dtl@getkeyforcolumn}[3]{% \def\@dtl@get@keyforcolumn##1% before stuff @@ -11000,10 +5603,10 @@ options>#2=\textsf{#2}|hyperpage}} \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 + \edef\@dtl@tmp{\expandafter\the\csname dtlkeys@#2\endcsname}% + \expandafter\@dtl@get@keyforcolumn\@dtl@tmp \db@plist@elt@w% start of block - \db@col@id@w #3\db@col@id@end@ index + \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 @@ -11226,12 +5829,13 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} % Is the value empty? % \begin{macrocode} - \def\@dtl@tmp{#3}% - \ifx\@dtl@tmp\@empty + \ifstrempty{#3}% + {% % \end{macrocode} % Leave data type as it is % \begin{macrocode} - \else + }% + {% % \end{macrocode} % Make a copy of current data type % \begin{macrocode} @@ -11244,9 +5848,11 @@ options>#2=\textsf{#2}|hyperpage}} % If this column currently has no data type assigned to it % then use the new type. % \begin{macrocode} - \ifx\@dtl@type\@empty + \ifdefempty{\@dtl@type}% + {% \edef\@dtl@type{\number\@dtl@datatype}% - \else + }% + {% % \end{macrocode} % This column already has an associated data type but it may % need updating. @@ -11275,7 +5881,7 @@ options>#2=\textsf{#2}|hyperpage}} \def\@dtl@type{3}% \fi \fi - \fi + }% % \end{macrocode} % Has the data type been updated? % \begin{macrocode} @@ -11304,7 +5910,7 @@ options>#2=\textsf{#2}|hyperpage}} }% {\@dtl@after}% \fi - \fi + }% }% {% % \end{macrocode} @@ -11321,13 +5927,14 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} % Get data type for this entry (stored in \cs{@dtl@datatype}) % \begin{macrocode} - \def\@dtl@tmp{#3}% - \ifx\@dtl@tmp\@empty + \ifstrempty{#2}% + {% \edef\@dtl@type{}% don't know data type yet - \else + }% + {% \@dtl@checknumerical{#3}% \edef\@dtl@type{\number\@dtl@datatype}% - \fi + }% % \end{macrocode} % Append to property list % \begin{macrocode} @@ -11609,7 +6216,29 @@ options>#2=\textsf{#2}|hyperpage}} %\changes{2.0}{2009 February 27}{removed \cs{dtl@getentryvalue}} %\changes{2.0}{2009 February 27}{removed \cs{dtl@getentryid}} % -%\subsection{Accessing Data} +%\section{Accessing Data} +% +%\begin{macro}{\DTLassign} +%\begin{definition} +%\cs{DTLassign}\marg{db}\marg{row idx}\marg{assign list} +%\end{definition} +% Assigns values given in \meta{assign list} for row \meta{row idx} in database +% \meta{db}. (Where \meta{assign list} is in the same form as in +% \cs{DTLforeach}) +%\changes{2.10}{2012-07-18}{new} +% \begin{macrocode} +\newcommand*{\DTLassign}[3]{% +% \end{macrocode} +% Grouped in the event that \cs{dtlcurrentrow} is already in use. +% (Assignments in \cs{@dtl@assign} are global.) +% \begin{macrocode} + {% + \dtlgetrow{#1}{#2}% + \@dtl@assign{#3}{#1}% + }% +} +% \end{macrocode} +%\end{macro} % %\begin{macro}{\@dtl@assign} %\begin{definition} @@ -11901,9 +6530,13 @@ options>#2=\textsf{#2}|hyperpage}} % Gets row with index \meta{row idx} from database named \meta{db} % and stores the row in \cs{dtlcurrentrow}, the preceding rows in % \cs{dtlbeforerow} and the following rows in \cs{dtlafterrow}. +% The row index, \meta{row idx}, is stored in \cs{dtlrownum} +% and the database name, \meta{db}, is stored in \cs{dtldbname}. % This assumes that the given row exists. % \begin{macrocode} \newcommand*{\dtlgetrow}[2]{% + \dtlrownum=#2\relax + \edef\dtldbname{#1}% \expandafter\toks@\expandafter=\csname dtldb@#1\endcsname \edef\@dtl@dogetrow{\noexpand\@dtlgetrow{\the\toks@}{\number#2}}% \@dtl@dogetrow @@ -11932,6 +6565,203 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} %\end{macro} % +%\begin{macro}{\dtlrecombine} +%\begin{definition} +%\cs{dtlrecombine} +%\end{definition} +% Recombines database contents from \cs{dtlbeforerow}, +% \cs{dtlcurrentrow} and \cs{dtlafterrow} +% \begin{macrocode} +\newcommand*{\dtlrecombine}{% + \toks@gconcat@middle@cx{dtldb@\dtldbname}% + {\dtlbeforerow}% + {% +% \end{macrocode} +% Start of row tag +% \begin{macrocode} + \noexpand\db@row@elt@w +% \end{macrocode} +% Row number +% \begin{macrocode} + \noexpand\db@row@id@w + \number\dtlrownum + \noexpand\db@row@id@end@ +% \end{macrocode} +% Current row specs: +% \begin{macrocode} + \the\dtlcurrentrow +% \end{macrocode} +% Row number +% \begin{macrocode} + \noexpand\db@row@id@w + \number\dtlrownum + \noexpand\db@row@id@end@ +% \end{macrocode} +% End of row tag +% \begin{macrocode} + \noexpand\db@row@elt@end@ + }% + {\dtlafterrow}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlrecombineomitcurrent} +%\begin{definition} +%\cs{dtlrecombineomitcurrent} +%\end{definition} +%Like \cs{dtlrecombine} but omits \cs{dtlcurrentrow} +%\changes{2.10}{2012-07-18}{new} +% \begin{macrocode} +\newcommand{\dtlrecombineomitcurrent}{% +% \end{macrocode} +% Decrement row indices in \cs{dtlafterrow}: +% \begin{macrocode} + \dtl@decrementrows{\dtlafterrow}{\dtlrownum} +% \end{macrocode} +% Reconstruct database contents by concatenating +% \cs{dtlbeforerow} and \cs{dtlafterrow} +% \begin{macrocode} + \csname dtldb@\dtldbname\endcsname=\dtlbeforerow + \toks@gput@right@cx{dtldb@\dtldbname}{\the\dtlafterrow}% + \dtl@message{Removed row \number\dtlrownum\space in database + `\dtldbname'}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlsplitrow} +%\begin{definition} +%\cs{dtlsplitrow}\marg{row specs}\marg{col num}\marg{before +% cs}\marg{after cs} +%\end{definition} +% Splits the row around the entry given by \meta{col num}. The +% entries before the split are stored in \meta{before cs} and the +% entries after the split are stored in \meta{after cs}. +% \meta{row specs} and \meta{col num} need to be expanded before use. +% \begin{macrocode} +\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 +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlreplaceentryincurrentrow} +%\begin{definition} +%\cs{dtlreplaceentryincurrentrow}\marg{new value}\marg{col num} +%\end{definition} +% Replaces entry for column \meta{col num} in \cs{dtlcurrentrow} +% with \meta{new value} +%\changes{2.10}{2012-07-18}{new} +% \begin{macrocode} +\newcommand*{\dtlreplaceentryincurrentrow}[2]{% +% \end{macrocode} +% Split row +% \begin{macrocode} + \edef\@dtl@do@splitrow{\noexpand\dtlsplitrow + {\the\dtlcurrentrow}% + {\number#2}% + {\noexpand\@dtl@before@cs}% + {\noexpand\@dtl@after@cs}}% + \@dtl@do@splitrow +% \end{macrocode} +% Recombine with new value +% \begin{macrocode} + \toks@{#1}% + \edef\@dtl@stuff{% + \expandonce\@dtl@before@cs +% \end{macrocode} +% Begin column index specs: +% \begin{macrocode} + \noexpand\db@col@id@w \number#2\noexpand + \noexpand\db@col@id@end@% column id +% \end{macrocode} +% New entry: +% \begin{macrocode} + \noexpand\db@col@elt@w + \the\toks@ + \noexpand\db@col@elt@end@ +% \end{macrocode} +% End column index specs: +% \begin{macrocode} + \noexpand\db@col@id@w \number#2\noexpand + \noexpand\db@col@id@end@% column id + \expandonce\@dtl@after@cs + }% +% \end{macrocode} +% Store in \cs{dtlcurrentrow} +% \begin{macrocode} + \expandafter\dtlcurrentrow\expandafter{\@dtl@stuff}% +% \end{macrocode} +% Update column specs +% \begin{macrocode} + \@sdtlgetkeyforcolumn{\@dtl@key}{\dtldbname}{#2}% + \@dtl@updatekeys{\dtldbname}{\@dtl@key}{#1}% + \dtl@message{Updated \@dtl@key\space -> #1\space in database + `\dtldbname'}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlremoveentryincurrentrow} +%\begin{definition} +%\cs{dtlremoveentryincurrentrow}\marg{col idx} +%\end{definition} +% Removes entry for column \meta{col idx} from \cs{dtlcurrentrow}. +%\changes{2.10}{2012-07-18}{new} +% \begin{macrocode} +\newcommand*{\dtlremoveentryincurrentrow}[1]{% +% \end{macrocode} +% Split row +% \begin{macrocode} + \edef\@dtl@do@splitrow{\noexpand\dtlsplitrow + {\the\dtlcurrentrow}% + {\number#1}% + {\noexpand\@dtl@before@cs}% + {\noexpand\@dtl@after@cs}}% + \@dtl@do@splitrow +% \end{macrocode} +% Combine row without given column: +% \begin{macrocode} + \edef\@dtl@stuff{% + \expandonce\@dtl@before@cs + \expandonce\@dtl@after@cs + }% +% \end{macrocode} +% Store in \cs{dtlcurrentrow} +% \begin{macrocode} + \expandafter\dtlcurrentrow\expandafter{\@dtl@stuff}% + \dtl@message{Removed entry from column \number#1\space\space in database + `\dtldbname'}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtlswapentriesincurrentrow} +%\begin{definition} +%\cs{dtlswapentriesincurrentrow}\marg{col1 +%num}\marg{col2 num} +%\end{definition} +% Swaps columns \meta{col1 num} and \meta{col2 num} in \cs{dtlcurrentrow} +%\changes{2.10}{2012-07-18}{new} +% \begin{macrocode} +\newcommand*{\dtlswapentriesincurrentrow}[2]{% + \dtlgetentryfromcurrentrow{\@dtl@entryI}{#1}% + \dtlgetentryfromcurrentrow{\@dtl@entryII}{#2}% + \expandafter\dtlreplaceentryincurrentrow\expandafter + {\@dtl@entryII}{#1}% + \expandafter\dtlreplaceentryincurrentrow\expandafter + {\@dtl@entryI}{#2}% +} +% \end{macrocode} +%\end{macro} +% %\begin{macro}{\dtlgetentryfromcurrentrow} %\begin{definition} %\cs{dtlgetentryfromcurrentrow}\marg{cs}\marg{col num} @@ -11981,6 +6811,78 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} %\end{macro} % +%\begin{macro}{\dtlappendentrytocurrentrow} +%\begin{definition} +%\cs{dtlappendentrytocurrentrow}\marg{key}\marg{value} +%\end{definition} +% Appends entry to \cs{dtlcurrentrow} +%\changes{2.10}{2012-07-18}{new} +% \begin{macrocode} +\newcommand*{\dtlappendentrytocurrentrow}[2]{% +% \end{macrocode} +% Update information about this column (adding new column if +% necessary) +% \begin{macrocode} + \@dtl@updatekeys{\dtldbname}{#1}{#2}% +% \end{macrocode} +% Get column index and store in \cs{dtlcolumnnum} +% \begin{macrocode} + \expandafter\dtlcolumnnum\expandafter + =\dtlcolumnindex{\dtldbname}{#1}\relax +% \end{macrocode} +% Does this row already have an entry with this key? +% \begin{macrocode} + \edef\dtl@dogetentry{\noexpand\dtlgetentryfromcurrentrow + {\noexpand\dtl@entry}{\number\dtlcolumnnum}% + }% + \dtl@dogetentry + \ifx\dtl@entry\dtlnovalue +% \end{macrocode} +% There are no entries in this row for the given key. +% Expand entry value before storing. +% \begin{macrocode} + \protected@edef\@dtl@tmp{#2}% + \expandafter\@dtl@toks\expandafter{\@dtl@tmp}% +% \end{macrocode} +% Append this entry to the current row. +% \begin{macrocode} + \toks@gput@right@cx{dtlcurrentrow}% + {% +% \end{macrocode} +% Begin column index specs: +% \begin{macrocode} + \noexpand\db@col@id@w + \number\dtlcolumnnum + \noexpand\db@col@id@end@ +% \end{macrocode} +% New entry: +% \begin{macrocode} + \noexpand\db@col@elt@w + \the\@dtl@toks + \noexpand\db@col@elt@end@ +% \end{macrocode} +% End column index specs: +% \begin{macrocode} + \noexpand\db@col@id@w + \number\dtlcolumnnum + \noexpand\db@col@id@end@ + }% +% \end{macrocode} +% Print information to terminal and log file if in verbose mode. +% \begin{macrocode} + \dtl@message{Appended #1\space -> #2\space to database + `\dtldbname'}% + \else +% \end{macrocode} +% There is already an entry in this row for the given key +% \begin{macrocode} + \PackageError{datatool}{Can't append entry to row: + there is already an entry for key `#1' in this row}{}% + \fi +} +% \end{macrocode} +%\end{macro} +% %\begin{macro}{\DTLgetvalue} %\begin{definition} %\cs{DTLgetvalue}\marg{cs}\marg{db}\marg{r}\marg{c} @@ -12050,159 +6952,9 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} %\end{macro} -%\subsection{Iterating Through Databases} +%\section{Iterating Through Databases} %\label{sec:code:loops} % -%\begin{macro}{\dtlbreak} -% Break out of loop at the end of current iteration. -% \begin{macrocode} -\newcommand*{\dtlbreak}{% - \PackageError{datatool}{Can't break out of anything}{}% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\dtlforint} -%\begin{definition} -%\cs{dtlforint}\meta{ct}=\meta{start}\cs{to}\meta{end}\cs{step}% -%\meta{inc}\cs{do}\marg{body} -%\end{definition} -% \meta{ct} is a count register, \meta{start}, \meta{end} and -% \meta{inc} are integers. -% Group if nested or use \cs{dtlgforint}. -% An infinite loop may result if \meta{inc}$=0$ and -% \meta{start} $\le$ \meta{end} and \cs{dtlbreak} isn't used. -% \begin{macrocode} -\long\def\dtlforint#1=#2\to#3\step#4\do#5{% -% \end{macrocode} -% Make a copy of old version of break function -% \begin{macrocode} - \let\@dtl@orgbreak\dtlbreak - \def\@dtl@endloophook{}% -% \end{macrocode} -% Setup break function for the loop (sets \meta{ct} to \meta{end} -% at the end of the current iteration). -% \begin{macrocode} - \def\dtlbreak{\def\@dtl@endloophook{#1=#3}}% -% \end{macrocode} -% Initialise \meta{ct} -% \begin{macrocode} - #1=#2\relax -% \end{macrocode} -% Check if the steps are positive or negative. -% \begin{macrocode} - \ifnum#4<0\relax -% \end{macrocode} -% Counting down -% \begin{macrocode} - \whiledo{\(#1>#3\)\TE@or\(#1=#3\)}% - {% - #5% - \@dtl@endloophook - \advance#1 by #4\relax - }% - \else -% \end{macrocode} -% Counting up -% \begin{macrocode} - \whiledo{\(#1<#3\)\TE@or\(#1=#3\)}% - {% - #5% - \@dtl@endloophook - \advance#1 by #4\relax - }% - \fi -% \end{macrocode} -% Restore break function. -% \begin{macrocode} - \let\dtlbreak\@dtl@orgbreak -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@dtl@foreach@level} -% Count register to keep track of global nested loops. -% \begin{macrocode} -\newcount\@dtl@foreach@level -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\dtlgforint} -%\begin{definition} -%\cs{dtlgforint}\meta{ct}=\meta{start}\cs{to}\meta{end}\cs{step}% -%\meta{inc}\cs{do}\marg{body} -%\end{definition} -% \meta{ct} is a count register, \meta{start}, \meta{end} and -% \meta{inc} are integers. -% An infinite loop may result if \meta{inc}=0 and \meta{start} $\le$ -% \meta{end} and \cs{dtlbreak} isn't used. -% \begin{macrocode} -\long\def\dtlgforint#1=#2\to#3\step#4\do#5{% -% \end{macrocode} -% Initialise -% \begin{macrocode} - \global#1=#2\relax -% \end{macrocode} -% Increment level counter to allow for nested loops -% \begin{macrocode} - \global\advance\@dtl@foreach@level by 1\relax -% \end{macrocode} -% Set up end loop hook -% \begin{macrocode} - \expandafter\global\expandafter - \let\csname @dtl@endhook@\the\@dtl@foreach@level\endcsname - \relax -% \end{macrocode} -% Set up the break function: -% Copy current definition -% \begin{macrocode} - \expandafter\global\expandafter - \let\csname @dtl@break@\the\@dtl@foreach@level\endcsname - \dtlbreak -% \end{macrocode} -% Set up definition for this level (sets <ct> to <end> at the end -% of the current iteration). -% \begin{macrocode} - \gdef\dtlbreak{\expandafter - \gdef\csname @dtl@endhook@\the\@dtl@foreach@level\endcsname{% - #1=#3}}% -% \end{macrocode} -% check the direction -% \begin{macrocode} - \ifnum#4<0\relax -% \end{macrocode} -% Counting down -% \begin{macrocode} - \whiledo{\(#1>#3\)\TE@or\(#1=#3\)}% - {% - #5% - \csname @dtl@endhook@\the\@dtl@foreach@level\endcsname - \global\advance#1 by #4\relax - }% - \else -% \end{macrocode} -% Counting up (or 0 increments) -% \begin{macrocode} - \whiledo{\(#1<#3\)\TE@or\(#1=#3\)}% - {% - #5% - \csname @dtl@endhook@\the\@dtl@foreach@level\endcsname - \global\advance#1 by #4\relax - }% - \fi -% \end{macrocode} -% Restore break function -% \begin{macrocode} - \expandafter\global\expandafter\let\expandafter\dtlbreak - \csname @dtl@break@\the\@dtl@foreach@level\endcsname -% \end{macrocode} -% Decrement level counter -% \begin{macrocode} - \global\advance\@dtl@foreach@level by -1\relax -} -% \end{macrocode} -%\end{macro} -% %\begin{macro}{\@dtlforeachrow} %\begin{definition} %\cs{@dtlforeachrow}(\meta{idx cs},\meta{row cs})\cs{in}\marg{db}% @@ -12643,6 +7395,38 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} %\end{macro} % +%\begin{environment}{DTLenvforeach} +% Environment form of \cs{DTLforeach} (contents are gathered, so +% verbatim can't be used). +% \begin{macrocode} +\newenvironment{DTLenvforeach}[3][\boolean{true}]% +{% + \def\@dtlenvforeach@args{[#1]{#2}{#3}}% + \long@collect@body\@do@dtlenvforeach +}% +{} +\newcommand{\@do@dtlenvforeach}[1]{% + \expandafter\@DTLforeach\@dtlenvforeach@args{#1}% +} +% \end{macrocode} +%\end{environment} +% +%\begin{environment}{DTLenvforeach*} +% Environment form of \cs{DTLforeach*} (contents are gathered, so +% verbatim can't be used). +% \begin{macrocode} +\newenvironment{DTLenvforeach*}[3][\boolean{true}]% +{% + \def\s@dtlenvforeach@args{[#1]{#2}{#3}}% + \long@collect@body\@do@sdtlenvforeach +}% +{} +\newcommand{\@do@sdtlenvforeach}[1]{% + \expandafter\@sDTLforeach\s@dtlenvforeach@args{#1}% +} +% \end{macrocode} +%\end{environment} +% %\begin{macro}{\DTLforeach} %\begin{definition} % \cs{DTLforeach}\oarg{conditions}\marg{db name}\marg{values}\marg{text} @@ -12771,7 +7555,7 @@ options>#2=\textsf{#2}|hyperpage}} = 0\relax % \end{macrocode} % Loop through each row. -% Loop counter given by \cs{dtl@row@}\meta{level} +% Loop counter given by \cs{dtl@row}\meta{level} % \begin{macrocode} \dtlgforint \csname dtl@row\romannumeral\dtlforeachlevel\endcsname @@ -13609,7 +8393,73 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} %\end{macro} % -%\subsection{Displaying Database} +%\section{DTLforeach Conditionals} +% The following conditionals are only meant to be used within +% \cs{DTLforeach} as they depend on the counter +% \texttt{DTLrow}\meta{n}. +% +%\begin{macro}{\DTLiffirstrow} +%\begin{definition} +%\cs{DTLiffirstrow}\marg{true part}\marg{false part} +%\end{definition} +% Test if the current row is the first row. (This takes +% \meta{condition}, the optional argument of \cs{DTLforeach}, +% into account, so it may not correspond to row~1 of the +% database.) Can only be used in \cs{DTLforeachrow}. +%\changes{2.0}{2009 February 27}{modified to have different +% definition depending on location} +% \begin{macrocode} +\newcommand{\DTLiffirstrow}[2]{% + \PackageError{datatool}{\string\DTLiffirstrow\space can only + be used inside \string\DTLforeach}{}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLiflastrow} +%\begin{definition} +%\cs{DTLiflastrow}\marg{true part}\marg{false part} +%\end{definition} +% Checks if the current row is the last row of the database. +% It doesn't take the condition (the optional argument of +% \cs{DTLforeach}) into account, so its possible it may never +% do \meta{true part}, as the last row of the database may not +% meet the condition. It is therefore not very useful and is +% confusing since it behaves differently to \cs{DTLiffirstrow} +% which does take the condition into account, so I have removed +% its description from the main part of the manual. If you need +% to use the optional argument of \cs{DTLforeach}, you will first +% have to iterate through the database to count up the number +% of rows which meet the condition, and then do another pass, +% checking if the current row has reached that number. +%\changes{1.01}{2007 Aug 17}{fixed bug} +%\changes{2.0}{2009 February 27}{modified to have different +% definition depending on location} +% \begin{macrocode} +\newcommand{\DTLiflastrow}[2]{% + \PackageError{datatool}{\string\DTLiflastrow\space can only + be used inside \string\DTLforeach}{}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLifoddrow} +%\begin{definition} +%\cs{DTLifoddrow}\marg{true part}\marg{false part} +%\end{definition} +% Determines whether the current row is odd (takes the optional +% argument of \cs{DTLforeach} into account.) +%\changes{2.0}{2009 February 27}{modified to have different +% definition depending on location} +% \begin{macrocode} +\newcommand{\DTLifoddrow}[2]{% + \PackageError{datatool}{\string\DTLifoddrow\space can only + be used inside \string\DTLforeach}{}% +} +% \end{macrocode} +%\end{macro} +% +%\section{Displaying Database} % This section defines commands to display the entire database % in a \env{tabular} or \env{longtable} environment. % @@ -13677,9 +8527,11 @@ options>#2=\textsf{#2}|hyperpage}} \else \protected@edef#1{#1\dtlbetweencols}% \fi - \ifx\@empty#2\@empty + \ifstrempty{#2}% + {% \protected@edef#1{#1c}% - \else + }% + {% \ifcase#2\relax % \end{macrocode} % string @@ -13707,7 +8559,7 @@ options>#2=\textsf{#2}|hyperpage}} \protected@edef#1{#1c}% \PackageError{datatool}{Unknown data type `#2'}{}% \fi - \fi + }% \ifnum#3=#4\relax \protected@edef#1{#1\dtlaftercols}% \fi @@ -13804,12 +8656,13 @@ options>#2=\textsf{#2}|hyperpage}} %\begin{macro}{\DTLdisplaydb} %\begin{definition} -%\cs{DTLdisplaydb}\marg{db} +%\cs{DTLdisplaydb}\oarg{omit list}\marg{db} %\end{definition} % Displays the database \meta{db} in a tabular environment. %\changes{2.0}{2009 February 27}{new} +%\changes{2.10}{2012-07-18}{added optional arg} % \begin{macrocode} -\newcommand*{\DTLdisplaydb}[1]{% +\newcommand*{\DTLdisplaydb}[2][]{% % \end{macrocode} % Initialise: % only want "&" between columns @@ -13820,15 +8673,25 @@ options>#2=\textsf{#2}|hyperpage}} % Store maximum number of columns % \begin{macrocode} \edef\@dtl@maxcols{\expandafter\number - \csname dtlcols@#1\endcsname}% + \csname dtlcols@#2\endcsname}% +% \end{macrocode} +% Subtract number of omitted columns +% \begin{macrocode} + \DTLnumitemsinlist{#1}{\@dtl@tmp}% + \dtlsub{\@dtl@maxcols}{\@dtl@maxcols}{\@dtl@tmp}% + \dtlclip{\@dtl@maxcols}{\@dtl@maxcols}% % \end{macrocode} % Argument for tabular environment % \begin{macrocode} \def\@dtl@tabargs{}% \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)% - \in{#1}\do + \in{#2}\do {% - \dtladdalign\@dtl@tabargs\@dtl@type\@dtl@idx\@dtl@maxcols + \expandafter\DTLifinlist\expandafter{\@dtl@key}{#1}% + {}% + {% + \dtladdalign\@dtl@tabargs\@dtl@type\@dtl@idx\@dtl@maxcols + } }% % \end{macrocode} % Begin tabular environment @@ -13848,10 +8711,14 @@ options>#2=\textsf{#2}|hyperpage}} % Do the header row. % \begin{macrocode} \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)% - \in{#1}\do + \in{#2}\do {% - \@dtl@doamp - \dtlheaderformat{\@dtl@head}% + \expandafter\DTLifinlist\expandafter{\@dtl@key}{#1}% + {}% + {% + \@dtl@doamp + \dtlheaderformat{\@dtl@head}% + }% }% \\% % \end{macrocode} @@ -13866,7 +8733,7 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} % Iterate through each row of the database % \begin{macrocode} - \DTLforeach*{#1}{}{% + \@sDTLforeach{#2}{}{% % \end{macrocode} % Do the start row hook if not the first row % \begin{macrocode} @@ -13881,29 +8748,33 @@ options>#2=\textsf{#2}|hyperpage}} % \begin{macrocode} \DTLforeachkeyinrow{\@dtl@val}% {% + \expandafter\DTLifinlist\expandafter{\dtlkey}{#1}% + {}% + {% % \end{macrocode} % Need to make value global as it needs to be used after the % ampersand. % \begin{macrocode} - \global\let\@dtl@val\@dtl@val - \@dtl@doamp + \global\let\@dtl@val\@dtl@val + \@dtl@doamp % \end{macrocode} % \cs{DTLforeachkeyinrow} sets \cs{dtltype} to the data type % for the current key. This can be used to determine which % format to use for this entry. % \begin{macrocode} - \@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 + \@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 @@ -13940,6 +8811,10 @@ options>#2=\textsf{#2}|hyperpage}} % \begin{macrocode} \define@key{displaylong}{lastfoot}{\def\@dtl@lastfoot{#1}} % \end{macrocode} +% List of omitted columns +% \begin{macrocode} +\define@key{displaylong}{omit}{\def\@dtl@omitlist{#1}} +% \end{macrocode} % %\begin{macro}{\@dtl@resetdostartrow} % Resets start row hook so that it skips the first row. @@ -13958,6 +8833,7 @@ options>#2=\textsf{#2}|hyperpage}} % Displays the database \meta{db} in a longtable environment. % (User needs to load \sty{longtable}). %\changes{2.0}{2009 February 27}{new} +%\changes{2.10}{2012-07-18}{added omit option} % \begin{macrocode} \newcommand*{\DTLdisplaylongdb}[2][]{% % \end{macrocode} @@ -13969,6 +8845,7 @@ options>#2=\textsf{#2}|hyperpage}} \def\@dtl@shortcap{\@dtl@cap}% \def\@dtl@foot{\@nil}% \def\@dtl@lastfoot{\@nil}% + \def\@dtl@omitlist{}% % \end{macrocode} % Set the options % \begin{macrocode} @@ -13985,13 +8862,23 @@ options>#2=\textsf{#2}|hyperpage}} \edef\@dtl@maxcols{\expandafter\number \csname dtlcols@#2\endcsname}% % \end{macrocode} +% Subtract number of omitted columns +% \begin{macrocode} + \DTLnumitemsinlist{\@dtl@omitlist}{\@dtl@tmp}% + \dtlsub{\@dtl@maxcols}{\@dtl@maxcols}{\@dtl@tmp}% + \dtlclip{\@dtl@maxcols}{\@dtl@maxcols}% +% \end{macrocode} % Argument for \env{longtable} environment % \begin{macrocode} \def\@dtl@tabargs{}% \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)% \in{#2}\do {% - \dtladdalign\@dtl@tabargs\@dtl@type\@dtl@idx\@dtl@maxcols + \expandafter\DTLifinlist\expandafter{\@dtl@key}{\@dtl@omitlist}% + {}% + {% + \dtladdalign\@dtl@tabargs\@dtl@type\@dtl@idx\@dtl@maxcols + }% }% % \end{macrocode} % Start the \env{longtable} environment. @@ -14026,7 +8913,13 @@ options>#2=\textsf{#2}|hyperpage}} \@dtl@resetdoamp \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)% \in{#2}\do - {\@dtl@doamp{\dtlheaderformat{\@dtl@head}}}% + {% + \expandafter\DTLifinlist\expandafter{\@dtl@key}{\@dtl@omitlist}% + {}% + {% + \@dtl@doamp{\dtlheaderformat{\@dtl@head}}% + }% + }% \@dtl@resetdoamp \@dtl@resetdostartrow \endhead\dtldisplayafterhead @@ -14049,7 +8942,13 @@ options>#2=\textsf{#2}|hyperpage}} \@dtl@resetdoamp \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)% \in{#2}\do - {\@dtl@doamp{\dtlheaderformat{\@dtl@head}}}% + {% + \expandafter\DTLifinlist\expandafter{\@dtl@key}{\@dtl@omitlist}% + {}% + {% + \@dtl@doamp{\dtlheaderformat{\@dtl@head}}% + }% + }% \@dtl@resetdoamp \@dtl@resetdostartrow \endfirsthead @@ -14068,7 +8967,13 @@ options>#2=\textsf{#2}|hyperpage}} \@dtl@resetdoamp \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)% \in{#2}\do - {\@dtl@doamp{\dtlheaderformat{\@dtl@head}}}% + {% + \expandafter\DTLifinlist\expandafter{\@dtl@key}{\@dtl@omitlist}% + {}% + {% + \@dtl@doamp{\dtlheaderformat{\@dtl@head}}% + }% + }% \@dtl@resetdoamp \@dtl@resetdostartrow \endhead\dtldisplayafterhead @@ -14076,7 +8981,7 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} % Iterate through each row of the database % \begin{macrocode} - \DTLforeach*{#2}{}{% + \@sDTLforeach{#2}{}{% \@dtl@dostartrow \@dtl@resetdoamp % \end{macrocode} @@ -14085,22 +8990,26 @@ options>#2=\textsf{#2}|hyperpage}} \DTLforeachkeyinrow{\@dtl@val}% {% \global\let\@dtl@val\@dtl@val - \@dtl@doamp + \expandafter\DTLifinlist\expandafter{\dtlkey}{\@dtl@omitlist}% + {}% + {% + \@dtl@doamp % \end{macrocode} % \cs{DTLforeachkeyinrow} sets \cs{dtltype} to the data type % for the current key. This can be used to determine which % format to use for this entry. % \begin{macrocode} - \@dtl@datatype=0\dtltype\relax - \ifcase\@dtl@datatype - \dtlstringformat\@dtl@val - \or - \dtlintformat\@dtl@val - \or - \dtlrealformat\@dtl@val - \or - \dtlcurrencyformat\@dtl@val - \fi + \@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 @@ -14110,7 +9019,7 @@ options>#2=\textsf{#2}|hyperpage}} %\end{macro} % % -%\subsection{Editing Databases} +%\section{Editing Databases} % %\begin{macro}{\dtlswaprows} %\begin{definition} @@ -14118,7 +9027,7 @@ options>#2=\textsf{#2}|hyperpage}} %\end{definition} % Swaps the rows with indices \meta{row1 idx} and \meta{row2 idx} % in the database \meta{db}. -% (Doesn't check if data base exists of if indices are out of +% (Doesn't check if data base exists or if indices are out of % bounds.) % \begin{macrocode} \newcommand*{\dtlswaprows}[3]{% @@ -14334,7 +9243,7 @@ options>#2=\textsf{#2}|hyperpage}} %\begin{definition} %\cs{@DTLremoverow}\marg{db}\marg{row index} %\end{definition} -% Doesn't perform any checks for the existance of the database +% Doesn't perform any checks for the existence of the database % or if the index is in range. %\changes{2.0}{2009 February 27}{new} % \begin{macrocode} @@ -14366,7 +9275,7 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} %\end{macro} % -%\subsection{Database Functions} +%\section{Database Functions} % %\begin{macro}{\DTLsumforkeys} %\begin{definition} @@ -14525,7 +9434,7 @@ options>#2=\textsf{#2}|hyperpage}} % Divide total by number of elements summed. % \begin{macrocode} \ifnum\@dtl@elements=0\relax - \PackageError{datatool}{Unable to evaluate mean: no data}{}% +% \PackageError{datatool}{Unable to evaluate mean: no data}{}% \else \edef\@dtl@n{\number\@dtl@elements}% \DTLdiv{#4}{#4}{\@dtl@n}% @@ -14811,11 +9720,13 @@ options>#2=\textsf{#2}|hyperpage}} \dtlgetentryfromrow{\DTLthisval}{\@dtl@col}{\dtlcurrentrow}% \expandafter\ifthenelse\expandafter{\@dtl@cond}% {% - \ifx#4\@empty + \ifstrempty{#4}% + {% \let#4\DTLthisval - \else + }% + {% \DTLmin{#4}{#4}{\DTLthisval}% - \fi + }% }{}% }% }% @@ -14848,11 +9759,13 @@ options>#2=\textsf{#2}|hyperpage}} {% \@sdtlforcolumn{\DTLthisval}{#1}{#2}% {% - \ifx#3\@empty + \ifdefempty{#3}% + {% \let#3\DTLthisval - \else + }% + {% \DTLmin{#3}{#3}{\DTLthisval}% - \fi + }% }% }% % \end{macrocode} @@ -14919,11 +9832,13 @@ options>#2=\textsf{#2}|hyperpage}} \dtlgetentryfromrow{\DTLthisval}{\@dtl@col}{\dtlcurrentrow}% \expandafter\ifthenelse\expandafter{\@dtl@cond}% {% - \ifx#4\@empty + \ifdefempty{#4}% + {% \let#4\DTLthisval - \else + }% + {% \DTLmax{#4}{#4}{\DTLthisval}% - \fi + }% }{}% }% }% @@ -14956,11 +9871,13 @@ options>#2=\textsf{#2}|hyperpage}} {% \@sdtlforcolumn{\DTLthisval}{#1}{#2}% {% - \ifx#3\@empty + \ifdefempty{#3}% + {% \let#3\DTLthisval - \else + }% + {% \DTLmax{#3}{#3}{\DTLthisval}% - \fi + }% }% }% % \end{macrocode} @@ -15000,18 +9917,18 @@ options>#2=\textsf{#2}|hyperpage}} \let#8=\relax \@for\dtl@thisdb:=#2\do{% \@sDTLforeach[#1]{\dtl@thisdb}{\DTLthisX=#3,\DTLthisY=#4}{% - \DTLconverttodecimal{\DTLthisX}{\dtl@decx}% - \DTLconverttodecimal{\DTLthisY}{\dtl@decy}% + \expandafter\DTLconverttodecimal\expandafter{\DTLthisX}{\dtl@decx}% + \expandafter\DTLconverttodecimal\expandafter{\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}% + \dtlmin{#5}{#5}{\dtl@decx}% + \dtlmin{#6}{#6}{\dtl@decy}% + \dtlmax{#7}{#7}{\dtl@decx}% + \dtlmax{#8}{#8}{\dtl@decy}% \fi }% }% @@ -15086,29 +10003,7 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} %\end{macro} % -%\begin{macro}{\dtlsplitrow} -%\begin{definition} -%\cs{dtlsplitrow}\marg{row specs}\marg{col num}\marg{before -% cs}\marg{after cs} -%\end{definition} -% Splits the row around the entry given by \meta{col num}. The -% entries before the split are stored in \meta{before cs} and the -% entries after the split are stored in \meta{after cs}. -% \meta{row specs} and \meta{col num} need to be expanded before use. -% \begin{macrocode} -\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 -} -% \end{macrocode} -%\end{macro} -% -%\subsection{Sorting Databases} +%\section{Sorting Databases} % %\begin{macro}{\@dtl@list} % Token register to store data when sorting. @@ -15577,12 +10472,14 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} % Check if a direction was specified. % \begin{macrocode} - \ifx\@dtl@sortdirection\@empty + \ifdefempty{\@dtl@sortdirection}% + {% % \end{macrocode} % No direction specified so assume ascending. % \begin{macrocode} \def\@dtl@sortdirection{-1}% - \else + }% + {% % \end{macrocode} % Get the sort direction from the second argument (needs terminating % equal sign removed) and store in \cs{@dtl@sortdirection}. @@ -15622,7 +10519,7 @@ options>#2=\textsf{#2}|hyperpage}} \def\@dtl@sortdirection{-1} \fi \fi - \fi + }% } % \end{macrocode} %\end{macro} @@ -15643,12 +10540,6 @@ options>#2=\textsf{#2}|hyperpage}} \newtoks\@dtl@toksB % \end{macrocode} %\end{macro} -%\begin{macro}{\@dtl@toks} -% \begin{macrocode} -\newtoks\@dtl@toks -% \end{macrocode} -%\end{macro} -% %\begin{macro}{\dtl@compare} %\begin{definition} %\cs{dtl@compare}\marg{key}\marg{a toks}\marg{b toks} @@ -15765,7 +10656,7 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} %\end{macro} % -%\subsection{Saving a database to an external file} +%\section{Saving a database to an external file} % %\begin{macro}{\@dtl@write} % \begin{macrocode} @@ -15800,24 +10691,28 @@ options>#2=\textsf{#2}|hyperpage}} {% \IfSubStringInString{\@dtl@separator}{\@dtl@key}% {% - \ifx\@dtl@header\@empty + \ifdefempty{\@dtl@header}% + {% \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 + \ifdefempty{\@dtl@header}% + {% \protected@edef\@dtl@header{\@dtl@key}% - \else + }% + {% \toks@=\expandafter{\@dtl@header}% \protected@edef\@dtl@header{\the\toks@ \@dtl@separator\@dtl@key}% - \fi + }% }% }% % \end{macrocode} @@ -15840,23 +10735,27 @@ options>#2=\textsf{#2}|hyperpage}} {% \IfSubStringInString{\@dtl@separator}{\@dtl@val}% {% - \ifx\@dtl@row\@empty + \ifdefempty{\@dtl@row}% + {% \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 + \ifdefempty{\@dtl@row}% + {% \protected@edef\@dtl@row{\@dtl@val}% - \else + }% + {% \toks@=\expandafter{\@dtl@row}% \protected@edef\@dtl@row{\the\toks@\@dtl@separator \@dtl@val}% - \fi + }% }% }% % \end{macrocode} @@ -15944,11 +10843,8 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} %\end{macro} % -%\subsection{Loading a database from an external file} +%\section{Loading a database from an external file} % -% \begin{macrocode} -\newcommand{\@longempty}{} -% \end{macrocode} %\begin{macro}{\@dtl@read} % \begin{macrocode} \newread\@dtl@read @@ -16000,6 +10896,13 @@ options>#2=\textsf{#2}|hyperpage}} } % \end{macrocode} % +% The following is supplied in a patch by Bruno Le Floch: +%\changes{2.10}{2012-07-18}{added omitlines key} +% \begin{macrocode} +\newcount{\dtl@omitlines} +\define@key{loaddb}{omitlines}{\dtl@omitlines=#1\relax} +% \end{macrocode} +% %\begin{macro}{\dtldefaultkey} % Default key to use if none specified (column index will be % appended). @@ -16022,7 +10925,12 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} % Trim the end of line character % \begin{macrocode} - \dtl@trim#2% + \ifdefempty{#2}% + {% + }% + {% + \dtl@trim#2% + } } % \end{macrocode} %\end{macro} @@ -16049,7 +10957,7 @@ options>#2=\textsf{#2}|hyperpage}} } % \end{macrocode} %\end{macro} - +% %\begin{macro}{\DTLloaddb} %\begin{definition} % \cs{DTLloaddb}\oarg{options}\marg{db name}\marg{filename} @@ -16098,6 +11006,15 @@ options>#2=\textsf{#2}|hyperpage}} \openin\@dtl@read=#3% \dtl@message{Reading `#3'}% % \end{macrocode} +% The following supplied in patch by Bruno Le~Floch: +%\changes{2.10}{2012-07-18}{added code to skip lines} +% \begin{macrocode} + \loop + \ifnum \dtl@omitlines > \z@ + \advance\dtl@omitlines by \m@ne + \read\@dtl@read to \@dtl@line + \repeat +% \end{macrocode} % Create the new database. % \begin{macrocode} \DTLnewdb{#2}% @@ -16135,9 +11052,12 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} % If this is a blank row, set repeat condition to true % \begin{macrocode} - \ifx\@dtl@line\@longempty + \ifdefempty{\@dtl@line}% + {% \@dtl@conditiontrue - \fi + }% + {% + }% \fi % \end{macrocode} % Repeat loop if necessary @@ -16170,6 +11090,15 @@ options>#2=\textsf{#2}|hyperpage}} % \begin{macrocode} \advance\dtl@entrycr by 1\relax % \end{macrocode} +% If missing a key, add generic one: +%\changes{2.10}{2012-07-18}{add generic header if missing} +% \begin{macrocode} + \ifdefempty{\@dtl@key}% + {% + \edef\@dtl@key{\dtldefaultkey\number\dtl@entrycr}% + }% + {}% +% \end{macrocode} % Store key in \cs{@dtl@toks} % \begin{macrocode} \expandafter\@dtl@toks\expandafter{\@dtl@key}% @@ -16239,12 +11168,15 @@ options>#2=\textsf{#2}|hyperpage}} % Check if the line is empty. %\changes{2.0}{2009 February 27}{changed \cs{ifthenelse} to %\cs{ifx} to improve efficiency} +%\changes{2.10}{2012-07-16}{changed \cs{ifx} to \cs{ifdefempty}} % \begin{macrocode} - \ifx\@dtl@line\@longempty + \ifdefempty{\@dtl@line}% + {% % \end{macrocode} % Do nothing if the row is empty. % \begin{macrocode} - \else + }% + {% % \end{macrocode} % Add a new row to the database. (Don't need to check if the % database exists, since it's just been created.) @@ -16327,7 +11259,7 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} % End of parsing this row % \begin{macrocode} - \fi + }% % \end{macrocode} % If the end of file has been reached, set the repeat condition % to false. @@ -16390,22 +11322,30 @@ options>#2=\textsf{#2}|hyperpage}} % Trims the trailing space from \meta{line}. % \begin{macrocode} \newcommand{\dtl@trim}[1]{% -\def\@dtl@trmstr{}% -\expandafter\@dtl@starttrim#1\@nil% -\let#1=\@dtl@trmstr + \def\@dtl@trmstr{}% + \expandafter\@dtl@starttrim#1\@nil + \let#1=\@dtl@trmstr } % \end{macrocode} %\end{macro} %\begin{macro}{\@dtl@starttrim} % Start trimming +%\changes{2.10}{2012-07-18}{added check in the event there's no +%trailing space} % \begin{macrocode} \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% + \def\@dtl@tmpB{#2}% + \ifx\par#1% + \def\@dtl@dotrim{\@dtl@trim{} #2}% + \else + \ifx\@dtl@tmpB\@nnil + \def\@dtl@dotrim{}% + \def\@dtl@trmstr{#1}% + \else + \def\@dtl@dotrim{\@dtl@trim#1#2}% + \fi + \fi + \@dtl@dotrim } % \end{macrocode} %\end{macro} @@ -16503,13 +11443,15 @@ options>#2=\textsf{#2}|hyperpage}} % Additional mappings to perform when reading a raw data file % \begin{macrocode} \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 + \expandafter\@dtl@toks\expandafter{\@dtl@rawmappings}% + \ifdefempty{\@dtl@rawmappings}% + {% + \def\@dtl@rawmappings{{#1}{#2}}% + }% + {% + \def\@dtl@tmp{{#1}{#2}} + \protected@edef\@dtl@rawmappings{\the\@dtl@toks,\@dtl@tmp} + }% } % \end{macrocode} %\end{macro} @@ -16525,1434 +11467,4070 @@ options>#2=\textsf{#2}|hyperpage}} % \cs{dtl@domappings}\marg{cmd} %\end{definition} % Do all mappings in string given by \meta{cmd}. +%\changes{2.10}{2012-07-18}{replaced \cs{DTLsubstitute} with +%\cs{DTLsubstituteall}} % \begin{macrocode} \newcommand*{\dtl@domappings}[1]{% -\@for\@dtl@map:=\@dtl@rawmappings\do{% - \expandafter\DTLsubstitute\expandafter#1\@dtl@map -}} + \@for\@dtl@map:=\@dtl@rawmappings\do{% + \expandafter\DTLsubstituteall\expandafter#1\@dtl@map + }% +} % \end{macrocode} %\end{macro} % -%\subsection{General List Utilities} +%\section{Debugging commands} +% These commands are provided to assist debugging +%\begin{macro}{\dtlshowdb} +%\begin{definition} +%\cs{dtlshowdb}\marg{db name} +%\end{definition} +% Shows the database. +%\changes{2.0}{2009 February 27}{updated to use new database structure} +% \begin{macrocode} +\newcommand*{\dtlshowdb}[1]{% + \expandafter\showthe\csname dtldb@#1\endcsname +} +% \end{macrocode} +%\end{macro} % -%\begin{macro}{\DTLifinlist} +%\begin{macro}{\dtlshowdbkeys} %\begin{definition} -%\cs{DTLifinlist}\marg{element}\marg{list}\marg{true part}\marg{false part} +%\cs{dtlshowdbkeys}\marg{db name} %\end{definition} -% If \meta{element} is contained in the comma-separated list given -% by \meta{list}, then do \meta{true part} otherwise do false -% part. (Does a one level expansion on \meta{list}, but no -% expansion on \meta{element}.) +% Shows the key list for the named database. +%\changes{2.0}{2009 February 27}{updated to use new database structure} % \begin{macrocode} -\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 -% not found - #4% - \else -% found - #3% - \fi +\newcommand*{\dtlshowdbkeys}[1]{% + \expandafter\showthe\csname dtlkeys@#1\endcsname } % \end{macrocode} %\end{macro} % -%\begin{macro}{\dtl@choplast} +%\begin{macro}{\dtlshowtype} %\begin{definition} -% \cs{dtl@choplast}\marg{list}\marg{rest}\marg{last} +%\cs{dtlshowtype}\marg{db name}\marg{key} %\end{definition} -% Chops the last element off a comma separated list, putting the -% last element in the control sequence \meta{last} and putting -% the rest in the control sequence \meta{rest}. The control -% sequence \meta{list} is unchanged. If the list is empty, both -% \meta{last} and \meta{rest} will be empty. +% Show the data type for given key in the named database. +% This should be an integer from 0 to 3. +%\changes{2.0}{2009 February 27}{updated to use new database structure} % \begin{macrocode} -\newcommand*{\dtl@choplast}[3]{% +\newcommand*{\dtlshowtype}[2]{% + \DTLgetdatatype{\@dtl@type}{#1}{#2}\show\@dtl@type +} % \end{macrocode} -% Set \meta{rest} to empty: +%\end{macro} +%\iffalse % \begin{macrocode} -\let#2\@empty +%</datatool.sty> % \end{macrocode} -% Set \meta{last} to empty: +%\fi +%\iffalse % \begin{macrocode} -\let#3\@empty +%<*databib.sty> % \end{macrocode} -% Iterate through \meta{list}: +%\fi +%\chapter{databib.sty} +%\label{sec:src:databib} +%\section{Package Declaration} % \begin{macrocode} -\@for\@dtl@element:=#1\do{% -\ifx#3\@empty +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{databib}[2012/07/18 v2.10 (NLCT)] % \end{macrocode} -% First iteration, don't set \meta{rest}. +% Load required packages: % \begin{macrocode} -\else - \ifx#2\@empty +\RequirePackage{datatool} % \end{macrocode} -% Second iteration, set \meta{rest} to \meta{last} (which is -% currently set to the previous value: +%\section{Package Options} +%\begin{macro}{\dtlbib@style} +%The default bib style is stored in \cs{dtlbib@style}. % \begin{macrocode} - \expandafter\toks@\expandafter{#3}% - \edef#2{{\the\toks@}}% - \else +\newcommand*{\dtlbib@style}{plain} % \end{macrocode} -% Subsequent iterations, set \meta{rest} to \meta{rest},\meta{last} -% (\meta{last} is currently set to the previous value): +%\end{macro} +% The \pkgopt[databib]{style} package option sets \cs{dtlbib@style}. % \begin{macrocode} - \expandafter\toks@\expandafter{#3}% - \expandafter\@dtl@toks\expandafter{#2}% - \edef#2{\the\@dtl@toks,{\the\toks@}}% - \fi +\define@choicekey{databib.sty}{style}{plain,abbrv,alpha}{% +\def\dtlbib@style{#1}} +% \end{macrocode} +% Process package options: +% \begin{macrocode} +\ProcessOptionsX +% \end{macrocode} +%\section{Loading BBL file} +%\begin{macro}{\DTLloadbbl} +%\begin{definition} +%\cs{DTLloadbib}\oarg{bbl file}\marg{db name}\marg{bib list} +%\end{definition} +% \begin{macrocode} +\newcommand*{\DTLloadbbl}[3][\jobname.bbl]{% +\bibliographystyle{databib}% +\if@filesw + \immediate\write\@auxout{\string\bibdata{#3}}% \fi +\DTLnewdb{#2}% +\edef\DTLBIBdbname{#2}% +\@input@{#1}} % \end{macrocode} -% Now set \meta{last} to current element. +%\end{macro} +%\begin{macro}{\DTLnewbibrow} +% \cs{DTLnewbibrow} adds a new row to the bibliography database. +% (\cs{DTLBIBdbname} must be set prior to use to the name +% of the \sty{datatool} database which must exist. Any check +% to determine its existence should be performed when +% \cs{DTLBIBdbname} is set.) +%\changes{1.03}{2009 January 27}{removed check if database exists} % \begin{macrocode} -\let#3=\@dtl@element% -}% -} +\newcommand*{\DTLnewbibrow}{\@DTLnewrow{\DTLBIBdbname}} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLnewbibitem} +%\begin{definition} +%\cs{DTLnewbibitem}\marg{key}\marg{value} +%\end{definition} +% Adds a new database entry with the given key and value. +%\changes{1.03}{2009 January 27}{removed check if database exists} +% \begin{macrocode} +\newcommand*{\DTLnewbibitem}[2]{% + \@DTLnewdbentry{\DTLBIBdbname}{#1}{#2}} +% \end{macrocode} +%\end{macro} +%\section{Predefined text} +%\label{sec:src:bibnames} +%\begin{macro}{\andname} +% \begin{macrocode} +\providecommand*{\andname}{and} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\ofname} +% \begin{macrocode} +\providecommand*{\ofname}{of} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\inname} +% \begin{macrocode} +\providecommand*{\inname}{in} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\etalname} +% \begin{macrocode} +\providecommand*{\etalname}{et al.} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\editorname} +% \begin{macrocode} +\providecommand*{\editorname}{editor} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\editorsname} +% \begin{macrocode} +\providecommand*{\editorsname}{editors} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\volumename} +% \begin{macrocode} +\providecommand*{\volumename}{volume} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\numbername} +% \begin{macrocode} +\providecommand*{\numbername}{number} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\pagesname} +% \begin{macrocode} +\providecommand*{\pagesname}{pages} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\pagename} +% \begin{macrocode} +\providecommand*{\pagename}{page} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\editionname} +% \begin{macrocode} +\providecommand*{\editionname}{edition} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\techreportname} +% \begin{macrocode} +\providecommand*{\techreportname}{Technical report} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\mscthesisname} +% \begin{macrocode} +\providecommand*{\mscthesisname}{Master's thesis} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\phdthesisname} +% \begin{macrocode} +\providecommand*{\phdthesisname}{PhD thesis} % \end{macrocode} %\end{macro} % -%\begin{macro}{\dtl@chopfirst} +% +%\section{Displaying the bibliography} +%\label{sec:src:displaybib} %\begin{definition} -% \cs{dtl@chopfirst}\marg{list}\marg{first}\marg{rest} +%\cs{DTLbibliography}\marg{bib dbname} %\end{definition} -% Chops first element off \meta{list} and store in \meta{first}. -% The remainder of the list is stored in \meta{rest}. (\meta{list} -% remains unchanged.) +% Displays the bibliography for the database \meta{bib dbname} +% which must have previously been loaded using +% \cs{DTLloadbbl}. +%\begin{macro}{\DTLbibliography} % \begin{macrocode} -\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*{\DTLbibliography}[2][\boolean{true}]{% + \begin{DTLthebibliography}[#1]{#2}% + \DTLforeachbibentry[#1]{#2}{% + \DTLbibitem \DTLformatbibentry \DTLendbibitem + }% + \end{DTLthebibliography}% } % \end{macrocode} %\end{macro} % -%\begin{macro}{\dtl@sortlist} +%\begin{macro}{\DTLformatbibentry} %\begin{definition} -% \cs{dtl@sortlist}\marg{list}\marg{criteria cmd} +%\cs{DTLformatbibentry} %\end{definition} -% Performs an insertion sort on \meta{list}, where \meta{criteria cmd} -% is a macro which takes two arguments \meta{a} and \meta{b}. -% \meta{criteria cmd} must set the count register \cs{dtl@sortresult} -% to either -1 (\meta{a} less than \meta{b}), 0 (\meta{a} is -% equal to \meta{b}) or 1 (\meta{a} is greater than \meta{b}.) +% Formats the current bib entry. % \begin{macrocode} -\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*{\DTLformatbibentry}{% +% \end{macrocode} +% Check format for this type is defined. +% \begin{macrocode} + \@ifundefined{DTLformat\DBIBentrytype}% + {% + \PackageError{databib}{Don't know how to format bibliography + entries of type `\DBIBentrytype'}{}% + }% + {% +% \end{macrocode} +% Print information to terminal and log file if in verbose mode. +% \begin{macrocode} + \dtl@message{[\DBIBcitekey]}% +% \end{macrocode} +% Initialise +% \begin{macrocode} + \DTLstartsentencefalse\DTLmidsentencefalse\DTLperiodfalse +% \end{macrocode} +% Format this entry +% \begin{macrocode} + \csname DTLformat\DBIBentrytype\endcsname + }% } % \end{macrocode} %\end{macro} +%\begin{macro}{\DTLendbibitem} +% Hook to add extra information at the end of a bibliography item. +% This does nothing by default. +% \begin{macrocode} +\newcommand*{\DTLendbibitem}{} +% \end{macrocode} +%\end{macro} % -%\begin{macro}{\dtl@insertinto} +%\begin{macro}{\DTLwidest} +%Define a length to store the widest bib entry label +% \begin{macrocode} +\newlength\dtl@widest +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLcomputewidestbibentry} %\begin{definition} -% \cs{dtl@insertinto}\marg{element}\marg{sorted-list}\marg{criteria cmd} +%\cs{DTLcomputewidestbibentry}\marg{conditions}\marg{db +%name}\marg{bib label}\marg{cmd} %\end{definition} -% Inserts \meta{element} into the sorted list \meta{sorted-list} -% according to the criteria given by \meta{criteria cmd} (see above.) +%Computes the widest bibliography entry over all entries satisfying +%\meta{condition} for the database called \meta{db name}, where +% the bibliography label is formated according to \meta{bib label} and +% stores the result in \meta{cmd} which must be a command name. % \begin{macrocode} -\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}% +\newcommand*{\DTLcomputewidestbibentry}[4]{% +\dtl@widest=0pt\relax +\let#4=\@empty +\DTLforeachbibentry[#1]{#2}{% +\settowidth{\dtl@tmplength}{#3}% +\ifdim\dtl@tmplength>\dtl@widest\relax + \dtl@widest=\dtl@tmplength + \protected@edef#4{#3}% \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 } % \end{macrocode} %\end{macro} -%\begin{macro}{\if@dtl@insertdone} -% Define conditional to indicate whether the new entry has -% been inserted into the sorted list. +% +%\begin{macro}{\DTLforeachbibentry} +%\begin{definition} +%\cs{DTLforeachbibentry}\oarg{condition}\marg{db name}\marg{text} +%\end{definition} +%\begin{definition} +%\cs{DTLforeachbibentry*}\oarg{condition}\marg{db name}\marg{text} +%\end{definition} +% Iterates through the database called \meta{db name} and does +% \meta{text} if \meta{condition} is met. As with +% \cs{DTLforeach}, the starred version is read only. % \begin{macrocode} -\newif\if@dtl@insertdone +\newcommand*{\DTLforeachbibentry}{% +\@ifstar\@DTLforeachbibentry\@DTLforeachbibentry} % \end{macrocode} %\end{macro} -%\begin{macro}{\dtl@sortresult} -% Define \cs{dtl@sortresult} to be set by comparision macro. +%\begin{macro}{\@DTLforeachbibentry} +% Unstarred version % \begin{macrocode} -\newcount\dtl@sortresult +\newcommand*{\@DTLforeachbibentry}[3][\boolean{true}]{% +% \end{macrocode} +% Store database name. +% \begin{macrocode} + \edef\DBIBname{#2}% +% \end{macrocode} +% Reset row counter. +% \begin{macrocode} + \setcounter{DTLbibrow}{0}% +% \end{macrocode} +% Iterate through the database. +% \begin{macrocode} + \@DTLforeach{#2}{\DBIBcitekey=CiteKey,\DBIBentrytype=EntryType}% + {% + \dtl@gathervalues{#2}{\dtlcurrentrow}% + \ifthenelse{#1}{\refstepcounter{DTLbibrow}#3}{}% + }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\@sDTLforeachbibentry} +% Starred version +% \begin{macrocode} +\newcommand*{\@sDTLforeachbibentry}[3][\boolean{true}]{% +% \end{macrocode} +% Store database name. +% \begin{macrocode} + \edef\DBIBname{#2}% +% \end{macrocode} +% Reset row counter. +% \begin{macrocode} + \setcounter{DTLbibrow}{0}% +% \end{macrocode} +% Iterate through the database (read only). +% \begin{macrocode} + \@sDTLforeach{#2}{\DBIBcitekey=CiteKey,\DBIBentrytype=EntryType}% + {% + \dtl@gathervalues{#2}{\dtlcurrentrow}% + \ifthenelse{#1}{\refstepcounter{DTLbibrow}#3}{}% + }% +} % \end{macrocode} %\end{macro} % -% \subsection{General Token Utilities} -%\begin{macro}{\toks@gput@right@cx} +%\begin{counter}{DTLbibrow} +%The counter \ctrfmt{DTLbibrow} keeps track of the current +%row in the body of \cs{DTLforeachbibentry}. (You can't rely on +%\ctr{DTLrowi}, \ctr{DTLrowii} and +% \ctr{DTLrowiii}, as \cs{DTLforeachbibentry} pass the +% conditions to the optional argument of \cs{DTLforeach}, but +% instead uses \cs{ifthenelse}, which means that \ctr{DTLrowi} +% etc will be incremented, even when the given condition is not met.) +% \begin{macrocode} +\newcounter{DTLbibrow} +% \end{macrocode} +%\end{counter} +%\begin{macro}{\theHDTLbibrow} +% Keep \sty{hyperref} happy: +% \begin{macrocode} +\def\theHDTLbibrow{\theHDTLrow.bib.\arabic{DTLbibrow}}% +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLbibfield} %\begin{definition} -%\cs{toks@gput@right@cx}\marg{toks name}\marg{stuff} +%\cs{DTLbibfield}\marg{field name} %\end{definition} -% Globally appends stuff to token register \cs{}\meta{toks name} +% Gets the value assigned to the field \meta{field name} for +% the current row of \cs{DTLforeachbibentry}. (Doesn't check if +% the field exists, or if it is being used within +% \cs{DTLforeachbibentry}.) % \begin{macrocode} -\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*{\DTLbibfield}[1]{\csname @dtl@key@#1\endcsname} % \end{macrocode} %\end{macro} -%\begin{macro}{\toks@gconcat@middle@cx} +% +%\begin{macro}{\DTLifbibfieldexists} %\begin{definition} -%\cs{toks@gconcat@middle@cx}\marg{toks name}\marg{before toks}\marg{stuff}\marg{after toks} +%\cs{DTLifbibfieldexists}\marg{field name}\marg{true part}\marg{false +%part} %\end{definition} -% Globally sets token register \cs{}\meta{toks name} to -% the contents of \meta{before toks} concatenated with -% \meta{stuff} (expanded) and the contents of \meta{after toks} +%Determines whether the given field name exists for the current +% row of \cs{DTLforeachbibentry}. % \begin{macrocode} -\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*{\DTLifbibfieldexists}[3]{% +\@ifundefined{@dtl@key@#1}{#3}{% +\expandafter\DTLifnull\csname @dtl@key@#1\endcsname +{#3}{#2}}} % \end{macrocode} %\end{macro} % -% \subsection{Floating Point Arithmetic} -% The commands defined in this section all use the equivalent -% commands provided by the \sty{fp} package, but first convert -% the decimal number into the required format. -% -%\begin{macro}{\DTLadd} +%\begin{macro}{\DTLifanybibfieldexists} %\begin{definition} -% \cs{DTLadd}\marg{cmd}\marg{num1}\marg{num2} +%\cs{DTLifanybibfieldexists}\marg{list of field name}\marg{true part}\marg{false +%part} %\end{definition} -% Sets \meta{cmd} = \meta{num1} + \meta{num2} +% Determines whether any of the listed fields exist for the current +% row of \cs{DTLforeachbibentry}. % \begin{macrocode} -\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}% +\newcommand*{\DTLifanybibfieldexists}[3]{% +\@for\dtl@thisfield:=#1\do{% +\@ifundefined{@dtl@key@\dtl@thisfield}{}{% +\expandafter\DTLifnull\csname @dtl@key@\dtl@thisfield\endcsname +{}{% +\@endfortrue}}}% +\if@endfor + #2% \else - \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + #3% \fi +\@endforfalse } % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLgadd} -% Global version +% +%\begin{macro}{\ifDTLperiod} +% The conditional \cs{ifDTLperiod} is used to keep track of any +% abbreviations ending with a period, this is to ensure that +% abbreviations aren't followed by a full stop if they already +% have a full stop terminating the abbreviation. % \begin{macrocode} -\newcommand*{\DTLgadd}[3]{% -\DTLadd{\@dtl@tmpii}{#2}{#3}% -\global\let#1=\@dtl@tmpii -} +\newif\ifDTLperiod % \end{macrocode} %\end{macro} -% -%\begin{macro}{\DTLaddall} +%\begin{macro}{\DTLcheckendsperiod} %\begin{definition} -%\cs{DTLaddall}\marg{cmd}\marg{num list} +%\cs{DTLcheckendperiod}\marg{string} %\end{definition} -% Sums all the values in \meta{num list} and stores in -% \meta{cmd} which must be a control sequence. -%\changes{1.01}{2007 Aug 17}{removed extraneous space} +% Checks if \meta{string} ends with a full stop. This sets +% \cs{ifDTLperiod}. % \begin{macrocode} -\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}% +\newcommand*{\DTLcheckendsperiod}[1]{% +\dtl@checkendsperiod#1\@nil\relax} +% \end{macrocode} +% \begin{macrocode} +\def\dtl@checkendsperiod#1#2{% +\def\@dtl@argi{#1}\def\@dtl@argii{#2}% +\def\@dtl@period{.}% +\ifx\@dtl@argi\@nnil + \global\DTLperiodfalse + \let\@dtl@donext=\relax \else - \DTLdecimaltocurrency{\@dtl@sum}{#1}% + \ifx\@dtl@argii\@nnil + \ifx\@dtl@argi\@dtl@period + \global\DTLperiodtrue + \else + \global\DTLperiodfalse + \fi + \let\@dtl@donext=\@gobble + \else + \let\@dtl@donext=\dtl@checkendsperiod + \fi \fi +\@dtl@donext{#2}% } % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLgaddall} +%\begin{macro}{\DTLcheckbibfieldendsperiod} %\begin{definition} -%\cs{DTLgaddall}\marg{cmd}\marg{num list} +%\cs{DTLcheckbibfieldendperiod}\marg{label} %\end{definition} -% Global version +% Checks if the bib field \meta{label} ends with a full stop. +% This sets \cs{ifDTLperiod}. % \begin{macrocode} -\newcommand*{\DTLgaddall}[2]{% -\DTLaddall{\@dtl@tmpi}{#2}% -\global\let#1=\@dtl@tmpi -} +\newcommand*{\DTLcheckbibfieldendsperiod}[1]{% +\protected@edef\@dtl@tmp{\DTLbibfield{#1}}% +\expandafter\DTLcheckendsperiod\expandafter{\@dtl@tmp}} % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLsub} +%\begin{macro}{\ifDTLmidsentence} %\begin{definition} -% \cs{DTLsub}\marg{cmd}\marg{num1}\marg{num2} +%\cs{ifDTLmidsentence} %\end{definition} -% Sets \meta{cmd} = \meta{num1} - \meta{num2} +% Determine whether we are in the middle +% of a sentence. % \begin{macrocode} -\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 -} +\newif\ifDTLmidsentence % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLgsub} -% Global version +%\begin{macro}{\ifDTLstartsentence} +%\begin{definition} +%\cs{ifDTLstartsentence} +%\end{definition} +% Determine whether we are at the start +% of a sentence. % \begin{macrocode} -\newcommand*{\DTLgsub}[3]{% -\DTLsub{\@dtl@tmpii}{#2}{#3}% -\global\let#1=\@dtl@tmpii -} +\newif\ifDTLstartsentence % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLmul} +%\begin{macro}{\DTLaddperiod} %\begin{definition} -% \cs{DTLmul}\marg{cmd}\marg{num1}\marg{num2} +%\cs{DTLaddperiod} %\end{definition} -% Sets \meta{cmd} = \meta{num1} $\times$ \meta{num2} +%Adds a full stop and sets \cs{DTLmidsentencefalse}, +%\cs{DTLstartsentencetrue} and +%\cs{DTLperiodfalse}. % \begin{macrocode} -\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*{\DTLaddperiod}{\DTLmidsentencefalse\DTLperiodfalse +\DTLstartsentencetrue +\ifDTLperiod\else.\fi} % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLgmul} -% Global version +% +%\begin{macro}{\DTLaddcomma} +%\begin{definition} +%\cs{DTLaddcomma} +%\end{definition} +%Adds a comma and sets \cs{DTLmidsentencetrue}, \cs{DTLperiodfalse} +%and \cs{DTLstartsentencefalse} % \begin{macrocode} -\newcommand*{\DTLgmul}[3]{% -\DTLmul{\@dtl@tmpii}{#2}{#3}% -\global\let#1=\@dtl@tmpii -} +\newcommand*{\DTLaddcomma}{, \DTLmidsentencetrue +\DTLperiodfalse\DTLstartsentencefalse} % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLdiv} -%\begin{definition} -% \cs{DTLdiv}\marg{cmd}\marg{num1}\marg{num2} -%\end{definition} -% Sets \meta{cmd} = \meta{num1} / \meta{num2} +%\begin{macro}{\DTLstartsentencespace} +%Adds a space if at the start of the sentence, otherwise does +% nothing. (The space between sentences is added this way, rather +% than in \cs{DTLaddperiod} otherwise spurious extra space can +% occur at the end of the bib item. The spacefactor needs to be +% set manually, because there's stuff in the way of the previous +% sentence's full stop and this space which confuses the inter +% sentence spacing (and, of course, the previous sentence could +% have ended with a capital letter.) % \begin{macrocode} -\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}% +\newcommand*{\DTLstartsentencespace}{% +\ifDTLstartsentence\spacefactor=\sfcode`\.\relax\space +\fi\DTLstartsentencefalse} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLtwoand} +% In a list of only two author (or editor) names, the text between the +% two names is given by \cs{DTLtwoand}: +% \begin{macrocode} +\newcommand*{\DTLtwoand}{\ \andname\ } +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLandlast} +% In a list of author (or editor) names, the text between the +% penultimate and last name is given by \cs{DTLandlast}: +% \begin{macrocode} +\newcommand*{\DTLandlast}{, \andname\ } +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLandnotlast} +% In a list of author (or editor) names, the text between the +% names (except the penultimate and last name) is given by +% \cs{DTLandnotlast}: +% \begin{macrocode} +\newcommand*{\DTLandnotlast}{, } +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtl@authorcount} +% Define a count register to keep track of the number of authors: +% \begin{macrocode} +\newcount\@dtl@authorcount +% \end{macrocode} +%\end{macro} +%\begin{counter}{DTLmaxauthors} +% The counter \ctrfmt{DTLmaxauthors} indicates the maximum number of +% author names to display, if there are more than that number, +% \cs{etalname} is used. +% \begin{macrocode} +\newcounter{DTLmaxauthors} +\setcounter{DTLmaxauthors}{10} +% \end{macrocode} +%\end{counter} +%\begin{macro}{\DTLformatauthorlist} +% Format a list of author names (the list is stored in +% \cs{@dtl@key@Author}): +% \begin{macrocode} +\newcommand*{\DTLformatauthorlist}{% +\DTLifbibfieldexists{Author}{% +\DTLstartsentencespace +\@dtl@authorcount=0\relax +\@for\@dtl@author:=\@dtl@key@Author\do{% +\advance\@dtl@authorcount by 1\relax}% +\@dtl@tmpcount=0\relax +\ifnum\@dtl@authorcount>\c@DTLmaxauthors +{% + \@for\@dtl@author:=\@dtl@key@Author\do{% + \advance\@dtl@tmpcount by 1\relax + \ifnum\@dtl@tmpcount=1\relax + \expandafter\DTLformatauthor\@dtl@author + \else + \ifnum\@dtl@tmpcount>\c@DTLmaxauthors + \DTLandnotlast \etalname + \expandafter\DTLcheckendsperiod\expandafter{\etalname}% + \@endfortrue + \else + \DTLandnotlast \expandafter\DTLformatauthor\@dtl@author + \fi + \fi + }% +}% \else - \ifx\@dtl@thisreplaced\@dtl@replaced - \DTLdecimaltolocale{\@dtl@tmp}{#1}% + \@for\@dtl@author:=\@dtl@key@Author\do{% + \advance\@dtl@tmpcount by 1\relax + \ifnum\@dtl@tmpcount=1\relax + \expandafter\DTLformatauthor\@dtl@author \else - \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + \ifnum\@dtl@tmpcount=\@dtl@authorcount + \ifnum\@dtl@authorcount=2\relax + \DTLtwoand + \else + \DTLandlast + \fi + \expandafter\DTLformatauthor\@dtl@author + \else + \DTLandnotlast \expandafter\DTLformatauthor\@dtl@author + \fi \fi + }% \fi +}{}% } % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLgdiv} -% Global version +%\begin{counter}{DTLmaxeditors} +% The counter \ctrfmt{DTLmaxeditors} indicates the maximum number of +% editor names to display, if there are more than that number, +% \cs{etalname} is used. % \begin{macrocode} -\newcommand*{\DTLgdiv}[3]{% -\DTLdiv{\@dtl@tmpii}{#2}{#3}% -\global\let#1=\@dtl@tmpii +\newcounter{DTLmaxeditors} +\setcounter{DTLmaxeditors}{10} +% \end{macrocode} +%\end{counter} +% +%\begin{macro}{\DTLformateditorlist} +% Format a list of editor names (the list is stored in +% \cs{@dtl@key@Editor}): +% \begin{macrocode} +\newcommand*{\DTLformateditorlist}{% +\DTLifbibfieldexists{Editor}{% +\DTLstartsentencespace +\@dtl@authorcount=0\relax +\@for\@dtl@author:=\@dtl@key@Editor\do{% +\advance\@dtl@authorcount by 1\relax}% +\@dtl@tmpcount=0\relax +\ifnum\@dtl@authorcount>\c@DTLmaxeditors +{% + \@for\@dtl@author:=\@dtl@key@Editor\do{% + \advance\@dtl@tmpcount by 1\relax + \ifnum\@dtl@tmpcount=1\relax + \expandafter\DTLformateditor\@dtl@author + \else + \ifnum\@dtl@tmpcount>\c@DTLmaxeditors + \DTLandnotlast \etalname + \expandafter\DTLcheckendsperiod\expandafter{\etalname}% + \@endfortrue + \else + \DTLandnotlast \expandafter\DTLformateditor\@dtl@author + \fi + \fi + }% +}% +\else +\@for\@dtl@author:=\@dtl@key@Editor\do{% + \advance\@dtl@tmpcount by 1\relax + \ifnum\@dtl@tmpcount=1\relax + \expandafter\DTLformateditor\@dtl@author + \else + \ifnum\@dtl@tmpcount=\@dtl@authorcount + \ifnum\@dtl@authorcount=2\relax + \DTLtwoand + \else + \DTLandlast + \fi + \expandafter\DTLformateditor\@dtl@author + \else + \DTLandnotlast \expandafter\DTLformateditor\@dtl@author + \fi + \fi + }% +\fi +, +\ifnum\@dtl@authorcount=1\relax + \editorname + \expandafter\DTLcheckendsperiod\expandafter{\editorname}% +\else + \editorsname + \expandafter\DTLcheckendsperiod\expandafter{\editorsname}% +\fi +}{}% } % \end{macrocode} %\end{macro} -% -%\begin{macro}{\DTLabs} +%\begin{macro}{\DTLformatsurnameonly} %\begin{definition} -% \cs{DTLabs}\marg{cmd}\marg{num} +%\cs{DTLformatsurnameonly}\marg{von part}\marg{surname}\marg{jr +%part}\marg{forenames} %\end{definition} -% Sets \meta{cmd} = abs(\meta{num}) +% This is used when only the surname should be displayed. (The +% final argument, \meta{forenames}, is ignored.) % \begin{macrocode} -\newcommand*{\DTLabs}[2]{% -\DTLconverttodecimal{#2}{\@dtl@numi}% -\FPabs{\@dtl@tmp}{\@dtl@numi}% -\ifx\@dtl@replaced\@empty - \DTLdecimaltolocale{\@dtl@tmp}{#1}% +\newcommand*{\DTLformatsurnameonly}[4]{% +\DTLstartsentencespace +\def\@dtl@tmp{#1}% +\ifx\@dtl@tmp\@empty\else#1~\fi +#2% +\def\@dtl@tmp{#3}% +\ifx\@dtl@tmp\@empty + \DTLcheckendsperiod{#2}% \else - \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + , #3% + \DTLcheckendsperiod{#3}% \fi } % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLgabs} -% Global version +% +%\begin{macro}{\DTLformatforenames} +%\begin{definition} +%\cs{DTLformatforenames}\marg{forenames} +%\end{definition} +% The format of an author/editor's forenames. If the forenames +% occur at the start of sentence, a new sentence space is added. +% The argument is checked to determine whether it ends with a +% full stop (sometimes the forenames may include initials.) % \begin{macrocode} -\newcommand*{\DTLgabs}[2]{% -\DTLabs{\@dtl@tmpii}{#2}% -\global\let#1=\@dtl@tmpii -} +\newcommand*{\DTLformatforenames}[1]{% +\DTLstartsentencespace +#1% +\DTLcheckendsperiod{#1}} % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLneg} +%\begin{macro}{\DTLformatabbrvforenames} %\begin{definition} -% \cs{DTLneg}\marg{cmd}\marg{num} +%\cs{DTLformatabbrvforenames}\marg{forenames} %\end{definition} -% Sets \meta{cmd} = -\meta{num} +% The format of an author/editor's abbreviated forenames. The initials +% may or may not end in a full stop depending on the commands +% governing the format of \cs{DTLstoreinitials}, so the initials +% need to be check using \cs{DTLcheckendsperiod}. % \begin{macrocode} -\newcommand*{\DTLneg}[2]{% -\DTLconverttodecimal{#2}{\@dtl@numi}% -\FPneg{\@dtl@tmp}{\@dtl@numi}% -\ifx\@dtl@replaced\@empty - \DTLdecimaltolocale{\@dtl@tmp}{#1}% +\newcommand*{\DTLformatabbrvforenames}[1]{% +\DTLstartsentencespace +\DTLstoreinitials{#1}{\@dtl@tmp}\@dtl@tmp +\expandafter\DTLcheckendsperiod\expandafter{\@dtl@tmp}} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLformatvon} +%\begin{definition} +%\cs{DTLformatvon}\marg{von part} +%\end{definition} +% The format of the ``von'' part. This does nothing if the argument +% is empty, otherwise it does the argument followed by a +% non-breakable space. +% \begin{macrocode} +\newcommand*{\DTLformatvon}[1]{% +\DTLstartsentencespace +\def\@dtl@tmp{#1}% +\ifx\@dtl@tmp\@empty \else - \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + #1~% \fi } % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLgneg} -% Global version +% +%\begin{macro}{\DTLformatsurname} +%\begin{definition} +%\cs{DTLformatsurname}\marg{surname} +%\end{definition} +% The format of an author/editor's surname. % \begin{macrocode} -\newcommand*{\DTLgneg}[2]{% -\DTLneg{\@dtl@tmpii}{#2}% -\global\let#1=\@dtl@tmpii -} +\newcommand*{\DTLformatsurname}[1]{% +\DTLstartsentencespace +#1\DTLcheckendsperiod{#1}} % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLsqrt} +%\begin{macro}{\DTLformatjr} %\begin{definition} -% \cs{DTLsqrt}\marg{cmd}\marg{num} +%\cs{DTLformatjr}\marg{jr part} %\end{definition} -% Sets \meta{cmd} = sqrt(\meta{num}) +% The format of the ``jr'' part. This does nothing if the +% argument is empty. % \begin{macrocode} -\newcommand*{\DTLsqrt}[2]{% -\DTLconverttodecimal{#2}{\@dtl@numi}% -\FProot{\@dtl@tmpi}{\@dtl@numi}{2}% -\ifx\@dtl@replaced\@empty - \DTLdecimaltolocale{\@dtl@tmpi}{#1}% +\newcommand*{\DTLformatjr}[1]{% +\DTLstartsentencespace +\def\@dtl@tmp{#1}% +\ifx\@dtl@tmp\@empty \else - \DTLdecimaltocurrency{\@dtl@tmpi}{#1}% + , #1\DTLcheckendsperiod{#1}% \fi } % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLgsqrt} -% Global version +% +%\begin{macro}{\DTLformatcrossrefeditor} +% Format cross reference editors: % \begin{macrocode} -\newcommand*{\DTLgsqrt}[2]{% -\DTLsqrt{\@dtl@tmpii}{#2}% -\global\let#1=\@dtl@tmpii +\newcommand*{\DTLformatcrossrefeditor}{% +\DTLifbibfieldexists{Editor}{% +\DTLstartsentencespace +\@dtl@authorcount=0\relax +\@for\@dtl@author:=\@dtl@key@Editor\do{% +\advance\@dtl@authorcount by 1\relax}% +{\@dtl@tmpcount=0\relax +\@for\@dtl@author:=\@dtl@key@Editor\do{% +\ifnum\@dtl@authorcount=1\relax + \expandafter\DTLformatsurnameonly\@dtl@author +\else + \advance\@dtl@tmpcount by 1\relax + \ifnum\@dtl@tmpcount=1\relax + \expandafter\DTLformatsurnameonly\@dtl@author + \else + \ifnum\@dtl@authorcount=2\relax + \ \andname\ \expandafter\DTLformatsurnameonly\@dtl@author + \else + \ \etalname + \expandafter\DTLcheckendsperiod\expandafter{\etalname} + \fi + \@endfortrue + \fi +\fi +}}% +}{}% } % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLmin} -%\begin{definition} -% \cs{DTLmin}\marg{cmd}\marg{num1}\marg{num2} -%\end{definition} -% Sets \meta{cmd} = min(\meta{num1}, \meta{num2}) +%\begin{macro}{\DTLformatvolnumpages} +% Format volume, number and pages (of an article). % \begin{macrocode} -\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}}% +\newcommand*{\DTLformatvolnumpages}{% +\DTLifbibfieldexists{Volume}{% +\DTLstartsentencespace +\DTLbibfield{Volume}\DTLperiodfalse}{}% +\DTLifbibfieldexists{Number}{% +\DTLstartsentencespace +(\DTLbibfield{Number})\DTLperiodfalse}{}% +\DTLifbibfieldexists{Pages}{% +\DTLifanybibfieldexists{Volume,Number}{:}{% +\DTLstartsentencespace +\protected@edef\@dtl@pages{0\DTLbibfield{Pages}}% +\DTLifnumerical{\@dtl@pages}{\pagename}{\pagesname}~}% +\DTLbibfield{Pages}\DTLperiodfalse}{}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLformatbvolume} +% Format book volume. +% \begin{macrocode} +\newcommand*{\DTLformatbvolume}{% +\DTLifbibfieldexists{Volume}{% +\ifDTLmidsentence + \volumename \else - \dtl@ifsingle{#3}{% - \let#1=#3}{% - \def#1{#3}}% + \DTLstartsentencespace + \expandafter\MakeUppercase\volumename \fi -} +~\DTLbibfield{Volume}% +\DTLifbibfieldexists{Series}{\ \ofname\ +{\em\DTLbibfield{Series}}\DTLcheckbibfieldendsperiod{Series}}{% +\DTLcheckbibfieldendsperiod{Volume}}% +}{}} % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLgmin} -% Global version +% +%\begin{macro}{\DTLformatchapterpages} +% Format chapter and pages: % \begin{macrocode} -\newcommand*{\DTLgmin}[3]{% -\DTLmin{\@dtl@tmpii}{#2}{#3}% -\global\let#1=\@dtl@tmpii +\newcommand*{\DTLformatchapterpages}{% +\DTLifbibfieldexists{Chapter}{% +\DTLifbibfieldexists{Type}{% +\DTLstartsentencespace +\DTLbibfield{Type}}{% +\DTLstartsentencespace +\chaptername}~\DTLbibfield{Chapter}% +\DTLifbibfieldexists{Pages}{\DTLaddcomma}{% +\DTLcheckbibfieldendsperiod{Chapter}}}{}% +\DTLstartsentencespace +\DTLformatpages} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLformatpages} +% Format pages: +% \begin{macrocode} +\newcommand*{\DTLformatpages}{% +\DTLifbibfieldexists{Pages}{% +\DTLstartsentencespace +\protected@edef\@dtl@pages{0\DTLbibfield{Pages}}% +\DTLifnumerical{\@dtl@pages}{\pagename}{\pagesname}~% +\DTLbibfield{Pages}\DTLcheckbibfieldendsperiod{Pages}}{}% } % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLminall} -%\begin{definition} -%\cs{DTLminall}\marg{cmd}\marg{num list} -%\end{definition} -% Finds the minimum value in \meta{num list} and stores in -% \meta{cmd} which must be a control sequence. -%\changes{1.01}{2007 Aug 17}{removed extraneous space} +%\begin{macro}{\DTLformatnumberseries} +% Format number and series (of book) % \begin{macrocode} -\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 +\newcommand*{\DTLformatnumberseries}{% +\DTLifbibfieldexists{Volume}{}{% +\DTLifbibfieldexists{Number}{% +\ifDTLmidsentence + \numbername +\else + \DTLstartsentencespace + \expandafter\MakeUppercase\numbername +\fi~\DTLbibfield{Number}% +\DTLifbibfieldexists{Series}{\ \inname\ \DTLbibfield{Series}% +\DTLcheckbibfieldendsperiod{Series}}{% +\DTLcheckbibfieldendsperiod{Number}}% +}{% +\DTLifbibfieldexists{Series}{% +\DTLstartsentencespace +\DTLbibfield{Series}% +\DTLcheckbibfieldendsperiod{Series}}{}}% }% -\ifx\@dtl@replaced\@empty - \DTLdecimaltolocale{\@dtl@min}{#1}% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLformatbookcrossref} +% Format a book cross reference. +% \begin{macrocode} +\newcommand*{\DTLformatbookcrossref}{% +\DTLifbibfieldexists{Volume}{% +\ifDTLmidsentence + \volumename \else - \DTLdecimaltocurrency{\@dtl@min}{#1}% + \DTLstartsentencespace + \expandafter\MakeUppercase\volumename \fi +~\DTLbibfield{Volume}\ \ofname\ +}{% +\ifDTLmidsentence + \inname +\else + \DTLstartsentencespace + \expandafter\MakeUppercase\inname +\fi\ }% +\DTLifbibfieldexists{Editor}{\DTLformatcrossrefeditor}{% +\DTLifbibfieldexists{Key}{% +\DTLbibfield{Key}}{% +\DTLifbibfieldexists{Series}{% +{\em\DTLbibfield{Series}}}{}% +}% +}% +\edef\@dtl@tmp{\DTLbibfield{CrossRef}}% +~\cite{\@dtl@tmp}% } % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLgminall} -%\begin{definition} -%\cs{DTLgminall}\marg{cmd}\marg{num list} -%\end{definition} -% Global version +%\begin{macro}{\DTLformatincollproccrossref} +% Format `incollections' cross reference. % \begin{macrocode} -\newcommand*{\DTLgminall}[2]{% -\DTLminall{\@dtl@tmpi}{#2}% -\global\let#1=\@dtl@tmpi +\newcommand*{\DTLformatincollproccrossref}{% +\DTLifbibfieldexists{Editor}{% +\ifDTLmidsentence + \inname +\else + \DTLstartsentencespace + \expandafter\MakeUppercase\inname +\fi\ +\DTLformatcrossrefeditor +}{% +\DTLifbibfieldexists{Key}{% +\ifDTLmidsentence + \inname +\else + \DTLstartsentencespace + \expandafter\MakeUppercase\inname +\fi\ \DTLbibfield{Key}% +}{% +\DTLifbibfieldexists{BookTitle}{% +\ifDTLmidsentence + \inname +\else + \DTLstartsentencespace + \expandafter\MakeUppercase\inname +\fi\ {\em\DTLbibfield{BookTitle}}}{}% +}}% +\edef\@dtl@tmp{\DTLbibfield{CrossRef}}% +~\cite{\@dtl@tmp}% } % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLmax} -%\begin{definition} -% \cs{DTLmax}\marg{cmd}\marg{num1}\marg{num2} -%\end{definition} -% Sets \meta{cmd} = max(\meta{num1}, \meta{num2}) +%\begin{macro}{\DTLformatinedbooktitle} +%Format editor and booktitle: % \begin{macrocode} -\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}}% +\newcommand*{\DTLformatinedbooktitle}{% +\DTLifbibfieldexists{BookTitle}{% +\ifDTLmidsentence + \inname \else - \dtl@ifsingle{#3}{% - \let#1=#3}{% - \def#1{#3}}% -\fi -} + \DTLstartsentencespace + \expandafter\MakeUppercase\inname +\fi\ +\DTLifbibfieldexists{Editor}{% +\DTLformateditorlist\DTLaddcomma {\em\DTLbibfield{BookTitle}}% +\DTLcheckbibfieldendsperiod{BookTitle}% +}{{\em\DTLbibfield{BookTitle}}% +\DTLcheckbibfieldendsperiod{BookTitle}% +}}{}} % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLgmax} -% Global version +% +%\begin{macro}{\DTLformatdate} +%Format date. % \begin{macrocode} -\newcommand*{\DTLgmax}[3]{% -\DTLmax{\@dtl@tmpii}{#2}{#3}% -\global\let#1=\@dtl@tmpii -} +\newcommand*{\DTLformatdate}{% +\DTLifbibfieldexists{Year}{% +\DTLifbibfieldexists{Month}{% +\protected@edef\@dtl@tmp{\DTLbibfield{Month}}% +\ifDTLmidsentence + \@dtl@tmp +\else + \DTLstartsentencespace + \expandafter\MakeUppercase\@dtl@tmp +\fi\ +\DTLmidsentencefalse}{}% +\DTLstartsentencespace +\DTLbibfield{Year}}{% +\DTLifbibfieldexists{Month}{% +\protected@edef\@dtl@tmp{\DTLbibfield{Month}}% +\ifDTLmidsentence + \@dtl@tmp +\else + \DTLstartsentencespace + \expandafter\MakeUppercase\@dtl@tmp +\fi +\DTLcheckbibfieldendsperiod{Month}% +}{}}} % \end{macrocode} %\end{macro} -% -%\begin{macro}{\DTLmaxall} -%\begin{definition} -%\cs{DTLmaxall}\marg{cmd}\marg{num list} -%\end{definition} -% Finds the maximum value in \meta{num list} and stores in -% \meta{cmd} which must be a control sequence. -%\changes{1.01}{2007 Aug 17}{removed extraneous space} +%\begin{macro}{\DTLformatarticlecrossref} +% Format article cross reference. % \begin{macrocode} -\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}% +\newcommand*{\DTLformatarticlecrossref}{% +\DTLifbibfieldexists{Key}{% +\ifDTLmidsentence + \inname +\else + \DTLstartsentencespace + \expandafter\MakeUppercase\inname +\fi +\ {\em\DTLbibfield{Key}}}{% +\DTLifbibfieldexists{Journal}{% +\ifDTLmidsentence + \inname \else - \DTLdecimaltocurrency{\@dtl@max}{#1}% + \DTLstartsentencespace + \expandafter\MakeUppercase\inname \fi +\ {\em\DTLbibfield{Journal}}}{}}% +\edef\@dtl@tmp{\DTLbibfield{CrossRef}}% +~\cite{\@dtl@tmp}% } % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLgmaxall} +% +%\subsection{ifthen conditionals} +% The conditionals defined in this section may be used in the +% optional argument of \cs{DTLforeachbib}. They may also be +% used in the first argument of \cs{ifthenelse}, but only if the +% command occurs within the body of \cs{DTLforeachbib}. +% +%\begin{macro}{\DTLbibfieldexists} %\begin{definition} -%\cs{DTLgmaxall}\marg{cmd}\marg{num list} +%\cs{DTLbibfieldexists}\marg{field label} %\end{definition} -% Global version +% Checks if named bib field exists for current entry % \begin{macrocode} -\newcommand*{\DTLgmaxall}[2]{% -\DTLmaxall{\@dtl@tmpi}{#2}% -\global\let#1=\@dtl@tmpi -} +\newcommand*{\DTLbibfieldexists}[1]{% +\TE@throw\noexpand\dtl@testbibfieldexists{#1}% +\noexpand\if@dtl@condition} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtl@testbibfieldexists} +% \begin{macrocode} +\newcommand*{\dtl@testbibfieldexists}[1]{% +\DTLifbibfieldexists{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLmeanforall} +%\begin{macro}{\DTLbibfieldiseq} %\begin{definition} -%\cs{DTLmeanforall}\marg{cmd}\marg{num list} +%\cs{DTLbibfieldiseq}\marg{field label}\marg{value} %\end{definition} -% Computes the arithmetic mean of all the values in \meta{num list} -% and stores in \meta{cmd} which must be a control sequence. -%\changes{1.01}{2007 Aug 17}{removed extraneous space} +% Checks if the value of the bib field given by \meta{field label} +% is equal to \meta{value}. (Uses \cs{dtlcompare} to determine if +% the values are equal. If the bib field doesn't exist, the +% condition is false.) % \begin{macrocode} -\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}% +\newcommand*{\DTLbibfieldiseq}[2]{% +\TE@throw\noexpand\dtl@testbibfieldiseq{#1}{#2}% +\noexpand\if@dtl@condition} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtl@testbibfieldiseq} +% \begin{macrocode} +\newcommand*{\dtl@testbibfieldiseq}[2]{% +\DTLifbibfieldexists{#1}{% +\expandafter\let\expandafter\@dtl@tmp\expandafter + =\csname @dtl@key@#1\endcsname +\expandafter\toks@\expandafter{\@dtl@tmp}% +\@dtl@toks{#2}% +\edef\@dtl@docompare{\noexpand\dtlcompare{\noexpand\@dtl@tmpcount}% +{\the\toks@}{\the\@dtl@toks}}% +\@dtl@docompare +\ifnum\@dtl@tmpcount=0\relax + \@dtl@conditiontrue \else - \DTLdecimaltocurrency{\@dtl@mean}{#1}% + \@dtl@conditionfalse \fi +}{% +\@dtl@conditionfalse}% } % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLgmeanforall} +% +%\begin{macro}{\DTLbibfieldislt} %\begin{definition} -%\cs{DTLgmeanforall}\marg{cmd}\marg{num list} +%\cs{DTLbibfieldislt}\marg{field label}\marg{value} %\end{definition} -% Global version +% Checks if the value of the bib field given by \meta{field label} +% is less than \meta{value}. (If the bib field doesn't exist, the +% condition is false.) % \begin{macrocode} -\newcommand*{\DTLgmeanforall}[2]{% -\DTLmeanforall{\@dtl@tmpi}{#2}% -\global\let#1=\@dtl@tmpi +\newcommand*{\DTLbibfieldislt}[2]{% +\TE@throw\noexpand\dtl@testbibfieldislt{#1}{#2}% +\noexpand\if@dtl@condition} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtl@testbibfieldislt} +% \begin{macrocode} +\newcommand*{\dtl@testbibfieldislt}[2]{% +\DTLifbibfieldexists{#1}{% +\expandafter\let\expandafter\@dtl@tmp\expandafter + =\csname @dtl@key@#1\endcsname +\expandafter\toks@\expandafter{\@dtl@tmp}% +\@dtl@toks{#2}% +\edef\@dtl@docompare{\noexpand\dtlcompare{\noexpand\@dtl@tmpcount}% +{\the\toks@}{\the\@dtl@toks}}% +\@dtl@docompare +\ifnum\@dtl@tmpcount=-1\relax + \@dtl@conditiontrue +\else + \@dtl@conditionfalse +\fi +}{% +\@dtl@conditionfalse}% } % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLvarianceforall} +%\begin{macro}{\DTLbibfieldisle} %\begin{definition} -%\cs{DTLvarianceforall}\marg{cmd}\marg{num list} +%\cs{DTLbibfieldisle}\marg{field label}\marg{value} %\end{definition} -% Computes the variance of all the values in \meta{num list} -% and stores in \meta{cmd} which must be a control sequence. -%\changes{1.01}{2007 Aug 17}{fixed bug} -%\changes{1.01}{2007 Aug 17}{removed extraneous space} +% Checks if the value of the bib field given by \meta{field label} +% is less than or equal to \meta{value}. +% (If the bib field doesn't exist, the +% condition is false.) % \begin{macrocode} -\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}% +\newcommand*{\DTLbibfieldisle}[2]{% +\TE@throw\noexpand\dtl@testbibfieldisle{#1}{#2}% +\noexpand\if@dtl@condition} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtl@testbibfieldisle} +% \begin{macrocode} +\newcommand*{\dtl@testbibfieldisle}[2]{% +\DTLifbibfieldexists{#1}{% +\expandafter\let\expandafter\@dtl@tmp\expandafter + =\csname @dtl@key@#1\endcsname +\expandafter\toks@\expandafter{\@dtl@tmp}% +\@dtl@toks{#2}% +\edef\@dtl@docompare{\noexpand\dtlcompare{\noexpand\@dtl@tmpcount}% +{\the\toks@}{\the\@dtl@toks}}% +\@dtl@docompare +\ifnum\@dtl@tmpcount<1\relax + \@dtl@conditiontrue \else - \DTLdecimaltocurrency{\@dtl@var}{#1}% + \@dtl@conditionfalse \fi +}{% +\@dtl@conditionfalse}% } % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLgvarianceforall} +% +%\begin{macro}{\DTLbibfieldisgt} %\begin{definition} -%\cs{DTLgvarianceforall}\marg{cmd}\marg{num list} +%\cs{DTLbibfieldisgt}\marg{field label}\marg{value} %\end{definition} -% Global version +% Checks if the value of the bib field given by \meta{field label} +% is greater than \meta{value}. (If the bib field doesn't exist, the +% condition is false.) % \begin{macrocode} -\newcommand*{\DTLgvarianceforall}[2]{% -\DTLvarianceforall{\@dtl@tmpi}{#2}% -\global\let#1=\@dtl@tmpi +\newcommand*{\DTLbibfieldisgt}[2]{% +\TE@throw\noexpand\dtl@testbibfieldisgt{#1}{#2}% +\noexpand\if@dtl@condition} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtl@testbibfieldisgt} +% \begin{macrocode} +\newcommand*{\dtl@testbibfieldisgt}[2]{% +\DTLifbibfieldexists{#1}{% +\expandafter\let\expandafter\@dtl@tmp\expandafter + =\csname @dtl@key@#1\endcsname +\expandafter\toks@\expandafter{\@dtl@tmp}% +\@dtl@toks{#2}% +\edef\@dtl@docompare{\noexpand\dtlcompare{\noexpand\@dtl@tmpcount}% +{\the\toks@}{\the\@dtl@toks}}% +\@dtl@docompare +\ifnum\@dtl@tmpcount=1\relax + \@dtl@conditiontrue +\else + \@dtl@conditionfalse +\fi +}{% +\@dtl@conditionfalse}% } % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLsdforall} +%\begin{macro}{\DTLbibfieldisge} %\begin{definition} -%\cs{DTLsdforall}\marg{cmd}\marg{num list} +%\cs{DTLbibfieldisge}\marg{field label}\marg{value} %\end{definition} -% Computes the standard deviation of all the values in \meta{num list} -% and stores in \meta{cmd} which must be a control sequence. -%\changes{1.01}{2007 Aug 17}{fixed bug} -%\changes{1.01}{2007 Aug 17}{removed extraneous space} +% Checks if the value of the bib field given by \meta{field label} +% is less than or equal to \meta{value}. +% (If the bib field doesn't exist, the +% condition is false.) % \begin{macrocode} -\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}% +\newcommand*{\DTLbibfieldisge}[2]{% +\TE@throw\noexpand\dtl@testbibfieldisge{#1}{#2}% +\noexpand\if@dtl@condition} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtl@testbibfieldisge} +% \begin{macrocode} +\newcommand*{\dtl@testbibfieldisge}[2]{% +\DTLifbibfieldexists{#1}{% +\expandafter\let\expandafter\@dtl@tmp\expandafter + =\csname @dtl@key@#1\endcsname +\expandafter\toks@\expandafter{\@dtl@tmp}% +\@dtl@toks{#2}% +\edef\@dtl@docompare{\noexpand\dtlcompare{\noexpand\@dtl@tmpcount}% +{\the\toks@}{\the\@dtl@toks}}% +\@dtl@docompare +\ifnum\@dtl@tmpcount>-1\relax + \@dtl@conditiontrue \else - \DTLdecimaltocurrency{\@dtl@sd}{#1}% + \@dtl@conditionfalse \fi +}{% +\@dtl@conditionfalse}% } % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLgsdforall} +% +%\begin{macro}{\DTLbibfieldcontains} %\begin{definition} -%\cs{DTLgsdforall}\marg{cmd}\marg{num list} +%\cs{DTLbibfieldcontains}\marg{field label}\marg{sub string} %\end{definition} -% Global version +% Checks if the value of the bib field given by \meta{field label} +% contains \meta{sub string}. +% (If the bib field doesn't exist, the +% condition is false.) % \begin{macrocode} -\newcommand*{\DTLgsdforall}[2]{% -\DTLsdforall{\@dtl@tmpi}{#2}% -\global\let#1=\@dtl@tmpi -} +\newcommand*{\DTLbibfieldcontains}[2]{% +\TE@throw\noexpand\dtl@testbibfieldcontains{#1}{#2}% +\noexpand\if@dtl@condition} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtl@testbibfieldcontains} +% \begin{macrocode} +\newcommand*{\dtl@testbibfieldcontains}[2]{% +\DTLifbibfieldexists{#1}{% +\expandafter\let\expandafter\@dtl@tmp\expandafter + =\csname @dtl@key@#1\endcsname +\expandafter\dtl@testifsubstring\expandafter{\@dtl@tmp}{#2}% +}{\@dtl@conditionfalse}} % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLround} -%\begin{definition} -% \cs{DTLround}\marg{cmd}\marg{num}\marg{num digits} -%\end{definition} -% Sets \meta{cmd} to \meta{num} rounded to \meta{num digits} -% digits after the decimal character. +%\section{Bibliography Style Macros} +%\label{sec:src:bibstyle} +% The macros defined in this section should be redefined by +% bibliography styles. +% +%\begin{environment}{DTLthebibliography} +% How to format the entire bibliography: % \begin{macrocode} -\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 -} +\newenvironment{DTLthebibliography}[2][\boolean{true}]{% +\@dtl@tmpcount=0\relax +\@sDTLforeach[#1]{#2}{}{\advance\@dtl@tmpcount by 1\relax}% +\begin{thebibliography}{\number\@dtl@tmpcount} +}{\end{thebibliography}} +% \end{macrocode} +%\end{environment} +%\begin{macro}{\DTLmonthname} +% The monthname style. The argument must be a number from~1 +% to~12. By default, uses \cs{dtl@monthname}. +% \begin{macrocode} +\newcommand*{\DTLmonthname}[1]{% +\dtl@monthname{#1}} % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLground} -% Global version +%\begin{macro}{\dtl@monthname} +% Full month names: % \begin{macrocode} -\newcommand*{\DTLground}[3]{% -\DTLround{\@dtl@tmpii}{#2}{#3}% -\global\let#1=\@dtl@tmpii -} +\newcommand*{\dtl@monthname}[1]{% +\ifcase#1% +\or January% +\or February% +\or March% +\or April% +\or May% +\or June% +\or July% +\or August% +\or September% +\or October% +\or November% +\or December% +\fi} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtl@abbrvmonthname} +% Abbreviated months: +% \begin{macrocode} +\newcommand*{\dtl@abbrvmonthname}[1]{% +\ifcase#1% +\or Jan.% +\or Feb.% +\or Mar.% +\or Apr.% +\or May% +\or June% +\or July% +\or Aug.% +\or Sept.% +\or Oct.% +\or Nov.% +\or Dec.% +\fi} % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLtrunc} -%\begin{definition} -% \cs{DTLtrunc}\marg{cmd}\marg{num}\marg{num digits} -%\end{definition} -% Sets \meta{cmd} to \meta{num} truncated to \meta{num digits} -% digits after the decimal character. +%\begin{macro}{\DTLbibitem} +% Define how to start a new bibitem: % \begin{macrocode} -\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*{\DTLbibitem}{\bibitem{\DBIBcitekey}} % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLgtrunc} -% Global version +% +%\begin{macro}{\DTLmbibitem} +% As \cs{DTLbibitem} but for \cs{DTLmbibliography} % \begin{macrocode} -\newcommand*{\DTLgtrunc}[3]{% -\DTLtrunc{\@dtl@tmpii}{#2}{#3}% -\global\let#1=\@dtl@tmpii -} +\newcommand*{\DTLmbibitem}[1]{\bibitem{#1@\DBIBcitekey}} % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLclip} +%\begin{macro}{\DTLformatauthor} %\begin{definition} -% \cs{DTLclip}\marg{cmd}\marg{num} +%\cs{DTLformatauthor}\marg{von part}\marg{surname}\marg{junior +%part}\marg{forenames} %\end{definition} -% Sets \meta{cmd} to \meta{num} with all unnecessary 0's removed. +% The format of an author's name. % \begin{macrocode} -\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*{\DTLformatauthor}[4]{% +\DTLformatforenames{#4} +\DTLformatvon{#1}% +\DTLformatsurname{#2}% +\DTLformatjr{#3}} % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLgclip} -% Global version +% +%\begin{macro}{\DTLformateditor} +% The format of an editor's name. % \begin{macrocode} -\newcommand*{\DTLgclip}[3]{% -\DTLclip{\@dtl@tmpii}{#2}% -\global\let#1=\@dtl@tmpii -} +\newcommand*{\DTLformateditor}[4]{% +\DTLformatforenames{#4} +\DTLformatvon{#1}% +\DTLformatsurname{#2}% +\DTLformatjr{#3}} % \end{macrocode} %\end{macro} % -%\subsection{String Macros} -%\begin{macro}{\DTLinitials} -%\begin{definition} -%\cs{DTLinitials}\marg{string} -%\end{definition} -% Convert a string into initials. -% (Any "~" character found is first converted into a space.) -%\changes{1.01}{2007 Aug 17}{now works with unbreakable space symbol} -%\changes{1.01}{2007 Aug 17}{now uses \cs{DTLinitialhyphen}} +%\begin{macro}{\DTLformatedition} +% The format of an edition: % \begin{macrocode} -\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}% +\newcommand*{\DTLformatedition}[1]{#1 \editionname} % \end{macrocode} %\end{macro} -% The following substitutes "\protect \nobreakspace {}" with -% a space. (Note that in this case the space following -% "\nobreakspace" forms part of the command.) +% +%\begin{macro}{\DTLformatarticle} +% The format of an article: % \begin{macrocode} -\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{\DTLformatarticle}{} % \end{macrocode} +%\end{macro} % -%\begin{macro}{\DTLstoreinitials} -%\begin{definition} -%\cs{DTLstoreinitials}\marg{string}\marg{cmd} -%\end{definition} -% Convert a string into initials and store in \meta{cmd}. -% (Any "~" character found is first converted into a space.) -%\changes{1.01}{2007 Aug 17}{now works with unbreakable space symbol} -%\changes{1.01}{2007 Aug 17}{now uses \cs{DTLinitialhyphen}} +%\begin{macro}{\DTLformatbook} +% The format of a book: % \begin{macrocode} -\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 -} +\newcommand{\DTLformatbook}{} % \end{macrocode} %\end{macro} -%\begin{macro}{\dtl@initials} +% +%\begin{macro}{\DTLformatbooklet} +% The format of a booklet: % \begin{macrocode} -\def\dtl@initials#1#2 #3{% -\dtl@ifsingle{#1}{% -\ifcat\noexpand#1\relax\relax - \def\@dtl@donextinitials{\@dtl@initials#2 {#3}}% +\newcommand{\DTLformatbooklet}{} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLformatinbook} +% The format of an ``inbook'' type: +% \begin{macrocode} +\newcommand{\DTLformatinbook}{} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLformatincollection} +% The format of an ``incollection'' type: +% \begin{macrocode} +\newcommand{\DTLformatincollection}{} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLformatinproceedings} +% The format of an ``inproceedings'' type: +% \begin{macrocode} +\newcommand{\DTLformatinproceedings}{} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLformatmanual} +% The format of a manual: +% \begin{macrocode} +\newcommand{\DTLformatmanual}{} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLformatmastersthesis} +% The format of a master's thesis: +% \begin{macrocode} +\newcommand{\DTLformatmastersthesis}{} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLformatmisc} +% The format of a miscellaneous entry: +% \begin{macrocode} +\newcommand{\DTLformatmisc}{} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLformatphdthesis} +% The format of a Ph.D. thesis: +% \begin{macrocode} +\newcommand{\DTLformatphdthesis}{} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLformatproceedings} +% The format of a proceedings: +% \begin{macrocode} +\newcommand{\DTLformatproceedings}{} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLformattechreport} +% The format of a technical report: +% \begin{macrocode} +\newcommand{\DTLformattechreport}{} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLformatunpublished} +% The format of an unpublished work: +% \begin{macrocode} +\newcommand{\DTLformatunpublished}{} +% \end{macrocode} +%\end{macro} +% +% Predefined names (these correspond to the standard \BibTeX\ +% predefined strings of the same name without the leading +% \cs{DTL}): +%\begin{macro}{\DTLacmcs} +% \begin{macrocode} +\newcommand*{\DTLacmcs}{ACM Computing Surveys} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLacta} +% \begin{macrocode} +\newcommand*{\DTLacta}{Acta Informatica} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLcacm} +% \begin{macrocode} +\newcommand*{\DTLcacm}{Communications of the ACM} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLibmjrd} +% \begin{macrocode} +\newcommand*{\DTLibmjrd}{IBM Journal of Research and Development} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLibmsj} +% \begin{macrocode} +\newcommand*{\DTLibmsj}{IBM Systems Journal} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLieeese} +% \begin{macrocode} +\newcommand*{\DTLieeese}{IEEE Transactions on Software Engineering} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLieeetc} +% \begin{macrocode} +\newcommand*{\DTLieeetc}{IEEE Transactions on Computers} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLieeetcad} +% \begin{macrocode} +\newcommand*{\DTLieeetcad}{IEEE Transactions on Computer-Aided Design +of Integrated Circuits} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLipl} +% \begin{macrocode} +\newcommand*{\DTLipl}{Information Processing Letters} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLjacm} +% \begin{macrocode} +\newcommand*{\DTLjacm}{Journal of the ACM} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLjcss} +% \begin{macrocode} +\newcommand*{\DTLjcss}{Journal of Computer and System Sciences} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLscp} +% \begin{macrocode} +\newcommand*{\DTLscp}{Science of Computer Programming} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLsicomp} +% \begin{macrocode} +\newcommand*{\DTLsicomp}{SIAM Journal on Computing} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLtocs} +% \begin{macrocode} +\newcommand*{\DTLtocs}{ACM Transactions on Computer Systems} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLtods} +% \begin{macrocode} +\newcommand*{\DTLtods}{ACM Transactions on Database Systems} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLtog} +% \begin{macrocode} +\newcommand*{\DTLtog}{ACM Transactions on Graphics} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLtoms} +% \begin{macrocode} +\newcommand*{\DTLtoms}{ACM Transactions on Mathematical Software} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLtoois} +% \begin{macrocode} +\newcommand*{\DTLtoois}{ACM Transactions on Office Information +Systems} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLtoplas} +% \begin{macrocode} +\newcommand*{\DTLtoplas}{ACM Transactions on Programming Languages +and Systems} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLtcs} +% \begin{macrocode} +\newcommand*{\DTLtcs}{Theoretical Computer Science} +% \end{macrocode} +%\end{macro} +% +%\section{Bibliography Styles} +% Each bibliography style is set by the command +% \cs{dtlbst@}\meta{style}, where \meta{style} is the name +% of the bibliography style. +% +%\begin{macro}{\dtlbst@plain} +% The `plain' style: +% \begin{macrocode} +\newcommand{\dtlbst@plain}{% +% \end{macrocode} +% Set how to format the entire bibliography: +% \begin{macrocode} +\renewenvironment{DTLthebibliography}[2][\boolean{true}]{% +\@dtl@tmpcount=0\relax +\@sDTLforeach[##1]{##2}{}{\advance\@dtl@tmpcount by 1\relax}% +\begin{thebibliography}{\number\@dtl@tmpcount}% +}{\end{thebibliography}}% +% \end{macrocode} +% Set how to start the bibliography entry: +% \begin{macrocode} +\renewcommand*{\DTLbibitem}{\bibitem{\DBIBcitekey}}% +\renewcommand*{\DTLmbibitem}[1]{\bibitem{##1@\DBIBcitekey}}% +% \end{macrocode} +% Sets the author name format. +% \begin{macrocode} +\renewcommand*{\DTLformatauthor}[4]{% +\DTLformatforenames{##4} +\DTLformatvon{##1}% +\DTLformatsurname{##2}% +\DTLformatjr{##3}} +% \end{macrocode} +% Sets the editor name format. +% \begin{macrocode} +\renewcommand*{\DTLformateditor}[4]{% +\DTLformatforenames{##4} +\DTLformatvon{##1}% +\DTLformatsurname{##2}% +\DTLformatjr{##3}} +% \end{macrocode} +% Sets the edition format. +% \begin{macrocode} +\renewcommand*{\DTLformatedition}[1]{##1 \editionname}% +% \end{macrocode} +% Sets the monthname format. +% \begin{macrocode} +\let\DTLmonthname\dtl@monthname +% \end{macrocode} +% Sets other predefined names: +% \begin{macrocode} +\renewcommand*{\DTLacmcs}{ACM Computing Surveys} +\renewcommand*{\DTLacta}{Acta Informatica} +\renewcommand*{\DTLcacm}{Communications of the ACM} +\renewcommand*{\DTLibmjrd}{IBM Journal of Research and Development} +\renewcommand*{\DTLibmsj}{IBM Systems Journal} +\renewcommand*{\DTLieeese}{IEEE Transactions on Software Engineering} +\renewcommand*{\DTLieeetc}{IEEE Transactions on Computers} +\renewcommand*{\DTLieeetcad}{IEEE Transactions on Computer-Aided Design +of Integrated Circuits} +\renewcommand*{\DTLipl}{Information Processing Letters} +\renewcommand*{\DTLjacm}{Journal of the ACM} +\renewcommand*{\DTLjcss}{Journal of Computer and System Sciences} +\renewcommand*{\DTLscp}{Science of Computer Programming} +\renewcommand*{\DTLsicomp}{SIAM Journal on Computing} +\renewcommand*{\DTLtocs}{ACM Transactions on Computer Systems} +\renewcommand*{\DTLtods}{ACM Transactions on Database Systems} +\renewcommand*{\DTLtog}{ACM Transactions on Graphics} +\renewcommand*{\DTLtoms}{ACM Transactions on Mathematical Software} +\renewcommand*{\DTLtoois}{ACM Transactions on Office Information +Systems} +\renewcommand*{\DTLtoplas}{ACM Transactions on Programming Languages +and Systems} +\renewcommand*{\DTLtcs}{Theoretical Computer Science} +% \end{macrocode} +% The format of an article. +% \begin{macrocode} +\renewcommand*{\DTLformatarticle}{% +\DTLformatauthorlist +\DTLifbibfieldexists{Author}{\DTLaddperiod}{}% +\DTLifbibfieldexists{Title}{% +\DTLstartsentencespace\DTLbibfield{Title}% +\DTLcheckbibfieldendsperiod{Title}% +\DTLaddperiod}{}% +\DTLifbibfieldexists{CrossRef}{% +% cross ref field +\DTLformatarticlecrossref +\DTLifbibfieldexists{Pages}{\DTLaddcomma}{}% +\DTLformatpages +\DTLaddperiod +}{% no cross ref field +\DTLifbibfieldexists{Journal}{\DTLstartsentencespace +{\em\DTLbibfield{Journal}}% +\DTLcheckbibfieldendsperiod{Journal}% +\DTLifanybibfieldexists{Number,Volume,Pages,Month,Year}{% +\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLformatvolnumpages +\DTLifanybibfieldexists{Volume,Number,Pages}{% +\DTLifanybibfieldexists{Year,Month}{\DTLaddcomma}{% +\DTLaddperiod}% +\DTLmidsentencefalse}{}% +\DTLformatdate +\DTLifanybibfieldexists{Year,Month}{\DTLaddperiod}{}% +}% +\DTLifbibfieldexists{Note}{\DTLstartsentencespace\DTLbibfield{Note}% +\DTLcheckbibfieldendsperiod{Note}% +\DTLaddperiod}{}% +} +% \end{macrocode} +% The format of a book. +% \begin{macrocode} +\renewcommand*{\DTLformatbook}{% +\DTLifbibfieldexists{Author}{% +\DTLformatauthorlist\DTLaddperiod +}{\DTLformateditorlist\DTLifbibfieldexists{Editor}{% +\DTLaddperiod}{}}% +\DTLifbibfieldexists{Title}{\DTLstartsentencespace +{\em\DTLbibfield{Title}}% +\DTLcheckbibfieldendsperiod{Title}}{}% +\DTLifbibfieldexists{CrossRef}{% +% cross ref field +\DTLifbibfieldexists{Title}{\DTLaddperiod}{}% +\DTLformatbookcrossref +\DTLifanybibfieldexists{Edition,Month,Year}{\DTLaddcomma +}{\DTLaddperiod}% +}{% no cross ref field +\DTLifbibfieldexists{Title}{% +\DTLifbibfieldexists{Volume}{\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLformatbvolume +\DTLformatnumberseries +\DTLifanybibfieldexists{Number,Series,Volume}{\DTLaddperiod}{}% +\DTLifbibfieldexists{Publisher}{\DTLstartsentencespace +\DTLbibfield{Publisher}% +\DTLcheckbibfieldendsperiod{Publisher}% +\DTLifbibfieldexists{Address}{\DTLaddcomma}{% +\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma +}{\DTLaddperiod}% +}}{}% +\DTLifbibfieldexists{Address}{\DTLstartsentencespace +\DTLbibfield{Address}% +\DTLcheckbibfieldendsperiod{Address}% +\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{\DTLaddperiod}}{}% +}% +\DTLifbibfieldexists{Edition}{% +\protected@edef\@dtl@tmp{\DTLformatedition{\DTLbibfield{Edition}}}% +\ifDTLmidsentence + \@dtl@tmp \else - \def\@dtl@donextinitials{\@dtl@initials#1#2 {#3}}% + \DTLstartsentencespace\expandafter\MakeUppercase\@dtl@tmp \fi -}{% - \def\@dtl@donextinitials{\@dtl@initials{#1}#2 {#3}}% +\expandafter\DTLcheckendsperiod\expandafter{\@dtl@tmp}% +\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{\DTLaddperiod}% +}{}% +\DTLformatdate +\DTLifanybibfieldexists{Year,Month}{\DTLaddperiod}{}% +\DTLifbibfieldexists{Note}{\DTLstartsentencespace +\DTLbibfield{Note}% +\DTLcheckbibfieldendsperiod{Note}% +\DTLaddperiod}{}% }% -\@dtl@donextinitials -} % \end{macrocode} -%\end{macro} -%\begin{macro}{\@dtl@initials} +% The format of a booklet. % \begin{macrocode} -\def\@dtl@initials#1#2 #3{% -\dtl@initialshyphen#2-{}\dtl@endhyp -\expandafter\@dtl@toks\expandafter{\dtl@initialscmd}% -\toks@{#1}% -\ifx\dtl@inithyphen\@empty +\renewcommand*{\DTLformatbooklet}{% +\DTLifbibfieldexists{Author}{% +\DTLformatauthorlist\DTLaddperiod}{}% +\DTLifbibfieldexists{Title}{\DTLstartsentencespace +\DTLbibfield{Title}% +\DTLcheckbibfieldendsperiod{Title}% +\DTLaddperiod}{}% +\DTLifbibfieldexists{HowPublished}{% +\DTLstartsentencespace\DTLbibfield{HowPublished}% +\DTLcheckbibfieldendsperiod{HowPublished}% +\DTLifanybibfieldexists{Address,Month,Year}{\DTLaddcomma +}{\DTLaddperiod}}{}% +\DTLifbibfieldexists{Address}{\DTLstartsentencespace +\DTLbibfield{Address}% +\DTLcheckbibfieldendsperiod{Address}% +\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLformatdate +\DTLifanybibfieldexists{Year,Month}{\DTLaddperiod}{}% +\DTLifbibfieldexists{Note}{\DTLstartsentencespace\DTLbibfield{Note}% +\DTLcheckbibfieldendsperiod{Note}% +\DTLaddperiod}{}% +}% +% \end{macrocode} +% The format of an `inbook' entry. +% \begin{macrocode} +\renewcommand*{\DTLformatinbook}{% +\DTLifbibfieldexists{Author}{% +\DTLformatauthorlist\DTLaddperiod}{% +\DTLifbibfieldexists{Editor}{\DTLformateditorlist\DTLaddperiod}{}}% +\DTLifbibfieldexists{Title}{% +\DTLstartsentencespace +{\em\DTLbibfield{Title}}% +\DTLcheckbibfieldendsperiod{Title}% +}{}% +\DTLifbibfieldexists{CrossRef}{% +% Cross ref entry +\DTLifbibfieldexists{Title}{% +\DTLifbibfieldexists{Chapter}{\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLformatchapterpages +\DTLifanybibfieldexists{Chapter,Pages}{\DTLaddperiod}{}% +\DTLformatbookcrossref +}{% no cross ref +\DTLifbibfieldexists{Title}{% +\DTLifanybibfieldexists{Chapter,Volume}{\DTLaddcomma +}{\DTLaddperiod}}{}% +\DTLformatbvolume +\DTLifanybibfieldexists{Volume,Series}{% +\DTLifanybibfieldexists{Chapter,Pages}{% +\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLformatchapterpages +\DTLifanybibfieldexists{Chapter,Pages}{\DTLaddperiod}{}% +\DTLifbibfieldexists{Publisher}{% +\DTLstartsentencespace +\DTLbibfield{Publisher}% +\DTLcheckbibfieldendsperiod{Publisher}% +\DTLifbibfieldexists{Address}{\DTLaddcomma}{}}{}% +\DTLifbibfieldexists{Address}{% +\DTLstartsentencespace +\DTLbibfield{Address}% +\DTLcheckbibfieldendsperiod{Address}}{}% +}% +\DTLifanybibfieldexists{Edition,Month,Year}{\DTLaddcomma +}{\DTLaddperiod}% +\DTLifbibfieldexists{Edition}{% +\protected@edef\@dtl@tmp{\DTLformatedition{\DTLbibfield{Edition}}}% +\ifDTLmidsentence + \@dtl@tmp \else - \edef\dtl@initialscmd{\the\@dtl@toks\the\toks@}% - \expandafter\@dtl@toks\expandafter{\dtl@initialscmd}% - \expandafter\toks@\expandafter{\dtl@inithyphen}% + \DTLstartsentencespace + \expandafter\MakeUppercase\@dtl@tmp \fi -\def\dtl@tmp{#3}% -\ifx\@nnil\dtl@tmp - \edef\dtl@initialscmd{\the\@dtl@toks\the\toks@\DTLafterinitials}% - \let\dtl@initialsnext=\@gobble +\expandafter\DTLcheckendsperiod\expandafter{\@dtl@tmp}% +\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma +}{\DTLaddperiod}% +}{}% +\DTLformatdate +\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% +\DTLifbibfieldexists{Note}{% +\DTLstartsentencespace +\DTLbibfield{Note}% +\DTLcheckbibfieldendsperiod{Note}% +\DTLaddperiod}{}% +}% +% \end{macrocode} +% The format of an `incollection' entry. +% \begin{macrocode} +\renewcommand*{\DTLformatincollection}{% +\DTLifbibfieldexists{Author}{\DTLformatauthorlist\DTLaddperiod}{}% +\DTLifbibfieldexists{Title}{% +\DTLstartsentencespace +\DTLbibfield{Title}% +\DTLcheckbibfieldendsperiod{Title}% +\DTLaddperiod}{}% +\DTLifbibfieldexists{CrossRef}{% +% cross ref entry +\DTLformatincollproccrossref +\DTLifanybibfieldexists{Chapter,Pages}{\DTLaddcomma}{}% +\DTLformatchapterpages\DTLaddperiod +}{% no cross ref entry +\DTLformatinedbooktitle +\DTLifbibfieldexists{BookTitle}{% +\DTLifanybibfieldexists{Volume,Series,Chapter,Pages,Number}{% +\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLformatbvolume +\DTLifbibfieldexists{Volume}{% +\DTLifanybibfieldexists{Number,Series,Chapter,Pages}{% +\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLformatnumberseries +\DTLifanybibfieldexists{Number,Series}{% +\DTLifanybibfieldexists{Chapter,Pages}{\DTLaddcomma +}{\DTLaddperiod}}{}% +\DTLformatchapterpages +\DTLifanybibfieldexists{Chapter,Pages}{\DTLaddperiod}{}% +\DTLifbibfieldexists{Publisher}{% +\DTLstartsentencespace +\DTLbibfield{Publisher}% +\DTLcheckbibfieldendsperiod{Publisher}% +\DTLifanybibfieldexists{Address,Edition,Month,Year}{% +\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLifbibfieldexists{Address}{% +\DTLstartsentencespace +\DTLbibfield{Address}% +\DTLcheckbibfieldendsperiod{Address}% +\DTLifanybibfieldexists{Edition,Month,Year}{% +\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLifbibfieldexists{Edition}{% +\protected@edef\@dtl@tmp{\DTLformatedition{\DTLbibfield{Edition}}}% +\ifDTLmidsentence + \@dtl@tmp \else - \edef\dtl@initialscmd{\the\@dtl@toks\the\toks@\DTLbetweeninitials}% - \let\dtl@initialsnext=\dtl@initials + \DTLstartsentencespace + \expandafter\MakeUppercase\@dtl@tmp \fi -\dtl@initialsnext{#3}} +\expandafter\DTLcheckendsperiod\expandafter{\@dtl@tmp}% +\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma +}{\DTLaddperiod}% +}{}% +\DTLformatdate +\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% +}% +\DTLifbibfieldexists{Note}{% +\DTLstartsentencespace +\DTLbibfield{Note}% +\DTLcheckbibfieldendsperiod{Note}% +\DTLaddperiod}{}% +}% % \end{macrocode} -%\end{macro} -%\begin{macro}{\dtl@initialshyphen} +% The format of an `inproceedings' entry. % \begin{macrocode} -\def\dtl@initialshyphen#1-#2#3\dtl@endhyp{% -\def\dtl@inithyphen{#2}% -\ifx\dtl@inithyphen\@empty +\renewcommand*{\DTLformatinproceedings}{% +\DTLifbibfieldexists{Author}{\DTLformatauthorlist +\DTLaddperiod}{}% +\DTLifbibfieldexists{Title}{% +\DTLstartsentencespace +\DTLbibfield{Title}% +\DTLcheckbibfieldendsperiod{Title}% +\DTLaddperiod}{}% +\DTLifbibfieldexists{CrossRef}{% +% cross ref entry +\DTLformatincollproccrossref +\DTLifbibfieldexists{Pages}{\DTLaddcomma}{% +\DTLaddperiod}% +\DTLformatpages +\DTLifbibfieldexists{Pages}{\DTLaddperiod}{}% +}{% no cross ref +\DTLformatinedbooktitle +\DTLifbibfieldexists{BookTitle}{% +\DTLifanybibfieldexists{Volume,Series,Pages,Number,Address,% +Month,Year}{% +\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLformatbvolume +\DTLifbibfieldexists{Volume}{% +\DTLifanybibfieldexists{Number,Series,Pages,Address,Month,Year}{% +\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLformatnumberseries +\DTLifanybibfieldexists{Number,Series}{% +\DTLifanybibfieldexists{Pages,Address,Month,Year}{% +\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLformatpages +\DTLifbibfieldexists{Pages}{% +\DTLifanybibfieldexists{Address,Month,Year}{% +\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLifbibfieldexists{Address}{% +\DTLstartsentencespace +\DTLbibfield{Address}% +\DTLcheckbibfieldendsperiod{Address}% +\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{% +\DTLaddperiod}% +\DTLformatdate +\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% +\DTLifbibfieldexists{Organization}{% +\DTLstartsentencespace +\DTLbibfield{Organization}% +\DTLcheckbibfieldendsperiod{Organization}% +\DTLifbibfieldexists{Publisher}{\DTLaddcomma}{% +\DTLaddperiod}}{}% +\DTLifbibfieldexists{Publisher}{% +\DTLstartsentencespace +\DTLbibfield{Publisher}% +\DTLcheckbibfieldendsperiod{Publisher}% +\DTLaddperiod}{}% +}{% +\DTLifanybibfieldexists{Publisher,Organization}{% +\DTLaddperiod}{}% +\DTLifbibfieldexists{Organization}{% +\DTLstartsentencespace +\DTLbibfield{Organization}% +\DTLcheckbibfieldendsperiod{Organization}% +\DTLifanybibfieldexists{Publisher,Month,Year}{% +\DTLaddcomma}{}}{}% +\DTLifbibfieldexists{Publisher}{% +\DTLstartsentencespace +\DTLbibfield{Publisher}% +\DTLcheckbibfieldendsperiod{Publisher}% +\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{% +\DTLaddperiod}}{}% +\DTLformatdate +\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% +}% +}% +\DTLifbibfieldexists{Note}{% +\DTLstartsentencespace +\DTLbibfield{Note}% +\DTLcheckbibfieldendsperiod{Note}% +\DTLaddperiod}{}% +}% +% \end{macrocode} +% The format of a manual. +% \begin{macrocode} +\renewcommand*{\DTLformatmanual}{% +\DTLifbibfieldexists{Author}{\DTLformatauthorlist +\DTLaddperiod}{% +\DTLifbibfieldexists{Organization}{% +\DTLstartsentencespace +\DTLbibfield{Organization}% +\DTLcheckbibfieldendsperiod{Organization}% +\DTLifbibfieldexists{Address}{\DTLaddcomma \DTLbibfield{Address}% +\DTLcheckbibfieldendsperiod{Address}% +}{}% +\DTLaddperiod}{}% +}% +\DTLifbibfieldexists{Title}{% +\DTLstartsentencespace +{\em\DTLbibfield{Title}}% +\DTLcheckbibfieldendsperiod{Title}% +\DTLifbibfieldexists{Author}{% +\DTLifanybibfieldexists{Organization,Address}{% +\DTLaddperiod}{\DTLaddcomma}}{% +\DTLifanybibfieldexists{Organization,Address,Edition,Month,Year}{% +\DTLaddcomma}{\DTLaddperiod}}}{}% +\DTLifbibfieldexists{Author}{% +\DTLifbibfieldexists{Organization}{% +\DTLstartsentencespace +\DTLbibfield{Organization}% +\DTLcheckbibfieldendsperiod{Organization}% +\DTLifanybibfieldexists{Address,Edition,Month,Year}{% +\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLifbibfieldexists{Address}{% +\DTLstartsentencespace +\DTLbibfield{Address}% +\DTLcheckbibfieldendsperiod{Address}% +\DTLifanybibfieldexists{Edition,Month,Year}{% +\DTLaddcomma}{\DTLaddperiod}}{}% +}{% +\DTLifbibfieldexists{Organization}{}{% +\DTLifbibfieldexists{Address}{% +\DTLstartsentencespace +\DTLbibfield{Address}% +\DTLcheckbibfieldendsperiod{Address}% +\DTLifanybibfieldexists{Edition,Month,Year}{\DTLaddcomma}{% +\DTLaddperiod}}{}}% +}% +\DTLifbibfieldexists{Edition}{% +\protected@edef\@dtl@tmp{\DTLformatedition{\DTLbibfield{Edition}}}% +\ifDTLmidsentence + \@dtl@tmp \else - \edef\dtl@inithyphen{% - \DTLafterinitialbeforehyphen\DTLinitialhyphen#2}% + \DTLstartsentencespace + \expandafter\MakeUppercase\@dtl@tmp \fi +\expandafter\DTLcheckendsperiod\expandafter{\@dtl@tmp}% +\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{% +\DTLaddperiod}}{}% +\DTLformatdate +\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% +\DTLifbibfieldexists{Note}{% +\DTLstartsentencespace +\DTLbibfield{Note}% +\DTLcheckbibfieldendsperiod{Note}% +\DTLaddperiod}{}% +}% +% \end{macrocode} +% The format of a master's thesis. +% \begin{macrocode} +\renewcommand*{\DTLformatmastersthesis}{% +\DTLifbibfieldexists{Author}{\DTLformatauthorlist\DTLaddperiod}{}% +\DTLifbibfieldexists{Title}{% +\DTLstartsentencespace +\DTLbibfield{Title}% +\DTLcheckbibfieldendsperiod{Title}% +\DTLaddperiod}{}% +\DTLifbibfieldexists{Type}{% +\DTLstartsentencespace +\DTLbibfield{Type}% +\DTLcheckbibfieldendsperiod{Type}% +\DTLifanybibfieldexists{School,Address,Month,Year}{% +\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLifbibfieldexists{School}{% +\DTLstartsentencespace +\DTLbibfield{School}% +\DTLcheckbibfieldendsperiod{School}% +\DTLifanybibfieldexists{Address,Month,Year}{% +\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLifbibfieldexists{Address}{% +\DTLstartsentencespace +\DTLbibfield{Address}% +\DTLcheckbibfieldendsperiod{Address}% +\DTLifanybibfieldexists{Month,Year}{% +\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLformatdate +\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% +\DTLifbibfieldexists{Note}{% +\DTLstartsentencespace +\DTLbibfield{Note}% +\DTLcheckbibfieldendsperiod{Note}% +\DTLaddperiod}{}% +}% +% \end{macrocode} +% The format of a miscellaneous entry. +% \begin{macrocode} +\renewcommand*{\DTLformatmisc}{% +\DTLifbibfieldexists{Author}{\DTLformatauthorlist\DTLaddperiod}{}% +\DTLifbibfieldexists{Title}{% +\DTLstartsentencespace +\DTLbibfield{Title}% +\DTLcheckbibfieldendsperiod{Title}% +\DTLifbibfieldexists{HowPublished}{\DTLaddperiod}{% +\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{% +\DTLaddperiod}% +}% +\DTLmidsentencefalse}{}% +\DTLifbibfieldexists{HowPublished}{% +\DTLstartsentencespace +\DTLbibfield{HowPublished}% +\DTLcheckbibfieldendsperiod{HowPublished}% +\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{% +\DTLaddperiod}}{}% +\DTLformatdate +\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% +\DTLifbibfieldexists{Note}{% +\DTLstartsentencespace +\DTLbibfield{Note}% +\DTLcheckbibfieldendsperiod{Note}% +\DTLaddperiod}{}% +}% +% \end{macrocode} +% The format of a PhD thesis. +% \begin{macrocode} +\renewcommand*{\DTLformatphdthesis}{% +\DTLifbibfieldexists{Author}{\DTLformatauthorlist\DTLaddperiod}{}% +\DTLifbibfieldexists{Title}{% +\DTLstartsentencespace +{\em\DTLbibfield{Title}}% +\DTLcheckbibfieldendsperiod{Title}% +\DTLaddperiod}{}% +\DTLifbibfieldexists{Type}{% +\DTLstartsentencespace +\DTLbibfield{Type}% +\DTLcheckbibfieldendsperiod{Type}% +\DTLifanybibfieldexists{School,Address,Month,Year}{% +\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLifbibfieldexists{School}{% +\DTLstartsentencespace +\DTLbibfield{School}% +\DTLcheckbibfieldendsperiod{School}% +\DTLifanybibfieldexists{Address,Month,Year}{% +\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLifbibfieldexists{Address}{% +\DTLstartsentencespace +\DTLbibfield{Address}% +\DTLcheckbibfieldendsperiod{Address}% +\DTLifanybibfieldexists{Month,Year}{% +\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLformatdate +\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% +\DTLifbibfieldexists{Note}{% +\DTLstartsentencespace +\DTLbibfield{Note}% +\DTLcheckbibfieldendsperiod{Note}% +\DTLaddperiod}{}% +}% +% \end{macrocode} +% The format of a proceedings. +% \begin{macrocode} +\renewcommand*{\DTLformatproceedings}{% +\DTLifbibfieldexists{Editor}{% +\DTLformateditorlist\DTLaddperiod}{% +\DTLifbibfieldexists{Organization}{% +\DTLstartsentencespace +\DTLbibfield{Organization}% +\DTLcheckbibfieldendsperiod{Organization}% +\DTLaddperiod}{}}% +\DTLifbibfieldexists{Title}{% +\DTLstartsentencespace +{\em\DTLbibfield{Title}}% +\DTLcheckbibfieldendsperiod{Title}% +\DTLifanybibfieldexists{Volume,Number,Address,Editor,Publisher,% +Month,Year}{\DTLaddcomma}{\DTLaddperiod}% +}{}% +\DTLformatbvolume +\DTLifbibfieldexists{Volume}{% +\DTLifanybibfieldexists{Number,Address,Editor,Publisher,% +Month,Year}{\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLformatnumberseries +\DTLifbibfieldexists{Number}{% +\DTLifanybibfieldexists{Address,Editor,Publisher,% +Month,Year}{\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLifbibfieldexists{Address}{% +\DTLstartsentencespace +\DTLbibfield{Address}% +\DTLcheckbibfieldendsperiod{Address}% +\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{\DTLaddperiod}% +\DTLformatdate +\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% +\DTLifbibfieldexists{Editor}{\DTLifbibfieldexists{Organization}{% +\DTLstartsentencespace +\DTLbibfield{Organization}% +\DTLcheckbibfieldendsperiod{Organization}% +\DTLifbibfieldexists{Publisher}{% +\DTLaddcomma}{\DTLaddperiod}}{}}{}% +\DTLifbibfieldexists{Publisher}{% +\DTLstartsentencespace +\DTLbibfield{Publisher}% +\DTLcheckbibfieldendsperiod{Publisher}% +\DTLaddperiod +}{}% +}{% no address +\DTLifbibfieldexists{Editor}{% +\DTLifbibfieldexists{Organization}{% +\DTLstartsentencespace +\DTLbibfield{Organization}% +\DTLcheckbibfieldendsperiod{Organization}% +\DTLifanybibfieldexists{Publisher,Month,Year}{% +\DTLaddcomma}{\DTLaddperiod}}{}% +}{}% +\DTLifbibfieldexists{Publisher}{% +\DTLstartsentencespace +\DTLbibfield{Publisher}% +\DTLcheckbibfieldendsperiod{Publisher}% +\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLformatdate +\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% +}% +\DTLifbibfieldexists{Note}{% +\DTLstartsentencespace +\DTLbibfield{Note}% +\DTLcheckbibfieldendsperiod{Note}% +\DTLaddperiod}{}% +}% +% \end{macrocode} +% The format of a technical report. +% \begin{macrocode} +\renewcommand*{\DTLformattechreport}{% +\DTLifbibfieldexists{Author}{\DTLformatauthorlist\DTLaddperiod}{}% +\DTLifbibfieldexists{Title}{% +\DTLstartsentencespace +\DTLbibfield{Title}% +\DTLcheckbibfieldendsperiod{Title}% +\DTLaddperiod}{}% +\DTLifbibfieldexists{Type}{% +\DTLstartsentencespace +\DTLbibfield{Type}% +\DTLcheckbibfieldendsperiod{Type}% +\DTLifbibfieldexists{Number}{~}{}}{}% +\DTLifbibfieldexists{Number}{% +\DTLstartsentencespace +\DTLbibfield{Number}% +\DTLcheckbibfieldendsperiod{Number}% +}{}% +\DTLifanybibfieldexists{Type,Number}{% +\DTLifanybibfieldexists{Institution,Address,Month,Year}{\DTLaddcomma +}{\DTLaddperiod}}{}% +\DTLifbibfieldexists{Institution}{% +\DTLstartsentencespace +\DTLbibfield{Institution}% +\DTLcheckbibfieldendsperiod{Institution}% +\DTLifanybibfieldexists{Address,Month,Year}{\DTLaddcomma +}{\DTLaddperiod}}{}% +\DTLifbibfieldexists{Address}{% +\DTLstartsentencespace +\DTLbibfield{Address}% +\DTLcheckbibfieldendsperiod{Address}% +\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma +}{\DTLaddperiod}}{}% +\DTLformatdate +\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% +\DTLifbibfieldexists{Note}{% +\DTLstartsentencespace +\DTLbibfield{Note}% +\DTLcheckbibfieldendsperiod{Note}% +\DTLaddperiod}{}% +}% +% \end{macrocode} +% The format of an unpublished work. +% \begin{macrocode} +\renewcommand*{\DTLformatunpublished}{% +\DTLifbibfieldexists{Author}{\DTLformatauthorlist\DTLaddperiod}{}% +\DTLifbibfieldexists{Title}{% +\DTLstartsentencespace +\DTLbibfield{Title}% +\DTLcheckbibfieldendsperiod{Title}% +\DTLaddperiod}{}% +\DTLifbibfieldexists{Note}{% +\DTLstartsentencespace +\DTLbibfield{Note}% +\DTLcheckbibfieldendsperiod{Note}% +\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{\DTLaddperiod}}{}% +\DTLformatdate +\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% +}% +% \end{macrocode} +% End of `plain' style. +% \begin{macrocode} } % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLafterinitials} -% Defines what to do after the final initial. +% +%\begin{macro}{\dtlbst@abbrv} +% Define `abbrv' style. This is similar to `plain' except that +% some of the values are abbreviated % \begin{macrocode} -\newcommand*{\DTLafterinitials}{.} +\newcommand{\dtlbst@abbrv}{% % \end{macrocode} -%\end{macro} -%\begin{macro}{\DTLbetweeninitials} -% Defines what to do between initials. +% Base this style on `plain': % \begin{macrocode} -\newcommand*{\DTLbetweeninitials}{.} +\dtlbst@plain % \end{macrocode} -%\end{macro} -%\begin{macro}{\DTLafterinitialbeforehyphen} -% Defines what to do before a hyphen. +% Sets the author name format. % \begin{macrocode} -\newcommand*{\DTLafterinitialbeforehyphen}{.} +\renewcommand*{\DTLformatauthor}[4]{% +\DTLformatabbrvforenames{##4} +\DTLformatvon{##1}% +\DTLformatsurname{##2}% +\DTLformatjr{##3}} +% \end{macrocode} +% Sets the editor name format. +% \begin{macrocode} +\renewcommand*{\DTLformateditor}[4]{% +\DTLformatabbrvforenames{##4} +\DTLformatvon{##1}% +\DTLformatsurname{##2}% +\DTLformatjr{##3}} +% \end{macrocode} +% Sets the monthname format. +% \begin{macrocode} +\let\DTLmonthname\dtl@abbrvmonthname +% \end{macrocode} +% Sets other predefined names: +% \begin{macrocode} +\renewcommand*{\DTLacmcs}{ACM Comput.\ Surv.} +\renewcommand*{\DTLacta}{Acta Inf.} +\renewcommand*{\DTLcacm}{Commun.\ ACM} +\renewcommand*{\DTLibmjrd}{IBM J.\ Res.\ Dev.} +\renewcommand*{\DTLibmsj}{IBM Syst.~J.} +\renewcommand*{\DTLieeese}{IEEE Trans. Softw.\ Eng.} +\renewcommand*{\DTLieeetc}{IEEE Trans.\ Comput.} +\renewcommand*{\DTLieeetcad}{IEEE Trans.\ Comput.-Aided Design +Integrated Circuits} +\renewcommand*{\DTLipl}{Inf.\ Process.\ Lett.} +\renewcommand*{\DTLjacm}{J.~ACM} +\renewcommand*{\DTLjcss}{J.~Comput.\ Syst.\ Sci.} +\renewcommand*{\DTLscp}{Sci.\ Comput.\ Programming} +\renewcommand*{\DTLsicomp}{SIAM J.~Comput.} +\renewcommand*{\DTLtocs}{ACM Trans.\ Comput.\ Syst.} +\renewcommand*{\DTLtods}{ACM Trans.\ Database Syst.} +\renewcommand*{\DTLtog}{ACM Trans.\ Gr.} +\renewcommand*{\DTLtoms}{ACM Trans.\ Math. Softw.} +\renewcommand*{\DTLtoois}{ACM Trans. Office Inf.\ Syst.} +\renewcommand*{\DTLtoplas}{ACM Trans.\ Prog. Lang.\ Syst.} +\renewcommand*{\DTLtcs}{Theoretical Comput.\ Sci.} +% \end{macrocode} +% End of `abbrv' style. +% \begin{macrocode} +} % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLinitialhyphen} -%Defines what to do at the hyphen -%\changes{1.01}{2007 Aug 17}{new} +% +%\begin{macro}{\dtlbst@alpha} +% Define `alpha' style. This is similar to `plain' except that +% the labels are strings rather than numerical. % \begin{macrocode} -\newcommand*{\DTLinitialhyphen}{-} +\newcommand{\dtlbst@alpha}{% +% \end{macrocode} +% Base this style on `plain': +% \begin{macrocode} +\dtlbst@plain +% \end{macrocode} +% Set how to format the entire bibliography: +% \begin{macrocode} +\renewenvironment{DTLthebibliography}[2][\boolean{true}]{% +\dtl@createalphabiblabels{##1}{##2}% +\begin{thebibliography}{\@dtl@widestlabel}% +}{\end{thebibliography}}% +% \end{macrocode} +% Set how to start the bibliography entry: +% \begin{macrocode} +\renewcommand*{\DTLbibitem}{% +\expandafter\bibitem\expandafter + [\csname dtl@biblabel@\DBIBcitekey\endcsname]{\DBIBcitekey}}% +\renewcommand*{\DTLmbibitem}[1]{% +\expandafter\bibitem\expandafter + [\csname dtl@biblabel@\DBIBcitekey\endcsname]{##1@\DBIBcitekey}}% +% \end{macrocode} +% \begin{macrocode} +% \end{macrocode} +% End of `alpha' style. +% \begin{macrocode} +} % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLifAllUpperCase} +%\begin{macro}{dtl@createalphabiblabels} %\begin{definition} -%\cs{DTLifAllUpperCase}\marg{string}\marg{true part}\marg{false part} +%\cs{dtl@createalphabiblabels}\marg{condition}\marg{db name} %\end{definition} -% If \meta{string} only contains uppercase characters do \meta{true -%part}, otherwise do \meta{false part}. +% Constructs the alpha style bib labels for the given database. +% (Labels are stored in the control sequence +%\cs{dtl@biblabel@}\meta{citekey}.) This also sets +% \cs{@dtl@widestlabel} to the widest label. % \begin{macrocode} -\newcommand*{\DTLifAllUpperCase}[3]{% -\protected@edef\dtl@tuc{#1}% -\expandafter\dtl@testifuppercase\dtl@tuc\@nil\relax -\if@dtl@condition#2\else#3\fi +\newcommand*{\dtl@createalphabiblabels}[2]{% +\dtl@message{Creating bib labels}% +\begingroup +\gdef\@dtl@widestlabel{}% +\dtl@widest=0pt\relax +\DTLforeachbibentry[#1]{#2}{% +\dtl@message{\DBIBcitekey}% +\DTLifbibfieldexists{Author}{% + \dtl@listgetalphalabel{\@dtl@thislabel}{\@dtl@key@Author}% +}{% +\DTLifbibfieldexists{Editor}{% + \dtl@listgetalphalabel{\@dtl@thislabel}{\@dtl@key@Editor}% + }{% + \DTLifbibfieldexists{Key}{% + \expandafter\dtl@get@firstthree\expandafter + {\@dtl@key@Key}{\@dtl@thislabel}% + }{% + \DTLifbibfieldexists{Organization}{% + \expandafter\dtl@get@firstthree\expandafter + {\@dtl@key@Organization}{\@dtl@thislabel}% + }{% + \expandafter\dtl@get@firstthree\expandafter + {\DBIBentrytype}{\@dtl@thislabel}% + }% + }}}% +\DTLifbibfieldexists{Year}{}{\DTLifbibfieldexists{CrossRef}{% +\DTLgetvalueforkey{\@dtl@key@Year}{Year}{#2}{CiteKey}{% +\@dtl@key@CrossRef}}{}}% +\DTLifbibfieldexists{Year}{% +\expandafter\dtl@get@yearsuffix\expandafter{\@dtl@key@Year}% +\expandafter\toks@\expandafter{\@dtl@thislabel}% +\expandafter\@dtl@toks\expandafter{\@dtl@year}% +\edef\@dtl@thislabel{\the\toks@\the\@dtl@toks}% +}{}% +\let\@dtl@s@thislabel=\@dtl@thislabel +\@onelevel@sanitize\@dtl@s@thislabel +\@ifundefined{c@biblabel@\@dtl@s@thislabel}{% +\newcounter{biblabel@\@dtl@s@thislabel}% +\setcounter{biblabel@\@dtl@s@thislabel}{1}% +\expandafter\edef\csname @dtl@bibfirst@\@dtl@s@thislabel\endcsname{% +\DBIBcitekey}% +\expandafter\global +\expandafter\let\csname dtl@biblabel@\DBIBcitekey\endcsname= + \@dtl@thislabel +}{% +\expandafter\ifnum\csname c@biblabel@\@dtl@s@thislabel\endcsname=1\relax + \expandafter\let\expandafter\@dtl@tmp + \csname @dtl@bibfirst@\@dtl@s@thislabel\endcsname + \expandafter\protected@xdef\csname dtl@biblabel@\@dtl@tmp\endcsname{% + \@dtl@thislabel a}% +\fi +\stepcounter{biblabel@\@dtl@s@thislabel}% +\expandafter\protected@xdef\csname dtl@biblabel@\DBIBcitekey\endcsname{% + \@dtl@thislabel\alph{biblabel@\@dtl@s@thislabel}}% +}% +\settowidth{\dtl@tmplength}{% + \csname dtl@biblabel@\DBIBcitekey\endcsname}% +\ifdim\dtl@tmplength>\dtl@widest + \dtl@widest=\dtl@tmplength + \expandafter\global\expandafter\let\expandafter\@dtl@widestlabel + \expandafter=\csname dtl@biblabel@\DBIBcitekey\endcsname +\fi +}% +\endgroup } % \end{macrocode} %\end{macro} -%\begin{macro}{\dtl@testifalluppercase} +% +%\begin{macro}{\dtl@listgetalphalabel} +% Determine the alpha style label from a list of authors/editors +% (the first argument must be a control sequence (in which the +% label is stored), the second argument must be the list of names.) % \begin{macrocode} -\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 +\newcommand*{\dtl@listgetalphalabel}[2]{% +\@dtl@authorcount=0\relax +\@for\@dtl@author:=#2\do{% +\advance\@dtl@authorcount by 1\relax}% +\ifnum\@dtl@authorcount=1\relax + \expandafter\dtl@getsinglealphalabel#2{#1}\relax \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 + {% + \xdef#1{}% + \@dtl@tmpcount=0\relax + \def\DTLafterinitials{}\def\DTLbetweeninitials{}% + \def\DTLafterinitialbeforehyphen{}\def\DTLinitialhyphen{}% + \@for\@dtl@author:=#2\do{% + \expandafter\dtl@getauthorinitial\@dtl@author + \expandafter\toks@\expandafter{\@dtl@tmp}% + \expandafter\@dtl@toks\expandafter{#1}% + \xdef#1{\the\@dtl@toks\the\toks@}% + \advance\@dtl@tmpcount by 1\relax + \ifnum\@dtl@tmpcount>2\relax\@endfortrue\fi + }}% \fi -\ifx\dtl@testifuppernext\relax - \edef\dtl@dotestifuppernext{% - \noexpand\dtl@testifuppercase}% +} +% \end{macrocode} +%\end{macro} +% Get author's initial (stores in \cs{@dtl@tmp}): +% \begin{macrocode} +\newcommand*{\dtl@getauthorinitial}[4]{% +\def\@dtl@vonpart{#1}% +\ifx\@dtl@vonpart\@empty + \DTLstoreinitials{#2}{\@dtl@tmp}% \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 + \DTLstoreinitials{#1 #2}{\@dtl@tmp}% +\fi} +% \end{macrocode} +% Get label for single author (last argument is control sequence +% in which to store the label): +% \begin{macrocode} +\newcommand*{\dtl@getsinglealphalabel}[5]{% +\def\@dtl@vonpart{#1}% +\ifx\@dtl@vonpart\@empty + \DTLifSubString{#2}{-}{% + {\def\DTLafterinitials{}\def\DTLbetweeninitials{}% + \def\DTLafterinitialbeforehyphen{}% + \def\DTLinitialhyphen{}% + \DTLstoreinitials{#2}{\@dtl@tmp}\global\let#5=\@dtl@tmp}% + }{% + \dtl@getfirstthree{#5}#2{}{}{}{}\@nil + } +\else + {\def\DTLafterinitials{}\def\DTLbetweeninitials{}% + \def\DTLafterinitialbeforehyphen{}% + \def\DTLinitialhyphen{}% + \DTLstoreinitials{#1 #2}{\@dtl@tmp}\global\let#5=\@dtl@tmp}% \fi -\dtl@dotestifuppernext } % \end{macrocode} -%\end{macro} -%\begin{macro}{\dtl@test@ifalluppercase} +%Get first three letters from the given string: % \begin{macrocode} -\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 +\def\dtl@getfirstthree#1#2#3#4#5\@nil{% + \def#1{#2#3#4}% +} +\newcommand*{\dtl@get@firstthree}[2]{% +\dtl@getfirstthree#2#1{}{}{}{}{}\@nil} +% \end{macrocode} +%Get year suffix: +% \begin{macrocode} +\newcommand*{\dtl@get@yearsuffix}[1]{% +\dtl@getyearsuffix#1\@nil\relax\relax} + +\def\dtl@getyearsuffix#1#2#3{% +\def\@dtl@argi{#1}\def\@dtl@argii{#2}% +\def\@dtl@argiii{#3}% +\ifx\@dtl@argi\@nnil + \def\@dtl@year{}% + \let\@dtl@donext=\relax +\else + \ifx\@dtl@argii\@nnil + \dtl@ifsingle{#1}{% + \def\@dtl@year{#1}% + \let\@dtl@donext=\relax + }{% + \def\@dtl@donext{\dtl@getyearsuffix#1#2#3}% + }% \else - \ifnum\dtl@uccode=0\relax - \@dtl@conditiontrue - \let\dtl@testifuppernext=\dtl@testifuppercase + \ifx\@dtl@argiii\@nnil + \dtl@ifsingle{#1}{% + \dtl@ifsingle{#2}{% + \def\@dtl@year{#1#2}% + \let\@dtl@donext=\relax + }{% + \def\@dtl@donext{\dtl@getyearsuffix#2#3}% + }% + }{% + \def\@dtl@donext{\dtl@getyearsuffix#2#3}% + }% \else - \@dtl@conditionfalse - \let\dtl@testifuppernext=\@dtl@gobbletonil + \def\@dtl@donext{\dtl@getyearsuffix{#2}{#3}}% \fi \fi -}}} +\fi +\@dtl@donext +} +% \end{macrocode} +% +%\begin{macro}{\DTLbibliographystyle} +%\begin{definition} +%\cs{DTLbibliographystyle}\marg{style} +%\end{definition} +% Sets the bibliography style. +% \begin{macrocode} +\newcommand*{\DTLbibliographystyle}[1]{% +\@ifundefined{dtlbst@#1}{\PackageError{databib}{Unknown +bibliography style `#1'}{}}{\csname dtlbst@#1\endcsname}} % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLifAllLowerCase} +%Set the default bibliography style: +% \begin{macrocode} +\DTLbibliographystyle{\dtlbib@style} +% \end{macrocode} +% +%\section{Multiple Bibliographies} +% In order to have multiple bibliographies, there needs to be +% an aux file for each bibliography. The main bibliography is in +% \cs{jobname}.aux, but need to provide a means of creating +% additional aux files. +%\begin{macro}{\DTLmultibibs} %\begin{definition} -%\cs{DTLifAllLowerCase}\marg{string}\marg{true part}\marg{false part} +%\cs{DTLmultibibs}\marg{list} %\end{definition} -% If \meta{string} only contains lowercase characters do \meta{true -%part}, otherwise do \meta{false part}. +%\changes{1.01}{2007/08/22}{new} +% This creates an auxiliary file for each name in \meta{list}. +% For example, "\DTLmultibibs{foo,bar}" will create the files +% "foo.aux" and "bar.aux". % \begin{macrocode} -\newcommand*{\DTLifAllLowerCase}[3]{% -\protected@edef\dtl@tlc{#1}% -\expandafter\dtl@testiflowercase\dtl@tlc\@nil\relax -\if@dtl@condition#2\else#3\fi -} +\newcommand*{\DTLmultibibs}[1]{% +\@for\@dtl@af:=#1\do{% +\@ifundefined{dtl@aux@\@dtl@af}{% +\expandafter\newwrite\csname dtl@aux@\@dtl@af\endcsname +\expandafter\immediate +\expandafter\openout\csname dtl@aux@\@dtl@af\endcsname=\@dtl@af.aux +\expandafter\def\csname b@\@dtl@af @*\endcsname{}% +}{% +\PackageError{databib}{Can't create auxiliary file `\@dtl@af.aux', +\expandafter\string\csname dtl@aux@\@dtl@af\endcsname\space +already exists}{}}}} +% \end{macrocode} +% Can only be used in the preamble: +% \begin{macrocode} +\@onlypreamble{\DTLmultibibs} % \end{macrocode} %\end{macro} -%\begin{macro}{\dtl@testifalllowercase} +%\begin{macro}{\DTLcite} +%\begin{definition} +%\cs{DTLcite}\oarg{text}\marg{mbib}\marg{labels} +%\end{definition} +% This is similar to \cs{cite}\oarg{text}\marg{labels}, except +% 1) the cite information is written to the auxiliary file +% associated with the multi-bib \meta{mbib} (which must be named +% in \cs{DTLmultibibs}) and 2) the cross referencing label is +% constructed from \meta{mbib} and \meta{label} to allow for +% the same citation to appear in multiple bibliographies. % \begin{macrocode} -\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 +\newcommand*{\DTLcite}{\@ifnextchar[{\@tempswatrue \dtl@citex +}{\@tempswafalse \dtl@citex[]}} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtl@citex} +% \begin{macrocode} +\def\dtl@citex[#1]#2#3{% +\leavevmode\let\@citea\@empty +\@cite{\@for\@citeb:=#3\do{\@citea + \def\@citea{,\penalty \@m \ }% + \edef\@citeb{\expandafter\@firstofone\@citeb\@empty}% + \if@filesw + \@ifundefined{dtl@aux@#2}{% + \PackageError{databib}{multibib `#2' not defined}{% + You need to define `#2' in \string\DTLmutlibibs}% + }{% + \expandafter\immediate + \expandafter\write\csname dtl@aux@#2\endcsname{% + \string\citation{\@citeb}}% + }% \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 + \@ifundefined{b@#2@\@citeb}{% + \hbox{\reset@font\bfseries ?}% + \G@refundefinedtrue + \@latex@warning{Citation `\@citeb ' on page \thepage \space + undefined}% + }{% + \@cite@ofmt{\csname b@#2@\@citeb \endcsname }% + }% +}}{#1}% } % \end{macrocode} %\end{macro} -%\begin{macro}{\dtl@test@ifalllowercase} +%\begin{macro}{\DTLnocite} +%\begin{definition} +%\cs{DTLnocite}\marg{mbib}\marg{key list} +%\end{definition} +% As \cs{nocite} but uses the aux file associated with \meta{mbib} +% which must have been defined using \cs{DTLmultibibs}. % \begin{macrocode} -\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 +\newcommand*{\DTLnocite}[2]{% +\@ifundefined{dtl@aux@#1}{% + \PackageError{databib}{multibib `#1' not defined}{% + You need to define `#1' in \string\DTLmutlibibs}% }{% - \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 + \@bsphack + \ifx\@onlypreamble\document + \@for\@citeb:=#2\do{% + \edef\@citeb{\expandafter\@firstofone\@citeb}% + \if@filesw + \expandafter\immediate + \expandafter\write\csname dtl@aux@#1\endcsname{% + \string\citation{\@citeb}}% + \fi + \@ifundefined{b@#1@\@citeb}{% + \G@refundefinedtrue + \@latex@warning{Citation `\@citeb ' undefined}}{}% + }% \else - \ifnum\dtl@lccode=0\relax - \@dtl@conditiontrue - \let\dtl@testiflowernext=\dtl@testiflowercase - \else - \@dtl@conditionfalse - \let\dtl@testiflowernext=\@dtl@gobbletonil - \fi + \@latex@error{Cannot be used in preamble}\@eha \fi -}}} + \@esphack +}% +} % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLsubstitute} +%\begin{macro}{\DTLloadmbbl} %\begin{definition} -%\cs{DTLsubstitute}\marg{cmd}\marg{original}\marg{replacement} +%\cs{DTLloadmbib}\marg{mbib}\marg{db name}\marg{bib list} %\end{definition} -% Substitutes first occurence of \meta{original} with -% \marg{replacement} within the string given by \meta{cmd} % \begin{macrocode} -\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*{\DTLloadmbbl}[3]{% +\@ifundefined{dtl@aux@#1}{% + \PackageError{databib}{multibib `#1' not defined}{% + You need to define `#1' in \string\DTLmutlibibs}% +}{% + \if@filesw + \expandafter\immediate\expandafter + \write\csname dtl@aux@#1\endcsname{\string\bibstyle{databib}}% + \expandafter\immediate\expandafter + \write\csname dtl@aux@#1\endcsname{\string\bibdata{#3}}% + \fi + \DTLnewdb{#2}% + \edef\DTLBIBdbname{#2}% + \@input@{#1.bbl}% +}% } % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLsplitstring} %\begin{definition} -%\cs{DTLsplitstring}\marg{string}\marg{split text}\marg{before -%cmd}\marg{after cmd} +%\cs{DTLmbibliography}\oarg{condition}\marg{mbib name}\marg{bib dbname} %\end{definition} -% Splits string at \meta{split text} stores the pre split text -% in \meta{before cmd} and the post split text in \meta{after cmd}. -%\changes{1.01}{2007 Aug 17}{new} +% Displays the bibliography for the database \meta{bib dbname} +% which must have previously been loaded using +% \cs{DTLloadmbbl}, where \meta{mbib name} must be listed +% in \cs{DTLmultibibs}. +%\begin{macro}{\DTLmbibliography} % \begin{macrocode} -\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 +\newcommand*{\DTLmbibliography}[3][\boolean{true}]{% +\begin{DTLthebibliography}[#1]{#3}% +\DTLforeachbibentry[#1]{#3}{% +\DTLmbibitem{#2} \DTLformatbibentry \DTLendbibitem }% -\def\dtl@split@str##1#2\@nil{% -\def#4{##1}}% -\dtl@splitstr#1#2\@nil +\end{DTLthebibliography}% } % \end{macrocode} %\end{macro} -% -%\begin{macro}{\DTLsubstituteall} -%\begin{definition} -%\cs{DTLsubstituteall}\marg{cmd}\marg{original}\marg{replacement} -%\end{definition} -% Substitutes all occurences of \meta{original} with -% \marg{replacement} within the string given by \meta{cmd} -%\changes{1.01}{2007 Aug 17}{fixed bug caused when certain commands -% occur in the string} +%\iffalse % \begin{macrocode} -\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}% -} +%</databib.sty> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%<*databar.sty> +% \end{macrocode} +%\fi +%\chapter{databar.sty} +% Declare package: +% \begin{macrocode} +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{databar}[2012/07/18 v2.10 (NLCT)] +% \end{macrocode} +% Require \sty{xkeyval} package +% \begin{macrocode} +\RequirePackage{xkeyval} +% \end{macrocode} +% Require \sty{dataplot} package +% \begin{macrocode} +\RequirePackage{dataplot} +% \end{macrocode} +%\begin{macro}{\ifDTLcolorbarchart} +% The conditional \cs{ifDTLcolorbarchart} is used to determine +% whether to use colour or grey scale. +% \begin{macrocode} +\newif\ifDTLcolorbarchart +\DTLcolorbarcharttrue % \end{macrocode} %\end{macro} -%\begin{macro}{\@dtl@dosubstitute} -% Recursive substitution macro. +% Package options to change the conditional: % \begin{macrocode} -\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 +\DeclareOption{color}{\DTLcolorbarcharttrue} +\DeclareOption{gray}{\DTLcolorbarchartfalse} +% \end{macrocode} +%\cs{DTLbarXlabelalign} specifies the alignment +% for the $x$ axis labels. +% \begin{macrocode} +\newcommand*{\DTLbarXlabelalign}{left,rotate=-90} +% \end{macrocode} +%\cs{DTLbarYticklabelalign} specifies the alignment +% for the $x$ axis labels. +% \begin{macrocode} +\newcommand*{\DTLbarYticklabelalign}{right} +% \end{macrocode} +%\begin{macro}{\ifDTLverticalbars} +% Define boolean keys to govern bar chart orientation. +% \begin{macrocode} +\define@boolkey{databar}[DTL]{verticalbars}[true]{% +\ifDTLverticalbars + \def\DTLbarXlabelalign{left,rotate=-90}% + \def\DTLbarYticklabelalign{right} \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\DTLbarXlabelalign{right}% + \def\DTLbarYticklabelalign{center} +\fi} +% \end{macrocode} +%\end{macro} +% Set defaults: +% \begin{macrocode} +\DTLverticalbarstrue +% \end{macrocode} +% Package options to change \cs{ifDTLverticalbars} +% \begin{macrocode} +\DeclareOption{vertical}{\DTLverticalbarstrue + \def\DTLbarXlabelalign{left,rotate=-90}% + \def\DTLbarYticklabelalign{right} +} +\DeclareOption{horizontal}{\DTLverticalbarsfalse + \def\DTLbarXlabelalign{right}% + \def\DTLbarYticklabelalign{center} } % \end{macrocode} +% Process options: +% \begin{macrocode} +\ProcessOptions +% \end{macrocode} +% Required packages: +% \begin{macrocode} +\RequirePackage{datatool} +\RequirePackage{tikz} +% \end{macrocode} +% Define some variables that govern the appearance of the bar +% chart. +% +%\begin{macro}{\DTLbarchartlength} +% The total height of the bar chart is given by \cs{DTLbarchartheight} +% \begin{macrocode} +\newlength\DTLbarchartlength +\DTLbarchartlength=3in +% \end{macrocode} %\end{macro} -%\begin{macro}{\@dtl@dosubstitutenoop} -% Terminates recursive substitution macro. +% +%\begin{macro}{\DTLbarwidth} +% The width of each bar is given by \cs{DTLbarwidth}. % \begin{macrocode} -\def\@dtl@dosubstitutenoop#1#2{} +\newlength\DTLbarwidth +\DTLbarwidth=1cm % \end{macrocode} %\end{macro} % -%\subsection{Currencies} -%\begin{macro}{\@dtl@currencies} -% \cs{@dtl@currencies} stores all known currencies. +%\begin{macro}{\DTLbarlabeloffset} +% The offset from the $x$ axis to the bar label if given by +% \cs{DTLbarlabeloffset}. % \begin{macrocode} -\newcommand*{\@dtl@currencies}{\$,\pounds} +\newlength\DTLbarlabeloffset +\setlength\DTLbarlabeloffset{10pt} % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLnewcurrencysymbol} +%\begin{macro}{\DTLBarXAxisStyle} +% The style of the $x$ axis is given by \cs{DTLBarXAxisStyle} +% \begin{macrocode} +\newcommand*{\DTLBarXAxisStyle}{-} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLBarYAxisStyle} +% The style of the $y$ axis is given by \cs{DTLBarYAxisStyle}. +% \begin{macrocode} +\newcommand*{\DTLBarYAxisStyle}{-} +% \end{macrocode} +%\end{macro} +% +%\begin{counter}{DTLbarroundvar} +% \ctrfmt{DTLbarroundvar} is a counter governing the number of digits +% to round to when using \cs{FPround}. +% \begin{macrocode} +\newcounter{DTLbarroundvar} +\setcounter{DTLbarroundvar}{1} +% \end{macrocode} +%\end{counter} +% +%\begin{macro}{\DTLbardisplayYticklabel} +%\cs{DTLbardisplayYticklabel} governs how the $y$ tick labels appear. +% \begin{macrocode} +\newcommand*{\DTLbardisplayYticklabel}[1]{#1} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLdisplaylowerbarlabel} +%\cs{DTLdisplaylowerbarlabel} governs how the lower bar labels appear. +% \begin{macrocode} +\newcommand*{\DTLdisplaylowerbarlabel}[1]{#1} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLdisplaylowermultibarlabel} +%\cs{DTLdisplaylowermultibarlabel} governs how the lower multi bar labels appear. +% \begin{macrocode} +\newcommand*{\DTLdisplaylowermultibarlabel}[1]{#1} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLdisplayupperbarlabel} +%\cs{DTLdisplayupperbarlabel} governs how the upper bar labels +% appear. +% \begin{macrocode} +\newcommand*{\DTLdisplayupperbarlabel}[1]{#1} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLdisplayuppermultibarlabel} +%\cs{DTLdisplayuppermultibarlabel} governs how the upper multi bar +% labels appear. +% \begin{macrocode} +\newcommand*{\DTLdisplayuppermultibarlabel}[1]{#1} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLbaratbegintikz} +% \cs{DTLbaratbegintikz} specifies any commands +% to apply at the start of the \env{tikzpicture} environment. +% By default it does nothing. +% \begin{macrocode} +\newcommand*{\DTLbaratbegintikz}{} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLbaratendtikz} +% \cs{DTLbaratendtikz} specifies any commands +% to apply at the end of the \env{tikzpicture} environment. +% By default it does nothing. +% \begin{macrocode} +\newcommand*{\DTLbaratendtikz}{} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\ifDTLbarxaxis} +% The conditional \cs{ifDTLbarxaxis} is used to determine +% whether or not to display the $x$ axis +% \begin{macrocode} +\newif\ifDTLbarxaxis +% \end{macrocode} +%\end{macro} +%\begin{macro}{\ifDTLbaryaxis} +% The conditional \cs{ifDTLbaryaxis} is used to determine +% whether or not to display the $y$ axis. +% \begin{macrocode} +\newif\ifDTLbaryaxis +% \end{macrocode} +%\end{macro} +%\begin{macro}{\ifDTLbarytics} +% The conditional \cs{ifDTLbarytics} to determine whether +% or not to display the $y$ tick marks. +% \begin{macrocode} +\newif\ifDTLbarytics +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@dtl@barcount} +% The count register \cs{@dtl@barcount} is used to store +% the current bar index. +% \begin{macrocode} +\newcount\@dtl@barcount +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLsetbarcolor} %\begin{definition} -% \cs{DTLaddcurrency}\marg{symbol} +% \cs{DTLsetbarcolor}\marg{n}\marg{color} %\end{definition} -% Adds \meta{symbol} to the list of known currencies +% Assigns colour name \meta{color} to the \meta{n}th bar. % \begin{macrocode} -\newcommand*{\DTLnewcurrencysymbol}[1]{% -\expandafter\toks@\expandafter{\@dtl@currencies}% -\@dtl@toks{#1}% -\edef\@dtl@currencies{\the\@dtl@toks,\the\toks@}% +\newcommand*{\DTLsetbarcolor}[2]{% +\expandafter\def\csname dtlbar@segcol\romannumeral#1\endcsname{#2}% } % \end{macrocode} %\end{macro} -% If any of the following currency commands have been defined, -% add them to the list: +% +%\begin{macro}{\DTLgetbarcolor} +%\begin{definition} +%\cs{DTLgetbarcolor}\marg{n} +%\end{definition} +% Gets the colour specification for the \meta{n}th bar. % \begin{macrocode} -\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*{\DTLgetbarcolor}[1]{% +\csname dtlbar@segcol\romannumeral#1\endcsname} % \end{macrocode} -%\begin{macro}{\@dtl@standardize@currency} +%\end{macro} +% +%\begin{macro}{\DTLdobarcolor} %\begin{definition} -%\cs{@dtl@standardize@currency}\marg{cmd} +%\cs{DTLdobarcolor}\marg{n} %\end{definition} -% Substitutes the first currency symbol found in \meta{cmd} -% with "\$". This is used when testing text to determine -% if it is currency. The original currency symbol is stored -% in \cs{@dtl@org@currency}, so that it can be replaced later. -% If no currency symbol is found, \cs{@dtl@org@currency} will -% be empty. +% Sets the colour to that for the \meta{n}th bar. % \begin{macrocode} -\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*{\DTLdobarcolor}[1]{% +\expandafter\color\expandafter +{\csname dtlbar@segcol\romannumeral#1\endcsname}} % \end{macrocode} %\end{macro} % -%\begin{macro}{\@dtl@currency} -%\cs{@dtl@currency} is set by \cs{DTLlocaltodecimal} and -%\cs{@dtl@checknumerical}. It is used by \cs{DTLdecimaltocurrency}. -% Set to "\$" by default. +%\begin{macro}{\DTLdocurrentbarcolor} +%\cs{DTLdocurrentbarcolor} +% sets the colour to that of the current bar. % \begin{macrocode} -\newcommand*{\@dtl@currency}{\$} +\newcommand*{\DTLdocurrentbarcolor}{% +\ifnum\dtlforeachlevel=0\relax + \PackageError{databar}{Can't use + \string\DTLdocurrentbarcolor\space outside + \string\DTLbarchart}{}% +\else + \expandafter\DTLdobarcolor\expandafter{% + \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname}% +\fi} % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLsetdefaultcurrency} -%\cs{DTLsetdefaultcurrency}\marg{symbol} sets the default currency. +% +%\begin{macro}{\DTLbaroutlinecolor} +%\cs{DTLbaroutlinecolor} specifies what colour to draw the +% outline. % \begin{macrocode} -\newcommand*{\DTLsetdefaultcurrency}[1]{% -\renewcommand*{\@dtl@currency}{#1}} +\newcommand*{\DTLbaroutlinecolor}{black} % \end{macrocode} %\end{macro} % -%\begin{macro}{\dtl@ifsingle} -%\begin{definition} -%\cs{dtl@ifsingle}\marg{arg}\marg{true part}\marg{false part} -%\end{definition} -% If there is only one object in \meta{arg} (without expansion) -% do \meta{true part}, otherwise do false part. +%\begin{macro}{\DTLbaroutlinewidth} +%\cs{DTLbaroutlinewidth} specifies the line width of the outline: +% Outline is only drawn if the linewidth is greater than 0pt. % \begin{macrocode} -\newcommand{\dtl@ifsingle}[3]{% -\def\@dtl@arg{#1}% -\ifx\@dtl@arg\@empty - #3% +\newlength\DTLbaroutlinewidth +\DTLbaroutlinewidth=0pt +% \end{macrocode} +%\end{macro} +% +% Set the default colours. If there are more than eight bars, +% more colours will need to be defined. +% \begin{macrocode} +\ifDTLcolorbarchart + \DTLsetbarcolor{1}{red} + \DTLsetbarcolor{2}{green} + \DTLsetbarcolor{3}{blue} + \DTLsetbarcolor{4}{yellow} + \DTLsetbarcolor{5}{magenta} + \DTLsetbarcolor{6}{cyan} + \DTLsetbarcolor{7}{orange} + \DTLsetbarcolor{8}{white} \else - \@dtl@ifsingle#1\@nil{#2}{#3}% + \DTLsetbarcolor{1}{black!15} + \DTLsetbarcolor{2}{black!25} + \DTLsetbarcolor{3}{black!35} + \DTLsetbarcolor{4}{black!45} + \DTLsetbarcolor{5}{black!55} + \DTLsetbarcolor{6}{black!65} + \DTLsetbarcolor{7}{black!75} + \DTLsetbarcolor{8}{black!85} \fi -} +% \end{macrocode} +%\begin{macro}{\DTLeverybarhook} +% Code to apply at every bar. The start point of the bar +% can be accessed via \cs{DTLstartpt}, the mid point of the bar +% can be accessed via \cs{DTLmidpt} and the end point of the +% bar can be accessed via \cs{DTLendpt} +%\changes{2.0}{2009 February 27}{new}% +% \begin{macrocode} +\newcommand*{\DTLeverybarhook}{} % \end{macrocode} %\end{macro} -%\begin{macro}{\@dtl@ifsingle} +% +% Define keys for \cs{DTLbarchart} optional argument. +% Set the maximum value of the $y$ axis. % \begin{macrocode} -\def\@dtl@ifsingle#1#2\@nil#3#4{% -\def\dtl@sg@arg{#2}% -\ifx\dtl@sg@arg\@empty - #3% +\define@key{databar}{max}{\def\DTLbarmax{#1}} +% \end{macrocode} +% Set the total length of the bar chart +% \begin{macrocode} +\define@key{databar}{length}{\DTLbarchartlength=#1\relax +} +% \end{macrocode} +% Set the maximum depth (negative extent) +% \begin{macrocode} +\define@key{databar}{maxdepth}{% +\ifnum#1>0\relax + \PackageError{databar}{depth must be zero or negative}{}% \else - #4% + \def\DTLnegextent{#1}% +\fi} +% \end{macrocode} +% Determine which axes should be shown +% \begin{macrocode} +\define@choicekey{databar}{axes}[\var\nr]{both,x,y,none}{% +\ifcase\nr\relax + % both + \DTLbarxaxistrue + \DTLbaryaxistrue + \DTLbaryticstrue +\or + % x only + \DTLbarxaxistrue + \DTLbaryaxisfalse + \DTLbaryticsfalse +\or + % y only + \DTLbarxaxisfalse + \DTLbaryaxistrue + \DTLbaryticstrue +\or + % neither + \DTLbarxaxisfalse + \DTLbaryaxisfalse + \DTLbaryticsfalse \fi } % \end{macrocode} -%\end{macro} -% -%\subsection{Debugging commands} -% These commands are provided to assist debugging -%\begin{macro}{\dtlshowdb} -%\begin{definition} -%\cs{dtlshowdb}\marg{db name} -%\end{definition} -% Shows the database. -%\changes{2.0}{2009 February 27}{updated to use new database structure} +% Variable used to create the bar chart. (Must be a control +% sequence.) % \begin{macrocode} -\newcommand*{\dtlshowdb}[1]{% -\expandafter\showthe\csname dtldb@#1\endcsname} +\define@key{databar}{variable}{% + \def\DTLbarvariable{#1}% +} +% \end{macrocode} +% Variables used to create the multi bar chart. (Must be a +% comma separated list of control sequences.) +% \begin{macrocode} +\define@key{databar}{variables}{% + \def\dtlbar@variables{#1}% +} +% \end{macrocode} +% Bar width +% \begin{macrocode} +\define@key{databar}{barwidth}{\setlength{\DTLbarwidth}{#1}} +% \end{macrocode} +% Lower bar labels +% \begin{macrocode} +\define@key{databar}{barlabel}{% +\def\dtl@barlabel{#1}} +\def\dtl@barlabel{} +% \end{macrocode} +% Lower bar labels for multi-bar charts +% \begin{macrocode} +\define@key{databar}{multibarlabels}{% +\def\dtl@multibarlabels{#1}} +\def\dtl@multibarlabels{} +% \end{macrocode} +% Gap between groups in multi-bar charts (This should be in $x$ units +% where 1 $x$ unit is the width of a bar.) +% \begin{macrocode} +\define@key{databar}{groupgap}{\def\dtlbar@groupgap{#1}} +\def\dtlbar@groupgap{1} +% \end{macrocode} +% Upper bar labels +% \begin{macrocode} +\define@key{databar}{upperbarlabel}{% +\def\dtl@upperbarlabel{#1}} +\def\dtl@upperbarlabel{} +% \end{macrocode} +% Upper bar labels for multi-bar charts +% \begin{macrocode} +\define@key{databar}{uppermultibarlabels}{% +\def\dtl@uppermultibarlabels{#1}} +\def\dtl@uppermultibarlabels{} +% \end{macrocode} +% Define list of points for $y$ tics. (Must be a comma separated list +% of decimal numbers.) +% \begin{macrocode} +\define@key{databar}{yticpoints}{% +\def\dtlbar@yticlist{#1}\DTLbaryticstrue\DTLbaryaxistrue} +\let\dtlbar@yticlist=\relax +% \end{macrocode} +% Set the $y$ tick gap: +% \begin{macrocode} +\define@key{databar}{yticgap}{% +\def\dtlbar@yticgap{#1}\DTLbaryticstrue\DTLbaryaxistrue} +\let\dtlbar@yticgap=\relax +% \end{macrocode} +% Define list of labels for $y$ tics. +% \begin{macrocode} +\define@key{databar}{yticlabels}{% +\def\dtlbar@yticlabels{#1}\DTLbaryticstrue\DTLbaryaxistrue} +\let\dtlbar@yticlabels=\relax +% \end{macrocode} +% Define $y$ axis label. +% \begin{macrocode} +\define@key{databar}{ylabel}{% +\def\dtlbar@ylabel{#1}} +\let\dtlbar@ylabel=\relax % \end{macrocode} -%\end{macro} % -%\begin{macro}{\dtlshowdbkeys} +%\begin{macro}{\DTLbarchart} %\begin{definition} -%\cs{dtlshowdbkeys}\marg{db name} +% \cs{DTLbarchart}\oarg{conditions}\marg{option list}\marg{db name}\marg{assign list} %\end{definition} -% Shows the key list for the named database. -%\changes{2.0}{2009 February 27}{updated to use new database structure} +% Make a bar chart from data given in data base \meta{db name}, +% where \meta{assign list} is a comma-separated list of +% \meta{cmd}\texttt{=}\meta{key} pairs. \meta{option list} must +% include \texttt{variable}\texttt{=}\meta{cmd}, where \meta{cmd} +% is included in \meta{assign list}. The optional argument +% \meta{conditions} is the same as that for \cs{DTLforeach}. % \begin{macrocode} -\newcommand*{\dtlshowdbkeys}[1]{% -\expandafter\showthe\csname dtlkeys@#1\endcsname} +\newcommand*{\DTLbarchart}[4][\boolean{true}]{% +{% + \undef\DTLbarvariable + \undef\DTLbarmax + \undef\DTLnegextent + \disable@keys{databar}{variables,multibarlabels,% + uppermultibarlabels,groupgap}% + \setkeys{databar}{#2}% + \ifundef{\DTLbarvariable}% + {% + \PackageError{databar}% + {\string\DTLbarchart\space missing variable}% + {You haven't use the "variable" key}% + }% + {% +% \end{macrocode} +% Compute the maximum bar height, unless \cs{DTLbarmax} has been +% set. +%\changes{1.01}{2007 Aug 17}{uses \cs{@sDTLforeach} instead of +%\cs{DTLforeach}} +% \begin{macrocode} + \ifundef{\DTLbarmax}% + {% + \@sDTLforeach[#1]{#3}{#4}{% + \expandafter\DTLconverttodecimal\expandafter + {\DTLbarvariable}{\dtl@barvar}% + \ifundef{\DTLbarmax}% + {% + \let\DTLbarmax=\dtl@barvar + }% + {% + \let\dtl@old=\DTLbarmax + \dtlmax{\DTLbarmax}{\dtl@old}{\dtl@barvar}% + }% + }% + \ifx\dtlbar@yticgap\relax + \else + \let\dtl@thistick=\dtlbar@yticgap + \whiledo{\DTLisFPopenbetween{\dtl@thistick}{0}{\DTLbarmax}}% + {% + \dtladd{\dtl@thistick}{\dtl@thistick}{\dtlbar@yticgap}% + }% + \let\DTLbarmax=\dtl@thistick + \fi + }% + {}% +% \end{macrocode} +% Compute the bar depth, unless \cs{DTLnegextent} has been +% set. +% \begin{macrocode} + \ifundef{\DTLnegextent}% + {% + \def\DTLnegextent{0}% + \@sDTLforeach[#1]{#3}{#4}{% + \expandafter\DTLconverttodecimal\expandafter + {\DTLbarvariable}{\dtl@barvar}% + \let\dtl@old=\DTLnegextent + \DTLmin{\DTLnegextent}{\dtl@old}{\dtl@barvar}% + }% + \ifx\dtlbar@yticgap\relax + \else + \ifthenelse{\DTLisFPlt{\DTLnegextent}{0}}% + {% + \edef\dtl@thistick{0}% + \whiledo{\DTLisFPclosedbetween{\dtl@thistick}{\DTLnegextent}{0}}{% + \dtlsub{\dtl@thistick}{\dtl@thistick}{\dtlbar@yticgap}% + }% + \let\DTLnegextent=\dtl@thistick + }{}% + \fi + }% + {}% +% \end{macrocode} +% Determine scaling factor +% \begin{macrocode} + \@dtl@tmpcount=\DTLbarchartlength + \dtlsub{\dtl@extent}{\DTLbarmax}{\DTLnegextent}% + \dtldiv{\dtl@unit}{\number\@dtl@tmpcount}{\dtl@extent}% +% \end{macrocode} +% Construct $y$ tick list if required +% \begin{macrocode} + \setlength{\dtl@yticlabelwidth}{0pt}% + \ifDTLbarytics + \ifx\dtlbar@yticlist\relax + \ifx\dtlbar@yticgap\relax + \dtl@constructticklist\DTLnegextent\DTLbarmax + \dtl@unit\dtlbar@yticlist + \else + \dtl@constructticklistwithgapz + \DTLnegextent\DTLbarmax\dtlbar@yticlist\dtlbar@yticgap + \fi + \fi + \ifx\dtlbar@ylabel\relax + \else + \ifx\dtlbar@yticlabels\relax + \@for\dtl@thislabel:=\dtlbar@yticlist\do{% + \dtlround{\dtl@thislabel}{\dtl@thislabel} + {\c@DTLbarroundvar}% + \ifDTLverticalbars + \settowidth{\dtl@tmplength}{% + \DTLbardisplayYticklabel{\dtl@thislabel}}% + \else + \settoheight{\dtl@tmplength}{% + \DTLbardisplayYticklabel{\dtl@thislabel}}% + \edef\@dtl@h{\the\dtl@tmplength}% + \settodepth{\dtl@tmplength}{% + \DTLbardisplayYticklabel{\dtl@thislabel}}% + \addtolength{\dtl@tmplength}{\@dtl@h}% + \addtolength{\dtl@tmplength}{\baselineskip}% + \fi + \ifdim\dtl@tmplength>\dtl@yticlabelwidth + \setlength{\dtl@yticlabelwidth}{\dtl@tmplength}% + \fi + }% + \else + \@for\dtl@thislabel:=\dtlbar@yticlabels\do{% + \ifDTLverticalbars + \settowidth{\dtl@tmplength}{% + \DTLbardisplayYticklabel{\dtl@thislabel}}% + \else + \settoheight{\dtl@tmplength}{% + \DTLbardisplayYticklabel{\dtl@thislabel}}% + \edef\@dtl@h{\the\dtl@tmplength}% + \settodepth{\dtl@tmplength}{% + \DTLbardisplayYticklabel{\dtl@thislabel}}% + \addtolength{\dtl@tmplength}{\@dtl@h}% + \addtolength{\dtl@tmplength}{\baselineskip}% + \fi + \ifdim\dtl@tmplength>\dtl@yticlabelwidth + \setlength{\dtl@yticlabelwidth}{\dtl@tmplength}% + \fi + }% + \fi + \fi + \fi +% \end{macrocode} +% Store the width of the bar chart in \cs{DTLbarchartwidth} +% \begin{macrocode} + \edef\DTLbarchartwidth{\expandafter\number\csname dtlrows@#3\endcsname} +% \end{macrocode} +% Do the bar chart +% \begin{macrocode} + \begin{tikzpicture} +% \end{macrocode} +% Set unit vectors +% \begin{macrocode} + \ifDTLverticalbars + \pgfsetyvec{\pgfpoint{0pt}{\dtl@unit sp}}% + \pgfsetxvec{\pgfpoint{\DTLbarwidth}{0pt}}% + \else + \pgfsetxvec{\pgfpoint{\dtl@unit sp}{0pt}}% + \pgfsetyvec{\pgfpoint{0pt}{\DTLbarwidth}}% + \fi +% \end{macrocode} +% Begin hook +% \begin{macrocode} + \DTLbaratbegintikz +% \end{macrocode} +% Initialise +% \begin{macrocode} + \def\@dtl@start{0}% +% \end{macrocode} +% Iterate through data +% \begin{macrocode} + \@sDTLforeach[#1]{#3}{#4}{% +% \end{macrocode} +% Store the bar number in \cs{@dtl@bar} +% \begin{macrocode} + \expandafter\let\expandafter\@dtl@bar + \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname% +% \end{macrocode} +% Convert variable to decimal +% \begin{macrocode} + \expandafter\DTLconverttodecimal\expandafter + {\DTLbarvariable}{\dtl@variable}% +% \end{macrocode} +% Draw bars +% \begin{macrocode} + \begin{scope} + \DTLdocurrentbarcolor + \ifDTLverticalbars + \fill (\@dtl@start,0) -- (\@dtl@start,\dtl@variable) + -- (\@dtl@bar,\dtl@variable) -- (\@dtl@bar,0) -- cycle; + \else + \fill (0,\@dtl@start) -- (\dtl@variable,\@dtl@start) + -- (\dtl@variable,\@dtl@bar) -- (0,\@dtl@bar) -- cycle; + \fi + \end{scope} +% \end{macrocode} +% Draw outline +% \begin{macrocode} + \begin{scope} + \ifdim\DTLbaroutlinewidth>0pt + \expandafter\color\expandafter{\DTLbaroutlinecolor} + \ifDTLverticalbars + \draw (\@dtl@start,0) -- (\@dtl@start,\dtl@variable) + -- (\@dtl@bar,\dtl@variable) -- (\@dtl@bar,0) -- cycle; + \else + \draw (0,\@dtl@start) -- (\dtl@variable,\@dtl@start) + -- (\dtl@variable,\@dtl@bar) -- (0,\@dtl@bar) -- cycle; + \fi + \fi + \end{scope} +% \end{macrocode} +% Draw lower $x$ labels +% \begin{macrocode} + \ifDTLverticalbars + \edef\dtl@textopt{% + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{\@dtl@start.5}{0}} + {\noexpand\pgfpoint{0pt}{-\noexpand\DTLbarlabeloffset}}}, + \DTLbarXlabelalign + }% +% \end{macrocode} +% Set \cs{DTLstartpt} to the starting point. +% \begin{macrocode} + \edef\DTLstartpt{\noexpand\pgfpointxy{\@dtl@start.5}{0}}% + \else + \edef\dtl@textopt{% + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{0}{\@dtl@start.5}} + {\noexpand\pgfpoint{-\noexpand\DTLbarlabeloffset}{0pt}}}, + \DTLbarXlabelalign + }% +% \end{macrocode} +% Set \cs{DTLstartpt} to the starting point. +% \begin{macrocode} + \edef\DTLstartpt{\noexpand\pgfpointxy{0}{\@dtl@start.5}}% + \fi + \expandafter\pgftext\expandafter[\dtl@textopt]{% + \DTLdisplaylowerbarlabel{\dtl@barlabel}} +% \end{macrocode} +% Draw upper $x$ labels +% \begin{macrocode} + \ifDTLverticalbars +% \end{macrocode} +% Vertical bars +% \begin{macrocode} + \expandafter\DTLifnumlt\expandafter{\DTLbarvariable}{0}% + { + \edef\dtl@textopt{% + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{\@dtl@start.5}{\dtl@variable}} + {\noexpand\pgfpoint{0pt}{-\noexpand\DTLbarlabeloffset}}} + }% + }{% + \edef\dtl@textopt{% + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{\@dtl@start.5}{\dtl@variable}} + {\noexpand\pgfpoint{0pt}{\noexpand\DTLbarlabeloffset}}} + }% + } +% \end{macrocode} +% Set \cs{DTLendpt} to the end point. +% \begin{macrocode} + \edef\DTLendpt{\noexpand\pgfpointxy{\@dtl@start.5}{\dtl@variable}}% + \else +% \end{macrocode} +% Horizontal bars +% \begin{macrocode} + \expandafter\DTLifnumlt\expandafter{\DTLbarvariable}{0}% + { + \edef\dtl@textopt{right, + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{\dtl@variable}{\@dtl@start.5}} + {\noexpand\pgfpoint{-\noexpand\DTLbarlabeloffset}{0pt}}} + }% + }{% + \edef\dtl@textopt{left, + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{\dtl@variable}{\@dtl@start.5}} + {\noexpand\pgfpoint{\noexpand\DTLbarlabeloffset}{0pt}}} + }% + } +% \end{macrocode} +% Set \cs{DTLendpt} to the end point. +% \begin{macrocode} + \edef\DTLendpt{\noexpand\pgfpointxy{\dtl@variable}{\@dtl@start.5}}% + \fi + \expandafter\pgftext\expandafter[\dtl@textopt]{% + \DTLdisplayupperbarlabel{\dtl@upperbarlabel}} +% \end{macrocode} +% Set the mid point +% \begin{macrocode} + \def\DTLmidpt{\pgfpointlineattime{0.5}{\DTLstartpt}{\DTLendpt}}% +% \end{macrocode} +% Do every bar hook +%\changes{2.0}{2009 February 27}{added \cs{DTLeverybarhook}}% +% \begin{macrocode} + \DTLeverybarhook +% \end{macrocode} +% End of loop +% \begin{macrocode} + \edef\@dtl@start{\number\@dtl@bar}% + }% +% \end{macrocode} +% Draw $x$ axis +% \begin{macrocode} + \ifDTLbarxaxis + \ifDTLverticalbars + \expandafter\draw\expandafter[\DTLBarXAxisStyle] + (0,0) -- (\DTLbarchartwidth,0); + \else + \expandafter\draw\expandafter[\DTLBarXAxisStyle] + (0,0) -- (0,\DTLbarchartwidth); + \fi + \fi +% \end{macrocode} +% Draw $y$ axis +% \begin{macrocode} + \ifDTLbaryaxis + \ifDTLverticalbars + \expandafter\draw\expandafter[\DTLBarYAxisStyle] + (0,\DTLnegextent) -- (0,\DTLbarmax); + \else + \expandafter\draw\expandafter[\DTLBarYAxisStyle] + (\DTLnegextent,0) -- (\DTLbarmax,0); + \fi + \fi +% \end{macrocode} +% Plot $y$ tick marks if required +% \begin{macrocode} + \ifx\dtlbar@yticlist\relax + \else + \@for\dtl@thistick:=\dtlbar@yticlist\do{% + \ifDTLverticalbars + \pgfpathmoveto{\pgfpointxy{0}{\dtl@thistick}} + \pgfpathlineto{ + \pgfpointadd{\pgfpointxy{0}{\dtl@thistick}} + {\pgfpoint{-\DTLticklength}{0pt}}} + \else + \pgfpathmoveto{\pgfpointxy{\dtl@thistick}{0}} + \pgfpathlineto{ + \pgfpointadd{\pgfpointxy{\dtl@thistick}{0}} + {\pgfpoint{0pt}{-\DTLticklength}}} + \fi + \pgfusepath{stroke} + \ifx\dtlbar@yticlabels\relax + \dtlround{\dtl@thislabel}{\dtl@thistick} + {\c@DTLbarroundvar}% + \else + \dtl@chopfirst\dtlbar@yticlabels\dtl@thislabel\dtl@rest + \let\dtlbar@yticlabels=\dtl@rest + \fi + \ifDTLverticalbars + \edef\dtl@textopt{\DTLbarYticklabelalign,% + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{0}{\dtl@thistick}} + {\noexpand\pgfpoint{-\noexpand\DTLticklabeloffset}{0pt}}, + }}% + \else + \edef\dtl@textopt{\DTLbarYticklabelalign, + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{\dtl@thistick}{0}} + {\noexpand\pgfpoint{0pt}{-\noexpand\DTLticklabeloffset}} + }}% + \fi + \expandafter\pgftext\expandafter[\dtl@textopt]{% + \DTLbardisplayYticklabel{\dtl@thislabel}} + }% + \fi +% \end{macrocode} +% Plot the $y$ label if required +% \begin{macrocode} + \ifx\dtlbar@ylabel\relax + \else + \addtolength{\dtl@yticlabelwidth}{\baselineskip}% + \setlength{\dtl@tmplength}{0.5\DTLbarchartlength} + \ifDTLverticalbars + \pgftext[bottom,center,at={\pgfpointadd + {\pgfpointxy{0}{\DTLnegextent}}% + {\pgfpoint{-\dtl@yticlabelwidth}{\dtl@tmplength}}}, + rotate=90]{% + \dtlbar@ylabel} + \else + \pgftext[bottom,center,at={\pgfpointadd + {\pgfpointxy{\DTLnegextent}{0}}% + {\pgfpoint{\dtl@tmplength}{-\dtl@yticlabelwidth}}}]{% + \dtlbar@ylabel} + \fi + \fi +% \end{macrocode} +% Finish bar chart +% \begin{macrocode} + \DTLbaratendtikz + \end{tikzpicture} + }% +}% +} % \end{macrocode} %\end{macro} % -%\begin{macro}{\dtlshowtype} +%\begin{macro}{\DTLmultibarchart} %\begin{definition} -%\cs{dtlshowtype}\marg{db name}\marg{key} +% \cs{DTLmultibarchart}\oarg{conditions}\marg{option list}\marg{db name}\marg{assign list} %\end{definition} -% Show the data type for given key in the named database. -% This should be an integer from 0 to 3. -%\changes{2.0}{2009 February 27}{updated to use new database structure} +% Make a multi-bar chart from data given in data base \meta{db name}, +% where \meta{assign list} is a comma-separated list of +% \meta{cmd}\texttt{=}\meta{key} pairs. \meta{option list} must +% include the \texttt{variables} key which must be a comma separated +% list of commands, where each command +% is included in \meta{assign list}. The optional argument +% \meta{conditions} is the same as that for \cs{DTLforeach}. % \begin{macrocode} -\newcommand*{\dtlshowtype}[2]{% - \DTLgetdatatype{\@dtl@type}{#1}{#2}\show\@dtl@type +\newcommand*{\DTLmultibarchart}[4][\boolean{true}]{% +{\let\dtlbar@variables=\relax +\let\DTLbarmax=\relax +\let\DTLnegextent=\relax +\disable@keys{databar}{variable,upperbarlabel}% +\setkeys{databar}{#2}% +\ifx\dtlbar@variables\relax + \PackageError{databar}{\string\DTLmultibarchart\space missing variables setting}{}% +\else +% \end{macrocode} +% Compute the maximum bar height, unless \cs{DTLbarmax} has been +% set. +%\changes{1.01}{2007 Aug 17}{uses \cs{@sDTLforeach} instead of +%\cs{DTLforeach}} +% \begin{macrocode} + \ifx\DTLbarmax\relax + \@sDTLforeach[#1]{#3}{#4}{% + \@for\DTLbarvariable:=\dtlbar@variables\do{% + \expandafter\DTLconverttodecimal\expandafter + {\DTLbarvariable}{\dtl@barvar}% + \ifx\DTLbarmax\relax + \let\DTLbarmax=\dtl@barvar + \else + \let\dtl@old=\DTLbarmax + \dtlmax{\DTLbarmax}{\dtl@old}{\dtl@barvar}% + \fi + }% + }% + \ifx\dtlbar@yticgap\relax + \else + \let\dtl@thistick=\dtlbar@yticgap% + \whiledo{\DTLisFPopenbetween{\dtl@thistick}{0}{\DTLbarmax}}{% + \dtladd{\dtl@thistick}{\dtl@thistick}{\dtlbar@yticgap}% + }% + \let\DTLbarmax=\dtl@thistick + \fi + \fi +% \end{macrocode} +% Compute the bar depth, unless \cs{DTLnegextent} has been +% set. +% \begin{macrocode} + \ifx\DTLnegextent\relax + \def\DTLnegextent{0}% + \@sDTLforeach[#1]{#3}{#4}{% + \@for\DTLbarvariable:=\dtlbar@variables\do{% + \expandafter\DTLconverttodecimal\expandafter + {\DTLbarvariable}{\dtl@barvar}% + \let\dtl@old=\DTLnegextent + \DTLmin{\DTLnegextent}{\dtl@old}{\dtl@barvar}% + }% + }% + \ifx\dtlbar@yticgap\relax + \else + \ifthenelse{\DTLisFPlt{\DTLnegextent}{0}}{% + \edef\dtl@thistick{0}% + \whiledo{\DTLisFPclosedbetween{\dtl@thistick}{\DTLnegextent}{0}}{% + \dtlsub{\dtl@thistick}{\dtl@thistick}{\dtlbar@yticgap}% + }% + \let\DTLnegextent=\dtl@thistick + }{}% + \fi + \fi +% \end{macrocode} +% Determine scaling factor +% \begin{macrocode} + \@dtl@tmpcount=\DTLbarchartlength + \dtlsub{\dtl@extent}{\DTLbarmax}{\DTLnegextent}% + \dtldiv{\dtl@unit}{\number\@dtl@tmpcount}{\dtl@extent}% +% \end{macrocode} +% Construct $y$ tick list if required +% \begin{macrocode} + \setlength{\dtl@yticlabelwidth}{0pt}% + \ifDTLbarytics + \ifx\dtlbar@yticlist\relax + \ifx\dtlbar@yticgap\relax + \dtl@constructticklist\DTLnegextent\DTLbarmax + \dtl@unit\dtlbar@yticlist + \else + \dtl@constructticklistwithgapz + \DTLnegextent\DTLbarmax\dtlbar@yticlist\dtlbar@yticgap + \fi + \fi + \ifx\dtlbar@ylabel\relax + \else + \ifx\dtlbar@yticlabels\relax + \@for\dtl@thislabel:=\dtlbar@yticlist\do{% + \dtlround{\dtl@thislabel}{\dtl@thislabel} + {\c@DTLbarroundvar}% + \ifDTLverticalbars + \settowidth{\dtl@tmplength}{% + \DTLbardisplayYticklabel{\dtl@thislabel}}% + \else + \settoheight{\dtl@tmplength}{% + \DTLbardisplayYticklabel{\dtl@thislabel}}% + \edef\@dtl@h{\the\dtl@tmplength}% + \settodepth{\dtl@tmplength}{% + \DTLbardisplayYticklabel{\dtl@thislabel}}% + \addtolength{\dtl@tmplength}{\@dtl@h}% + \addtolength{\dtl@tmplength}{\baselineskip}% + \fi + \ifdim\dtl@tmplength>\dtl@yticlabelwidth + \setlength{\dtl@yticlabelwidth}{\dtl@tmplength}% + \fi + }% + \else + \@for\dtl@thislabel:=\dtlbar@yticlabels\do{% + \ifDTLverticalbars + \settowidth{\dtl@tmplength}{% + \DTLbardisplayYticklabel{\dtl@thislabel}}% + \else + \settoheight{\dtl@tmplength}{% + \DTLbardisplayYticklabel{\dtl@thislabel}}% + \edef\@dtl@h{\the\dtl@tmplength}% + \settodepth{\dtl@tmplength}{% + \DTLbardisplayYticklabel{\dtl@thislabel}}% + \addtolength{\dtl@tmplength}{\@dtl@h}% + \addtolength{\dtl@tmplength}{\baselineskip}% + \fi + \ifdim\dtl@tmplength>\dtl@yticlabelwidth + \setlength{\dtl@yticlabelwidth}{\dtl@tmplength}% + \fi + }% + \fi + \fi + \fi +% \end{macrocode} +% Calculate the offset for the lower label and number of labels +% \begin{macrocode} +\dtl@xticlabelheight=0pt\relax +\@dtl@tmpcount=0\relax +\@for\dtl@thislabel:=\dtl@multibarlabels\do{% + \advance\@dtl@tmpcount by 1\relax + \settoheight{\dtl@tmplength}{\tikz\expandafter\pgftext\expandafter + [\DTLbarXlabelalign]{\DTLdisplaylowerbarlabel{\dtl@thislabel}};}% + \edef\@dtl@h{\the\dtl@tmplength}% + \settodepth{\dtl@tmplength}{\tikz\expandafter\pgftext\expandafter + [\DTLbarXlabelalign]{\DTLdisplaylowerbarlabel{\dtl@thislabel}};}% + \addtolength{\dtl@tmplength}{\@dtl@h}% + \addtolength{\dtl@tmplength}{\baselineskip}% + \ifdim\dtl@tmplength>\dtl@xticlabelheight + \setlength{\dtl@xticlabelheight}{\dtl@tmplength}% + \fi +} +% \end{macrocode} +% Calculate number of bars per group +% \begin{macrocode} +\@dtl@tmpcount=0\relax +\@for\dtl@this:=\dtlbar@variables\do{% + \advance\@dtl@tmpcount by 1\relax +}% +\edef\DTLbargroupwidth{\number\@dtl@tmpcount}% +% \end{macrocode} +% Compute the total width of the bar chart (in terms of +% the $x$ unit vector.) +% \begin{macrocode} +\edef\dtl@n{\expandafter\number\csname dtlrows@#3\endcsname} +\dtlmul{\dtl@tmpi}{\dtl@n}{\DTLbargroupwidth} +\dtlsub{\dtl@tmpii}{\dtl@n}{1}% +\dtlmul{\dtl@tmpii}{\dtl@tmpii}{\dtlbar@groupgap}% +\dtladd{\DTLbarchartwidth}{\dtl@tmpi}{\dtl@tmpii} +% \end{macrocode} +% Do the bar chart +% \begin{macrocode} +\begin{tikzpicture} +% \end{macrocode} +% Set unit vectors +% \begin{macrocode} +\ifDTLverticalbars + \pgfsetyvec{\pgfpoint{0pt}{\dtl@unit sp}}% + \pgfsetxvec{\pgfpoint{\DTLbarwidth}{0pt}}% +\else + \pgfsetxvec{\pgfpoint{\dtl@unit sp}{0pt}}% + \pgfsetyvec{\pgfpoint{0pt}{\DTLbarwidth}}% +\fi +% \end{macrocode} +% Begin hook +% \begin{macrocode} +\DTLbaratbegintikz +% \end{macrocode} +% Initialise +% \begin{macrocode} +\def\@dtl@start{0}% +% \end{macrocode} +% Iterate through data +% \begin{macrocode} +\@sDTLforeach[#1]{#3}{#4}{% +% \end{macrocode} +% Store the bar number in \cs{@dtl@bar} +% \begin{macrocode} +\@dtl@barcount = 1\relax +% \end{macrocode} +% Set the multibar label lists +% \begin{macrocode} +\let\dtl@multibar@labels=\dtl@multibarlabels +\let\dtl@uppermultibar@labels=\dtl@uppermultibarlabels +% \end{macrocode} +% Compute mid point over group +% \begin{macrocode} +\dtlmul{\dtl@multimidpt}{\DTLbargroupwidth}{0.5}% +\dtladd{\dtl@multimidpt}{\dtl@multimidpt}{\@dtl@start}% +% \end{macrocode} +% Iterate through each variable +% \begin{macrocode} +\@for\DTLbarvariable:=\dtlbar@variables\do{% +% \end{macrocode} +% Set end point +% \begin{macrocode} +\dtladd{\@dtl@endpt}{\@dtl@start}{1}% +% \end{macrocode} +% Convert variable to decimal +% \begin{macrocode} +\expandafter\DTLconverttodecimal\expandafter + {\DTLbarvariable}{\dtl@variable}% +% \end{macrocode} +% Get the current lower label: +% \begin{macrocode} +\dtl@chopfirst\dtl@multibar@labels\dtl@thisbarlabel\dtl@rest +\let\dtl@multibar@labels=\dtl@rest +% \end{macrocode} +% Get the current upper label: +% \begin{macrocode} +\dtl@chopfirst\dtl@uppermultibar@labels\dtl@thisupperbarlabel\dtl@rest +\let\dtl@uppermultibar@labels=\dtl@rest +% \end{macrocode} +% Draw bars +% \begin{macrocode} +\begin{scope} + \expandafter\color\expandafter{\DTLgetbarcolor{\@dtl@barcount}}% + \ifDTLverticalbars + \fill (\@dtl@start,0) -- (\@dtl@start,\dtl@variable) + -- (\@dtl@endpt,\dtl@variable) -- (\@dtl@endpt,0) -- cycle; + \else + \fill (0,\@dtl@start) -- (\dtl@variable,\@dtl@start) + -- (\dtl@variable,\@dtl@endpt) -- (0,\@dtl@endpt) -- cycle; + \fi +\end{scope} +% \end{macrocode} +% Draw outline +% \begin{macrocode} +\begin{scope} +\ifdim\DTLbaroutlinewidth>0pt + \expandafter\color\expandafter{\DTLbaroutlinecolor} + \ifDTLverticalbars + \draw (\@dtl@start,0) -- (\@dtl@start,\dtl@variable) + -- (\@dtl@endpt,\dtl@variable) -- (\@dtl@endpt,0) -- cycle; + \else + \draw (0,\@dtl@start) -- (\dtl@variable,\@dtl@start) + -- (\dtl@variable,\@dtl@endpt) -- (0,\@dtl@endpt) -- cycle; + \fi +\fi +\end{scope} +% \end{macrocode} +% Calculate mid point +% \begin{macrocode} +\dtladd{\@dtl@midpt}{\@dtl@start}{0.5}% +% \end{macrocode} +% Draw lower $x$ labels +% \begin{macrocode} +\ifDTLverticalbars + \edef\dtl@textopt{% + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{\@dtl@midpt}{0}} + {\noexpand\pgfpoint{0pt}{-\noexpand\DTLbarlabeloffset}}}, + \DTLbarXlabelalign + }% + \edef\DTLstartpt{\noexpand\pgfpointxy{\@dtl@midpt}{0}}% +\else + \edef\dtl@textopt{% + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{0}{\@dtl@midpt}} + {\noexpand\pgfpoint{-\noexpand\DTLbarlabeloffset}{0pt}}}, + \DTLbarXlabelalign + }% + \edef\DTLstartpt{\noexpand\pgfpointxy{0}{\@dtl@midpt}}% +\fi + \expandafter\pgftext\expandafter[\dtl@textopt]{% + \DTLdisplaylowermultibarlabel{\dtl@thisbarlabel}} +% \end{macrocode} +% Draw upper $x$ labels +% \begin{macrocode} +\ifDTLverticalbars + \expandafter\DTLifnumlt\expandafter{\DTLbarvariable}{0} + { + \edef\dtl@textopt{% + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{\@dtl@midpt}{\dtl@variable}} + {\noexpand\pgfpoint{0pt}{-\noexpand\DTLbarlabeloffset}}} + }% + }{% + \edef\dtl@textopt{% + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{\@dtl@midpt}{\dtl@variable}} + {\noexpand\pgfpoint{0pt}{\noexpand\DTLbarlabeloffset}}} + }% + } + \edef\DTLendpt{\noexpand\pgfpointxy{\@dtl@midpt}{\dtl@variable}}% +\else + \expandafter\DTLifnumlt\expandafter{\DTLbarvariable}{0} + { + \edef\dtl@textopt{right, + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{\dtl@variable}{\@dtl@midpt}} + {\noexpand\pgfpoint{-\noexpand\DTLbarlabeloffset}{0pt}}} + }% + }{% + \edef\dtl@textopt{left, + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{\dtl@variable}{\@dtl@midpt}} + {\noexpand\pgfpoint{\noexpand\DTLbarlabeloffset}{0pt}}} + }% + } + \edef\DTLendpt{\noexpand\pgfpointxy{\dtl@variable}{\@dtl@midpt}}% +\fi + \expandafter\pgftext\expandafter[\dtl@textopt]{% + \DTLdisplayuppermultibarlabel{\dtl@thisupperbarlabel}} +% \end{macrocode} +% Set the mid point +% \begin{macrocode} +\def\DTLmidpt{\pgfpointlineattime{0.5}{\DTLstartpt}{\DTLendpt}}% +% \end{macrocode} +% Do every bar hook +%\changes{2.0}{2009 February 27}{added \cs{DTLeverybarhook}}% +% \begin{macrocode} +\DTLeverybarhook +% \end{macrocode} +% End of loop increment loop variables +% \begin{macrocode} + \dtladd{\@dtl@start}{\@dtl@start}{1}% + \advance\@dtl@barcount by 1\relax +}% +% Draw lower group $x$ labels +% \begin{macrocode} +\setlength{\dtl@tmplength}{\DTLbarlabeloffset}% +\addtolength{\dtl@tmplength}{\dtl@xticlabelheight}% +\ifDTLverticalbars + \edef\dtl@textopt{% + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{\dtl@multimidpt}{0}} + {\noexpand\pgfpoint{0pt}{-\noexpand\dtl@tmplength}}}, + \DTLbarXlabelalign + }% +\else + \edef\dtl@textopt{% + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{0}{\dtl@multimidpt}} + {\noexpand\pgfpoint{-\noexpand\dtl@tmplength}{0pt}}}, + \DTLbarXlabelalign + }% +\fi + \expandafter\pgftext\expandafter[\dtl@textopt]{% + \DTLdisplaylowerbarlabel{\dtl@barlabel}} +% \end{macrocode} +% Increment starting position by \cs{dtlbar@groupgap} +% \begin{macrocode} + \dtladd{\@dtl@start}{\@dtl@start}{\dtlbar@groupgap}% } % \end{macrocode} +% Draw $x$ axis +% \begin{macrocode} +\ifDTLbarxaxis + \ifDTLverticalbars + \expandafter\draw\expandafter[\DTLBarXAxisStyle] + (0,0) -- (\DTLbarchartwidth,0); + \else + \expandafter\draw\expandafter[\DTLBarXAxisStyle] + (0,0) -- (0,\DTLbarchartwidth); + \fi +\fi +% \end{macrocode} +% Draw $y$ axis +% \begin{macrocode} +\ifDTLbaryaxis + \ifDTLverticalbars + \expandafter\draw\expandafter[\DTLBarYAxisStyle] + (0,\DTLnegextent) -- (0,\DTLbarmax); + \else + \expandafter\draw\expandafter[\DTLBarYAxisStyle] + (\DTLnegextent,0) -- (\DTLbarmax,0); + \fi +\fi +% \end{macrocode} +% Plot $y$ tick marks if required +% \begin{macrocode} +\ifx\dtlbar@yticlist\relax +\else + \@for\dtl@thistick:=\dtlbar@yticlist\do{% + \ifDTLverticalbars + \pgfpathmoveto{\pgfpointxy{0}{\dtl@thistick}} + \pgfpathlineto{ + \pgfpointadd{\pgfpointxy{0}{\dtl@thistick}} + {\pgfpoint{-\DTLticklength}{0pt}}} + \else + \pgfpathmoveto{\pgfpointxy{\dtl@thistick}{0}} + \pgfpathlineto{ + \pgfpointadd{\pgfpointxy{\dtl@thistick}{0}} + {\pgfpoint{0pt}{-\DTLticklength}}} + \fi + \pgfusepath{stroke} + \ifx\dtlbar@yticlabels\relax + \dtlround{\dtl@thislabel}{\dtl@thistick} + {\c@DTLbarroundvar}% + \else + \dtl@chopfirst\dtlbar@yticlabels\dtl@thislabel\dtl@rest + \let\dtlbar@yticlabels=\dtl@rest + \fi + \ifDTLverticalbars + \edef\dtl@textopt{\DTLbarYticklabelalign,% + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{0}{\dtl@thistick}} + {\noexpand\pgfpoint{-\noexpand\DTLticklabeloffset}{0pt}}, + }}% + \else + \edef\dtl@textopt{\DTLbarYticklabelalign, + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{\dtl@thistick}{0}} + {\noexpand\pgfpoint{0pt}{-\noexpand\DTLticklabeloffset}} + }}% + \fi + \expandafter\pgftext\expandafter[\dtl@textopt]{% + \DTLbardisplayYticklabel{\dtl@thislabel}} + }% +\fi +% \end{macrocode} +% Plot the $y$ label if required +% \begin{macrocode} +\ifx\dtlbar@ylabel\relax +\else + \addtolength{\dtl@yticlabelwidth}{\baselineskip}% + \setlength{\dtl@tmplength}{0.5\DTLbarchartlength} + \ifDTLverticalbars + \pgftext[bottom,center,at={\pgfpointadd + {\pgfpointxy{0}{\DTLnegextent}}% + {\pgfpoint{-\dtl@yticlabelwidth}{\dtl@tmplength}}}, + rotate=90]{% + \dtlbar@ylabel} + \else + \pgftext[bottom,center,at={\pgfpointadd + {\pgfpointxy{\DTLnegextent}{0}}% + {\pgfpoint{\dtl@tmplength}{-\dtl@yticlabelwidth}}}]{% + \dtlbar@ylabel} + \fi +\fi +% \end{macrocode} +% Finish bar chart +% \begin{macrocode} +\DTLbaratendtikz +\end{tikzpicture} +\fi +}} +% \end{macrocode} %\end{macro} %\iffalse % \begin{macrocode} -%</datatool.sty> +%</databar.sty> % \end{macrocode} %\fi %\iffalse @@ -17960,11 +15538,11 @@ options>#2=\textsf{#2}|hyperpage}} %<*datapie.sty> % \end{macrocode} %\fi -%\section{datapie.sty} +%\chapter{datapie.sty} % Declare package: % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{datapie}[2009/10/22 v2.01 (NLCT)] +\ProvidesPackage{datapie}[2012/07/18 v2.10 (NLCT)] % \end{macrocode} % Require \sty{xkeyval} package % \begin{macrocode} @@ -18638,11 +16216,11 @@ Try #2-#1 instead of #1-#2}% %<*dataplot.sty> % \end{macrocode} %\fi -%\section{dataplot.sty} +%\chapter{dataplot.sty} % Declare package: % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{dataplot}[2009/10/22 v2.01 (NLCT)] +\ProvidesPackage{dataplot}[2012/07/18 v2.10 (NLCT)] % \end{macrocode} % Required packages % \begin{macrocode} @@ -20063,3996 +17641,1126 @@ east,southeast,south,southwest,west,northwest}[northeast]{% %\fi %\iffalse % \begin{macrocode} -%<*databar.sty> +%<*person.sty> % \end{macrocode} %\fi -%\section{databar.sty} -% Declare package: +%\chapter{person.sty}\label{sec:code:person} +%\section{Package Declaration} +% Package identification: % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{databar}[2009/10/22 v2.01 (NLCT)] +\ProvidesPackage{person}[2012/07/18 v2.10 (NLCT)] % \end{macrocode} -% Require \sty{xkeyval} package -% \begin{macrocode} -\RequirePackage{xkeyval} -% \end{macrocode} -% Require \sty{dataplot} package -% \begin{macrocode} -\RequirePackage{dataplot} -% \end{macrocode} -%\begin{macro}{\ifDTLcolorbarchart} -% The conditional \cs{ifDTLcolorbarchart} is used to determine -% whether to use colour or grey scale. -% \begin{macrocode} -\newif\ifDTLcolorbarchart -\DTLcolorbarcharttrue -% \end{macrocode} -%\end{macro} -% Package options to change the conditional: +% Requires the \sty{ifthen} package. % \begin{macrocode} -\DeclareOption{color}{\DTLcolorbarcharttrue} -\DeclareOption{gray}{\DTLcolorbarchartfalse} +\RequirePackage{ifthen} +\RequirePackage{datatool} % \end{macrocode} -%\cs{DTLbarXlabelalign} specifies the alignment -% for the $x$ axis labels. +%\section{Defining People} +%\begin{counter}{people} +% Keep count of the number of people who have been defined: % \begin{macrocode} -\newcommand*{\DTLbarXlabelalign}{left,rotate=-90} +\newcounter{people} % \end{macrocode} -%\cs{DTLbarYticklabelalign} specifies the alignment -% for the $x$ axis labels. +%\end{counter} +%\begin{counter}{person} +% Temporary counter % \begin{macrocode} -\newcommand*{\DTLbarYticklabelalign}{right} +\newcounter{person} % \end{macrocode} -%\begin{macro}{\ifDTLverticalbars} -% Define boolean keys to govern bar chart orientation. +%\end{counter} +%\begin{macro}{\@people@list} +% Keep a list of labels for each person who has been defined: % \begin{macrocode} -\define@boolkey{databar}[DTL]{verticalbars}[true]{% -\ifDTLverticalbars - \def\DTLbarXlabelalign{left,rotate=-90}% - \def\DTLbarYticklabelalign{right} -\else - \def\DTLbarXlabelalign{right}% - \def\DTLbarYticklabelalign{center} -\fi} +\newcommand*{\@people@list}{,} % \end{macrocode} %\end{macro} -% Set defaults: -% \begin{macrocode} -\DTLverticalbarstrue -% \end{macrocode} -% Package options to change \cs{ifDTLverticalbars} +%\begin{macro}{\@get@firstperson} +% Get the first person's name in \cs{@people@list}, and store in +% the argument (which must be a control sequence.) % \begin{macrocode} -\DeclareOption{vertical}{\DTLverticalbarstrue - \def\DTLbarXlabelalign{left,rotate=-90}% - \def\DTLbarYticklabelalign{right} -} -\DeclareOption{horizontal}{\DTLverticalbarsfalse - \def\DTLbarXlabelalign{right}% - \def\DTLbarYticklabelalign{center} +\newcommand*{\@get@firstperson}[1]{% + \expandafter\@@get@firstperson\@people@list,\@nil{#1}} + \def\@@get@firstperson,#1,#2\@nil#3{% + \def#3{#1}% } % \end{macrocode} -% Process options: -% \begin{macrocode} -\ProcessOptions -% \end{macrocode} -% Required packages: -% \begin{macrocode} -\RequirePackage{datatool} -\RequirePackage{tikz} -% \end{macrocode} -% Define some variables that govern the appearance of the bar -% chart. -% -%\begin{macro}{\DTLbarchartlength} -% The total height of the bar chart is given by \cs{DTLbarchartheight} -% \begin{macrocode} -\newlength\DTLbarchartlength -\DTLbarchartlength=3in -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLbarwidth} -% The width of each bar is given by \cs{DTLbarwidth}. -% \begin{macrocode} -\newlength\DTLbarwidth -\DTLbarwidth=1cm -% \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLbarlabeloffset} -% The offset from the $x$ axis to the bar label if given by -% \cs{DTLbarlabeloffset}. +%\begin{macro}{\malelabels} +% List of labels that can be used to indicate that a person is +% male (when defining a person using \cs{newperson}). % \begin{macrocode} -\newlength\DTLbarlabeloffset -\setlength\DTLbarlabeloffset{10pt} +\newcommand*{\malelabels}{male,Male,MALE,M,m} % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLBarXAxisStyle} -% The style of the $x$ axis is given by \cs{DTLBarXAxisStyle} +%\begin{macro}{\addmalelabel} +% Adds a label to the list of male labels. % \begin{macrocode} -\newcommand*{\DTLBarXAxisStyle}{-} +\newcommand*{\addmalelabel}[1]{% + \expandafter\@dtl@toksA\expandafter{\malelabels}% + \expandafter\@dtl@toksB\expandafter{#1}% + \edef\malelabels{\the\@dtl@toksA,\the\@dtl@toksB}% +} % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLBarYAxisStyle} -% The style of the $y$ axis is given by \cs{DTLBarYAxisStyle}. +%\begin{macro}{\addfemalelabel} +% Adds a label to the list of female labels. % \begin{macrocode} -\newcommand*{\DTLBarYAxisStyle}{-} +\newcommand*{\addfemalelabel}[1]{% + \expandafter\@dtl@toksA\expandafter{\femalelabels}% + \expandafter\@dtl@toksB\expandafter{#1}% + \edef\femalelabels{\the\@dtl@toksA,\the\@dtl@toksB}% +} % \end{macrocode} %\end{macro} % -%\begin{counter}{DTLbarroundvar} -% \ctrfmt{DTLbarroundvar} is a counter governing the number of digits -% to round to when using \cs{FPround}. -% \begin{macrocode} -\newcounter{DTLbarroundvar} -\setcounter{DTLbarroundvar}{1} -% \end{macrocode} -%\end{counter} -% -%\begin{macro}{\DTLbardisplayYticklabel} -%\cs{DTLbardisplayYticklabel} governs how the $y$ tick labels appear. -% \begin{macrocode} -\newcommand*{\DTLbardisplayYticklabel}[1]{#1} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\DTLdisplaylowerbarlabel} -%\cs{DTLdisplaylowerbarlabel} governs how the lower bar labels appear. -% \begin{macrocode} -\newcommand*{\DTLdisplaylowerbarlabel}[1]{#1} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\DTLdisplaylowermultibarlabel} -%\cs{DTLdisplaylowermultibarlabel} governs how the lower multi bar labels appear. -% \begin{macrocode} -\newcommand*{\DTLdisplaylowermultibarlabel}[1]{#1} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\DTLdisplayupperbarlabel} -%\cs{DTLdisplayupperbarlabel} governs how the upper bar labels -% appear. -% \begin{macrocode} -\newcommand*{\DTLdisplayupperbarlabel}[1]{#1} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\DTLdisplayuppermultibarlabel} -%\cs{DTLdisplayuppermultibarlabel} governs how the upper multi bar -% labels appear. +%\begin{macro}{\femalelabels} +% List of labels that can be used to indicate that a person is +% female (when defining a person using \cs{newperson}). % \begin{macrocode} -\newcommand*{\DTLdisplayuppermultibarlabel}[1]{#1} +\newcommand*{\femalelabels}{female,Female,FEMALE,F,f} % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLbaratbegintikz} -% \cs{DTLbaratbegintikz} specifies any commands -% to apply at the start of the \env{tikzpicture} environment. -% By default it does nothing. +%\begin{macro}{\ifmalelabel} +% Determines if first argument is contained in the list of male +% labels. (One level expansion is performed on the first object +% in first argument.) +% If true does second argument, otherwise does third argument. % \begin{macrocode} -\newcommand*{\DTLbaratbegintikz}{} +\newcommand{\ifmalelabel}[3]{% + \expandafter\DTLifinlist\expandafter{#1}{\malelabels}{#2}{#3}% +} % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLbaratendtikz} -% \cs{DTLbaratendtikz} specifies any commands -% to apply at the end of the \env{tikzpicture} environment. -% By default it does nothing. +%\begin{macro}{\iffemalelabel} +% Determines if first argument is contained in the list of female +% labels. (One level expansion is performed on the first object +% in first argument.) +% If true does second argument, otherwise does third argument. % \begin{macrocode} -\newcommand*{\DTLbaratendtikz}{} +\newcommand{\iffemalelabel}[3]{% + \expandafter\DTLifinlist\expandafter{#1}{\femalelabels}{#2}{#3}% +} % \end{macrocode} %\end{macro} % -%\begin{macro}{\ifDTLbarxaxis} -% The conditional \cs{ifDTLbarxaxis} is used to determine -% whether or not to display the $x$ axis -% \begin{macrocode} -\newif\ifDTLbarxaxis -% \end{macrocode} -%\end{macro} -%\begin{macro}{\ifDTLbaryaxis} -% The conditional \cs{ifDTLbaryaxis} is used to determine -% whether or not to display the $y$ axis. -% \begin{macrocode} -\newif\ifDTLbaryaxis -% \end{macrocode} -%\end{macro} -%\begin{macro}{\ifDTLbarytics} -% The conditional \cs{ifDTLbarytics} to determine whether -% or not to display the $y$ tick marks. +%\begin{macro}{\newperson} +% Define a new person. The optional argument specifies a label +% with which to refer to that person. If omitted, \texttt{anon} +% is used. If more than one person is defined, the optional +% argument will be required to specify a unique label. The +% compulsory arguments are the person's full name, their +% familiar name and their gender. % \begin{macrocode} -\newif\ifDTLbarytics +\newcommand*{\newperson}[4][anon]{% + \@ifundefined{person@#1@name}% + {% + \ifmalelabel{#4}% + {% + \expandafter\gdef\csname person@#1@gender\endcsname{male}% + }% + {% + \iffemalelabel{#4}% + {% + \expandafter\gdef\csname person@#1@gender\endcsname{female}% + }% + {% + \PackageError{person}{Unknown gender `#4' for person + `#1'}{Allowed gender labels are: \malelabels\space or + \femalelabels}% + \@namedef{person@#1@gender}{other}% + }% + }% + \expandafter + \protected@xdef\csname person@#1@fullname\endcsname{#2}% + \expandafter + \protected@xdef\csname person@#1@name\endcsname{#3}% + \protected@xdef\@people@list{\@people@list#1,}% + \stepcounter{people}% + }% + {% + \PackageError{person}{Person `#1' has already been defined}{}% + }% +} % \end{macrocode} %\end{macro} % -%\begin{macro}{\@dtl@barcount} -% The count register \cs{@dtl@barcount} is used to store -% the current bar index. -% \begin{macrocode} -\newcount\@dtl@barcount -% \end{macrocode} -%\end{macro} +%\section{Remove People} % -%\begin{macro}{\DTLsetbarcolor} -%\begin{definition} -% \cs{DTLsetbarcolor}\marg{n}\marg{color} -%\end{definition} -% Assigns colour name \meta{color} to the \meta{n}th bar. +%\begin{macro}{\removeperson} +% Removes person identified by their label from the list. % \begin{macrocode} -\newcommand*{\DTLsetbarcolor}[2]{% -\expandafter\def\csname dtlbar@segcol\romannumeral#1\endcsname{#2}% +\newcommand*{\removeperson}[1][anon]{% + \edef\@person@label{#1}% + \expandafter\@removeperson\expandafter{\@person@label}% } % \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLgetbarcolor} -%\begin{definition} -%\cs{DTLgetbarcolor}\marg{n} -%\end{definition} -% Gets the colour specification for the \meta{n}th bar. +% The label has to be full expanded for the internal command. % \begin{macrocode} -\newcommand*{\DTLgetbarcolor}[1]{% -\csname dtlbar@segcol\romannumeral#1\endcsname} +\newcommand*{\@removeperson}[1]{% + \ifpersonexists{#1}% + {% % \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLdobarcolor} -%\begin{definition} -%\cs{DTLdobarcolor}\marg{n} -%\end{definition} -% Sets the colour to that for the \meta{n}th bar. +% Remove label from list of people. % \begin{macrocode} -\newcommand*{\DTLdobarcolor}[1]{% -\expandafter\color\expandafter -{\csname dtlbar@segcol\romannumeral#1\endcsname}} + \def\@remove@person##1,#1,##2\@nil{% + \def\@prsn@pre{##1}\def\@prsn@post{##2}}% + \expandafter\@remove@person\@people@list\@nil + \xdef\@people@list{\@prsn@pre,\@prsn@post}% % \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLdocurrentbarcolor} -%\cs{DTLdocurrentbarcolor} -% sets the colour to that of the current bar. +% Decrement number of people: % \begin{macrocode} -\newcommand*{\DTLdocurrentbarcolor}{% -\ifnum\dtlforeachlevel=0\relax - \PackageError{databar}{Can't use - \string\DTLdocurrentbarcolor\space outside - \string\DTLbarchart}{}% -\else - \expandafter\DTLdobarcolor\expandafter{% - \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname}% -\fi} + \addtocounter{people}{-1}% % \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLbaroutlinecolor} -%\cs{DTLbaroutlinecolor} specifies what colour to draw the -% outline. +% Undefine associated control sequences: % \begin{macrocode} -\newcommand*{\DTLbaroutlinecolor}{black} + \expandafter\global\expandafter + \let\csname person@#1@name\endcsname\undefined + \expandafter\global\expandafter + \let\csname person@#1@fullname\endcsname\undefined + \expandafter\global\expandafter + \let\csname person@#1@gender\endcsname\undefined + }% + {% + \PackageError{person}{Can't remove person `#1': no such + person}{}% + }% +} % \end{macrocode} %\end{macro} -% -%\begin{macro}{\DTLbaroutlinewidth} -%\cs{DTLbaroutlinewidth} specifies the line width of the outline: -% Outline is only drawn if the linewidth is greater than 0pt. +%\begin{macro}{\removepeople} +% Removes the people listed. % \begin{macrocode} -\newlength\DTLbaroutlinewidth -\DTLbaroutlinewidth=0pt +\newcommand*{\removepeople}[1]{% + \@for\@thisperson:=#1\do{% + \ifx\@thisperson\@empty + \else + \expandafter\removeperson\expandafter[\@thisperson]% + \fi + }% +} % \end{macrocode} %\end{macro} -% -% Set the default colours. If there are more than eight bars, -% more colours will need to be defined. -% \begin{macrocode} -\ifDTLcolorbarchart - \DTLsetbarcolor{1}{red} - \DTLsetbarcolor{2}{green} - \DTLsetbarcolor{3}{blue} - \DTLsetbarcolor{4}{yellow} - \DTLsetbarcolor{5}{magenta} - \DTLsetbarcolor{6}{cyan} - \DTLsetbarcolor{7}{orange} - \DTLsetbarcolor{8}{white} -\else - \DTLsetbarcolor{1}{black!15} - \DTLsetbarcolor{2}{black!25} - \DTLsetbarcolor{3}{black!35} - \DTLsetbarcolor{4}{black!45} - \DTLsetbarcolor{5}{black!55} - \DTLsetbarcolor{6}{black!65} - \DTLsetbarcolor{7}{black!75} - \DTLsetbarcolor{8}{black!85} -\fi -% \end{macrocode} -%\begin{macro}{\DTLeverybarhook} -% Code to apply at every bar. The start point of the bar -% can be accessed via \cs{DTLstartpt}, the mid point of the bar -% can be accessed via \cs{DTLmidpt} and the end point of the -% bar can be accessed via \cs{DTLendpt} -%\changes{2.0}{2009 February 27}{new}% +%\begin{macro}{\removeallpeople} +% Removes everyone. % \begin{macrocode} -\newcommand*{\DTLeverybarhook}{} +\newcommand*{\removeallpeople}{% + \@for\@thisperson:=\@people@list\do{% + \expandafter\global\expandafter + \let\csname person@\@thisperson @name\endcsname\undefined + \expandafter\global\expandafter + \let\csname person@\@thisperson @fullname\endcsname\undefined + \expandafter\global\expandafter + \let\csname person@\@thisperson @gender\endcsname\undefined + }% + \setcounter{people}{0}% + \gdef\@people@list{,}% +} % \end{macrocode} %\end{macro} % -% Define keys for \cs{DTLbarchart} optional argument. -% Set the maximum value of the $y$ axis. -% \begin{macrocode} -\define@key{databar}{max}{\def\DTLbarmax{#1}} -% \end{macrocode} -% Set the total length of the bar chart +%\section{Conditionals and Loops} +%\begin{macro}{\ifpersonexists} +% If person whose label is given by the first argument exists, then +% do the second argument otherwise do third argument. % \begin{macrocode} -\define@key{databar}{length}{\DTLbarchartlength=#1\relax +\newcommand{\ifpersonexists}[3]{% + \@ifundefined{person@#1@name}{#3}{#2}% } % \end{macrocode} -% Set the maximum depth (negative extent) -% \begin{macrocode} -\define@key{databar}{maxdepth}{% -\ifnum#1>0\relax - \PackageError{databar}{depth must be zero or negative}{}% -\else - \def\DTLnegextent{#1}% -\fi} -% \end{macrocode} -% Determine which axes should be shown +%\end{macro} +% +%\begin{macro}{\ifmale} +% If the person given by the label in the first argument is male, +% do the second argument, otherwise do the third argument. % \begin{macrocode} -\define@choicekey{databar}{axes}[\var\nr]{both,x,y,none}{% -\ifcase\nr\relax - % both - \DTLbarxaxistrue - \DTLbaryaxistrue - \DTLbaryticstrue -\or - % x only - \DTLbarxaxistrue - \DTLbaryaxisfalse - \DTLbaryticsfalse -\or - % y only - \DTLbarxaxisfalse - \DTLbaryaxistrue - \DTLbaryticstrue -\or - % neither - \DTLbarxaxisfalse - \DTLbaryaxisfalse - \DTLbaryticsfalse -\fi +\newcommand{\ifmale}[3]{% + \ifpersonexists{#1}% + {% + \edef\@gender{\csname person@\@thisperson @gender\endcsname}% + \ifx\@gender\@male@label + #2% + \else + #3% + \fi + }% + {% + \PackageError{person}{Person `#1' doesn't exist.}{}% + }% } +\def\@male@label{male} % \end{macrocode} -% Variable used to create the bar chart. (Must be a control -% sequence.) -% \begin{macrocode} -\define@key{databar}{variable}{% -\def\DTLbarvariable{#1}} -% \end{macrocode} -% Variables used to create the multi bar chart. (Must be a -% comma separated list of control sequences.) -% \begin{macrocode} -\define@key{databar}{variables}{% -\def\dtlbar@variables{#1}} -% \end{macrocode} -% Bar width -% \begin{macrocode} -\define@key{databar}{barwidth}{\setlength{\DTLbarwidth}{#1}} -% \end{macrocode} -% Lower bar labels -% \begin{macrocode} -\define@key{databar}{barlabel}{% -\def\dtl@barlabel{#1}} -\def\dtl@barlabel{} -% \end{macrocode} -% Lower bar labels for multi-bar charts -% \begin{macrocode} -\define@key{databar}{multibarlabels}{% -\def\dtl@multibarlabels{#1}} -\def\dtl@multibarlabels{} -% \end{macrocode} -% Gap between groups in multi-bar charts (This should be in $x$ units -% where 1 $x$ unit is the width of a bar.) -% \begin{macrocode} -\define@key{databar}{groupgap}{\def\dtlbar@groupgap{#1}} -\def\dtlbar@groupgap{1} -% \end{macrocode} -% Upper bar labels -% \begin{macrocode} -\define@key{databar}{upperbarlabel}{% -\def\dtl@upperbarlabel{#1}} -\def\dtl@upperbarlabel{} -% \end{macrocode} -% Upper bar labels for multi-bar charts -% \begin{macrocode} -\define@key{databar}{uppermultibarlabels}{% -\def\dtl@uppermultibarlabels{#1}} -\def\dtl@uppermultibarlabels{} -% \end{macrocode} -% Define list of points for $y$ tics. (Must be a comma separated list -% of decimal numbers.) -% \begin{macrocode} -\define@key{databar}{yticpoints}{% -\def\dtlbar@yticlist{#1}\DTLbaryticstrue\DTLbaryaxistrue} -\let\dtlbar@yticlist=\relax -% \end{macrocode} -% Set the $y$ tick gap: -% \begin{macrocode} -\define@key{databar}{yticgap}{% -\def\dtlbar@yticgap{#1}\DTLbaryticstrue\DTLbaryaxistrue} -\let\dtlbar@yticgap=\relax -% \end{macrocode} -% Define list of labels for $y$ tics. -% \begin{macrocode} -\define@key{databar}{yticlabels}{% -\def\dtlbar@yticlabels{#1}\DTLbaryticstrue\DTLbaryaxistrue} -\let\dtlbar@yticlabels=\relax -% \end{macrocode} -% Define $y$ axis label. -% \begin{macrocode} -\define@key{databar}{ylabel}{% -\def\dtlbar@ylabel{#1}} -\let\dtlbar@ylabel=\relax -% \end{macrocode} +%\end{macro} % -%\begin{macro}{\DTLbarchart} -%\begin{definition} -% \cs{DTLbarchart}\oarg{conditions}\marg{option list}\marg{db name}\marg{assign list} -%\end{definition} -% Make a bar chart from data given in data base \meta{db name}, -% where \meta{assign list} is a comma-separated list of -% \meta{cmd}\texttt{=}\meta{key} pairs. \meta{option list} must -% include \texttt{variable}\texttt{=}\meta{cmd}, where \meta{cmd} -% is included in \meta{assign list}. The optional argument -% \meta{conditions} is the same as that for \cs{DTLforeach}. -% \begin{macrocode} -\newcommand*{\DTLbarchart}[4][\boolean{true}]{% -{\let\DTLbarvariable=\relax -\let\DTLbarmax=\relax -\let\DTLnegextent=\relax -\disable@keys{databar}{variables,multibarlabels,% -uppermultibarlabels,groupgap}% -\setkeys{databar}{#2}% -\ifx\DTLbarvariable\relax - \PackageError{databar}{\string\DTLbarchart\space missing - variable}{You haven't use the "variable" key}% -\else -% \end{macrocode} -% Compute the maximum bar height, unless \cs{DTLbarmax} has been -% set. -%\changes{1.01}{2007 Aug 17}{uses \cs{@sDTLforeach} instead of -%\cs{DTLforeach}} +%\begin{macro}{\ifallmale} +% If all people listed in first argument are male, do the second +% argument otherwise do the third argument. If the first argument +% is omitted, all defined people are checked. % \begin{macrocode} - \ifx\DTLbarmax\relax - \@sDTLforeach[#1]{#3}{#4}{% - \expandafter\DTLconverttodecimal\expandafter - {\DTLbarvariable}{\dtl@barvar}% - \ifx\DTLbarmax\relax - \let\DTLbarmax=\dtl@barvar +\newcommand{\ifallmale}[3][\@people@list]{% + \@for\@thisperson:=#1\do{% + \ifpersonexists{\@thisperson}% + {% + \edef\@gender{\csname person@\@thisperson @gender\endcsname}% + \ifx\@gender\@male@label \else - \let\dtl@old=\DTLbarmax - \FPmax{\DTLbarmax}{\dtl@old}{\dtl@barvar}% + \@endfortrue \fi }% - \ifx\dtlbar@yticgap\relax - \else - \let\dtl@thistick=\dtlbar@yticgap% - \whiledo{\DTLisFPopenbetween{\dtl@thistick}{0}{\DTLbarmax}}{% - \FPadd{\dtl@thistick}{\dtl@thistick}{\dtlbar@yticgap}% - }% - \let\DTLbarmax=\dtl@thistick - \fi - \fi -% \end{macrocode} -% Compute the bar depth, unless \cs{DTLnegextent} has been -% set. -% \begin{macrocode} - \ifx\DTLnegextent\relax - \def\DTLnegextent{0}% - \@sDTLforeach[#1]{#3}{#4}{% - \expandafter\DTLconverttodecimal\expandafter - {\DTLbarvariable}{\dtl@barvar}% - \let\dtl@old=\DTLnegextent - \DTLmin{\DTLnegextent}{\dtl@old}{\dtl@barvar}% + {% + \PackageError{person}{Person `#1' doesn't exist.}{}% }% - \ifx\dtlbar@yticgap\relax - \else - \ifthenelse{\DTLisFPlt{\DTLnegextent}{0}}{% - \edef\dtl@thistick{0}% - \whiledo{\DTLisFPclosedbetween{\dtl@thistick}{\DTLnegextent}{0}}{% - \FPsub{\dtl@thistick}{\dtl@thistick}{\dtlbar@yticgap}% - }% - \let\DTLnegextent=\dtl@thistick - }{}% - \fi - \fi -% \end{macrocode} -% Determine scaling factor -% \begin{macrocode} - \@dtl@tmpcount=\DTLbarchartlength - \FPsub{\dtl@extent}{\DTLbarmax}{\DTLnegextent}% - \FPdiv{\dtl@unit}{\number\@dtl@tmpcount}{\dtl@extent}% -% \end{macrocode} -% Construct $y$ tick list if required -% \begin{macrocode} - \setlength{\dtl@yticlabelwidth}{0pt}% - \ifDTLbarytics - \ifx\dtlbar@yticlist\relax - \ifx\dtlbar@yticgap\relax - \dtl@constructticklist\DTLnegextent\DTLbarmax - \dtl@unit\dtlbar@yticlist - \else - \dtl@constructticklistwithgapz - \DTLnegextent\DTLbarmax\dtlbar@yticlist\dtlbar@yticgap - \fi - \fi - \ifx\dtlbar@ylabel\relax - \else - \ifx\dtlbar@yticlabels\relax - \@for\dtl@thislabel:=\dtlbar@yticlist\do{% - \FPround{\dtl@thislabel}{\dtl@thislabel} - {\c@DTLbarroundvar}% - \ifDTLverticalbars - \settowidth{\dtl@tmplength}{% - \DTLbardisplayYticklabel{\dtl@thislabel}}% - \else - \settoheight{\dtl@tmplength}{% - \DTLbardisplayYticklabel{\dtl@thislabel}}% - \edef\@dtl@h{\the\dtl@tmplength}% - \settodepth{\dtl@tmplength}{% - \DTLbardisplayYticklabel{\dtl@thislabel}}% - \addtolength{\dtl@tmplength}{\@dtl@h}% - \addtolength{\dtl@tmplength}{\baselineskip}% - \fi - \ifdim\dtl@tmplength>\dtl@yticlabelwidth - \setlength{\dtl@yticlabelwidth}{\dtl@tmplength}% - \fi - }% - \else - \@for\dtl@thislabel:=\dtlbar@yticlabels\do{% - \ifDTLverticalbars - \settowidth{\dtl@tmplength}{% - \DTLbardisplayYticklabel{\dtl@thislabel}}% - \else - \settoheight{\dtl@tmplength}{% - \DTLbardisplayYticklabel{\dtl@thislabel}}% - \edef\@dtl@h{\the\dtl@tmplength}% - \settodepth{\dtl@tmplength}{% - \DTLbardisplayYticklabel{\dtl@thislabel}}% - \addtolength{\dtl@tmplength}{\@dtl@h}% - \addtolength{\dtl@tmplength}{\baselineskip}% - \fi - \ifdim\dtl@tmplength>\dtl@yticlabelwidth - \setlength{\dtl@yticlabelwidth}{\dtl@tmplength}% - \fi - }% - \fi - \fi - \fi -% \end{macrocode} -% Store the width of the bar chart in \cs{DTLbarchartwidth} -% \begin{macrocode} -\edef\DTLbarchartwidth{\expandafter\number\csname dtlrows@#3\endcsname} -% \end{macrocode} -% Do the bar chart -% \begin{macrocode} -\begin{tikzpicture} -% \end{macrocode} -% Set unit vectors -% \begin{macrocode} -\ifDTLverticalbars - \pgfsetyvec{\pgfpoint{0pt}{\dtl@unit sp}}% - \pgfsetxvec{\pgfpoint{\DTLbarwidth}{0pt}}% -\else - \pgfsetxvec{\pgfpoint{\dtl@unit sp}{0pt}}% - \pgfsetyvec{\pgfpoint{0pt}{\DTLbarwidth}}% -\fi -% \end{macrocode} -% Begin hook -% \begin{macrocode} -\DTLbaratbegintikz -% \end{macrocode} -% Initialise -% \begin{macrocode} -\def\@dtl@start{0}% -% \end{macrocode} -% Iterate through data -% \begin{macrocode} -\@sDTLforeach[#1]{#3}{#4}{% -% \end{macrocode} -% Store the bar number in \cs{@dtl@bar} -% \begin{macrocode} -\expandafter\let\expandafter\@dtl@bar - \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname% -% \end{macrocode} -% Convert variable to decimal -% \begin{macrocode} -\expandafter\DTLconverttodecimal\expandafter - {\DTLbarvariable}{\dtl@variable}% -% \end{macrocode} -% Draw bars -% \begin{macrocode} -\begin{scope} - \DTLdocurrentbarcolor - \ifDTLverticalbars - \fill (\@dtl@start,0) -- (\@dtl@start,\dtl@variable) - -- (\@dtl@bar,\dtl@variable) -- (\@dtl@bar,0) -- cycle; - \else - \fill (0,\@dtl@start) -- (\dtl@variable,\@dtl@start) - -- (\dtl@variable,\@dtl@bar) -- (0,\@dtl@bar) -- cycle; - \fi -\end{scope} -% \end{macrocode} -% Draw outline -% \begin{macrocode} -\begin{scope} -\ifdim\DTLbaroutlinewidth>0pt - \expandafter\color\expandafter{\DTLbaroutlinecolor} - \ifDTLverticalbars - \draw (\@dtl@start,0) -- (\@dtl@start,\dtl@variable) - -- (\@dtl@bar,\dtl@variable) -- (\@dtl@bar,0) -- cycle; - \else - \draw (0,\@dtl@start) -- (\dtl@variable,\@dtl@start) - -- (\dtl@variable,\@dtl@bar) -- (0,\@dtl@bar) -- cycle; - \fi -\fi -\end{scope} -% \end{macrocode} -% Draw lower $x$ labels -% \begin{macrocode} -\ifDTLverticalbars - \edef\dtl@textopt{% - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{\@dtl@start.5}{0}} - {\noexpand\pgfpoint{0pt}{-\noexpand\DTLbarlabeloffset}}}, - \DTLbarXlabelalign - }% -% \end{macrocode} -% Set \cs{DTLstartpt} to the starting point. -% \begin{macrocode} - \edef\DTLstartpt{\noexpand\pgfpointxy{\@dtl@start.5}{0}}% -\else - \edef\dtl@textopt{% - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{0}{\@dtl@start.5}} - {\noexpand\pgfpoint{-\noexpand\DTLbarlabeloffset}{0pt}}}, - \DTLbarXlabelalign }% -% \end{macrocode} -% Set \cs{DTLstartpt} to the starting point. -% \begin{macrocode} - \edef\DTLstartpt{\noexpand\pgfpointxy{0}{\@dtl@start.5}}% -\fi - \expandafter\pgftext\expandafter[\dtl@textopt]{% - \DTLdisplaylowerbarlabel{\dtl@barlabel}} -% \end{macrocode} -% Draw upper $x$ labels -% \begin{macrocode} -\ifDTLverticalbars -% \end{macrocode} -% Vertical bars -% \begin{macrocode} - \expandafter\DTLifnumlt\expandafter{\DTLbarvariable}{0} - { - \edef\dtl@textopt{% - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{\@dtl@start.5}{\dtl@variable}} - {\noexpand\pgfpoint{0pt}{-\noexpand\DTLbarlabeloffset}}} - }% - }{% - \edef\dtl@textopt{% - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{\@dtl@start.5}{\dtl@variable}} - {\noexpand\pgfpoint{0pt}{\noexpand\DTLbarlabeloffset}}} - }% - } -% \end{macrocode} -% Set \cs{DTLendpt} to the end point. -% \begin{macrocode} - \edef\DTLendpt{\noexpand\pgfpointxy{\@dtl@start.5}{\dtl@variable}}% -\else -% \end{macrocode} -% Horizontal bars -% \begin{macrocode} - \expandafter\DTLifnumlt\expandafter{\DTLbarvariable}{0} - { - \edef\dtl@textopt{right, - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{\dtl@variable}{\@dtl@start.5}} - {\noexpand\pgfpoint{-\noexpand\DTLbarlabeloffset}{0pt}}} - }% - }{% - \edef\dtl@textopt{left, - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{\dtl@variable}{\@dtl@start.5}} - {\noexpand\pgfpoint{\noexpand\DTLbarlabeloffset}{0pt}}} - }% - } -% \end{macrocode} -% Set \cs{DTLendpt} to the end point. -% \begin{macrocode} - \edef\DTLendpt{\noexpand\pgfpointxy{\dtl@variable}{\@dtl@start.5}}% -\fi - \expandafter\pgftext\expandafter[\dtl@textopt]{% - \DTLdisplayupperbarlabel{\dtl@upperbarlabel}} -% \end{macrocode} -% Set the mid point -% \begin{macrocode} -\def\DTLmidpt{\pgfpointlineattime{0.5}{\DTLstartpt}{\DTLendpt}}% -% \end{macrocode} -% Do every bar hook -%\changes{2.0}{2009 February 27}{added \cs{DTLeverybarhook}}% -% \begin{macrocode} - \DTLeverybarhook -% \end{macrocode} -% End of loop -% \begin{macrocode} - \edef\@dtl@start{\number\@dtl@bar}% -} -% \end{macrocode} -% Draw $x$ axis -% \begin{macrocode} -\ifDTLbarxaxis - \ifDTLverticalbars - \expandafter\draw\expandafter[\DTLBarXAxisStyle] - (0,0) -- (\DTLbarchartwidth,0); + \if@endfor + #3% \else - \expandafter\draw\expandafter[\DTLBarXAxisStyle] - (0,0) -- (0,\DTLbarchartwidth); + #2% \fi -\fi +} % \end{macrocode} -% Draw $y$ axis +%\end{macro} +% +%\begin{macro}{\iffemale} +% If the person given by the label in the first argument is female, +% do the second argument, otherwise do the third argument. % \begin{macrocode} -\ifDTLbaryaxis - \ifDTLverticalbars - \expandafter\draw\expandafter[\DTLBarYAxisStyle] - (0,\DTLnegextent) -- (0,\DTLbarmax); - \else - \expandafter\draw\expandafter[\DTLBarYAxisStyle] - (\DTLnegextent,0) -- (\DTLbarmax,0); - \fi -\fi +\newcommand{\iffemale}[3]{% + \ifpersonexists{#1}% + {% + \edef\@gender{\csname person@\@thisperson @gender\endcsname}% + \ifx\@gender\@female@label + #2% + \else + #3% + \fi + }% + {% + \PackageError{person}{Person `#1' doesn't exist.}{}% + }% +} +\def\@female@label{female} % \end{macrocode} -% Plot $y$ tick marks if required +%\end{macro} +% +%\begin{macro}{\ifallfemale} +% If all people listed in first argument are female, do the second +% argument otherwise do the third argument. % \begin{macrocode} -\ifx\dtlbar@yticlist\relax -\else - \@for\dtl@thistick:=\dtlbar@yticlist\do{% - \ifDTLverticalbars - \pgfpathmoveto{\pgfpointxy{0}{\dtl@thistick}} - \pgfpathlineto{ - \pgfpointadd{\pgfpointxy{0}{\dtl@thistick}} - {\pgfpoint{-\DTLticklength}{0pt}}} - \else - \pgfpathmoveto{\pgfpointxy{\dtl@thistick}{0}} - \pgfpathlineto{ - \pgfpointadd{\pgfpointxy{\dtl@thistick}{0}} - {\pgfpoint{0pt}{-\DTLticklength}}} - \fi - \pgfusepath{stroke} - \ifx\dtlbar@yticlabels\relax - \FPround{\dtl@thislabel}{\dtl@thistick} - {\c@DTLbarroundvar}% - \else - \dtl@chopfirst\dtlbar@yticlabels\dtl@thislabel\dtl@rest - \let\dtlbar@yticlabels=\dtl@rest - \fi - \ifDTLverticalbars - \edef\dtl@textopt{\DTLbarYticklabelalign,% - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{0}{\dtl@thistick}} - {\noexpand\pgfpoint{-\noexpand\DTLticklabeloffset}{0pt}}, - }}% +\newcommand{\ifallfemale}[3][\@people@list]{% + \@for\@thisperson:=#1\do{% + \edef\@gender{\csname person@\@thisperson @gender\endcsname}% + \ifx\@gender\@female@label \else - \edef\dtl@textopt{\DTLbarYticklabelalign, - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{\dtl@thistick}{0}} - {\noexpand\pgfpoint{0pt}{-\noexpand\DTLticklabeloffset}} - }}% + \@endfortrue \fi - \expandafter\pgftext\expandafter[\dtl@textopt]{% - \DTLbardisplayYticklabel{\dtl@thislabel}} }% -\fi -% \end{macrocode} -% Plot the $y$ label if required -% \begin{macrocode} -\ifx\dtlbar@ylabel\relax -\else - \addtolength{\dtl@yticlabelwidth}{\baselineskip}% - \setlength{\dtl@tmplength}{0.5\DTLbarchartlength} - \ifDTLverticalbars - \pgftext[bottom,center,at={\pgfpointadd - {\pgfpointxy{0}{\DTLnegextent}}% - {\pgfpoint{-\dtl@yticlabelwidth}{\dtl@tmplength}}}, - rotate=90]{% - \dtlbar@ylabel} + \if@endfor + #3% \else - \pgftext[bottom,center,at={\pgfpointadd - {\pgfpointxy{\DTLnegextent}{0}}% - {\pgfpoint{\dtl@tmplength}{-\dtl@yticlabelwidth}}}]{% - \dtlbar@ylabel} + #2% \fi -\fi -% \end{macrocode} -% Finish bar chart -% \begin{macrocode} -\DTLbaratendtikz -\end{tikzpicture} -\fi -}} +} % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLmultibarchart} +%\begin{macro}{\foreachperson} %\begin{definition} -% \cs{DTLmultibarchart}\oarg{conditions}\marg{option list}\marg{db name}\marg{assign list} +%\cs{foreachperson}(\meta{name cs},\meta{full name cs},\meta{gender cs},\meta{label cs})\cs{in}\marg{list}\cs{do}\marg{body} %\end{definition} -% Make a multi-bar chart from data given in data base \meta{db name}, -% where \meta{assign list} is a comma-separated list of -% \meta{cmd}\texttt{=}\meta{key} pairs. \meta{option list} must -% include the \texttt{variables} key which must be a comma separated -% list of commands, where each command -% is included in \meta{assign list}. The optional argument -% \meta{conditions} is the same as that for \cs{DTLforeach}. -% \begin{macrocode} -\newcommand*{\DTLmultibarchart}[4][\boolean{true}]{% -{\let\dtlbar@variables=\relax -\let\DTLbarmax=\relax -\let\DTLnegextent=\relax -\disable@keys{databar}{variable,upperbarlabel}% -\setkeys{databar}{#2}% -\ifx\dtlbar@variables\relax - \PackageError{databar}{\string\DTLmultibarchart\space missing variables setting}{}% -\else -% \end{macrocode} -% Compute the maximum bar height, unless \cs{DTLbarmax} has been -% set. -%\changes{1.01}{2007 Aug 17}{uses \cs{@sDTLforeach} instead of -%\cs{DTLforeach}} +% Iterates through list of people the \cs{in}\marg{list} is optional. +% If omitted, the list of all defined people is used. % \begin{macrocode} - \ifx\DTLbarmax\relax - \@sDTLforeach[#1]{#3}{#4}{% - \@for\DTLbarvariable:=\dtlbar@variables\do{% - \expandafter\DTLconverttodecimal\expandafter - {\DTLbarvariable}{\dtl@barvar}% - \ifx\DTLbarmax\relax - \let\DTLbarmax=\dtl@barvar - \else - \let\dtl@old=\DTLbarmax - \FPmax{\DTLbarmax}{\dtl@old}{\dtl@barvar}% - \fi - }% - }% - \ifx\dtlbar@yticgap\relax - \else - \let\dtl@thistick=\dtlbar@yticgap% - \whiledo{\DTLisFPopenbetween{\dtl@thistick}{0}{\DTLbarmax}}{% - \FPadd{\dtl@thistick}{\dtl@thistick}{\dtlbar@yticgap}% - }% - \let\DTLbarmax=\dtl@thistick - \fi +\def\foreachperson(#1,#2,#3,#4)#5{% + \ifx#5\in + \def\@do@foreachperson{\@foreachperson(#1,#2,#3,#4)#5}% + \else + \def\@do@foreachperson{% + \@foreachperson(#1,#2,#3,#4)\in\@people@list#5}% \fi -% \end{macrocode} -% Compute the bar depth, unless \cs{DTLnegextent} has been -% set. -% \begin{macrocode} - \ifx\DTLnegextent\relax - \def\DTLnegextent{0}% - \@sDTLforeach[#1]{#3}{#4}{% - \@for\DTLbarvariable:=\dtlbar@variables\do{% - \expandafter\DTLconverttodecimal\expandafter - {\DTLbarvariable}{\dtl@barvar}% - \let\dtl@old=\DTLnegextent - \DTLmin{\DTLnegextent}{\dtl@old}{\dtl@barvar}% - }% - }% - \ifx\dtlbar@yticgap\relax + \@do@foreachperson +} +\long\def\@foreachperson(#1,#2,#3,#4)\in#5\do#6{% + \@for#4:=#5\do{% + \ifx#4\@empty \else - \ifthenelse{\DTLisFPlt{\DTLnegextent}{0}}{% - \edef\dtl@thistick{0}% - \whiledo{\DTLisFPclosedbetween{\dtl@thistick}{\DTLnegextent}{0}}{% - \FPsub{\dtl@thistick}{\dtl@thistick}{\dtlbar@yticgap}% - }% - \let\DTLnegextent=\dtl@thistick - }{}% - \fi - \fi -% \end{macrocode} -% Determine scaling factor -% \begin{macrocode} - \@dtl@tmpcount=\DTLbarchartlength - \FPsub{\dtl@extent}{\DTLbarmax}{\DTLnegextent}% - \FPdiv{\dtl@unit}{\number\@dtl@tmpcount}{\dtl@extent}% -% \end{macrocode} -% Construct $y$ tick list if required -% \begin{macrocode} - \setlength{\dtl@yticlabelwidth}{0pt}% - \ifDTLbarytics - \ifx\dtlbar@yticlist\relax - \ifx\dtlbar@yticgap\relax - \dtl@constructticklist\DTLnegextent\DTLbarmax - \dtl@unit\dtlbar@yticlist - \else - \dtl@constructticklistwithgapz - \DTLnegextent\DTLbarmax\dtlbar@yticlist\dtlbar@yticgap - \fi - \fi - \ifx\dtlbar@ylabel\relax - \else - \ifx\dtlbar@yticlabels\relax - \@for\dtl@thislabel:=\dtlbar@yticlist\do{% - \FPround{\dtl@thislabel}{\dtl@thislabel} - {\c@DTLbarroundvar}% - \ifDTLverticalbars - \settowidth{\dtl@tmplength}{% - \DTLbardisplayYticklabel{\dtl@thislabel}}% - \else - \settoheight{\dtl@tmplength}{% - \DTLbardisplayYticklabel{\dtl@thislabel}}% - \edef\@dtl@h{\the\dtl@tmplength}% - \settodepth{\dtl@tmplength}{% - \DTLbardisplayYticklabel{\dtl@thislabel}}% - \addtolength{\dtl@tmplength}{\@dtl@h}% - \addtolength{\dtl@tmplength}{\baselineskip}% - \fi - \ifdim\dtl@tmplength>\dtl@yticlabelwidth - \setlength{\dtl@yticlabelwidth}{\dtl@tmplength}% - \fi - }% - \else - \@for\dtl@thislabel:=\dtlbar@yticlabels\do{% - \ifDTLverticalbars - \settowidth{\dtl@tmplength}{% - \DTLbardisplayYticklabel{\dtl@thislabel}}% - \else - \settoheight{\dtl@tmplength}{% - \DTLbardisplayYticklabel{\dtl@thislabel}}% - \edef\@dtl@h{\the\dtl@tmplength}% - \settodepth{\dtl@tmplength}{% - \DTLbardisplayYticklabel{\dtl@thislabel}}% - \addtolength{\dtl@tmplength}{\@dtl@h}% - \addtolength{\dtl@tmplength}{\baselineskip}% - \fi - \ifdim\dtl@tmplength>\dtl@yticlabelwidth - \setlength{\dtl@yticlabelwidth}{\dtl@tmplength}% + \ifpersonexists{#4}% + {% + \expandafter + \let\expandafter#1\csname person@#4@name\endcsname + \expandafter + \let\expandafter#2\csname person@#4@fullname\endcsname + \expandafter + \let\expandafter#3\csname person@#4@gender\endcsname + \ifx#3\@male@label + \let#3\malename + \else + \ifx#3\@female@label + \let#3\femalename \fi - }% - \fi + \fi + #6% + }% + {% + \PackageError{person}{Person `#4' doesn't exist}{}% + }% \fi - \fi -% \end{macrocode} -% Calculate the offset for the lower label and number of labels -% \begin{macrocode} -\dtl@xticlabelheight=0pt\relax -\@dtl@tmpcount=0\relax -\@for\dtl@thislabel:=\dtl@multibarlabels\do{% - \advance\@dtl@tmpcount by 1\relax - \settoheight{\dtl@tmplength}{\tikz\expandafter\pgftext\expandafter - [\DTLbarXlabelalign]{\DTLdisplaylowerbarlabel{\dtl@thislabel}};}% - \edef\@dtl@h{\the\dtl@tmplength}% - \settodepth{\dtl@tmplength}{\tikz\expandafter\pgftext\expandafter - [\DTLbarXlabelalign]{\DTLdisplaylowerbarlabel{\dtl@thislabel}};}% - \addtolength{\dtl@tmplength}{\@dtl@h}% - \addtolength{\dtl@tmplength}{\baselineskip}% - \ifdim\dtl@tmplength>\dtl@xticlabelheight - \setlength{\dtl@xticlabelheight}{\dtl@tmplength}% - \fi -} -% \end{macrocode} -% Calculate number of bars per group -% \begin{macrocode} -\@dtl@tmpcount=0\relax -\@for\dtl@this:=\dtlbar@variables\do{% - \advance\@dtl@tmpcount by 1\relax -}% -\edef\DTLbargroupwidth{\number\@dtl@tmpcount}% -% \end{macrocode} -% Compute the total width of the bar chart (in terms of -% the $x$ unit vector.) -% \begin{macrocode} -\edef\dtl@n{\expandafter\number\csname dtlrows@#3\endcsname} -\FPmul{\dtl@tmpi}{\dtl@n}{\DTLbargroupwidth} -\FPsub{\dtl@tmpii}{\dtl@n}{1}% -\FPmul{\dtl@tmpii}{\dtl@tmpii}{\dtlbar@groupgap}% -\FPadd{\DTLbarchartwidth}{\dtl@tmpi}{\dtl@tmpii} -% \end{macrocode} -% Do the bar chart -% \begin{macrocode} -\begin{tikzpicture} -% \end{macrocode} -% Set unit vectors -% \begin{macrocode} -\ifDTLverticalbars - \pgfsetyvec{\pgfpoint{0pt}{\dtl@unit sp}}% - \pgfsetxvec{\pgfpoint{\DTLbarwidth}{0pt}}% -\else - \pgfsetxvec{\pgfpoint{\dtl@unit sp}{0pt}}% - \pgfsetyvec{\pgfpoint{0pt}{\DTLbarwidth}}% -\fi -% \end{macrocode} -% Begin hook -% \begin{macrocode} -\DTLbaratbegintikz -% \end{macrocode} -% Initialise -% \begin{macrocode} -\def\@dtl@start{0}% -% \end{macrocode} -% Iterate through data -% \begin{macrocode} -\@sDTLforeach[#1]{#3}{#4}{% -% \end{macrocode} -% Store the bar number in \cs{@dtl@bar} -% \begin{macrocode} -\@dtl@barcount = 1\relax -% \end{macrocode} -% Set the multibar label lists -% \begin{macrocode} -\let\dtl@multibar@labels=\dtl@multibarlabels -\let\dtl@uppermultibar@labels=\dtl@uppermultibarlabels -% \end{macrocode} -% Compute mid point over group -% \begin{macrocode} -\FPmul{\dtl@multimidpt}{\DTLbargroupwidth}{0.5}% -\FPadd{\dtl@multimidpt}{\dtl@multimidpt}{\@dtl@start}% -% \end{macrocode} -% Iterate through each variable -% \begin{macrocode} -\@for\DTLbarvariable:=\dtlbar@variables\do{% -% \end{macrocode} -% Set end point -% \begin{macrocode} -\FPadd{\@dtl@endpt}{\@dtl@start}{1}% -% \end{macrocode} -% Convert variable to decimal -% \begin{macrocode} -\expandafter\DTLconverttodecimal\expandafter - {\DTLbarvariable}{\dtl@variable}% -% \end{macrocode} -% Get the current lower label: -% \begin{macrocode} -\dtl@chopfirst\dtl@multibar@labels\dtl@thisbarlabel\dtl@rest -\let\dtl@multibar@labels=\dtl@rest -% \end{macrocode} -% Get the current upper label: -% \begin{macrocode} -\dtl@chopfirst\dtl@uppermultibar@labels\dtl@thisupperbarlabel\dtl@rest -\let\dtl@uppermultibar@labels=\dtl@rest -% \end{macrocode} -% Draw bars -% \begin{macrocode} -\begin{scope} - \expandafter\color\expandafter{\DTLgetbarcolor{\@dtl@barcount}}% - \ifDTLverticalbars - \fill (\@dtl@start,0) -- (\@dtl@start,\dtl@variable) - -- (\@dtl@endpt,\dtl@variable) -- (\@dtl@endpt,0) -- cycle; - \else - \fill (0,\@dtl@start) -- (\dtl@variable,\@dtl@start) - -- (\dtl@variable,\@dtl@endpt) -- (0,\@dtl@endpt) -- cycle; - \fi -\end{scope} -% \end{macrocode} -% Draw outline -% \begin{macrocode} -\begin{scope} -\ifdim\DTLbaroutlinewidth>0pt - \expandafter\color\expandafter{\DTLbaroutlinecolor} - \ifDTLverticalbars - \draw (\@dtl@start,0) -- (\@dtl@start,\dtl@variable) - -- (\@dtl@endpt,\dtl@variable) -- (\@dtl@endpt,0) -- cycle; - \else - \draw (0,\@dtl@start) -- (\dtl@variable,\@dtl@start) - -- (\dtl@variable,\@dtl@endpt) -- (0,\@dtl@endpt) -- cycle; - \fi -\fi -\end{scope} -% \end{macrocode} -% Calculate mid point -% \begin{macrocode} -\FPadd{\@dtl@midpt}{\@dtl@start}{0.5}% -% \end{macrocode} -% Draw lower $x$ labels -% \begin{macrocode} -\ifDTLverticalbars - \edef\dtl@textopt{% - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{\@dtl@midpt}{0}} - {\noexpand\pgfpoint{0pt}{-\noexpand\DTLbarlabeloffset}}}, - \DTLbarXlabelalign - }% - \edef\DTLstartpt{\noexpand\pgfpointxy{\@dtl@midpt}{0}}% -\else - \edef\dtl@textopt{% - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{0}{\@dtl@midpt}} - {\noexpand\pgfpoint{-\noexpand\DTLbarlabeloffset}{0pt}}}, - \DTLbarXlabelalign - }% - \edef\DTLstartpt{\noexpand\pgfpointxy{0}{\@dtl@midpt}}% -\fi - \expandafter\pgftext\expandafter[\dtl@textopt]{% - \DTLdisplaylowermultibarlabel{\dtl@thisbarlabel}} -% \end{macrocode} -% Draw upper $x$ labels -% \begin{macrocode} -\ifDTLverticalbars - \expandafter\DTLifnumlt\expandafter{\DTLbarvariable}{0} - { - \edef\dtl@textopt{% - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{\@dtl@midpt}{\dtl@variable}} - {\noexpand\pgfpoint{0pt}{-\noexpand\DTLbarlabeloffset}}} - }% - }{% - \edef\dtl@textopt{% - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{\@dtl@midpt}{\dtl@variable}} - {\noexpand\pgfpoint{0pt}{\noexpand\DTLbarlabeloffset}}} - }% - } - \edef\DTLendpt{\noexpand\pgfpointxy{\@dtl@midpt}{\dtl@variable}}% -\else - \expandafter\DTLifnumlt\expandafter{\DTLbarvariable}{0} - { - \edef\dtl@textopt{right, - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{\dtl@variable}{\@dtl@midpt}} - {\noexpand\pgfpoint{-\noexpand\DTLbarlabeloffset}{0pt}}} - }% - }{% - \edef\dtl@textopt{left, - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{\dtl@variable}{\@dtl@midpt}} - {\noexpand\pgfpoint{\noexpand\DTLbarlabeloffset}{0pt}}} - }% - } - \edef\DTLendpt{\noexpand\pgfpointxy{\dtl@variable}{\@dtl@midpt}}% -\fi - \expandafter\pgftext\expandafter[\dtl@textopt]{% - \DTLdisplayuppermultibarlabel{\dtl@thisupperbarlabel}} -% \end{macrocode} -% Set the mid point -% \begin{macrocode} -\def\DTLmidpt{\pgfpointlineattime{0.5}{\DTLstartpt}{\DTLendpt}}% -% \end{macrocode} -% Do every bar hook -%\changes{2.0}{2009 February 27}{added \cs{DTLeverybarhook}}% -% \begin{macrocode} -\DTLeverybarhook -% \end{macrocode} -% End of loop increment loop variables -% \begin{macrocode} - \FPadd{\@dtl@start}{\@dtl@start}{1}% - \advance\@dtl@barcount by 1\relax -}% -% Draw lower group $x$ labels -% \begin{macrocode} -\setlength{\dtl@tmplength}{\DTLbarlabeloffset}% -\addtolength{\dtl@tmplength}{\dtl@xticlabelheight}% -\ifDTLverticalbars - \edef\dtl@textopt{% - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{\dtl@multimidpt}{0}} - {\noexpand\pgfpoint{0pt}{-\noexpand\dtl@tmplength}}}, - \DTLbarXlabelalign - }% -\else - \edef\dtl@textopt{% - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{0}{\dtl@multimidpt}} - {\noexpand\pgfpoint{-\noexpand\dtl@tmplength}{0pt}}}, - \DTLbarXlabelalign }% -\fi - \expandafter\pgftext\expandafter[\dtl@textopt]{% - \DTLdisplaylowerbarlabel{\dtl@barlabel}} -% \end{macrocode} -% Increment starting position by \cs{dtlbar@groupgap} -% \begin{macrocode} - \FPadd{\@dtl@start}{\@dtl@start}{\dtlbar@groupgap}% } % \end{macrocode} -% Draw $x$ axis -% \begin{macrocode} -\ifDTLbarxaxis - \ifDTLverticalbars - \expandafter\draw\expandafter[\DTLBarXAxisStyle] - (0,0) -- (\DTLbarchartwidth,0); - \else - \expandafter\draw\expandafter[\DTLBarXAxisStyle] - (0,0) -- (0,\DTLbarchartwidth); - \fi -\fi -% \end{macrocode} -% Draw $y$ axis -% \begin{macrocode} -\ifDTLbaryaxis - \ifDTLverticalbars - \expandafter\draw\expandafter[\DTLBarYAxisStyle] - (0,\DTLnegextent) -- (0,\DTLbarmax); - \else - \expandafter\draw\expandafter[\DTLBarYAxisStyle] - (\DTLnegextent,0) -- (\DTLbarmax,0); - \fi -\fi -% \end{macrocode} -% Plot $y$ tick marks if required -% \begin{macrocode} -\ifx\dtlbar@yticlist\relax -\else - \@for\dtl@thistick:=\dtlbar@yticlist\do{% - \ifDTLverticalbars - \pgfpathmoveto{\pgfpointxy{0}{\dtl@thistick}} - \pgfpathlineto{ - \pgfpointadd{\pgfpointxy{0}{\dtl@thistick}} - {\pgfpoint{-\DTLticklength}{0pt}}} - \else - \pgfpathmoveto{\pgfpointxy{\dtl@thistick}{0}} - \pgfpathlineto{ - \pgfpointadd{\pgfpointxy{\dtl@thistick}{0}} - {\pgfpoint{0pt}{-\DTLticklength}}} - \fi - \pgfusepath{stroke} - \ifx\dtlbar@yticlabels\relax - \FPround{\dtl@thislabel}{\dtl@thistick} - {\c@DTLbarroundvar}% - \else - \dtl@chopfirst\dtlbar@yticlabels\dtl@thislabel\dtl@rest - \let\dtlbar@yticlabels=\dtl@rest - \fi - \ifDTLverticalbars - \edef\dtl@textopt{\DTLbarYticklabelalign,% - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{0}{\dtl@thistick}} - {\noexpand\pgfpoint{-\noexpand\DTLticklabeloffset}{0pt}}, - }}% - \else - \edef\dtl@textopt{\DTLbarYticklabelalign, - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{\dtl@thistick}{0}} - {\noexpand\pgfpoint{0pt}{-\noexpand\DTLticklabeloffset}} - }}% - \fi - \expandafter\pgftext\expandafter[\dtl@textopt]{% - \DTLbardisplayYticklabel{\dtl@thislabel}} - }% -\fi -% \end{macrocode} -% Plot the $y$ label if required -% \begin{macrocode} -\ifx\dtlbar@ylabel\relax -\else - \addtolength{\dtl@yticlabelwidth}{\baselineskip}% - \setlength{\dtl@tmplength}{0.5\DTLbarchartlength} - \ifDTLverticalbars - \pgftext[bottom,center,at={\pgfpointadd - {\pgfpointxy{0}{\DTLnegextent}}% - {\pgfpoint{-\dtl@yticlabelwidth}{\dtl@tmplength}}}, - rotate=90]{% - \dtlbar@ylabel} - \else - \pgftext[bottom,center,at={\pgfpointadd - {\pgfpointxy{\DTLnegextent}{0}}% - {\pgfpoint{\dtl@tmplength}{-\dtl@yticlabelwidth}}}]{% - \dtlbar@ylabel} - \fi -\fi -% \end{macrocode} -% Finish bar chart -% \begin{macrocode} -\DTLbaratendtikz -\end{tikzpicture} -\fi -}} -% \end{macrocode} %\end{macro} -%\iffalse -% \begin{macrocode} -%</databar.sty> -% \end{macrocode} -%\fi -%\iffalse -% \begin{macrocode} -%<*databib.sty> -% \end{macrocode} -%\fi -%\section{databib.sty} -%\label{sec:src:databib} -%\subsection{Package Declaration} -% \begin{macrocode} -\NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{databib}[2009/10/22 v2.01 (NLCT)] -% \end{macrocode} -% Load required packages: -% \begin{macrocode} -\RequirePackage{datatool} -% \end{macrocode} -%\subsection{Package Options} -%\begin{macro}{\dtlbib@style} -%The default bib style is stored in \cs{dtlbib@style}. -% \begin{macrocode} -\newcommand*{\dtlbib@style}{plain} -% \end{macrocode} -%\end{macro} -% The \pkgopt[databib]{style} package option sets \cs{dtlbib@style}. -% \begin{macrocode} -\define@choicekey{databib.sty}{style}{plain,abbrv,alpha}{% -\def\dtlbib@style{#1}} -% \end{macrocode} -% Process package options: -% \begin{macrocode} -\ProcessOptionsX -% \end{macrocode} -%\subsection{Loading BBL file} -%\begin{macro}{\DTLloadbbl} -%\begin{definition} -%\cs{DTLloadbib}\oarg{bbl file}\marg{db name}\marg{bib list} -%\end{definition} -% \begin{macrocode} -\newcommand*{\DTLloadbbl}[3][\jobname.bbl]{% -\bibliographystyle{databib}% -\if@filesw - \immediate\write\@auxout{\string\bibdata{#3}}% -\fi -\DTLnewdb{#2}% -\edef\DTLBIBdbname{#2}% -\@input@{#1}} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\DTLnewbibrow} -% \cs{DTLnewbibrow} adds a new row to the bibliography database. -% (\cs{DTLBIBdbname} must be set prior to use to the name -% of the \sty{datatool} database which must exist. Any check -% to determine its existence should be performed when -% \cs{DTLBIBdbname} is set.) -%\changes{1.03}{2009 January 27}{removed check if database exists} +% +%\section{Predefined Words}\label{sec:code:peoplenames} +% These commands should be redefined if +% you are writing in another language, but note that these +% are structured according to English grammar. +%\begin{macro}{\malepronoun} % \begin{macrocode} -\newcommand*{\DTLnewbibrow}{\@DTLnewrow{\DTLBIBdbname}} +\newcommand*{\malepronoun}{he} % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLnewbibitem} -%\begin{definition} -%\cs{DTLnewbibitem}\marg{key}\marg{value} -%\end{definition} -% Adds a new database entry with the given key and value. -%\changes{1.03}{2009 January 27}{removed check if database exists} +%\begin{macro}{\femalepronoun} % \begin{macrocode} -\newcommand*{\DTLnewbibitem}[2]{% - \@DTLnewdbentry{\DTLBIBdbname}{#1}{#2}} +\newcommand*{\femalepronoun}{she} % \end{macrocode} %\end{macro} -%\subsection{Predefined text} -%\label{sec:src:bibnames} -%\begin{macro}{\andname} +%\begin{macro}{\pluralpronoun} % \begin{macrocode} -\providecommand*{\andname}{and} +\newcommand*{\pluralpronoun}{they} % \end{macrocode} %\end{macro} -%\begin{macro}{\ofname} +%\begin{macro}{\maleobjpronoun} % \begin{macrocode} -\providecommand*{\ofname}{of} +\newcommand*{\maleobjpronoun}{him} % \end{macrocode} %\end{macro} -%\begin{macro}{\inname} +%\begin{macro}{\femaleobjpronoun} % \begin{macrocode} -\providecommand*{\inname}{in} +\newcommand*{\femaleobjpronoun}{her} % \end{macrocode} %\end{macro} -%\begin{macro}{\etalname} +%\begin{macro}{\pluralobjpronoun} % \begin{macrocode} -\providecommand*{\etalname}{et al.} +\newcommand*{\pluralobjpronoun}{them} % \end{macrocode} %\end{macro} -%\begin{macro}{\editorname} +%\begin{macro}{\malepossadj} % \begin{macrocode} -\providecommand*{\editorname}{editor} +\newcommand*{\malepossadj}{his} % \end{macrocode} %\end{macro} -%\begin{macro}{\editorsname} +%\begin{macro}{\femalepossadj} % \begin{macrocode} -\providecommand*{\editorsname}{editors} +\newcommand*{\femalepossadj}{her} % \end{macrocode} %\end{macro} -%\begin{macro}{\volumename} +%\begin{macro}{\pluralpossadj} % \begin{macrocode} -\providecommand*{\volumename}{volume} +\newcommand*{\pluralpossadj}{their} % \end{macrocode} %\end{macro} -%\begin{macro}{\numbername} +%\begin{macro}{\maleposspronoun} % \begin{macrocode} -\providecommand*{\numbername}{number} +\newcommand*{\maleposspronoun}{his} % \end{macrocode} %\end{macro} -%\begin{macro}{\pagesname} +%\begin{macro}{\femaleposspronoun} % \begin{macrocode} -\providecommand*{\pagesname}{pages} +\newcommand*{\femaleposspronoun}{hers} % \end{macrocode} %\end{macro} -%\begin{macro}{\pagename} +%\begin{macro}{\pluralposspronoun} % \begin{macrocode} -\providecommand*{\pagename}{page} +\newcommand*{\pluralposspronoun}{theirs} % \end{macrocode} %\end{macro} -%\begin{macro}{\editionname} +%\begin{macro}{\malechild} % \begin{macrocode} -\providecommand*{\editionname}{edition} +\newcommand*{\malechild}{son} % \end{macrocode} %\end{macro} -%\begin{macro}{\techreportname} +%\begin{macro}{\femalechild} % \begin{macrocode} -\providecommand*{\techreportname}{Technical report} +\newcommand*{\femalechild}{daughter} % \end{macrocode} %\end{macro} -%\begin{macro}{\mscthesisname} +%\begin{macro}{\pluralchild} % \begin{macrocode} -\providecommand*{\mscthesisname}{Master's thesis} +\newcommand*{\pluralchild}{children} % \end{macrocode} %\end{macro} -%\begin{macro}{\phdthesisname} +%\begin{macro}{\malechildren} % \begin{macrocode} -\providecommand*{\phdthesisname}{PhD thesis} +\newcommand*{\malechildren}{sons} % \end{macrocode} %\end{macro} -% -% -%\subsection{Displaying the bibliography} -%\label{sec:src:displaybib} -%\begin{definition} -%\cs{DTLbibliography}\marg{bib dbname} -%\end{definition} -% Displays the bibliography for the database \meta{bib dbname} -% which must have previously been loaded using -% \cs{DTLloadbbl}. -%\begin{macro}{\DTLbibliography} +%\begin{macro}{\femalechildren} % \begin{macrocode} -\newcommand*{\DTLbibliography}[2][\boolean{true}]{% - \begin{DTLthebibliography}[#1]{#2}% - \DTLforeachbibentry[#1]{#2}{% - \DTLbibitem \DTLformatbibentry \DTLendbibitem - }% - \end{DTLthebibliography}% -} +\newcommand*{\femalechildren}{daughters} % \end{macrocode} %\end{macro} -% -%\begin{macro}{\DTLformatbibentry} -%\begin{definition} -%\cs{DTLformatbibentry} -%\end{definition} -% Formats the current bib entry. -% \begin{macrocode} -\newcommand*{\DTLformatbibentry}{% -% \end{macrocode} -% Check format for this type is defined. -% \begin{macrocode} - \@ifundefined{DTLformat\DBIBentrytype}% - {% - \PackageError{databib}{Don't know how to format bibliography - entries of type `\DBIBentrytype'}{}% - }% - {% -% \end{macrocode} -% Print information to terminal and log file if in verbose mode. -% \begin{macrocode} - \dtl@message{[\DBIBcitekey]}% -% \end{macrocode} -% Initialise -% \begin{macrocode} - \DTLstartsentencefalse\DTLmidsentencefalse\DTLperiodfalse -% \end{macrocode} -% Format this entry +%\begin{macro}{\maleparent} % \begin{macrocode} - \csname DTLformat\DBIBentrytype\endcsname - }% -} +\newcommand*{\maleparent}{father} % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLendbibitem} -% Hook to add extra information at the end of a bibliography item. -% This does nothing by default. +%\begin{macro}{\femaleparent} % \begin{macrocode} -\newcommand*{\DTLendbibitem}{} +\newcommand*{\femaleparent}{mother} % \end{macrocode} %\end{macro} -% -%\begin{macro}{\DTLwidest} -%Define a length to store the widest bib entry label +%\begin{macro}{\pluralparent} % \begin{macrocode} -\newlength\dtl@widest +\newcommand*{\pluralparent}{parents} % \end{macrocode} %\end{macro} -% -%\begin{macro}{\DTLcomputewidestbibentry} -%\begin{definition} -%\cs{DTLcomputewidestbibentry}\marg{conditions}\marg{db -%name}\marg{bib label}\marg{cmd} -%\end{definition} -%Computes the widest bibliography entry over all entries satisfying -%\meta{condition} for the database called \meta{db name}, where -% the bibliography label is formated according to \meta{bib label} and -% stores the result in \meta{cmd} which must be a command name. +%\begin{macro}{\malesibling} % \begin{macrocode} -\newcommand*{\DTLcomputewidestbibentry}[4]{% -\dtl@widest=0pt\relax -\let#4=\@empty -\DTLforeachbibentry[#1]{#2}{% -\settowidth{\dtl@tmplength}{#3}% -\ifdim\dtl@tmplength>\dtl@widest\relax - \dtl@widest=\dtl@tmplength - \protected@edef#4{#3}% -\fi -}% -} +\newcommand*{\malesibling}{brother} % \end{macrocode} %\end{macro} -% -%\begin{macro}{\DTLforeachbibentry} -%\begin{definition} -%\cs{DTLforeachbibentry}\oarg{condition}\marg{db name}\marg{text} -%\end{definition} -%\begin{definition} -%\cs{DTLforeachbibentry*}\oarg{condition}\marg{db name}\marg{text} -%\end{definition} -% Iterates through the database called \meta{db name} and does -% \meta{text} if \meta{condition} is met. As with -% \cs{DTLforeach}, the starred version is read only. +%\begin{macro}{\femalesibling} % \begin{macrocode} -\newcommand*{\DTLforeachbibentry}{% -\@ifstar\@DTLforeachbibentry\@DTLforeachbibentry} +\newcommand*{\femalesibling}{sister} % \end{macrocode} %\end{macro} -%\begin{macro}{\@DTLforeachbibentry} -% Unstarred version -% \begin{macrocode} -\newcommand*{\@DTLforeachbibentry}[3][\boolean{true}]{% -% \end{macrocode} -% Store database name. -% \begin{macrocode} - \edef\DBIBname{#2}% -% \end{macrocode} -% Reset row counter. -% \begin{macrocode} - \setcounter{DTLbibrow}{0}% -% \end{macrocode} -% Iterate through the database. +%\begin{macro}{\pluralsibling} % \begin{macrocode} - \@DTLforeach{#2}{\DBIBcitekey=CiteKey,\DBIBentrytype=EntryType}% - {% - \dtl@gathervalues{#2}{\dtlcurrentrow}% - \ifthenelse{#1}{\refstepcounter{DTLbibrow}#3}{}% - }% -} +\newcommand*{\pluralsibling}{siblings} % \end{macrocode} %\end{macro} -%\begin{macro}{\@sDTLforeachbibentry} -% Starred version -% \begin{macrocode} -\newcommand*{\@sDTLforeachbibentry}[3][\boolean{true}]{% -% \end{macrocode} -% Store database name. -% \begin{macrocode} - \edef\DBIBname{#2}% -% \end{macrocode} -% Reset row counter. -% \begin{macrocode} - \setcounter{DTLbibrow}{0}% -% \end{macrocode} -% Iterate through the database (read only). +%\begin{macro}{\malesiblings} % \begin{macrocode} - \@sDTLforeach{#2}{\DBIBcitekey=CiteKey,\DBIBentrytype=EntryType}% - {% - \dtl@gathervalues{#2}{\dtlcurrentrow}% - \ifthenelse{#1}{\refstepcounter{DTLbibrow}#3}{}% - }% -} +\newcommand*{\malesiblings}{brothers} % \end{macrocode} %\end{macro} -% -%\begin{counter}{DTLbibrow} -%The counter \ctrfmt{DTLbibrow} keeps track of the current -%row in the body of \cs{DTLforeachbibentry}. (You can't rely on -%\ctr{DTLrowi}, \ctr{DTLrowii} and -% \ctr{DTLrowiii}, as \cs{DTLforeachbibentry} pass the -% conditions to the optional argument of \cs{DTLforeach}, but -% instead uses \cs{ifthenelse}, which means that \ctr{DTLrowi} -% etc will be incremented, even when the given condition is not met.) -% \begin{macrocode} -\newcounter{DTLbibrow} -% \end{macrocode} -%\end{counter} -%\begin{macro}{\theHDTLbibrow} -% Keep \sty{hyperref} happy: +%\begin{macro}{\femalesiblings} % \begin{macrocode} -\def\theHDTLbibrow{\theHDTLrow.bib.\arabic{DTLbibrow}}% +\newcommand*{\femalesiblings}{sisters} % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLbibfield} -%\begin{definition} -%\cs{DTLbibfield}\marg{field name} -%\end{definition} -% Gets the value assigned to the field \meta{field name} for -% the current row of \cs{DTLforeachbibentry}. (Doesn't check if -% the field exists, or if it is being used within -% \cs{DTLforeachbibentry}.) +%\begin{macro}{\andname} +% Define \cs{andname} if it hasn't already been defined: % \begin{macrocode} -\newcommand*{\DTLbibfield}[1]{\csname @dtl@key@#1\endcsname} +\providecommand*{\andname}{and} % \end{macrocode} %\end{macro} -% -%\begin{macro}{\DTLifbibfieldexists} -%\begin{definition} -%\cs{DTLifbibfieldexists}\marg{field name}\marg{true part}\marg{false -%part} -%\end{definition} -%Determines whether the given field name exists for the current -% row of \cs{DTLforeachbibentry}. +%\begin{macro}{\malename} % \begin{macrocode} -\newcommand*{\DTLifbibfieldexists}[3]{% -\@ifundefined{@dtl@key@#1}{#3}{% -\expandafter\DTLifnull\csname @dtl@key@#1\endcsname -{#3}{#2}}} +\newcommand*{\malename}{male} % \end{macrocode} %\end{macro} -% -%\begin{macro}{\DTLifanybibfieldexists} -%\begin{definition} -%\cs{DTLifanybibfieldexists}\marg{list of field name}\marg{true part}\marg{false -%part} -%\end{definition} -% Determines whether any of the listed fields exist for the current -% row of \cs{DTLforeachbibentry}. +%\begin{macro}{\femalename} % \begin{macrocode} -\newcommand*{\DTLifanybibfieldexists}[3]{% -\@for\dtl@thisfield:=#1\do{% -\@ifundefined{@dtl@key@\dtl@thisfield}{}{% -\expandafter\DTLifnull\csname @dtl@key@\dtl@thisfield\endcsname -{}{% -\@endfortrue}}}% -\if@endfor - #2% -\else - #3% -\fi -\@endforfalse -} +\newcommand*{\femalename}{female} % \end{macrocode} %\end{macro} % -%\begin{macro}{\ifDTLperiod} -% The conditional \cs{ifDTLperiod} is used to keep track of any -% abbreviations ending with a period, this is to ensure that -% abbreviations aren't followed by a full stop if they already -% have a full stop terminating the abbreviation. +%\begin{macro}{\personsep} +% Separator to use between people (but not the between the last +% two). % \begin{macrocode} -\newif\ifDTLperiod +\newcommand*{\personsep}{, } % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLcheckendsperiod} -%\begin{definition} -%\cs{DTLcheckendperiod}\marg{string} -%\end{definition} -% Checks if \meta{string} ends with a full stop. This sets -% \cs{ifDTLperiod}. -% \begin{macrocode} -\newcommand*{\DTLcheckendsperiod}[1]{% -\dtl@checkendsperiod#1\@nil\relax} -% \end{macrocode} +%\begin{macro}{\personlastsep} +% Separator to use between last two people. % \begin{macrocode} -\def\dtl@checkendsperiod#1#2{% -\def\@dtl@argi{#1}\def\@dtl@argii{#2}% -\def\@dtl@period{.}% -\ifx\@dtl@argi\@nnil - \global\DTLperiodfalse - \let\@dtl@donext=\relax -\else - \ifx\@dtl@argii\@nnil - \ifx\@dtl@argi\@dtl@period - \global\DTLperiodtrue - \else - \global\DTLperiodfalse - \fi - \let\@dtl@donext=\@gobble - \else - \let\@dtl@donext=\dtl@checkendsperiod - \fi -\fi -\@dtl@donext{#2}% -} +\newcommand*{\personlastsep}{\space\andname\space} % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLcheckbibfieldendsperiod} -%\begin{definition} -%\cs{DTLcheckbibfieldendperiod}\marg{label} -%\end{definition} -% Checks if the bib field \meta{label} ends with a full stop. -% This sets \cs{ifDTLperiod}. +%\begin{macro}{\twopeoplesep} +% Separator to use when list only contains two people. % \begin{macrocode} -\newcommand*{\DTLcheckbibfieldendsperiod}[1]{% -\protected@edef\@dtl@tmp{\DTLbibfield{#1}}% -\expandafter\DTLcheckendsperiod\expandafter{\@dtl@tmp}} +\newcommand*{\twopeoplesep}{\space\andname\space} % \end{macrocode} %\end{macro} % -%\begin{macro}{\ifDTLmidsentence} -%\begin{definition} -%\cs{ifDTLmidsentence} -%\end{definition} -% Determine whether we are in the middle -% of a sentence. -% \begin{macrocode} -\newif\ifDTLmidsentence -% \end{macrocode} -%\end{macro} -%\begin{macro}{\ifDTLstartsentence} -%\begin{definition} -%\cs{ifDTLstartsentence} -%\end{definition} -% Determine whether we are at the start -% of a sentence. +%\section{Displaying Information} +%\begin{macro}{\personfullname} +% The person's full name can be displayed using +% \cs{personfullname}\oarg{label}, where \meta{label} is the +% unique label used when defining that person. If \meta{label} +% is omitted, \texttt{anon} is used. % \begin{macrocode} -\newif\ifDTLstartsentence +\newcommand*{\personfullname}[1][anon]{% + \@ifundefined{person@#1@fullname}% + {% + \PackageError{person}{Person `#1' has not been defined}{}% + }% + {% + \csname person@#1@fullname\endcsname + }% +} % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLaddperiod} -%\begin{definition} -%\cs{DTLaddperiod} -%\end{definition} -%Adds a full stop and sets \cs{DTLmidsentencefalse}, -%\cs{DTLstartsentencetrue} and -%\cs{DTLperiodfalse}. +%\begin{macro}{\peoplefullname} +% List all defined people's full names. This iterates through all +% labels in \cs{@people@list}. % \begin{macrocode} -\newcommand*{\DTLaddperiod}{\DTLmidsentencefalse\DTLperiodfalse -\DTLstartsentencetrue -\ifDTLperiod\else.\fi} +\newcommand*{\peoplefullname}{% + \setcounter{person}{1}% + \@for\@thisperson:=\@people@list\do{% + \ifthenelse{\equal{\@thisperson}{}}% + {}% + {% + \personfullname[\@thisperson]% + \stepcounter{person}% + \ifnum\c@people=1\relax + \else + \ifnum\c@person=\c@people + \ifnum\c@people=2\relax + \twopeoplesep + \else + \personlastsep + \fi + \else + \ifnum\c@person<\c@people + \personsep + \fi + \fi + \fi + }% + }% +} % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLaddcomma} -%\begin{definition} -%\cs{DTLaddcomma} -%\end{definition} -%Adds a comma and sets \cs{DTLmidsentencetrue}, \cs{DTLperiodfalse} -%and \cs{DTLstartsentencefalse} +%\begin{macro}{\personname} +% As \cs{personfullname}, but for the person's familiar name. % \begin{macrocode} -\newcommand*{\DTLaddcomma}{, \DTLmidsentencetrue -\DTLperiodfalse\DTLstartsentencefalse} +\newcommand*{\personname}[1][anon]{% + \@ifundefined{person@#1@name}% + {% + \PackageError{person}{Person `#1' has not been defined}{}% + }% + {% + \csname person@#1@name\endcsname + }% +} % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLstartsentencespace} -%Adds a space if at the start of the sentence, otherwise does -% nothing. (The space between sentences is added this way, rather -% than in \cs{DTLaddperiod} otherwise spurious extra space can -% occur at the end of the bib item. The spacefactor needs to be -% set manually, because there's stuff in the way of the previous -% sentence's full stop and this space which confuses the inter -% sentence spacing (and, of course, the previous sentence could -% have ended with a capital letter.) -% \begin{macrocode} -\newcommand*{\DTLstartsentencespace}{% -\ifDTLstartsentence\spacefactor=\sfcode`\.\relax\space -\fi\DTLstartsentencefalse} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLtwoand} -% In a list of only two author (or editor) names, the text between the -% two names is given by \cs{DTLtwoand}: -% \begin{macrocode} -\newcommand*{\DTLtwoand}{\ \andname\ } -% \end{macrocode} -%\end{macro} -%\begin{macro}{\DTLandlast} -% In a list of author (or editor) names, the text between the -% penultimate and last name is given by \cs{DTLandlast}: -% \begin{macrocode} -\newcommand*{\DTLandlast}{, \andname\ } -% \end{macrocode} -%\end{macro} -%\begin{macro}{\DTLandnotlast} -% In a list of author (or editor) names, the text between the -% names (except the penultimate and last name) is given by -% \cs{DTLandnotlast}: -% \begin{macrocode} -\newcommand*{\DTLandnotlast}{, } -% \end{macrocode} -%\end{macro} -%\begin{macro}{\dtl@authorcount} -% Define a count register to keep track of the number of authors: -% \begin{macrocode} -\newcount\@dtl@authorcount -% \end{macrocode} -%\end{macro} -%\begin{counter}{DTLmaxauthors} -% The counter \ctrfmt{DTLmaxauthors} indicates the maximum number of -% author names to display, if there are more than that number, -% \cs{etalname} is used. -% \begin{macrocode} -\newcounter{DTLmaxauthors} -\setcounter{DTLmaxauthors}{10} -% \end{macrocode} -%\end{counter} -%\begin{macro}{\DTLformatauthorlist} -% Format a list of author names (the list is stored in -% \cs{@dtl@key@Author}): +%\begin{macro}{\peoplename} +% List all defined people's familiar names. This iterates through all +% labels in \cs{@people@list}. % \begin{macrocode} -\newcommand*{\DTLformatauthorlist}{% -\DTLifbibfieldexists{Author}{% -\DTLstartsentencespace -\@dtl@authorcount=0\relax -\@for\@dtl@author:=\@dtl@key@Author\do{% -\advance\@dtl@authorcount by 1\relax}% -\@dtl@tmpcount=0\relax -\ifnum\@dtl@authorcount>\c@DTLmaxauthors -{% - \@for\@dtl@author:=\@dtl@key@Author\do{% - \advance\@dtl@tmpcount by 1\relax - \ifnum\@dtl@tmpcount=1\relax - \expandafter\DTLformatauthor\@dtl@author - \else - \ifnum\@dtl@tmpcount>\c@DTLmaxauthors - \DTLandnotlast \etalname - \expandafter\DTLcheckendsperiod\expandafter{\etalname}% - \@endfortrue - \else - \DTLandnotlast \expandafter\DTLformatauthor\@dtl@author - \fi - \fi - }% -}% -\else - \@for\@dtl@author:=\@dtl@key@Author\do{% - \advance\@dtl@tmpcount by 1\relax - \ifnum\@dtl@tmpcount=1\relax - \expandafter\DTLformatauthor\@dtl@author - \else - \ifnum\@dtl@tmpcount=\@dtl@authorcount - \ifnum\@dtl@authorcount=2\relax - \DTLtwoand +\newcommand*{\peoplename}{% + \setcounter{person}{1}% + \@for\@thisperson:=\@people@list\do{% + \ifthenelse{\equal{\@thisperson}{}}% + {}% + {% + \personname[\@thisperson]% + \stepcounter{person}% + \ifnum\c@people=1\relax \else - \DTLandlast + \ifnum\c@person=\c@people + \ifnum\c@people=2\relax + \twopeoplesep + \else + \personlastsep + \fi + \else + \ifnum\c@person<\c@people + \personsep + \fi + \fi \fi - \expandafter\DTLformatauthor\@dtl@author - \else - \DTLandnotlast \expandafter\DTLformatauthor\@dtl@author - \fi - \fi + }% }% -\fi -}{}% } % \end{macrocode} %\end{macro} -%\begin{counter}{DTLmaxeditors} -% The counter \ctrfmt{DTLmaxeditors} indicates the maximum number of -% editor names to display, if there are more than that number, -% \cs{etalname} is used. -% \begin{macrocode} -\newcounter{DTLmaxeditors} -\setcounter{DTLmaxeditors}{10} -% \end{macrocode} -%\end{counter} % -%\begin{macro}{\DTLformateditorlist} -% Format a list of editor names (the list is stored in -% \cs{@dtl@key@Editor}): +%\begin{macro}{\personpronoun} +% Display the pronoun (he/she) according to the person's gender. % \begin{macrocode} -\newcommand*{\DTLformateditorlist}{% -\DTLifbibfieldexists{Editor}{% -\DTLstartsentencespace -\@dtl@authorcount=0\relax -\@for\@dtl@author:=\@dtl@key@Editor\do{% -\advance\@dtl@authorcount by 1\relax}% -\@dtl@tmpcount=0\relax -\ifnum\@dtl@authorcount>\c@DTLmaxeditors -{% - \@for\@dtl@author:=\@dtl@key@Editor\do{% - \advance\@dtl@tmpcount by 1\relax - \ifnum\@dtl@tmpcount=1\relax - \expandafter\DTLformateditor\@dtl@author - \else - \ifnum\@dtl@tmpcount>\c@DTLmaxeditors - \DTLandnotlast \etalname - \expandafter\DTLcheckendsperiod\expandafter{\etalname}% - \@endfortrue - \else - \DTLandnotlast \expandafter\DTLformateditor\@dtl@author - \fi - \fi +\newcommand*{\personpronoun}[1][anon]{% + \@ifundefined{person@#1@gender}% + {% + \PackageError{person}{Person `#1' has not been defined}{}% }% -}% -\else -\@for\@dtl@author:=\@dtl@key@Editor\do{% - \advance\@dtl@tmpcount by 1\relax - \ifnum\@dtl@tmpcount=1\relax - \expandafter\DTLformateditor\@dtl@author - \else - \ifnum\@dtl@tmpcount=\@dtl@authorcount - \ifnum\@dtl@authorcount=2\relax - \DTLtwoand - \else - \DTLandlast - \fi - \expandafter\DTLformateditor\@dtl@author - \else - \DTLandnotlast \expandafter\DTLformateditor\@dtl@author - \fi - \fi + {% + \edef\@gender{\csname person@#1@gender\endcsname}% + \csname\@gender pronoun\endcsname }% -\fi -, -\ifnum\@dtl@authorcount=1\relax - \editorname - \expandafter\DTLcheckendsperiod\expandafter{\editorname}% -\else - \editorsname - \expandafter\DTLcheckendsperiod\expandafter{\editorsname}% -\fi -}{}% } % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLformatsurnameonly} -%\begin{definition} -%\cs{DTLformatsurnameonly}\marg{von part}\marg{surname}\marg{jr -%part}\marg{forenames} -%\end{definition} -% This is used when only the surname should be displayed. (The -% final argument, \meta{forenames}, is ignored.) +%\begin{macro}{\Personpronoun} +% As above, but make the first letter uppercase. % \begin{macrocode} -\newcommand*{\DTLformatsurnameonly}[4]{% -\DTLstartsentencespace -\def\@dtl@tmp{#1}% -\ifx\@dtl@tmp\@empty\else#1~\fi -#2% -\def\@dtl@tmp{#3}% -\ifx\@dtl@tmp\@empty - \DTLcheckendsperiod{#2}% -\else - , #3% - \DTLcheckendsperiod{#3}% -\fi +\newcommand*{\Personpronoun}[1][anon]{% + \@ifundefined{person@#1@gender}% + {% + \PackageError{person}{Person `#1' has not been defined}{}% + }% + {% + \edef\@gender{\csname person@#1@gender\endcsname}% + \expandafter\expandafter\expandafter + \MakeUppercase\csname\@gender pronoun\endcsname + }% } % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLformatforenames} -%\begin{definition} -%\cs{DTLformatforenames}\marg{forenames} -%\end{definition} -% The format of an author/editor's forenames. If the forenames -% occur at the start of sentence, a new sentence space is added. -% The argument is checked to determine whether it ends with a -% full stop (sometimes the forenames may include initials.) -% \begin{macrocode} -\newcommand*{\DTLformatforenames}[1]{% -\DTLstartsentencespace -#1% -\DTLcheckendsperiod{#1}} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLformatabbrvforenames} -%\begin{definition} -%\cs{DTLformatabbrvforenames}\marg{forenames} -%\end{definition} -% The format of an author/editor's abbreviated forenames. The initials -% may or may not end in a full stop depending on the commands -% governing the format of \cs{DTLstoreinitials}, so the initials -% need to be check using \cs{DTLcheckendsperiod}. +%\begin{macro}{\peoplepronoun} +% If there is more than one person, \cs{peoplepronoun} will use +% \cs{pluralpronoun}, otherwise it will use \cs{personpronoun}. % \begin{macrocode} -\newcommand*{\DTLformatabbrvforenames}[1]{% -\DTLstartsentencespace -\DTLstoreinitials{#1}{\@dtl@tmp}\@dtl@tmp -\expandafter\DTLcheckendsperiod\expandafter{\@dtl@tmp}} +\newcommand*{\peoplepronoun}{% + \ifnum\c@people>1\relax + \pluralpronoun + \else + \@get@firstperson{\@thisperson}% + \personpronoun[\@thisperson]% + \fi +} % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLformatvon} -%\begin{definition} -%\cs{DTLformatvon}\marg{von part} -%\end{definition} -% The format of the ``von'' part. This does nothing if the argument -% is empty, otherwise it does the argument followed by a -% non-breakable space. +%\begin{macro}{\Peoplepronoun} +% As above, but first letter in upper case % \begin{macrocode} -\newcommand*{\DTLformatvon}[1]{% -\DTLstartsentencespace -\def\@dtl@tmp{#1}% -\ifx\@dtl@tmp\@empty -\else - #1~% -\fi +\newcommand*{\Peoplepronoun}{% + \ifnum\c@people>1\relax + \expandafter\MakeUppercase\pluralpronoun + \else + \@get@firstperson{\@thisperson}% + \Personpronoun[\@thisperson]% + \fi } % \end{macrocode} %\end{macro} -% -%\begin{macro}{\DTLformatsurname} -%\begin{definition} -%\cs{DTLformatsurname}\marg{surname} -%\end{definition} -% The format of an author/editor's surname. +%\begin{macro}{\personobjpronoun} +% Display the objective pronoun (him/her) according to the person's +% gender. % \begin{macrocode} -\newcommand*{\DTLformatsurname}[1]{% -\DTLstartsentencespace -#1\DTLcheckendsperiod{#1}} +\newcommand*{\personobjpronoun}[1][anon]{% + \@ifundefined{person@#1@gender}% + {% + \PackageError{person}{Person `#1' has not been defined}{}% + }% + {% + \edef\@gender{\csname person@#1@gender\endcsname}% + \csname\@gender objpronoun\endcsname + }% +} % \end{macrocode} %\end{macro} -% -%\begin{macro}{\DTLformatjr} -%\begin{definition} -%\cs{DTLformatjr}\marg{jr part} -%\end{definition} -% The format of the ``jr'' part. This does nothing if the -% argument is empty. +%\begin{macro}{\Personobjpronoun} +% As above, but make the first letter uppercase. % \begin{macrocode} -\newcommand*{\DTLformatjr}[1]{% -\DTLstartsentencespace -\def\@dtl@tmp{#1}% -\ifx\@dtl@tmp\@empty -\else - , #1\DTLcheckendsperiod{#1}% -\fi +\newcommand*{\Personobjpronoun}[1][anon]{% + \@ifundefined{person@#1@gender}% + {% + \PackageError{person}{Person `#1' has not been defined}{}% + }% + {% + \edef\@gender{\csname person@#1@gender\endcsname}% + \expandafter\expandafter\expandafter + \MakeUppercase\csname\@gender objpronoun\endcsname + }% } % \end{macrocode} %\end{macro} -% -%\begin{macro}{\DTLformatcrossrefeditor} -% Format cross reference editors: +%\begin{macro}{\peopleobjpronoun} +% If there is more than one person, \cs{peopleobjpronoun} will use +% \cs{pluralobjpronoun}, otherwise it will use \cs{personobjpronoun}. % \begin{macrocode} -\newcommand*{\DTLformatcrossrefeditor}{% -\DTLifbibfieldexists{Editor}{% -\DTLstartsentencespace -\@dtl@authorcount=0\relax -\@for\@dtl@author:=\@dtl@key@Editor\do{% -\advance\@dtl@authorcount by 1\relax}% -{\@dtl@tmpcount=0\relax -\@for\@dtl@author:=\@dtl@key@Editor\do{% -\ifnum\@dtl@authorcount=1\relax - \expandafter\DTLformatsurnameonly\@dtl@author -\else - \advance\@dtl@tmpcount by 1\relax - \ifnum\@dtl@tmpcount=1\relax - \expandafter\DTLformatsurnameonly\@dtl@author +\newcommand*{\peopleobjpronoun}{% + \ifnum\c@people>1\relax + \pluralobjpronoun \else - \ifnum\@dtl@authorcount=2\relax - \ \andname\ \expandafter\DTLformatsurnameonly\@dtl@author - \else - \ \etalname - \expandafter\DTLcheckendsperiod\expandafter{\etalname} - \fi - \@endfortrue + \@get@firstperson{\@thisperson}% + \personobjpronoun[\@thisperson]% \fi -\fi -}}% -}{}% } % \end{macrocode} %\end{macro} -% -%\begin{macro}{\DTLformatvolnumpages} -% Format volume, number and pages (of an article). +%\begin{macro}{\Peopleobjpronoun} +% As above, but first letter in upper case % \begin{macrocode} -\newcommand*{\DTLformatvolnumpages}{% -\DTLifbibfieldexists{Volume}{% -\DTLstartsentencespace -\DTLbibfield{Volume}\DTLperiodfalse}{}% -\DTLifbibfieldexists{Number}{% -\DTLstartsentencespace -(\DTLbibfield{Number})\DTLperiodfalse}{}% -\DTLifbibfieldexists{Pages}{% -\DTLifanybibfieldexists{Volume,Number}{:}{% -\DTLstartsentencespace -\protected@edef\@dtl@pages{0\DTLbibfield{Pages}}% -\DTLifnumerical{\@dtl@pages}{\pagename}{\pagesname}~}% -\DTLbibfield{Pages}\DTLperiodfalse}{}% +\newcommand*{\Peopleobjpronoun}{% + \ifnum\c@people>1\relax + \expandafter\MakeUppercase\pluralobjpronoun + \else + \@get@firstperson{\@thisperson}% + \Personobjpronoun[\@thisperson]% + \fi } % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLformatbvolume} -% Format book volume. -% \begin{macrocode} -\newcommand*{\DTLformatbvolume}{% -\DTLifbibfieldexists{Volume}{% -\ifDTLmidsentence - \volumename -\else - \DTLstartsentencespace - \expandafter\MakeUppercase\volumename -\fi -~\DTLbibfield{Volume}% -\DTLifbibfieldexists{Series}{\ \ofname\ -{\em\DTLbibfield{Series}}\DTLcheckbibfieldendsperiod{Series}}{% -\DTLcheckbibfieldendsperiod{Volume}}% -}{}} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLformatchapterpages} -% Format chapter and pages: -% \begin{macrocode} -\newcommand*{\DTLformatchapterpages}{% -\DTLifbibfieldexists{Chapter}{% -\DTLifbibfieldexists{Type}{% -\DTLstartsentencespace -\DTLbibfield{Type}}{% -\DTLstartsentencespace -\chaptername}~\DTLbibfield{Chapter}% -\DTLifbibfieldexists{Pages}{\DTLaddcomma}{% -\DTLcheckbibfieldendsperiod{Chapter}}}{}% -\DTLstartsentencespace -\DTLformatpages} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLformatpages} -% Format pages: +%\begin{macro}{\personpssadj} +% Display the possessive adjective (his/her) according to the person's +% gender. % \begin{macrocode} -\newcommand*{\DTLformatpages}{% -\DTLifbibfieldexists{Pages}{% -\DTLstartsentencespace -\protected@edef\@dtl@pages{0\DTLbibfield{Pages}}% -\DTLifnumerical{\@dtl@pages}{\pagename}{\pagesname}~% -\DTLbibfield{Pages}\DTLcheckbibfieldendsperiod{Pages}}{}% +\newcommand*{\personpossadj}[1][anon]{% + \@ifundefined{person@#1@gender}% + {% + \PackageError{person}{Person `#1' has not been defined}{}% + }% + {% + \edef\@gender{\csname person@#1@gender\endcsname}% + \csname\@gender possadj\endcsname + }% } % \end{macrocode} %\end{macro} -% -%\begin{macro}{\DTLformatnumberseries} -% Format number and series (of book) +%\begin{macro}{\Personpossadj} +% As above, but make the first letter uppercase. % \begin{macrocode} -\newcommand*{\DTLformatnumberseries}{% -\DTLifbibfieldexists{Volume}{}{% -\DTLifbibfieldexists{Number}{% -\ifDTLmidsentence - \numbername -\else - \DTLstartsentencespace - \expandafter\MakeUppercase\numbername -\fi~\DTLbibfield{Number}% -\DTLifbibfieldexists{Series}{\ \inname\ \DTLbibfield{Series}% -\DTLcheckbibfieldendsperiod{Series}}{% -\DTLcheckbibfieldendsperiod{Number}}% -}{% -\DTLifbibfieldexists{Series}{% -\DTLstartsentencespace -\DTLbibfield{Series}% -\DTLcheckbibfieldendsperiod{Series}}{}}% -}% +\newcommand*{\Personpossadj}[1][anon]{% + \@ifundefined{person@#1@gender}% + {% + \PackageError{person}{Person `#1' has not been defined}{}% + }% + {% + \edef\@gender{\csname person@#1@gender\endcsname}% + \expandafter\expandafter\expandafter + \MakeUppercase\csname\@gender possadj\endcsname + }% } % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLformatbookcrossref} -% Format a book cross reference. +%\begin{macro}{\peoplepossadj} +% If there is more than one person, \cs{peoplepossadj} will use +% \cs{pluralpossadj}, otherwise it will use \cs{personpossadj}. % \begin{macrocode} -\newcommand*{\DTLformatbookcrossref}{% -\DTLifbibfieldexists{Volume}{% -\ifDTLmidsentence - \volumename -\else - \DTLstartsentencespace - \expandafter\MakeUppercase\volumename -\fi -~\DTLbibfield{Volume}\ \ofname\ -}{% -\ifDTLmidsentence - \inname -\else - \DTLstartsentencespace - \expandafter\MakeUppercase\inname -\fi\ }% -\DTLifbibfieldexists{Editor}{\DTLformatcrossrefeditor}{% -\DTLifbibfieldexists{Key}{% -\DTLbibfield{Key}}{% -\DTLifbibfieldexists{Series}{% -{\em\DTLbibfield{Series}}}{}% -}% -}% -\edef\@dtl@tmp{\DTLbibfield{CrossRef}}% -~\cite{\@dtl@tmp}% +\newcommand*{\peoplepossadj}{% + \ifnum\c@people>1\relax + \pluralpossadj + \else + \@get@firstperson{\@thisperson}% + \personpossadj[\@thisperson]% + \fi } % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLformatincollproccrossref} -% Format `incollections' cross reference. +%\begin{macro}{\Peoplepossadj} +% As above, but first letter in upper case % \begin{macrocode} -\newcommand*{\DTLformatincollproccrossref}{% -\DTLifbibfieldexists{Editor}{% -\ifDTLmidsentence - \inname -\else - \DTLstartsentencespace - \expandafter\MakeUppercase\inname -\fi\ -\DTLformatcrossrefeditor -}{% -\DTLifbibfieldexists{Key}{% -\ifDTLmidsentence - \inname -\else - \DTLstartsentencespace - \expandafter\MakeUppercase\inname -\fi\ \DTLbibfield{Key}% -}{% -\DTLifbibfieldexists{BookTitle}{% -\ifDTLmidsentence - \inname -\else - \DTLstartsentencespace - \expandafter\MakeUppercase\inname -\fi\ {\em\DTLbibfield{BookTitle}}}{}% -}}% -\edef\@dtl@tmp{\DTLbibfield{CrossRef}}% -~\cite{\@dtl@tmp}% +\newcommand*{\Peoplepossadj}{% + \ifnum\c@people>1\relax + \expandafter\MakeUppercase\pluralpossadj + \else + \@get@firstperson{\@thisperson}% + \Personpossadj[\@thisperson]% + \fi } % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLformatinedbooktitle} -%Format editor and booktitle: -% \begin{macrocode} -\newcommand*{\DTLformatinedbooktitle}{% -\DTLifbibfieldexists{BookTitle}{% -\ifDTLmidsentence - \inname -\else - \DTLstartsentencespace - \expandafter\MakeUppercase\inname -\fi\ -\DTLifbibfieldexists{Editor}{% -\DTLformateditorlist\DTLaddcomma {\em\DTLbibfield{BookTitle}}% -\DTLcheckbibfieldendsperiod{BookTitle}% -}{{\em\DTLbibfield{BookTitle}}% -\DTLcheckbibfieldendsperiod{BookTitle}% -}}{}} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLformatdate} -%Format date. -% \begin{macrocode} -\newcommand*{\DTLformatdate}{% -\DTLifbibfieldexists{Year}{% -\DTLifbibfieldexists{Month}{% -\protected@edef\@dtl@tmp{\DTLbibfield{Month}}% -\ifDTLmidsentence - \@dtl@tmp -\else - \DTLstartsentencespace - \expandafter\MakeUppercase\@dtl@tmp -\fi\ -\DTLmidsentencefalse}{}% -\DTLstartsentencespace -\DTLbibfield{Year}}{% -\DTLifbibfieldexists{Month}{% -\protected@edef\@dtl@tmp{\DTLbibfield{Month}}% -\ifDTLmidsentence - \@dtl@tmp -\else - \DTLstartsentencespace - \expandafter\MakeUppercase\@dtl@tmp -\fi -\DTLcheckbibfieldendsperiod{Month}% -}{}}} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\DTLformatarticlecrossref} -% Format article cross reference. +%\begin{macro}{\personposspronoun} +% Display possessive pronoun (his/hers) according to the +% person's gender. % \begin{macrocode} -\newcommand*{\DTLformatarticlecrossref}{% -\DTLifbibfieldexists{Key}{% -\ifDTLmidsentence - \inname -\else - \DTLstartsentencespace - \expandafter\MakeUppercase\inname -\fi -\ {\em\DTLbibfield{Key}}}{% -\DTLifbibfieldexists{Journal}{% -\ifDTLmidsentence - \inname -\else - \DTLstartsentencespace - \expandafter\MakeUppercase\inname -\fi -\ {\em\DTLbibfield{Journal}}}{}}% -\edef\@dtl@tmp{\DTLbibfield{CrossRef}}% -~\cite{\@dtl@tmp}% +\newcommand*{\personposspronoun}[1][anon]{% + \@ifundefined{person@#1@gender}% + {% + \PackageError{person}{Person `#1' has not been defined}{}% + }% + {% + \edef\@gender{\csname person@#1@gender\endcsname}% + \csname\@gender posspronoun\endcsname + }% } % \end{macrocode} %\end{macro} -% -%\subsubsection{ifthen conditionals} -% The conditionals defined in this section may be used in the -% optional argument of \cs{DTLforeachbib}. They may also be -% used in the first argument of \cs{ifthenelse}, but only if the -% command occurs within the body of \cs{DTLforeachbib}. -% -%\begin{macro}{\DTLbibfieldexists} -%\begin{definition} -%\cs{DTLbibfieldexists}\marg{field label} -%\end{definition} -% Checks if named bib field exists for current entry -% \begin{macrocode} -\newcommand*{\DTLbibfieldexists}[1]{% -\TE@throw\noexpand\dtl@testbibfieldexists{#1}% -\noexpand\if@dtl@condition} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\dtl@testbibfieldexists} -% \begin{macrocode} -\newcommand*{\dtl@testbibfieldexists}[1]{% -\DTLifbibfieldexists{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLbibfieldiseq} -%\begin{definition} -%\cs{DTLbibfieldiseq}\marg{field label}\marg{value} -%\end{definition} -% Checks if the value of the bib field given by \meta{field label} -% is equal to \meta{value}. (Uses \cs{dtlcompare} to determine if -% the values are equal. If the bib field doesn't exist, the -% condition is false.) -% \begin{macrocode} -\newcommand*{\DTLbibfieldiseq}[2]{% -\TE@throw\noexpand\dtl@testbibfieldiseq{#1}{#2}% -\noexpand\if@dtl@condition} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\dtl@testbibfieldiseq} +%\begin{macro}{\Personposspronoun} +% As above, but make the first letter uppercase. % \begin{macrocode} -\newcommand*{\dtl@testbibfieldiseq}[2]{% -\DTLifbibfieldexists{#1}{% -\expandafter\let\expandafter\@dtl@tmp\expandafter - =\csname @dtl@key@#1\endcsname -\expandafter\toks@\expandafter{\@dtl@tmp}% -\@dtl@toks{#2}% -\edef\@dtl@docompare{\noexpand\dtlcompare{\noexpand\@dtl@tmpcount}% -{\the\toks@}{\the\@dtl@toks}}% -\@dtl@docompare -\ifnum\@dtl@tmpcount=0\relax - \@dtl@conditiontrue -\else - \@dtl@conditionfalse -\fi -}{% -\@dtl@conditionfalse}% +\newcommand*{\Personposspronoun}[1][anon]{% + \@ifundefined{person@#1@gender}% + {% + \PackageError{person}{Person `#1' has not been defined}{}% + }% + {% + \edef\@gender{\csname person@#1@gender\endcsname}% + \expandafter\expandafter\expandafter + \MakeUppercase\csname\@gender posspronoun\endcsname + }% } % \end{macrocode} %\end{macro} -% -%\begin{macro}{\DTLbibfieldislt} -%\begin{definition} -%\cs{DTLbibfieldislt}\marg{field label}\marg{value} -%\end{definition} -% Checks if the value of the bib field given by \meta{field label} -% is less than \meta{value}. (If the bib field doesn't exist, the -% condition is false.) -% \begin{macrocode} -\newcommand*{\DTLbibfieldislt}[2]{% -\TE@throw\noexpand\dtl@testbibfieldislt{#1}{#2}% -\noexpand\if@dtl@condition} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\dtl@testbibfieldislt} +%\begin{macro}{\peopleposspronoun} +% If there is more than one person, \cs{peopleposspronoun} will use +% \cs{pluralposspronoun}, otherwise it will use \cs{personposspronoun}. % \begin{macrocode} -\newcommand*{\dtl@testbibfieldislt}[2]{% -\DTLifbibfieldexists{#1}{% -\expandafter\let\expandafter\@dtl@tmp\expandafter - =\csname @dtl@key@#1\endcsname -\expandafter\toks@\expandafter{\@dtl@tmp}% -\@dtl@toks{#2}% -\edef\@dtl@docompare{\noexpand\dtlcompare{\noexpand\@dtl@tmpcount}% -{\the\toks@}{\the\@dtl@toks}}% -\@dtl@docompare -\ifnum\@dtl@tmpcount=-1\relax - \@dtl@conditiontrue -\else - \@dtl@conditionfalse -\fi -}{% -\@dtl@conditionfalse}% +\newcommand*{\peopleposspronoun}{% + \ifnum\c@people>1\relax + \pluralposspronoun + \else + \@get@firstperson{\@thisperson}% + \personposspronoun[\@thisperson]% + \fi } % \end{macrocode} %\end{macro} -% -%\begin{macro}{\DTLbibfieldisle} -%\begin{definition} -%\cs{DTLbibfieldisle}\marg{field label}\marg{value} -%\end{definition} -% Checks if the value of the bib field given by \meta{field label} -% is less than or equal to \meta{value}. -% (If the bib field doesn't exist, the -% condition is false.) -% \begin{macrocode} -\newcommand*{\DTLbibfieldisle}[2]{% -\TE@throw\noexpand\dtl@testbibfieldisle{#1}{#2}% -\noexpand\if@dtl@condition} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\dtl@testbibfieldisle} +%\begin{macro}{\Peopleposspronoun} +% As above, but first letter in upper case % \begin{macrocode} -\newcommand*{\dtl@testbibfieldisle}[2]{% -\DTLifbibfieldexists{#1}{% -\expandafter\let\expandafter\@dtl@tmp\expandafter - =\csname @dtl@key@#1\endcsname -\expandafter\toks@\expandafter{\@dtl@tmp}% -\@dtl@toks{#2}% -\edef\@dtl@docompare{\noexpand\dtlcompare{\noexpand\@dtl@tmpcount}% -{\the\toks@}{\the\@dtl@toks}}% -\@dtl@docompare -\ifnum\@dtl@tmpcount<1\relax - \@dtl@conditiontrue -\else - \@dtl@conditionfalse -\fi -}{% -\@dtl@conditionfalse}% +\newcommand*{\Peopleposspronoun}{% + \ifnum\c@people>1\relax + \expandafter\MakeUppercase\pluralposspronoun + \else + \@get@firstperson{\@thisperson}% + \Personposspronoun[\@thisperson]% + \fi } % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLbibfieldisgt} -%\begin{definition} -%\cs{DTLbibfieldisgt}\marg{field label}\marg{value} -%\end{definition} -% Checks if the value of the bib field given by \meta{field label} -% is greater than \meta{value}. (If the bib field doesn't exist, the -% condition is false.) -% \begin{macrocode} -\newcommand*{\DTLbibfieldisgt}[2]{% -\TE@throw\noexpand\dtl@testbibfieldisgt{#1}{#2}% -\noexpand\if@dtl@condition} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\dtl@testbibfieldisgt} +%\begin{macro}{\personchild} +% Display this person's relationship to their parent (i.e.\ son +% or daughter). % \begin{macrocode} -\newcommand*{\dtl@testbibfieldisgt}[2]{% -\DTLifbibfieldexists{#1}{% -\expandafter\let\expandafter\@dtl@tmp\expandafter - =\csname @dtl@key@#1\endcsname -\expandafter\toks@\expandafter{\@dtl@tmp}% -\@dtl@toks{#2}% -\edef\@dtl@docompare{\noexpand\dtlcompare{\noexpand\@dtl@tmpcount}% -{\the\toks@}{\the\@dtl@toks}}% -\@dtl@docompare -\ifnum\@dtl@tmpcount=1\relax - \@dtl@conditiontrue -\else - \@dtl@conditionfalse -\fi -}{% -\@dtl@conditionfalse}% +\newcommand*{\personchild}[1][anon]{% + \@ifundefined{person@#1@gender}% + {% + \PackageError{person}{Person `#1' has not been defined}{}% + }% + {% + \edef\@gender{\csname person@#1@gender\endcsname}% + \csname\@gender child\endcsname + }% } % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLbibfieldisge} -%\begin{definition} -%\cs{DTLbibfieldisge}\marg{field label}\marg{value} -%\end{definition} -% Checks if the value of the bib field given by \meta{field label} -% is less than or equal to \meta{value}. -% (If the bib field doesn't exist, the -% condition is false.) -% \begin{macrocode} -\newcommand*{\DTLbibfieldisge}[2]{% -\TE@throw\noexpand\dtl@testbibfieldisge{#1}{#2}% -\noexpand\if@dtl@condition} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\dtl@testbibfieldisge} +%\begin{macro}{\Personchild} +% As above, but make first letter uppercase. % \begin{macrocode} -\newcommand*{\dtl@testbibfieldisge}[2]{% -\DTLifbibfieldexists{#1}{% -\expandafter\let\expandafter\@dtl@tmp\expandafter - =\csname @dtl@key@#1\endcsname -\expandafter\toks@\expandafter{\@dtl@tmp}% -\@dtl@toks{#2}% -\edef\@dtl@docompare{\noexpand\dtlcompare{\noexpand\@dtl@tmpcount}% -{\the\toks@}{\the\@dtl@toks}}% -\@dtl@docompare -\ifnum\@dtl@tmpcount>-1\relax - \@dtl@conditiontrue -\else - \@dtl@conditionfalse -\fi -}{% -\@dtl@conditionfalse}% +\newcommand*{\Personchild}[1][anon]{% + \@ifundefined{person@#1@gender}% + {% + \PackageError{person}{Person `#1' has not been defined}{}% + }% + {% + \edef\@gender{\csname person@#1@gender\endcsname}% + \expandafter\expandafter\expandafter\MakeUppercase + \csname\@gender child\endcsname + }% } % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLbibfieldcontains} -%\begin{definition} -%\cs{DTLbibfieldcontains}\marg{field label}\marg{sub string} -%\end{definition} -% Checks if the value of the bib field given by \meta{field label} -% contains \meta{sub string}. -% (If the bib field doesn't exist, the -% condition is false.) -% \begin{macrocode} -\newcommand*{\DTLbibfieldcontains}[2]{% -\TE@throw\noexpand\dtl@testbibfieldcontains{#1}{#2}% -\noexpand\if@dtl@condition} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\dtl@testbibfieldcontains} -% \begin{macrocode} -\newcommand*{\dtl@testbibfieldcontains}[2]{% -\DTLifbibfieldexists{#1}{% -\expandafter\let\expandafter\@dtl@tmp\expandafter - =\csname @dtl@key@#1\endcsname -\expandafter\dtl@testifsubstring\expandafter{\@dtl@tmp}{#2}% -}{\@dtl@conditionfalse}} -% \end{macrocode} -%\end{macro} -% -%\subsection{Bibliography Style Macros} -%\label{sec:src:bibstyle} -% The macros defined in this section should be redefined by -% bibliography styles. -% -%\begin{environment}{DTLthebibliography} -% How to format the entire bibliography: -% \begin{macrocode} -\newenvironment{DTLthebibliography}[2][\boolean{true}]{% -\@dtl@tmpcount=0\relax -\@sDTLforeach[#1]{#2}{}{\advance\@dtl@tmpcount by 1\relax}% -\begin{thebibliography}{\number\@dtl@tmpcount} -}{\end{thebibliography}} -% \end{macrocode} -%\end{environment} -%\begin{macro}{\DTLmonthname} -% The monthname style. The argument must be a number from~1 -% to~12. By default, uses \cs{dtl@monthname}. -% \begin{macrocode} -\newcommand*{\DTLmonthname}[1]{% -\dtl@monthname{#1}} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\dtl@monthname} -% Full month names: -% \begin{macrocode} -\newcommand*{\dtl@monthname}[1]{% -\ifcase#1% -\or January% -\or February% -\or March% -\or April% -\or May% -\or June% -\or July% -\or August% -\or September% -\or October% -\or November% -\or December% -\fi} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\dtl@abbrvmonthname} -% Abbreviated months: -% \begin{macrocode} -\newcommand*{\dtl@abbrvmonthname}[1]{% -\ifcase#1% -\or Jan.% -\or Feb.% -\or Mar.% -\or Apr.% -\or May% -\or June% -\or July% -\or Aug.% -\or Sept.% -\or Oct.% -\or Nov.% -\or Dec.% -\fi} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLbibitem} -% Define how to start a new bibitem: -% \begin{macrocode} -\newcommand*{\DTLbibitem}{\bibitem{\DBIBcitekey}} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLmbibitem} -% As \cs{DTLbibitem} but for \cs{DTLmbibliography} -% \begin{macrocode} -\newcommand*{\DTLmbibitem}[1]{\bibitem{#1@\DBIBcitekey}} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLformatauthor} -%\begin{definition} -%\cs{DTLformatauthor}\marg{von part}\marg{surname}\marg{junior -%part}\marg{forenames} -%\end{definition} -% The format of an author's name. -% \begin{macrocode} -\newcommand*{\DTLformatauthor}[4]{% -\DTLformatforenames{#4} -\DTLformatvon{#1}% -\DTLformatsurname{#2}% -\DTLformatjr{#3}} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLformateditor} -% The format of an editor's name. -% \begin{macrocode} -\newcommand*{\DTLformateditor}[4]{% -\DTLformatforenames{#4} -\DTLformatvon{#1}% -\DTLformatsurname{#2}% -\DTLformatjr{#3}} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLformatedition} -% The format of an edition: -% \begin{macrocode} -\newcommand*{\DTLformatedition}[1]{#1 \editionname} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLformatarticle} -% The format of an article: -% \begin{macrocode} -\newcommand{\DTLformatarticle}{} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLformatbook} -% The format of a book: -% \begin{macrocode} -\newcommand{\DTLformatbook}{} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLformatbooklet} -% The format of a booklet: -% \begin{macrocode} -\newcommand{\DTLformatbooklet}{} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLformatinbook} -% The format of an ``inbook'' type: -% \begin{macrocode} -\newcommand{\DTLformatinbook}{} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLformatincollection} -% The format of an ``incollection'' type: -% \begin{macrocode} -\newcommand{\DTLformatincollection}{} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLformatinproceedings} -% The format of an ``inproceedings'' type: -% \begin{macrocode} -\newcommand{\DTLformatinproceedings}{} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLformatmanual} -% The format of a manual: -% \begin{macrocode} -\newcommand{\DTLformatmanual}{} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLformatmastersthesis} -% The format of a master's thesis: -% \begin{macrocode} -\newcommand{\DTLformatmastersthesis}{} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLformatmisc} -% The format of a miscellaneous entry: -% \begin{macrocode} -\newcommand{\DTLformatmisc}{} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLformatphdthesis} -% The format of a Ph.D. thesis: -% \begin{macrocode} -\newcommand{\DTLformatphdthesis}{} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLformatproceedings} -% The format of a proceedings: -% \begin{macrocode} -\newcommand{\DTLformatproceedings}{} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLformattechreport} -% The format of a technical report: -% \begin{macrocode} -\newcommand{\DTLformattechreport}{} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLformatunpublished} -% The format of an unpublished work: -% \begin{macrocode} -\newcommand{\DTLformatunpublished}{} -% \end{macrocode} -%\end{macro} -% -% Predefined names (these correspond to the standard \BibTeX\ -% predefined strings of the same name without the leading -% \cs{DTL}): -%\begin{macro}{\DTLacmcs} -% \begin{macrocode} -\newcommand*{\DTLacmcs}{ACM Computing Surveys} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLacta} -% \begin{macrocode} -\newcommand*{\DTLacta}{Acta Informatica} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLcacm} -% \begin{macrocode} -\newcommand*{\DTLcacm}{Communications of the ACM} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLibmjrd} -% \begin{macrocode} -\newcommand*{\DTLibmjrd}{IBM Journal of Research and Development} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLibmsj} -% \begin{macrocode} -\newcommand*{\DTLibmsj}{IBM Systems Journal} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLieeese} -% \begin{macrocode} -\newcommand*{\DTLieeese}{IEEE Transactions on Software Engineering} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLieeetc} -% \begin{macrocode} -\newcommand*{\DTLieeetc}{IEEE Transactions on Computers} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLieeetcad} -% \begin{macrocode} -\newcommand*{\DTLieeetcad}{IEEE Transactions on Computer-Aided Design -of Integrated Circuits} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLipl} -% \begin{macrocode} -\newcommand*{\DTLipl}{Information Processing Letters} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLjacm} -% \begin{macrocode} -\newcommand*{\DTLjacm}{Journal of the ACM} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLjcss} -% \begin{macrocode} -\newcommand*{\DTLjcss}{Journal of Computer and System Sciences} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLscp} -% \begin{macrocode} -\newcommand*{\DTLscp}{Science of Computer Programming} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLsicomp} -% \begin{macrocode} -\newcommand*{\DTLsicomp}{SIAM Journal on Computing} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLtocs} -% \begin{macrocode} -\newcommand*{\DTLtocs}{ACM Transactions on Computer Systems} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLtods} -% \begin{macrocode} -\newcommand*{\DTLtods}{ACM Transactions on Database Systems} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLtog} -% \begin{macrocode} -\newcommand*{\DTLtog}{ACM Transactions on Graphics} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLtoms} -% \begin{macrocode} -\newcommand*{\DTLtoms}{ACM Transactions on Mathematical Software} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLtoois} +%\begin{macro}{\peoplechild} +% If there is more than one person, \cs{peoplechild} will use +% \cs{malechildren} (if all male), \cs{femalechildren} (if all +% female) or \cs{pluralchild} (if mixed), otherwise it will use +% \cs{personchild}. % \begin{macrocode} -\newcommand*{\DTLtoois}{ACM Transactions on Office Information -Systems} +\newcommand*{\peoplechild}{% + \ifnum\c@people>1\relax + \ifallmale + {\malechildren}% + {\ifallfemale{\femalechildren}{\pluralchild}}% + \else + \@get@firstperson{\@thisperson}% + \personchild[\@thisperson]% + \fi +} % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLtoplas} +%\begin{macro}{\Peoplechild} +% As above but first letter is made uppercase. % \begin{macrocode} -\newcommand*{\DTLtoplas}{ACM Transactions on Programming Languages -and Systems} +\newcommand*{\Peoplechild}{% + \ifnum\c@people>1\relax + \ifallmale + {\expandafter\MakeUppercase\malechildren}% + {\ifallfemale + {\expandafter\MakeUppercase\femalechildren} + {\expandafter\MakeUppercase\pluralchild}}% + \else + \@get@firstperson{\@thisperson}% + \Personchild[\@thisperson]% + \fi +} % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLtcs} +%\begin{macro}{\personparent} +% Display this person's relationship to their child (i.e.\ father +% or mother). % \begin{macrocode} -\newcommand*{\DTLtcs}{Theoretical Computer Science} +\newcommand*{\personparent}[1][anon]{% + \@ifundefined{person@#1@gender}% + {% + \PackageError{person}{Person `#1' has not been defined}{}% + }% + {% + \edef\@gender{\csname person@#1@gender\endcsname}% + \csname\@gender parent\endcsname + }% +} % \end{macrocode} %\end{macro} % -%\subsection{Bibliography Styles} -% Each bibliography style is set by the command -% \cs{dtlbst@}\meta{style}, where \meta{style} is the name -% of the bibliography style. -% -%\begin{macro}{\dtlbst@plain} -% The `plain' style: -% \begin{macrocode} -\newcommand{\dtlbst@plain}{% -% \end{macrocode} -% Set how to format the entire bibliography: -% \begin{macrocode} -\renewenvironment{DTLthebibliography}[2][\boolean{true}]{% -\@dtl@tmpcount=0\relax -\@sDTLforeach[##1]{##2}{}{\advance\@dtl@tmpcount by 1\relax}% -\begin{thebibliography}{\number\@dtl@tmpcount}% -}{\end{thebibliography}}% -% \end{macrocode} -% Set how to start the bibliography entry: -% \begin{macrocode} -\renewcommand*{\DTLbibitem}{\bibitem{\DBIBcitekey}}% -\renewcommand*{\DTLmbibitem}[1]{\bibitem{##1@\DBIBcitekey}}% -% \end{macrocode} -% Sets the author name format. -% \begin{macrocode} -\renewcommand*{\DTLformatauthor}[4]{% -\DTLformatforenames{##4} -\DTLformatvon{##1}% -\DTLformatsurname{##2}% -\DTLformatjr{##3}} -% \end{macrocode} -% Sets the editor name format. -% \begin{macrocode} -\renewcommand*{\DTLformateditor}[4]{% -\DTLformatforenames{##4} -\DTLformatvon{##1}% -\DTLformatsurname{##2}% -\DTLformatjr{##3}} -% \end{macrocode} -% Sets the edition format. -% \begin{macrocode} -\renewcommand*{\DTLformatedition}[1]{##1 \editionname}% -% \end{macrocode} -% Sets the monthname format. -% \begin{macrocode} -\let\DTLmonthname\dtl@monthname -% \end{macrocode} -% Sets other predefined names: -% \begin{macrocode} -\renewcommand*{\DTLacmcs}{ACM Computing Surveys} -\renewcommand*{\DTLacta}{Acta Informatica} -\renewcommand*{\DTLcacm}{Communications of the ACM} -\renewcommand*{\DTLibmjrd}{IBM Journal of Research and Development} -\renewcommand*{\DTLibmsj}{IBM Systems Journal} -\renewcommand*{\DTLieeese}{IEEE Transactions on Software Engineering} -\renewcommand*{\DTLieeetc}{IEEE Transactions on Computers} -\renewcommand*{\DTLieeetcad}{IEEE Transactions on Computer-Aided Design -of Integrated Circuits} -\renewcommand*{\DTLipl}{Information Processing Letters} -\renewcommand*{\DTLjacm}{Journal of the ACM} -\renewcommand*{\DTLjcss}{Journal of Computer and System Sciences} -\renewcommand*{\DTLscp}{Science of Computer Programming} -\renewcommand*{\DTLsicomp}{SIAM Journal on Computing} -\renewcommand*{\DTLtocs}{ACM Transactions on Computer Systems} -\renewcommand*{\DTLtods}{ACM Transactions on Database Systems} -\renewcommand*{\DTLtog}{ACM Transactions on Graphics} -\renewcommand*{\DTLtoms}{ACM Transactions on Mathematical Software} -\renewcommand*{\DTLtoois}{ACM Transactions on Office Information -Systems} -\renewcommand*{\DTLtoplas}{ACM Transactions on Programming Languages -and Systems} -\renewcommand*{\DTLtcs}{Theoretical Computer Science} -% \end{macrocode} -% The format of an article. -% \begin{macrocode} -\renewcommand*{\DTLformatarticle}{% -\DTLformatauthorlist -\DTLifbibfieldexists{Author}{\DTLaddperiod}{}% -\DTLifbibfieldexists{Title}{% -\DTLstartsentencespace\DTLbibfield{Title}% -\DTLcheckbibfieldendsperiod{Title}% -\DTLaddperiod}{}% -\DTLifbibfieldexists{CrossRef}{% -% cross ref field -\DTLformatarticlecrossref -\DTLifbibfieldexists{Pages}{\DTLaddcomma}{}% -\DTLformatpages -\DTLaddperiod -}{% no cross ref field -\DTLifbibfieldexists{Journal}{\DTLstartsentencespace -{\em\DTLbibfield{Journal}}% -\DTLcheckbibfieldendsperiod{Journal}% -\DTLifanybibfieldexists{Number,Volume,Pages,Month,Year}{% -\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLformatvolnumpages -\DTLifanybibfieldexists{Volume,Number,Pages}{% -\DTLifanybibfieldexists{Year,Month}{\DTLaddcomma}{% -\DTLaddperiod}% -\DTLmidsentencefalse}{}% -\DTLformatdate -\DTLifanybibfieldexists{Year,Month}{\DTLaddperiod}{}% -}% -\DTLifbibfieldexists{Note}{\DTLstartsentencespace\DTLbibfield{Note}% -\DTLcheckbibfieldendsperiod{Note}% -\DTLaddperiod}{}% -} -% \end{macrocode} -% The format of a book. -% \begin{macrocode} -\renewcommand*{\DTLformatbook}{% -\DTLifbibfieldexists{Author}{% -\DTLformatauthorlist\DTLaddperiod -}{\DTLformateditorlist\DTLifbibfieldexists{Editor}{% -\DTLaddperiod}{}}% -\DTLifbibfieldexists{Title}{\DTLstartsentencespace -{\em\DTLbibfield{Title}}% -\DTLcheckbibfieldendsperiod{Title}}{}% -\DTLifbibfieldexists{CrossRef}{% -% cross ref field -\DTLifbibfieldexists{Title}{\DTLaddperiod}{}% -\DTLformatbookcrossref -\DTLifanybibfieldexists{Edition,Month,Year}{\DTLaddcomma -}{\DTLaddperiod}% -}{% no cross ref field -\DTLifbibfieldexists{Title}{% -\DTLifbibfieldexists{Volume}{\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLformatbvolume -\DTLformatnumberseries -\DTLifanybibfieldexists{Number,Series,Volume}{\DTLaddperiod}{}% -\DTLifbibfieldexists{Publisher}{\DTLstartsentencespace -\DTLbibfield{Publisher}% -\DTLcheckbibfieldendsperiod{Publisher}% -\DTLifbibfieldexists{Address}{\DTLaddcomma}{% -\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma -}{\DTLaddperiod}% -}}{}% -\DTLifbibfieldexists{Address}{\DTLstartsentencespace -\DTLbibfield{Address}% -\DTLcheckbibfieldendsperiod{Address}% -\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{\DTLaddperiod}}{}% -}% -\DTLifbibfieldexists{Edition}{% -\protected@edef\@dtl@tmp{\DTLformatedition{\DTLbibfield{Edition}}}% -\ifDTLmidsentence - \@dtl@tmp -\else - \DTLstartsentencespace\expandafter\MakeUppercase\@dtl@tmp -\fi -\expandafter\DTLcheckendsperiod\expandafter{\@dtl@tmp}% -\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{\DTLaddperiod}% -}{}% -\DTLformatdate -\DTLifanybibfieldexists{Year,Month}{\DTLaddperiod}{}% -\DTLifbibfieldexists{Note}{\DTLstartsentencespace -\DTLbibfield{Note}% -\DTLcheckbibfieldendsperiod{Note}% -\DTLaddperiod}{}% -}% -% \end{macrocode} -% The format of a booklet. -% \begin{macrocode} -\renewcommand*{\DTLformatbooklet}{% -\DTLifbibfieldexists{Author}{% -\DTLformatauthorlist\DTLaddperiod}{}% -\DTLifbibfieldexists{Title}{\DTLstartsentencespace -\DTLbibfield{Title}% -\DTLcheckbibfieldendsperiod{Title}% -\DTLaddperiod}{}% -\DTLifbibfieldexists{HowPublished}{% -\DTLstartsentencespace\DTLbibfield{HowPublished}% -\DTLcheckbibfieldendsperiod{HowPublished}% -\DTLifanybibfieldexists{Address,Month,Year}{\DTLaddcomma -}{\DTLaddperiod}}{}% -\DTLifbibfieldexists{Address}{\DTLstartsentencespace -\DTLbibfield{Address}% -\DTLcheckbibfieldendsperiod{Address}% -\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLformatdate -\DTLifanybibfieldexists{Year,Month}{\DTLaddperiod}{}% -\DTLifbibfieldexists{Note}{\DTLstartsentencespace\DTLbibfield{Note}% -\DTLcheckbibfieldendsperiod{Note}% -\DTLaddperiod}{}% -}% -% \end{macrocode} -% The format of an `inbook' entry. -% \begin{macrocode} -\renewcommand*{\DTLformatinbook}{% -\DTLifbibfieldexists{Author}{% -\DTLformatauthorlist\DTLaddperiod}{% -\DTLifbibfieldexists{Editor}{\DTLformateditorlist\DTLaddperiod}{}}% -\DTLifbibfieldexists{Title}{% -\DTLstartsentencespace -{\em\DTLbibfield{Title}}% -\DTLcheckbibfieldendsperiod{Title}% -}{}% -\DTLifbibfieldexists{CrossRef}{% -% Cross ref entry -\DTLifbibfieldexists{Title}{% -\DTLifbibfieldexists{Chapter}{\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLformatchapterpages -\DTLifanybibfieldexists{Chapter,Pages}{\DTLaddperiod}{}% -\DTLformatbookcrossref -}{% no cross ref -\DTLifbibfieldexists{Title}{% -\DTLifanybibfieldexists{Chapter,Volume}{\DTLaddcomma -}{\DTLaddperiod}}{}% -\DTLformatbvolume -\DTLifanybibfieldexists{Volume,Series}{% -\DTLifanybibfieldexists{Chapter,Pages}{% -\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLformatchapterpages -\DTLifanybibfieldexists{Chapter,Pages}{\DTLaddperiod}{}% -\DTLifbibfieldexists{Publisher}{% -\DTLstartsentencespace -\DTLbibfield{Publisher}% -\DTLcheckbibfieldendsperiod{Publisher}% -\DTLifbibfieldexists{Address}{\DTLaddcomma}{}}{}% -\DTLifbibfieldexists{Address}{% -\DTLstartsentencespace -\DTLbibfield{Address}% -\DTLcheckbibfieldendsperiod{Address}}{}% -}% -\DTLifanybibfieldexists{Edition,Month,Year}{\DTLaddcomma -}{\DTLaddperiod}% -\DTLifbibfieldexists{Edition}{% -\protected@edef\@dtl@tmp{\DTLformatedition{\DTLbibfield{Edition}}}% -\ifDTLmidsentence - \@dtl@tmp -\else - \DTLstartsentencespace - \expandafter\MakeUppercase\@dtl@tmp -\fi -\expandafter\DTLcheckendsperiod\expandafter{\@dtl@tmp}% -\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma -}{\DTLaddperiod}% -}{}% -\DTLformatdate -\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% -\DTLifbibfieldexists{Note}{% -\DTLstartsentencespace -\DTLbibfield{Note}% -\DTLcheckbibfieldendsperiod{Note}% -\DTLaddperiod}{}% -}% -% \end{macrocode} -% The format of an `incollection' entry. -% \begin{macrocode} -\renewcommand*{\DTLformatincollection}{% -\DTLifbibfieldexists{Author}{\DTLformatauthorlist\DTLaddperiod}{}% -\DTLifbibfieldexists{Title}{% -\DTLstartsentencespace -\DTLbibfield{Title}% -\DTLcheckbibfieldendsperiod{Title}% -\DTLaddperiod}{}% -\DTLifbibfieldexists{CrossRef}{% -% cross ref entry -\DTLformatincollproccrossref -\DTLifanybibfieldexists{Chapter,Pages}{\DTLaddcomma}{}% -\DTLformatchapterpages\DTLaddperiod -}{% no cross ref entry -\DTLformatinedbooktitle -\DTLifbibfieldexists{BookTitle}{% -\DTLifanybibfieldexists{Volume,Series,Chapter,Pages,Number}{% -\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLformatbvolume -\DTLifbibfieldexists{Volume}{% -\DTLifanybibfieldexists{Number,Series,Chapter,Pages}{% -\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLformatnumberseries -\DTLifanybibfieldexists{Number,Series}{% -\DTLifanybibfieldexists{Chapter,Pages}{\DTLaddcomma -}{\DTLaddperiod}}{}% -\DTLformatchapterpages -\DTLifanybibfieldexists{Chapter,Pages}{\DTLaddperiod}{}% -\DTLifbibfieldexists{Publisher}{% -\DTLstartsentencespace -\DTLbibfield{Publisher}% -\DTLcheckbibfieldendsperiod{Publisher}% -\DTLifanybibfieldexists{Address,Edition,Month,Year}{% -\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLifbibfieldexists{Address}{% -\DTLstartsentencespace -\DTLbibfield{Address}% -\DTLcheckbibfieldendsperiod{Address}% -\DTLifanybibfieldexists{Edition,Month,Year}{% -\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLifbibfieldexists{Edition}{% -\protected@edef\@dtl@tmp{\DTLformatedition{\DTLbibfield{Edition}}}% -\ifDTLmidsentence - \@dtl@tmp -\else - \DTLstartsentencespace - \expandafter\MakeUppercase\@dtl@tmp -\fi -\expandafter\DTLcheckendsperiod\expandafter{\@dtl@tmp}% -\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma -}{\DTLaddperiod}% -}{}% -\DTLformatdate -\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% -}% -\DTLifbibfieldexists{Note}{% -\DTLstartsentencespace -\DTLbibfield{Note}% -\DTLcheckbibfieldendsperiod{Note}% -\DTLaddperiod}{}% -}% -% \end{macrocode} -% The format of an `inproceedings' entry. -% \begin{macrocode} -\renewcommand*{\DTLformatinproceedings}{% -\DTLifbibfieldexists{Author}{\DTLformatauthorlist -\DTLaddperiod}{}% -\DTLifbibfieldexists{Title}{% -\DTLstartsentencespace -\DTLbibfield{Title}% -\DTLcheckbibfieldendsperiod{Title}% -\DTLaddperiod}{}% -\DTLifbibfieldexists{CrossRef}{% -% cross ref entry -\DTLformatincollproccrossref -\DTLifbibfieldexists{Pages}{\DTLaddcomma}{% -\DTLaddperiod}% -\DTLformatpages -\DTLifbibfieldexists{Pages}{\DTLaddperiod}{}% -}{% no cross ref -\DTLformatinedbooktitle -\DTLifbibfieldexists{BookTitle}{% -\DTLifanybibfieldexists{Volume,Series,Pages,Number,Address,% -Month,Year}{% -\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLformatbvolume -\DTLifbibfieldexists{Volume}{% -\DTLifanybibfieldexists{Number,Series,Pages,Address,Month,Year}{% -\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLformatnumberseries -\DTLifanybibfieldexists{Number,Series}{% -\DTLifanybibfieldexists{Pages,Address,Month,Year}{% -\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLformatpages -\DTLifbibfieldexists{Pages}{% -\DTLifanybibfieldexists{Address,Month,Year}{% -\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLifbibfieldexists{Address}{% -\DTLstartsentencespace -\DTLbibfield{Address}% -\DTLcheckbibfieldendsperiod{Address}% -\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{% -\DTLaddperiod}% -\DTLformatdate -\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% -\DTLifbibfieldexists{Organization}{% -\DTLstartsentencespace -\DTLbibfield{Organization}% -\DTLcheckbibfieldendsperiod{Organization}% -\DTLifbibfieldexists{Publisher}{\DTLaddcomma}{% -\DTLaddperiod}}{}% -\DTLifbibfieldexists{Publisher}{% -\DTLstartsentencespace -\DTLbibfield{Publisher}% -\DTLcheckbibfieldendsperiod{Publisher}% -\DTLaddperiod}{}% -}{% -\DTLifanybibfieldexists{Publisher,Organization}{% -\DTLaddperiod}{}% -\DTLifbibfieldexists{Organization}{% -\DTLstartsentencespace -\DTLbibfield{Organization}% -\DTLcheckbibfieldendsperiod{Organization}% -\DTLifanybibfieldexists{Publisher,Month,Year}{% -\DTLaddcomma}{}}{}% -\DTLifbibfieldexists{Publisher}{% -\DTLstartsentencespace -\DTLbibfield{Publisher}% -\DTLcheckbibfieldendsperiod{Publisher}% -\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{% -\DTLaddperiod}}{}% -\DTLformatdate -\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% -}% -}% -\DTLifbibfieldexists{Note}{% -\DTLstartsentencespace -\DTLbibfield{Note}% -\DTLcheckbibfieldendsperiod{Note}% -\DTLaddperiod}{}% -}% -% \end{macrocode} -% The format of a manual. -% \begin{macrocode} -\renewcommand*{\DTLformatmanual}{% -\DTLifbibfieldexists{Author}{\DTLformatauthorlist -\DTLaddperiod}{% -\DTLifbibfieldexists{Organization}{% -\DTLstartsentencespace -\DTLbibfield{Organization}% -\DTLcheckbibfieldendsperiod{Organization}% -\DTLifbibfieldexists{Address}{\DTLaddcomma \DTLbibfield{Address}% -\DTLcheckbibfieldendsperiod{Address}% -}{}% -\DTLaddperiod}{}% -}% -\DTLifbibfieldexists{Title}{% -\DTLstartsentencespace -{\em\DTLbibfield{Title}}% -\DTLcheckbibfieldendsperiod{Title}% -\DTLifbibfieldexists{Author}{% -\DTLifanybibfieldexists{Organization,Address}{% -\DTLaddperiod}{\DTLaddcomma}}{% -\DTLifanybibfieldexists{Organization,Address,Edition,Month,Year}{% -\DTLaddcomma}{\DTLaddperiod}}}{}% -\DTLifbibfieldexists{Author}{% -\DTLifbibfieldexists{Organization}{% -\DTLstartsentencespace -\DTLbibfield{Organization}% -\DTLcheckbibfieldendsperiod{Organization}% -\DTLifanybibfieldexists{Address,Edition,Month,Year}{% -\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLifbibfieldexists{Address}{% -\DTLstartsentencespace -\DTLbibfield{Address}% -\DTLcheckbibfieldendsperiod{Address}% -\DTLifanybibfieldexists{Edition,Month,Year}{% -\DTLaddcomma}{\DTLaddperiod}}{}% -}{% -\DTLifbibfieldexists{Organization}{}{% -\DTLifbibfieldexists{Address}{% -\DTLstartsentencespace -\DTLbibfield{Address}% -\DTLcheckbibfieldendsperiod{Address}% -\DTLifanybibfieldexists{Edition,Month,Year}{\DTLaddcomma}{% -\DTLaddperiod}}{}}% -}% -\DTLifbibfieldexists{Edition}{% -\protected@edef\@dtl@tmp{\DTLformatedition{\DTLbibfield{Edition}}}% -\ifDTLmidsentence - \@dtl@tmp -\else - \DTLstartsentencespace - \expandafter\MakeUppercase\@dtl@tmp -\fi -\expandafter\DTLcheckendsperiod\expandafter{\@dtl@tmp}% -\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{% -\DTLaddperiod}}{}% -\DTLformatdate -\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% -\DTLifbibfieldexists{Note}{% -\DTLstartsentencespace -\DTLbibfield{Note}% -\DTLcheckbibfieldendsperiod{Note}% -\DTLaddperiod}{}% -}% -% \end{macrocode} -% The format of a master's thesis. -% \begin{macrocode} -\renewcommand*{\DTLformatmastersthesis}{% -\DTLifbibfieldexists{Author}{\DTLformatauthorlist\DTLaddperiod}{}% -\DTLifbibfieldexists{Title}{% -\DTLstartsentencespace -\DTLbibfield{Title}% -\DTLcheckbibfieldendsperiod{Title}% -\DTLaddperiod}{}% -\DTLifbibfieldexists{Type}{% -\DTLstartsentencespace -\DTLbibfield{Type}% -\DTLcheckbibfieldendsperiod{Type}% -\DTLifanybibfieldexists{School,Address,Month,Year}{% -\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLifbibfieldexists{School}{% -\DTLstartsentencespace -\DTLbibfield{School}% -\DTLcheckbibfieldendsperiod{School}% -\DTLifanybibfieldexists{Address,Month,Year}{% -\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLifbibfieldexists{Address}{% -\DTLstartsentencespace -\DTLbibfield{Address}% -\DTLcheckbibfieldendsperiod{Address}% -\DTLifanybibfieldexists{Month,Year}{% -\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLformatdate -\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% -\DTLifbibfieldexists{Note}{% -\DTLstartsentencespace -\DTLbibfield{Note}% -\DTLcheckbibfieldendsperiod{Note}% -\DTLaddperiod}{}% -}% -% \end{macrocode} -% The format of a miscellaneous entry. -% \begin{macrocode} -\renewcommand*{\DTLformatmisc}{% -\DTLifbibfieldexists{Author}{\DTLformatauthorlist\DTLaddperiod}{}% -\DTLifbibfieldexists{Title}{% -\DTLstartsentencespace -\DTLbibfield{Title}% -\DTLcheckbibfieldendsperiod{Title}% -\DTLifbibfieldexists{HowPublished}{\DTLaddperiod}{% -\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{% -\DTLaddperiod}% -}% -\DTLmidsentencefalse}{}% -\DTLifbibfieldexists{HowPublished}{% -\DTLstartsentencespace -\DTLbibfield{HowPublished}% -\DTLcheckbibfieldendsperiod{HowPublished}% -\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{% -\DTLaddperiod}}{}% -\DTLformatdate -\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% -\DTLifbibfieldexists{Note}{% -\DTLstartsentencespace -\DTLbibfield{Note}% -\DTLcheckbibfieldendsperiod{Note}% -\DTLaddperiod}{}% -}% -% \end{macrocode} -% The format of a PhD thesis. -% \begin{macrocode} -\renewcommand*{\DTLformatphdthesis}{% -\DTLifbibfieldexists{Author}{\DTLformatauthorlist\DTLaddperiod}{}% -\DTLifbibfieldexists{Title}{% -\DTLstartsentencespace -{\em\DTLbibfield{Title}}% -\DTLcheckbibfieldendsperiod{Title}% -\DTLaddperiod}{}% -\DTLifbibfieldexists{Type}{% -\DTLstartsentencespace -\DTLbibfield{Type}% -\DTLcheckbibfieldendsperiod{Type}% -\DTLifanybibfieldexists{School,Address,Month,Year}{% -\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLifbibfieldexists{School}{% -\DTLstartsentencespace -\DTLbibfield{School}% -\DTLcheckbibfieldendsperiod{School}% -\DTLifanybibfieldexists{Address,Month,Year}{% -\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLifbibfieldexists{Address}{% -\DTLstartsentencespace -\DTLbibfield{Address}% -\DTLcheckbibfieldendsperiod{Address}% -\DTLifanybibfieldexists{Month,Year}{% -\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLformatdate -\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% -\DTLifbibfieldexists{Note}{% -\DTLstartsentencespace -\DTLbibfield{Note}% -\DTLcheckbibfieldendsperiod{Note}% -\DTLaddperiod}{}% -}% -% \end{macrocode} -% The format of a proceedings. -% \begin{macrocode} -\renewcommand*{\DTLformatproceedings}{% -\DTLifbibfieldexists{Editor}{% -\DTLformateditorlist\DTLaddperiod}{% -\DTLifbibfieldexists{Organization}{% -\DTLstartsentencespace -\DTLbibfield{Organization}% -\DTLcheckbibfieldendsperiod{Organization}% -\DTLaddperiod}{}}% -\DTLifbibfieldexists{Title}{% -\DTLstartsentencespace -{\em\DTLbibfield{Title}}% -\DTLcheckbibfieldendsperiod{Title}% -\DTLifanybibfieldexists{Volume,Number,Address,Editor,Publisher,% -Month,Year}{\DTLaddcomma}{\DTLaddperiod}% -}{}% -\DTLformatbvolume -\DTLifbibfieldexists{Volume}{% -\DTLifanybibfieldexists{Number,Address,Editor,Publisher,% -Month,Year}{\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLformatnumberseries -\DTLifbibfieldexists{Number}{% -\DTLifanybibfieldexists{Address,Editor,Publisher,% -Month,Year}{\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLifbibfieldexists{Address}{% -\DTLstartsentencespace -\DTLbibfield{Address}% -\DTLcheckbibfieldendsperiod{Address}% -\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{\DTLaddperiod}% -\DTLformatdate -\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% -\DTLifbibfieldexists{Editor}{\DTLifbibfieldexists{Organization}{% -\DTLstartsentencespace -\DTLbibfield{Organization}% -\DTLcheckbibfieldendsperiod{Organization}% -\DTLifbibfieldexists{Publisher}{% -\DTLaddcomma}{\DTLaddperiod}}{}}{}% -\DTLifbibfieldexists{Publisher}{% -\DTLstartsentencespace -\DTLbibfield{Publisher}% -\DTLcheckbibfieldendsperiod{Publisher}% -\DTLaddperiod -}{}% -}{% no address -\DTLifbibfieldexists{Editor}{% -\DTLifbibfieldexists{Organization}{% -\DTLstartsentencespace -\DTLbibfield{Organization}% -\DTLcheckbibfieldendsperiod{Organization}% -\DTLifanybibfieldexists{Publisher,Month,Year}{% -\DTLaddcomma}{\DTLaddperiod}}{}% -}{}% -\DTLifbibfieldexists{Publisher}{% -\DTLstartsentencespace -\DTLbibfield{Publisher}% -\DTLcheckbibfieldendsperiod{Publisher}% -\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLformatdate -\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% -}% -\DTLifbibfieldexists{Note}{% -\DTLstartsentencespace -\DTLbibfield{Note}% -\DTLcheckbibfieldendsperiod{Note}% -\DTLaddperiod}{}% -}% -% \end{macrocode} -% The format of a technical report. -% \begin{macrocode} -\renewcommand*{\DTLformattechreport}{% -\DTLifbibfieldexists{Author}{\DTLformatauthorlist\DTLaddperiod}{}% -\DTLifbibfieldexists{Title}{% -\DTLstartsentencespace -\DTLbibfield{Title}% -\DTLcheckbibfieldendsperiod{Title}% -\DTLaddperiod}{}% -\DTLifbibfieldexists{Type}{% -\DTLstartsentencespace -\DTLbibfield{Type}% -\DTLcheckbibfieldendsperiod{Type}% -\DTLifbibfieldexists{Number}{~}{}}{}% -\DTLifbibfieldexists{Number}{% -\DTLstartsentencespace -\DTLbibfield{Number}% -\DTLcheckbibfieldendsperiod{Number}% -}{}% -\DTLifanybibfieldexists{Type,Number}{% -\DTLifanybibfieldexists{Institution,Address,Month,Year}{\DTLaddcomma -}{\DTLaddperiod}}{}% -\DTLifbibfieldexists{Institution}{% -\DTLstartsentencespace -\DTLbibfield{Institution}% -\DTLcheckbibfieldendsperiod{Institution}% -\DTLifanybibfieldexists{Address,Month,Year}{\DTLaddcomma -}{\DTLaddperiod}}{}% -\DTLifbibfieldexists{Address}{% -\DTLstartsentencespace -\DTLbibfield{Address}% -\DTLcheckbibfieldendsperiod{Address}% -\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma -}{\DTLaddperiod}}{}% -\DTLformatdate -\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% -\DTLifbibfieldexists{Note}{% -\DTLstartsentencespace -\DTLbibfield{Note}% -\DTLcheckbibfieldendsperiod{Note}% -\DTLaddperiod}{}% -}% -% \end{macrocode} -% The format of an unpublished work. -% \begin{macrocode} -\renewcommand*{\DTLformatunpublished}{% -\DTLifbibfieldexists{Author}{\DTLformatauthorlist\DTLaddperiod}{}% -\DTLifbibfieldexists{Title}{% -\DTLstartsentencespace -\DTLbibfield{Title}% -\DTLcheckbibfieldendsperiod{Title}% -\DTLaddperiod}{}% -\DTLifbibfieldexists{Note}{% -\DTLstartsentencespace -\DTLbibfield{Note}% -\DTLcheckbibfieldendsperiod{Note}% -\DTLifanybibfieldexists{Month,Year}{\DTLaddcomma}{\DTLaddperiod}}{}% -\DTLformatdate -\DTLifanybibfieldexists{Month,Year}{\DTLaddperiod}{}% -}% -% \end{macrocode} -% End of `plain' style. +%\begin{macro}{\Personparent} +% As above, but make the first letter uppercase. % \begin{macrocode} +\newcommand*{\Personparent}[1][anon]{% + \@ifundefined{person@#1@gender}% + {% + \PackageError{person}{Person `#1' has not been defined}{}% + }% + {% + \edef\@gender{\csname person@#1@gender\endcsname}% + \expandafter\expandafter\expandafter\MakeUppercase + \csname\@gender parent\endcsname + }% } % \end{macrocode} %\end{macro} % -%\begin{macro}{\dtlbst@abbrv} -% Define `abbrv' style. This is similar to `plain' except that -% some of the values are abbreviated -% \begin{macrocode} -\newcommand{\dtlbst@abbrv}{% -% \end{macrocode} -% Base this style on `plain': -% \begin{macrocode} -\dtlbst@plain -% \end{macrocode} -% Sets the author name format. -% \begin{macrocode} -\renewcommand*{\DTLformatauthor}[4]{% -\DTLformatabbrvforenames{##4} -\DTLformatvon{##1}% -\DTLformatsurname{##2}% -\DTLformatjr{##3}} -% \end{macrocode} -% Sets the editor name format. -% \begin{macrocode} -\renewcommand*{\DTLformateditor}[4]{% -\DTLformatabbrvforenames{##4} -\DTLformatvon{##1}% -\DTLformatsurname{##2}% -\DTLformatjr{##3}} -% \end{macrocode} -% Sets the monthname format. -% \begin{macrocode} -\let\DTLmonthname\dtl@abbrvmonthname -% \end{macrocode} -% Sets other predefined names: -% \begin{macrocode} -\renewcommand*{\DTLacmcs}{ACM Comput.\ Surv.} -\renewcommand*{\DTLacta}{Acta Inf.} -\renewcommand*{\DTLcacm}{Commun.\ ACM} -\renewcommand*{\DTLibmjrd}{IBM J.\ Res.\ Dev.} -\renewcommand*{\DTLibmsj}{IBM Syst.~J.} -\renewcommand*{\DTLieeese}{IEEE Trans. Softw.\ Eng.} -\renewcommand*{\DTLieeetc}{IEEE Trans.\ Comput.} -\renewcommand*{\DTLieeetcad}{IEEE Trans.\ Comput.-Aided Design -Integrated Circuits} -\renewcommand*{\DTLipl}{Inf.\ Process.\ Lett.} -\renewcommand*{\DTLjacm}{J.~ACM} -\renewcommand*{\DTLjcss}{J.~Comput.\ Syst.\ Sci.} -\renewcommand*{\DTLscp}{Sci.\ Comput.\ Programming} -\renewcommand*{\DTLsicomp}{SIAM J.~Comput.} -\renewcommand*{\DTLtocs}{ACM Trans.\ Comput.\ Syst.} -\renewcommand*{\DTLtods}{ACM Trans.\ Database Syst.} -\renewcommand*{\DTLtog}{ACM Trans.\ Gr.} -\renewcommand*{\DTLtoms}{ACM Trans.\ Math. Softw.} -\renewcommand*{\DTLtoois}{ACM Trans. Office Inf.\ Syst.} -\renewcommand*{\DTLtoplas}{ACM Trans.\ Prog. Lang.\ Syst.} -\renewcommand*{\DTLtcs}{Theoretical Comput.\ Sci.} -% \end{macrocode} -% End of `abbrv' style. +%\begin{macro}{\peopleparent} +% If there is more than one person, \cs{peopleparent} will use +% \cs{pluralparent}, otherwise it will use \cs{personparent}. % \begin{macrocode} +\newcommand*{\peopleparent}{% + \ifnum\c@people>1\relax + \pluralparent + \else + \@get@firstperson{\@thisperson}% + \personparent[\@thisperson]% + \fi } % \end{macrocode} %\end{macro} % -%\begin{macro}{\dtlbst@alpha} -% Define `alpha' style. This is similar to `plain' except that -% the labels are strings rather than numerical. -% \begin{macrocode} -\newcommand{\dtlbst@alpha}{% -% \end{macrocode} -% Base this style on `plain': -% \begin{macrocode} -\dtlbst@plain -% \end{macrocode} -% Set how to format the entire bibliography: -% \begin{macrocode} -\renewenvironment{DTLthebibliography}[2][\boolean{true}]{% -\dtl@createalphabiblabels{##1}{##2}% -\begin{thebibliography}{\@dtl@widestlabel}% -}{\end{thebibliography}}% -% \end{macrocode} -% Set how to start the bibliography entry: -% \begin{macrocode} -\renewcommand*{\DTLbibitem}{% -\expandafter\bibitem\expandafter - [\csname dtl@biblabel@\DBIBcitekey\endcsname]{\DBIBcitekey}}% -\renewcommand*{\DTLmbibitem}[1]{% -\expandafter\bibitem\expandafter - [\csname dtl@biblabel@\DBIBcitekey\endcsname]{##1@\DBIBcitekey}}% -% \end{macrocode} -% \begin{macrocode} -% \end{macrocode} -% End of `alpha' style. +%\begin{macro}{\Peopleparent} +% As above, but make first letter uppercase. % \begin{macrocode} +\newcommand*{\Peopleparent}{% + \ifnum\c@people>1\relax + \expandafter\MakeUppercase\pluralparent + \else + \@get@firstperson{\@thisperson}% + \Personparent[\@thisperson]% + \fi } % \end{macrocode} %\end{macro} % -%\begin{macro}{dtl@createalphabiblabels} -%\begin{definition} -%\cs{dtl@createalphabiblabels}\marg{condition}\marg{db name} -%\end{definition} -% Constructs the alpha style bib labels for the given database. -% (Labels are stored in the control sequence -%\cs{dtl@biblabel@}\meta{citekey}.) This also sets -% \cs{@dtl@widestlabel} to the widest label. +%\begin{macro}{\personsibling} +% Display this person's relationship to their siblings (i.e.\ +% brother or sister). % \begin{macrocode} -\newcommand*{\dtl@createalphabiblabels}[2]{% -\dtl@message{Creating bib labels}% -\begingroup -\gdef\@dtl@widestlabel{}% -\dtl@widest=0pt\relax -\DTLforeachbibentry[#1]{#2}{% -\dtl@message{\DBIBcitekey}% -\DTLifbibfieldexists{Author}{% - \dtl@listgetalphalabel{\@dtl@thislabel}{\@dtl@key@Author}% -}{% -\DTLifbibfieldexists{Editor}{% - \dtl@listgetalphalabel{\@dtl@thislabel}{\@dtl@key@Editor}% - }{% - \DTLifbibfieldexists{Key}{% - \expandafter\dtl@get@firstthree\expandafter - {\@dtl@key@Key}{\@dtl@thislabel}% - }{% - \DTLifbibfieldexists{Organization}{% - \expandafter\dtl@get@firstthree\expandafter - {\@dtl@key@Organization}{\@dtl@thislabel}% - }{% - \expandafter\dtl@get@firstthree\expandafter - {\DBIBentrytype}{\@dtl@thislabel}% - }% - }}}% -\DTLifbibfieldexists{Year}{}{\DTLifbibfieldexists{CrossRef}{% -\DTLgetvalueforkey{\@dtl@key@Year}{Year}{#2}{CiteKey}{% -\@dtl@key@CrossRef}}{}}% -\DTLifbibfieldexists{Year}{% -\expandafter\dtl@get@yearsuffix\expandafter{\@dtl@key@Year}% -\expandafter\toks@\expandafter{\@dtl@thislabel}% -\expandafter\@dtl@toks\expandafter{\@dtl@year}% -\edef\@dtl@thislabel{\the\toks@\the\@dtl@toks}% -}{}% -\let\@dtl@s@thislabel=\@dtl@thislabel -\@onelevel@sanitize\@dtl@s@thislabel -\@ifundefined{c@biblabel@\@dtl@s@thislabel}{% -\newcounter{biblabel@\@dtl@s@thislabel}% -\setcounter{biblabel@\@dtl@s@thislabel}{1}% -\expandafter\edef\csname @dtl@bibfirst@\@dtl@s@thislabel\endcsname{% -\DBIBcitekey}% -\expandafter\global -\expandafter\let\csname dtl@biblabel@\DBIBcitekey\endcsname= - \@dtl@thislabel -}{% -\expandafter\ifnum\csname c@biblabel@\@dtl@s@thislabel\endcsname=1\relax - \expandafter\let\expandafter\@dtl@tmp - \csname @dtl@bibfirst@\@dtl@s@thislabel\endcsname - \expandafter\protected@xdef\csname dtl@biblabel@\@dtl@tmp\endcsname{% - \@dtl@thislabel a}% -\fi -\stepcounter{biblabel@\@dtl@s@thislabel}% -\expandafter\protected@xdef\csname dtl@biblabel@\DBIBcitekey\endcsname{% - \@dtl@thislabel\alph{biblabel@\@dtl@s@thislabel}}% -}% -\settowidth{\dtl@tmplength}{% - \csname dtl@biblabel@\DBIBcitekey\endcsname}% -\ifdim\dtl@tmplength>\dtl@widest - \dtl@widest=\dtl@tmplength - \expandafter\global\expandafter\let\expandafter\@dtl@widestlabel - \expandafter=\csname dtl@biblabel@\DBIBcitekey\endcsname -\fi -}% -\endgroup +\newcommand*{\personsibling}[1][anon]{% + \@ifundefined{person@#1@gender}% + {% + \PackageError{person}{Person `#1' has not been defined}{}% + }% + {% + \edef\@gender{\csname person@#1@gender\endcsname}% + \csname\@gender sibling\endcsname + }% } % \end{macrocode} %\end{macro} % -%\begin{macro}{\dtl@listgetalphalabel} -% Determine the alpha style label from a list of authors/editors -% (the first argument must be a control sequence (in which the -% label is stored), the second argument must be the list of names.) +%\begin{macro}{\Personsibling} +% Display this person's relationship to their siblings (i.e.\ +% brother or sister). % \begin{macrocode} -\newcommand*{\dtl@listgetalphalabel}[2]{% -\@dtl@authorcount=0\relax -\@for\@dtl@author:=#2\do{% -\advance\@dtl@authorcount by 1\relax}% -\ifnum\@dtl@authorcount=1\relax - \expandafter\dtl@getsinglealphalabel#2{#1}\relax -\else +\newcommand*{\Personsibling}[1][anon]{% + \@ifundefined{person@#1@gender}% {% - \xdef#1{}% - \@dtl@tmpcount=0\relax - \def\DTLafterinitials{}\def\DTLbetweeninitials{}% - \def\DTLafterinitialbeforehyphen{}\def\DTLinitialhyphen{}% - \@for\@dtl@author:=#2\do{% - \expandafter\dtl@getauthorinitial\@dtl@author - \expandafter\toks@\expandafter{\@dtl@tmp}% - \expandafter\@dtl@toks\expandafter{#1}% - \xdef#1{\the\@dtl@toks\the\toks@}% - \advance\@dtl@tmpcount by 1\relax - \ifnum\@dtl@tmpcount>2\relax\@endfortrue\fi - }}% -\fi + \PackageError{person}{Person `#1' has not been defined}{}% + }% + {% + \edef\@gender{\csname person@#1@gender\endcsname}% + \expandafter\expandafter\expandafter\MakeUppercase + \csname\@gender sibling\endcsname + }% } % \end{macrocode} %\end{macro} -% Get author's initial (stores in \cs{@dtl@tmp}): -% \begin{macrocode} -\newcommand*{\dtl@getauthorinitial}[4]{% -\def\@dtl@vonpart{#1}% -\ifx\@dtl@vonpart\@empty - \DTLstoreinitials{#2}{\@dtl@tmp}% -\else - \DTLstoreinitials{#1 #2}{\@dtl@tmp}% -\fi} -% \end{macrocode} -% Get label for single author (last argument is control sequence -% in which to store the label): -% \begin{macrocode} -\newcommand*{\dtl@getsinglealphalabel}[5]{% -\def\@dtl@vonpart{#1}% -\ifx\@dtl@vonpart\@empty - \DTLifSubString{#2}{-}{% - {\def\DTLafterinitials{}\def\DTLbetweeninitials{}% - \def\DTLafterinitialbeforehyphen{}% - \def\DTLinitialhyphen{}% - \DTLstoreinitials{#2}{\@dtl@tmp}\global\let#5=\@dtl@tmp}% - }{% - \dtl@getfirstthree{#5}#2{}{}{}{}\@nil - } -\else - {\def\DTLafterinitials{}\def\DTLbetweeninitials{}% - \def\DTLafterinitialbeforehyphen{}% - \def\DTLinitialhyphen{}% - \DTLstoreinitials{#1 #2}{\@dtl@tmp}\global\let#5=\@dtl@tmp}% -\fi -} -% \end{macrocode} -%Get first three letters from the given string: -% \begin{macrocode} -\def\dtl@getfirstthree#1#2#3#4#5\@nil{% - \def#1{#2#3#4}% -} -\newcommand*{\dtl@get@firstthree}[2]{% -\dtl@getfirstthree#2#1{}{}{}{}{}\@nil} -% \end{macrocode} -%Get year suffix: +%\begin{macro}{\peoplesibling} +% If there is more than one person, \cs{peoplesibling} will use +% \cs{malesiblings} (if all male), \cs{femalesiblings} (if all +% female) or \cs{pluralsibling} (if mixed), otherwise it will use +% \cs{personsibling}. % \begin{macrocode} -\newcommand*{\dtl@get@yearsuffix}[1]{% -\dtl@getyearsuffix#1\@nil\relax\relax} - -\def\dtl@getyearsuffix#1#2#3{% -\def\@dtl@argi{#1}\def\@dtl@argii{#2}% -\def\@dtl@argiii{#3}% -\ifx\@dtl@argi\@nnil - \def\@dtl@year{}% - \let\@dtl@donext=\relax -\else - \ifx\@dtl@argii\@nnil - \dtl@ifsingle{#1}{% - \def\@dtl@year{#1}% - \let\@dtl@donext=\relax - }{% - \def\@dtl@donext{\dtl@getyearsuffix#1#2#3}% - }% +\newcommand*{\peoplesibling}{% + \ifnum\c@people>1\relax + \ifallmale + {\malesiblings}% + {\ifallfemale{\femalesiblings}{\pluralsibling}}% \else - \ifx\@dtl@argiii\@nnil - \dtl@ifsingle{#1}{% - \dtl@ifsingle{#2}{% - \def\@dtl@year{#1#2}% - \let\@dtl@donext=\relax - }{% - \def\@dtl@donext{\dtl@getyearsuffix#2#3}% - }% - }{% - \def\@dtl@donext{\dtl@getyearsuffix#2#3}% - }% - \else - \def\@dtl@donext{\dtl@getyearsuffix{#2}{#3}}% - \fi - \fi -\fi -\@dtl@donext + \@get@firstperson{\@thisperson}% + \personsibling[\@thisperson]% + \fi } % \end{macrocode} -% -%\begin{macro}{\DTLbibliographystyle} -%\begin{definition} -%\cs{DTLbibliographystyle}\marg{style} -%\end{definition} -% Sets the bibliography style. -% \begin{macrocode} -\newcommand*{\DTLbibliographystyle}[1]{% -\@ifundefined{dtlbst@#1}{\PackageError{databib}{Unknown -bibliography style `#1'}{}}{\csname dtlbst@#1\endcsname}} -% \end{macrocode} %\end{macro} -%Set the default bibliography style: -% \begin{macrocode} -\DTLbibliographystyle{\dtlbib@style} -% \end{macrocode} % -%\subsection{Multiple Bibliographies} -% In order to have multiple bibliographies, there needs to be -% an aux file for each bibliography. The main bibliography is in -% \cs{jobname}.aux, but need to provide a means of creating -% additional aux files. -%\begin{macro}{\DTLmultibibs} -%\begin{definition} -%\cs{DTLmultibibs}\marg{list} -%\end{definition} -%\changes{1.01}{2007/08/22}{new} -% This creates an auxiliary file for each name in \meta{list}. -% For example, "\DTLmultibibs{foo,bar}" will create the files -% "foo.aux" and "bar.aux". -% \begin{macrocode} -\newcommand*{\DTLmultibibs}[1]{% -\@for\@dtl@af:=#1\do{% -\@ifundefined{dtl@aux@\@dtl@af}{% -\expandafter\newwrite\csname dtl@aux@\@dtl@af\endcsname -\expandafter\immediate -\expandafter\openout\csname dtl@aux@\@dtl@af\endcsname=\@dtl@af.aux -\expandafter\def\csname b@\@dtl@af @*\endcsname{}% -}{% -\PackageError{databib}{Can't create auxiliary file `\@dtl@af.aux', -\expandafter\string\csname dtl@aux@\@dtl@af\endcsname\space -already exists}{}}}} -% \end{macrocode} -% Can only be used in the preamble: -% \begin{macrocode} -\@onlypreamble{\DTLmultibibs} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\DTLcite} -%\begin{definition} -%\cs{DTLcite}\oarg{text}\marg{mbib}\marg{labels} -%\end{definition} -% This is similar to \cs{cite}\oarg{text}\marg{labels}, except -% 1) the cite information is written to the auxiliary file -% associated with the multi-bib \meta{mbib} (which must be named -% in \cs{DTLmultibibs}) and 2) the cross referencing label is -% constructed from \meta{mbib} and \meta{label} to allow for -% the same citation to appear in multiple bibliographies. -% \begin{macrocode} -\newcommand*{\DTLcite}{\@ifnextchar[{\@tempswatrue \dtl@citex -}{\@tempswafalse \dtl@citex[]}} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\dtl@citex} +%\begin{macro}{\persongender} +% Displays the given person's gender (\cs{malename} or +% \cs{femalename}). % \begin{macrocode} -\def\dtl@citex[#1]#2#3{% -\leavevmode\let\@citea\@empty -\@cite{\@for\@citeb:=#3\do{\@citea - \def\@citea{,\penalty \@m \ }% - \edef\@citeb{\expandafter\@firstofone\@citeb\@empty}% - \if@filesw - \@ifundefined{dtl@aux@#2}{% - \PackageError{databib}{multibib `#2' not defined}{% - You need to define `#2' in \string\DTLmutlibibs}% - }{% - \expandafter\immediate - \expandafter\write\csname dtl@aux@#2\endcsname{% - \string\citation{\@citeb}}% - }% - \fi - \@ifundefined{b@#2@\@citeb}{% - \hbox{\reset@font\bfseries ?}% - \G@refundefinedtrue - \@latex@warning{Citation `\@citeb ' on page \thepage \space - undefined}% - }{% - \@cite@ofmt{\csname b@#2@\@citeb \endcsname }% - }% -}}{#1}% +\newcommand*{\persongender}[1]{% + \ifpersonmale{#1}{\malename}{\femalename}% } % \end{macrocode} %\end{macro} -%\begin{macro}{\DTLnocite} -%\begin{definition} -%\cs{DTLnocite}\marg{mbib}\marg{key list} -%\end{definition} -% As \cs{nocite} but uses the aux file associated with \meta{mbib} -% which must have been defined using \cs{DTLmultibibs}. +% +%\section{Extracting Information} +% +%\begin{macro}{\getpersongender} +% Gets person's gender and stores in first argument which must be +% a control sequence. % \begin{macrocode} -\newcommand*{\DTLnocite}[2]{% -\@ifundefined{dtl@aux@#1}{% - \PackageError{databib}{multibib `#1' not defined}{% - You need to define `#1' in \string\DTLmutlibibs}% -}{% - \@bsphack - \ifx\@onlypreamble\document - \@for\@citeb:=#2\do{% - \edef\@citeb{\expandafter\@firstofone\@citeb}% - \if@filesw - \expandafter\immediate - \expandafter\write\csname dtl@aux@#1\endcsname{% - \string\citation{\@citeb}}% - \fi - \@ifundefined{b@#1@\@citeb}{% - \G@refundefinedtrue - \@latex@warning{Citation `\@citeb ' undefined}}{}% - }% - \else - \@latex@error{Cannot be used in preamble}\@eha - \fi - \@esphack -}% +\newcommand*{\getpersongender}[2]{% + \ifpersonmale{#2}{\let#1\malename}{\let#1\femalename}% } % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLloadmbbl} -%\begin{definition} -%\cs{DTLloadmbib}\marg{mbib}\marg{db name}\marg{bib list} -%\end{definition} +%\begin{macro}{\getpersonname} +% Gets person's name and stores in first argument which must be +% a control sequence. % \begin{macrocode} -\newcommand*{\DTLloadmbbl}[3]{% -\@ifundefined{dtl@aux@#1}{% - \PackageError{databib}{multibib `#1' not defined}{% - You need to define `#1' in \string\DTLmutlibibs}% -}{% - \if@filesw - \expandafter\immediate\expandafter - \write\csname dtl@aux@#1\endcsname{\string\bibstyle{databib}}% - \expandafter\immediate\expandafter - \write\csname dtl@aux@#1\endcsname{\string\bibdata{#3}}% - \fi - \DTLnewdb{#2}% - \edef\DTLBIBdbname{#2}% - \@input@{#1.bbl}% -}% +\newcommand*{\getpersonname}[2]{% + \ifpersonexists{#2}% + {% + \expandafter\let\expandafter#1\csname person@#2@name\endcsname + }% + {% + \PackageError{person}{Person `#2' doesn't exist}{}% + }% } % \end{macrocode} %\end{macro} -%\begin{definition} -%\cs{DTLmbibliography}\oarg{condition}\marg{mbib name}\marg{bib dbname} -%\end{definition} -% Displays the bibliography for the database \meta{bib dbname} -% which must have previously been loaded using -% \cs{DTLloadmbbl}, where \meta{mbib name} must be listed -% in \cs{DTLmultibibs}. -%\begin{macro}{\DTLmbibliography} +% +%\begin{macro}{\getpersonfullname} +% Gets person's full name and stores in first argument which must be +% a control sequence. % \begin{macrocode} -\newcommand*{\DTLmbibliography}[3][\boolean{true}]{% -\begin{DTLthebibliography}[#1]{#3}% -\DTLforeachbibentry[#1]{#3}{% -\DTLmbibitem{#2} \DTLformatbibentry \DTLendbibitem -}% -\end{DTLthebibliography}% +\newcommand*{\getpersonfullname}[2]{% + \ifpersonexists{#2}% + {% + \expandafter + \let\expandafter#1\csname person@#2@fullname\endcsname + }% + {% + \PackageError{person}{Person `#2' doesn't exist}{}% + }% } % \end{macrocode} %\end{macro} %\iffalse % \begin{macrocode} -%</databib.sty> +%</person.sty> % \end{macrocode} %\fi %\iffalse @@ -24060,13 +18768,7 @@ already exists}{}}}} %<*databib.bst> % \end{macrocode} %\fi -%\iffalse -% \begin{macrocode} % \begin{macrocode} -% Bibliography style `databib' -% This style is provided for use with the databib package. -% v1.01 (2007/08/22) - added "file" field - ENTRY { address author @@ -24096,6 +18798,7 @@ ENTRY url abstract file + eprints } {} { label } @@ -24113,25 +18816,15 @@ STRINGS { s t } FUNCTION {output.nonnull} { 's := -% output.state mid.sentence = -% { "%" * write$ -% newline$ -% } -% { output.state after.block = -% { add.period$ write$ -% newline$ -% } - %{ output.state before.all = { - "%" * write$ + "%" * write$ newline$ } - { newline$ + { newline$ %add.period$ " " * write$ } - if$ -% } + if$ % if$ % mid.sentence 'output.state := % } @@ -24184,8 +18877,8 @@ FUNCTION {new.sentence} { output.state after.block = 'skip$ { output.state before.all = - 'skip$ - { after.sentence 'output.state := } +'skip$ +{ after.sentence 'output.state := } if$ } if$ @@ -24290,10 +18983,10 @@ FUNCTION {format.names} { } if$ nameptr #1 > - { +{ t * - } - 't +} +'t if$ nameptr #1 + 'nameptr := namesleft #1 - 'namesleft := @@ -24303,7 +18996,7 @@ FUNCTION {format.names} } FUNCTION {format.authors} -{ +{ author empty$ { "" } { author @@ -24335,7 +19028,7 @@ FUNCTION {format.title} FUNCTION {format.howpublished} { howpublished empty$ { "" } - { + { howpublished "\DTLnewbibitem {HowPublished}" swap$ group * } @@ -24345,7 +19038,7 @@ FUNCTION {format.howpublished} FUNCTION {format.organization} { organization empty$ { "" } - { + { organization "\DTLnewbibitem {Organization}" swap$ group * } @@ -24355,7 +19048,7 @@ FUNCTION {format.organization} FUNCTION {format.institution} { institution empty$ { "" } - { + { institution "\DTLnewbibitem {Institution}" swap$ group * } @@ -24365,7 +19058,7 @@ FUNCTION {format.institution} FUNCTION {format.key} { key empty$ { "" } - { + { key "\DTLnewbibitem {Key}" swap$ group * } @@ -24375,7 +19068,7 @@ FUNCTION {format.key} FUNCTION {format.note} { note empty$ { "" } - { + { note "\DTLnewbibitem {Note}" swap$ group * } @@ -24385,7 +19078,7 @@ FUNCTION {format.note} FUNCTION {format.isbn} { isbn empty$ { "" } - { + { isbn "\DTLnewbibitem {ISBN}" swap$ group * } @@ -24395,7 +19088,7 @@ FUNCTION {format.isbn} FUNCTION {format.doi} { doi empty$ { "" } - { + { doi "\DTLnewbibitem {DOI}" swap$ group * } @@ -24405,7 +19098,7 @@ FUNCTION {format.doi} FUNCTION {format.pubmed} { pubmed empty$ { "" } - { + { pubmed "\DTLnewbibitem {PubMed}" swap$ group * } @@ -24415,7 +19108,7 @@ FUNCTION {format.pubmed} FUNCTION {format.abstract} { abstract empty$ { "" } - { + { abstract "\DTLnewbibitem {Abstract}" swap$ group * } @@ -24425,7 +19118,7 @@ FUNCTION {format.abstract} FUNCTION {format.url} { url empty$ { "" } - { + { url "\DTLnewbibitem {Url}" swap$ group * } @@ -24435,17 +19128,27 @@ FUNCTION {format.url} FUNCTION {format.file} { file empty$ { "" } - { + { file "\DTLnewbibitem {File}" swap$ group * } if$ } +FUNCTION {format.eprints} +{ eprints empty$ + { "" } + { + eprints + "\DTLnewbibitem {Eprints}" swap$ group * + } + if$ +} + FUNCTION {format.address} { address empty$ { "" } - { + { address "\DTLnewbibitem {Address}" swap$ group * } @@ -24455,7 +19158,7 @@ FUNCTION {format.address} FUNCTION {format.school} { school empty$ { "" } - { + { school "\DTLnewbibitem {School}" swap$ group * } @@ -24465,7 +19168,7 @@ FUNCTION {format.school} FUNCTION {format.publisher} { publisher empty$ { "" } - { + { publisher "\DTLnewbibitem {Publisher}" swap$ group * } @@ -24477,21 +19180,21 @@ FUNCTION {n.dashify} "" { t empty$ not } { t #1 #1 substring$ "-" = - { t #1 #2 substring$ "--" = not - { "--" * - t #2 global.max$ substring$ 't := - } - { { t #1 #1 substring$ "-" = } - { "-" * - t #2 global.max$ substring$ 't := - } - while$ - } - if$ - } - { t #1 #1 substring$ * - t #2 global.max$ substring$ 't := - } +{ t #1 #2 substring$ "--" = not + { "--" * + t #2 global.max$ substring$ 't := + } + { { t #1 #1 substring$ "-" = } +{ "-" * + t #2 global.max$ substring$ 't := +} + while$ + } + if$ +} +{ t #1 #1 substring$ * + t #2 global.max$ substring$ 't := +} if$ } while$ @@ -24500,24 +19203,24 @@ FUNCTION {n.dashify} FUNCTION {format.date} { year empty$ { month empty$ - { "" } - { "there's a month but no year in " cite$ * warning$ +{ "" } +{ "there's a month but no year in " cite$ * warning$ "\DTLnewbibitem {Month}" * - month group - } + month group +} if$ } { month empty$ - { } - { "\DTLnewbibitem {Month}{" * month * "}" * } +{ } +{ "\DTLnewbibitem {Month}{" * month * "}" * } if$ - "\DTLnewbibitem {Year}{" * year * "}" + "\DTLnewbibitem {Year}{" * year * "}" } if$ } FUNCTION {format.btitle} -{ title +{ title "\DTLnewbibitem {Title}{" swap$ * "}" * } @@ -24540,11 +19243,11 @@ FUNCTION {either.or.check} FUNCTION {format.bvolume} { volume empty$ { "" } - { + { "\DTLnewbibitem {Volume}{" volume * "}" * series empty$ - 'skip$ - { +'skip$ +{ "\DTLnewbibitem {Series}" * series group * } if$ @@ -24556,20 +19259,20 @@ FUNCTION {format.bvolume} FUNCTION {format.number.series} { volume empty$ { number empty$ - { +{ %series field.or.null group series empty$ { "" } { "\DTLnewbibitem {Series}" * series group } if$ } - { +{ "\DTLnewbibitem {Number}" number group * - series empty$ - { "there's a number but no series in " cite$ * warning$ } - { "\DTLnewbibitem {Series}{" * series * "}" * } - if$ - } + series empty$ + { "there's a number but no series in " cite$ * warning$ } + { "\DTLnewbibitem {Series}{" * series * "}" * } + if$ +} if$ } { "" } @@ -24579,9 +19282,9 @@ FUNCTION {format.number.series} FUNCTION {format.edition} { edition empty$ { "" } - { + { "\DTLnewbibitem {Edition}" - edition "l" change.case$ group * + edition "l" change.case$ group * } if$ } @@ -24600,8 +19303,8 @@ FUNCTION {multi.page.check} swap$ duplicate$ "," = swap$ "+" = or or - { #1 'multiresult := } - { t #2 global.max$ substring$ 't := } +{ #1 'multiresult := } +{ t #2 global.max$ substring$ 't := } if$ } while$ @@ -24612,9 +19315,9 @@ FUNCTION {format.pages} { pages empty$ { "" } { pages multi.page.check - { "\DTLnewbibitem {Pages}" pages n.dashify +{ "\DTLnewbibitem {Pages}" pages n.dashify group * } - { "\DTLnewbibitem {Pages}" pages +{ "\DTLnewbibitem {Pages}" pages group *} if$ } @@ -24633,16 +19336,16 @@ FUNCTION {format.vol.num.pages} 'skip$ { "\DTLnewbibitem {Number}{" number * "}\relax " * * volume empty$ - { "there's a number but no volume in " cite$ * warning$ } - 'skip$ +{ "there's a number but no volume in " cite$ * warning$ } +'skip$ if$ } if$ pages empty$ 'skip$ { duplicate$ empty$ - { pop$ format.pages } - { "\DTLnewbibitem {Pages}" * pages n.dashify group * } +{ pop$ format.pages } +{ "\DTLnewbibitem {Pages}" * pages n.dashify group * } if$ } if$ @@ -24652,13 +19355,13 @@ FUNCTION {format.chapter.pages} { chapter empty$ 'format.pages { type empty$ - { "\DTLnewbibitem {Type}{chapter}" } - { "\DTLnewbibitem {Type}" type "l" change.case$ group *} +{ "\DTLnewbibitem {Type}{chapter}" } +{ "\DTLnewbibitem {Type}" type "l" change.case$ group *} if$ "\DTLnewbibitem {Chapter}{" * chapter * "}" * pages empty$ - 'skip$ - { format.pages * } +'skip$ +{ format.pages * } if$ } if$ @@ -24667,11 +19370,11 @@ FUNCTION {format.chapter.pages} FUNCTION {format.in.ed.booktitle} { booktitle empty$ { "" } - { - "\DTLnewbibitem {BookTitle}" booktitle group * + { + "\DTLnewbibitem {BookTitle}" booktitle group * editor empty$ {} - { + { "\DTLnewbibitem {Editor}{" * editor format.names * } @@ -24716,11 +19419,11 @@ FUNCTION {format.tr.number} FUNCTION {format.article.crossref} { key empty$ { journal empty$ - { "need key or journal for " cite$ * " to crossref " * crossref * - warning$ - "" - } - { +{ "need key or journal for " cite$ * " to crossref " * crossref * + warning$ + "" +} +{ "\DTLnewbibitem {Journal}" journal group * } if$ @@ -24734,27 +19437,13 @@ FUNCTION {format.article.crossref} FUNCTION {format.crossref.editor} { format.editors -% editor #1 "{vv~}{ll}" format.name$ -% editor num.names$ duplicate$ -% #2 > -% { pop$ " et~al." * } -% { #2 < -% 'skip$ -% { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = -% { " et~al." * } -% { " and " * editor #2 "{vv~}{ll}" format.name$ * } -% if$ -% } -% if$ -% } -% if$ } FUNCTION {format.book.crossref} { volume empty$ { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ } - { + { "\DTLnewbibitem {Volume}" volume group * } @@ -24763,18 +19452,18 @@ FUNCTION {format.book.crossref} editor field.or.null author field.or.null = or { key empty$ - { series empty$ - { "need editor, key, or series for " cite$ * " to crossref " * - crossref * warning$ - "" * - } - { - "\DTLnewbibitem {Series}{" * series * +{ series empty$ + { "need editor, key, or series for " cite$ * " to crossref " * + crossref * warning$ + "" * + } + { + "\DTLnewbibitem {Series}{" * series * "}" * } - if$ - } - { "" + if$ +} +{ "" } if$ } @@ -24790,20 +19479,20 @@ FUNCTION {format.incoll.inproc.crossref} editor field.or.null author field.or.null = or { key empty$ - { booktitle empty$ - { "need editor, key, or booktitle for " cite$ * " to crossref " * - crossref * warning$ - "" - } - { "\DTLnewbibitem {BookTitle}{" booktitle * "}" * } - if$ - } - { "" } +{ booktitle empty$ + { "need editor, key, or booktitle for " cite$ * " to crossref " * + crossref * warning$ + "" + } + { "\DTLnewbibitem {BookTitle}{" booktitle * "}" * } + if$ +} +{ "" } if$ } { "\DTLnewbibitem {Editor}{" * - editor format.names + editor format.names } if$ "\DTLnewbibitem {CrossRef}{" * crossref * "}" * @@ -24813,7 +19502,7 @@ FUNCTION {article} { output.bibitem "\DTLnewbibitem {EntryType}{article}%" write$ newline$ - format.authors "author" + format.authors "author" output.check format.title "title" output.check new.block @@ -24848,9 +19537,9 @@ FUNCTION {book} { format.editors "author and editor" output.check } { format.authors output.nonnull crossref missing$ - { "author and editor" editor either.or.check +{ "author and editor" editor either.or.check } - 'skip$ +'skip$ if$ } if$ @@ -24913,8 +19602,8 @@ FUNCTION {inbook} { format.editors "author and editor" output.check } { format.authors output.nonnull crossref missing$ - { "author and editor" editor either.or.check } - 'skip$ +{ "author and editor" editor either.or.check } +'skip$ if$ } if$ @@ -24992,15 +19681,15 @@ FUNCTION {inproceedings} format.number.series output format.pages output address empty$ - { %organization publisher new.sentence.checkb - format.organization write$ - format.publisher output - } - { format.address write$ - new.sentence - format.organization output - format.publisher output - } +{ %organization publisher new.sentence.checkb + format.organization write$ + format.publisher output +} +{ format.address write$ + new.sentence + format.organization output + format.publisher output +} if$ format.date "year" output.check } @@ -25028,10 +19717,10 @@ FUNCTION {manual} newline$ author empty$ { organization empty$ - 'skip$ - { format.organization output - format.address output - } +'skip$ +{ format.organization output + format.address output +} if$ } { format.authors output } @@ -25040,10 +19729,10 @@ FUNCTION {manual} format.btitle "title" output.check author empty$ { organization empty$ - { address new.block.checka - address output - } - 'skip$ +{ address new.block.checka + address output +} +'skip$ if$ } { %organization address new.block.checkb @@ -25152,10 +19841,10 @@ FUNCTION {proceedings} format.number.series output address empty$ { editor empty$ - { publisher new.sentence.checka } - { organization publisher new.sentence.checkb - format.organization output - } +{ publisher new.sentence.checka } +{ organization publisher new.sentence.checkb + format.organization output +} if$ format.publisher output format.date "year" output.check @@ -25164,8 +19853,8 @@ FUNCTION {proceedings} format.date "year" output.check new.sentence editor empty$ - 'skip$ - { format.organization output } +'skip$ +{ format.organization output } if$ format.publisher output } @@ -25338,1136 +20027,10 @@ FUNCTION {end.bib} EXECUTE {end.bib} % \end{macrocode} -% \end{macrocode} -%\fi %\iffalse % \begin{macrocode} %</databib.bst> % \end{macrocode} %\fi -%\iffalse -% \begin{macrocode} -%<*person.sty> -% \end{macrocode} -%\fi -%\section{person.sty}\label{sec:code:person} -%\subsection{Package Declaration} -% Package identification: -% \begin{macrocode} -\NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{person}[2009/11/15 v1.01 (NLCT)] -% \end{macrocode} -% Requires the \sty{ifthen} package. -% \begin{macrocode} -\RequirePackage{ifthen} -\RequirePackage{datatool} -% \end{macrocode} -%\subsection{Defining People} -%\begin{counter}{people} -% Keep count of the number of people who have been defined: -% \begin{macrocode} -\newcounter{people} -% \end{macrocode} -%\end{counter} -%\begin{counter}{person} -% Temporary counter -% \begin{macrocode} -\newcounter{person} -% \end{macrocode} -%\end{counter} -%\begin{macro}{\@people@list} -% Keep a list of labels for each person who has been defined: -% \begin{macrocode} -\newcommand*{\@people@list}{,} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\@get@firstperson} -% Get the first person's name in \cs{@people@list}, and store in -% the argument (which must be a control sequence.) -% \begin{macrocode} -\newcommand*{\@get@firstperson}[1]{% - \expandafter\@@get@firstperson\@people@list,\@nil{#1}} - \def\@@get@firstperson,#1,#2\@nil#3{% - \def#3{#1}% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\malelabels} -% List of labels that can be used to indicate that a person is -% male (when defining a person using \cs{newperson}). -% \begin{macrocode} -\newcommand*{\malelabels}{male,Male,MALE,M,m} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\addmalelabel} -% Adds a label to the list of male labels. -% \begin{macrocode} -\newcommand*{\addmalelabel}[1]{% - \expandafter\@dtl@toksA\expandafter{\malelabels}% - \expandafter\@dtl@toksB\expandafter{#1}% - \edef\malelabels{\the\@dtl@toksA,\the\@dtl@toksB}% -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\addfemalelabel} -% Adds a label to the list of female labels. -% \begin{macrocode} -\newcommand*{\addfemalelabel}[1]{% - \expandafter\@dtl@toksA\expandafter{\femalelabels}% - \expandafter\@dtl@toksB\expandafter{#1}% - \edef\femalelabels{\the\@dtl@toksA,\the\@dtl@toksB}% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\femalelabels} -% List of labels that can be used to indicate that a person is -% female (when defining a person using \cs{newperson}). -% \begin{macrocode} -\newcommand*{\femalelabels}{female,Female,FEMALE,F,f} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\ifmalelabel} -% Determines if first argument is contained in the list of male -% labels. (One level expansion is performed on the first object -% in first argument.) -% If true does second argument, otherwise does third argument. -% \begin{macrocode} -\newcommand{\ifmalelabel}[3]{% - \expandafter\DTLifinlist\expandafter{#1}{\malelabels}{#2}{#3}% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\iffemalelabel} -% Determines if first argument is contained in the list of female -% labels. (One level expansion is performed on the first object -% in first argument.) -% If true does second argument, otherwise does third argument. -% \begin{macrocode} -\newcommand{\iffemalelabel}[3]{% - \expandafter\DTLifinlist\expandafter{#1}{\femalelabels}{#2}{#3}% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\newperson} -% Define a new person. The optional argument specifies a label -% with which to refer to that person. If omitted, \texttt{anon} -% is used. If more than one person is defined, the optional -% argument will be required to specify a unique label. The -% compulsory arguments are the person's full name, their -% familiar name and their gender. -% \begin{macrocode} -\newcommand*{\newperson}[4][anon]{% - \@ifundefined{person@#1@name}% - {% - \ifmalelabel{#4}% - {% - \expandafter\gdef\csname person@#1@gender\endcsname{male}% - }% - {% - \iffemalelabel{#4}% - {% - \expandafter\gdef\csname person@#1@gender\endcsname{female}% - }% - {% - \PackageError{person}{Unknown gender `#4' for person - `#1'}{Allowed gender labels are: \malelabels\space or - \femalelabels}% - \@namedef{person@#1@gender}{other}% - }% - }% - \expandafter - \protected@xdef\csname person@#1@fullname\endcsname{#2}% - \expandafter - \protected@xdef\csname person@#1@name\endcsname{#3}% - \protected@xdef\@people@list{\@people@list#1,}% - \stepcounter{people}% - }% - {% - \PackageError{person}{Person `#1' has already been defined}{}% - }% -} -% \end{macrocode} -%\end{macro} -% -%\subsection{Remove People} -% -%\begin{macro}{\removeperson} -% Removes person identified by their label from the list. -% \begin{macrocode} -\newcommand*{\removeperson}[1][anon]{% - \edef\@person@label{#1}% - \expandafter\@removeperson\expandafter{\@person@label}% -} -% \end{macrocode} -% The label has to be full expanded for the internal command. -% \begin{macrocode} -\newcommand*{\@removeperson}[1]{% - \ifpersonexists{#1}% - {% -% \end{macrocode} -% Remove label from list of people. -% \begin{macrocode} - \def\@remove@person##1,#1,##2\@nil{% - \def\@prsn@pre{##1}\def\@prsn@post{##2}}% - \expandafter\@remove@person\@people@list\@nil - \xdef\@people@list{\@prsn@pre,\@prsn@post}% -% \end{macrocode} -% Decrement number of people: -% \begin{macrocode} - \addtocounter{people}{-1}% -% \end{macrocode} -% Undefine associated control sequences: -% \begin{macrocode} - \expandafter\global\expandafter - \let\csname person@#1@name\endcsname\undefined - \expandafter\global\expandafter - \let\csname person@#1@fullname\endcsname\undefined - \expandafter\global\expandafter - \let\csname person@#1@gender\endcsname\undefined - }% - {% - \PackageError{person}{Can't remove person `#1': no such - person}{}% - }% -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\removepeople} -% Removes the people listed. -% \begin{macrocode} -\newcommand*{\removepeople}[1]{% - \@for\@thisperson:=#1\do{% - \ifx\@thisperson\@empty - \else - \expandafter\removeperson\expandafter[\@thisperson]% - \fi - }% -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\removeallpeople} -% Removes everyone. -% \begin{macrocode} -\newcommand*{\removeallpeople}{% - \@for\@thisperson:=\@people@list\do{% - \expandafter\global\expandafter - \let\csname person@\@thisperson @name\endcsname\undefined - \expandafter\global\expandafter - \let\csname person@\@thisperson @fullname\endcsname\undefined - \expandafter\global\expandafter - \let\csname person@\@thisperson @gender\endcsname\undefined - }% - \setcounter{people}{0}% - \gdef\@people@list{,}% -} -% \end{macrocode} -%\end{macro} -% -%\subsection{Conditionals and Loops} -%\begin{macro}{\ifpersonexists} -% If person whose label is given by the first argument exists, then -% do the second argument otherwise do third argument. -% \begin{macrocode} -\newcommand{\ifpersonexists}[3]{% - \@ifundefined{person@#1@name}{#3}{#2}% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\ifmale} -% If the person given by the label in the first argument is male, -% do the second argument, otherwise do the third argument. -% \begin{macrocode} -\newcommand{\ifmale}[3]{% - \ifpersonexists{#1}% - {% - \edef\@gender{\csname person@\@thisperson @gender\endcsname}% - \ifx\@gender\@male@label - #2% - \else - #3% - \fi - }% - {% - \PackageError{person}{Person `#1' doesn't exist.}{}% - }% -} -\def\@male@label{male} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\ifallmale} -% If all people listed in first argument are male, do the second -% argument otherwise do the third argument. If the first argument -% is omitted, all defined people are checked. -% \begin{macrocode} -\newcommand{\ifallmale}[3][\@people@list]{% - \@for\@thisperson:=#1\do{% - \ifpersonexists{\@thisperson}% - {% - \edef\@gender{\csname person@\@thisperson @gender\endcsname}% - \ifx\@gender\@male@label - \else - \@endfortrue - \fi - }% - {% - \PackageError{person}{Person `#1' doesn't exist.}{}% - }% - }% - \if@endfor - #3% - \else - #2% - \fi -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\iffemale} -% If the person given by the label in the first argument is female, -% do the second argument, otherwise do the third argument. -% \begin{macrocode} -\newcommand{\iffemale}[3]{% - \ifpersonexists{#1}% - {% - \edef\@gender{\csname person@\@thisperson @gender\endcsname}% - \ifx\@gender\@female@label - #2% - \else - #3% - \fi - }% - {% - \PackageError{person}{Person `#1' doesn't exist.}{}% - }% -} -\def\@female@label{female} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\ifallfemale} -% If all people listed in first argument are female, do the second -% argument otherwise do the third argument. -% \begin{macrocode} -\newcommand{\ifallfemale}[3][\@people@list]{% - \@for\@thisperson:=#1\do{% - \edef\@gender{\csname person@\@thisperson @gender\endcsname}% - \ifx\@gender\@female@label - \else - \@endfortrue - \fi - }% - \if@endfor - #3% - \else - #2% - \fi -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\foreachperson} -%\begin{definition} -%\cs{foreachperson}(\meta{name cs},\meta{full name cs},\meta{gender cs},\meta{label cs})\cs{in}\marg{list}\cs{do}\marg{body} -%\end{definition} -% Iterates through list of people the \cs{in}\marg{list} is optional. -% If omitted, the list of all defined people is used. -% \begin{macrocode} -\def\foreachperson(#1,#2,#3,#4)#5{% - \ifx#5\in - \def\@do@foreachperson{\@foreachperson(#1,#2,#3,#4)#5}% - \else - \def\@do@foreachperson{% - \@foreachperson(#1,#2,#3,#4)\in\@people@list#5}% - \fi - \@do@foreachperson -} -\long\def\@foreachperson(#1,#2,#3,#4)\in#5\do#6{% - \@for#4:=#5\do{% - \ifx#4\@empty - \else - \ifpersonexists{#4}% - {% - \expandafter - \let\expandafter#1\csname person@#4@name\endcsname - \expandafter - \let\expandafter#2\csname person@#4@fullname\endcsname - \expandafter - \let\expandafter#3\csname person@#4@gender\endcsname - \ifx#3\@male@label - \let#3\malename - \else - \ifx#3\@female@label - \let#3\femalename - \fi - \fi - #6% - }% - {% - \PackageError{person}{Person `#4' doesn't exist}{}% - }% - \fi - }% -} -% \end{macrocode} -%\end{macro} -% -%\subsection{Predefined Words}\label{sec:code:peoplenames} -% These commands should be redefined if -% you are writing in another language, but note that these -% are structured according to English grammar. -%\begin{macro}{\malepronoun} -% \begin{macrocode} -\newcommand*{\malepronoun}{he} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\femalepronoun} -% \begin{macrocode} -\newcommand*{\femalepronoun}{she} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\pluralpronoun} -% \begin{macrocode} -\newcommand*{\pluralpronoun}{they} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\maleobjpronoun} -% \begin{macrocode} -\newcommand*{\maleobjpronoun}{him} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\femaleobjpronoun} -% \begin{macrocode} -\newcommand*{\femaleobjpronoun}{her} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\pluralobjpronoun} -% \begin{macrocode} -\newcommand*{\pluralobjpronoun}{them} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\malepossadj} -% \begin{macrocode} -\newcommand*{\malepossadj}{his} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\femalepossadj} -% \begin{macrocode} -\newcommand*{\femalepossadj}{her} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\pluralpossadj} -% \begin{macrocode} -\newcommand*{\pluralpossadj}{their} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\maleposspronoun} -% \begin{macrocode} -\newcommand*{\maleposspronoun}{his} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\femaleposspronoun} -% \begin{macrocode} -\newcommand*{\femaleposspronoun}{hers} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\pluralposspronoun} -% \begin{macrocode} -\newcommand*{\pluralposspronoun}{theirs} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\malechild} -% \begin{macrocode} -\newcommand*{\malechild}{son} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\femalechild} -% \begin{macrocode} -\newcommand*{\femalechild}{daughter} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\pluralchild} -% \begin{macrocode} -\newcommand*{\pluralchild}{children} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\malechildren} -% \begin{macrocode} -\newcommand*{\malechildren}{sons} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\femalechildren} -% \begin{macrocode} -\newcommand*{\femalechildren}{daughters} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\maleparent} -% \begin{macrocode} -\newcommand*{\maleparent}{father} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\femaleparent} -% \begin{macrocode} -\newcommand*{\femaleparent}{mother} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\pluralparent} -% \begin{macrocode} -\newcommand*{\pluralparent}{parents} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\malesibling} -% \begin{macrocode} -\newcommand*{\malesibling}{brother} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\femalesibling} -% \begin{macrocode} -\newcommand*{\femalesibling}{sister} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\pluralsibling} -% \begin{macrocode} -\newcommand*{\pluralsibling}{siblings} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\malesiblings} -% \begin{macrocode} -\newcommand*{\malesiblings}{brothers} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\femalesiblings} -% \begin{macrocode} -\newcommand*{\femalesiblings}{sisters} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\andname} -% Define \cs{andname} if it hasn't already been defined: -% \begin{macrocode} -\providecommand*{\andname}{and} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\malename} -% \begin{macrocode} -\newcommand*{\malename}{male} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\femalename} -% \begin{macrocode} -\newcommand*{\femalename}{female} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\personsep} -% Separator to use between people (but not the between the last -% two). -% \begin{macrocode} -\newcommand*{\personsep}{, } -% \end{macrocode} -%\end{macro} -%\begin{macro}{\personlastsep} -% Separator to use between last two people. -% \begin{macrocode} -\newcommand*{\personlastsep}{\space\andname\space} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\twopeoplesep} -% Separator to use when list only contains two people. -% \begin{macrocode} -\newcommand*{\twopeoplesep}{\space\andname\space} -% \end{macrocode} -%\end{macro} -% -%\subsection{Displaying Information} -%\begin{macro}{\personfullname} -% The person's full name can be displayed using -% \cs{personfullname}\oarg{label}, where \meta{label} is the -% unique label used when defining that person. If \meta{label} -% is omitted, \texttt{anon} is used. -% \begin{macrocode} -\newcommand*{\personfullname}[1][anon]{% - \@ifundefined{person@#1@fullname}% - {% - \PackageError{person}{Person `#1' has not been defined}{}% - }% - {% - \csname person@#1@fullname\endcsname - }% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\peoplefullname} -% List all defined people's full names. This iterates through all -% labels in \cs{@people@list}. -% \begin{macrocode} -\newcommand*{\peoplefullname}{% - \setcounter{person}{1}% - \@for\@thisperson:=\@people@list\do{% - \ifthenelse{\equal{\@thisperson}{}}% - {}% - {% - \personfullname[\@thisperson]% - \stepcounter{person}% - \ifnum\c@people=1\relax - \else - \ifnum\c@person=\c@people - \ifnum\c@people=2\relax - \twopeoplesep - \else - \personlastsep - \fi - \else - \ifnum\c@person<\c@people - \personsep - \fi - \fi - \fi - }% - }% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\personname} -% As \cs{personfullname}, but for the person's familiar name. -% \begin{macrocode} -\newcommand*{\personname}[1][anon]{% - \@ifundefined{person@#1@name}% - {% - \PackageError{person}{Person `#1' has not been defined}{}% - }% - {% - \csname person@#1@name\endcsname - }% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\peoplename} -% List all defined people's familiar names. This iterates through all -% labels in \cs{@people@list}. -% \begin{macrocode} -\newcommand*{\peoplename}{% - \setcounter{person}{1}% - \@for\@thisperson:=\@people@list\do{% - \ifthenelse{\equal{\@thisperson}{}}% - {}% - {% - \personname[\@thisperson]% - \stepcounter{person}% - \ifnum\c@people=1\relax - \else - \ifnum\c@person=\c@people - \ifnum\c@people=2\relax - \twopeoplesep - \else - \personlastsep - \fi - \else - \ifnum\c@person<\c@people - \personsep - \fi - \fi - \fi - }% - }% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\personpronoun} -% Display the pronoun (he/she) according to the person's gender. -% \begin{macrocode} -\newcommand*{\personpronoun}[1][anon]{% - \@ifundefined{person@#1@gender}% - {% - \PackageError{person}{Person `#1' has not been defined}{}% - }% - {% - \edef\@gender{\csname person@#1@gender\endcsname}% - \csname\@gender pronoun\endcsname - }% -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\Personpronoun} -% As above, but make the first letter uppercase. -% \begin{macrocode} -\newcommand*{\Personpronoun}[1][anon]{% - \@ifundefined{person@#1@gender}% - {% - \PackageError{person}{Person `#1' has not been defined}{}% - }% - {% - \edef\@gender{\csname person@#1@gender\endcsname}% - \expandafter\expandafter\expandafter - \MakeUppercase\csname\@gender pronoun\endcsname - }% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\peoplepronoun} -% If there is more than one person, \cs{peoplepronoun} will use -% \cs{pluralpronoun}, otherwise it will use \cs{personpronoun}. -% \begin{macrocode} -\newcommand*{\peoplepronoun}{% - \ifnum\c@people>1\relax - \pluralpronoun - \else - \@get@firstperson{\@thisperson}% - \personpronoun[\@thisperson]% - \fi -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\Peoplepronoun} -% As above, but first letter in upper case -% \begin{macrocode} -\newcommand*{\Peoplepronoun}{% - \ifnum\c@people>1\relax - \expandafter\MakeUppercase\pluralpronoun - \else - \@get@firstperson{\@thisperson}% - \Personpronoun[\@thisperson]% - \fi -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\personobjpronoun} -% Display the objective pronoun (him/her) according to the person's -% gender. -% \begin{macrocode} -\newcommand*{\personobjpronoun}[1][anon]{% - \@ifundefined{person@#1@gender}% - {% - \PackageError{person}{Person `#1' has not been defined}{}% - }% - {% - \edef\@gender{\csname person@#1@gender\endcsname}% - \csname\@gender objpronoun\endcsname - }% -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\Personobjpronoun} -% As above, but make the first letter uppercase. -% \begin{macrocode} -\newcommand*{\Personobjpronoun}[1][anon]{% - \@ifundefined{person@#1@gender}% - {% - \PackageError{person}{Person `#1' has not been defined}{}% - }% - {% - \edef\@gender{\csname person@#1@gender\endcsname}% - \expandafter\expandafter\expandafter - \MakeUppercase\csname\@gender objpronoun\endcsname - }% -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\peopleobjpronoun} -% If there is more than one person, \cs{peopleobjpronoun} will use -% \cs{pluralobjpronoun}, otherwise it will use \cs{personobjpronoun}. -% \begin{macrocode} -\newcommand*{\peopleobjpronoun}{% - \ifnum\c@people>1\relax - \pluralobjpronoun - \else - \@get@firstperson{\@thisperson}% - \personobjpronoun[\@thisperson]% - \fi -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\Peopleobjpronoun} -% As above, but first letter in upper case -% \begin{macrocode} -\newcommand*{\Peopleobjpronoun}{% - \ifnum\c@people>1\relax - \expandafter\MakeUppercase\pluralobjpronoun - \else - \@get@firstperson{\@thisperson}% - \Personobjpronoun[\@thisperson]% - \fi -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\personpssadj} -% Display the possessive adjective (his/her) according to the person's -% gender. -% \begin{macrocode} -\newcommand*{\personpossadj}[1][anon]{% - \@ifundefined{person@#1@gender}% - {% - \PackageError{person}{Person `#1' has not been defined}{}% - }% - {% - \edef\@gender{\csname person@#1@gender\endcsname}% - \csname\@gender possadj\endcsname - }% -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\Personpossadj} -% As above, but make the first letter uppercase. -% \begin{macrocode} -\newcommand*{\Personpossadj}[1][anon]{% - \@ifundefined{person@#1@gender}% - {% - \PackageError{person}{Person `#1' has not been defined}{}% - }% - {% - \edef\@gender{\csname person@#1@gender\endcsname}% - \expandafter\expandafter\expandafter - \MakeUppercase\csname\@gender possadj\endcsname - }% -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\peoplepossadj} -% If there is more than one person, \cs{peoplepossadj} will use -% \cs{pluralpossadj}, otherwise it will use \cs{personpossadj}. -% \begin{macrocode} -\newcommand*{\peoplepossadj}{% - \ifnum\c@people>1\relax - \pluralpossadj - \else - \@get@firstperson{\@thisperson}% - \personpossadj[\@thisperson]% - \fi -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\Peoplepossadj} -% As above, but first letter in upper case -% \begin{macrocode} -\newcommand*{\Peoplepossadj}{% - \ifnum\c@people>1\relax - \expandafter\MakeUppercase\pluralpossadj - \else - \@get@firstperson{\@thisperson}% - \Personpossadj[\@thisperson]% - \fi -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\personposspronoun} -% Display possessive pronoun (his/hers) according to the -% person's gender. -% \begin{macrocode} -\newcommand*{\personposspronoun}[1][anon]{% - \@ifundefined{person@#1@gender}% - {% - \PackageError{person}{Person `#1' has not been defined}{}% - }% - {% - \edef\@gender{\csname person@#1@gender\endcsname}% - \csname\@gender posspronoun\endcsname - }% -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\Personposspronoun} -% As above, but make the first letter uppercase. -% \begin{macrocode} -\newcommand*{\Personposspronoun}[1][anon]{% - \@ifundefined{person@#1@gender}% - {% - \PackageError{person}{Person `#1' has not been defined}{}% - }% - {% - \edef\@gender{\csname person@#1@gender\endcsname}% - \expandafter\expandafter\expandafter - \MakeUppercase\csname\@gender posspronoun\endcsname - }% -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\peopleposspronoun} -% If there is more than one person, \cs{peopleposspronoun} will use -% \cs{pluralposspronoun}, otherwise it will use \cs{personposspronoun}. -% \begin{macrocode} -\newcommand*{\peopleposspronoun}{% - \ifnum\c@people>1\relax - \pluralposspronoun - \else - \@get@firstperson{\@thisperson}% - \personposspronoun[\@thisperson]% - \fi -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\Peopleposspronoun} -% As above, but first letter in upper case -% \begin{macrocode} -\newcommand*{\Peopleposspronoun}{% - \ifnum\c@people>1\relax - \expandafter\MakeUppercase\pluralposspronoun - \else - \@get@firstperson{\@thisperson}% - \Personposspronoun[\@thisperson]% - \fi -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\personchild} -% Display this person's relationship to their parent (i.e.\ son -% or daughter). -% \begin{macrocode} -\newcommand*{\personchild}[1][anon]{% - \@ifundefined{person@#1@gender}% - {% - \PackageError{person}{Person `#1' has not been defined}{}% - }% - {% - \edef\@gender{\csname person@#1@gender\endcsname}% - \csname\@gender child\endcsname - }% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\Personchild} -% As above, but make first letter uppercase. -% \begin{macrocode} -\newcommand*{\Personchild}[1][anon]{% - \@ifundefined{person@#1@gender}% - {% - \PackageError{person}{Person `#1' has not been defined}{}% - }% - {% - \edef\@gender{\csname person@#1@gender\endcsname}% - \expandafter\expandafter\expandafter\MakeUppercase - \csname\@gender child\endcsname - }% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\peoplechild} -% If there is more than one person, \cs{peoplechild} will use -% \cs{malechildren} (if all male), \cs{femalechildren} (if all -% female) or \cs{pluralchild} (if mixed), otherwise it will use -% \cs{personchild}. -% \begin{macrocode} -\newcommand*{\peoplechild}{% - \ifnum\c@people>1\relax - \ifallmale - {\malechildren}% - {\ifallfemale{\femalechildren}{\pluralchild}}% - \else - \@get@firstperson{\@thisperson}% - \personchild[\@thisperson]% - \fi -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\Peoplechild} -% As above but first letter is made uppercase. -% \begin{macrocode} -\newcommand*{\Peoplechild}{% - \ifnum\c@people>1\relax - \ifallmale - {\expandafter\MakeUppercase\malechildren}% - {\ifallfemale - {\expandafter\MakeUppercase\femalechildren} - {\expandafter\MakeUppercase\pluralchild}}% - \else - \@get@firstperson{\@thisperson}% - \Personchild[\@thisperson]% - \fi -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\personparent} -% Display this person's relationship to their child (i.e.\ father -% or mother). -% \begin{macrocode} -\newcommand*{\personparent}[1][anon]{% - \@ifundefined{person@#1@gender}% - {% - \PackageError{person}{Person `#1' has not been defined}{}% - }% - {% - \edef\@gender{\csname person@#1@gender\endcsname}% - \csname\@gender parent\endcsname - }% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\Personparent} -% As above, but make the first letter uppercase. -% \begin{macrocode} -\newcommand*{\Personparent}[1][anon]{% - \@ifundefined{person@#1@gender}% - {% - \PackageError{person}{Person `#1' has not been defined}{}% - }% - {% - \edef\@gender{\csname person@#1@gender\endcsname}% - \expandafter\expandafter\expandafter\MakeUppercase - \csname\@gender parent\endcsname - }% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\peopleparent} -% If there is more than one person, \cs{peopleparent} will use -% \cs{pluralparent}, otherwise it will use \cs{personparent}. -% \begin{macrocode} -\newcommand*{\peopleparent}{% - \ifnum\c@people>1\relax - \pluralparent - \else - \@get@firstperson{\@thisperson}% - \personparent[\@thisperson]% - \fi -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\Peopleparent} -% As above, but make first letter uppercase. -% \begin{macrocode} -\newcommand*{\Peopleparent}{% - \ifnum\c@people>1\relax - \expandafter\MakeUppercase\pluralparent - \else - \@get@firstperson{\@thisperson}% - \Personparent[\@thisperson]% - \fi -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\personsibling} -% Display this person's relationship to their siblings (i.e.\ -% brother or sister). -% \begin{macrocode} -\newcommand*{\personsibling}[1][anon]{% - \@ifundefined{person@#1@gender}% - {% - \PackageError{person}{Person `#1' has not been defined}{}% - }% - {% - \edef\@gender{\csname person@#1@gender\endcsname}% - \csname\@gender sibling\endcsname - }% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\Personsibling} -% Display this person's relationship to their siblings (i.e.\ -% brother or sister). -% \begin{macrocode} -\newcommand*{\Personsibling}[1][anon]{% - \@ifundefined{person@#1@gender}% - {% - \PackageError{person}{Person `#1' has not been defined}{}% - }% - {% - \edef\@gender{\csname person@#1@gender\endcsname}% - \expandafter\expandafter\expandafter\MakeUppercase - \csname\@gender sibling\endcsname - }% -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\peoplesibling} -% If there is more than one person, \cs{peoplesibling} will use -% \cs{malesiblings} (if all male), \cs{femalesiblings} (if all -% female) or \cs{pluralsibling} (if mixed), otherwise it will use -% \cs{personsibling}. -% \begin{macrocode} -\newcommand*{\peoplesibling}{% - \ifnum\c@people>1\relax - \ifallmale - {\malesiblings}% - {\ifallfemale{\femalesiblings}{\pluralsibling}}% - \else - \@get@firstperson{\@thisperson}% - \personsibling[\@thisperson]% - \fi -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\persongender} -% Displays the given person's gender (\cs{malename} or -% \cs{femalename}). -% \begin{macrocode} -\newcommand*{\persongender}[1]{% - \ifpersonmale{#1}{\malename}{\femalename}% -} -% \end{macrocode} -%\end{macro} -% -%\subsection{Extracting Information} -% -%\begin{macro}{\getpersongender} -% Gets person's gender and stores in first argument which must be -% a control sequence. -% \begin{macrocode} -\newcommand*{\getpersongender}[2]{% - \ifpersonmale{#2}{\let#1\malename}{\let#1\femalename}% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\getpersonname} -% Gets person's name and stores in first argument which must be -% a control sequence. -% \begin{macrocode} -\newcommand*{\getpersonname}[2]{% - \ifpersonexists{#2}% - {% - \expandafter\let\expandafter#1\csname person@#2@name\endcsname - }% - {% - \PackageError{person}{Person `#2' doesn't exist}{}% - }% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\getpersonfullname} -% Gets person's full name and stores in first argument which must be -% a control sequence. -% \begin{macrocode} -\newcommand*{\getpersonfullname}[2]{% - \ifpersonexists{#2}% - {% - \expandafter - \let\expandafter#1\csname person@#2@fullname\endcsname - }% - {% - \PackageError{person}{Person `#2' doesn't exist}{}% - }% -} -% \end{macrocode} -%\end{macro} -%\iffalse -% \begin{macrocode} -%</person.sty> -% \end{macrocode} -%\fi %\Finale \endinput diff --git a/Master/texmf-dist/source/latex/datatool/datatool.ins b/Master/texmf-dist/source/latex/datatool/datatool.ins index a3d3bd39125..ace8870e0cc 100644 --- a/Master/texmf-dist/source/latex/datatool/datatool.ins +++ b/Master/texmf-dist/source/latex/datatool/datatool.ins @@ -1,10 +1,10 @@ -% datatool.ins generated using makedtx version 0.94b 2009/11/15 15:10 +% datatool.ins generated using makedtx version 0.94b 2012/7/19 16:34 \input docstrip \preamble datatool.dtx - Copyright 2009 Nicola Talbot + Copyright 2012 Nicola Talbot This work may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3 @@ -18,25 +18,32 @@ 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, person.sty. + This work consists of the files datatool.dtx and datatool.ins and the derived files datatool-base.sty, datatool-fp.sty, datatool-pgfmath.sty, datatool.sty, databib.sty, databar.sty, datapie.sty, dataplot.sty, person.sty, databib.bst. \endpreamble \askforoverwritefalse -\generate{\file{datatool.sty}{\usepreamble\defaultpreamble +\generate{\file{datatool-base.sty}{\usepreamble\defaultpreamble +\usepostamble\defaultpostamble\from{datatool.dtx}{datatool-base.sty,package}} +\file{datatool-fp.sty}{\usepreamble\defaultpreamble +\usepostamble\defaultpostamble\from{datatool.dtx}{datatool-fp.sty,package}} +\file{datatool-pgfmath.sty}{\usepreamble\defaultpreamble +\usepostamble\defaultpostamble\from{datatool.dtx}{datatool-pgfmath.sty,package}} +\file{datatool.sty}{\usepreamble\defaultpreamble \usepostamble\defaultpostamble\from{datatool.dtx}{datatool.sty,package}} +\file{databib.sty}{\usepreamble\defaultpreamble +\usepostamble\defaultpostamble\from{datatool.dtx}{databib.sty,package}} +\file{databar.sty}{\usepreamble\defaultpreamble +\usepostamble\defaultpostamble\from{datatool.dtx}{databar.sty,package}} \file{datapie.sty}{\usepreamble\defaultpreamble \usepostamble\defaultpostamble\from{datatool.dtx}{datapie.sty,package}} \file{dataplot.sty}{\usepreamble\defaultpreamble \usepostamble\defaultpostamble\from{datatool.dtx}{dataplot.sty,package}} -\file{databar.sty}{\usepreamble\defaultpreamble -\usepostamble\defaultpostamble\from{datatool.dtx}{databar.sty,package}} -\file{databib.sty}{\usepreamble\defaultpreamble -\usepostamble\defaultpostamble\from{datatool.dtx}{databib.sty,package}} -\file{databib.bst}{\nopreamble\usepreamble\defaultpreamble\nopostamble\from{datatool.dtx}{databib.bst}} \file{person.sty}{\usepreamble\defaultpreamble \usepostamble\defaultpostamble\from{datatool.dtx}{person.sty,package}} +\file{databib.bst}{\usepreamble\defaultpreamble +\usepostamble\defaultpostamble\from{datatool.dtx}{databib.bst,package}} } \endbatchfile diff --git a/Master/texmf-dist/tex/latex/datatool/databar.sty b/Master/texmf-dist/tex/latex/datatool/databar.sty index a381960c486..513e39c512e 100644 --- a/Master/texmf-dist/tex/latex/datatool/databar.sty +++ b/Master/texmf-dist/tex/latex/datatool/databar.sty @@ -7,7 +7,7 @@ %% datatool.dtx (with options: `databar.sty,package') %% %% datatool.dtx -%% Copyright 2009 Nicola Talbot +%% Copyright 2012 Nicola Talbot %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either version 1.3 @@ -21,7 +21,7 @@ %% %% 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, person.sty. +%% This work consists of the files datatool.dtx and datatool.ins and the derived files datatool-base.sty, datatool-fp.sty, datatool-pgfmath.sty, datatool.sty, databib.sty, databar.sty, datapie.sty, dataplot.sty, person.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 @@ -38,13 +38,8 @@ %% Right bracket \] Circumflex \^ Underscore \_ %% Grave accent \` Left brace \{ Vertical bar \| %% Right brace \} Tilde \~} -%% load student information from file "students.csv" -%% Iterate through the student database: -%% Define "anon": -%% Do the letter: -%% Undefine "anon": \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{databar}[2009/10/22 v2.01 (NLCT)] +\ProvidesPackage{databar}[2012/07/18 v2.10 (NLCT)] \RequirePackage{xkeyval} \RequirePackage{dataplot} \newif\ifDTLcolorbarchart @@ -167,9 +162,11 @@ \fi } \define@key{databar}{variable}{% -\def\DTLbarvariable{#1}} + \def\DTLbarvariable{#1}% +} \define@key{databar}{variables}{% -\def\dtlbar@variables{#1}} + \def\dtlbar@variables{#1}% +} \define@key{databar}{barwidth}{\setlength{\DTLbarwidth}{#1}} \define@key{databar}{barlabel}{% \def\dtl@barlabel{#1}} @@ -198,286 +195,299 @@ \def\dtlbar@ylabel{#1}} \let\dtlbar@ylabel=\relax \newcommand*{\DTLbarchart}[4][\boolean{true}]{% -{\let\DTLbarvariable=\relax -\let\DTLbarmax=\relax -\let\DTLnegextent=\relax -\disable@keys{databar}{variables,multibarlabels,% -uppermultibarlabels,groupgap}% -\setkeys{databar}{#2}% -\ifx\DTLbarvariable\relax - \PackageError{databar}{\string\DTLbarchart\space missing - variable}{You haven't use the "variable" key}% -\else - \ifx\DTLbarmax\relax - \@sDTLforeach[#1]{#3}{#4}{% - \expandafter\DTLconverttodecimal\expandafter - {\DTLbarvariable}{\dtl@barvar}% - \ifx\DTLbarmax\relax - \let\DTLbarmax=\dtl@barvar +{% + \undef\DTLbarvariable + \undef\DTLbarmax + \undef\DTLnegextent + \disable@keys{databar}{variables,multibarlabels,% + uppermultibarlabels,groupgap}% + \setkeys{databar}{#2}% + \ifundef{\DTLbarvariable}% + {% + \PackageError{databar}% + {\string\DTLbarchart\space missing variable}% + {You haven't use the "variable" key}% + }% + {% + \ifundef{\DTLbarmax}% + {% + \@sDTLforeach[#1]{#3}{#4}{% + \expandafter\DTLconverttodecimal\expandafter + {\DTLbarvariable}{\dtl@barvar}% + \ifundef{\DTLbarmax}% + {% + \let\DTLbarmax=\dtl@barvar + }% + {% + \let\dtl@old=\DTLbarmax + \dtlmax{\DTLbarmax}{\dtl@old}{\dtl@barvar}% + }% + }% + \ifx\dtlbar@yticgap\relax \else - \let\dtl@old=\DTLbarmax - \FPmax{\DTLbarmax}{\dtl@old}{\dtl@barvar}% + \let\dtl@thistick=\dtlbar@yticgap + \whiledo{\DTLisFPopenbetween{\dtl@thistick}{0}{\DTLbarmax}}% + {% + \dtladd{\dtl@thistick}{\dtl@thistick}{\dtlbar@yticgap}% + }% + \let\DTLbarmax=\dtl@thistick \fi }% - \ifx\dtlbar@yticgap\relax - \else - \let\dtl@thistick=\dtlbar@yticgap% - \whiledo{\DTLisFPopenbetween{\dtl@thistick}{0}{\DTLbarmax}}{% - \FPadd{\dtl@thistick}{\dtl@thistick}{\dtlbar@yticgap}% + {}% + \ifundef{\DTLnegextent}% + {% + \def\DTLnegextent{0}% + \@sDTLforeach[#1]{#3}{#4}{% + \expandafter\DTLconverttodecimal\expandafter + {\DTLbarvariable}{\dtl@barvar}% + \let\dtl@old=\DTLnegextent + \DTLmin{\DTLnegextent}{\dtl@old}{\dtl@barvar}% }% - \let\DTLbarmax=\dtl@thistick - \fi - \fi - \ifx\DTLnegextent\relax - \def\DTLnegextent{0}% - \@sDTLforeach[#1]{#3}{#4}{% - \expandafter\DTLconverttodecimal\expandafter - {\DTLbarvariable}{\dtl@barvar}% - \let\dtl@old=\DTLnegextent - \DTLmin{\DTLnegextent}{\dtl@old}{\dtl@barvar}% + \ifx\dtlbar@yticgap\relax + \else + \ifthenelse{\DTLisFPlt{\DTLnegextent}{0}}% + {% + \edef\dtl@thistick{0}% + \whiledo{\DTLisFPclosedbetween{\dtl@thistick}{\DTLnegextent}{0}}{% + \dtlsub{\dtl@thistick}{\dtl@thistick}{\dtlbar@yticgap}% + }% + \let\DTLnegextent=\dtl@thistick + }{}% + \fi }% - \ifx\dtlbar@yticgap\relax - \else - \ifthenelse{\DTLisFPlt{\DTLnegextent}{0}}{% - \edef\dtl@thistick{0}% - \whiledo{\DTLisFPclosedbetween{\dtl@thistick}{\DTLnegextent}{0}}{% - \FPsub{\dtl@thistick}{\dtl@thistick}{\dtlbar@yticgap}% - }% - \let\DTLnegextent=\dtl@thistick - }{}% - \fi - \fi - \@dtl@tmpcount=\DTLbarchartlength - \FPsub{\dtl@extent}{\DTLbarmax}{\DTLnegextent}% - \FPdiv{\dtl@unit}{\number\@dtl@tmpcount}{\dtl@extent}% - \setlength{\dtl@yticlabelwidth}{0pt}% - \ifDTLbarytics - \ifx\dtlbar@yticlist\relax - \ifx\dtlbar@yticgap\relax - \dtl@constructticklist\DTLnegextent\DTLbarmax - \dtl@unit\dtlbar@yticlist - \else - \dtl@constructticklistwithgapz - \DTLnegextent\DTLbarmax\dtlbar@yticlist\dtlbar@yticgap + {}% + \@dtl@tmpcount=\DTLbarchartlength + \dtlsub{\dtl@extent}{\DTLbarmax}{\DTLnegextent}% + \dtldiv{\dtl@unit}{\number\@dtl@tmpcount}{\dtl@extent}% + \setlength{\dtl@yticlabelwidth}{0pt}% + \ifDTLbarytics + \ifx\dtlbar@yticlist\relax + \ifx\dtlbar@yticgap\relax + \dtl@constructticklist\DTLnegextent\DTLbarmax + \dtl@unit\dtlbar@yticlist + \else + \dtl@constructticklistwithgapz + \DTLnegextent\DTLbarmax\dtlbar@yticlist\dtlbar@yticgap + \fi \fi - \fi - \ifx\dtlbar@ylabel\relax - \else - \ifx\dtlbar@yticlabels\relax - \@for\dtl@thislabel:=\dtlbar@yticlist\do{% - \FPround{\dtl@thislabel}{\dtl@thislabel} - {\c@DTLbarroundvar}% - \ifDTLverticalbars - \settowidth{\dtl@tmplength}{% - \DTLbardisplayYticklabel{\dtl@thislabel}}% - \else - \settoheight{\dtl@tmplength}{% - \DTLbardisplayYticklabel{\dtl@thislabel}}% - \edef\@dtl@h{\the\dtl@tmplength}% - \settodepth{\dtl@tmplength}{% - \DTLbardisplayYticklabel{\dtl@thislabel}}% - \addtolength{\dtl@tmplength}{\@dtl@h}% - \addtolength{\dtl@tmplength}{\baselineskip}% - \fi - \ifdim\dtl@tmplength>\dtl@yticlabelwidth - \setlength{\dtl@yticlabelwidth}{\dtl@tmplength}% - \fi - }% + \ifx\dtlbar@ylabel\relax \else - \@for\dtl@thislabel:=\dtlbar@yticlabels\do{% - \ifDTLverticalbars - \settowidth{\dtl@tmplength}{% - \DTLbardisplayYticklabel{\dtl@thislabel}}% - \else - \settoheight{\dtl@tmplength}{% - \DTLbardisplayYticklabel{\dtl@thislabel}}% - \edef\@dtl@h{\the\dtl@tmplength}% - \settodepth{\dtl@tmplength}{% - \DTLbardisplayYticklabel{\dtl@thislabel}}% - \addtolength{\dtl@tmplength}{\@dtl@h}% - \addtolength{\dtl@tmplength}{\baselineskip}% - \fi - \ifdim\dtl@tmplength>\dtl@yticlabelwidth - \setlength{\dtl@yticlabelwidth}{\dtl@tmplength}% - \fi - }% + \ifx\dtlbar@yticlabels\relax + \@for\dtl@thislabel:=\dtlbar@yticlist\do{% + \dtlround{\dtl@thislabel}{\dtl@thislabel} + {\c@DTLbarroundvar}% + \ifDTLverticalbars + \settowidth{\dtl@tmplength}{% + \DTLbardisplayYticklabel{\dtl@thislabel}}% + \else + \settoheight{\dtl@tmplength}{% + \DTLbardisplayYticklabel{\dtl@thislabel}}% + \edef\@dtl@h{\the\dtl@tmplength}% + \settodepth{\dtl@tmplength}{% + \DTLbardisplayYticklabel{\dtl@thislabel}}% + \addtolength{\dtl@tmplength}{\@dtl@h}% + \addtolength{\dtl@tmplength}{\baselineskip}% + \fi + \ifdim\dtl@tmplength>\dtl@yticlabelwidth + \setlength{\dtl@yticlabelwidth}{\dtl@tmplength}% + \fi + }% + \else + \@for\dtl@thislabel:=\dtlbar@yticlabels\do{% + \ifDTLverticalbars + \settowidth{\dtl@tmplength}{% + \DTLbardisplayYticklabel{\dtl@thislabel}}% + \else + \settoheight{\dtl@tmplength}{% + \DTLbardisplayYticklabel{\dtl@thislabel}}% + \edef\@dtl@h{\the\dtl@tmplength}% + \settodepth{\dtl@tmplength}{% + \DTLbardisplayYticklabel{\dtl@thislabel}}% + \addtolength{\dtl@tmplength}{\@dtl@h}% + \addtolength{\dtl@tmplength}{\baselineskip}% + \fi + \ifdim\dtl@tmplength>\dtl@yticlabelwidth + \setlength{\dtl@yticlabelwidth}{\dtl@tmplength}% + \fi + }% + \fi \fi \fi + \edef\DTLbarchartwidth{\expandafter\number\csname dtlrows@#3\endcsname} + \begin{tikzpicture} + \ifDTLverticalbars + \pgfsetyvec{\pgfpoint{0pt}{\dtl@unit sp}}% + \pgfsetxvec{\pgfpoint{\DTLbarwidth}{0pt}}% + \else + \pgfsetxvec{\pgfpoint{\dtl@unit sp}{0pt}}% + \pgfsetyvec{\pgfpoint{0pt}{\DTLbarwidth}}% + \fi + \DTLbaratbegintikz + \def\@dtl@start{0}% + \@sDTLforeach[#1]{#3}{#4}{% + \expandafter\let\expandafter\@dtl@bar + \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname% + \expandafter\DTLconverttodecimal\expandafter + {\DTLbarvariable}{\dtl@variable}% + \begin{scope} + \DTLdocurrentbarcolor + \ifDTLverticalbars + \fill (\@dtl@start,0) -- (\@dtl@start,\dtl@variable) + -- (\@dtl@bar,\dtl@variable) -- (\@dtl@bar,0) -- cycle; + \else + \fill (0,\@dtl@start) -- (\dtl@variable,\@dtl@start) + -- (\dtl@variable,\@dtl@bar) -- (0,\@dtl@bar) -- cycle; \fi -\edef\DTLbarchartwidth{\expandafter\number\csname dtlrows@#3\endcsname} -\begin{tikzpicture} -\ifDTLverticalbars - \pgfsetyvec{\pgfpoint{0pt}{\dtl@unit sp}}% - \pgfsetxvec{\pgfpoint{\DTLbarwidth}{0pt}}% -\else - \pgfsetxvec{\pgfpoint{\dtl@unit sp}{0pt}}% - \pgfsetyvec{\pgfpoint{0pt}{\DTLbarwidth}}% -\fi -\DTLbaratbegintikz -\def\@dtl@start{0}% -\@sDTLforeach[#1]{#3}{#4}{% -\expandafter\let\expandafter\@dtl@bar - \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname% -\expandafter\DTLconverttodecimal\expandafter - {\DTLbarvariable}{\dtl@variable}% -\begin{scope} - \DTLdocurrentbarcolor - \ifDTLverticalbars - \fill (\@dtl@start,0) -- (\@dtl@start,\dtl@variable) - -- (\@dtl@bar,\dtl@variable) -- (\@dtl@bar,0) -- cycle; - \else - \fill (0,\@dtl@start) -- (\dtl@variable,\@dtl@start) - -- (\dtl@variable,\@dtl@bar) -- (0,\@dtl@bar) -- cycle; - \fi -\end{scope} -\begin{scope} -\ifdim\DTLbaroutlinewidth>0pt - \expandafter\color\expandafter{\DTLbaroutlinecolor} - \ifDTLverticalbars - \draw (\@dtl@start,0) -- (\@dtl@start,\dtl@variable) - -- (\@dtl@bar,\dtl@variable) -- (\@dtl@bar,0) -- cycle; - \else - \draw (0,\@dtl@start) -- (\dtl@variable,\@dtl@start) - -- (\dtl@variable,\@dtl@bar) -- (0,\@dtl@bar) -- cycle; - \fi -\fi -\end{scope} -\ifDTLverticalbars - \edef\dtl@textopt{% - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{\@dtl@start.5}{0}} - {\noexpand\pgfpoint{0pt}{-\noexpand\DTLbarlabeloffset}}}, - \DTLbarXlabelalign - }% - \edef\DTLstartpt{\noexpand\pgfpointxy{\@dtl@start.5}{0}}% -\else - \edef\dtl@textopt{% - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{0}{\@dtl@start.5}} - {\noexpand\pgfpoint{-\noexpand\DTLbarlabeloffset}{0pt}}}, - \DTLbarXlabelalign - }% - \edef\DTLstartpt{\noexpand\pgfpointxy{0}{\@dtl@start.5}}% -\fi - \expandafter\pgftext\expandafter[\dtl@textopt]{% - \DTLdisplaylowerbarlabel{\dtl@barlabel}} -\ifDTLverticalbars - \expandafter\DTLifnumlt\expandafter{\DTLbarvariable}{0} - { + \end{scope} + \begin{scope} + \ifdim\DTLbaroutlinewidth>0pt + \expandafter\color\expandafter{\DTLbaroutlinecolor} + \ifDTLverticalbars + \draw (\@dtl@start,0) -- (\@dtl@start,\dtl@variable) + -- (\@dtl@bar,\dtl@variable) -- (\@dtl@bar,0) -- cycle; + \else + \draw (0,\@dtl@start) -- (\dtl@variable,\@dtl@start) + -- (\dtl@variable,\@dtl@bar) -- (0,\@dtl@bar) -- cycle; + \fi + \fi + \end{scope} + \ifDTLverticalbars \edef\dtl@textopt{% - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{\@dtl@start.5}{\dtl@variable}} - {\noexpand\pgfpoint{0pt}{-\noexpand\DTLbarlabeloffset}}} + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{\@dtl@start.5}{0}} + {\noexpand\pgfpoint{0pt}{-\noexpand\DTLbarlabeloffset}}}, + \DTLbarXlabelalign }% - }{% + \edef\DTLstartpt{\noexpand\pgfpointxy{\@dtl@start.5}{0}}% + \else \edef\dtl@textopt{% - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{\@dtl@start.5}{\dtl@variable}} - {\noexpand\pgfpoint{0pt}{\noexpand\DTLbarlabeloffset}}} - }% - } - \edef\DTLendpt{\noexpand\pgfpointxy{\@dtl@start.5}{\dtl@variable}}% -\else - \expandafter\DTLifnumlt\expandafter{\DTLbarvariable}{0} - { - \edef\dtl@textopt{right, - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{\dtl@variable}{\@dtl@start.5}} - {\noexpand\pgfpoint{-\noexpand\DTLbarlabeloffset}{0pt}}} - }% - }{% - \edef\dtl@textopt{left, - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{\dtl@variable}{\@dtl@start.5}} - {\noexpand\pgfpoint{\noexpand\DTLbarlabeloffset}{0pt}}} + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{0}{\@dtl@start.5}} + {\noexpand\pgfpoint{-\noexpand\DTLbarlabeloffset}{0pt}}}, + \DTLbarXlabelalign }% - } - \edef\DTLendpt{\noexpand\pgfpointxy{\dtl@variable}{\@dtl@start.5}}% -\fi - \expandafter\pgftext\expandafter[\dtl@textopt]{% - \DTLdisplayupperbarlabel{\dtl@upperbarlabel}} -\def\DTLmidpt{\pgfpointlineattime{0.5}{\DTLstartpt}{\DTLendpt}}% - \DTLeverybarhook - \edef\@dtl@start{\number\@dtl@bar}% -} -\ifDTLbarxaxis - \ifDTLverticalbars - \expandafter\draw\expandafter[\DTLBarXAxisStyle] - (0,0) -- (\DTLbarchartwidth,0); - \else - \expandafter\draw\expandafter[\DTLBarXAxisStyle] - (0,0) -- (0,\DTLbarchartwidth); + \edef\DTLstartpt{\noexpand\pgfpointxy{0}{\@dtl@start.5}}% \fi -\fi -\ifDTLbaryaxis + \expandafter\pgftext\expandafter[\dtl@textopt]{% + \DTLdisplaylowerbarlabel{\dtl@barlabel}} \ifDTLverticalbars - \expandafter\draw\expandafter[\DTLBarYAxisStyle] - (0,\DTLnegextent) -- (0,\DTLbarmax); + \expandafter\DTLifnumlt\expandafter{\DTLbarvariable}{0}% + { + \edef\dtl@textopt{% + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{\@dtl@start.5}{\dtl@variable}} + {\noexpand\pgfpoint{0pt}{-\noexpand\DTLbarlabeloffset}}} + }% + }{% + \edef\dtl@textopt{% + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{\@dtl@start.5}{\dtl@variable}} + {\noexpand\pgfpoint{0pt}{\noexpand\DTLbarlabeloffset}}} + }% + } + \edef\DTLendpt{\noexpand\pgfpointxy{\@dtl@start.5}{\dtl@variable}}% \else - \expandafter\draw\expandafter[\DTLBarYAxisStyle] - (\DTLnegextent,0) -- (\DTLbarmax,0); + \expandafter\DTLifnumlt\expandafter{\DTLbarvariable}{0}% + { + \edef\dtl@textopt{right, + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{\dtl@variable}{\@dtl@start.5}} + {\noexpand\pgfpoint{-\noexpand\DTLbarlabeloffset}{0pt}}} + }% + }{% + \edef\dtl@textopt{left, + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{\dtl@variable}{\@dtl@start.5}} + {\noexpand\pgfpoint{\noexpand\DTLbarlabeloffset}{0pt}}} + }% + } + \edef\DTLendpt{\noexpand\pgfpointxy{\dtl@variable}{\@dtl@start.5}}% \fi -\fi -\ifx\dtlbar@yticlist\relax -\else - \@for\dtl@thistick:=\dtlbar@yticlist\do{% + \expandafter\pgftext\expandafter[\dtl@textopt]{% + \DTLdisplayupperbarlabel{\dtl@upperbarlabel}} + \def\DTLmidpt{\pgfpointlineattime{0.5}{\DTLstartpt}{\DTLendpt}}% + \DTLeverybarhook + \edef\@dtl@start{\number\@dtl@bar}% + }% + \ifDTLbarxaxis \ifDTLverticalbars - \pgfpathmoveto{\pgfpointxy{0}{\dtl@thistick}} - \pgfpathlineto{ - \pgfpointadd{\pgfpointxy{0}{\dtl@thistick}} - {\pgfpoint{-\DTLticklength}{0pt}}} + \expandafter\draw\expandafter[\DTLBarXAxisStyle] + (0,0) -- (\DTLbarchartwidth,0); \else - \pgfpathmoveto{\pgfpointxy{\dtl@thistick}{0}} - \pgfpathlineto{ - \pgfpointadd{\pgfpointxy{\dtl@thistick}{0}} - {\pgfpoint{0pt}{-\DTLticklength}}} + \expandafter\draw\expandafter[\DTLBarXAxisStyle] + (0,0) -- (0,\DTLbarchartwidth); \fi - \pgfusepath{stroke} - \ifx\dtlbar@yticlabels\relax - \FPround{\dtl@thislabel}{\dtl@thistick} - {\c@DTLbarroundvar}% + \fi + \ifDTLbaryaxis + \ifDTLverticalbars + \expandafter\draw\expandafter[\DTLBarYAxisStyle] + (0,\DTLnegextent) -- (0,\DTLbarmax); \else - \dtl@chopfirst\dtlbar@yticlabels\dtl@thislabel\dtl@rest - \let\dtlbar@yticlabels=\dtl@rest + \expandafter\draw\expandafter[\DTLBarYAxisStyle] + (\DTLnegextent,0) -- (\DTLbarmax,0); \fi + \fi + \ifx\dtlbar@yticlist\relax + \else + \@for\dtl@thistick:=\dtlbar@yticlist\do{% + \ifDTLverticalbars + \pgfpathmoveto{\pgfpointxy{0}{\dtl@thistick}} + \pgfpathlineto{ + \pgfpointadd{\pgfpointxy{0}{\dtl@thistick}} + {\pgfpoint{-\DTLticklength}{0pt}}} + \else + \pgfpathmoveto{\pgfpointxy{\dtl@thistick}{0}} + \pgfpathlineto{ + \pgfpointadd{\pgfpointxy{\dtl@thistick}{0}} + {\pgfpoint{0pt}{-\DTLticklength}}} + \fi + \pgfusepath{stroke} + \ifx\dtlbar@yticlabels\relax + \dtlround{\dtl@thislabel}{\dtl@thistick} + {\c@DTLbarroundvar}% + \else + \dtl@chopfirst\dtlbar@yticlabels\dtl@thislabel\dtl@rest + \let\dtlbar@yticlabels=\dtl@rest + \fi + \ifDTLverticalbars + \edef\dtl@textopt{\DTLbarYticklabelalign,% + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{0}{\dtl@thistick}} + {\noexpand\pgfpoint{-\noexpand\DTLticklabeloffset}{0pt}}, + }}% + \else + \edef\dtl@textopt{\DTLbarYticklabelalign, + at={\noexpand\pgfpointadd + {\noexpand\pgfpointxy{\dtl@thistick}{0}} + {\noexpand\pgfpoint{0pt}{-\noexpand\DTLticklabeloffset}} + }}% + \fi + \expandafter\pgftext\expandafter[\dtl@textopt]{% + \DTLbardisplayYticklabel{\dtl@thislabel}} + }% + \fi + \ifx\dtlbar@ylabel\relax + \else + \addtolength{\dtl@yticlabelwidth}{\baselineskip}% + \setlength{\dtl@tmplength}{0.5\DTLbarchartlength} \ifDTLverticalbars - \edef\dtl@textopt{\DTLbarYticklabelalign,% - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{0}{\dtl@thistick}} - {\noexpand\pgfpoint{-\noexpand\DTLticklabeloffset}{0pt}}, - }}% + \pgftext[bottom,center,at={\pgfpointadd + {\pgfpointxy{0}{\DTLnegextent}}% + {\pgfpoint{-\dtl@yticlabelwidth}{\dtl@tmplength}}}, + rotate=90]{% + \dtlbar@ylabel} \else - \edef\dtl@textopt{\DTLbarYticklabelalign, - at={\noexpand\pgfpointadd - {\noexpand\pgfpointxy{\dtl@thistick}{0}} - {\noexpand\pgfpoint{0pt}{-\noexpand\DTLticklabeloffset}} - }}% + \pgftext[bottom,center,at={\pgfpointadd + {\pgfpointxy{\DTLnegextent}{0}}% + {\pgfpoint{\dtl@tmplength}{-\dtl@yticlabelwidth}}}]{% + \dtlbar@ylabel} \fi - \expandafter\pgftext\expandafter[\dtl@textopt]{% - \DTLbardisplayYticklabel{\dtl@thislabel}} - }% -\fi -\ifx\dtlbar@ylabel\relax -\else - \addtolength{\dtl@yticlabelwidth}{\baselineskip}% - \setlength{\dtl@tmplength}{0.5\DTLbarchartlength} - \ifDTLverticalbars - \pgftext[bottom,center,at={\pgfpointadd - {\pgfpointxy{0}{\DTLnegextent}}% - {\pgfpoint{-\dtl@yticlabelwidth}{\dtl@tmplength}}}, - rotate=90]{% - \dtlbar@ylabel} - \else - \pgftext[bottom,center,at={\pgfpointadd - {\pgfpointxy{\DTLnegextent}{0}}% - {\pgfpoint{\dtl@tmplength}{-\dtl@yticlabelwidth}}}]{% - \dtlbar@ylabel} \fi -\fi -\DTLbaratendtikz -\end{tikzpicture} -\fi -}} + \DTLbaratendtikz + \end{tikzpicture} + }% +}% +} \newcommand*{\DTLmultibarchart}[4][\boolean{true}]{% {\let\dtlbar@variables=\relax \let\DTLbarmax=\relax @@ -496,7 +506,7 @@ uppermultibarlabels,groupgap}% \let\DTLbarmax=\dtl@barvar \else \let\dtl@old=\DTLbarmax - \FPmax{\DTLbarmax}{\dtl@old}{\dtl@barvar}% + \dtlmax{\DTLbarmax}{\dtl@old}{\dtl@barvar}% \fi }% }% @@ -504,7 +514,7 @@ uppermultibarlabels,groupgap}% \else \let\dtl@thistick=\dtlbar@yticgap% \whiledo{\DTLisFPopenbetween{\dtl@thistick}{0}{\DTLbarmax}}{% - \FPadd{\dtl@thistick}{\dtl@thistick}{\dtlbar@yticgap}% + \dtladd{\dtl@thistick}{\dtl@thistick}{\dtlbar@yticgap}% }% \let\DTLbarmax=\dtl@thistick \fi @@ -524,15 +534,15 @@ uppermultibarlabels,groupgap}% \ifthenelse{\DTLisFPlt{\DTLnegextent}{0}}{% \edef\dtl@thistick{0}% \whiledo{\DTLisFPclosedbetween{\dtl@thistick}{\DTLnegextent}{0}}{% - \FPsub{\dtl@thistick}{\dtl@thistick}{\dtlbar@yticgap}% + \dtlsub{\dtl@thistick}{\dtl@thistick}{\dtlbar@yticgap}% }% \let\DTLnegextent=\dtl@thistick }{}% \fi \fi \@dtl@tmpcount=\DTLbarchartlength - \FPsub{\dtl@extent}{\DTLbarmax}{\DTLnegextent}% - \FPdiv{\dtl@unit}{\number\@dtl@tmpcount}{\dtl@extent}% + \dtlsub{\dtl@extent}{\DTLbarmax}{\DTLnegextent}% + \dtldiv{\dtl@unit}{\number\@dtl@tmpcount}{\dtl@extent}% \setlength{\dtl@yticlabelwidth}{0pt}% \ifDTLbarytics \ifx\dtlbar@yticlist\relax @@ -548,7 +558,7 @@ uppermultibarlabels,groupgap}% \else \ifx\dtlbar@yticlabels\relax \@for\dtl@thislabel:=\dtlbar@yticlist\do{% - \FPround{\dtl@thislabel}{\dtl@thislabel} + \dtlround{\dtl@thislabel}{\dtl@thislabel} {\c@DTLbarroundvar}% \ifDTLverticalbars \settowidth{\dtl@tmplength}{% @@ -608,10 +618,10 @@ uppermultibarlabels,groupgap}% }% \edef\DTLbargroupwidth{\number\@dtl@tmpcount}% \edef\dtl@n{\expandafter\number\csname dtlrows@#3\endcsname} -\FPmul{\dtl@tmpi}{\dtl@n}{\DTLbargroupwidth} -\FPsub{\dtl@tmpii}{\dtl@n}{1}% -\FPmul{\dtl@tmpii}{\dtl@tmpii}{\dtlbar@groupgap}% -\FPadd{\DTLbarchartwidth}{\dtl@tmpi}{\dtl@tmpii} +\dtlmul{\dtl@tmpi}{\dtl@n}{\DTLbargroupwidth} +\dtlsub{\dtl@tmpii}{\dtl@n}{1}% +\dtlmul{\dtl@tmpii}{\dtl@tmpii}{\dtlbar@groupgap}% +\dtladd{\DTLbarchartwidth}{\dtl@tmpi}{\dtl@tmpii} \begin{tikzpicture} \ifDTLverticalbars \pgfsetyvec{\pgfpoint{0pt}{\dtl@unit sp}}% @@ -626,10 +636,10 @@ uppermultibarlabels,groupgap}% \@dtl@barcount = 1\relax \let\dtl@multibar@labels=\dtl@multibarlabels \let\dtl@uppermultibar@labels=\dtl@uppermultibarlabels -\FPmul{\dtl@multimidpt}{\DTLbargroupwidth}{0.5}% -\FPadd{\dtl@multimidpt}{\dtl@multimidpt}{\@dtl@start}% +\dtlmul{\dtl@multimidpt}{\DTLbargroupwidth}{0.5}% +\dtladd{\dtl@multimidpt}{\dtl@multimidpt}{\@dtl@start}% \@for\DTLbarvariable:=\dtlbar@variables\do{% -\FPadd{\@dtl@endpt}{\@dtl@start}{1}% +\dtladd{\@dtl@endpt}{\@dtl@start}{1}% \expandafter\DTLconverttodecimal\expandafter {\DTLbarvariable}{\dtl@variable}% \dtl@chopfirst\dtl@multibar@labels\dtl@thisbarlabel\dtl@rest @@ -658,7 +668,7 @@ uppermultibarlabels,groupgap}% \fi \fi \end{scope} -\FPadd{\@dtl@midpt}{\@dtl@start}{0.5}% +\dtladd{\@dtl@midpt}{\@dtl@start}{0.5}% \ifDTLverticalbars \edef\dtl@textopt{% at={\noexpand\pgfpointadd @@ -715,7 +725,7 @@ uppermultibarlabels,groupgap}% \DTLdisplayuppermultibarlabel{\dtl@thisupperbarlabel}} \def\DTLmidpt{\pgfpointlineattime{0.5}{\DTLstartpt}{\DTLendpt}}% \DTLeverybarhook - \FPadd{\@dtl@start}{\@dtl@start}{1}% + \dtladd{\@dtl@start}{\@dtl@start}{1}% \advance\@dtl@barcount by 1\relax }% \setlength{\dtl@tmplength}{\DTLbarlabeloffset}% @@ -737,7 +747,7 @@ uppermultibarlabels,groupgap}% \fi \expandafter\pgftext\expandafter[\dtl@textopt]{% \DTLdisplaylowerbarlabel{\dtl@barlabel}} - \FPadd{\@dtl@start}{\@dtl@start}{\dtlbar@groupgap}% + \dtladd{\@dtl@start}{\@dtl@start}{\dtlbar@groupgap}% } \ifDTLbarxaxis \ifDTLverticalbars @@ -773,7 +783,7 @@ uppermultibarlabels,groupgap}% \fi \pgfusepath{stroke} \ifx\dtlbar@yticlabels\relax - \FPround{\dtl@thislabel}{\dtl@thistick} + \dtlround{\dtl@thislabel}{\dtl@thistick} {\c@DTLbarroundvar}% \else \dtl@chopfirst\dtlbar@yticlabels\dtl@thislabel\dtl@rest diff --git a/Master/texmf-dist/tex/latex/datatool/databib.sty b/Master/texmf-dist/tex/latex/datatool/databib.sty index 4e45c052256..1229b6dcfc7 100644 --- a/Master/texmf-dist/tex/latex/datatool/databib.sty +++ b/Master/texmf-dist/tex/latex/datatool/databib.sty @@ -7,7 +7,7 @@ %% datatool.dtx (with options: `databib.sty,package') %% %% datatool.dtx -%% Copyright 2009 Nicola Talbot +%% Copyright 2012 Nicola Talbot %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either version 1.3 @@ -21,7 +21,7 @@ %% %% 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, person.sty. +%% This work consists of the files datatool.dtx and datatool.ins and the derived files datatool-base.sty, datatool-fp.sty, datatool-pgfmath.sty, datatool.sty, databib.sty, databar.sty, datapie.sty, dataplot.sty, person.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 @@ -38,13 +38,8 @@ %% Right bracket \] Circumflex \^ Underscore \_ %% Grave accent \` Left brace \{ Vertical bar \| %% Right brace \} Tilde \~} -%% load student information from file "students.csv" -%% Iterate through the student database: -%% Define "anon": -%% Do the letter: -%% Undefine "anon": \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{databib}[2009/10/22 v2.01 (NLCT)] +\ProvidesPackage{databib}[2012/07/18 v2.10 (NLCT)] \RequirePackage{datatool} \newcommand*{\dtlbib@style}{plain} \define@choicekey{databib.sty}{style}{plain,abbrv,alpha}{% diff --git a/Master/texmf-dist/tex/latex/datatool/datapie.sty b/Master/texmf-dist/tex/latex/datatool/datapie.sty index 62916f4638d..f464e584153 100644 --- a/Master/texmf-dist/tex/latex/datatool/datapie.sty +++ b/Master/texmf-dist/tex/latex/datatool/datapie.sty @@ -7,7 +7,7 @@ %% datatool.dtx (with options: `datapie.sty,package') %% %% datatool.dtx -%% Copyright 2009 Nicola Talbot +%% Copyright 2012 Nicola Talbot %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either version 1.3 @@ -21,7 +21,7 @@ %% %% 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, person.sty. +%% This work consists of the files datatool.dtx and datatool.ins and the derived files datatool-base.sty, datatool-fp.sty, datatool-pgfmath.sty, datatool.sty, databib.sty, databar.sty, datapie.sty, dataplot.sty, person.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 @@ -38,13 +38,8 @@ %% Right bracket \] Circumflex \^ Underscore \_ %% Grave accent \` Left brace \{ Vertical bar \| %% Right brace \} Tilde \~} -%% load student information from file "students.csv" -%% Iterate through the student database: -%% Define "anon": -%% Do the letter: -%% Undefine "anon": \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{datapie}[2009/10/22 v2.01 (NLCT)] +\ProvidesPackage{datapie}[2012/07/18 v2.10 (NLCT)] \RequirePackage{xkeyval} \newif\ifDTLcolorpiechart \DTLcolorpiecharttrue diff --git a/Master/texmf-dist/tex/latex/datatool/dataplot.sty b/Master/texmf-dist/tex/latex/datatool/dataplot.sty index 3d67f7823de..29bc2632de6 100644 --- a/Master/texmf-dist/tex/latex/datatool/dataplot.sty +++ b/Master/texmf-dist/tex/latex/datatool/dataplot.sty @@ -7,7 +7,7 @@ %% datatool.dtx (with options: `dataplot.sty,package') %% %% datatool.dtx -%% Copyright 2009 Nicola Talbot +%% Copyright 2012 Nicola Talbot %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either version 1.3 @@ -21,7 +21,7 @@ %% %% 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, person.sty. +%% This work consists of the files datatool.dtx and datatool.ins and the derived files datatool-base.sty, datatool-fp.sty, datatool-pgfmath.sty, datatool.sty, databib.sty, databar.sty, datapie.sty, dataplot.sty, person.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 @@ -38,13 +38,8 @@ %% Right bracket \] Circumflex \^ Underscore \_ %% Grave accent \` Left brace \{ Vertical bar \| %% Right brace \} Tilde \~} -%% load student information from file "students.csv" -%% Iterate through the student database: -%% Define "anon": -%% Do the letter: -%% Undefine "anon": \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{dataplot}[2009/10/22 v2.01 (NLCT)] +\ProvidesPackage{dataplot}[2012/07/18 v2.10 (NLCT)] \RequirePackage{xkeyval} \RequirePackage{tikz} \RequirePackage{datatool} diff --git a/Master/texmf-dist/tex/latex/datatool/datatool-base.sty b/Master/texmf-dist/tex/latex/datatool/datatool-base.sty new file mode 100644 index 00000000000..90e7a0c545a --- /dev/null +++ b/Master/texmf-dist/tex/latex/datatool/datatool-base.sty @@ -0,0 +1,2375 @@ +%% +%% This is file `datatool-base.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% datatool.dtx (with options: `datatool-base.sty,package') +%% +%% datatool.dtx +%% Copyright 2012 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-base.sty, datatool-fp.sty, datatool-pgfmath.sty, datatool.sty, databib.sty, databar.sty, datapie.sty, dataplot.sty, person.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-base}[2012/07/18 v2.10 (NLCT)] +\RequirePackage{etoolbox} +\RequirePackage{amsmath} +\RequirePackage{xkeyval} +\RequirePackage{xfor} +\RequirePackage{ifthen} +\RequirePackage{substr}[2009/10/20] +\ifundef{\ifdtlverbose} +{ + \define@boolkey{datatool-base.sty}[dtl]{verbose}[true]{} +}% +{} +\define@choicekey{datatool-base.sty}{math}[\val\nr]{fp,pgfmath}{% + \renewcommand*\@dtl@mathprocessor{#1}% +} +\providecommand*{\@dtl@mathprocessor}{fp} +\ProcessOptionsX +\RequirePackage{datatool-\@dtl@mathprocessor} +\newcommand*{\dtl@message}[1]{% + \ifdtlverbose\typeout{#1}\fi +} +\newtoks\@dtl@toks +\newcount\@dtl@tmpcount +\newlength\dtl@tmplength +\newcommand{\dtl@ifsingle}[3]{% + \def\@dtl@arg{#1}% + \ifdefempty{\@dtl@arg}% + {% + #3% + }% + {% + \@dtl@ifsingle#1\@nil{#2}{#3}% + }% +} +\def\@dtl@ifsingle#1#2\@nil#3#4{% + \def\dtl@sg@arg{#2}% + \ifdefempty{\dtl@sg@arg}% + {% + #3% + }% + {% + #4% + }% +} +\long\def\long@collect@body#1{% + \@envbody{\@xp#1\@xp{\the\@envbody}}% + \edef\process@envbody{\the\@envbody\@nx\end{\@currenvir}}% + \@envbody\@emptytoks \def\begin@stack{b}% + \begingroup + \@xp\let\csname\@currenvir\endcsname\long@collect@@body + \edef\process@envbody{\@xp\@nx\csname\@currenvir\endcsname}% + \process@envbody +} +\long\def\long@addto@envbody#1{% + \toks@{#1}% + \edef\@dtl@tmp{\the\@envbody\the\toks@}% + \global\@envbody\@xp{\@dtl@tmp}% +} +\long\def\long@collect@@body#1\end#2{% + \protected@edef\begin@stack{% + \long@push@begins#1\begin\end \@xp\@gobble\begin@stack + }% + \ifx\@empty\begin@stack + \endgroup + \@checkend{#2}% + \long@addto@envbody{#1}% + \else + \long@addto@envbody{#1\end{#2}}% + \fi + \process@envbody +} +\long\def\long@push@begins#1\begin#2{% + \ifx\end#2\else b\@xp\long@push@begins\fi +} +\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*{\DTLnumitemsinlist}[2]{% + \@dtl@tmpcount=0\relax + \@for\@dtl@element:=#1\do{% + \ifdefempty{\@dtl@element}% + {}% + {\advance\@dtl@tmpcount by 1\relax}% + }% + \edef#2{\number\@dtl@tmpcount}% +} +\newcommand*{\dtl@choplast}[3]{% + \let#2\@empty + \let#3\@empty + \@for\@dtl@element:=#1\do{% + \ifdefempty{#3}% + {% + }% + {% + \ifdefempty{#2}% + {% + \expandafter\toks@\expandafter{#3}% + \edef#2{{\the\toks@}}% + }% + {% + \expandafter\toks@\expandafter{#3}% + \expandafter\@dtl@toks\expandafter{#2}% + \edef#2{\the\@dtl@toks,{\the\toks@}}% + }% + }% + \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 + \ifdefempty{\@dtl@newsortedlist}% + {% + \expandafter\toks@\expandafter{\@dtl@newstuff}% + \edef\@dtl@newsortedlist{\the\toks@}% + }% + {% + \expandafter\toks@\expandafter{\@dtl@newsortedlist}% + \expandafter\@dtl@toks\expandafter{\@dtl@newstuff}% + \edef\@dtl@newsortedlist{\the\toks@,\the\@dtl@toks}% + }% + \@endforfalse + }% + \ifdefempty{\@dtl@newsortedlist}% + {% + \@dtl@toks{#1}% + \edef\@dtl@newsortedlist{{\the\@dtl@toks}}% + }% + {% + \if@dtl@insertdone + \else + \expandafter\toks@\expandafter{\@dtl@newsortedlist}% + \@dtl@toks{#1}% + \edef\@dtl@newsortedlist{\the\toks@,{\the\@dtl@toks}}% + \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}% +} +\newcount\@dtl@numgrpsepcount +\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\ifdefempty{\noexpand\@dtl@org@currency}% + {% + }% + {% + \noexpand\let\noexpand\@dtl@currency\noexpand\@dtl@org@currency + }% + \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{% + \dtlifnumeq{#2}{0}% + {% + \edef\@dtl@tmpcpz{\@dtl@tmpcpz#1}% + \let\@dtl@chopzeroesnext=\@dtl@gobbletonil + }% + {% + \edef\@dtl@tmpcpz{\@dtl@tmpcpz#1}% + \let\@dtl@chopzeroesnext=\@dtl@chop@trailingzeroes + }% + \@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 + \dtlifnumeq{\@dtl@fracpart}{0}% + {% + \edef#2{\@dtl@intpart}% + }% + {% + \edef#2{\@dtl@intpart\@dtl@decimal\@dtl@fracpart}% + }% +} +\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}% + \dtlifnumeq{\@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 + }% + {% + \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 + }% +} +\@dtl@construct@getnums +\expandafter\@dtl@construct@stripnumgrpchar\expandafter + {\@dtl@numbergroupchar} +\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 + \ifdefempty{\@dtl@replaced}% + {% + }% + {% + \let\@dtl@org@currency=\@dtl@replaced + \@endfortrue + }% + }% + \@endforfalse +} +\newcommand*{\@dtl@currency}{\$} +\newcommand*{\DTLsetdefaultcurrency}[1]{% + \renewcommand*{\@dtl@currency}{#1}% +} +\newcommand*{\DTLadd}[3]{% + \DTLconverttodecimal{#2}{\@dtl@numi}% + \DTLconverttodecimal{#3}{\@dtl@numii}% + \dtladd{\@dtl@tmp}{\@dtl@numi}{\@dtl@numii}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@tmp}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + }% +} +\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{% + \expandafter\DTLconverttodecimal\expandafter{\dtl@thisval}{\@dtl@num}% + \dtladd{\@dtl@sum}{\@dtl@sum}{\@dtl@num}% + }% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@sum}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@sum}{#1}% + }% +} +\newcommand*{\DTLgaddall}[2]{% + \DTLaddall{\@dtl@tmpi}{#2}% + \global\let#1=\@dtl@tmpi +} +\newcommand*{\DTLsub}[3]{% + \DTLconverttodecimal{#2}{\@dtl@numi}% + \DTLconverttodecimal{#3}{\@dtl@numii}% + \dtlsub{\@dtl@tmp}{\@dtl@numi}{\@dtl@numii}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@tmp}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + }% +} +\newcommand*{\DTLgsub}[3]{% + \DTLsub{\@dtl@tmpii}{#2}{#3}% + \global\let#1=\@dtl@tmpii +} +\newcommand*{\DTLmul}[3]{% + \let\@dtl@thisreplaced=\@empty + \DTLconverttodecimal{#2}{\@dtl@numi}% + \ifdefempty{\@dtl@replaced}% + {% + }% + {% + \let\@dtl@thisreplaced=\@dtl@replaced + }% + \DTLconverttodecimal{#3}{\@dtl@numii}% + \ifdefempty{\@dtl@replaced}% + {% + }% + {% + \let\@dtl@thisreplaced=\@dtl@replaced + }% + \dtlmul{\@dtl@tmp}{\@dtl@numi}{\@dtl@numii}% + \ifdefempty{\@dtl@thisreplaced}% + {% + \DTLdecimaltolocale{\@dtl@tmp}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + }% +} +\newcommand*{\DTLgmul}[3]{% + \DTLmul{\@dtl@tmpii}{#2}{#3}% + \global\let#1=\@dtl@tmpii +} +\newcommand*{\DTLdiv}[3]{% + \let\@dtl@thisreplaced=\@empty + \DTLconverttodecimal{#2}{\@dtl@numi}% + \ifdefempty{\@dtl@replaced}% + {% + }% + {% + \let\@dtl@thisreplaced=\@dtl@replaced + }% + \DTLconverttodecimal{#3}{\@dtl@numii}% + \dtldiv{\@dtl@tmp}{\@dtl@numi}{\@dtl@numii}% + \ifdefempty{\@dtl@thisreplaced}% + {% + \DTLdecimaltolocale{\@dtl@tmp}{#1}% + }% + {% + \ifdefequal{\@dtl@thisreplaced}{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@tmp}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + }% + }% +} +\newcommand*{\DTLgdiv}[3]{% + \DTLdiv{\@dtl@tmpii}{#2}{#3}% + \global\let#1=\@dtl@tmpii +} +\newcommand*{\DTLabs}[2]{% + \DTLconverttodecimal{#2}{\@dtl@numi}% + \dtlabs{\@dtl@tmp}{\@dtl@numi}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@tmp}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + }% +} +\newcommand*{\DTLgabs}[2]{% + \DTLabs{\@dtl@tmpii}{#2}% + \global\let#1=\@dtl@tmpii +} +\newcommand*{\DTLneg}[2]{% + \DTLconverttodecimal{#2}{\@dtl@numi}% + \dtlneg{\@dtl@tmp}{\@dtl@numi}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@tmp}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + }% +} +\newcommand*{\DTLgneg}[2]{% + \DTLneg{\@dtl@tmpii}{#2}% + \global\let#1=\@dtl@tmpii +} +\newcommand*{\DTLsqrt}[2]{% + \DTLconverttodecimal{#2}{\@dtl@numi}% + \dtlroot{\@dtl@tmpi}{\@dtl@numi}{2}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@tmpi}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@tmpi}{#1}% + }% +} +\newcommand*{\DTLgsqrt}[2]{% +\DTLsqrt{\@dtl@tmpii}{#2}% +\global\let#1=\@dtl@tmpii +} +\newcommand*{\DTLmin}[3]{% + \DTLconverttodecimal{#2}{\@dtl@numi}% + \DTLconverttodecimal{#3}{\@dtl@numii}% + \dtlifnumlt{\@dtl@numi}{\@dtl@numii}% + {% + \dtl@ifsingle{#2}% + {\let#1=#2}% + {\def#1{#2}}% + }% + {% + \dtl@ifsingle{#3}% + {\let#1=#3}% + {\def#1{#3}}% + }% +} +\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{% + \expandafter\DTLconverttodecimal\expandafter{\dtl@thisval}{\@dtl@num}% + \ifdefempty{\@dtl@min}% + {% + \let\@dtl@min=\@dtl@num + }% + {% + \dtlmin{\@dtl@min}{\@dtl@min}{\@dtl@num}% + }% + }% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@min}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@min}{#1}% + }% +} +\newcommand*{\DTLgminall}[2]{% + \DTLminall{\@dtl@tmpi}{#2}% + \global\let#1=\@dtl@tmpi +} +\newcommand*{\DTLmax}[3]{% + \DTLconverttodecimal{#2}{\@dtl@numi}% + \DTLconverttodecimal{#3}{\@dtl@numii}% + \dtlmax{\@dtl@tmp}{\@dtl@numi}{\@dtl@numii}% + \dtlifnumgt{\@dtl@numi}{\@dtl@numii}% + {% + \dtl@ifsingle{#2}% + {\let#1=#2}% + {\def#1{#2}}% + }% + {% + \dtl@ifsingle{#3}% + {\let#1=#3}% + {\def#1{#3}}% + }% +} +\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{% + \expandafter\DTLconverttodecimal\expandafter{\dtl@thisval}{\@dtl@num}% + \ifdefempty{\@dtl@max}% + {% + \let\@dtl@max\@dtl@num + }% + {% + \dtlmax{\@dtl@max}{\@dtl@max}{\@dtl@num}% + }% + }% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@max}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@max}{#1}% + }% +} +\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{% + \expandafter\DTLconverttodecimal\expandafter{\dtl@thisval}{\@dtl@num}% + \dtladd{\@dtl@mean}{\@dtl@mean}{\@dtl@num}% + \dtladd{\@dtl@n}{\@dtl@n}{1}% + }% + \dtldiv{\@dtl@mean}{\@dtl@mean}{\@dtl@n}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@mean}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@mean}{#1}% + }% +} +\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{% + \expandafter\DTLconverttodecimal\expandafter{\dtl@thisval}{\@dtl@num}% + \ifdefempty{\@dtl@decvals}% + {% + \let\@dtl@decvals=\@dtl@num + }% + {% + \expandafter\toks@\expandafter{\@dtl@decvals}% + \edef\@dtl@decvals{\the\toks@,\@dtl@num}% + }% + \dtladd{\@dtl@mean}{\@dtl@mean}{\@dtl@num}% + \dtladd{\@dtl@n}{\@dtl@n}{1}% + }% + \dtldiv{\@dtl@mean}{\@dtl@mean}{\@dtl@n}% + \def\@dtl@var{0}% + \@for\@dtl@num:=\@dtl@decvals\do{% + \dtlsub{\@dtl@diff}{\@dtl@num}{\@dtl@mean}% + \dtlmul{\@dtl@diff}{\@dtl@diff}{\@dtl@diff}% + \dtladd{\@dtl@var}{\@dtl@var}{\@dtl@diff}% + }% + \dtldiv{\@dtl@var}{\@dtl@var}{\@dtl@n}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@var}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@var}{#1}% + }% +} +\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{% + \expandafter\DTLconverttodecimal\expandafter{\dtl@thisval}{\@dtl@num}% + \ifdefempty{\@dtl@decvals}% + {% + \let\@dtl@decvals=\@dtl@num + }% + {% + \expandafter\toks@\expandafter{\@dtl@decvals}% + \edef\@dtl@decvals{\the\toks@,\@dtl@num}% + }% + \dtladd{\@dtl@mean}{\@dtl@mean}{\@dtl@num}% + \dtladd{\@dtl@n}{\@dtl@n}{1}% + }% + \dtldiv{\@dtl@mean}{\@dtl@mean}{\@dtl@n}% + \def\@dtl@sd{0}% + \@for\@dtl@num:=\@dtl@decvals\do{% + \dtlsub{\@dtl@diff}{\@dtl@num}{\@dtl@mean}% + \dtlmul{\@dtl@diff}{\@dtl@diff}{\@dtl@diff}% + \dtladd{\@dtl@sd}{\@dtl@sd}{\@dtl@diff}% + }% + \dtldiv{\@dtl@sd}{\@dtl@sd}{\@dtl@n}% + \dtlroot{\@dtl@sd}{\@dtl@sd}{2}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@sd}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@sd}{#1}% + }% +} +\newcommand*{\DTLgsdforall}[2]{% + \DTLsdforall{\@dtl@tmpi}{#2}% + \global\let#1=\@dtl@tmpi +} +\newcommand*{\DTLround}[3]{% + \DTLconverttodecimal{#2}{\@dtl@numi}% + \dtlround{\@dtl@tmp}{\@dtl@numi}{#3}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@tmp}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + }% +} +\newcommand*{\DTLground}[3]{% + \DTLround{\@dtl@tmpii}{#2}{#3}% + \global\let#1=\@dtl@tmpii +} +\newcommand*{\DTLtrunc}[3]{% + \DTLconverttodecimal{#2}{\@dtl@numi}% + \dtltrunc{\@dtl@tmp}{\@dtl@numi}{#3}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@tmp}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + }% +} +\newcommand*{\DTLgtrunc}[3]{% + \DTLtrunc{\@dtl@tmpii}{#2}{#3}% + \global\let#1=\@dtl@tmpii +} +\newcommand*{\DTLclip}[2]{% + \DTLconverttodecimal{#2}{\@dtl@numi}% + \dtlclip{\@dtl@tmp}{\@dtl@numi}% + \ifdefempty{\@dtl@replaced}% + {% + \DTLdecimaltolocale{\@dtl@tmp}{#1}% + }% + {% + \DTLdecimaltocurrency{\@dtl@tmp}{#1}% + }% +} +\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}% + \ifdefempty{\dtl@inithyphen}% + {% + }% + {% + \edef\dtl@initialscmd{\the\@dtl@toks\the\toks@}% + \expandafter\@dtl@toks\expandafter{\dtl@initialscmd}% + \expandafter\toks@\expandafter{\dtl@inithyphen}% + }% + \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}% + \ifdefempty{\dtl@inithyphen}% + {% + }% + {% + \edef\dtl@inithyphen{% + \DTLafterinitialbeforehyphen\DTLinitialhyphen#2}% + }% +} +\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 + }% + }% +} +\newcommand{\DTLsubstitute}[3]{% + \expandafter\DTLsplitstring\expandafter + {#1}{#2}{\@dtl@beforepart}{\@dtl@afterpart}% + \ifdefempty{\@dtl@replaced}% + {% + }% + {% + \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}% + }% +} +\newcommand*{\DTLsplitstring}[4]{% + \def\dtl@splitstr##1#2##2\@nil{% + \def#3{##1}% + \def#4{##2}% + \ifdefempty{#4}% + {% + \let\@dtl@replaced=\@empty + }% + {% + \def\@dtl@replaced{#2}% + \dtl@split@str##2\@nil + }% + }% + \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}% + \long\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}% + \ifdefempty{\@dtl@replaced}% + {% + \let\@dtl@dosubstnext=\@dtl@dosubstitutenoop + }% + {% + \expandafter\toks@\expandafter{\@dtl@splitsubstr}% + \@dtl@toks{#2}% + \edef\@dtl@splitsubstr{\the\toks@\the\@dtl@toks}% + \let\@dtl@dosubstnext=\@dtl@dosubstitute + }% + \@dtl@dosubstnext{#1}{#2}% +} +\def\@dtl@dosubstitutenoop#1#2{} +\newif\if@dtl@condition +\newcount\@dtl@datatype +\newcommand{\@dtl@checknumerical}[1]{% + \@dtl@numgrpsepfalse + \def\@dtl@tmp{#1}% + \ifstrempty{#1}% + {% + \@dtl@datatype=0\relax + }% + {% + \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 + \ifdefempty{\@dtl@org@currency}% + {% + }% + {% + \let\@dtl@currency\@dtl@org@currency + }% + \expandafter\@dtl@checknumericalstart\@dtl@tmp\@nil\@nil + }% + \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\relax + \@dtl@checknumericalstart#2\@nil\@nil\relax +\else + \ifx-#1\relax + \def\@dtl@tmp{#2}% + \ifdefempty{\@dtl@tmp}% + {% + \@dtl@datatype=0\relax + }% + {% + \ifnum\@dtl@datatype=0\relax + \@dtl@datatype=1\relax + \fi + \@dtl@checknumericalstart#2\@nil\@nil\relax + }% + \else + \ifx+#1\relax + \def\@dtl@tmp{#2}% + \ifdefempty{\@dtl@tmp}% + {% + \@dtl@datatype=0\relax + }% + {% + \ifnum\@dtl@datatype=0\relax + \@dtl@datatype=1\relax + \fi + \@dtl@checknumericalstart#2\@nil\@nil\relax + }% + \else + \def\@dtl@tmp{#1}% + \ifx#1\$\relax + \@dtl@datatype=3\relax + \@dtl@checknumericalstart#2\@nil\@nil\relax + \else + \ifdefempty{\@dtl@tmp}% + {% + \@dtl@datatype=0\relax + }% + {% + \ifnum\@dtl@datatype=0\relax + \@dtl@datatype=1\relax + \fi + \@dtl@checknumericalloop#1#2\@nil\@nil\relax + }% + \fi + \fi + \fi +\fi +} +\newif\if@dtl@numgrpsep +\newcommand*{\@dtl@ifDigitOrDecimalSep}[3]{% + \ifnum 9<1\noexpand#1\relax + #2% + \else + \expandafter\ifx\@dtl@decimal#1\relax + #2% + \else + #3% + \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}% + \dtlifnumlt{\@dtl@numi}{\@dtl@numii}% + {% + #3% + }% + {% + #4% + }% +} +\newcommand*{\dtlcompare}[3]{% + \dtl@subnobrsp{#2}{\@dtl@argA}% + \dtl@subnobrsp{#3}{\@dtl@argB}% + \ifdefempty{\@dtl@argA}% + {% + \ifdefempty{\@dtl@argB}% + {% + #1=0\relax + }% + {% + #1=-1\relax + }% + }% + {% + \ifdefempty{\@dtl@argB}% + {% + #1=1\relax + }% + {% + \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 + \ifdefempty{\dtl@restA}% + {% + \ifdefempty{\dtl@restB}% + {% + #1=0\relax + }% + {% + #1=-1\relax + }% + }% + {% + \ifdefempty{\restB}% + {% + #1=1\relax + }% + {% + \protected@edef\dtl@donext{% + \noexpand\dtlcompare + {\noexpand#1}{\dtl@restA}{\dtl@restB}}% + \dtl@donext + }% + }% + \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 + }% + }% + }% +} +\def\dtl@getfirst#1#2\end{% + \def\dtl@first{#1}% + \ifdefempty{\dtl@first}% + {% + \def\dtl@rest{#2}% + }% + {% + \dtl@ifsingle{#1}{\def\dtl@rest{#2}}{\dtl@getfirst#1#2\end}% + }% +} +\newcount\dtl@codeA +\newcount\dtl@codeB +\newcommand*{\dtl@setcharcode}[2]{% + \ifstrempty{#1}% + {% + #2=-1\relax + }% + {% + \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 + }% +} +\newcommand*{\dtl@setlccharcode}[2]{% + \ifstrempty{#1}% + {% + #2=-1\relax + }% + {% + \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 + }% +} +\newcommand*{\dtlicompare}[3]{% + \dtl@subnobrsp{#2}{\@dtl@argA}% + \dtl@subnobrsp{#3}{\@dtl@argB}% + \ifdefempty{\@dtl@argA}% + {% + \ifdefempty{\@dtl@argB}% + {% + #1=0\relax + }% + {% + #1=-1\relax + }% + }% + {% + \ifdefempty{\@dtl@argB}% + {% + #1=1\relax + }% + {% + \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 + \ifdefempty{\dtl@restA}% + {% + \ifdefempty{\dtl@restB}% + {% + #1=0\relax + }% + {% + #1=-1\relax + }% + }% + {% + \ifdefempty{\restB}% + {% + #1=1\relax + }% + {% + \protected@edef\dtl@donext{% + \noexpand\dtlicompare + {\noexpand#1}{\dtl@restA}{\dtl@restB}}% + \dtl@donext + }% + }% + \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 + }% + }% + }% +} +\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}% + \dtlifnumgt{\@dtl@numi}{\@dtl@numii}% + {% + #3% + }% + {% + #4% + }% +} +\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}% + \dtlifnumeq{\@dtl@numi}{\@dtl@numii}% + {% + #3% + }% + {% + #4% + }% +} +\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}% + \ifdefempty{\@dtl@argB}% + {% + \@dtl@conditiontrue + }% + {% + \ifdefempty{\@dtl@argA}% + {% + \@dtl@conditionfalse + }% + {% + \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 + }% + }% +} +\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}% + \ifdefempty{\@dtl@argA}% + {% + \ifdefempty{\@dtl@argB}% + {% + \@dtl@conditiontrue + }% + {% + \@dtl@conditionfalse + }% + }% + {% + \ifdefempty{\@dtl@argB}% + {% + \@dtl@conditiontrue + }% + {% + \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}}% + }% + }% + }% +} +\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 +} +\let\DTLifFPopenbetween\dtlifnumopenbetween +\let\DTLifFPclosedbetween\dtlifnumclosedbetween +\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@testnumclosedbetween}[3]{% + \DTLifnumclosedbetween{#1}{#2}{#3}% + {\@dtl@conditiontrue}{\@dtl@conditionfalse}% +} +\newcommand*{\DTLisnumclosedbetween}[3]{% + \TE@throw\noexpand\dtl@testnumclosedbetween{#1}{#2}{#3}% + \noexpand\if@dtl@condition +} +\newcommand*{\dtl@testnumopenbetween}[3]{% + \DTLifnumopenbetween{#1}{#2}{#3}% + {\@dtl@conditiontrue}{\@dtl@conditionfalse}% +} +\newcommand*{\DTLisnumopenbetween}[3]{% + \TE@throw\noexpand\dtl@testnumopenbetween{#1}{#2}{#3}% + \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 +} +\let\DTLisFPclosedbetween\DTLisnumclosedbetween +\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]{% + \dtlifnumlt{#1}{#2}% + {% + \@dtl@conditiontrue + }% + {% + \@dtl@conditionfalse + }% +} +\newcommand*{\DTLisFPlt}[2]{% + \TE@throw\noexpand\dtl@testFPislt{#1}{#2}% + \noexpand\if@dtl@condition +} +\newcommand*{\dtl@testFPisgt}[2]{% + \dtlifnumgt{#1}{#2}% + {% + \@dtl@conditiontrue + }% + {% + \@dtl@conditionfalse + }% +} +\newcommand*{\DTLisFPgt}[2]{% + \TE@throw\noexpand\dtl@testFPisgt{#1}{#2}% + \noexpand\if@dtl@condition +} +\newcommand*{\dtl@testFPiseq}[2]{% + \dtlifnumeq{#1}{#2}% + {% + \@dtl@conditiontrue + }% + {% + \@dtl@conditionfalse + }% +} +\newcommand*{\DTLisFPeq}[2]{% + \TE@throw\noexpand\dtl@testFPiseq{#1}{#2}% + \noexpand\if@dtl@condition +} +\newcommand*{\dtl@testFPislteq}[2]{% + \dtlifnumlt{#1}{#2}% + {% + \@dtl@conditiontrue + }% + {% + \@dtl@conditionfalse + }% + \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]{% + \dtlifnumgt{#1}{#2}% + {% + \@dtl@conditiontrue + }% + {% + \@dtl@conditionfalse + }% + \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*{\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 +} +\newenvironment{dtlenvgforint}[1]% +{% + \def\@dtlenvgforint@arg{#1}% + \long@collect@body\@do@dtlenvgforint +}% +{} +\newcommand{\@do@dtlenvgforint}[1]{% + \expandafter\dtlgforint\@dtlenvgforint@arg\do{#1}% +} +\endinput +%% +%% End of file `datatool-base.sty'. diff --git a/Master/texmf-dist/tex/latex/datatool/datatool-fp.sty b/Master/texmf-dist/tex/latex/datatool/datatool-fp.sty new file mode 100644 index 00000000000..135d81f2c5b --- /dev/null +++ b/Master/texmf-dist/tex/latex/datatool/datatool-fp.sty @@ -0,0 +1,164 @@ +%% +%% This is file `datatool-fp.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% datatool.dtx (with options: `datatool-fp.sty,package') +%% +%% datatool.dtx +%% Copyright 2012 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-base.sty, datatool-fp.sty, datatool-pgfmath.sty, datatool.sty, databib.sty, databar.sty, datapie.sty, dataplot.sty, person.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-fp}[2012/07/18 v2.10 (NLCT)] +\RequirePackage{xkeyval} +\RequirePackage{fp} +\RequirePackage{datatool-base} +\define@choicekey{datatool-fp}{verbose}[\val\nr]{true,false}[true]{% + \ifcase\nr\relax + \FPmessagestrue + \or + \FPmessagesfalse + \fi +} +\let\ifFPmessages\ifdtlverbose +\ProcessOptionsX +\providecommand*{\@dtl@mathprocessor}{fp} +\newcommand*{\dtlifnumeq}[4]{% + \FPifeq{#1}{#2}% + #3% + \else + #4% + \fi +} +\let\ifdtlverbose\ifFPmessages +\newcommand*{\dtlifnumlt}[4]{% + \FPiflt{#1}{#2}% + #3% + \else + #4% + \fi +} +\newcommand*{\dtlifnumgt}[4]{% + \FPifgt{#1}{#2}% + #3% + \else + #4% + \fi +} +\newcommand*{\dtlifnumopenbetween}[5]{% + \let\@dtl@dovalue\relax + \dtlifnumgt{#1}{#2}% + {}% + {% + \def\@dtl@dovalue{#5}% + }% + \dtlifnumlt{#1}{#3}% + {% + \ifx\@dtl@dovalue\relax + \def\@dtl@dovalue{#4}% + \fi + }% + {% + \def\@dtl@dovalue{#5}% + }% + \@dtl@dovalue +} +\newcommand*{\dtlifnumclosedbetween}[5]{% + \let\@dtl@dovalue\relax + \dtlifnumgt{#1}{#2}% + {}% + {% + \dtlifnumeq{#1}{#2}% + {% + \def\@dtl@dovalue{#4}% + }% + {% + \def\@dtl@dovalue{#5}% + }% + }% + \dtlifnumlt{#1}{#3}% + {% + \ifx\@dtl@dovalue\relax + \def\@dtl@dovalue{#4}% + \fi + }% + {% + \dtlifnumeq{#1}{#3}% + {% + \def\@dtl@dovalue{#4}% + }% + {% + \def\@dtl@dovalue{#5}% + }% + }% + \@dtl@dovalue +} +\newcommand*{\dtladd}[3]{% + \FPadd{#1}{#2}{#3}% +} +\newcommand*{\dtlsub}[3]{% + \FPsub{#1}{#2}{#3}% +} +\newcommand*{\dtlmul}[3]{% + \FPmul{#1}{#2}{#3}% +} +\newcommand*{\dtldiv}[3]{% + \FPdiv{#1}{#2}{#3}% +} +\newcommand*{\dtlroot}[2]{% + \FProot{#1}{#2}% +} +\newcommand*{\dtlround}[3]{% + \FPround{#1}{#2}{#3}% +} +\newcommand*{\dtltrunc}[3]{% + \FPtrunc{#1}{#2}{#3}% +} +\newcommand*{\dtlclip}[2]{% + \FPclip{#1}{#2}% +} +\newcommand*{\dtlmin}[3]{% + \FPmin{#1}{#2}{#3}% +} +\newcommand*{\dtlmax}[3]{% + \FPmax{#1}{#2}{#3}% +} +\newcommand*{\dtlabs}[2]{% + \FPabs{#1}{#2}% +} +\newcommand*{\dtlneg}[2]{% + \FPneg{#1}{#2}% +} +\endinput +%% +%% End of file `datatool-fp.sty'. diff --git a/Master/texmf-dist/tex/latex/datatool/datatool-pgfmath.sty b/Master/texmf-dist/tex/latex/datatool/datatool-pgfmath.sty new file mode 100644 index 00000000000..4da81dbc76f --- /dev/null +++ b/Master/texmf-dist/tex/latex/datatool/datatool-pgfmath.sty @@ -0,0 +1,121 @@ +%% +%% This is file `datatool-pgfmath.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% datatool.dtx (with options: `datatool-pgfmath.sty,package') +%% +%% datatool.dtx +%% Copyright 2012 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-base.sty, datatool-fp.sty, datatool-pgfmath.sty, datatool.sty, databib.sty, databar.sty, datapie.sty, dataplot.sty, person.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-pgfmath}[2012/07/18 v2.10 (NLCT)] +\RequirePackage{xkeyval} +\RequirePackage{pgfrcs,pgfkeys,pgfmath} +\ProcessOptionsX +\providecommand*{\@dtl@mathprocessor}{pgfmath} +\newcommand*{\dtlifnumeq}[4]{% + \pgfmathifthenelse{#1==#2}{"#3"}{"#4"}% + \pgfmathresult +} +\RequirePackage{datatool-base} +\newcommand*{\dtlifnumlt}[4]{% + \pgfmathifthenelse{#1 < #2}{"#3"}{"#4"}% + \pgfmathresult +} +\newcommand*{\dtlifnumgt}[4]{% + \pgfmathifthenelse{#1 > #2}{"#3"}{"#4"}% + \pgfmathresult +} +\newcommand*{\dtlifnumopenbetween}[5]{% + \pgfmathifthenelse{(#2 < #1) && (#1 < #3)}{"#4"}{"#5"}% + \pgfmathresult +} +\newcommand*{\dtlifnumclosedbetween}[5]{% + \pgfmathifthenelse{(#2 <= #1) && (#1 <= #3)}{"#4"}{"#5"}% + \pgfmathresult +} +\newcommand*{\dtladd}[3]{% + \pgfmathadd{#2}{#3}% + \let#1\pgfmathresult +} +\newcommand*{\dtlsub}[3]{% + \pgfmathsubtract{#2}{#3}% + \let#1\pgfmathresult +} +\newcommand*{\dtlmul}[3]{% + \pgfmathmultiply{#2}{#3}% + \let#1\pgfmathresult +} +\newcommand*{\dtldiv}[3]{% + \pgfmathdivide{#2}{#3}% + \let#1\pgfmathresult +} +\newcommand*{\dtlroot}[2]{% + \pgfmathsqrt{#2}% + \let#1\pgfmathresult +} +\newcommand*{\dtlround}[3]{% + \pgfmathparse{10^#3}% + \let\dtl@tmpshift\pgfmathresult + \pgfmathparse{round(#2 * \dtl@tmpshift) / \dtl@tmpshift}% + \let#1\pgfmathresult +} +\newcommand*{\dtltrunc}[3]{% + \pgfmathparse{10^#3}% + \let\dtl@tmpshift\pgfmathresult + \pgfmathparse{floor(#2 * \dtl@tmpshift) / \dtl@tmpshift}% + \let#1\pgfmathresult +} +\newcommand*{\dtlclip}[2]{% + \edef#1{#2}% +} +\newcommand*{\dtlmin}[3]{% + \pgfmathmin{#2}{#3}% + \let#1\pgfmathresult +} +\newcommand*{\dtlmax}[3]{% + \pgfmathmax{#2}{#3}% + \let#1\pgfmathresult +} +\newcommand*{\dtlabs}[2]{% + \pgfmathabs{#2}% + \let#1\pgfmathresult +} +\newcommand*{\dtlneg}[2]{% + \pgfmathmul{-1}{#2}% + \let#1\pgfmathresult +} +\endinput +%% +%% End of file `datatool-pgfmath.sty'. diff --git a/Master/texmf-dist/tex/latex/datatool/datatool.sty b/Master/texmf-dist/tex/latex/datatool/datatool.sty index 8306dba927c..103f7daa59a 100644 --- a/Master/texmf-dist/tex/latex/datatool/datatool.sty +++ b/Master/texmf-dist/tex/latex/datatool/datatool.sty @@ -7,7 +7,7 @@ %% datatool.dtx (with options: `datatool.sty,package') %% %% datatool.dtx -%% Copyright 2009 Nicola Talbot +%% Copyright 2012 Nicola Talbot %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either version 1.3 @@ -21,7 +21,7 @@ %% %% 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, person.sty. +%% This work consists of the files datatool.dtx and datatool.ins and the derived files datatool-base.sty, datatool-fp.sty, datatool-pgfmath.sty, datatool.sty, databib.sty, databar.sty, datapie.sty, dataplot.sty, person.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 @@ -38,29 +38,23 @@ %% Right bracket \] Circumflex \^ Underscore \_ %% Grave accent \` Left brace \{ Vertical bar \| %% Right brace \} Tilde \~} -%% load student information from file "students.csv" -%% Iterate through the student database: -%% Define "anon": -%% Do the letter: -%% Undefine "anon": \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{datatool}[2009/11/15 v2.03 (NLCT)] +\ProvidesPackage{datatool}[2012/07/18 v2.10 (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 + \renewcommand*{\@dtl@separator}{#1}% + \@dtl@construct@lopoffs } \begingroup -\catcode`\ 12 +\catcode`\^^I12 \gdef\DTLsettabseparator{% - \catcode`\ 12 - \DTLsetseparator{ }% + \catcode`\^^I12 + \DTLsetseparator{^^I}% } \endgroup \begingroup @@ -68,1300 +62,61 @@ \gdef\@dtl@delimiter{"} \endgroup \newcommand*\DTLsetdelimiter[1]{% -\renewcommand*{\@dtl@delimiter}{#1}% -\@dtl@construct@lopoffs} + \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 -}} + \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}% -}} + \noexpand\long + \noexpand\def\noexpand\@dtl@qlopoff#1#2##1#2#1##2\noexpand\to##3##4{% + \noexpand\def##4{##1}% + \noexpand\DTLsubstituteall{##4}{#2#2}{#2}% + \noexpand\edef\noexpand\@dtl@dosubs{% + \noexpand\noexpand\noexpand\DTLsubstituteall{\noexpand\noexpand##4}% + {\noexpand\expandafter\noexpand\noexpand\noexpand\csname#2\noexpand\endcsname#2}% + {\noexpand\expandafter\noexpand\noexpand\noexpand\csname#2\noexpand\endcsname}% + }% + \noexpand\@dtl@dosubs + \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 + \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}% + }% } -\def\@dtl@get@next@intpart#1.\relax{% -\edef\@dtl@intpart{\@dtl@intpart#1}% +\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@choptrailingzeroes}[1]{% -\def\@dtl@tmpcpz{}% -\expandafter\@dtl@chop@trailingzeroes#1\@nil% -\let#1=\@dtl@tmpcpz +\define@key{datatool.sty}{separator}{% + \DTLsetseparator{#1}% } -\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 -}% +\define@key{datatool.sty}{delimiter}{% + \DTLsetdelimiter{#1}% } -\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 +\define@boolkey{datatool.sty}[dtl]{verbose}[true]{} +\define@choicekey{datatool.sty}{math}[\val\nr]{fp,pgfmath}{% + \renewcommand*\@dtl@mathprocessor{#1}% } -\@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} +\newcommand*{\@dtl@mathprocessor}{fp} \ProcessOptionsX +\@dtl@construct@lopoffs +\RequirePackage{datatool-base} \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}% {% @@ -1410,9 +165,11 @@ }% } \newcommand*{\DTLrowcount}[1]{% -\expandafter\number\csname dtlrows@#1\endcsname} + \expandafter\number\csname dtlrows@#1\endcsname +} \newcommand*{\DTLcolumncount}[1]{% -\expandafter\number\csname dtlcols@#1\endcsname} + \expandafter\number\csname dtlcols@#1\endcsname +} \newcommand{\DTLifdbempty}[3]{% \DTLifdbexists{#1}% {\@DTLifdbempty{#1}{#2}{#3}}% @@ -1531,10 +288,10 @@ \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 + \edef\@dtl@tmp{\expandafter\the\csname dtlkeys@#2\endcsname}% + \expandafter\@dtl@get@keyforcolumn\@dtl@tmp \db@plist@elt@w% start of block - \db@col@id@w #3\db@col@id@end@ index + \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 @@ -1617,14 +374,17 @@ {\noexpand\@dtl@after}{\the\csname dtlkeys@#1\endcsname}% {\number\dtlcolumnnum}} \@dtl@dogetprops - \def\@dtl@tmp{#3}% - \ifx\@dtl@tmp\@empty - \else + \ifstrempty{#3}% + {% + }% + {% \let\@dtl@oldtype\@dtl@type \@dtl@checknumerical{#3}% - \ifx\@dtl@type\@empty + \ifdefempty{\@dtl@type}% + {% \edef\@dtl@type{\number\@dtl@datatype}% - \else + }% + {% \ifcase\@dtl@datatype % string \def\@dtl@type{0}% \or % int @@ -1637,7 +397,7 @@ \def\@dtl@type{3}% \fi \fi - \fi + }% \ifx\@dtl@oldtype\@dtl@type \else \toks@gconcat@middle@cx{dtlkeys@#1}% @@ -1657,7 +417,7 @@ }% {\@dtl@after}% \fi - \fi + }% }% {% \expandafter\global\expandafter\advance @@ -1665,13 +425,14 @@ \dtlcolumnnum=\csname dtlcols@#1\endcsname\relax \expandafter\xdef\csname dtl@ci@#1@#2\endcsname{% \number\dtlcolumnnum}% - \def\@dtl@tmp{#3}% - \ifx\@dtl@tmp\@empty + \ifstrempty{#2}% + {% \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 @@ -1792,6 +553,12 @@ } \newcommand{\DTLifdbexists}[3]{% \@ifundefined{dtldb@#1}{#3}{#2}} +\newcommand*{\DTLassign}[3]{% + {% + \dtlgetrow{#1}{#2}% + \@dtl@assign{#3}{#1}% + }% +} \newcommand*{\@dtl@assign}[2]{% \@dtl@assigncmd#1,\@nil\@@{#2}% } @@ -1896,6 +663,8 @@ \newtoks\dtlbeforerow \newtoks\dtlafterrow \newcommand*{\dtlgetrow}[2]{% + \dtlrownum=#2\relax + \edef\dtldbname{#1}% \expandafter\toks@\expandafter=\csname dtldb@#1\endcsname \edef\@dtl@dogetrow{\noexpand\@dtlgetrow{\the\toks@}{\number#2}}% \@dtl@dogetrow @@ -1911,6 +680,86 @@ \q@nil{\dtlbeforerow={##1}\dtlcurrentrow={##2}\dtlafterrow={##3}}% \@dtl@getrow#1\q@nil } +\newcommand*{\dtlrecombine}{% + \toks@gconcat@middle@cx{dtldb@\dtldbname}% + {\dtlbeforerow}% + {% + \noexpand\db@row@elt@w + \noexpand\db@row@id@w + \number\dtlrownum + \noexpand\db@row@id@end@ + \the\dtlcurrentrow + \noexpand\db@row@id@w + \number\dtlrownum + \noexpand\db@row@id@end@ + \noexpand\db@row@elt@end@ + }% + {\dtlafterrow}% +} +\newcommand{\dtlrecombineomitcurrent}{% + \dtl@decrementrows{\dtlafterrow}{\dtlrownum} + \csname dtldb@\dtldbname\endcsname=\dtlbeforerow + \toks@gput@right@cx{dtldb@\dtldbname}{\the\dtlafterrow}% + \dtl@message{Removed row \number\dtlrownum\space in database + `\dtldbname'}% +} +\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 +} +\newcommand*{\dtlreplaceentryincurrentrow}[2]{% + \edef\@dtl@do@splitrow{\noexpand\dtlsplitrow + {\the\dtlcurrentrow}% + {\number#2}% + {\noexpand\@dtl@before@cs}% + {\noexpand\@dtl@after@cs}}% + \@dtl@do@splitrow + \toks@{#1}% + \edef\@dtl@stuff{% + \expandonce\@dtl@before@cs + \noexpand\db@col@id@w \number#2\noexpand + \noexpand\db@col@id@end@% column id + \noexpand\db@col@elt@w + \the\toks@ + \noexpand\db@col@elt@end@ + \noexpand\db@col@id@w \number#2\noexpand + \noexpand\db@col@id@end@% column id + \expandonce\@dtl@after@cs + }% + \expandafter\dtlcurrentrow\expandafter{\@dtl@stuff}% + \@sdtlgetkeyforcolumn{\@dtl@key}{\dtldbname}{#2}% + \@dtl@updatekeys{\dtldbname}{\@dtl@key}{#1}% + \dtl@message{Updated \@dtl@key\space -> #1\space in database + `\dtldbname'}% +} +\newcommand*{\dtlremoveentryincurrentrow}[1]{% + \edef\@dtl@do@splitrow{\noexpand\dtlsplitrow + {\the\dtlcurrentrow}% + {\number#1}% + {\noexpand\@dtl@before@cs}% + {\noexpand\@dtl@after@cs}}% + \@dtl@do@splitrow + \edef\@dtl@stuff{% + \expandonce\@dtl@before@cs + \expandonce\@dtl@after@cs + }% + \expandafter\dtlcurrentrow\expandafter{\@dtl@stuff}% + \dtl@message{Removed entry from column \number#1\space\space in database + `\dtldbname'}% +} +\newcommand*{\dtlswapentriesincurrentrow}[2]{% + \dtlgetentryfromcurrentrow{\@dtl@entryI}{#1}% + \dtlgetentryfromcurrentrow{\@dtl@entryII}{#2}% + \expandafter\dtlreplaceentryincurrentrow\expandafter + {\@dtl@entryII}{#1}% + \expandafter\dtlreplaceentryincurrentrow\expandafter + {\@dtl@entryI}{#2}% +} \newcommand*{\dtlgetentryfromcurrentrow}[2]{% \dtlgetentryfromrow{#1}{#2}{\dtlcurrentrow}% } @@ -1932,6 +781,36 @@ \db@col@id@w #2\db@col@id@end@% \q@nil } +\newcommand*{\dtlappendentrytocurrentrow}[2]{% + \@dtl@updatekeys{\dtldbname}{#1}{#2}% + \expandafter\dtlcolumnnum\expandafter + =\dtlcolumnindex{\dtldbname}{#1}\relax + \edef\dtl@dogetentry{\noexpand\dtlgetentryfromcurrentrow + {\noexpand\dtl@entry}{\number\dtlcolumnnum}% + }% + \dtl@dogetentry + \ifx\dtl@entry\dtlnovalue + \protected@edef\@dtl@tmp{#2}% + \expandafter\@dtl@toks\expandafter{\@dtl@tmp}% + \toks@gput@right@cx{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@ + }% + \dtl@message{Appended #1\space -> #2\space to database + `\dtldbname'}% + \else + \PackageError{datatool}{Can't append entry to row: + there is already an entry for key `#1' in this row}{}% + \fi +} \newcommand*{\DTLgetvalue}[4]{% \edef\dtl@dogetvalue{\noexpand\dtl@getvalue{\noexpand#1}{#2}% {\number#3}{\number#4}}% @@ -1976,63 +855,6 @@ \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 @@ -2240,6 +1062,24 @@ \csname c@DTLrow\romannumeral\@dtl@tmpcount\endcsname}% \fi \fi} +\newenvironment{DTLenvforeach}[3][\boolean{true}]% +{% + \def\@dtlenvforeach@args{[#1]{#2}{#3}}% + \long@collect@body\@do@dtlenvforeach +}% +{} +\newcommand{\@do@dtlenvforeach}[1]{% + \expandafter\@DTLforeach\@dtlenvforeach@args{#1}% +} +\newenvironment{DTLenvforeach*}[3][\boolean{true}]% +{% + \def\s@dtlenvforeach@args{[#1]{#2}{#3}}% + \long@collect@body\@do@sdtlenvforeach +}% +{} +\newcommand{\@do@sdtlenvforeach}[1]{% + \expandafter\@sDTLforeach\s@dtlenvforeach@args{#1}% +} \newcommand*{\DTLforeach}{\@ifstar\@sDTLforeach\@DTLforeach} \newcommand{\@DTLforeach}[4][\boolean{true}]{% \DTLifdbexists{#2}% @@ -2725,6 +1565,18 @@ }% \fi } +\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}{}% +} \newcommand*{\dtlbetweencols}{} \newcommand*{\dtlbeforecols}{} \newcommand*{\dtlaftercols}{} @@ -2738,9 +1590,11 @@ \else \protected@edef#1{#1\dtlbetweencols}% \fi - \ifx\@empty#2\@empty + \ifstrempty{#2}% + {% \protected@edef#1{#1c}% - \else + }% + {% \ifcase#2\relax \protected@edef#1{#1\dtlstringalign}% \or @@ -2753,7 +1607,7 @@ \protected@edef#1{#1c}% \PackageError{datatool}{Unknown data type `#2'}{}% \fi - \fi + }% \ifnum#3=#4\relax \protected@edef#1{#1\dtlaftercols}% \fi @@ -2768,49 +1622,64 @@ \newcommand*{\dtldisplayafterhead}{} \newcommand*{\dtldisplaystartrow}{} -\newcommand*{\DTLdisplaydb}[1]{% +\newcommand*{\DTLdisplaydb}[2][]{% \def\@dtl@doamp{\gdef\@dtl@doamp{&}} \def\@dtl@resetdoamp{\gdef\@dtl@doamp{\gdef\@dtl@doamp{&}}} \edef\@dtl@maxcols{\expandafter\number - \csname dtlcols@#1\endcsname}% + \csname dtlcols@#2\endcsname}% + \DTLnumitemsinlist{#1}{\@dtl@tmp}% + \dtlsub{\@dtl@maxcols}{\@dtl@maxcols}{\@dtl@tmp}% + \dtlclip{\@dtl@maxcols}{\@dtl@maxcols}% \def\@dtl@tabargs{}% \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)% - \in{#1}\do + \in{#2}\do {% - \dtladdalign\@dtl@tabargs\@dtl@type\@dtl@idx\@dtl@maxcols + \expandafter\DTLifinlist\expandafter{\@dtl@key}{#1}% + {}% + {% + \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 + \in{#2}\do {% - \@dtl@doamp - \dtlheaderformat{\@dtl@head}% + \expandafter\DTLifinlist\expandafter{\@dtl@key}{#1}% + {}% + {% + \@dtl@doamp + \dtlheaderformat{\@dtl@head}% + }% }% \\% \dtldisplayafterhead \@dtl@resetdoamp - \DTLforeach*{#1}{}{% + \@sDTLforeach{#2}{}{% \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 + \expandafter\DTLifinlist\expandafter{\dtlkey}{#1}% + {}% + {% + \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 @@ -2822,6 +1691,7 @@ \define@key{displaylong}{label}{\def\@dtl@label{#1}} \define@key{displaylong}{foot}{\def\@dtl@foot{#1}} \define@key{displaylong}{lastfoot}{\def\@dtl@lastfoot{#1}} +\define@key{displaylong}{omit}{\def\@dtl@omitlist{#1}} \newcommand*{\@dtl@resetdostartrow}{% \gdef\@dtl@dostartrow{% \gdef\@dtl@dostartrow{\\\dtldisplaystartrow}}% @@ -2833,17 +1703,25 @@ \def\@dtl@shortcap{\@dtl@cap}% \def\@dtl@foot{\@nil}% \def\@dtl@lastfoot{\@nil}% + \def\@dtl@omitlist{}% \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}% + \DTLnumitemsinlist{\@dtl@omitlist}{\@dtl@tmp}% + \dtlsub{\@dtl@maxcols}{\@dtl@maxcols}{\@dtl@tmp}% + \dtlclip{\@dtl@maxcols}{\@dtl@maxcols}% \def\@dtl@tabargs{}% \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)% \in{#2}\do {% - \dtladdalign\@dtl@tabargs\@dtl@type\@dtl@idx\@dtl@maxcols + \expandafter\DTLifinlist\expandafter{\@dtl@key}{\@dtl@omitlist}% + {}% + {% + \dtladdalign\@dtl@tabargs\@dtl@type\@dtl@idx\@dtl@maxcols + }% }% \edef\@dtl@dobegintab{\noexpand\begin{longtable}{\@dtl@tabargs}}% \@dtl@dobegintab @@ -2860,7 +1738,13 @@ \@dtl@resetdoamp \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)% \in{#2}\do - {\@dtl@doamp{\dtlheaderformat{\@dtl@head}}}% + {% + \expandafter\DTLifinlist\expandafter{\@dtl@key}{\@dtl@omitlist}% + {}% + {% + \@dtl@doamp{\dtlheaderformat{\@dtl@head}}% + }% + }% \@dtl@resetdoamp \@dtl@resetdostartrow \endhead\dtldisplayafterhead @@ -2874,7 +1758,13 @@ \@dtl@resetdoamp \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)% \in{#2}\do - {\@dtl@doamp{\dtlheaderformat{\@dtl@head}}}% + {% + \expandafter\DTLifinlist\expandafter{\@dtl@key}{\@dtl@omitlist}% + {}% + {% + \@dtl@doamp{\dtlheaderformat{\@dtl@head}}% + }% + }% \@dtl@resetdoamp \@dtl@resetdostartrow \endfirsthead @@ -2887,28 +1777,38 @@ \@dtl@resetdoamp \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)% \in{#2}\do - {\@dtl@doamp{\dtlheaderformat{\@dtl@head}}}% + {% + \expandafter\DTLifinlist\expandafter{\@dtl@key}{\@dtl@omitlist}% + {}% + {% + \@dtl@doamp{\dtlheaderformat{\@dtl@head}}% + }% + }% \@dtl@resetdoamp \@dtl@resetdostartrow \endhead\dtldisplayafterhead \fi - \DTLforeach*{#2}{}{% + \@sDTLforeach{#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 + \expandafter\DTLifinlist\expandafter{\dtlkey}{\@dtl@omitlist}% + {}% + {% + \@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 @@ -3116,7 +2016,6 @@ }% }% \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}% @@ -3249,11 +2148,13 @@ \dtlgetentryfromrow{\DTLthisval}{\@dtl@col}{\dtlcurrentrow}% \expandafter\ifthenelse\expandafter{\@dtl@cond}% {% - \ifx#4\@empty + \ifstrempty{#4}% + {% \let#4\DTLthisval - \else + }% + {% \DTLmin{#4}{#4}{\DTLthisval}% - \fi + }% }{}% }% }% @@ -3267,11 +2168,13 @@ {% \@sdtlforcolumn{\DTLthisval}{#1}{#2}% {% - \ifx#3\@empty + \ifdefempty{#3}% + {% \let#3\DTLthisval - \else + }% + {% \DTLmin{#3}{#3}{\DTLthisval}% - \fi + }% }% }% {% @@ -3301,11 +2204,13 @@ \dtlgetentryfromrow{\DTLthisval}{\@dtl@col}{\dtlcurrentrow}% \expandafter\ifthenelse\expandafter{\@dtl@cond}% {% - \ifx#4\@empty + \ifdefempty{#4}% + {% \let#4\DTLthisval - \else + }% + {% \DTLmax{#4}{#4}{\DTLthisval}% - \fi + }% }{}% }% }% @@ -3319,11 +2224,13 @@ {% \@sdtlforcolumn{\DTLthisval}{#1}{#2}% {% - \ifx#3\@empty + \ifdefempty{#3}% + {% \let#3\DTLthisval - \else + }% + {% \DTLmax{#3}{#3}{\DTLthisval}% - \fi + }% }% }% {% @@ -3343,18 +2250,18 @@ \let#8=\relax \@for\dtl@thisdb:=#2\do{% \@sDTLforeach[#1]{\dtl@thisdb}{\DTLthisX=#3,\DTLthisY=#4}{% - \DTLconverttodecimal{\DTLthisX}{\dtl@decx}% - \DTLconverttodecimal{\DTLthisY}{\dtl@decy}% + \expandafter\DTLconverttodecimal\expandafter{\DTLthisX}{\dtl@decx}% + \expandafter\DTLconverttodecimal\expandafter{\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}% + \dtlmin{#5}{#5}{\dtl@decx}% + \dtlmin{#6}{#6}{\dtl@decy}% + \dtlmax{#7}{#7}{\dtl@decx}% + \dtlmax{#8}{#8}{\dtl@decy}% \fi }% }% @@ -3385,15 +2292,6 @@ }% }% } -\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][]{% @@ -3551,9 +2449,11 @@ \def\@dtl@getsortdirection#1=#2\relax{% \def\@dtl@key{#1}% \def\@dtl@sortdirection{#2}% - \ifx\@dtl@sortdirection\@empty + \ifdefempty{\@dtl@sortdirection}% + {% \def\@dtl@sortdirection{-1}% - \else + }% + {% \@dtl@get@sortdirection#2% \def\@dtl@dir{ascending}% \ifx\@dtl@sortdirection\@dtl@dir @@ -3569,12 +2469,11 @@ \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}% } @@ -3633,24 +2532,28 @@ {% \IfSubStringInString{\@dtl@separator}{\@dtl@key}% {% - \ifx\@dtl@header\@empty + \ifdefempty{\@dtl@header}% + {% \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 + \ifdefempty{\@dtl@header}% + {% \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}% @@ -3661,23 +2564,27 @@ {% \IfSubStringInString{\@dtl@separator}{\@dtl@val}% {% - \ifx\@dtl@row\@empty + \ifdefempty{\@dtl@row}% + {% \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 + \ifdefempty{\@dtl@row}% + {% \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}% @@ -3719,7 +2626,6 @@ database}{}% }% } -\newcommand{\@longempty}{} \newread\@dtl@read \newcount\dtl@entrycr \define@boolkey{loaddb}[dtl]{noheader}[true]{} @@ -3744,17 +2650,23 @@ \the\toks@}% }% } +\newcount{\dtl@omitlines} +\define@key{loaddb}{omitlines}{\dtl@omitlines=#1\relax} \newcommand*{\dtldefaultkey}{Column} \newcommand*{\@dtl@readline}[2]{% \read#1 to #2% - \dtl@trim#2% + \ifdefempty{#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 @@ -3767,6 +2679,11 @@ \setkeys{loaddb}{#1}% \openin\@dtl@read=#3% \dtl@message{Reading `#3'}% + \loop + \ifnum \dtl@omitlines > \z@ + \advance\dtl@omitlines by \m@ne + \read\@dtl@read to \@dtl@line + \repeat \DTLnewdb{#2}% \ifeof\@dtl@read \PackageWarning{datatool}{File `#3' has no data}% @@ -3778,9 +2695,12 @@ \ifeof\@dtl@read \else \@dtl@doreadline\@dtl@read\@dtl@line - \ifx\@dtl@line\@longempty + \ifdefempty{\@dtl@line}% + {% \@dtl@conditiontrue - \fi + }% + {% + }% \fi \if@dtl@condition \repeat @@ -3790,6 +2710,11 @@ \loop \expandafter\@dtl@lopoff\@dtl@lin@\to\@dtl@lin@\@dtl@key \advance\dtl@entrycr by 1\relax + \ifdefempty{\@dtl@key}% + {% + \edef\@dtl@key{\dtldefaultkey\number\dtl@entrycr}% + }% + {}% \expandafter\@dtl@toks\expandafter{\@dtl@key}% \@ifundefined{@dtl@inky@\romannumeral\dtl@entrycr}% {% @@ -3824,8 +2749,10 @@ \@dtl@conditiontrue \loop \@dtl@doreadline\@dtl@read\@dtl@line - \ifx\@dtl@line\@longempty - \else + \ifdefempty{\@dtl@line}% + {% + }% + {% \@sDTLnewrow{#2}% \expandafter\@dtl@toks\expandafter{\@dtl@line}% \edef\@dtl@lin@{\@dtl@separator\the\@dtl@toks @@ -3860,7 +2787,7 @@ \if@dtl@condition \repeat }% - \fi + }% \ifeof\@dtl@read \@dtl@conditionfalse\fi \if@dtl@condition \repeat @@ -3889,17 +2816,23 @@ }% } \newcommand{\dtl@trim}[1]{% -\def\@dtl@trmstr{}% -\expandafter\@dtl@starttrim#1\@nil% -\let#1=\@dtl@trmstr + \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% + \def\@dtl@tmpB{#2}% + \ifx\par#1% + \def\@dtl@dotrim{\@dtl@trim{} #2}% + \else + \ifx\@dtl@tmpB\@nnil + \def\@dtl@dotrim{}% + \def\@dtl@trmstr{#1}% + \else + \def\@dtl@dotrim{\@dtl@trim#1#2}% + \fi + \fi + \@dtl@dotrim } \long\def\@dtl@trim#1 \@nil{\long\def\@dtl@trmstr{#1}} \newcommand*\DTLloadrawdb{% @@ -3956,793 +2889,28 @@ >% \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 + \expandafter\@dtl@toks\expandafter{\@dtl@rawmappings}% + \ifdefempty{\@dtl@rawmappings}% + {% + \def\@dtl@rawmappings{{#1}{#2}}% + }% + {% + \def\@dtl@tmp{{#1}{#2}} + \protected@edef\@dtl@rawmappings{\the\@dtl@toks,\@dtl@tmp} + }% } \newcommand*{\@dtl@rawmappings}{} \newcommand*{\dtl@domappings}[1]{% -\@for\@dtl@map:=\@dtl@rawmappings\do{% - \expandafter\DTLsubstitute\expandafter#1\@dtl@map -}} -\newcommand*{\DTLifinlist}[4]{% - \def\@dtl@doifinlist##1,#1,##2\end@dtl@doifinlist{% - \def\@before{##1}% - \def\@after{##2}% + \@for\@dtl@map:=\@dtl@rawmappings\do{% + \expandafter\DTLsubstituteall\expandafter#1\@dtl@map }% - \expandafter\@dtl@doifinlist\expandafter,#2,#1,\@nil - \end@dtl@doifinlist - \ifx\@after\@nnil - #4% - \else - #3% - \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 -}}} -\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*{\@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} + \expandafter\showthe\csname dtldb@#1\endcsname +} \newcommand*{\dtlshowdbkeys}[1]{% -\expandafter\showthe\csname dtlkeys@#1\endcsname} + \expandafter\showthe\csname dtlkeys@#1\endcsname +} \newcommand*{\dtlshowtype}[2]{% \DTLgetdatatype{\@dtl@type}{#1}{#2}\show\@dtl@type } diff --git a/Master/texmf-dist/tex/latex/datatool/person.sty b/Master/texmf-dist/tex/latex/datatool/person.sty index 3a6ea1b6d27..8d77dbcacd0 100644 --- a/Master/texmf-dist/tex/latex/datatool/person.sty +++ b/Master/texmf-dist/tex/latex/datatool/person.sty @@ -7,7 +7,7 @@ %% datatool.dtx (with options: `person.sty,package') %% %% datatool.dtx -%% Copyright 2009 Nicola Talbot +%% Copyright 2012 Nicola Talbot %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either version 1.3 @@ -21,7 +21,7 @@ %% %% 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, person.sty. +%% This work consists of the files datatool.dtx and datatool.ins and the derived files datatool-base.sty, datatool-fp.sty, datatool-pgfmath.sty, datatool.sty, databib.sty, databar.sty, datapie.sty, dataplot.sty, person.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 @@ -38,13 +38,8 @@ %% Right bracket \] Circumflex \^ Underscore \_ %% Grave accent \` Left brace \{ Vertical bar \| %% Right brace \} Tilde \~} -%% load student information from file "students.csv" -%% Iterate through the student database: -%% Define "anon": -%% Do the letter: -%% Undefine "anon": \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{person}[2009/11/15 v1.01 (NLCT)] +\ProvidesPackage{person}[2012/07/18 v2.10 (NLCT)] \RequirePackage{ifthen} \RequirePackage{datatool} \newcounter{people} |