diff options
Diffstat (limited to 'Master/texmf-dist/doc/latex/csvsimple/csvsimple-l3.tex')
-rw-r--r-- | Master/texmf-dist/doc/latex/csvsimple/csvsimple-l3.tex | 2504 |
1 files changed, 2504 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/latex/csvsimple/csvsimple-l3.tex b/Master/texmf-dist/doc/latex/csvsimple/csvsimple-l3.tex new file mode 100644 index 00000000000..a3e61e241ff --- /dev/null +++ b/Master/texmf-dist/doc/latex/csvsimple/csvsimple-l3.tex @@ -0,0 +1,2504 @@ +% \LaTeX-Main\ +% !TeX encoding=UTF-8 +%% The LaTeX package csvsimple - version 2.0.0 (2021/06/29) +%% csvsimple.tex: Manual +%% +%% ------------------------------------------------------------------------------------------- +%% Copyright (c) 2008-2021 by Prof. Dr. Dr. Thomas F. Sturm <thomas dot sturm at unibw dot de> +%% ------------------------------------------------------------------------------------------- +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2005/12/01 or later. +%% +%% This work has the LPPL maintenance status `author-maintained'. +%% +%% This work consists of all files listed in README.md +%% +\documentclass[a4paper,11pt]{ltxdoc} +\usepackage{csvsimple-doc} + +\usepackage{\csvpkgprefix csvsimple-l3} + +\tcbmakedocSubKey{docCsvKey}{csvsim} +\tcbmakedocSubKeys{docCsvKeys}{csvsim} + +\hypersetup{ + pdftitle={Manual for the csvsimple-l3 package}, + pdfauthor={Thomas F. Sturm}, + pdfsubject={csv file processing with LaTeX3}, + pdfkeywords={csv file, comma separated values, key value syntax} +} + +\usepackage{incgraph} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{document} + + +\begin{center} +\begin{tcolorbox}[enhanced,hbox,tikznode,left=8mm,right=8mm,boxrule=0.4pt, + colback=white,colframe=black!50!yellow, + drop lifted shadow=black!50!yellow,arc is angular, + before=\par\vspace*{5mm},after=\par\bigskip] +{\bfseries\LARGE The \texttt{csvsimple-l3} package}\\[3mm] +{\large Manual for version \version\ (\datum)} +\end{tcolorbox} +{\large Thomas F.~Sturm% + \footnote{Prof.~Dr.~Dr.~Thomas F.~Sturm, Institut f\"{u}r Mathematik und Informatik, + Universit\"{a}t der Bundeswehr M\"{u}nchen, D-85577 Neubiberg, Germany; + email: \href{mailto:thomas.sturm@unibw.de}{thomas.sturm@unibw.de}}\par\medskip +\normalsize\url{https://www.ctan.org/pkg/csvsimple}\par +\url{https://github.com/T-F-S/csvsimple} +} +\end{center} +\bigskip +\begin{absquote} + \begin{center}\bfseries Abstract\end{center} + |csvsimple(-l3)| provides a simple \LaTeX\ interface for the processing of files with + comma separated values (CSV). |csvsimple-l3| relies heavily on the key value + syntax from |l3keys| which results in an easy way of usage. + Filtering and table generation is especially supported. Since the package + is considered as a lightweight tool, there is no support for data sorting + or data base storage. +\end{absquote} + +\vspace{1cm} + +\includegraphics[width=\linewidth]{csvsimple-title.png} +% Source code for the title picture - omitted for PDF viewer compatibility +\begin{tcolorbox}[void] +\begin{NoHyper} +\begin{inctext}[] +\begin{tikzpicture} +\fill[top color=blue!50!gray!50,bottom color=red!50!gray!50] (-8,-5) rectangle (8,5); +\node at (0,2.5) {\tcbinputlisting{listing file=csvsimple-example.csv,listing only,width=11cm,blankest,colupper=blue!50!black}}; +\node[red!50!black] at (0,-2.5) {\csvautotabular{csvsimple-example.csv}}; +\begin{scope}[transparency group=knockout] +\fill [top color=blue!50!gray!10,bottom color=red!50!gray!10] (-7.7,-4.7) rectangle (7.7,4.7); +\node at (0,2.5) {\tcbinputlisting{listing file=csvsimple-example.csv,listing only,width=11cm,blankest,colupper=blue!20}}; +\node[red!20] at (0,-2.5) {\csvautotabular{csvsimple-example.csv}}; +\node at (0,2.5) [opacity=0,font=\fontencoding{T1}\fontfamily{lmr}\fontsize{7cm}{7cm}\bfseries] {csv}; +\node at (0,-2.5) [opacity=0,font=\fontencoding{T1}\fontfamily{lmr}\fontsize{4.8cm}{4.8cm}\bfseries] {simple}; +\end{scope} +\end{tikzpicture} +\end{inctext} +\end{NoHyper} +\end{tcolorbox} + + +\clearpage +\tableofcontents + +\clearpage +\section{Introduction}% +The |csvsimple-l3| package is applied to the processing of +CSV\footnote{CSV file: file with comma separated values.} files. +This processing is controlled by key value assignments according to the +syntax of |l3keys|. Sample applications of the package +are tabular lists, serial letters, and charts. + +An alternative to |csvsimple-l3| is the |datatool| package +which provides considerably more functions and allows sorting of data by \LaTeX. +|csvsimple-l3| has a different approach for the user interface and +is deliberately restricted to some basic functions with fast +processing speed. + +Mind the following restrictions: +\begin{itemize} +\item Sorting is not supported directly but can be done + with external tools, see \Fullref{sec:Sorting}. +\item Values are expected to be comma separated, but the package + provides support for other separators, see \Fullref{sec:separators}. +\item Values are expected to be either not quoted or quoted with + curly braces |{}| of \TeX\ groups. Other quotes like doublequotes + are not supported directly, but can be achieved + with external tools, see \Fullref{sec:importeddata}. +\item Every data line is expected to contain the same amount of values. + Unfeasible data lines are silently ignored by default, but this can + be configured, see \Fullref{sec:consistency}. +\end{itemize} + + +\subsection{Loading the Package} +|csvsimple-l3| is loaded with \emph{one} of the following +alternatives inside the preamble: +\begin{dispListing} +\usepackage[l3]{csvsimple} + % or alternatively (not simultaneously!) +\usepackage{csvsimple-l3} +\end{dispListing} + +Not automatically loaded, but used for many examples are the packages +|longtable|, |booktabs|, |ifthen|, and |booktabs|. + + +\clearpage +\subsection{First Steps} +Every line of a processable CSV file has to contain an identical amount of +comma\footnote{See \refKey{/csvsim/separator} for other separators than comma.} separated values. The curly braces |{}| of \TeX\ groups can be used +to mask a block which may contain commas not to be processed as separators. + +The first line of such a CSV file is usually but not necessarily a header line +which contains the identifiers for each column. + +%-- file embedded for simplicity -- +\begin{tcbverbatimwrite}{grade.csv} +name,givenname,matriculation,gender,grade +Maier,Hans,12345,m,1.0 +Huber,Anna,23456,f,2.3 +Weißbäck,Werner,34567,m,5.0 +Bauer,Maria,19202,f,3.3 +\end{tcbverbatimwrite} +%-- end embedded file -- + +\csvlisting{grade} + +\smallskip +The most simple way to display a CSV file in tabular form is the processing +with the \refCom{csvautotabular} command. + +\begin{dispExample} +\csvautotabular{grade.csv} +\end{dispExample} + + +Typically, one would use \refCom{csvreader} instead of |\csvautotabular| to +gain full control over the interpretation of the included data. + +In the following example, the entries of the header line are automatically +assigned to \TeX\ macros which may be used deliberately. + + +\begin{dispExample} +\begin{tabular}{|l|c|}\hline% +\bfseries Person & \bfseries Matr.~No. +\csvreader[ + head to column names + ]{grade.csv}{}{% + \\\givenname\ \name & \matriculation + }% +\\\hline +\end{tabular} +\end{dispExample} + + +\clearpage +|\csvreader| is controlled by a plenty of options. For example, for table +applications line breaks are easily inserted by +\refKey{/csvsim/late after line}. This defines a macro execution just before +the following line. +Additionally, the assignment of columns to \TeX\ macros is shown in a non automated +way. + +\begin{dispExample} +\begin{tabular}{|r|l|c|}\hline% +& Person & Matr.~No.\\\hline\hline +\csvreader[ + late after line = \\\hline + ]{grade.csv}% + {name=\name, givenname=\firstname, matriculation=\matnumber}{% + \thecsvrow & \firstname~\name & \matnumber + }% +\end{tabular} +\end{dispExample} + +\smallskip +An even more comfortable and preferrable way to create a table is setting +appropriate option keys. Note, that this gives you the possibility to create a +meta key (called style here) which contains the whole table creation +using \refCom{csvstyle} or |keys_define:nn| from |l3keys|. + +\begin{dispExample} +\csvreader[ + tabular = |r|l|c|, + table head = \hline & Person & Matr.~No.\\\hline\hline, + late after line = \\\hline + ]{grade.csv} + {name=\name, givenname=\firstname, matriculation=\matnumber}{% + \thecsvrow & \firstname~\name & \matnumber + }% +\end{dispExample} + + +\clearpage +The next example shows such a style definition with the convenience macro +\refCom{csvstyle}. Here, we see again the automated assignment of header +entries to column names by \refKey{/csvsim/head to column names}. +For this, the header entries have to be without spaces and special characters. +But you can always assign entries to canonical macro names manually like in the examples +above. Here, we also add a \refKey{/csvsim/head to column names prefix} to avoid +macro name clashes. + +\begin{dispExample} +\csvstyle{myTableStyle}{ + tabular = |r|l|c|, + table head = \hline & Person & Matr.~No.\\\hline\hline, + late after line = \\\hline, + head to column names, + head to column names prefix = MY, + } + +\csvreader[myTableStyle] + {grade.csv}{}{% + \thecsvrow & \MYgivenname~\MYname & \MYmatriculation + } +\end{dispExample} + + +\smallskip +Another way to address columns is to use their roman numbers. +The direct addressing is done by |\csvcoli|, |\csvcolii|, |\csvcoliii|, \ldots: + +\begin{dispExample} +\csvreader[ + tabular = |r|l|c|, + table head = \hline & Person & Matr.~No.\\\hline\hline, + late after line = \\\hline + ]{grade.csv}{}{% + \thecsvrow & \csvcolii~\csvcoli & \csvcoliii + } +\end{dispExample} + +\smallskip +And yet another method to assign macros to columns is to use arabic numbers +for the assignment: + +\begin{dispExample} +\csvreader[ + tabular = |r|l|c|, + table head = \hline & Person & Matr.~No.\\\hline\hline, + late after line = \\\hline]% + {grade.csv} + {1=\name, 2=\firstname, 3=\matnumber}{% + \thecsvrow & \firstname~\name & \matnumber + } +\end{dispExample} + +\smallskip +For recurring applications, the |l3keys| syntax allows to create own meta options +(styles) for a consistent and centralized design. The following example is easily +modified to obtain more or less option settings. + +\begin{dispExample} +\csvstyle{myStudentList}{% + tabular = |r|l|c|, + table head = \hline & Person & #1\\\hline\hline, + late after line = \\\hline, + column names = {name=\name, givenname=\firstname} + } + +\csvreader[ myStudentList={Matr.~No.} ] + {grade.csv} + {matriculation=\matnumber}{% + \thecsvrow & \firstname~\name & \matnumber + }% +\hfill% +\csvreader[ myStudentList={Grade} ] + {grade.csv} + {grade=\grade}{% + \thecsvrow & \firstname~\name & \grade + } +\end{dispExample} + + +\clearpage +Alternatively, column names can be set by \refCom{csvnames} +and style definitions by \refCom{csvstyle}. +With this, the last example is rewritten as follows: + +\begin{dispExample} +\csvnames{myNames}{1=\name,2=\firstname,3=\matnumber,5=\grade} +\csvstyle{myStudentList}{ + tabular = |r|l|c|, + table head = \hline & Person & #1\\\hline\hline, + late after line = \\\hline, + myNames + } + +\csvreader[ myStudentList={Matr.~No.} ] + {grade.csv}{}{% + \thecsvrow & \firstname~\name & \matnumber + }% +\hfill% +\csvreader[ myStudentList={Grade} ] + {grade.csv}{}{% + \thecsvrow & \firstname~\name & \grade + } +\end{dispExample} + +\smallskip +The data lines of a CSV file can also be filtered. In the following example, +a certificate is printed only for students with grade unequal to 5.0. + +\begin{dispExample} +\csvreader[ + filter not strcmp={\grade}{5.0} + ]{grade.csv} + {1=\name,2=\firstname,3=\matnumber,4=\gender,5=\grade}{% + \begin{center}\Large\bfseries Certificate in Mathematics\end{center} + \large\ifcsvstrcmp{\gender}{f}{Ms.}{Mr.} + \firstname~\name, matriculation number \matnumber, has passed the test + in mathematics with grade \grade.\par\ldots\par + }% +\end{dispExample} + + +\clearpage +\section{Macros for the Processing of CSV Files}\label{sec:makros}% + +\begin{docCommand}{csvreader}{\oarg{options}\marg{file name}\marg{assignments}\marg{command list}} + \refCom{csvreader} reads the file denoted by \meta{file name} line by line. + Every line of the file has to contain an identical amount of + comma separated values. The curly braces |{}| of \TeX\ groups can be used + to mask a block which may contain commas not to be processed as separators.\smallskip + + The first line of such a CSV file is by default but not necessarily + processed as a header line which contains the identifiers for each column. + The entries of this line can be used to give \meta{assignments} to \TeX\ macros + to address the columns. The number of entries of this first line + determines the accepted number of entries for all following lines. + Every line which contains a higher or lower number of entries is ignored + during standard processing.\smallskip + + The \meta{assignments} are given as comma separated list of key value pairs + \mbox{\meta{name}|=|\meta{macro}}. Here, \meta{name} is an entry from the + header line \emph{or} the arabic number of the addressed column. + \meta{macro} is some \TeX\ macro which gets the content of the addressed column.\smallskip + + The \meta{command list} is executed for every accepted data line. Inside the + \meta{command list} is applicable: + \begin{itemize} + \item \docAuxCommand{thecsvrow} or the counter |csvrow| which contains the number of the + current data line (starting with 1). + \item \docAuxCommand{csvcoli}, \docAuxCommand{csvcolii}, \docAuxCommand{csvcoliii}, \ldots, + which contain the contents of the column entries of the current data line. + Alternatively can be used: + \item \meta{macro} from the \meta{assignments} to have a logical + addressing of a column entry. + \end{itemize} + Note, that the \meta{command list} is allowed to contain |\par| and + that \textbf{all macro definitions are made global} to be used for table applications.\smallskip + + The processing of the given CSV file can be controlled by various + \meta{options} given as key value list. The feasible option keys + are described in section \ref{sec:schluessel} from page \pageref{sec:schluessel}. + +\begin{dispExample} +\csvreader[ + tabular = |r|l|l|, + table head = \hline, + table foot = \hline + ]{grade.csv}% + {name=\name, givenname=\firstname, grade=\grade}{% + \grade & \firstname~\name & \csvcoliii + } +\end{dispExample} + +Mainly, the |\csvreader| command consists of a \refCom{csvloop} macro with +following parameters:\par +|\csvloop{|\meta{options}|, file=|\meta{file name}|, column names=|\meta{assignments}|,|\\ + \hspace*{2cm} |command=|\meta{command list}|}|\par + Therefore, the application of the keys \refKey{/csvsim/file} and \refKey{/csvsim/command} +is useless for |\csvreader|. +\end{docCommand} + + +\clearpage +\begin{docCommand}{csvloop}{\marg{options}} + Usually, \refCom{csvreader} may be preferred instead of |\csvloop|. + \refCom{csvreader} is based on |\csvloop| which takes a mandatory list of + \meta{options} in key value syntax. + This list of \meta{options} controls the total processing. Especially, + it has to contain the CSV file name. +\begin{dispExample} +\csvloop{ + file = {grade.csv}, + head to column names, + command = \name, + before reading = {List of students:\ }, + late after line = {{,}\ }, + late after last line = . + } +\end{dispExample} +\end{docCommand} + +\bigskip + +The following |\csvauto...| commands are intended for quick data overview +with limited formatting potential. +See Subsection~\ref{subsec:tabsupport} on page \pageref{subsec:tabsupport} +for the general table options in combination with \refCom{csvreader} and +\refCom{csvloop}. + +\begin{docCommands}[ + doc parameter = \oarg{options}\marg{file name} + ] + { + { doc name = csvautotabular }, + { doc name = csvautotabular*, doc new = 2021-06-25 } + } + |\csvautotabular| or |\csvautotabular*| + is an abbreviation for the application of the option key + \refKey{/csvsim/autotabular} or \refKey{/csvsim/autotabular*} + together with other \meta{options} to \refCom{csvloop}. + This macro reads the whole CSV file denoted by \meta{file name} + with an automated formatting. + The star variant treats the first line as data line and not as header line. +\begin{dispExample} +\csvautotabular*{grade.csv} +\end{dispExample} +\begin{dispExample} +\csvautotabular[filter equal={\csvcoliv}{f}]{grade.csv} +\end{dispExample} +\end{docCommands} + +\clearpage + +\begin{docCommands}[ + doc parameter = \oarg{options}\marg{file name} + ] + { + { doc name = csvautolongtable }, + { doc name = csvautolongtable*, doc new = 2021-06-25 } + } + |\csvautolongtable| or |\csvautolongtable*| + is an abbreviation for the application of the option key + \refKey{/csvsim/autolongtable} or \refKey{/csvsim/autolongtable*} + together with other \meta{options} to \refCom{csvloop}. + This macro reads the whole CSV file denoted by \meta{file name} + with an automated formatting. + For application, the package |longtable| is required which has to be + loaded in the preamble. + The star variant treats the first line as data line and not as header line. +\begin{dispListing} +\csvautolongtable{grade.csv} +\end{dispListing} +\csvautolongtable{grade.csv} +\end{docCommands} + + + +\begin{docCommands}[ + doc parameter = \oarg{options}\marg{file name} + ] + { + { doc name = csvautobooktabular }, + { doc name = csvautobooktabular*, doc new = 2021-06-25 } + } + |\csvautobooktabular| or |\csvautobooktabular*| + is an abbreviation for the application of the option key + \refKey{/csvsim/autobooktabular} or \refKey{/csvsim/autobooktabular*} + together with other \meta{options} to \refCom{csvloop}. + This macro reads the whole CSV file denoted by \meta{file name} + with an automated formatting. + For application, the package |booktabs| is required which has to be + loaded in the preamble. + The star variant treats the first line as data line and not as header line. +\begin{dispExample} +\csvautobooktabular{grade.csv} +\end{dispExample} +\end{docCommands} + + +\begin{docCommands}[ + doc parameter = \oarg{options}\marg{file name} + ] + { + { doc name = csvautobooklongtable }, + { doc name = csvautobooklongtable*, doc new = 2021-06-25 } + } + |\csvautobooklongtable| or |\csvautobooklongtable*| + is an abbreviation for the application of the option key + \refKey{/csvsim/autobooklongtable} or \refKey{/csvsim/autobooklongtable*} + together with other \meta{options} to \refCom{csvloop}. + This macro reads the whole CSV file denoted by \meta{file name} + with an automated formatting. + For application, the packages |booktabs| and |longtable| are required which have to be + loaded in the preamble. + The star variant treats the first line as data line and not as header line. +\begin{dispListing} +\csvautobooklongtable{grade.csv} +\end{dispListing} +\csvautobooklongtable{grade.csv} +\end{docCommands} + + + +\clearpage + +\begin{docCommand}[doc updated = 2021-06-25]{csvset}{\marg{options}} + Sets \meta{options} for every following + \refCom{csvreader} and \refCom{csvloop}. + Note that most options are set to default values at the begin of these + commands and therefore cannot be defined reasonable by \refCom{csvset}. + But it may be used for options like \refKey{/csvsim/csvsorter command} + to give global settings. Also see \refKey{/csvsim/every csv}. +\end{docCommand} + + +\begin{docCommand}{csvstyle}{\marg{key}\marg{options}} + Defines a new |l3keys| meta key to call other keys. It is used to + make abbreviations for convenient key set applications. + The new \meta{key} can take one parameter. The name \refCom{csvstyle} + originates from an old version of |csvsimple| which used |pgfkeys| + instead of |l3keys|. + +\begin{dispExample} +\csvstyle{grade list}{ + column names = {name=\name, givenname=\firstname, grade=\grade} + } +\csvstyle{passed}{ + filter not strcmp = {\grade}{5.0} + } +The following students passed the test in mathematics:\\ +\csvreader[grade list,passed]{grade.csv}{}{ + \firstname\ \name\ (\grade); + } +\end{dispExample} +\end{docCommand} + + +\begin{docCommand}{csvnames}{\marg{key}\marg{assignments}} + Abbreviation for |\csvstyle{|\meta{key}|}{column names=|\marg{assignments}|}| + to define additional \meta{assignments} of macros to columns. +\begin{dispExample} +\csvnames{grade list}{ + name=\name, givenname=\firstname, grade=\grade + } +\csvstyle{passed}{ + filter not strcmp = {\grade}{5.0} + } +The following students passed the test in mathematics:\\ +\csvreader[grade list,passed]{grade.csv}{}{ + \firstname\ \name\ (\grade); + } +\end{dispExample} +\end{docCommand} + + +%\begin{docCommand}{csvheadset}{\marg{assignments}} +% For some special cases, this command can be used to change the +% \meta{assignments} of macros to columns during execution of +% \refCom{csvreader} and \refCom{csvloop}. +%\begin{dispExample} +%\csvreader{grade.csv}{}% +% { \csvheadset{name=\n} \fbox{\n} +% \csvheadset{givenname=\n} \ldots\ \fbox{\n} }% +%\end{dispExample} +%\end{docCommand} + +\clearpage + + +\begin{docCommand}[doc updated=2021-06-28]{ifcsvoddrow}{\marg{then macros}\marg{else macros}} + Inside the command list of \refCom{csvreader}, the \meta{then macros} + are executed for odd-numbered data lines, and the \meta{else macros} + are executed for even-numbered lines. + \refCom{ifcsvoddrow} is expandable. +\begin{dispExample} +\csvreader[ + head to column names, + tabular = |l|l|l|l|, + table head = \hline\bfseries \# & \bfseries Name & \bfseries Grade\\\hline, + table foot = \hline + ]{grade.csv}{}{% + \ifcsvoddrow{\slshape\thecsvrow & \slshape\name, \givenname & \slshape\grade}% + {\bfseries\thecsvrow & \bfseries\name, \givenname & \bfseries\grade} + } +\end{dispExample} + +The |\ifcsvoddrow| macro may be used for striped tables: + +\begin{dispExample} +% This example needs the xcolor package +\csvreader[ + head to column names, + tabular = rlcc, + table head = \hline\rowcolor{red!50!black}\color{white}\# & \color{white}Person + & \color{white}Matr.~No. & \color{white}Grade, + late after head = \\\hline\rowcolor{yellow!50}, + late after line = \ifcsvoddrow{\\\rowcolor{yellow!50}}{\\\rowcolor{red!25}} + ]{grade.csv}{}{% + \thecsvrow & \givenname~\name & \matriculation & \grade + } +\end{dispExample} + +Alternatively, |\rowcolors| from the |xcolor| package can be used for this +purpose: + +\begin{dispExample} +% This example needs the xcolor package +\csvreader[ + head to column names, + tabular = rlcc, + before table = \rowcolors{2}{red!25}{yellow!50}, + table head = \hline\rowcolor{red!50!black}\color{white}\# & \color{white}Person + & \color{white}Matr.~No. & \color{white}Grade\\\hline + ]{grade.csv}{}{% + \thecsvrow & \givenname~\name & \matriculation & \grade + } +\end{dispExample} + + The deprecated, but still available alias for this command is + \docAuxCommand{csvifoddrow}. +\end{docCommand} + +\clearpage + +\begin{docCommand}[doc updated=2021-06-28]{ifcsvfirstrow}{\marg{then macros}\marg{else macros}} + Inside the command list of \refCom{csvreader}, the \meta{then macros} + are executed for the first data line, and the \meta{else macros} + are executed for all following lines. + \refCom{ifcsvfirstrow} is expandable. +\begin{dispExample} +\csvreader[ + tabbing, + head to column names, + table head = {\hspace*{3cm}\=\kill} + ]{grade.csv}{}{% + \givenname~\name \> (\ifcsvfirstrow{first entry!!}{following entry}) + } +\end{dispExample} + The deprecated, but still available alias for this command is + \docAuxCommand{csviffirstrow}. +\end{docCommand} + +\medskip + + +\begin{docCommand}{csvfilteraccept}{} + All following consistent data lines will be accepted and processed. + This command overwrites all previous filter settings and may be used + inside \refKey{/csvsim/full filter} to implement + an own filtering rule together with |\csvfilterreject|. +\begin{dispExample} +\csvreader[ + autotabular, + full filter = \ifcsvstrcmp{\csvcoliv}{m}{\csvfilteraccept}{\csvfilterreject} + ]{grade.csv}{}{% + \csvlinetotablerow + } +\end{dispExample} +\end{docCommand} + + +\begin{docCommand}{csvfilterreject}{} + All following data lines will be ignored. + This command overwrites all previous filter settings. +\end{docCommand} + + +\begin{docCommand}{csvline}{} + This macro contains the current and unprocessed data line. +\begin{dispExample} +\csvreader[ + no head, + tabbing, + table head = {\textit{line XX:}\=\kill} + ]{grade.csv}{}{% + \textit{line \thecsvrow:} \> \csvline + } +\end{dispExample} +\end{docCommand} + + +\begin{docCommand}[doc updated=2016-07-01]{csvlinetotablerow}{} + Typesets the current processed data line with |&| between the entries. + %Most users will never apply this command. +\end{docCommand} + +\clearpage +\begin{docCommands}{ + { doc name = thecsvrow , doc updated = 2021-06-25 }, + { doc name = g_csvsim_row_int, doc new = 2021-06-25 } + } + Typesets the current data line number. This is the + current number of accepted data lines without the header line. + Despite of the name, there is no associated \LaTeX\ counter |csvrow|, + but \refCom{thecsvrow} is an accessor the \LaTeX3 integer + \refCom{g_csvsim_row_int}. +\end{docCommands} + + +\begin{docCommands}[doc new=2021-06-25]{ + { doc name = thecsvcolumncount }, + { doc name = g_csvsim_columncount_int } + } + Typesets the number of columns of the current CSV file. This number + is either computed from the first valid line (header or data) or + given by \refKey{/csvsim/column count}. + Despite of the name, there is no associated \LaTeX\ counter |csvcolumncount|, + but \refCom{thecsvcolumncount} is an accessor the \LaTeX3 integer + \refCom{g_csvsim_columncount_int}. +\begin{dispExample} +\csvreader{grade.csv}{}{}% +The last file consists of \thecsvcolumncount{} columns and +\thecsvrow{} accepted data lines. The total number of lines +ist \thecsvinputline{}. +\end{dispExample} +\end{docCommands} + + +\begin{docCommands}{ + { doc name = thecsvinputline , doc updated = 2021-06-25 }, + { doc name = g_csvsim_inputline_int, doc new = 2021-06-25 } + } + Typesets the current file line number. This is the + current number of all data lines including the header line and all + lines filtered out. + Despite of the name, there is no associated \LaTeX\ counter |csvinputline|, + but \refCom{thecsvinputline} is an accessor the \LaTeX3 integer + \refCom{g_csvsim_inputline_int}. +\begin{dispExample} +\csvreader[ + no head, + filter test = \ifnumequal{\thecsvinputline}{3} + ]{grade.csv}{}{% + The line with number \thecsvinputline\ contains: \csvline + } +\end{dispExample} +\end{docCommands} + + + + + +\clearpage +\section{Option Keys}\label{sec:schluessel}% +For the \meta{options} in \refCom{csvreader} respectively \refCom{csvloop} +the following |l3keys| keys can be applied. The \meta{module} name |/csvsim/| is not +to be used inside these macros. + + +\subsection{Command Definition}%--------%[[ + +\begin{docCsvKey}{before reading}{=\meta{code}}{no default, initially empty} + Sets the \meta{code} to be executed before the CSV file is opened. +\end{docCsvKey} + +\begin{docCsvKey}{after head}{=\meta{code}}{no default, initially empty} + Sets the \meta{code} to be executed after the header line is read. + \refCom{thecsvcolumncount} and header entries are available. +\end{docCsvKey} + +\begin{docCsvKey}{before filter}{=\meta{code}}{no default, initially empty} + Sets the \meta{code} to be executed after reading and consistency checking + of a data line. They are executed before any filter condition is checked, + see e.g. \refKey{/csvsim/filter ifthen}. + Also see \refKey{/csvsim/full filter}. + All line entries are available. +\end{docCsvKey} + +\begin{docCsvKey}{late after head}{=\meta{code}}{no default, initially empty} + Sets the \meta{code} to be executed after reading and disassembling + of the first accepted data line. + These operations are executed before further processing of this line. + \meta{code} should not refer to any data content, but may be something + like |\\|. +\end{docCsvKey} + +\begin{docCsvKey}{late after line}{=\meta{code}}{no default, initially empty} + Sets the \meta{code} to be executed after reading and disassembling + of the next accepted data line (after \refKey{/csvsim/before filter}). + These operations are executed before further processing of this line. + \meta{code} should not refer to any data content, but may be something + like |\\|. + \refKey{/csvsim/late after line} overwrites + \refKey{/csvsim/late after first line} and + \refKey{/csvsim/late after last line}. + Note that table options like \refKey{/csvsim/tabular} set this key to |\\| + automatically. +\end{docCsvKey} + + +\begin{docCsvKey}{late after first line}{=\meta{code}}{no default, initially empty} + Sets the \meta{code} to be executed after reading and disassembling + of the second accepted data line instead of \refKey{/csvsim/late after line}. + \meta{code} should not refer to any data content. + This key has to be set after \refKey{/csvsim/late after line}. +\end{docCsvKey} + + +\begin{docCsvKey}{late after last line}{=\meta{code}}{no default, initially empty} + Sets the \meta{code} to be executed after processing of the last + accepted data line instead of \refKey{/csvsim/late after line}. + \meta{code} should not refer to any data content. + This key has to be set after \refKey{/csvsim/late after line}. +\end{docCsvKey} + + +\begin{docCsvKey}{before line}{=\meta{code}}{no default, initially empty} + Sets the \meta{code} to be executed after \refKey{/csvsim/late after line} + and before \refKey{/csvsim/command}. + All line entries are available. + \refKey{/csvsim/before line} overwrites + \refKey{/csvsim/before first line}. +\end{docCsvKey} + + +\begin{docCsvKey}{before first line}{=\meta{code}}{no default, initially empty} + Sets the \meta{code} to be executed instead of \refKey{/csvsim/before line} + for the first accepted data line. + All line entries are available. + This key has to be set after \refKey{/csvsim/before line}. +\end{docCsvKey} + + +\begin{docCsvKey}{command}{=\meta{code}}{no default, initially \cs{csvline}} + Sets the \meta{code} to be executed for every accepted data line. + It is executed between \refKey{/csvsim/before line} and \refKey{/csvsim/after line}. + \refKey{/csvsim/command} describes the main processing of the line + entries. \refCom{csvreader} sets \refKey{/csvsim/command} as mandatory + parameter. +\end{docCsvKey} + +\pagebreak + +\begin{docCsvKey}{after line}{=\meta{code}}{no default, initially empty} + Sets the \meta{code} to be executed for every accepted data line + after \refKey{/csvsim/command}. + All line entries are still available. + \refKey{/csvsim/after line} overwrites \refKey{/csvsim/after first line}. +\end{docCsvKey} + + +\begin{docCsvKey}{after first line}{=\meta{code}}{no default, initially empty} + Sets the \meta{code} to be executed instead of \refKey{/csvsim/after line} + for the first accepted data line. + All line entries are still available. + This key has to be set after \refKey{/csvsim/after line}. +\end{docCsvKey} + +\begin{docCsvKey}{after reading}{=\meta{code}}{no default, initially empty} + Sets the \meta{code} to be executed after the CSV file is closed. +\end{docCsvKey} + +\bigskip + +The following example illustrates the sequence of command execution. +Note that \refKey{/csvsim/command} is set by the mandatory last +parameter of \refCom{csvreader}. + +\begin{dispExample} +\csvreader[ + before reading = \meta{before reading}\\, + after head = \meta{after head}, + before filter = \\\meta{before filter}, + late after head = \meta{late after head}, + late after line = \meta{late after line}, + late after first line = \meta{late after first line}, + late after last line = \\\meta{late after last line}, + before line = \meta{before line}, + before first line = \meta{before first line}, + after line = \meta{after line}, + after first line = \meta{after first line}, + after reading = \\\meta{after reading} + ]{grade.csv}{name=\name}{\textbf{\name}}% +\end{dispExample} + +Additional command definition keys are provided for the supported tables, +see Section~\ref{subsec:tabsupport} from page~\pageref{subsec:tabsupport}. + +\clearpage +\subsection{Header Processing and Column Name Assignment}% + +\begin{docCsvKey}{head}{\colOpt{=true\textbar false}}{default |true|, initially |true|} + If this key is set, the first line of the CSV file is treated as a header + line which can be used for column name assignments. +\end{docCsvKey} + + +\begin{docCsvKey}{no head}{}{no value} + Abbreviation for |head=false|, i.\,e. the first line of the CSV file is + treated as data line. + Note that this option cannot be used in combination with + the |\csvauto...| commands like \refCom{csvautotabular}, etc. + Instead, there are \emph{star} variants like \refCom{csvautotabular*} to + process files without header line. + See Section~\ref{noheader} on page~\pageref{noheader} for examples. +\end{docCsvKey} + +\begin{docCsvKey}{column names}{=\marg{assignments}}{no default, initially empty} + Adds some new \meta{assignments} of macros to columns in key value syntax. + Existing assignments are kept.\par + The \meta{assignments} are given as comma separated list of key value pairs + \mbox{\meta{name}|=|\meta{macro}}. Here, \meta{name} is an entry from the + header line \emph{or} the arabic number of the addressed column. + \meta{macro} is some \TeX\ macro which gets the content of the addressed column. +\begin{dispListing} + column names = {name=\surname, givenname=\firstname, grade=\grade} +\end{dispListing} +\end{docCsvKey} + + +\begin{docCsvKey}{column names reset}{}{no value} + Clears all assignments of macros to columns. +\end{docCsvKey} + + +\begin{docCsvKey}{head to column names}{\colOpt{=true\textbar false}}{default |true|, initially |false|} + If this key is set, the entries of the header line are used automatically + as macro names for the columns. This option can be used only, if + the header entries do not contain spaces and special characters to be + used as feasible \LaTeX\ macro names. + Note that the macro definition is \emph{global} and may therefore override + existing macros for the rest of the document. Adding + \refKey{/csvsim/head to column names prefix} may help to avoid unwanted + overrides. +\end{docCsvKey} + + +\begin{docCsvKey}[][doc new=2019-07-16]{head to column names prefix}{=\meta{text}}{no default, initially empty} + The given \meta{text} is prefixed to the name of all macros generated by + \refKey{/csvsim/head to column names}. For example, if you use the settings +\begin{dispListing} + head to column names, + head to column names prefix=MY, +\end{dispListing} + a header entry |section| will generate the corresponding macro + |\MYsection| instead of destroying the standard \LaTeX\ |\section| macro. +\end{docCsvKey} + + +\clearpage +\subsection{Consistency Check}\label{sec:consistency}% + +\begin{docCsvKey}{check column count}{\colOpt{=true\textbar false}}{default |true|, initially |true|} + This key defines, wether the number of entries in a data line is checked against + an expected value or not.\\ + If |true|, every non consistent line is ignored without announcement.\\ + If |false|, every line is accepted and may produce an error during + further processing. +\end{docCsvKey} + + +\begin{docCsvKey}{no check column count}{}{no value} + Abbreviation for |check column count=false|. +\end{docCsvKey} + + +\begin{docCsvKey}[][doc updated=2021-06-24]{column count}{=\meta{number}}{no default, initially |0|} + Sets the \meta{number} of feasible entries per data line. + If \refKey{/csvsim/column count} is set to |0|, the number of entries of + the first non-empty line determines the column count (automatic detection). + + This setting is only useful in connection with \refKey{/csvsim/no head}, + since \meta{number} would be replaced by the number of entries in the + header line otherwise. +\end{docCsvKey} + + +\begin{docCsvKey}{on column count error}{=\meta{code}}{no default, initially empty} + \meta{code} to be executed for unfeasible data lines. +\end{docCsvKey} + + +\begin{docCsvKey}{warn on column count error}{}{style, no value} + Display of a warning for unfeasible data lines. +\end{docCsvKey} + + +\clearpage +\subsection{Filtering}\label{subsec:filtering}% + +Applying a \emph{filter} means that data lines are only processed / displayed, +if they fulfill a given \emph{condition}. + +The following string compare filters \refKey{/csvsim/filter strcmp} and +\refKey{/csvsim/filter equal} are identical by logic, but differ in implementation. + +\begin{docCsvKey}{filter strcmp}{=\marg{stringA}\marg{stringB}}{style, no default} + Only lines where \meta{stringA} and \meta{stringB} are equal after expansion + are accepted. + The implementation is done with \refCom{ifcsvstrcmp}. +\begin{dispExample} +% \usepackage{booktabs} +\csvreader[ + head to column names, + tabular = llll, + table head = \toprule & \bfseries Name & \bfseries Matr & \bfseries Grade\\\midrule, + table foot = \bottomrule, + filter strcmp = {\gender}{f}, %>> list only female persons << + ]{grade.csv}{}{% + \thecsvrow & \slshape\name, \givenname & \matriculation & \grade + } +\end{dispExample} +\end{docCsvKey} + + +\begin{docCsvKey}{filter not strcmp}{=\marg{stringA}\marg{stringB}}{style, no default} + Only lines where \meta{stringA} and \meta{stringB} are not equal after expansion + are accepted. + The implementation is done with \refCom{ifcsvnotstrcmp}. +\end{docCsvKey} + + +\begin{docCsvKey}{filter equal}{=\marg{stringA}\marg{stringB}}{style, no default} + Only lines where \meta{stringA} and \meta{stringB} are equal after expansion + are accepted. + The implementation is done with the |ifthen| package (loading required!). +\end{docCsvKey} + + +\begin{docCsvKey}{filter not equal}{=\marg{stringA}\marg{stringB}}{style, no default} + Only lines where \meta{stringA} and \meta{stringB} are not equal after expansion + are accepted. + The implementation is done with the |ifthen| package (loading required!). +\end{docCsvKey} + + +\begin{docCsvKey}[][doc new=2021-06-25]{filter fp}{=\meta{floating point expression}}{no default} + Only data lines which fulfill a \LaTeX3 \meta{floating point expression} + (|l3fp|, |xfp|) are accepted. +\begin{dispExample} +% \usepackage{booktabs} +\csvreader[ + head to column names, + tabular = llll, + table head = \toprule & \bfseries Name & \bfseries Matr & \bfseries Grade\\\midrule, + table foot = \bottomrule, + %>> list only matriculation numbers greater than 20000 + % and grade less than 4.0 << + filter fp = { \matriculation > 20000 && \grade < 4.0 }, + ]{grade.csv}{}{% + \thecsvrow & \slshape\name, \givenname & \matriculation & \grade + } +\end{dispExample} +\end{docCsvKey} + + +\clearpage + +\begin{docCsvKey}[][doc new=2021-06-25]{filter bool}{=\meta{boolean expression}}{no default} + Only data lines which fulfill a \LaTeX3 \meta{boolean expression} are accepted. + Note that such an \meta{boolean expression} needs expl3 code. + To preprocess the data line before testing the \meta{condition}, + the option key \refKey{/csvsim/before filter} can be used. +\begin{dispExample} +% For convenience, we save the filter +\ExplSyntaxOn +%>> list only matriculation numbers greater than 20000, list only men << +\csvstyle{myfilter} + { + filter~bool = + { + \int_compare_p:n { \matriculation > 20000 } && + \str_compare_p:eNe { \gender } = { m } + } + } +\ExplSyntaxOff + +\csvreader[ + head to column names, + tabular = llll, + table head = \toprule & \bfseries Name & \bfseries Matr & \bfseries Grade\\\midrule, + table foot = \bottomrule, + myfilter + ]{grade.csv}{}{% + \thecsvrow & \slshape\name, \givenname & \matriculation & \grade + } +\end{dispExample} +\end{docCsvKey} + +\medskip +\begin{docCommand}[doc new=2021-06-25]{csvfilterbool}{\marg{key}\marg{boolean expression}} + Defines a new |l3keys| meta key which applies \refKey{/csvsim/filter bool} + with the given \meta{boolean expression}. +\begin{dispExample} +% For convenience, we save the filter +\ExplSyntaxOn +%>> list only matriculation numbers greater than 20000, list only men << +\csvfilterbool{myfilter} + { + \int_compare_p:n { \matriculation > 20000 } && + \str_compare_p:eNe { \gender } = { m } + } +\ExplSyntaxOff + +\csvreader[ + head to column names, + tabular = llll, + table head = \toprule & \bfseries Name & \bfseries Matr & \bfseries Grade\\\midrule, + table foot = \bottomrule, + myfilter + ]{grade.csv}{}{% + \thecsvrow & \slshape\name, \givenname & \matriculation & \grade + } +\end{dispExample} +\end{docCommand} + + + +\clearpage + +\begin{docCsvKey}[][doc new=2016-07-01]{filter test}{=\meta{condition}}{no default} + Only data lines which fulfill a logical \meta{condition} are accepted. + For the \meta{condition}, every single test normally employed like +\begin{dispListing} +\iftest{some testing}{true}{false} +\end{dispListing} + can be used as +\begin{dispListing} +filter test=\iftest{some testing}, +\end{dispListing} + For |\iftest|, tests from the |etoolbox| package like + |\ifnumcomp|, |\ifdimgreater|, etc. and from \Fullref{sec:stringtests} can be used. + Also, arbitrary own macros fulfilling this signature can be applied. +\begin{dispExample} +% \usepackage{etoolbox,booktabs} +\csvreader[ + head to column names, + tabular = llll, + table head = \toprule & \bfseries Name & \bfseries Matr & \bfseries Grade\\\midrule, + table foot = \bottomrule, + %>> list only matriculation numbers greater than 20000 << + filter test = \ifnumgreater{\matriculation}{20000}, + ]{grade.csv}{}{% + \thecsvrow & \slshape\name, \givenname & \matriculation & \grade + } +\end{dispExample} +\end{docCsvKey} + + +\medskip +\begin{docCsvKey}[][doc new=2016-07-01]{filter expr}{=\meta{boolean expression}}{no default} + Only data lines which fulfill a \meta{boolean expression} are accepted. + Every \meta{boolean expression} + from the |etoolbox| package is feasible (package loading required!). + To preprocess the data line before testing the \meta{condition}, + the option key \refKey{/csvsim/before filter} can be used. +\begin{dispExample} +% \usepackage{etoolbox,booktabs} +\csvreader[ + head to column names, + tabular = llll, + table head = \toprule & \bfseries Name & \bfseries Matr & \bfseries Grade\\\midrule, + table foot = \bottomrule, + %>> list only matriculation numbers greater than 20000 + % and grade less than 4.0 << + filter expr = { test{\ifnumgreater{\matriculation}{20000}} + and test{\ifdimless{\grade pt}{4.0pt}} }, + ]{grade.csv}{}{% + \thecsvrow & \slshape\name, \givenname & \matriculation & \grade + } +\end{dispExample} +\end{docCsvKey} + + +\clearpage +\begin{docCsvKey}[][doc new=2016-07-01]{filter ifthen}{=\meta{boolean expression}}{no default} + Only data lines which fulfill a \meta{boolean expression} are accepted. + For the \meta{boolean expression}, every term from the |ifthen| package + is feasible (package loading required!). + To preprocess the data line before testing the \meta{condition}, + the option key \refKey{/csvsim/before filter} can be used. + +\begin{dispExample} +% \usepackage{ifthen,booktabs} +\csvreader[ + head to column names, + tabular = llll, + table head = \toprule & \bfseries Name & \bfseries Matr & \bfseries Grade\\\midrule, + table foot = \bottomrule, + %>> list only female persons << + filter ifthen=\equal{\gender}{f}, + ]{grade.csv}{}{% + \thecsvrow & \slshape\name, \givenname & \matriculation & \grade + } +\end{dispExample} +\end{docCsvKey} + + +\begin{docCsvKey}{no filter}{}{no value, initially set} + Clears a set filter. +\end{docCsvKey} + + +\begin{docCsvKey}{filter accept all}{}{no value, initially set} + Alias for |no filter|. All consistent data lines are accepted. +\end{docCsvKey} + + +\begin{docCsvKey}{filter reject all}{}{no value} + All data line are ignored. +\end{docCsvKey} + + +\begin{docCsvKey}[][doc new=2016-07-01]{full filter}{=\meta{code}}{no default} + Technically, this key is an alias for \refKey{/csvsim/before filter}. + Philosophically, \refKey{/csvsim/before filter} computes something before + a filter condition is set, but \refKey{/csvsim/full filter} should implement + the full filtering. Especially, \refCom{csvfilteraccept} or + \refCom{csvfilterreject} \emph{should} be set inside the \meta{code}. +\begin{dispExample} +% \usepackage{etoolbox,booktabs} +\csvreader[ + head to column names, + tabular = llll, + table head = \toprule & \bfseries Name & \bfseries Matr & \bfseries Grade\\\midrule, + table foot = \bottomrule, + %>> list only matriculation numbers greater than 20000 + % and grade less than 4.0 << + full filter = \ifnumgreater{\matriculation}{20000} + {\ifdimless{\grade pt}{4.0pt}{\csvfilteraccept}{\csvfilterreject}} + {\csvfilterreject}, + ]{grade.csv}{}{% + \thecsvrow & \slshape\name, \givenname & \matriculation & \grade + } +\end{dispExample} +\end{docCsvKey} + + + +%]] + +\clearpage +\subsection{Line Range}\label{subsec:linerange} + +Applying a \emph{line range} means to select certain line numbers to be +displayed. These line numbers are not necessarily line numbers of +the input file, see \refCom{thecsvinputline}, but line numbers of +type \refCom{thecsvrow}. + +For example, if a \emph{filter} was applied, see \Fullref{subsec:filtering}, +and 42 lines are accepted, a \emph{range} could select the first 20 of them or +line 10 to 30 of the accepted lines. + + +\begin{docCsvKey}[][doc new=2021-06-29]{range}{=\brackets{\meta{range1},\meta{range2},\meta{range3},... }}{no default, initially empty} + Defines a comma separated list of line ranges. If a line number \refCom{thecsvrow} + satisfies one or more of the given \meta{range1}, \meta{range2}, \ldots, + the corresponding line is processed and displayed. + If \refKey{/csvsim/range} is set to empty, all lines are accepted. + + Every \meta{range} can + corresponds to one of the following variants: + \begin{tabbing} + \hspace*{2cm}\=\kill + \texttt{\meta{a}-\meta{b}} \> meaning line numbers \meta{a} to \meta{b}.\\ + \texttt{\meta{a}-} \> meaning line numbers \meta{a} to |\c_max_int|=2 147 483 647.\\ + \texttt{-\meta{b}} \> meaning line numbers 1 to \meta{b}.\\ + \texttt{-} \> meaning line numbers 1 to 2 147 483 647 (inefficient; don't use).\\ + \texttt{\meta{a}} \> meaning line numbers \meta{a} to \meta{a} (i.e. only \meta{a}).\\ + \texttt{\meta{a}+\meta{d}} \> meaning line numbers \meta{a} to \meta{a}$+$\meta{d}$-1$.\\ + \texttt{\meta{a}+} \> meaning line numbers \meta{a} to \meta{a} (i.e. only \meta{a}).\\ + \texttt{+\meta{d}} \> meaning line numbers 1 to \meta{d}.\\ + \texttt{+} \> meaning line numbers 1 to 1 (i.e. only 1; weird).\\ + \end{tabbing} + +\begin{dispExample} +% \usepackage{booktabs} +\csvreader[ + head to column names, + range = 2-3, + tabular = llll, + table head = \toprule & \bfseries Name & \bfseries Matr & \bfseries Grade\\\midrule, + table foot = \bottomrule, + ]{grade.csv}{}{% + \thecsvrow & \slshape\name, \givenname & \matriculation & \grade + } +\end{dispExample} + + +\begin{dispExample} +% \usepackage{booktabs} +\csvreader[ + head to column names, + range = 3-, + tabular = llll, + table head = \toprule & \bfseries Name & \bfseries Matr & \bfseries Grade\\\midrule, + table foot = \bottomrule, + ]{grade.csv}{}{% + \thecsvrow & \slshape\name, \givenname & \matriculation & \grade + } +\end{dispExample} + + +\begin{dispExample} +% \usepackage{booktabs} +\csvreader[ + head to column names, + range = 2+2, + tabular = llll, + table head = \toprule & \bfseries Name & \bfseries Matr & \bfseries Grade\\\midrule, + table foot = \bottomrule, + ]{grade.csv}{}{% + \thecsvrow & \slshape\name, \givenname & \matriculation & \grade + } +\end{dispExample} + +\begin{dispExample} +% \usepackage{booktabs} +\csvreader[ + head to column names, + range = {2,4}, + tabular = llll, + table head = \toprule & \bfseries Name & \bfseries Matr & \bfseries Grade\\\midrule, + table foot = \bottomrule, + ]{grade.csv}{}{% + \thecsvrow & \slshape\name, \givenname & \matriculation & \grade + } +\end{dispExample} + +To select the last $n$ lines, you have to know or count the line numbers first. +The following example displays the last three line numbers: + +\begin{dispExample} +% \usepackage{booktabs} +\csvreader{grade.csv}{}{}% count line numbers +\csvreader[ + head to column names, + range = {\thecsvrow-2}-, + tabular = llll, + table head = \toprule & \bfseries Name & \bfseries Matr & \bfseries Grade\\\midrule, + table foot = \bottomrule, + ]{grade.csv}{}{% + \thecsvrow & \slshape\name, \givenname & \matriculation & \grade + } +\end{dispExample} + +\end{docCsvKey} + + + +\clearpage +\subsection{Table Support}\label{subsec:tabsupport}%--------%[[ + +\begin{docCsvKey}{tabular}{=\meta{table format}}{style, no default} + Surrounds the CSV processing with |\begin{tabular}|\marg{table format} + at begin and with |\end{tabular}| at end. +Additionally, the commands defined by the key values of + \refKey{/csvsim/before table}, \refKey{/csvsim/table head}, \refKey{/csvsim/table foot}, + and \refKey{/csvsim/after table} are executed at the appropriate places. +\end{docCsvKey} + + +\begin{docCsvKey}{centered tabular}{=\meta{table format}}{style, no default} + Like \refKey{/csvsim/tabular} but inside an additional |center| environment. +\end{docCsvKey} + + +\begin{docCsvKey}{longtable}{=\meta{table format}}{style, no default} + Like \refKey{/csvsim/tabular} but for the |longtable| environment. + This requires the package |longtable| (not loaded automatically). +\end{docCsvKey} + + +\begin{docCsvKey}{tabbing}{}{style, no value} + Like \refKey{/csvsim/tabular} but for the |tabbing| environment. +\end{docCsvKey} + + +\begin{docCsvKey}{centered tabbing}{}{style, no value} + Like \refKey{/csvsim/tabbing} but inside an additional |center| environment. +\end{docCsvKey} + + +\begin{docCsvKey}{no table}{}{style, no value} + Deactivates |tabular|, |longtable|, and |tabbing|. +\end{docCsvKey} + + +\begin{docCsvKey}{before table}{=\meta{code}}{no default, initially empty} + Sets the \meta{code} to be executed before |\begin{tabular}| or before |\begin{longtable}| + or before |\begin{tabbing}|, respectively. +\end{docCsvKey} + + +\begin{docCsvKey}{table head}{=\meta{code}}{no default, initially empty} + Sets the \meta{code} to be executed after |\begin{tabular}| or after |\begin{longtable}| + or after |\begin{tabbing}|, respectively. +\end{docCsvKey} + + +\begin{docCsvKey}{table foot}{=\meta{code}}{no default, initially empty} + Sets the \meta{code} to be executed before |\end{tabular}| or before |\end{longtable}| + or before |\end{tabbing}|, respectively. +\end{docCsvKey} + + +\begin{docCsvKey}{after table}{=\meta{code}}{no default, initially empty} + Sets the \meta{code} to be executed after |\end{tabular}| or after |\end{longtable}| + or after |\end{tabbing}|, respectively. +\end{docCsvKey} + +\clearpage + +The following |auto| options are the counterparts for the respective quick +overview commands like \refCom{csvautotabular}. They are listed for +completeness, but are unlikely to be used directly. + +\begin{docCsvKeys}[ + doc parameter = {=\meta{file name}}, + doc description = no default, + ] + { + { doc name = autotabular }, + { doc name = autotabular* }, + } + Reads the whole CSV file denoted \meta{file name} with an automated formatting. + The star variant treats the first line as data line and not as header line. +\end{docCsvKeys} + + +\begin{docCsvKeys}[ + doc parameter = {=\meta{file name}}, + doc description = no default, + ] + { + { doc name = autolongtable }, + { doc name = autolongtable* }, + } + Reads the whole CSV file denoted \meta{file name} with an automated formatting + using the required |longtable| package. + The star variant treats the first line as data line and not as header line. +\end{docCsvKeys} + + +\begin{docCsvKeys}[ + doc parameter = {=\meta{file name}}, + doc description = no default, + ] + { + { doc name = autobooktabular }, + { doc name = autobooktabular* }, + } + Reads the whole CSV file denoted \meta{file name} with an automated formatting + using the required |booktabs| package. + The star variant treats the first line as data line and not as header line. +\end{docCsvKeys} + + +\begin{docCsvKeys}[ + doc parameter = {=\meta{file name}}, + doc description = no default, + ] + { + { doc name = autobooklongtable }, + { doc name = autobooklongtable* }, + } + Reads the whole CSV file denoted \meta{file name} with an automated formatting + using the required |booktabs| and |longtable| packages. + The star variant treats the first line as data line and not as header line. +\end{docCsvKeys} + + +\clearpage +\subsection{Special Characters}\label{subsec:specchar} +Be default, the CSV content is treated like normal \LaTeX\ text, see +Subsection~\ref{macrocodexample} on page~\pageref{macrocodexample}. +But, \TeX\ special characters of the CSV content may also be interpreted +as normal characters (|\catcode| 12, other), if one or more of the following options are used. + +\begin{docCsvKey}{respect tab}{\colOpt{=true\textbar false}}{default |true|, initially |false|} + If this key is set, every + tabulator sign + inside the CSV content is a normal character. +\end{docCsvKey} + +\begin{docCsvKey}{respect percent}{\colOpt{=true\textbar false}}{default |true|, initially |false|} + If this key is set, every + percent sign \verbbox{\%} + inside the CSV content is a normal character. +\end{docCsvKey} + +\begin{docCsvKey}{respect sharp}{\colOpt{=true\textbar false}}{default |true|, initially |false|} + If this key is set, every + sharp sign \verbbox{\#} + inside the CSV content is a normal character. +\end{docCsvKey} + +\begin{docCsvKey}{respect dollar}{\colOpt{=true\textbar false}}{default |true|, initially |false|} + If this key is set, every + dollar sign \verbbox{\$} + inside the CSV content is a normal character. +\end{docCsvKey} + +\begin{docCsvKey}{respect and}{\colOpt{=true\textbar false}}{default |true|, initially |false|} + If this key is set, every + and sign \verbbox{\&} + inside the CSV content is a normal character. +\end{docCsvKey} + +\begin{docCsvKey}{respect backslash}{\colOpt{=true\textbar false}}{default |true|, initially |false|} + If this key is set, every + backslash sign \verbbox{\textbackslash} + inside the CSV content is a normal character. +\end{docCsvKey} + +\begin{docCsvKey}{respect underscore}{\colOpt{=true\textbar false}}{default |true|, initially |false|} + If this key is set, every + underscore sign \verbbox{\_} + inside the CSV content is a normal character. +\end{docCsvKey} + +\begin{docCsvKey}{respect tilde}{\colOpt{=true\textbar false}}{default |true|, initially |false|} + If this key is set, every + tilde sign \verbbox{\textasciitilde} + inside the CSV content is a normal character. +\end{docCsvKey} + +\begin{docCsvKey}{respect circumflex}{\colOpt{=true\textbar false}}{default |true|, initially |false|} + If this key is set, every + circumflex sign \verbbox{\textasciicircum} + inside the CSV content is a normal character. +\end{docCsvKey} + +\begin{docCsvKey}{respect leftbrace}{\colOpt{=true\textbar false}}{default |true|, initially |false|} + If this key is set, every + left brace sign \verbbox{\textbraceleft} + inside the CSV content is a normal character. +\end{docCsvKey} + +\begin{docCsvKey}{respect rightbrace}{\colOpt{=true\textbar false}}{default |true|, initially |false|} + If this key is set, every + right brace sign \verbbox{\textbraceright} + inside the CSV content is a normal character. +\end{docCsvKey} + +\begin{docCsvKey}{respect all}{}{style, no value, initially unset} + Set all special characters from above to normal characters. This means + a quite verbatim interpretation of the CSV content. +\end{docCsvKey} + +\begin{docCsvKey}{respect none}{}{style, no value, initially set} + Do not change any special character from above to normal character. +\end{docCsvKey} + +\clearpage +\subsection{Separators}\label{sec:separators}% +\begin{docCsvKey}{separator}{=\meta{sign}}{no default, initially |comma|} + \catcode `|=12 + Sets the \meta{sign} which is treates as separator between the data values + of a data line. Feasible values are: + \begin{itemize} + \item\docValue{comma}: This is the initial value with '\texttt{,}' as separator. + \medskip + + \item\docValue{semicolon}: Sets the separator to '\texttt{;}'. +\begin{dispExample} +% \usepackage{tcolorbox} for tcbverbatimwrite +\begin{tcbverbatimwrite}{testsemi.csv} + name;givenname;matriculation;gender;grade + Maier;Hans;12345;m;1.0 + Huber;Anna;23456;f;2.3 + Weißbäck;Werner;34567;m;5.0 +\end{tcbverbatimwrite} + +\csvautobooktabular[separator=semicolon]{testsemi.csv} +\end{dispExample} +\medskip + +\item\docValue{pipe}: Sets the separator to '\texttt{|}'. +\begin{dispExample} +% \usepackage{tcolorbox} for tcbverbatimwrite +\begin{tcbverbatimwrite}{pipe.csv} + name|givenname|matriculation|gender|grade + Maier|Hans|12345|m|1.0 + Huber|Anna|23456|f|2.3 + Weißbäck|Werner|34567|m|5.0 +\end{tcbverbatimwrite} + +\csvautobooktabular[separator=pipe]{pipe.csv} +\end{dispExample} +\medskip + +\item\docValue{tab}: Sets the separator to the tabulator sign. + Automatically, \refKey{/csvsim/respect tab} is set also. + \end{itemize} +\end{docCsvKey} + +\clearpage +\subsection{Miscellaneous}% + +\begin{docCsvKey}{every csv}{}{style, initially empty} + A meta key (style) definition which is used for every following CSV file. + This definition can be overwritten with user code. +\begin{dispListing} +% Sets a warning message for unfeasible data lines. +\csvstyle{every csv}{warn on column count error} +\end{dispListing} +\end{docCsvKey} + +\begin{docCsvKey}{default}{}{style} + A style definition which is used for every following CSV file which + resets all settings to default values\footnote{\texttt{default} is used + because of the global nature of most settings.}. + This key should not be used or changed by the user if there is not a + really good reason (and you know what you do). +\end{docCsvKey} + + +\begin{docCsvKey}{file}{=\meta{file name}}{no default, initially |unknown.csv|} + Sets the \meta{file name} of the CSV file to be processed. + \refCom{csvreader} sets this option by a mandatory parameter. +\end{docCsvKey} + + +\begin{docCsvKey}{preprocessed file}{=\meta{file name}}{no default, initially \texttt{\textbackslash\detokenize{jobname_sorted.csv}}} + Sets the \meta{file name} of the CSV file which is the output of a + preprocessor. +\end{docCsvKey} + + +\begin{docCsvKey}{preprocessor}{=\meta{macro}}{no default} + Defines a preprocessor for the given CSV file. + The \meta{macro} has to have two mandatory arguments. The first argument + is the original CSV file which is set by \refKey{/csvsim/file}. + The second argument is the preprocessed CSV file + which is set by \refKey{/csvsim/preprocessed file}.\par\smallskip + Typically, the \meta{macro} may call an external program which preprocesses + the original CSV file (e.\,g. sorting the file) and creates the + preprocessed CSV file. The later file is used by \refCom{csvreader} + or \refCom{csvloop}. +\begin{dispListing} +\newcommand{\mySortTool}[2]{% + % call to an external program to sort file #1 with resulting file #2 +} + +\csvreader[% + preprocessed file = \jobname_sorted.csv, + preprocessor = \mySortTool, + ]{some.csv}{}{% + % do something +} +\end{dispListing} +See Subsection~\ref{sec:Sorting} on page~\pageref{sec:Sorting} for a +concrete sorting preprocessing implemented with an external tool. +\end{docCsvKey} + + +\begin{docCsvKey}{no preprocessing}{}{style, no value, initially set} + Clears any preprocessing, i.\,e. preprocessing is switched of. +\end{docCsvKey} + + + +\clearpage +\subsection{Sorting}\label{sec:Sorting}% +\TeX/\LaTeX\ was not born under a sorting planet. |csvsimple-l3| provides no +sorting of data lines by \LaTeX-methods since sorting can be done much faster +and much better by external tools. + +First, one should consider the appropriate \emph{place} for sorting: +\begin{itemize} +\item CSV files may be sorted by a tool \emph{before} the \LaTeX\ document is processed + at all. If the CSV data is not likely to change, this is the most efficient method. +\item CSV files may be sorted by a tool every time before the \LaTeX\ document is compiled. + This could be automated by a shell script or some processing tool like |arara|. +\item CSV files may be sorted on-the-fly by a tool during compilation of + a \LaTeX\ document. This is the most elegant but not the most efficient way. +\end{itemize} + +The first two methods are decoupled from anything concerning |csvsimple-l3|. +For the third method, the \refKey{/csvsim/preprocessor} option is made for. +This allows to access an external tool for sorting. +\emph{Which tool} is your choice. + +\csvsorter\ was written as a companion tool for |csvsimple|. +It is an open source Java command-line tool for sorting CSV files, available at\\ +\url{https://T-F-S.github.io/csvsorter/}\quad or\quad +\url{https://github.com/T-F-S/csvsorter} + +It can be +used for all three sorting approaches described above. +There is special support for on-the-fly sorting with \csvsorter\ using the +following options. + +\begin{enumerate}\bfseries +\item To use the sorting options, you have to install \csvsorter\ before! +\item You have to give permission to call external tools during + compilation, i.\,e.\ the command-line options for |latex| have to include + |-shell-escape|. +\end{enumerate} + +\bigskip + +\begin{docCsvKey}{csvsorter command}{=\meta{system command}}{no default, initially |csvsorter|} + The \meta{system command} specifies the system call for \csvsorter\ (without the options). + If \csvsorter\ was completely installed following its documentation, there is + nothing to change here. If the |csvsorter.jar| file is inside the same + directory as the \LaTeX\ source file, you may configure:% preferrably inside the preamble: +\begin{dispListing} +\csvset{csvsorter command=java -jar csvsorter.jar} +\end{dispListing} +\end{docCsvKey} + +\begin{docCsvKey}{csvsorter configpath}{=\meta{path}}{no default, initially |.|} + Sorting with \csvsorter\ is done using XML configuration files. If these files + are not stored inside the same directory as the \LaTeX\ source file, a + \meta{path} to access them can be configured: +\begin{dispListing} +\csvset{csvsorter configpath=xmlfiles} +\end{dispListing} + Here, the configuration files would be stored in a subdirectory named |xmlfiles|. +\end{docCsvKey} + +\begin{docCsvKey}{csvsorter log}{=\meta{file name}}{no default, initially |csvsorter.log|} + Sets the log file of \csvsorter\ to the given \meta{file name}. +\begin{dispListing} +\csvset{csvsorter log=outdir/csvsorter.log} +\end{dispListing} + Here, the log file is written to a subdirectory named |outdir|. +\end{docCsvKey} + +\clearpage +\begin{docCsvKey}{csvsorter token}{=\meta{file name}}{no default, initially |\textbackslash jobname.csvtoken|} + Sets \meta{file name} as token file. This is an auxiliary file which + communicates the success of \csvsorter\ to |csvsimple|. +\begin{dispListing} +\csvset{csvsorter log=outdir/\jobname.csvtoken} +\end{dispListing} + Here, the token file is written to a subdirectory named |outdir|. +\end{docCsvKey} + + +\begin{docCsvKey}{sort by}{=\meta{file name}}{style, initially unset} + The \meta{file name} denotes an XML configuration file for \csvsorter. + Setting this option inside \refCom{csvreader} or + \refCom{csvloop} will issue a system call to \csvsorter. + \begin{itemize} + \item \csvsorter\ uses the given CSV file as input file. + \item \csvsorter\ uses \meta{file name} as configuration file. + \item The output CSV file is denoted by \refKey{/csvsim/preprocessed file} + which is by default \texttt{\textbackslash\detokenize{jobname_sorted.csv}}. + This output file is this actual file processed by \refCom{csvreader} or \refCom{csvloop}. + \item \csvsorter\ also generates a log file denoted by \refKey{/csvsim/csvsorter log} which is by default |csvsorter.log|. + \end{itemize} + +\par\medskip\textbf{First example:} + To sort our example |grade.csv| file according to |name| and |givenname|, we + use the following XML configuration file. Since \csvsorter\ uses double quotes + as default brackets for column values, we remove bracket recognition to avoid + a clash with the escaped umlauts of the example CSV file.\par\smallskip + +\xmllisting{namesort} +\begin{dispExample} +% \usepackage{booktabs} +\csvreader[ + head to column names, + sort by = namesort.xml, + tabular = >{\color{red}}lllll, + table head = \toprule Name & Given Name & Matriculation & Gender & Grade\\\midrule, + table foot = \bottomrule + ]{grade.csv}{}{% + \csvlinetotablerow + } +\end{dispExample} + +\clearpage\textbf{Second example:} + To sort our example |grade.csv| file according to |grade|, we + use the following XML configuration file. Further, persons with the same |grade| + are sorted by |name| and |givenname|. Since \csvsorter\ uses double quotes + as default brackets for column values, we remove bracket recognition to avoid + a clash with the escaped umlauts of the example CSV file.\par\smallskip + +\xmllisting{gradesort} +\begin{dispExample} +% \usepackage{booktabs} +\csvreader[ + head to column names, + sort by = gradesort.xml, + tabular = llll>{\color{red}}l, + table head = \toprule Name & Given Name & Matriculation & Gender & Grade\\\midrule, + table foot = \bottomrule + ]{grade.csv}{}{% + \csvlinetotablerow + } +\end{dispExample} + +\clearpage\textbf{Third example:} + To generate a matriculation/grade list, we sort our example |grade.csv| file + using the following XML configuration file. + Again, since \csvsorter\ uses double quotes + as default brackets for column values, we remove bracket recognition to avoid + a clash with the escaped umlauts of the example CSV file.\par\smallskip + +\xmllisting{matriculationsort} +\begin{dispExample} +% \usepackage{booktabs} +\csvreader[ + head to column names, + sort by = matriculationsort.xml, + tabular = >{\color{red}}ll, + table head = \toprule Matriculation & Grade\\\midrule, + table foot = \bottomrule + ]{grade.csv}{}{% + \matriculation & \grade + } +\end{dispExample} +\end{docCsvKey} + + +\clearpage +\begin{docCsvKey}{new sorting rule}{=\marg{name}\marg{file name}}{style, initially unset} +This is a convenience option to generate a new shortcut for often used +\refKey{/csvsim/sort by} applications. It also adds a more semantic touch. +The new shortcut option is +\tcbox[on line,size=small,colback=white,colframe=red]{|sort by| \meta{name}} which expands to +\tcbox[on line,size=small,colback=white,colframe=red]{|sort by=|\marg{file name}}.\par\medskip + +Consider the following example: +\begin{dispExample} +\csvautotabular[sort by=namesort.xml]{grade.csv} +\end{dispExample} +A good place for setting up a new sorting rule would be inside the preamble: + +\csvset{new sorting rule={name}{namesort.xml}} +\begin{dispListing} +\csvset{new sorting rule={name}{namesort.xml}} +\end{dispListing} + +Now, we can use the new rule: +\begin{dispExample} +\csvautotabular[sort by name]{grade.csv} +\end{dispExample} +\end{docCsvKey} + + +\begin{docCommand}[doc new=2021-06-28]{csvsortingrule}{\marg{name}\marg{file name}} + Identical in function to \refKey{/csvsim/new sorting rule}, see above. +A good place for setting up a new sorting rule would be inside the preamble: + +\csvsortingrule{name}{namesort.xml} +\begin{dispListing} +\csvsortingrule{name}{namesort.xml} +\end{dispListing} + +Now, we can use the new rule: +\begin{dispExample} +\csvautotabular[sort by name]{grade.csv} +\end{dispExample} +\end{docCommand} + + + +\clearpage +\section{String and Number Tests}\label{sec:stringtests}% + +The following string tests are complementing the string tests +from packages like |etoolbox|. They all do the same, i.e., +comparing expanded strings for equality. To some extent, they are +provided for backward compatibility. +\begin{itemize} +\item\refCom{ifcsvstrcmp} may be the most efficient method, because it uses + the native compiler string comparison (if available). +\item\refCom{ifcsvstrequal} does not rely on a compiler. It also is the + fallback implementation for \refCom{ifcsvstrcmp}, if there is no + native comparison method. +\item\refCom{ifcsvprostrequal} is possibly more failsafe than the other two + string tests. It may be used, if strings contain dirty things like |\textbf{A}|. +\end{itemize} +\medskip + +\begin{docCommand}[doc new and updated={2016-07-01}{2021-06-28}]{ifcsvstrcmp}{\marg{stringA}\marg{stringB}\marg{true}\marg{false}} + Compares two strings and executes \meta{true} if they are equal, and \meta{false} otherwise. + The comparison is done using |\str_compare:eNeTF|. + \refCom{ifcsvstrcmp} is expandable. +\end{docCommand} + + +\begin{docCommand}[doc new and updated={2016-07-01}{2021-06-28}]{ifcsvnotstrcmp}{\marg{stringA}\marg{stringB}\marg{true}\marg{false}} + Compares two strings and executes \meta{true} if they are \emph{not} equal, and \meta{false} otherwise. + The implementation uses \refCom{ifcsvstrcmp}. + \refCom{ifcsvstrcmp} is expandable. +\end{docCommand} + + +\begin{docCommand}[doc new and updated={2016-07-01}{2021-06-28}]{ifcsvstrequal}{\marg{stringA}\marg{stringB}\marg{true}\marg{false}} + Compares two strings and executes \meta{true} if they are equal, and \meta{false} otherwise. + The strings are expanded + and the comparison is done using |\tl_if_eq:NNTF|. + \refCom{ifcsvstrequal} is not expandable. +\end{docCommand} + + +\begin{docCommand}[doc new and updated={2016-07-01}{2021-06-28}]{ifcsvprostrequal}{\marg{stringA}\marg{stringB}\marg{true}\marg{false}} + Compares two strings and executes \meta{true} if they are equal, and \meta{false} otherwise. + The strings are expanded with |\protected@edef| + in the test, i.e. parts of the + strings which are protected stay unexpanded. + The comparison is done using |\tl_if_eq:NNTF|. + \refCom{ifcsvprostrequal} is not expandable. +\end{docCommand} + + +The following number tests are wrappers for corresponding \LaTeX3 conditionals. + +\begin{docCommand}[doc new={2021-06-28}]{ifcsvfpcmp}{\marg{floating point expression}\marg{true}\marg{false}} + Evaluates the given \meta{floating point expression} + and executes \meta{true} or \meta{false} appropriately. + The evaluation is done using |\fp_compare:nTF|. + \refCom{ifcsvfpcmp} is expandable. +\end{docCommand} + +\begin{docCommand}[doc new={2021-06-28}]{ifcsvintcmp}{\marg{integer expression}\marg{true}\marg{false}} + Evaluates the given \meta{integer expression} + and executes \meta{true} or \meta{false} appropriately. + The evaluation is done using |\int_compare:nTF|. + \refCom{ifcsvintcmp} is expandable. +\end{docCommand} + + +\clearpage +\section{Examples}% + +\subsection{A Serial Letter}% +In this example, a serial letter is to be written to all persons with +addresses from the following CSV file. Deliberately, the file content is +not given in very pretty format. + +%-- file embedded for simplicity -- +\begin{tcbverbatimwrite}{address.csv} +name,givenname,gender,degree,street,zip,location,bonus +Maier,Hans,m,,Am Bachweg 17,10010,Hopfingen,20 + % next line with a comma in curly braces +Huber,Erna,f,Dr.,{Moosstraße 32, Hinterschlag},10020,Örtingstetten,30 +Weißbäck,Werner,m,Prof. Dr.,Brauallee 10,10030,Klingenbach,40 + % this line is ignored % + Siebener , Franz,m, , Blaumeisenweg 12 , 10040 , Pardauz , 50 + % preceding and trailing spaces in entries are removed % +Schmitt,Anton,m,,{\AE{}lfred-Esplanade, T\ae{}g 37}, 10050,\OE{}resung,60 +\end{tcbverbatimwrite} +%-- end embedded file -- + +\csvlisting{address} + +Firstly, we survey the file content quickly using +|\csvautotabular|. +As can be seen, unfeasible lines are ignored automatically. + +\begin{dispExample} +\tiny\csvautotabular{address.csv} +\end{dispExample} + +Now, we create the serial letter where every feasible data line produces +an own page. Here, we simulate the page by a |tcolorbox| (from the package +|tcolorbox|). +For the gender specific salutations, an auxiliary macro |\ifmale| is +introduced. + +\begin{dispExample} +% this example requires the tcolorbox package +\newcommand{\ifmale}[2]{\ifcsvstrcmp{\gender}{m}{#1}{#2}} + +\csvreader[head to column names]{address.csv}{}{% +\begin{tcolorbox}[colframe=DarkGray,colback=White,arc=0mm,width=(\linewidth-2pt)/2, + equal height group=letter,before=,after=\hfill,fonttitle=\bfseries, + adjusted title={Letter to \name}] + \ifcsvstrcmp{\degree}{}{\ifmale{Mr.}{Ms.}}{\degree}~\givenname~\name\\ + \street\\\zip~\location + \tcblower + {\itshape Dear \ifmale{Sir}{Madam},}\\ + we are pleased to announce you a bonus value of \bonus\%{} + which will be delivered to \location\ soon.\\\ldots +\end{tcolorbox}} +\end{dispExample} + + + +\clearpage +\subsection{A Graphical Presentation}% +For this example, we use some artificial statistical data given by a CSV file. + +%-- file embedded for simplicity -- +\begin{tcbverbatimwrite}{data.csv} +land,group,amount +Bayern,A,1700 +Baden-Württemberg,A,2300 +Sachsen,B,1520 +Thüringen,A,1900 +Hessen,B,2100 +\end{tcbverbatimwrite} +%-- end embedded file -- + +\csvlisting{data} + +Firstly, we survey the file content using +|\csvautobooktabular|. + +\begin{dispExample} +% needs the booktabs package +\csvautobooktabular{data.csv} +\end{dispExample} + +The amount values are presented in the following diagram by bars where +the group classification is given using different colors. + +\begin{dispExample} +% This example requires the package tikz +\begin{tikzpicture}[Group/A/.style={left color=red!10,right color=red!20}, + Group/B/.style={left color=blue!10,right color=blue!20}] +\csvreader[head to column names]{data.csv}{}{% + \begin{scope}[yshift=-\thecsvrow cm] + \path [draw,Group/\group] (0,-0.45) + rectangle node[font=\bfseries] {\amount} (\amount/1000,0.45); + \node[left] at (0,0) {\land}; + \end{scope} } +\end{tikzpicture} +\end{dispExample} + + +\clearpage +It would be nice to sort the bars by length, i.\,e.\ to sort the CSV file +by the |amount| column. If the \csvsorter\ program is properly installed, +see Subsection~\ref{sec:Sorting} on page~\pageref{sec:Sorting}, +this can be done with the following configuration file for \csvsorter: + +\xmllisting{amountsort} + +Now, we just have to add an option |sort by=amountsort.xml|: +\begin{dispExample} +% This example requires the package tikz +% Also, the CSV-Sorter tool has to be installed +\begin{tikzpicture}[Group/A/.style={left color=red!10,right color=red!20}, + Group/B/.style={left color=blue!10,right color=blue!20}] +\csvreader[head to column names,sort by=amountsort.xml]{data.csv}{}{% + \begin{scope}[yshift=-\thecsvrow cm] + \path [draw,Group/\group] (0,-0.45) + rectangle node[font=\bfseries] {\amount} (\amount/1000,0.45); + \node[left] at (0,0) {\land}; + \end{scope} } +\end{tikzpicture} +\end{dispExample} + + + + +\clearpage +Next, we create a pie chart by calling |\csvreader| twice. +In the first step, the total sum of amounts is computed, and in the second +step the slices are drawn. + +\begin{dispExample} +% Modified example from www.texample.net for pie charts +% This example needs the packages tikz, xcolor, calc +\definecolorseries{myseries}{rgb}{step}[rgb]{.95,.85,.55}{.17,.47,.37} +\resetcolorseries{myseries}% + +% a pie slice +\newcommand{\slice}[4]{ + \pgfmathsetmacro{\midangle}{0.5*#1+0.5*#2} + \begin{scope} + \clip (0,0) -- (#1:1) arc (#1:#2:1) -- cycle; + \colorlet{SliceColor}{myseries!!+}% + \fill[inner color=SliceColor!30,outer color=SliceColor!60] (0,0) circle (1cm); + \end{scope} + \draw[thick] (0,0) -- (#1:1) arc (#1:#2:1) -- cycle; + \node[label=\midangle:#4] at (\midangle:1) {}; + \pgfmathsetmacro{\temp}{min((#2-#1-10)/110*(-0.3),0)} + \pgfmathsetmacro{\innerpos}{max(\temp,-0.5) + 0.8} + \node at (\midangle:\innerpos) {#3}; +} + +% sum of amounts +\csvreader[before reading=\def\mysum{0}]{data.csv}{amount=\amount}{% + \pgfmathsetmacro{\mysum}{\mysum+\amount}% +} + +% drawing of the pie chart +\begin{tikzpicture}[scale=3]% +\def\mya{0}\def\myb{0} +\csvreader[head to column names]{data.csv}{}{% + \let\mya\myb + \pgfmathsetmacro{\myb}{\myb+\amount} + \slice{\mya/\mysum*360}{\myb/\mysum*360}{\amount}{\land} +} +\end{tikzpicture}% +\end{dispExample} + + +\clearpage +Finally, the filter option is demonstrated by separating the groups A and B. +Every item is piled upon the appropriate stack. + +\begin{dispExample} +\newcommand{\drawGroup}[2]{% + \def\mya{0}\def\myb{0} + \node[below=3mm] at (2.5,0) {\bfseries Group #1}; + \csvreader[head to column names,filter equal={\group}{#1}]{data.csv}{}{% + \let\mya\myb + \pgfmathsetmacro{\myb}{\myb+\amount} + \path[draw,top color=#2!25,bottom color=#2!50] + (0,\mya/1000) rectangle node{\land\ (\amount)} (5,\myb/1000); +}} + +\begin{tikzpicture} + \fill[gray!75] (-1,0) rectangle (13,-0.1); + \drawGroup{A}{red} + \begin{scope}[xshift=7cm] + \drawGroup{B}{blue} + \end{scope} +\end{tikzpicture} + +\end{dispExample} + + +\clearpage +\subsection{Macro code inside the data}\label{macrocodexample}% + +If needed, the data file may contain macro code. + +%-- file embedded for simplicity -- +\begin{tcbverbatimwrite}{macrodata.csv} +type,description,content +M,A nice \textbf{formula}, $\displaystyle \int\frac{1}{x} = \ln|x|+c$ +G,A \textcolor{red}{colored} ball, {\tikz \shadedraw [shading=ball] (0,0) circle (.5cm);} +M,\textbf{Another} formula, $\displaystyle \lim\limits_{n\to\infty} \frac{1}{n}=0$ +\end{tcbverbatimwrite} +%-- end embedded file -- + +\csvlisting{macrodata} + +Firstly, we survey the file content using +|\csvautobooktabular|. + +\begin{dispExample} +\csvautobooktabular{macrodata.csv} +\end{dispExample} + + +\begin{dispExample} +\csvstyle{my enumerate}{head to column names, + before reading=\begin{enumerate},after reading=\end{enumerate}} + +\csvreader[my enumerate]{macrodata.csv}{}{% + \item \description:\par\content} + +\bigskip +Now, formulas only: +\csvreader[my enumerate,filter strcmp={\type}{M}]{macrodata.csv}{}{% + \item \description:\qquad\content} +\end{dispExample} + +\clearpage +\subsection{Tables with Number Formatting}\label{numberformatting}% + +We consider a file with numerical data which should be pretty-printed. + +%-- file embedded for simplicity -- +\begin{tcbverbatimwrite}{data_numbers.csv} +month, dogs, cats +January, 12.50,12.3e5 +February, 3.32, 8.7e3 +March, 43, 3.1e6 +April, 0.33, 21.2e4 +May, 5.12, 3.45e6 +June, 6.44, 6.66e6 +July, 123.2,7.3e7 +August, 12.3, 5.3e4 +September,2.3, 4.4e4 +October, 6.5, 6.5e6 +November, 0.55, 5.5e5 +December, 2.2, 3.3e3 +\end{tcbverbatimwrite} + +\csvlisting{data_numbers} + +\medskip + +The |siunitx| package provides a huge amount of formatting options for +numbers. A good and robust way to apply formatting by |siunitx| inside +tables generated by |csvsimple-l3| is the |\tablenum| macro from +|siunitx|. + +\begin{dispExample} +% \usepackage{siunitx,array,booktabs} +\csvreader[ + head to column names, + before reading = \begin{center}\sisetup{table-number-alignment=center}, + tabular = cc, + table head = \toprule \textbf{Cats} & \textbf{Dogs} \\\midrule, + table foot = \bottomrule, + after reading = \end{center} + ]{data_numbers.csv}{}{% + \tablenum[table-format=2.2e1]{\cats} & \tablenum{\dogs} + } +\end{dispExample} + +\clearpage + +It is also possible to create on-the-fly tables using calcations of +the given data. The following example shows cat values bisected and +dog values doubled. + +\begin{dispExample} +% \usepackage{siunitx,array,booktabs,xfp} +\csvreader[ + head to column names, + before reading = \begin{center}\sisetup{table-number-alignment=center}, + tabular = cccc, + table head = \toprule \textbf{Cats} & \textbf{Dogs} + & \textbf{Halfcats} & \textbf{Doubledogs} \\\midrule, + table foot = \bottomrule, + after reading = \end{center} + ]{data_numbers.csv}{}{% + \tablenum[table-format=2.2e1]{\cats} & \tablenum{\dogs} + & \tablenum[exponent-mode=scientific, round-precision=3, + round-mode=places, table-format=1.3e1]{\fpeval{\cats/2}} + & \tablenum{\fpeval{\dogs*2}} + } +\end{dispExample} + + +\clearpage + +The |siunitx| package also provides a new column type |S| +which can align material using a number of different strategies. +Special care is needed, if the \emph{first} or the \emph{last} column is to be formatted with +the column type |S|. The number detection of |siunitx| is disturbed by +the line reading code of |csvsimple-l3| which actually is present at the +first and last column. To avoid this problem, the utilization of +|\tablenum| is appropriate, see above. +Alternatively, a very nifty workaround suggested by Enrico Gregorio is to +add an invisible dummy column with |c@{}| as first column +and |@{}c| as last column: + +\begin{dispExample} +% \usepackage{siunitx,array,booktabs} +\csvreader[ + head to column names, + before reading = \begin{center}\sisetup{table-number-alignment=center}, + tabular = {c@{}S[table-format=2.2e1]S@{}c}, + table head = \toprule & \textbf{Cats} & \textbf{Dogs} & \\\midrule, + table foot = \bottomrule, + after reading = \end{center} + ]{data_numbers.csv}{}{% + & \cats & \dogs & + } +\end{dispExample} + + + + +\clearpage +Now, the preceding table shall be sorted by the \emph{cats} values. +If the \csvsorter\ program is properly installed, +see Subsection~\ref{sec:Sorting} on page~\pageref{sec:Sorting}, +this can be done with the following configuration file for \csvsorter: + +\xmllisting{catsort} + +Now, we just have to add an option |sort by=catsort.xml|: +\begin{dispExample} +% \usepackage{siunitx,array,booktabs} +% Also, the CSV-Sorter tool has to be installed +\csvreader[ + head to column names, + sort by = catsort.xml, + before reading = \begin{center}\sisetup{table-number-alignment=center}, + tabular = lcc, + table head = \toprule \textbf{Month} & \textbf{Dogs} & \textbf{Cats} \\\midrule, + table foot = \bottomrule, + after reading = \end{center} + ]{data_numbers.csv}{}{% + \month & \tablenum{\dogs} & \tablenum[table-format=2.2e1]{\cats} + } +\end{dispExample} + + +\clearpage +\subsection{CSV data without header line}\label{noheader}% +CSV files with a header line are more semantic than files without header, +but it's no problem to work with headless files. + +For this example, we use again some artificial statistical data given by a CSV file +but this time without header. + +%-- file embedded for simplicity -- +\begin{tcbverbatimwrite}{data_headless.csv} +Bayern,A,1700 +Baden-Württemberg,A,2300 +Sachsen,B,1520 +Thüringen,A,1900 +Hessen,B,2100 +\end{tcbverbatimwrite} +%-- end embedded file -- + +\csvlisting{data_headless} + +Note that you cannot use the \refKey{/csvsim/no head} option for the auto tabular +commands. +If no options are given, the first line is interpreted as header line +which gives an unpleasant result: + +\begin{dispExample} +\csvautobooktabular{data_headless.csv} +\end{dispExample} + +To get the expected result, the \emph{star} versions of the auto tabular +commands can be used. + +\begin{dispExample} +\csvautobooktabular*{data_headless.csv} +\end{dispExample} + +This example can be extended to insert a table head for this headless data: + +\begin{dispExample} +\csvautobooktabular*[ + table head=\toprule\bfseries Land & \bfseries Group + & \bfseries Amount\\\midrule + ]{data_headless.csv} +\end{dispExample} + + +\clearpage + +For the normal \refCom{csvreader} command, the \refKey{/csvsim/no head} option +should be applied. Of course, we cannot use \refKey{/csvsim/head to column names} +because there is no head, but the columns can be addressed by their numbers: + +\begin{dispExample} +\csvreader[ + no head, + tabular = lr, + table head = \toprule\bfseries Land & \bfseries Amount\\\midrule, + table foot = \bottomrule] + {data_headless.csv} + { 1=\land, 3=\amount } + {\land & \amount} +\end{dispExample} + + +\clearpage +\subsection{Imported CSV data}\label{sec:importeddata}% +If data is imported from other applications, there is not always a choice +to format in comma separated values with curly brackets. + +Consider the following example data file: + +%-- file embedded for simplicity -- +\begin{tcbverbatimwrite}{imported.csv} +"name";"address";"email" +"Frank Smith";"Yellow Road 123, Brimblsby";"frank.smith@organization.org" +"Mary May";"Blue Alley 2a, London";"mmay@maybe.uk" +"Hans Meier";"Hauptstraße 32, Berlin";"hans.meier@corporation.de" +\end{tcbverbatimwrite} +%-- end embedded file -- + +\csvlisting{imported} + +If the \csvsorter\ program is properly installed, +see Subsection~\ref{sec:Sorting} on page~\pageref{sec:Sorting}, +this can be transformed on-the-fly +with the following configuration file for \csvsorter: + +\xmllisting{transform} + +Now, we just have to add an option |sort by=transform.xml| to transform +the input data. Here, we actually do not sort. + +\begin{dispExample} +% \usepackage{booktabs,array} +% Also, the CSV-Sorter tool has to be installed +\newcommand{\Header}[1]{\normalfont\bfseries #1} + +\csvreader[ + sort by = transform.xml, + tabular = >{\itshape}ll>{\ttfamily}l, + table head = \toprule\Header{Name} & \Header{Address} & \Header{email}\\\midrule, + table foot = \bottomrule + ] + {imported.csv}{} + {\csvlinetotablerow} +\end{dispExample} + +The file which is generated on-the-fly and which is actually read by +|csvsimple-l3| is the following: + +\tcbinputlisting{docexample,listing style=tcbdocumentation,fonttitle=\bfseries, + listing only,listing file=\jobname_sorted._csv} + + +\clearpage +\subsection{Encoding}\label{encoding}% +If the CSV file has a different encoding than the \LaTeX\ source file, +then special care is needed. + +\begin{itemize} +\item The most obvious treatment is to change the encoding of the CSV file + or the \LaTeX\ source file to match the other one (every good editor + supports such a conversion). This is the easiest choice, if there a no + good reasons against such a step. E.g., unfortunately, several tools + under Windows need the CSV file to be |cp1252| encoded while + the \LaTeX\ source file may need to be |utf8| encoded. + +\item The |inputenc| package allows to switch the encoding inside the + document, say from |utf8| to |cp1252|. Just be aware that you should only + use pure ASCII for additional texts inside the switched region. +\begin{dispListing} +% !TeX encoding=UTF-8 +% .... +\usepackage[utf8]{inputenc} +% .... +\begin{document} +% .... +\inputencoding{latin1}% only use ASCII from here, e.g. "Uberschrift +\csvreader[%... + ]{data_cp1252.csv}{%... + }{% .... + } +\inputencoding{utf8} +% .... +\end{document} +\end{dispListing} + +\item As a variant to the last method, the encoding switch can be done + using options from |csvsimple-l3|: +\begin{dispListing} +% !TeX encoding=UTF-8 +% .... +\usepackage[utf8]{inputenc} +% .... +\begin{document} +% .... +% only use ASCII from here, e.g. "Uberschrift +\csvreader[%... + before reading=\inputencoding{latin1}, + after reading=\inputencoding{utf8}, + ]{data_cp1252.csv}{%... + }{% .... + } +% .... +\end{document} +\end{dispListing} + +\pagebreak\item +If the \csvsorter\ program is properly installed, +see Subsection~\ref{sec:Sorting} on page~\pageref{sec:Sorting}, +the CSV file can be re-encoded on-the-fly +with the following configuration file for \csvsorter: + +\xmllisting{encoding} + +\begin{dispListing} +% !TeX encoding=UTF-8 +% .... +\usepackage[utf8]{inputenc} +% .... +\begin{document} +% .... +\csvreader[%... + sort by=encoding.xml, + ]{data_cp1252.csv}{%... + }{% .... + } +% .... +\end{document} +\end{dispListing} + + +\end{itemize} + + +\clearpage + +\printindex + +\end{document} |