diff --git a/texmf/tex/latex/frank_tex/csvsimple.sty b/texmf/tex/latex/frank_tex/csvsimple.sty new file mode 100644 index 0000000..51e622e --- /dev/null +++ b/texmf/tex/latex/frank_tex/csvsimple.sty @@ -0,0 +1,477 @@ +%% The LaTeX package csvsimple - version 1.07 (2013/09/25) +%% csvsimple.sty: Simple LaTeX CSV file processing +%% +%% ------------------------------------------------------------------------------------------- +%% Copyright (c) 2008-2013 by Prof. Dr. Dr. Thomas F. Sturm +%% ------------------------------------------------------------------------------------------- +%% +%% 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 +%% +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{csvsimple}[2013/09/25 version 1.07 LaTeX CSV file processing] + +\RequirePackage{pgfkeys,ifthen} + + +%---- general + +\def\csv@warning#1{\PackageWarning{csvsimple}{#1}} + +\newread\csv@file +\newcounter{csvinputline} +\newcounter{csvrow} +\newcounter{csvcol} + +\def\csv@empty{} + +\def\csv@addto@macro#1#2{% + \begingroup% + \toks@\expandafter{#1#2}% + \xdef#1{\the\toks@}% + \endgroup% + } + +\long\def\csviffirstrow#1#2{% + \ifnum\c@csvrow=1% + \long\def\csviffirstrow@doit{#1}% + \else% + \long\def\csviffirstrow@doit{#2}% + \fi% + \csviffirstrow@doit% +} + +\long\def\csvifoddrow#1#2{% + \ifodd\c@csvrow% + \long\def\csvifoddrow@doit{#1}% + \else% + \long\def\csvifoddrow@doit{#2}% + \fi% + \csvifoddrow@doit% +} + +\def\csv@and{&} + +\def\csvlinetotablerow{% + \setcounter{csvcol}{0}% + \stepcounter{csvcol}\csv@current@col% + \whiledo{\thecsvcol<\csv@columncount}{\csv@and\stepcounter{csvcol}\csv@current@col}% +} + + +%---- breaking lines + +% This command removes leading and trailing spaces from . I found +% the original code on the web. The original author was Michael Downes, who +% provided the code as an answer to 'around the bend' question #15. +\catcode`\Q=3 +\def\csv@TrimSpaces#1{% + \begingroup% + \aftergroup\toks\aftergroup0\aftergroup{% + \expandafter\csv@trimb\expandafter\noexpand#1Q Q}% + \global\edef#1{\the\toks0}% +} +\def\csv@trimb#1 Q{\csv@trimc#1Q} +\def\csv@trimc#1Q#2{\afterassignment\endgroup \vfuzz\the\vfuzz#1} +\catcode`\Q=11 + +\def\csv@breakline@kernel#1{% + \ifx\csv@termination#1\let\nextcol=\relax\else% + \let\nextcol=\csv@breakline% + \stepcounter{csvcol}% + \def\csv@col@body{#1}\csv@TrimSpaces\csv@col@body% + \toks@\expandafter{\csv@col@body}% + \expandafter\xdef\csname csvcol\roman{csvcol}\endcsname{\the\toks@}% + \fi% + \nextcol% + } + +% comma +\def\csv@breakline@A#1,{\csv@breakline@kernel{#1}} + +\def\csv@scanline@A#1{% + \setcounter{csvcol}{0}% + \csv@breakline#1,\csv@termination,% + } + +% semi colon +\def\csv@breakline@B#1;{\csv@breakline@kernel{#1}} + +\def\csv@scanline@B#1{% + \setcounter{csvcol}{0}% + \csv@breakline#1;\csv@termination;% + } + +% pipe +\def\csv@breakline@C#1|{\csv@breakline@kernel{#1}} + +\def\csv@scanline@C#1{% + \setcounter{csvcol}{0}% + \csv@breakline#1|\csv@termination|% + } + +% expands a CSV line and scans content +\def\csv@escanline#1{% + \toks@\expandafter{#1}% + \edef\@csv@scanline{\noexpand\csv@scanline{\the\toks@}}% + \@csv@scanline% + } + + +% default preprocessor (no preprocessing) +\def\csv@no@preprocessor#1#2{\let#2=#1\relax} + + +%---- the loop + +\def\csv@AtEndLoop{\csv@addto@macro\@endloophook} +\let\@endloophook\csv@empty + +\def\csv@current@col{\csname csvcol\roman{csvcol}\endcsname} + +% auto head names +\def\set@csv@autohead{% + \toks0=\expandafter{\csname\csv@current@col\endcsname}% + \toks1=\expandafter{\csname csvcol\roman{csvcol}\endcsname}% + \edef\csv@temp{\noexpand\gdef\the\toks0{\the\toks1}\noexpand\csv@AtEndLoop{\noexpand\gdef\the\toks0{}}}% + \csv@temp% +} + + +% head names and numbers +\def\set@csv@head{% + \toks0={\gdef##1}% + \toks1=\expandafter{\csname csvcol\roman{csvcol}\endcsname}% + \edef\csv@temp{\noexpand\pgfkeysdef{/csv head/\csv@current@col}{\the\toks0{\the\toks1}\noexpand\csv@AtEndLoop{\the\toks0{}}}}% + \csv@temp% + \edef\csv@temp{\noexpand\pgfkeysdef{/csv head/\thecsvcol}{\the\toks0{\the\toks1}\noexpand\csv@AtEndLoop{\the\toks0{}}}}% + \csv@temp% +} + +% head line +\def\csv@processheadline{% + \csvreadnext% + \csv@escanline{\csvline}% + \xdef\csv@columncount{\thecsvcol}% + \setcounter{csvcol}{0}% + \loop% + \stepcounter{csvcol}% + \csv@opt@headtocolumnames% + \set@csv@head% + \ifnum\thecsvcol<\csv@columncount\repeat% + \toks@=\expandafter{\csv@columnnames}% + \edef\csv@processkeys{\noexpand\pgfkeys{/csv head/.cd,\the\toks@}}% + \csv@processkeys% + \csv@posthead% +} + +% head numbers for no head +\def\set@csv@nohead{% + \toks0={\gdef##1}% + \toks1=\expandafter{\csname csvcol\roman{csvcol}\endcsname}% + \edef\csv@temp{\noexpand\pgfkeysdef{/csv head/\thecsvcol}{\the\toks0{\the\toks1}\noexpand\csv@AtEndLoop{\the\toks0{}}}}% + \csv@temp% +} + +% no head line +\def\csv@noheadline{% + \setcounter{csvcol}{0}% + \loop% + \stepcounter{csvcol}% + \set@csv@nohead% + \ifnum\thecsvcol<\csv@columncount\repeat% + \toks@=\expandafter{\csv@columnnames}% + \edef\csv@processkeys{\noexpand\pgfkeys{/csv head/.cd,\the\toks@}}% + \csv@processkeys% +} + +% check filter +\def\csv@checkfilter{% + \csv@prefiltercommand% + \csv@iffilter{% + \stepcounter{csvrow}% + \let\csv@usage=\csv@do@linecommand% + }{}% +} + +\def\csv@truefilter#1#2{#1} + +\def\csv@falsefilter#1#2{#2} + +\def\csvfilteraccept{\global\let\csv@iffilter=\csv@truefilter} + +\def\csvfilterreject{\global\let\csv@iffilter=\csv@falsefilter} + +% check columns +\def\csv@checkcolumncount{% + \ifnum\thecsvcol=\csv@columncount% + \csv@checkfilter% + \else + \csv@columncounterror% + \fi% +} + +\def\csv@nocheckcolumncount{% + \csv@checkfilter% +} + +% normal line +\def\csv@do@linecommand{% + \csv@do@latepostline% + \csv@do@preline% + \csv@body% + \csv@do@postline% +} + +\gdef\csvreadnext{% + \global\read\csv@file to\csvline% + \stepcounter{csvinputline}% +} + +\let\csv@par=\par + +% reads and processes a CSV file +\def\csvloop#1{% + % reset + \global\let\@endloophook\csv@empty% + % options + \csvset{default,every csv,#1}% + \csv@preprocessor\csv@filename\csv@ppfilename% + \csv@prereading% + \csv@table@begin% + \setcounter{csvinputline}{0}% + % start reading + \openin\csv@file=\csv@ppfilename\relax% + \ifeof\csv@file% + \csv@warning{File \csv@ppfilename\ not existent, not readable, or empty!}% + \else% + % the head line + \csv@opt@processheadline% + \fi% + % + \setcounter{csvrow}{0}% + \gdef\csv@do@preline{% + \csv@prefirstline% + \global\let\csv@do@preline=\csv@preline% + }% + \gdef\csv@do@postline{% + \csv@postfirstline% + \global\let\csv@do@postline=\csv@postline% + }% + \gdef\csv@do@@latepostline{% + \csv@latepostfirstline% + \global\let\csv@do@latepostline=\csv@latepostline% + }% + \gdef\csv@do@latepostline{% + \csv@lateposthead% + \global\let\csv@do@latepostline=\csv@do@@latepostline% + }% + % command for the reading loop + \gdef\csv@iterate{% + \let\csv@usage=\csv@empty% + \csvreadnext% + \ifeof\csv@file% + \global\let\csv@next=\csv@empty% + \else% + \global\let\csv@next=\csv@iterate% + \if\csv@par\csvline\relax% + \else% + \csv@escanline{\csvline}% + % check and decide + \csv@opt@checkcolumncount% + \fi% + \fi% + % do or do not + \csv@usage% + \csv@next}% + \ifeof\csv@file% + \global\let\csv@next=\csv@empty% + \else% + \global\let\csv@next=\csv@iterate% + \fi% + \csv@next% + \closein\csv@file% + \@endloophook% + \csv@latepostlastline% + \csv@table@end% + \csv@postreading% +} + +% user command +\long\def\csv@reader[#1]#2#3#4{% + \global\long\def\csv@@body{#4}% + \csvloop{#1,file={#2},column names={#3},command=\csv@@body}% +} + +\def\csvreader{% + \@ifnextchar[{\csv@reader}{\csv@reader[]}} + + +%---- keys + +\pgfkeys{/handlers/.gstore in/.code=\pgfkeysalso{\pgfkeyscurrentpath/.code=\gdef#1{##1}}} +\pgfkeys{/csv/.is family} +\pgfkeys{/csv head/.is family} + +\def\csvset{\pgfqkeys{/csv}} +\def\csvheadset{\pgfqkeys{/csv head}} + +\csvset{% + file/.gstore in=\csv@filename,% + preprocessed file/.gstore in=\csv@ppfilename,% + preprocessor/.gstore in=\csv@preprocessor,% + no preprocessing/.style={preprocessor=\csv@no@preprocessor}, + column names reset/.code={\gdef\csv@columnnames{}},% + column names/.code={% + \toks0=\expandafter{\csv@columnnames}% + \def\temp{#1}\toks1=\expandafter{\temp}% + \xdef\csv@columnnames{\the\toks0,\the\toks1}% + }, + command/.gstore in=\csv@body,% + check column count/.code={\ifthenelse{\equal{#1}{true}}{% + \global\let\csv@opt@checkcolumncount=\csv@checkcolumncount}{% + \global\let\csv@opt@checkcolumncount=\csv@nocheckcolumncount}}, + check column count/.default=true,% + on column count error/.gstore in=\csv@columncounterror, + head/.code={\ifthenelse{\equal{#1}{true}}{% + \global\let\csv@opt@processheadline=\csv@processheadline% + \pgfkeysalso{check column count}}{% + \global\let\csv@opt@processheadline=\csv@noheadline% + \pgfkeysalso{check column count=false,late after head=}}}, + head/.default=true,% + head to column names/.code={\ifthenelse{\equal{#1}{true}}{% + \global\let\csv@opt@headtocolumnames=\set@csv@autohead}{% + \global\let\csv@opt@headtocolumnames=\csv@empty}},% + head to column names/.default=true,% + column count/.gstore in=\csv@columncount,% + filter/.code={% + \def\temp{#1}\toks@=\expandafter{\temp}% + \xdef\csv@iffilter{\noexpand\ifthenelse{\the\toks@}}}, + no filter/.code={\csvfilteraccept}, + filter reject all/.code={\csvfilterreject}, + filter accept all/.code={\csvfilteraccept}, + before filter/.gstore in=\csv@prefiltercommand, + before first line/.gstore in=\csv@prefirstline, + before line/.code={\gdef\csv@preline{#1}\pgfkeysalso{before first line=#1}}, + after first line/.gstore in=\csv@postfirstline, + after line/.code={\gdef\csv@postline{#1}\pgfkeysalso{after first line=#1}}, + late after first line/.gstore in=\csv@latepostfirstline, + late after last line/.gstore in=\csv@latepostlastline, + late after line/.code={\gdef\csv@latepostline{#1}\pgfkeysalso{late after first line=#1,late after last line=#1}}, + after head/.gstore in=\csv@posthead, + late after head/.gstore in=\csv@lateposthead, + before reading/.gstore in=\csv@prereading, + after reading/.gstore in=\csv@postreading, + before table/.gstore in=\csv@pretable, + after table/.gstore in=\csv@posttable, + table head/.gstore in=\csv@tablehead, + table foot/.gstore in=\csv@tablefoot, + @table/.code 2 args={\gdef\csv@table@begin{#1}\gdef\csv@table@end{#2}}, + no table/.style={@table={}{}}, + separator/.is choice, + separator/comma/.code={\global\let\csv@scanline=\csv@scanline@A% + \global\let\csv@breakline\csv@breakline@A}, + separator/semicolon/.code={\global\let\csv@scanline=\csv@scanline@B% + \global\let\csv@breakline\csv@breakline@B}, + separator/pipe/.code={\global\let\csv@scanline=\csv@scanline@C% + \global\let\csv@breakline\csv@breakline@C}, + % + % default for reset + default/.style={ + file=unknown.csv, + no preprocessing, + command=\csvline, + column names reset, + head, + head to column names=false, + column count=10, + on column count error=, + no filter, + before filter=, + before line=, + after line=, + late after line=, + after head=, + late after head=, + before reading=, + after reading=, + before table=, + after table=, + table head=, + table foot=, + no table, + separator=comma, + }, + default, + % + % styles + every csv/.style={}, + no head/.style={head=false}, + no check column count/.style={check column count=false}, + warn on column count error/.style={on column count error={\csv@warning{>\thecsvcol< instead of >\csv@columncount< columns for input line >\thecsvinputline< of file >\csv@ppfilename<}}}, + filter equal/.style 2 args={filter=\equal{#1}{#2}}, + filter not equal/.style 2 args={filter=\not\equal{#1}{#2}}, + tabular/.style={ + @table={\csv@pretable\begin{tabular}{#1}\csv@tablehead}{\csv@tablefoot\end{tabular}\csv@posttable}, + late after line=\\}, + centered tabular/.style={ + @table={\begin{center}\csv@pretable\begin{tabular}{#1}\csv@tablehead}{\csv@tablefoot\end{tabular}\csv@posttable\end{center}}, + late after line=\\}, + longtable/.style={ + @table={\csv@pretable\begin{longtable}{#1}\csv@tablehead}{\csv@tablefoot\end{longtable}\csv@posttable}, + late after line=\\}, + tabbing/.style={ + @table={\csv@pretable\begin{tabbing}\csv@tablehead}{\csv@tablefoot\end{tabbing}\csv@posttable}, + late after line=\\, + late after last line=}, + centered tabbing/.style={ + @table={\begin{center}\csv@pretable\begin{tabbing}\csv@tablehead}{\csv@tablefoot\end{tabbing}\csv@posttable\end{center}}, + late after line=\\, + late after last line=}, + autotabular/.style={ + file=#1, + after head=\csv@pretable\begin{tabular}{|*{\csv@columncount}{l|}}\csv@tablehead, + table head=\hline\csvlinetotablerow\\\hline, + late after line=\\, + table foot=\\\hline, + late after last line=\csv@tablefoot\end{tabular}\csv@posttable, + command=\csvlinetotablerow}, + autolongtable/.style={ + file=#1, + after head=\csv@pretable\begin{longtable}{|*{\csv@columncount}{l|}}\csv@tablehead, + table head=\hline\csvlinetotablerow\\\hline\endhead\hline\endfoot, + late after line=\\, + late after last line=\csv@tablefoot\end{longtable}\csv@posttable, + command=\csvlinetotablerow} +} + +% deprecated keys +\csvset{ + nofilter/.style=no filter, + nohead/.style=no head, +} + + +\long\def\csv@autotabular[#1]#2{\csvloop{autotabular={#2},#1}} + +\def\csvautotabular{% + \@ifnextchar[{\csv@autotabular}{\csv@autotabular[]}} + +\long\def\csv@autolongtable[#1]#2{\csvloop{autolongtable={#2},#1}} + +\def\csvautolongtable{% + \@ifnextchar[{\csv@autolongtable}{\csv@autolongtable[]}} + +\def\csvstyle#1#2{\csvset{#1/.style={#2}}} + +\def\csvnames#1#2{\csvset{#1/.style={column names={#2}}}} +