diff options
author | Karl Berry <karl@freefriends.org> | 2009-11-16 01:44:59 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2009-11-16 01:44:59 +0000 |
commit | 2b1511b76524ed6e4b906094ee4a63aacf7d68e5 (patch) | |
tree | 7e7f3ab490a4e0c1140ba03ed59373be4c4dd226 /Master/texmf-dist/source | |
parent | faaa36262649a67fb85d27b3e605d94da0b75fa4 (diff) |
datalog 2.03 (15nov09)
git-svn-id: svn://tug.org/texlive/trunk@16023 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source')
-rw-r--r-- | Master/texmf-dist/source/latex/datatool/datatool.dtx | 3732 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/datatool/datatool.ins | 6 |
2 files changed, 2803 insertions, 935 deletions
diff --git a/Master/texmf-dist/source/latex/datatool/datatool.dtx b/Master/texmf-dist/source/latex/datatool/datatool.dtx index 8db14f657ed..fcae77779b6 100644 --- a/Master/texmf-dist/source/latex/datatool/datatool.dtx +++ b/Master/texmf-dist/source/latex/datatool/datatool.dtx @@ -2,20 +2,21 @@ % 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 "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" -% -doc "manual.tex" +% -doc "datatool-manual.tex" % -codetitle "datatool.sty" % datatool -% Created on 2009/7/13 10:04 +% Created on 2009/11/15 15:10 %\fi %\iffalse %<*package> @@ -43,15 +44,17 @@ % \iffalse %<*driver> \documentclass[a4paper]{ltxdoc} +\usepackage{dox} \usepackage{ifthen} \usepackage[verbose=false]{datatool} -\usepackage{datapie,databar,databib} +\usepackage{datapie,databar,databib,person} \usepackage{textcomp} \usepackage{graphicx} \usepackage{colortbl} \usepackage{cmap} \usepackage[T1]{fontenc} \usepackage[utf8]{inputenc} +\usepackage{caption} \usepackage[colorlinks, bookmarks, hyperindex=false, @@ -80,7 +83,7 @@ \makeatother \RecordChanges \PageIndex -\CheckSum{15418} +\CheckSum{16375} \newcommand*{\sty}[1]{\textsf{#1}} \newcommand*{\env}[1]{\textsf{#1}} @@ -96,11 +99,6 @@ }} \makeatother -\newcommand*{\counterfmt}[1]{\texttt{#1}\index -{#1 counter=\texttt{#1} counter|hyperpage}} - -\newcommand*{\ics}[1]{\cs{#1}\SpecialMainIndex{#1}} - \newsavebox\defsbox \newlength\defwidth \newenvironment{definition}[1][]{% @@ -118,6 +116,8 @@ \noindent \defarg\fcolorbox{black}{defbackground}{\usebox\defsbox}% \vskip10pt +\noindent +\ignorespacesafterend } \newlength\tmplength @@ -133,6 +133,14 @@ \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}} @@ -173,7 +181,7 @@ options>#2=\textsf{#2}|hyperpage}} %\MakeShortVerb{"} %\DeleteShortVerb{\|} % -% \title{datatool v 2.02: Databases and data manipulation} +% \title{datatool v 2.03: Databases and data manipulation} % \author{Nicola L.C. Talbot\\[10pt] %School of Computing Sciences\\ %University of East Anglia\\ @@ -181,11 +189,16 @@ options>#2=\textsf{#2}|hyperpage}} %NR4 7TJ. United Kingdom.\\ %\url{http://theoval.cmp.uea.ac.uk/~nlct/}} % -% \date{13th July 2009} +% \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} @@ -1930,6 +1943,12 @@ options>#2=\textsf{#2}|hyperpage}} %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} @@ -1967,7 +1986,11 @@ options>#2=\textsf{#2}|hyperpage}} %\DTLrowcount{mydata} %\end{verbatim} %which produces: -%\DTLrowcount{mydata}. +%\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} @@ -1986,6 +2009,17 @@ options>#2=\textsf{#2}|hyperpage}} %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 @@ -2016,6 +2050,8 @@ options>#2=\textsf{#2}|hyperpage}} %{\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} @@ -2177,7 +2213,7 @@ options>#2=\textsf{#2}|hyperpage}} %\cs{DTLloadrawdb}]{Special character mappings used by %\cs{DTLloadrawdb} (note that the backslash retains its active state)} %\label{tab:rawmappings} -%\begin{center} +%\centering %\begin{tabular}{cl} %Character & Mapping\\ %\verb|%| & \verb|\%|\\ @@ -2190,7 +2226,6 @@ options>#2=\textsf{#2}|hyperpage}} %\verb|~| & \cs{textasciitilde}\\ %\verb|^| & \cs{textasciicircum} %\end{tabular} -%\end{center} %\end{table} % %It may be that there are other characters that require mapping. @@ -2204,7 +2239,7 @@ options>#2=\textsf{#2}|hyperpage}} %\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 will therefore be necessary to convert +%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}]% @@ -2249,8 +2284,8 @@ options>#2=\textsf{#2}|hyperpage}} %\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 -%\sty{longtable}, as it is not loaded by \sty{datatool}. +%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} @@ -2337,7 +2372,6 @@ options>#2=\textsf{#2}|hyperpage}} %\begin{verbatim} %\begin{table}[htbp] %\caption{Time to Growth Data} -%\vspace{\baselineskip} %\centering %\DTLdisplaydb{t2g} %\end{table} @@ -2346,7 +2380,6 @@ options>#2=\textsf{#2}|hyperpage}} %\begin{table}[htbp] %\caption{Time to Growth Data} %\label{tab:t2g} -%\vspace{\baselineskip} %\centering %\DTLdisplaydb{t2g} %\end{table} @@ -2524,8 +2557,8 @@ options>#2=\textsf{#2}|hyperpage}} %\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} +%\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 @@ -2535,7 +2568,6 @@ options>#2=\textsf{#2}|hyperpage}} %\begin{table}[htbp] %\caption{Balance Sheet} %\renewcommand*{\dtlrealformat}[1]{\DTLiflt{#1}{0}{\color{red}}{}#1} -%\vspace{\baselineskip} %\centering %\DTLdisplaydb{balance} %\end{table} @@ -2545,7 +2577,6 @@ options>#2=\textsf{#2}|hyperpage}} %\caption{Balance Sheet} %\label{tab:balance} %\renewcommand*{\dtlrealformat}[1]{\DTLiflt{#1}{0}{\color{red}}{}#1} -%\vspace{\baselineskip} %\centering %\DTLdisplaydb{balance} %\end{table} @@ -2676,9 +2707,9 @@ options>#2=\textsf{#2}|hyperpage}} % %The macro \ics{DTLforeach} may be nested up to three times. Each %level uses the corresponding counters: -%\counterfmt{DTLrowi}, -%\counterfmt{DTLrowii} and -%\counterfmt{DTLrowiii} which keep track of +%\desctr{DTLrowi}, +%\desctr{DTLrowii} and +%\desctr{DTLrowiii} which keep track of %the current row. % %\importantpar Note that these counters are only incremented when @@ -2738,33 +2769,6 @@ options>#2=\textsf{#2}|hyperpage}} %the column have mixed types, it may not correspond to the type %of the current entry. % -%\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, \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. The data type may have the -%following values: 0 (string), 1 (integer), 2 (real number), 3 -%(currency) or it will be empty if the column has no entries. -% -%\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}. -% %\begin{definition}[\DescribeMacro{\dtlbreak}]% %\cs{dtlbreak} %\end{definition} @@ -2927,7 +2931,7 @@ options>#2=\textsf{#2}|hyperpage}} % %\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 \counterfmt{DTLrowi} is incremented +%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}.} @@ -2946,7 +2950,6 @@ options>#2=\textsf{#2}|hyperpage}} %\begin{table}[htbp] %\caption{First Three Rows} %\centering -%\vskip\baselineskip %\begin{tabular}{llr} %\bfseries First Name & \bfseries Surname & \bfseries Score (\%)% %\DTLforeach*{scores}% @@ -2963,7 +2966,7 @@ options>#2=\textsf{#2}|hyperpage}} %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 -%\counterfmt{DTLrowi} instead: +%\ctr{DTLrowi} instead: %\begin{verbatim} %\DTLforeach{scores}% %{\firstname=FirstName,\surname=Surname,\score=Score}{% @@ -2976,7 +2979,6 @@ options>#2=\textsf{#2}|hyperpage}} %\caption{First Three Rows} %\label{tab:dtlbreak}% %\centering -%\vskip\baselineskip %\begin{tabular}{llr} %\bfseries First Name & \bfseries Surname & \bfseries Score (\%)\relax %\DTLforeach*{scores}% @@ -3077,7 +3079,6 @@ options>#2=\textsf{#2}|hyperpage}} %\begin{verbatim} %\begin{table}[htbp] %\caption{Student Scores (Iterating Through Keys)} -%\vskip\baselineskip %\centering %\begin{tabular}{llll} %\bfseries First Name & \bfseries Surname & @@ -3093,7 +3094,6 @@ options>#2=\textsf{#2}|hyperpage}} %\begin{table}[htbp] %\caption{Student Scores (Iterating Through Keys)} %\label{tab:foreachkey} -%\vskip\baselineskip %\centering %\begin{tabular}{llll} %\bfseries First Name & \bfseries Surname & @@ -3120,7 +3120,6 @@ options>#2=\textsf{#2}|hyperpage}} %\begin{verbatim} % \begin{table}[htbp] % \caption{Student Scores} -% \vskip\baselineskip % \centering % % Work out the column alignments. % \def\colalign{}% @@ -3145,7 +3144,6 @@ options>#2=\textsf{#2}|hyperpage}} %\caption{Student Scores (Using \cs{dtlforeachkey} and %\cs{DTLforeachkeyinrow})} %\label{tab:foreachkey2} -%\vskip\baselineskip %\centering %\def\colalign{}% %\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do @@ -3211,7 +3209,6 @@ options>#2=\textsf{#2}|hyperpage}} %\begin{verbatim} %\begin{table}[htbp] %\caption{Student Scores (Filtering Out a Column)} -%\vskip\baselineskip %\centering %\def\colalign{}% %\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do @@ -3233,7 +3230,6 @@ options>#2=\textsf{#2}|hyperpage}} %\begin{table}[htbp] %\caption{Student Scores (Filtering Out a Column)} %\label{tab:foreachkey3} -%\vskip\baselineskip %\centering %\def\colalign{}% %\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do @@ -3437,7 +3433,6 @@ options>#2=\textsf{#2}|hyperpage}} %\begin{verbatim} %\begin{table}[htbp] %\caption{Club Membership} -%\vskip\baselineskip %\centering %\begin{tabular}{lll} %\bfseries First Name & \bfseries Surname & \bfseries Status @@ -3453,7 +3448,6 @@ options>#2=\textsf{#2}|hyperpage}} %\begin{table}[htbp] %\caption{Club Membership} %\label{tab:dyn} -%\vskip\baselineskip %\centering %\begin{tabular}{lll} %\bfseries First Name & \bfseries Surname & \bfseries Status @@ -3559,9 +3553,9 @@ options>#2=\textsf{#2}|hyperpage}} %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} (0), -%and null strings are set to \cs{DTLstringnull} (NULL). +%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} @@ -3663,6 +3657,19 @@ options>#2=\textsf{#2}|hyperpage}} %\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: @@ -3671,11 +3678,13 @@ options>#2=\textsf{#2}|hyperpage}} %\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}. +%This replaces the entry for \meta{key} with \meta{value}. +%(\meta{value} is expanded.) % %\begin{definition}[\DescribeMacro{\DTLremoveentryfromrow}]% %\cs{DTLremoveentryfromrow}\marg{key} @@ -4075,6 +4084,9 @@ options>#2=\textsf{#2}|hyperpage}} %} %\end{document} %\end{verbatim} +% +%To determine a person's gender when mail merging, see +%\autoref{sec:person}. %\end{example} % %\subsection{Sorting a Database} @@ -4395,6 +4407,162 @@ options>#2=\textsf{#2}|hyperpage}} %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}. +% +%\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}. +% +%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}.) +% %\section{Pie Charts (\texorpdfstring{\sty{datapie}}{datapie} package)} % %The \sty{datapie} package is not loaded by the \sty{datatool} package, @@ -4404,7 +4572,7 @@ options>#2=\textsf{#2}|hyperpage}} %may be given the following options: %\begin{description} %\item[{\pkgopt[datapie]{color}}] Colour option (default). -%\item[{\pkgopt[datapie]{monochrome}}] Monochrome option. +%\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. @@ -4707,7 +4875,7 @@ options>#2=\textsf{#2}|hyperpage}} %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 -%\counterfmt{DTLpieroundvar}. +%\desctr{DTLpieroundvar}. % %\begin{example}{Changing the Inner and Outer Labels}{ex:pielabels} %This example uses the database defined in \autoref{ex:piechart}. @@ -5109,13 +5277,13 @@ options>#2=\textsf{#2}|hyperpage}} %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 \counterfmt{DTLplotroundXvar}. +%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 \counterfmt{DTLplotroundYvar}. +%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. @@ -5433,21 +5601,21 @@ options>#2=\textsf{#2}|hyperpage}} %created using \ics{DTLplot}. The value of the counters can be %changed using \cs{setcounter}. % -%\begin{definition} -%\counterfmt{DTLplotroundXvar} +%\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 -%\counterfmt{DTLplotroundXvar}. +%\ctrfmt{DTLplotroundXvar}. % -%\begin{definition} -%\counterfmt{DTLplotroundYvar} +%\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 -%\counterfmt{DTLplotroundYvar}. +%\ctrfmt{DTLplotroundYvar}. % %\subsubsection{Macros} %These macros govern the appearance of plots created using @@ -5674,7 +5842,7 @@ options>#2=\textsf{#2}|hyperpage}} %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 \counterfmt{DTLplotroundXvar} to zero +%\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 @@ -5894,12 +6062,12 @@ options>#2=\textsf{#2}|hyperpage}} %You must use \cs{setlength} to change this value. The default value %is 10pt. % -%\begin{definition} -%\counterfmt{DTLbarroundvar} +%\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 \counterfmt{DTLbarroundvar}. You must use \cs{setcounter} +%counter \ctrfmt{DTLbarroundvar}. You must use \cs{setcounter} %to change this value. % %\begin{definition}[\DescribeMacro{\DTLsetbarcolor}]% @@ -6667,7 +6835,7 @@ options>#2=\textsf{#2}|hyperpage}} % %Note that \cs{DTLbibliography} uses \cs{DTLforeachbibentry} %(described in \autoref{sec:foreachbib}) so you may also use -%test the value of the counter \counterfmt{DTLbibrow} within +%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}. % @@ -6891,23 +7059,23 @@ options>#2=\textsf{#2}|hyperpage}} %} %\end{verbatim} % -%\begin{definition} -%\counterfmt{DTLmaxauthors} +%\begin{definition}[\DescribeCounter{DTLmaxauthors}] +%\ctrfmt{DTLmaxauthors} %\end{definition} -%The counter \counterfmt{DTLmaxauthors} is used to determine the +%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 -%\counterfmt{DTLmaxauthors} is \theDTLmaxauthors. +%\ctrfmt{DTLmaxauthors} is \theDTLmaxauthors. % -%\begin{definition} -%\counterfmt{DTLmaxeditors} +%\begin{definition}[\DescribeCounter{DTLmaxeditors}] +%\ctrfmt{DTLmaxeditors} %\end{definition} -%The \counterfmt{DTLmaxeditors} counter is analogous to the -%\counterfmt{DTLmaxauthors} counter. It is used to determine the +%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 \counterfmt{DTLmaxeditors} is \theDTLmaxeditors. +%of \ctrfmt{DTLmaxeditors} is \theDTLmaxeditors. % %\DescribeMacro{\DTLandlast} %Within a list of author or editor names, \cs{DTLandlast} is @@ -7116,7 +7284,7 @@ options>#2=\textsf{#2}|hyperpage}} %is stored in \meta{cmd}, which may then be used in the %argument of the \env{thebibliography} environment. % -%The counter \counterfmt{DTLbibrow} keeps track of the current +%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. @@ -7293,10 +7461,475 @@ options>#2=\textsf{#2}|hyperpage}} %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} +% +%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. +% +%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. +% +%\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} +%\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} -%\section{Acknowledgements} +%\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 @@ -7305,6 +7938,7 @@ options>#2=\textsf{#2}|hyperpage}} % %\phantomsection %\addcontentsline{toc}{section}{Change History}\PrintChanges +%\clearpage %\phantomsection %\addcontentsline{toc}{section}{Index}\PrintIndex %} @@ -7317,10 +7951,11 @@ options>#2=\textsf{#2}|hyperpage}} %<*datatool.sty> % \end{macrocode} %\fi +%\label{sec:code:datatool} %\subsection{Package Declaration} % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{datatool}[2009/07/13 v2.02 (NLCT)] +\ProvidesPackage{datatool}[2009/11/15 v2.03 (NLCT)] % \end{macrocode} % Load required packages: % \begin{macrocode} @@ -9938,9 +10573,11 @@ options>#2=\textsf{#2}|hyperpage}} % the database name. % %\begin{macro}{\DTLnewdb} +%\begin{definition} +% \cs{DTLnewdb}\marg{db name} +%\end{definition} %\changes{2.0}{2009 February 27}{Changed way database is stored} -% \cs{DTLnewdb}\marg{name} -% initialises a database called \meta{name}. +% Initialises a database called \meta{name}. % \begin{macrocode} \newcommand*{\DTLnewdb}[1]{% % \end{macrocode} @@ -9977,6 +10614,60 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} %\end{macro} % +%\begin{macro}{\DTLcleardb} +%\begin{definition} +% \cs{DTLcleardb}\marg{db name} +%\end{definition} +% Clears the database. (Makes it empty, but still defined.) +%\changes{2.03}{2009 November 15}{new} +% \begin{macrocode} +\newcommand*{\DTLcleardb}[1]{% + \DTLifdbexists{#1}% + {% + \dtlforeachkey(\@dtl@key,\@dtl@col,\@dtl@type,\@dtl@head)\in{#1}\do + {% + \expandafter\let\csname dtl@ci@#1@\@dtl@key\endcsname\undefined + }% + \csname dtldb@#1\endcsname{}% + \csname dtlkeys@#1\endcsname{}% + \csname dtlrows@#1\endcsname=0\relax + \csname dtlcols@#1\endcsname=0\relax + }% + {% + \PackageError{Can't clear database `#1': + database doesn't exist}{}{}% + }% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLdeletedb} +%\begin{definition} +% \cs{DTLdeletedb}\marg{db name} +%\end{definition} +% Deletes a database. +%\changes{2.03}{2009 November 15}{new} +% \begin{macrocode} +\newcommand*{\DTLdeletedb}[1]{% + \DTLifdbexists{#1}% + {% + \dtlforeachkey(\@dtl@key,\@dtl@col,\@dtl@type,\@dtl@head)\in{#1}\do + {% + \expandafter\let\csname dtl@ci@#1@\@dtl@key\endcsname\undefined + }% + \expandafter\let\csname dtldb@#1\endcsname\undefined + \expandafter\let\csname dtlkeys@#1\endcsname\undefined + \expandafter\let\csname dtlrows@#1\endcsname\undefined + \expandafter\let\csname dtlcols@#1\endcsname\undefined + }% + {% + \PackageError{Can't delete database `#1': + database doesn't exist}{}{}% + }% +} +% \end{macrocode} +%\end{macro} +% %\begin{macro}{\DTLrowcount} %\begin{definition} % \cs{DTLrowcount}\marg{db name} @@ -10225,15 +10916,17 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} %\end{macro} % -%\begin{macro}{\dtl@columnindex} +%\begin{macro}{\dtlcolumnindex} %\begin{definition} -% \cs{dtl@columnindex}\marg{db}\marg{key} +% \cs{dtlcolumnindex}\marg{db}\marg{key} %\end{definition} % Column index corresponding to \meta{key} in database \meta{db}. % (No check for existance of database or key.) %\changes{2.0}{2009 February 27}{new} +%\changes{2.03}{2009 November 15}{renamed \cs{dtl@columnindex} to +%\cs{dtlcolumnindex}} % \begin{macrocode} -\newcommand*{\dtl@columnindex}[2]{% +\newcommand*{\dtlcolumnindex}[2]{% \csname dtl@ci@#1@#2\endcsname } % \end{macrocode} @@ -10423,7 +11116,7 @@ options>#2=\textsf{#2}|hyperpage}} \newcommand*{\@sdtlgetdatatype}[3]{% \edef\@dtl@dogetdata{\noexpand\@dtl@getdatatype{\noexpand#1}% {\expandafter\the\csname dtlkeys@#2\endcsname}% - {\dtl@columnindex{#2}{#3}}}% + {\dtlcolumnindex{#2}{#3}}}% \@dtl@dogetdata } % \end{macrocode} @@ -10520,7 +11213,7 @@ options>#2=\textsf{#2}|hyperpage}} % column index. % \begin{macrocode} \expandafter\dtlcolumnnum\expandafter - =\dtl@columnindex{#1}{#2}\relax + =\dtlcolumnindex{#1}{#2}\relax % \end{macrocode} % Get the properties for this column % \begin{macrocode} @@ -10700,7 +11393,7 @@ options>#2=\textsf{#2}|hyperpage}} % \begin{macrocode} \newcommand*{\@sDTLsetheader}[3]{% \expandafter\dtlcolumnnum\expandafter - =\dtl@columnindex{#1}{#2}\relax + =\dtlcolumnindex{#1}{#2}\relax \@dtl@setheaderforindex{#1}{\dtlcolumnnum}{#3}% } % \end{macrocode} @@ -10751,6 +11444,28 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} %\end{macro} % +%\begin{macro}{\dtlexpandnewvalue} +% Expand new value before adding to database +% \begin{macrocode} +\newcommand*{\dtlexpandnewvalue}{% + \def\@dtl@setnewvalue##1{\protected@edef\@dtl@tmp{##1}% + \expandafter\@dtl@toks\expandafter{\@dtl@tmp}}% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtlnoexpandnewvalue} +% Don't expand new value before adding to database +% \begin{macrocode} +\newcommand*{\dtlnoexpandnewvalue}{% + \def\@dtl@setnewvalue##1{\@dtl@toks{##1}}% +} +% \end{macrocode} +% Do this by default: +% \begin{macrocode} +\dtlnoexpandnewvalue +% \end{macrocode} +%\end{macro} +% %\begin{macro}{\DTLnewdbentry} %\begin{definition} % \cs{DTLnewdbentry}\marg{db name}\marg{id}\marg{value}. @@ -10788,7 +11503,7 @@ options>#2=\textsf{#2}|hyperpage}} % Get the column index % \begin{macrocode} \expandafter\dtlcolumnnum\expandafter - =\dtl@columnindex{#1}{#2}\relax + =\dtlcolumnindex{#1}{#2}\relax % \end{macrocode} % Get the current row: % \begin{macrocode} @@ -10805,8 +11520,10 @@ options>#2=\textsf{#2}|hyperpage}} \ifx\dtl@entry\dtlnovalue % \end{macrocode} % Store the value of this entry in \cs{@dtl@toks} +%\changes{2.03}{2009 November 15}{value can be expanded before +% adding to database}% % \begin{macrocode} - \@dtl@toks{#3}% + \@dtl@setnewvalue{#3}% % \end{macrocode} % There are no entries in this row for the given column. % Add this entry. @@ -10913,22 +11630,24 @@ options>#2=\textsf{#2}|hyperpage}} %\begin{definition} % \cs{@dtl@assigncmd}\meta{cmd}=\meta{id}\cs{@nil} %\end{definition} +%\changes{2.03}{2009 November 15}{modified to ignore spaces after +% commas} % \begin{macrocode} -\def\@dtl@assigncmd#1=#2,#3\@@#4{% +\def\@dtl@assigncmd#1#2=#3,#4\@@#5{% % \end{macrocode} -% get entry for ID given by \#2 and store in \#1 +% get entry for ID given by \#3 and store in \#2 % \begin{macrocode} - \@sDTLifhaskey{#4}{#2}% + \@sDTLifhaskey{#5}{#3}% {% \edef\@dtl@dogetentry{% \noexpand\dtlgetentryfromcurrentrow - {\noexpand#1}{\dtl@columnindex{#4}{#2}}}% + {\noexpand#1}{\dtlcolumnindex{#5}{#3}}}% \@dtl@dogetentry % \end{macrocode} % Set to null if required % \begin{macrocode} \ifx#1\dtlnovalue - \@@dtl@setnull{#1}{#2}% + \@@dtl@setnull{#1}{#3}% \fi % \end{macrocode} % Make it global @@ -10937,7 +11656,7 @@ options>#2=\textsf{#2}|hyperpage}} }% {% \PackageError{datatool}{Can't assign \string#1\space: there - is no key `#2' in data base `#4'}{}% + is no key `#3' in data base `#5'}{}% % \end{macrocode} % Set to null % \begin{macrocode} @@ -10946,13 +11665,13 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} % Recurse? % \begin{macrocode} - \def\dtl@tmp{#3}% + \def\dtl@tmp{#4}% \ifx\@nnil\dtl@tmp \let\@dtl@next\@dtl@assigncmdnoop \else \let\@dtl@next\@dtl@assigncmd \fi - \@dtl@next#3\@@{#4}% + \@dtl@next#4\@@{#5}% } % \end{macrocode} %\end{macro} @@ -11195,9 +11914,9 @@ options>#2=\textsf{#2}|hyperpage}} %\begin{macro}{\@dtlgetrow} %\begin{definition} %\cs{@dtlgetrow}\marg{data specs}\marg{row idx} +%\end{definition} % Gets the row specs from \meta{data specs} for row with index % \meta{row idx} which must be fully expanded. -%\end{definition} % \begin{macrocode} \newcommand*{\@dtlgetrow}[2]{% \def\@dtl@getrow##1% before stuff @@ -11734,7 +12453,7 @@ options>#2=\textsf{#2}|hyperpage}} \toks@{#4}% \edef\@dtl@doforcol{\noexpand\dtl@forcolumn{\noexpand#1}% {\expandafter\the\csname dtldb@#2\endcsname}% - {\dtl@columnindex{#2}{#3}}{\the\toks@}% + {\dtlcolumnindex{#2}{#3}}{\the\toks@}% }% \@dtl@doforcol% } @@ -12464,7 +13183,7 @@ options>#2=\textsf{#2}|hyperpage}} % Get column index and store in \cs{dtlcolumnnum} % \begin{macrocode} \expandafter\dtlcolumnnum\expandafter - =\dtl@columnindex{\@dtl@thisdb}{#1}\relax + =\dtlcolumnindex{\@dtl@thisdb}{#1}\relax % \end{macrocode} % Set \cs{dtlcurrentrow} to the current row % \begin{macrocode} @@ -12480,9 +13199,11 @@ options>#2=\textsf{#2}|hyperpage}} \ifx\dtl@entry\dtlnovalue % \end{macrocode} % There are no entries in this row for the given key. -% Store value in \cs{@dtl@toks} with one level expansion. +% Expand entry value before storing. +%\changes{2.03}{2009 November 15}{value expanded before storing} % \begin{macrocode} - \expandafter\@dtl@toks\expandafter{#2}% + \protected@edef\@dtl@tmp{#2}% + \expandafter\@dtl@toks\expandafter{\@dtl@tmp}% % \end{macrocode} % Append this entry to the current row. % \begin{macrocode} @@ -12689,9 +13410,11 @@ options>#2=\textsf{#2}|hyperpage}} }% \@dtl@dosplitrow % \end{macrocode} -% Reconstruct row with new entry +% Reconstruct row with new value (given by \verb|#2|). +%\changes{2.03}{2009 November 15}{expand replacement entry} % \begin{macrocode} - \@dtl@toks{#2}% new value + \protected@edef\@dtl@tmp{#2}% + \expandafter\@dtl@toks\expandafter{\@dtl@tmp}% new value \expandafter\@dtl@before\expandafter{\dtl@pre}% \expandafter\@dtl@after\expandafter{\dtl@post}% \toks@gconcat@middle@cx @@ -15042,8 +15765,803 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} %\end{macro} % +%\subsection{Saving a database to an external file} +% +%\begin{macro}{\@dtl@write} +% \begin{macrocode} +\newwrite\@dtl@write +% \end{macrocode} +%\end{macro} +%\begin{macro}{\DTLsavedb} +%\begin{definition} +% \cs{DTLsavedb}\marg{db name}\marg{filename} +%\end{definition} +% Save a database as an ASCII data file using the separator +% and delimiter given by \cs{@dtl@separator} and \cs{@dtl@delimiter}. +%\changes{2.0}{2009 February 27}{updated to use new database structure} +% \begin{macrocode} +\newcommand*{\DTLsavedb}[2]{% + \DTLifdbexists{#1}% + {% +% \end{macrocode} +% Open output file +%\changes{2.02}{2009 July 13}{Fixed bug that didn't set the filename} +% \begin{macrocode} + \openout\@dtl@write=#2\relax +% \end{macrocode} +% Initialise header row +% \begin{macrocode} + \def\@dtl@header{}% +% \end{macrocode} +% Construct the header row +% \begin{macrocode} + \dtlforeachkey(\@dtl@key,\@dtl@col,\@dtl@type,\@dtl@head)% + \in{#1}\do + {% + \IfSubStringInString{\@dtl@separator}{\@dtl@key}% + {% + \ifx\@dtl@header\@empty + \protected@edef\@dtl@header{% + \@dtl@delimiter\@dtl@key\@dtl@delimiter}% + \else + \toks@=\expandafter{\@dtl@header}% + \protected@edef\@dtl@header{% + \the\toks@\@dtl@separator + \@dtl@delimiter\@dtl@key\@dtl@delimiter}% + \fi + }% + {% + \ifx\@dtl@header\@empty + \protected@edef\@dtl@header{\@dtl@key}% + \else + \toks@=\expandafter{\@dtl@header}% + \protected@edef\@dtl@header{\the\toks@ + \@dtl@separator\@dtl@key}% + \fi + }% + }% +% \end{macrocode} +% Print header +% \begin{macrocode} + \protected@write\@dtl@write{}{\@dtl@header}% +% \end{macrocode} +% Iterate through each row +% \begin{macrocode} + \@sDTLforeach{#1}{}% + {% +% \end{macrocode} +% Initialise row +% \begin{macrocode} + \def\@dtl@row{}% +% \end{macrocode} +% Iterate through each key +% \begin{macrocode} + \DTLforeachkeyinrow{\@dtl@val}% + {% + \IfSubStringInString{\@dtl@separator}{\@dtl@val}% + {% + \ifx\@dtl@row\@empty + \protected@edef\@dtl@row{% + \@dtl@delimiter\@dtl@val\@dtl@delimiter}% + \else + \toks@=\expandafter{\@dtl@row}% + \protected@edef\@dtl@row{\the\toks@\@dtl@separator + \@dtl@delimiter\@dtl@val\@dtl@delimiter}% + \fi + }% + {% + \ifx\@dtl@row\@empty + \protected@edef\@dtl@row{\@dtl@val}% + \else + \toks@=\expandafter{\@dtl@row}% + \protected@edef\@dtl@row{\the\toks@\@dtl@separator + \@dtl@val}% + \fi + }% + }% +% \end{macrocode} +% Print row\changes{2.03}{2009 November 15}{Moved outside loop} +% \begin{macrocode} + \protected@write\@dtl@write{}{\@dtl@row}% + }% +% \end{macrocode} +% Close output file +% \begin{macrocode} + \closeout\@dtl@write + }% + {% + \PackageError{datatool}{Can't save database `#1': no such + database}{}% + }% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLsavetexdb} +%\begin{definition} +% \cs{DTLsavetexdb}\marg{db name}\marg{filename} +%\end{definition} +% Save a database as a \LaTeX\ file. +%\changes{2.0}{2009 February 27}{updated to use new database structure} +% \begin{macrocode} +\newcommand*{\DTLsavetexdb}[2]{% + \DTLifdbexists{#1}% + {% +% \end{macrocode} +% Open output file +% \begin{macrocode} + \openout\@dtl@write=#2\relax +% \end{macrocode} +% Write new data base definition +% \begin{macrocode} + \protected@write\@dtl@write{}{\string\DTLnewdb{#1}}% +% \end{macrocode} +% Iterate through each row +% \begin{macrocode} + \@sDTLforeach{#1}{}% + {% +% \end{macrocode} +% Start new row +% \begin{macrocode} + \protected@write\@dtl@write{}{\string\DTLnewrow*{#1}}% +% \end{macrocode} +% Iterate through each column +% \begin{macrocode} + \DTLforeachkeyinrow{\@dtl@val}% + {% +% \end{macrocode} +% Is this entry null? +% \begin{macrocode} + \DTLifnull{\@dtl@val}% + {\def\@dtl@val{}}% + {}% +% \end{macrocode} +% Add entry +% \begin{macrocode} + \protected@write\@dtl@write{}{% + \string\DTLnewdbentry*{#1}{\dtlkey}{\@dtl@val}}% + }% + }% +% \end{macrocode} +% Save the column headers. +% \begin{macrocode} + \dtlforeachkey(\@dtl@k,\@dtl@c,\@dtl@t,\@dtl@h)\in{#1}\do + {% + \@onelevel@sanitize\@dtl@h + \protected@write\@dtl@write{}{% + \string\DTLsetheader*{#1}{\@dtl@k}{\@dtl@h}}% + }% +% \end{macrocode} +% Close output file +% \begin{macrocode} + \closeout\@dtl@write + }% + {% + \PackageError{datatool}{Can't save database `#1': no such + database}{}% + }% +} +% \end{macrocode} +%\end{macro} +% +%\subsection{Loading a database from an external file} +% +% \begin{macrocode} +\newcommand{\@longempty}{} +% \end{macrocode} +%\begin{macro}{\@dtl@read} +% \begin{macrocode} +\newread\@dtl@read +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtl@entrycr} +% Keep track of current column in data file +% \begin{macrocode} +\newcount\dtl@entrycr +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\ifdtlnoheader} +% The "noheader" option indicates that the file doesn't have a +% header row. +% \begin{macrocode} +\define@boolkey{loaddb}[dtl]{noheader}[true]{} +% \end{macrocode} +%\end{macro} +% The "keys" option specifies the list of keys in the same order +% as the columns in the data file. +% Each key is stored in \cs{@dtl@inky@}\meta{n} where \meta{n} is the +% roman numeral representation of the current column. +% \begin{macrocode} +\define@key{loaddb}{keys}{% + \dtl@entrycr=0\relax + \@for\@dtl@key:=#1\do + {% + \advance\dtl@entrycr by 1\relax + \expandafter + \edef\csname @dtl@inky@\romannumeral\dtl@entrycr\endcsname{% + \@dtl@key}% + }% +} +% \end{macrocode} +% The "headers" option specifies the list of headers in the +% same order as the columns in the data file. +% \begin{macrocode} +\define@key{loaddb}{headers}{% + \dtl@entrycr=0\relax + \@for\@dtl@head:=#1\do + {% + \advance\dtl@entrycr by 1\relax + \toks@=\expandafter{\@dtl@head}% + \expandafter + \edef\csname @dtl@inhd@\romannumeral\dtl@entrycr\endcsname{% + \the\toks@}% + }% +} +% \end{macrocode} +% +%\begin{macro}{\dtldefaultkey} +% Default key to use if none specified (column index will be +% appended). +% \begin{macrocode} +\newcommand*{\dtldefaultkey}{Column} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@dtl@readline} +%\begin{definition} +%\cs{@dtl@readline}\marg{file reg}\marg{cs} +%\end{definition} +% Reads line from \meta{file reg}, trims end of line character +% and stores in \meta{cs}. +% \begin{macrocode} +\newcommand*{\@dtl@readline}[2]{% +% Read a line from "#1" and store in "#2" +% \begin{macrocode} + \read#1 to #2% +% \end{macrocode} +% Trim the end of line character +% \begin{macrocode} + \dtl@trim#2% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@dtl@readrawline} +%\begin{definition} +%\cs{@dtl@readrawline}\marg{file register}\marg{cs} +%\end{definition} +% Reads line from \meta{file register}, trims end of line character, +% applies mappings and stores in \meta{cs}. +% \begin{macrocode} +\newcommand*{\@dtl@readrawline}[2]{% +% Read a line from "#1" and store in "#2" +% \begin{macrocode} + \@dtl@rawread#1 to #2% +% \end{macrocode} +% Trim the end of line character +% \begin{macrocode} + \dtl@trim#2% +% \end{macrocode} +% Apply mappings +% \begin{macrocode} + \dtl@domappings\@dtl@line +} +% \end{macrocode} +%\end{macro} + +%\begin{macro}{\DTLloaddb} +%\begin{definition} +% \cs{DTLloaddb}\oarg{options}\marg{db name}\marg{filename} +%\end{definition} +% Creates a new database called \meta{db name}, and loads the data +% in \meta{filename} into it. The separator and delimiter used in +% the file must match \cs{@dtl@separator} and \cs{@dtl@delimiter}. +% The optional argument is a comma-separated list. +%\changes{2.0}{2009 February 27}{removed checks to see if the +% database exists when adding to it} +%\changes{2.0}{2009 February 27}{added optional argument} +% \begin{macrocode} +\newcommand*{\DTLloaddb}{% + \let\@dtl@doreadline\@dtl@readline + \@dtlloaddb +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@dtlloaddb} +% Loads database using \cs{@dtl@doreadline} to read and trim +% line from file. (\cs{@dtl@doreadline} must be set before use.) +% \begin{macrocode} +\newcommand*{\@dtlloaddb}[3][]{% +% \end{macrocode} +% Check if file exists +% \begin{macrocode} + \IfFileExists{#3}{% +% \end{macrocode} +% File exists. Locally change catcode of double quote character in +% case it has been made active. +% \begin{macrocode} + \begingroup + \catcode`\"12\relax +% \end{macrocode} +% Initialise default options +% \begin{macrocode} + \dtlnoheaderfalse +% \end{macrocode} +% Get the options +% \begin{macrocode} + \setkeys{loaddb}{#1}% +% \end{macrocode} +% Open the file for reading. +% \begin{macrocode} + \openin\@dtl@read=#3% + \dtl@message{Reading `#3'}% +% \end{macrocode} +% Create the new database. +% \begin{macrocode} + \DTLnewdb{#2}% +% \end{macrocode} +% Check if the file is empty. +% \begin{macrocode} + \ifeof\@dtl@read +% \end{macrocode} +% File is empty, so just issue a warning. +% \begin{macrocode} + \PackageWarning{datatool}{File `#3' has no data}% + \else +% \end{macrocode} +% Does the file have a header row? +% \begin{macrocode} + \ifdtlnoheader + \else +% \end{macrocode} +% Remove initial blank rows +% \begin{macrocode} + \loop +% \end{macrocode} +% Set repeat condition to false +% \begin{macrocode} + \@dtl@conditionfalse +% \end{macrocode} +% Do nothing if reached the end of file +% \begin{macrocode} + \ifeof\@dtl@read + \else +% \end{macrocode} +% Read a line from the file and store in \cs{@dtl@line} +% \begin{macrocode} + \@dtl@doreadline\@dtl@read\@dtl@line +% \end{macrocode} +% If this is a blank row, set repeat condition to true +% \begin{macrocode} + \ifx\@dtl@line\@longempty + \@dtl@conditiontrue + \fi + \fi +% \end{macrocode} +% Repeat loop if necessary +% \begin{macrocode} + \if@dtl@condition + \repeat +% \end{macrocode} +% Parse the header row. Store the row as +% \meta{sep}\meta{row}\meta{sep} in \cs{@dtl@lin@}. +% \begin{macrocode} + \protected@edef\@dtl@lin@{% + \@dtl@separator\@dtl@line\@dtl@separator}% +% \end{macrocode} +% Keep track of columns: +% \begin{macrocode} + \dtl@entrycr=0\relax +% \end{macrocode} +% Keep lopping off elements until the end of the row is reached. +% (That is, until \cs{@dtl@lin@} is \cs{@dtl@separator}.) +%\changes{2.0}{2009 February 27}{changed \cs{whiledo} to +% \cs{loop} to improve efficiency}% +% \begin{macrocode} + \loop +% \end{macrocode} +% Lopoff the first element and store in \cs{@dtl@key} +% \begin{macrocode} + \expandafter\@dtl@lopoff\@dtl@lin@\to\@dtl@lin@\@dtl@key +% \end{macrocode} +% Increment column count. +% \begin{macrocode} + \advance\dtl@entrycr by 1\relax +% \end{macrocode} +% Store key in \cs{@dtl@toks} +% \begin{macrocode} + \expandafter\@dtl@toks\expandafter{\@dtl@key}% +% \end{macrocode} +% Store the key in \cs{@dtl@inky@}\meta{n} where \meta{n} is the +% roman numeral representation of the current column, unless +% already defined. +% \begin{macrocode} + \@ifundefined{@dtl@inky@\romannumeral\dtl@entrycr}% + {% + \expandafter + \edef\csname @dtl@inky@\romannumeral + \dtl@entrycr\endcsname{\the\@dtl@toks}% + }% + {% +% \end{macrocode} +% If key has been specified in "#1", then use the header found in the +% file, unless a header has also been specified in "#1" +% \begin{macrocode} + \@ifundefined{@dtl@inhd@\romannumeral\dtl@entrycr}% + {% + \expandafter + \edef\csname @dtl@inhd@\romannumeral + \dtl@entrycr\endcsname{\the\@dtl@toks}% + }% + {}% + }% +% \end{macrocode} +% Check if the loop should be repeated +% \begin{macrocode} + \ifx\@dtl@lin@\@dtl@separator + \@dtl@conditionfalse + \else + \@dtl@conditiontrue + \fi +% \end{macrocode} +% Repeat loop if necessary. +% \begin{macrocode} + \if@dtl@condition + \repeat +% \end{macrocode} +% End if no header +% \begin{macrocode} + \fi +% \end{macrocode} +% Now for the rest of the data. If the end of file has been +% reached, then only the header row is available or file is empty. +% \begin{macrocode} + \ifeof\@dtl@read + \ifdtlnoheader + \PackageWarning{datatool}{No data in `#3'}% + \else + \PackageWarning{datatool}{Only header row found in `#3'}% + \fi + \else +% \end{macrocode} +% Iterate through the rest of the file. First set the repeat +% condition to true: +% \begin{macrocode} + \@dtl@conditiontrue + \loop +% \end{macrocode} +% Read in a line +% \begin{macrocode} + \@dtl@doreadline\@dtl@read\@dtl@line +% \end{macrocode} +% Check if the line is empty. +%\changes{2.0}{2009 February 27}{changed \cs{ifthenelse} to +%\cs{ifx} to improve efficiency} +% \begin{macrocode} + \ifx\@dtl@line\@longempty +% \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.) +% \begin{macrocode} + \@sDTLnewrow{#2}% +% \end{macrocode} +% Store the row as \meta{sep}\meta{row}\meta{sep} to make the +% lopping off easier +% \begin{macrocode} + \expandafter\@dtl@toks\expandafter{\@dtl@line}% + \edef\@dtl@lin@{\@dtl@separator\the\@dtl@toks + \@dtl@separator}% +% \end{macrocode} +% Reset the column counter. +% \begin{macrocode} + \dtl@entrycr=0\relax +% \end{macrocode} +%\changes{2.0}{2009 February 27}{changed \cs{whiledo} to \cs{loop} +% to improve efficiency} +% Iterate through each element in the row. Needs to be grouped +% since we're already inside a loop. +% \begin{macrocode} + {% +% \end{macrocode} +% Initialise repeat condition +% \begin{macrocode} + \@dtl@conditiontrue +% \end{macrocode} +% Iterate through the list +% \begin{macrocode} + \loop +% \end{macrocode} +% lop off first element and store in \cs{@dtl@thisentry} +% \begin{macrocode} + \expandafter\@dtl@lopoff\@dtl@lin@\to + \@dtl@lin@\@dtl@thisentry +% \end{macrocode} +% Increment the column count. +% \begin{macrocode} + \advance\dtl@entrycr by 1\relax +% \end{macrocode} +% Get the key for this column and store in \cs{@dtl@thiskey}. +% Use default value if not defined. +% \begin{macrocode} + \@ifundefined{@dtl@inky@\romannumeral\dtl@entrycr}% + {% + \edef\@dtl@thiskey{\dtldefaultkey + \number\dtl@entrycr}% + \expandafter\let + \csname @dtl@inky@\romannumeral + \dtl@entrycr\endcsname\@dtl@thiskey + }% + {% + \edef\@dtl@thiskey{% + \csname @dtl@inky@\romannumeral + \dtl@entrycr\endcsname}% + }% +% \end{macrocode} +% Store this entry in \cs{@dtl@toks} +% \begin{macrocode} + \expandafter\@dtl@toks\expandafter{\@dtl@thisentry}% +% \end{macrocode} +% Add this entry to the database +% \begin{macrocode} + \edef\@do@dtlnewentry{\noexpand\@sDTLnewdbentry + {#2}{\@dtl@thiskey}{\the\@dtl@toks}}% + \@do@dtlnewentry +% \end{macrocode} +% Check if loop should be terminated +% \begin{macrocode} + \ifx\@dtl@lin@\@dtl@separator + \@dtl@conditionfalse + \fi +% \end{macrocode} +% Repeat loop if necessary +% \begin{macrocode} + \if@dtl@condition + \repeat + }% +% \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. +% \begin{macrocode} + \ifeof\@dtl@read \@dtl@conditionfalse\fi +% \end{macrocode} +% Repeat if necessary +% \begin{macrocode} + \if@dtl@condition + \repeat + \fi +% \end{macrocode} +% End of first \cs{ifeof} +% \begin{macrocode} + \fi +% \end{macrocode} +% Close the input file +% \begin{macrocode} + \closein\@dtl@read +% \end{macrocode} +% Set the headers if required +% \begin{macrocode} + \edef\@dtl@maxcols{\expandafter + \number\csname dtlcols@#2\endcsname}% + \dtlgforint\dtl@entrycr=1\to\@dtl@maxcols\step1\do + {% + \@ifundefined{@dtl@inhd@\romannumeral\dtl@entrycr}% + {}% + {% + \expandafter\let\expandafter\@dtl@head + \csname @dtl@inhd@\romannumeral\dtl@entrycr\endcsname + \@dtl@toks=\expandafter{\@dtl@head}% + \edef\@dtl@dosetheader{\noexpand\@dtl@setheaderforindex + {#2}{\number\dtl@entrycr}{\the\@dtl@toks}}% + \@dtl@dosetheader + }% + }% +% \end{macrocode} +% End current scope +% \begin{macrocode} + \endgroup +% \end{macrocode} +% End true part of if file exists +% \begin{macrocode} + }{% +% \end{macrocode} +% Requested file not found on TeX's path +% \begin{macrocode} + \PackageError{datatool}{Can't load database `#2' (file `#3' + doesn't exist)}{}% + }% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\dtl@trim} +%\begin{definition} +%\cs{dtl@trim}\marg{line} +%\end{definition} +% 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 +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\@dtl@starttrim} +% Start trimming +% \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% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\@dtl@trim} +% \begin{macrocode} +\long\def\@dtl@trim#1 \@nil{\long\def\@dtl@trmstr{#1}} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLloadrawdb} +%\begin{definition} +%\cs{DTLloadrawdb}\marg{db name}\marg{filename} +%\end{definition} +% Loads a raw database (substitutes "%" $\to$ "\%", +% "$" $\to$ "\$", "&" $\to$ "\&", "#" $\to$ "\#", +% "~" $\to$ "\textasciitilde", "_" $\to$ "\_" +% and "^" $\to$ "\textasciicircum".) The user can add additional +% mappings. +% \begin{macrocode} +\newcommand*\DTLloadrawdb{% + \let\@dtl@doreadline\@dtl@readrawline + \@dtlloaddb +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@dtl@rawread} +%\begin{definition} +% \cs{@dtl@rawread}\meta{number}to\meta{cmd} +%\end{definition} +% Reads in a raw line from file given by \meta{number} +% converts special characters and stores in \meta{cmd} +% \begin{macrocode} +\begingroup +\catcode`\%=\active +\catcode`$=\active +\catcode`&=\active +\catcode`~=\active +\catcode`_=\active +\catcode`^=\active +\catcode`#=\active +\catcode`?=6\relax +\catcode`<=1\relax +\catcode`>=2\relax +\catcode`\{=\active +\catcode`\}=\active +\gdef\@dtl@rawread?1to?2<\relax +<<\catcode`\%=\active +\catcode`$=\active +\catcode`&=\active +\catcode`~=\active +\catcode`_=\active +\catcode`^=\active +\catcode`#=\active +\catcode`\{=\active +\catcode`\}=\active +\def%<\noexpand\%>\relax +\def$<\noexpand\$>\relax +\def&<\&>\relax +\def#<\#>\relax +\def~<\noexpand\textasciitilde>\relax +\def_<\noexpand\_>\relax +\def^<\noexpand\textasciicircum>\relax +\@dtl@activatebraces +\@dtl@doreadraw?1?2>>> +\gdef\@dtl@doreadraw?1?2<\relax +\read?1 to \tmp +\xdef?2<\tmp>\relax +> +\endgroup +% \end{macrocode} +%\end{macro} +%\begin{macro}{\@dtl@activatebraces} +% \cs{@dtl@activatebraces} resets braces for \cs{@dtl@rawread} +% \begin{macrocode} +\begingroup +\catcode`\{=\active +\catcode`\}=\active +\catcode`<=1\relax +\catcode`>=2\relax +\gdef\@dtl@activatebraces<% + \catcode`\{=\active + \catcode`\}=\active + \def{<\noexpand\{>% + \def}<\noexpand\}>% +>% +\endgroup +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\DTLrawmap} +%\begin{definition} +%\cs{DTLrawmap}\marg{string}\marg{replacement} +%\end{definition} +% 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 +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@dtl@rawmappings} +% List of mappings. +% \begin{macrocode} +\newcommand*{\@dtl@rawmappings}{} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\dtl@domappings} +%\begin{definition} +% \cs{dtl@domappings}\marg{cmd} +%\end{definition} +% Do all mappings in string given by \meta{cmd}. +% \begin{macrocode} +\newcommand*{\dtl@domappings}[1]{% +\@for\@dtl@map:=\@dtl@rawmappings\do{% + \expandafter\DTLsubstitute\expandafter#1\@dtl@map +}} +% \end{macrocode} +%\end{macro} +% %\subsection{General List Utilities} % +%\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}.) +% \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} +% %\begin{macro}{\dtl@choplast} %\begin{definition} % \cs{dtl@choplast}\marg{list}\marg{rest}\marg{last} @@ -16188,773 +17706,6 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} %\end{macro} % -%\subsection{Saving a database to an external file} -% -%\begin{macro}{\@dtl@write} -% \begin{macrocode} -\newwrite\@dtl@write -% \end{macrocode} -%\end{macro} -%\begin{macro}{\DTLsavedb} -%\begin{definition} -% \cs{DTLsavedb}\marg{db name}\marg{filename} -%\end{definition} -% Save a database as an ASCII data file using the separator -% and delimiter given by \cs{@dtl@separator} and \cs{@dtl@delimiter}. -%\changes{2.0}{2009 February 27}{updated to use new database structure} -% \begin{macrocode} -\newcommand*{\DTLsavedb}[2]{% - \DTLifdbexists{#1}% - {% -% \end{macrocode} -% Open output file -%\changes{2.02}{2009 July 13}{Fixed bug that didn't set the filename} -% \begin{macrocode} - \openout\@dtl@write=#2\relax -% \end{macrocode} -% Initialise header row -% \begin{macrocode} - \def\@dtl@header{}% -% \end{macrocode} -% Construct the header row -% \begin{macrocode} - \dtlforeachkey(\@dtl@key,\@dtl@col,\@dtl@type,\@dtl@head)% - \in{#1}\do - {% - \IfSubStringInString{\@dtl@separator}{\@dtl@key}% - {% - \ifx\@dtl@header\@empty - \protected@edef\@dtl@header{% - \@dtl@delimiter\@dtl@key\@dtl@delimiter}% - \else - \toks@=\expandafter{\@dtl@header}% - \protected@edef\@dtl@header{% - \the\toks@\@dtl@separator - \@dtl@delimiter\@dtl@key\@dtl@delimiter}% - \fi - }% - {% - \ifx\@dtl@header\@empty - \protected@edef\@dtl@header{\@dtl@key}% - \else - \toks@=\expandafter{\@dtl@header}% - \protected@edef\@dtl@header{\the\toks@ - \@dtl@separator\@dtl@key}% - \fi - }% - }% -% \end{macrocode} -% Print header -% \begin{macrocode} - \protected@write\@dtl@write{}{\@dtl@header}% -% \end{macrocode} -% Iterate through each row -% \begin{macrocode} - \@sDTLforeach{#1}{}% - {% -% \end{macrocode} -% Initialise row -% \begin{macrocode} - \def\@dtl@row{}% -% \end{macrocode} -% Iterate through each key -% \begin{macrocode} - \DTLforeachkeyinrow{\@dtl@val}% - {% - \IfSubStringInString{\@dtl@separator}{\@dtl@val}% - {% - \ifx\@dtl@row\@empty - \protected@edef\@dtl@row{% - \@dtl@delimiter\@dtl@val\@dtl@delimiter}% - \else - \toks@=\expandafter{\@dtl@row}% - \protected@edef\@dtl@row{\the\toks@\@dtl@separator - \@dtl@delimiter\@dtl@val\@dtl@delimiter}% - \fi - }% - {% - \ifx\@dtl@row\@empty - \protected@edef\@dtl@row{\@dtl@val}% - \else - \toks@=\expandafter{\@dtl@row}% - \protected@edef\@dtl@row{\the\toks@\@dtl@separator - \@dtl@val}% - \fi - }% -% \end{macrocode} -% Print row -% \begin{macrocode} - \protected@write\@dtl@write{}{\@dtl@row}% - }% - }% -% \end{macrocode} -% Close output file -% \begin{macrocode} - \closeout\@dtl@write - }% - {% - \PackageError{datatool}{Can't save database `#1': no such - database}{}% - }% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLsavetexdb} -%\begin{definition} -% \cs{DTLsavetexdb}\marg{db name}\marg{filename} -%\end{definition} -% Save a database as a \LaTeX\ file. -%\changes{2.0}{2009 February 27}{updated to use new database structure} -% \begin{macrocode} -\newcommand*{\DTLsavetexdb}[2]{% - \DTLifdbexists{#1}% - {% -% \end{macrocode} -% Open output file -% \begin{macrocode} - \openout\@dtl@write=#2\relax -% \end{macrocode} -% Write new data base definition -% \begin{macrocode} - \protected@write\@dtl@write{}{\string\DTLnewdb{#1}}% -% \end{macrocode} -% Iterate through each row -% \begin{macrocode} - \@sDTLforeach{#1}{}% - {% -% \end{macrocode} -% Start new row -% \begin{macrocode} - \protected@write\@dtl@write{}{\string\DTLnewrow*{#1}}% -% \end{macrocode} -% Iterate through each column -% \begin{macrocode} - \DTLforeachkeyinrow{\@dtl@val}% - {% -% \end{macrocode} -% Is this entry null? -% \begin{macrocode} - \DTLifnull{\@dtl@val}% - {\def\@dtl@val{}}% - {}% -% \end{macrocode} -% Add entry -% \begin{macrocode} - \protected@write\@dtl@write{}{% - \string\DTLnewdbentry*{#1}{\dtlkey}{\@dtl@val}}% - }% - }% -% \end{macrocode} -% Save the column headers. -% \begin{macrocode} - \dtlforeachkey(\@dtl@k,\@dtl@c,\@dtl@t,\@dtl@h)\in{#1}\do - {% - \@onelevel@sanitize\@dtl@h - \protected@write\@dtl@write{}{% - \string\DTLsetheader*{#1}{\@dtl@k}{\@dtl@h}}% - }% -% \end{macrocode} -% Close output file -% \begin{macrocode} - \closeout\@dtl@write - }% - {% - \PackageError{datatool}{Can't save database `#1': no such - database}{}% - }% -} -% \end{macrocode} -%\end{macro} -% -%\subsection{Loading a database from an external file} -% -% \begin{macrocode} -\newcommand{\@longempty}{} -% \end{macrocode} -%\begin{macro}{\@dtl@read} -% \begin{macrocode} -\newread\@dtl@read -% \end{macrocode} -%\end{macro} -%\begin{macro}{\dtl@entrycr} -% Keep track of current column in data file -% \begin{macrocode} -\newcount\dtl@entrycr -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\ifdtlnoheader} -% The "noheader" option indicates that the file doesn't have a -% header row. -% \begin{macrocode} -\define@boolkey{loaddb}[dtl]{noheader}[true]{} -% \end{macrocode} -%\end{macro} -% The "keys" option specifies the list of keys in the same order -% as the columns in the data file. -% Each key is stored in \cs{@dtl@inky@}\meta{n} where \meta{n} is the -% roman numeral representation of the current column. -% \begin{macrocode} -\define@key{loaddb}{keys}{% - \dtl@entrycr=0\relax - \@for\@dtl@key:=#1\do - {% - \advance\dtl@entrycr by 1\relax - \expandafter - \edef\csname @dtl@inky@\romannumeral\dtl@entrycr\endcsname{% - \@dtl@key}% - }% -} -% \end{macrocode} -% The "headers" option specifies the list of headers in the -% same order as the columns in the data file. -% \begin{macrocode} -\define@key{loaddb}{headers}{% - \dtl@entrycr=0\relax - \@for\@dtl@head:=#1\do - {% - \advance\dtl@entrycr by 1\relax - \toks@=\expandafter{\@dtl@head}% - \expandafter - \edef\csname @dtl@inhd@\romannumeral\dtl@entrycr\endcsname{% - \the\toks@}% - }% -} -% \end{macrocode} -% -%\begin{macro}{\dtldefaultkey} -% Default key to use if none specified (column index will be -% appended). -% \begin{macrocode} -\newcommand*{\dtldefaultkey}{Column} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@dtl@readline} -%\begin{definition} -%\cs{@dtl@readline}\marg{file reg}\marg{cs} -%\end{definition} -% Reads line from \meta{file reg}, trims end of line character -% and stores in \meta{cs}. -% \begin{macrocode} -\newcommand*{\@dtl@readline}[2]{% -% Read a line from "#1" and store in "#2" -% \begin{macrocode} - \read#1 to #2% -% \end{macrocode} -% Trim the end of line character -% \begin{macrocode} - \dtl@trim#2% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@dtl@readrawline} -%\begin{definition} -%\cs{@dtl@readrawline}\marg{file register}\marg{cs} -%\end{definition} -% Reads line from \meta{file register}, trims end of line character, -% applies mappings and stores in \meta{cs}. -% \begin{macrocode} -\newcommand*{\@dtl@readrawline}[2]{% -% Read a line from "#1" and store in "#2" -% \begin{macrocode} - \@dtl@rawread#1 to #2% -% \end{macrocode} -% Trim the end of line character -% \begin{macrocode} - \dtl@trim#2% -% \end{macrocode} -% Apply mappings -% \begin{macrocode} - \dtl@domappings\@dtl@line -} -% \end{macrocode} -%\end{macro} - -%\begin{macro}{\DTLloaddb} -%\begin{definition} -% \cs{DTLloaddb}\oarg{options}\marg{db name}\marg{filename} -%\end{definition} -% Creates a new database called \meta{db name}, and loads the data -% in \meta{filename} into it. The separator and delimiter used in -% the file must match \cs{@dtl@separator} and \cs{@dtl@delimiter}. -% The optional argument is a comma-separated list. -%\changes{2.0}{2009 February 27}{removed checks to see if the -% database exists when adding to it} -%\changes{2.0}{2009 February 27}{added optional argument} -% \begin{macrocode} -\newcommand*{\DTLloaddb}{% - \let\@dtl@doreadline\@dtl@readline - \@dtlloaddb -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@dtlloaddb} -% Loads database using \cs{@dtl@doreadline} to read and trim -% line from file. (\cs{@dtl@doreadline} must be set before use.) -% \begin{macrocode} -\newcommand*{\@dtlloaddb}[3][]{% -% \end{macrocode} -% Check if file exists -% \begin{macrocode} - \IfFileExists{#3}{% -% \end{macrocode} -% File exists. Locally change catcode of double quote character in -% case it has been made active. -% \begin{macrocode} - \begingroup - \catcode`\"12\relax -% \end{macrocode} -% Initialise default options -% \begin{macrocode} - \dtlnoheaderfalse -% \end{macrocode} -% Get the options -% \begin{macrocode} - \setkeys{loaddb}{#1}% -% \end{macrocode} -% Open the file for reading. -% \begin{macrocode} - \openin\@dtl@read=#3% - \dtl@message{Reading `#3'}% -% \end{macrocode} -% Create the new database. -% \begin{macrocode} - \DTLnewdb{#2}% -% \end{macrocode} -% Check if the file is empty. -% \begin{macrocode} - \ifeof\@dtl@read -% \end{macrocode} -% File is empty, so just issue a warning. -% \begin{macrocode} - \PackageWarning{datatool}{File `#3' has no data}% - \else -% \end{macrocode} -% Does the file have a header row? -% \begin{macrocode} - \ifdtlnoheader - \else -% \end{macrocode} -% Remove initial blank rows -% \begin{macrocode} - \loop -% \end{macrocode} -% Set repeat condition to false -% \begin{macrocode} - \@dtl@conditionfalse -% \end{macrocode} -% Do nothing if reached the end of file -% \begin{macrocode} - \ifeof\@dtl@read - \else -% \end{macrocode} -% Read a line from the file and store in \cs{@dtl@line} -% \begin{macrocode} - \@dtl@doreadline\@dtl@read\@dtl@line -% \end{macrocode} -% If this is a blank row, set repeat condition to true -% \begin{macrocode} - \ifx\@dtl@line\@longempty - \@dtl@conditiontrue - \fi - \fi -% \end{macrocode} -% Repeat loop if necessary -% \begin{macrocode} - \if@dtl@condition - \repeat -% \end{macrocode} -% Parse the header row. Store the row as -% \meta{sep}\meta{row}\meta{sep} in \cs{@dtl@lin@}. -% \begin{macrocode} - \protected@edef\@dtl@lin@{% - \@dtl@separator\@dtl@line\@dtl@separator}% -% \end{macrocode} -% Keep track of columns: -% \begin{macrocode} - \dtl@entrycr=0\relax -% \end{macrocode} -% Keep lopping off elements until the end of the row is reached. -% (That is, until \cs{@dtl@lin@} is \cs{@dtl@separator}.) -%\changes{2.0}{2009 February 27}{changed \cs{whiledo} to -% \cs{loop} to improve efficiency}% -% \begin{macrocode} - \loop -% \end{macrocode} -% Lopoff the first element and store in \cs{@dtl@key} -% \begin{macrocode} - \expandafter\@dtl@lopoff\@dtl@lin@\to\@dtl@lin@\@dtl@key -% \end{macrocode} -% Increment column count. -% \begin{macrocode} - \advance\dtl@entrycr by 1\relax -% \end{macrocode} -% Store key in \cs{@dtl@toks} -% \begin{macrocode} - \expandafter\@dtl@toks\expandafter{\@dtl@key}% -% \end{macrocode} -% Store the key in \cs{@dtl@inky@}\meta{n} where \meta{n} is the -% roman numeral representation of the current column, unless -% already defined. -% \begin{macrocode} - \@ifundefined{@dtl@inky@\romannumeral\dtl@entrycr}% - {% - \expandafter - \edef\csname @dtl@inky@\romannumeral - \dtl@entrycr\endcsname{\the\@dtl@toks}% - }% - {% -% \end{macrocode} -% If key has been specified in "#1", then use the header found in the -% file, unless a header has also been specified in "#1" -% \begin{macrocode} - \@ifundefined{@dtl@inhd@\romannumeral\dtl@entrycr}% - {% - \expandafter - \edef\csname @dtl@inhd@\romannumeral - \dtl@entrycr\endcsname{\the\@dtl@toks}% - }% - {}% - }% -% \end{macrocode} -% Check if the loop should be repeated -% \begin{macrocode} - \ifx\@dtl@lin@\@dtl@separator - \@dtl@conditionfalse - \else - \@dtl@conditiontrue - \fi -% \end{macrocode} -% Repeat loop if necessary. -% \begin{macrocode} - \if@dtl@condition - \repeat -% \end{macrocode} -% End if no header -% \begin{macrocode} - \fi -% \end{macrocode} -% Now for the rest of the data. If the end of file has been -% reached, then only the header row is available or file is empty. -% \begin{macrocode} - \ifeof\@dtl@read - \ifdtlnoheader - \PackageWarning{datatool}{No data in `#3'}% - \else - \PackageWarning{datatool}{Only header row found in `#3'}% - \fi - \else -% \end{macrocode} -% Iterate through the rest of the file. First set the repeat -% condition to true: -% \begin{macrocode} - \@dtl@conditiontrue - \loop -% \end{macrocode} -% Read in a line -% \begin{macrocode} - \@dtl@doreadline\@dtl@read\@dtl@line -% \end{macrocode} -% Check if the line is empty. -%\changes{2.0}{2009 February 27}{changed \cs{ifthenelse} to -%\cs{ifx} to improve efficiency} -% \begin{macrocode} - \ifx\@dtl@line\@longempty -% \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.) -% \begin{macrocode} - \@sDTLnewrow{#2}% -% \end{macrocode} -% Store the row as \meta{sep}\meta{row}\meta{sep} to make the -% lopping off easier -% \begin{macrocode} - \expandafter\@dtl@toks\expandafter{\@dtl@line}% - \edef\@dtl@lin@{\@dtl@separator\the\@dtl@toks - \@dtl@separator}% -% \end{macrocode} -% Reset the column counter. -% \begin{macrocode} - \dtl@entrycr=0\relax -% \end{macrocode} -%\changes{2.0}{2009 February 27}{changed \cs{whiledo} to \cs{loop} -% to improve efficiency} -% Iterate through each element in the row. Needs to be grouped -% since we're already inside a loop. -% \begin{macrocode} - {% -% \end{macrocode} -% Initialise repeat condition -% \begin{macrocode} - \@dtl@conditiontrue -% \end{macrocode} -% Iterate through the list -% \begin{macrocode} - \loop -% \end{macrocode} -% lop off first element and store in \cs{@dtl@thisentry} -% \begin{macrocode} - \expandafter\@dtl@lopoff\@dtl@lin@\to - \@dtl@lin@\@dtl@thisentry -% \end{macrocode} -% Increment the column count. -% \begin{macrocode} - \advance\dtl@entrycr by 1\relax -% \end{macrocode} -% Get the key for this column and store in \cs{@dtl@thiskey}. -% Use default value if not defined. -% \begin{macrocode} - \@ifundefined{@dtl@inky@\romannumeral\dtl@entrycr}% - {% - \edef\@dtl@thiskey{\dtldefaultkey - \number\dtl@entrycr}% - \expandafter\let - \csname @dtl@inky@\romannumeral - \dtl@entrycr\endcsname\@dtl@thiskey - }% - {% - \edef\@dtl@thiskey{% - \csname @dtl@inky@\romannumeral - \dtl@entrycr\endcsname}% - }% -% \end{macrocode} -% Store this entry in \cs{@dtl@toks} -% \begin{macrocode} - \expandafter\@dtl@toks\expandafter{\@dtl@thisentry}% -% \end{macrocode} -% Add this entry to the database -% \begin{macrocode} - \edef\@do@dtlnewentry{\noexpand\@sDTLnewdbentry - {#2}{\@dtl@thiskey}{\the\@dtl@toks}}% - \@do@dtlnewentry -% \end{macrocode} -% Check if loop should be terminated -% \begin{macrocode} - \ifx\@dtl@lin@\@dtl@separator - \@dtl@conditionfalse - \fi -% \end{macrocode} -% Repeat loop if necessary -% \begin{macrocode} - \if@dtl@condition - \repeat - }% -% \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. -% \begin{macrocode} - \ifeof\@dtl@read \@dtl@conditionfalse\fi -% \end{macrocode} -% Repeat if necessary -% \begin{macrocode} - \if@dtl@condition - \repeat - \fi -% \end{macrocode} -% End of first \cs{ifeof} -% \begin{macrocode} - \fi -% \end{macrocode} -% Close the input file -% \begin{macrocode} - \closein\@dtl@read -% \end{macrocode} -% Set the headers if required -% \begin{macrocode} - \edef\@dtl@maxcols{\expandafter - \number\csname dtlcols@#2\endcsname}% - \dtlgforint\dtl@entrycr=1\to\@dtl@maxcols\step1\do - {% - \@ifundefined{@dtl@inhd@\romannumeral\dtl@entrycr}% - {}% - {% - \expandafter\let\expandafter\@dtl@head - \csname @dtl@inhd@\romannumeral\dtl@entrycr\endcsname - \@dtl@toks=\expandafter{\@dtl@head}% - \edef\@dtl@dosetheader{\noexpand\@dtl@setheaderforindex - {#2}{\number\dtl@entrycr}{\the\@dtl@toks}}% - \@dtl@dosetheader - }% - }% -% \end{macrocode} -% End current scope -% \begin{macrocode} - \endgroup -% \end{macrocode} -% End true part of if file exists -% \begin{macrocode} - }{% -% \end{macrocode} -% Requested file not found on TeX's path -% \begin{macrocode} - \PackageError{datatool}{Can't load database `#2' (file `#3' - doesn't exist)}{}% - }% -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\dtl@trim} -%\begin{definition} -%\cs{dtl@trim}\marg{line} -%\end{definition} -% 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 -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\@dtl@starttrim} -% Start trimming -% \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% -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\@dtl@trim} -% \begin{macrocode} -\long\def\@dtl@trim#1 \@nil{\long\def\@dtl@trmstr{#1}} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLloadrawdb} -%\begin{definition} -%\cs{DTLloadrawdb}\marg{db name}\marg{filename} -%\end{definition} -% Loads a raw database (substitutes "%" $\to$ "\%", -% "$" $\to$ "\$", "&" $\to$ "\&", "#" $\to$ "\#", -% "~" $\to$ "\textasciitilde", "_" $\to$ "\_" -% and "^" $\to$ "\textasciicircum".) -% \begin{macrocode} -\newcommand*\DTLloadrawdb{% - \let\@dtl@doreadline\@dtl@readrawline - \@dtlloaddb -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@dtl@rawread} -%\begin{definition} -% \cs{@dtl@rawread}\meta{number}to\meta{cmd} -%\end{definition} -% Reads in a raw line from file given by \meta{number} -% converts special characters and stores in \meta{cmd} -% \begin{macrocode} -\begingroup -\catcode`\%=\active -\catcode`$=\active -\catcode`&=\active -\catcode`~=\active -\catcode`_=\active -\catcode`^=\active -\catcode`#=\active -\catcode`?=6\relax -\catcode`<=1\relax -\catcode`>=2\relax -\catcode`\{=\active -\catcode`\}=\active -\gdef\@dtl@rawread?1to?2<\relax -<<\catcode`\%=\active -\catcode`$=\active -\catcode`&=\active -\catcode`~=\active -\catcode`_=\active -\catcode`^=\active -\catcode`#=\active -\catcode`\{=\active -\catcode`\}=\active -\def%<\noexpand\%>\relax -\def$<\noexpand\$>\relax -\def&<\&>\relax -\def#<\#>\relax -\def~<\noexpand\textasciitilde>\relax -\def_<\noexpand\_>\relax -\def^<\noexpand\textasciicircum>\relax -\@dtl@activatebraces -\@dtl@doreadraw?1?2>>> -\gdef\@dtl@doreadraw?1?2<\relax -\read?1 to \tmp -\xdef?2<\tmp>\relax -> -\endgroup -% \end{macrocode} -%\end{macro} -%\begin{macro}{\@dtl@activatebraces} -% \cs{@dtl@activatebraces} resets braces for \cs{@dtl@rawread} -% \begin{macrocode} -\begingroup -\catcode`\{=\active -\catcode`\}=\active -\catcode`<=1\relax -\catcode`>=2\relax -\gdef\@dtl@activatebraces<% - \catcode`\{=\active - \catcode`\}=\active - \def{<\noexpand\{>% - \def}<\noexpand\}>% ->% -\endgroup -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\DTLrawmap} -%\begin{definition} -%\cs{DTLrawmap}\marg{string}\marg{replacement} -%\end{definition} -% 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 -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@dtl@rawmappings} -% List of mappings. -% \begin{macrocode} -\newcommand*{\@dtl@rawmappings}{} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\dtl@domappings} -%\begin{definition} -% \cs{dtl@domappings}\marg{cmd} -%\end{definition} -% Do all mappings in string given by \meta{cmd}. -% \begin{macrocode} -\newcommand*{\dtl@domappings}[1]{% -\@for\@dtl@map:=\@dtl@rawmappings\do{% - \expandafter\DTLsubstitute\expandafter#1\@dtl@map -}} -% \end{macrocode} -%\end{macro} -% %\begin{macro}{\DTLsubstitute} %\begin{definition} %\cs{DTLsubstitute}\marg{cmd}\marg{original}\marg{replacement} @@ -17052,31 +17803,6 @@ options>#2=\textsf{#2}|hyperpage}} % \end{macrocode} %\end{macro} % -%\begin{macro}{\DTLifinlist} -%\cs{DTLifinlist}\marg{element}\marg{list}\marg{true part}\marg{false part} -% 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}) -% \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} -% -% %\subsection{Currencies} %\begin{macro}{\@dtl@currencies} % \cs{@dtl@currencies} stores all known currencies. @@ -17238,7 +17964,7 @@ options>#2=\textsf{#2}|hyperpage}} % Declare package: % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{datapie}[2007/02/27 v2.0 (NLCT)] +\ProvidesPackage{datapie}[2009/10/22 v2.01 (NLCT)] % \end{macrocode} % Require \sty{xkeyval} package % \begin{macrocode} @@ -17365,12 +18091,14 @@ options>#2=\textsf{#2}|hyperpage}} \def\dtl@outerlabel{}% % \end{macrocode} %\end{macro} -% \counterfmt{DTLpieroundvar} is a counter governing the number of digits +%\begin{counter}{DTLpieroundvar} +% \ctrfmt{DTLpieroundvar} is a counter governing the number of digits % to round to when using \cs{FPround}. % \begin{macrocode} \newcounter{DTLpieroundvar} \setcounter{DTLpieroundvar}{1} % \end{macrocode} +%\end{counter} % %\begin{macro}{\DTLdisplayinnerlabel} %\begin{definition} @@ -17914,7 +18642,7 @@ Try #2-#1 instead of #1-#2}% % Declare package: % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{dataplot}[2009/02/27 v2.0 (NLCT)] +\ProvidesPackage{dataplot}[2009/10/22 v2.01 (NLCT)] % \end{macrocode} % Required packages % \begin{macrocode} @@ -18083,18 +18811,22 @@ Try #2-#1 instead of #1-#2}% \setlength\DTLminminortickgap{5pt} % \end{macrocode} %\end{macro} +%\begin{counter}{DTLplotroundvar} % Round $x$ tick labels to the number of digits given by -% the counter \counterfmt{DTLplotroundXvar}. +% the counter \ctrfmt{DTLplotroundXvar}. % \begin{macrocode} \newcounter{DTLplotroundXvar} \setcounter{DTLplotroundXvar}{2} % \end{macrocode} +%\end{counter} +%\begin{counter}{DTLplotroundYvar} % Round $y$ tick labels to the number of digits given by -% the counter \counterfmt{DTLplotroundYvar}. +% the counter \ctrfmt{DTLplotroundYvar}. % \begin{macrocode} \newcounter{DTLplotroundYvar} \setcounter{DTLplotroundYvar}{2} % \end{macrocode} +%\end{counter} %\begin{macro}{\ifDTLxaxis} % The conditional \cs {ifDTLxaxis} is used to determine whether or % not to display the $x$ axis. @@ -19338,7 +20070,7 @@ east,southeast,south,southwest,west,northwest}[northeast]{% % Declare package: % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{databar}[2009/02/27 v2.0 (NLCT)] +\ProvidesPackage{databar}[2009/10/22 v2.01 (NLCT)] % \end{macrocode} % Require \sty{xkeyval} package % \begin{macrocode} @@ -19448,12 +20180,14 @@ east,southeast,south,southwest,west,northwest}[northeast]{% % \end{macrocode} %\end{macro} % -% \counterfmt{DTLbarroundvar} is a counter governing the number of digits +%\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. @@ -20623,7 +21357,7 @@ uppermultibarlabels,groupgap}% %\subsection{Package Declaration} % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{databib}[2009/02/27 v2.0 (NLCT)] +\ProvidesPackage{databib}[2009/10/22 v2.01 (NLCT)] % \end{macrocode} % Load required packages: % \begin{macrocode} @@ -20910,20 +21644,24 @@ uppermultibarlabels,groupgap}% % \end{macrocode} %\end{macro} % -%The counter \counterfmt{DTLbibrow} keeps track of the current +%\begin{counter}{DTLbibrow} +%The counter \ctrfmt{DTLbibrow} keeps track of the current %row in the body of \cs{DTLforeachbibentry}. (You can't rely on -%\counterfmt{DTLrowi}, \counterfmt{DTLrowii} and -% \counterfmt{DTLrowiii}, as \cs{DTLforeachbibentry} pass the +%\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 \counterfmt{DTLrowi} +% 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} @@ -21123,13 +21861,15 @@ uppermultibarlabels,groupgap}% \newcount\@dtl@authorcount % \end{macrocode} %\end{macro} -% The counter \counterfmt{DTLmaxauthors} indicates the maximum number of +%\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}): @@ -21181,13 +21921,15 @@ uppermultibarlabels,groupgap}% } % \end{macrocode} %\end{macro} -% The counter \counterfmt{DTLmaxeditors} indicates the maximum number of +%\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 @@ -24603,5 +25345,1129 @@ EXECUTE {end.bib} %</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 8dc5e7e9d71..a3d3bd39125 100644 --- a/Master/texmf-dist/source/latex/datatool/datatool.ins +++ b/Master/texmf-dist/source/latex/datatool/datatool.ins @@ -1,4 +1,4 @@ -% datatool.ins generated using makedtx version 0.94b 2009/7/13 10:04 +% datatool.ins generated using makedtx version 0.94b 2009/11/15 15:10 \input docstrip \preamble @@ -18,7 +18,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. + 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. \endpreamble @@ -35,6 +35,8 @@ \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}} } \endbatchfile |