summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2021-06-29 19:53:39 +0000
committerKarl Berry <karl@freefriends.org>2021-06-29 19:53:39 +0000
commitfbf2ab9fcc75e9134c6e0f67d21cf7b993e67d99 (patch)
tree9936b4ef85813b6d9fd9076c679851396960ac6c /Master/texmf-dist/tex/latex
parent48647527a4d38db34ffd7ef702866e54fa17de55 (diff)
csvsimple (29jun21)
git-svn-id: svn://tug.org/texlive/trunk@59756 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex')
-rw-r--r--Master/texmf-dist/tex/latex/csvsimple/csvsimple-l3.sty1260
-rw-r--r--Master/texmf-dist/tex/latex/csvsimple/csvsimple-legacy.sty795
-rw-r--r--Master/texmf-dist/tex/latex/csvsimple/csvsimple.sty795
3 files changed, 2087 insertions, 763 deletions
diff --git a/Master/texmf-dist/tex/latex/csvsimple/csvsimple-l3.sty b/Master/texmf-dist/tex/latex/csvsimple/csvsimple-l3.sty
new file mode 100644
index 00000000000..da7e62f47dd
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/csvsimple/csvsimple-l3.sty
@@ -0,0 +1,1260 @@
+%% The LaTeX package csvsimple - version 2.0.0 (2021/06/29)
+%% csvsimple-l3.sty: Simple LaTeX CSV file processing (LaTeX3)
+%%
+%% -------------------------------------------------------------------------------------------
+%% 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
+%%
+\ProvidesExplPackage{csvsimple-l3}{2021/06/29}{2.0.0}
+ {LaTeX3 CSV file processing}
+
+
+
+%---- check package
+
+\cs_if_exist:NT \c__csvsim_package_expl_bool
+ {
+ \msg_new:nnn { csvsimple }{ l3 / package-loaded }
+ { Package~'csvsimple-legacy'~seems~already~be~loaded!~
+ 'csvsimple-l3'~cannot~be~loaded~simultaneously.~
+ Therefore,~loading~of~'csvsimple-l3'~stops~now.}
+ \msg_warning:nn { csvsimple }{ l3 / package-loaded }
+ \tex_endinput:D
+ }
+\bool_const:Nn \c__csvsim_package_expl_bool { 1 }
+
+
+
+%---- declarations and expl3 variants
+
+\bool_new:N \g__csvsim_check_column_count_bool
+\bool_new:N \g__csvsim_firstline_bool
+\bool_new:N \g__csvsim_head_bool
+\bool_new:N \g__csvsim_head_to_colnames_bool
+\bool_new:N \g__csvsim_line_accepted_bool
+\bool_new:N \l__csvsim_respect_and_bool
+\bool_new:N \l__csvsim_respect_backslash_bool
+\bool_new:N \l__csvsim_respect_circumflex_bool
+\bool_new:N \l__csvsim_respect_dollar_bool
+\bool_new:N \l__csvsim_respect_leftbrace_bool
+\bool_new:N \l__csvsim_respect_percent_bool
+\bool_new:N \l__csvsim_respect_rightbrace_bool
+\bool_new:N \l__csvsim_respect_sharp_bool
+\bool_new:N \l__csvsim_respect_tab_bool
+\bool_new:N \l__csvsim_respect_tilde_bool
+\bool_new:N \l__csvsim_respect_underscore_bool
+
+\int_new:N \g__csvsim_col_int
+\int_new:N \g__csvsim_colmax_int
+\int_new:N \g_csvsim_inputline_int
+\int_new:N \g_csvsim_row_int
+\int_new:N \g_csvsim_columncount_int
+
+\seq_new:N \g__csvsim_colname_seq
+\seq_new:N \g__csvsim_line_seq
+\seq_new:N \g__csvsim_range_seq
+
+\str_new:N \g__csvsim_curfilename_str
+\str_new:N \g__csvsim_filename_str
+\str_new:N \l__csvsim_csvsorter_command_str
+\str_new:N \l__csvsim_csvsorter_configpath_str
+\str_new:N \l__csvsim_csvsorter_log_str
+\str_new:N \l__csvsim_csvsorter_token_str
+\str_new:N \l__csvsim_ppfilename_str
+\str_new:N \l__csvsim_temp_filename_str
+
+\tl_const:Nn \c__csvsim_par_tl { \par }
+
+\tl_new:N \g__csvsim_after_table_tl
+\tl_new:N \g__csvsim_before_table_tl
+\tl_new:N \g__csvsim_body_tl
+\tl_new:N \g__csvsim_catcode_tl
+
+\tl_new:N \g__csvsim_columnnames_tl
+\tl_new:N \g__csvsim_filter_tl
+\tl_new:N \g__csvsim_headname_prefix_tl
+\tl_new:N \g__csvsim_hook_after_first_line_tl
+\tl_new:N \g__csvsim_hook_after_head_tl
+\tl_new:N \g__csvsim_hook_after_line_tl
+\tl_new:N \g__csvsim_hook_after_reading_tl
+\tl_new:N \g__csvsim_hook_before_filter_tl
+\tl_new:N \g__csvsim_hook_before_first_line_tl
+\tl_new:N \g__csvsim_hook_before_line_tl
+\tl_new:N \g__csvsim_hook_before_reading_tl
+\tl_new:N \g__csvsim_hook_columncounterror_tl
+\tl_new:N \g__csvsim_hook_late_after_first_line_tl
+\tl_new:N \g__csvsim_hook_late_after_head_tl
+\tl_new:N \g__csvsim_hook_late_after_last_line_tl
+\tl_new:N \g__csvsim_hook_late_after_line_tl
+\tl_new:N \g__csvsim_hook_table_begin_tl
+\tl_new:N \g__csvsim_hook_table_end_tl
+\tl_new:N \g__csvsim_preprocessor_tl
+\tl_new:N \g__csvsim_separator_tl
+\tl_new:N \g__csvsim_table_foot_tl
+\tl_new:N \g__csvsim_table_head_tl
+
+\group_begin:
+ \char_set_catcode_other:n { 9 }
+ \str_const:Nn \c__csvsim_tab_str { ^^I }
+\group_end:
+
+\regex_const:Nn \c__csvsim_integer_regex {\A\d+\Z}
+
+\cs_generate_variant:Nn \seq_gset_split:Nnn { NVV }
+
+
+%---- messages
+
+\msg_new:nnnn { csvsimple }{ column-name }
+ { Unknown~column~key~'#1'. }
+ { The~key~'#1'~you~used~in~'column~names'~is~unknown.\\
+ Therefore,~the~macro~#2 is~not~defined.
+ }
+
+\msg_new:nnn { csvsimple }{ empty-head }
+ { File~'#1'~starts~with~an~empty~line~(empty~head)!.}
+
+\msg_new:nnn { csvsimple }{ file-error }
+ { File~'#1'~not~existent,~not~readable,~or~empty!}
+
+\msg_new:nnn { csvsimple }{ column-wrong-count }
+ { #1~instead~of~#2~columns~for~input~line~#3~of~file~'#4'}
+
+\msg_new:nnn { csvsimple }{ sort-info }
+ { Sort~'#1'~by~'#2' }
+
+\msg_new:nnn { csvsimple }{ sort-shell-escape }
+ { You~need~to~use~'-shell-escape'~to~run~CSV-Sorter }
+
+\msg_new:nnnn { csvsimple }{ sort-error }
+ { Call~of~CSV-Sorter~failed! }
+ { See~log~file~'\l__csvsim_csvsorter_log_str'. }
+
+
+
+%---- core loop processing
+
+\cs_new_protected_nopar:Npn \__csvsim_read_line:
+ {
+ \group_begin:
+ \g__csvsim_catcode_tl
+ \ior_get:NNTF \g__csvsim_ior \l_tmpa_tl
+ {
+ \tl_gset_eq:NN \csvline \l_tmpa_tl
+ \int_gincr:N \g_csvsim_inputline_int
+ }
+ {
+ \msg_error:nnx { csvsimple }{ file-error }{ \g__csvsim_curfilename_str }
+ }
+ \group_end:
+ }
+
+
+\cs_new_protected_nopar:Npn \__csvsim_scan_line:
+ {
+ \int_gzero:N \g__csvsim_col_int
+ \seq_gset_split:NVV \g__csvsim_line_seq \g__csvsim_separator_tl \csvline
+ \seq_map_inline:Nn \g__csvsim_line_seq
+ {
+ \int_gincr:N \g__csvsim_col_int
+ \tl_gset:cn {csvcol \int_to_roman:n \g__csvsim_col_int}{##1}
+ }
+ \int_compare:nNnT \g__csvsim_colmax_int < \g__csvsim_col_int
+ {
+ \int_gset_eq:NN \g__csvsim_colmax_int \g__csvsim_col_int
+ }
+ \int_compare:nNnT \g_csvsim_columncount_int < \c_one_int
+ {
+ \int_gset_eq:NN \g_csvsim_columncount_int \g__csvsim_col_int
+ }
+ }
+
+
+\cs_new_protected_nopar:Npn \__csvsim_process_head_name:n #1
+ {
+ \tl_set:No \l_tmpa_tl {\cs:w csvcol\int_to_roman:n{#1} \cs_end:}
+ \exp_args:NnV \cs_set_nopar:cpn {__csvsim__/\l_tmpa_tl} \l_tmpa_tl
+
+ \bool_if:NT \g__csvsim_head_to_colnames_bool
+ {
+ \tl_set:No \l_tmpb_tl {\cs:w \g__csvsim_headname_prefix_tl \l_tmpa_tl \cs_end:}
+ \tl_put_right:NV \l_tmpb_tl \l_tmpa_tl
+ \exp_args:NNV \seq_gput_right:Nn \g__csvsim_colname_seq \l_tmpb_tl
+ }
+ }
+
+
+\cs_new_protected_nopar:Npn \__csvsim_read_head:
+ {
+ \__csvsim_read_line:
+ \tl_if_eq:NNTF \csvline \c__csvsim_par_tl
+ {
+ \msg_error:nnx { csvsimple }{ empty-head }{ \g__csvsim_filename_str }
+ }
+ {
+ \int_zero:N \g_csvsim_columncount_int
+ \__csvsim_scan_line:
+ \int_step_function:nN \g_csvsim_columncount_int \__csvsim_process_head_name:n
+ }
+ }
+
+
+\cs_new_protected_nopar:Npn \__csvsim_process_colname:nn #1#2
+ {
+ \cs_if_exist:cTF {__csvsim__/#1}
+ {
+ \tl_set:Nv \l_tmpa_tl {__csvsim__/#1}
+ \tl_put_left:Nn \l_tmpa_tl {#2}
+ \exp_args:NNV \seq_gput_right:Nn \g__csvsim_colname_seq \l_tmpa_tl
+ }
+ {
+ \regex_match:NnTF \c__csvsim_integer_regex {#1}
+ {
+ \tl_set:No \l_tmpa_tl {\cs:w csvcol\int_to_roman:n{#1} \cs_end:}
+ \tl_put_left:Nn \l_tmpa_tl {#2}
+ \exp_args:NNV \seq_gput_right:Nn \g__csvsim_colname_seq \l_tmpa_tl
+ }
+ {
+ \str_set:Nn \l_tmpb_str {#2}
+ \msg_error:nnxx { csvsimple }{ column-name }{ #1 }{ \l_tmpb_str }
+ }
+ }
+ }
+
+
+\cs_new_protected_nopar:Npn \__csvsim_set_colnames:
+ {
+ \seq_map_inline:Nn \g__csvsim_colname_seq
+ {
+ \tl_gset_eq:NN ##1
+ }
+ }
+
+
+\cs_new_protected_nopar:Npn \__csvsim_loop:
+ {
+ % preprocess
+ \tl_if_empty:NTF \l__csvsim_preprocessor_tl
+ {
+ \str_gset_eq:NN \g__csvsim_curfilename_str \g__csvsim_filename_str
+ }
+ {
+ \l__csvsim_preprocessor_tl \g__csvsim_filename_str \l__csvsim_ppfilename_str
+ \str_gset_eq:NN \g__csvsim_curfilename_str \l__csvsim_ppfilename_str
+ }
+
+ % initialize
+ \cs_if_exist:NF \g__csvsim_ior
+ {
+ \ior_new:N \g__csvsim_ior
+ }
+ \__csvsim_setup_catcode_list:
+ \seq_gclear:N \g__csvsim_colname_seq
+ \int_gzero:N \g_csvsim_inputline_int
+ \int_gzero:N \g_csvsim_row_int
+ \int_gset_eq:NN \g__csvsim_colmax_int \c_one_int
+
+ % open file
+ \g__csvsim_hook_before_reading_tl
+ \g__csvsim_hook_table_begin_tl
+ \ior_open:Nn \g__csvsim_ior { \g__csvsim_curfilename_str }
+
+ % read head line
+ \bool_if:NT \g__csvsim_head_bool
+ {
+ \__csvsim_read_head:
+ }
+ \exp_args:NNNV \keyval_parse:NNn \use_none:n
+ \__csvsim_process_colname:nn \g__csvsim_columnnames_tl
+ \bool_if:NT \g__csvsim_head_bool
+ {
+ \g__csvsim_hook_after_head_tl
+ }
+
+ % read body lines
+ \bool_gset_true:N \g__csvsim_line_firstline_bool
+ \bool_until_do:nn {\ior_if_eof_p:N \g__csvsim_ior}
+ {
+ \__csvsim_read_line:
+ \tl_if_eq:NNF \csvline \c__csvsim_par_tl
+ {
+ \bool_gset_true:N \g__csvsim_line_accepted_bool
+ \__csvsim_scan_line:
+ \__csvsim_set_colnames:
+ \bool_if:NT \g__csvsim_check_column_count_bool
+ {
+ \int_compare:nNnF \g__csvsim_col_int = \g_csvsim_columncount_int
+ {
+ \bool_gset_false:N \g__csvsim_line_accepted_bool
+ \g__csvsim_hook_columncounterror_tl
+ }
+ }
+ \bool_if:NT \g__csvsim_line_accepted_bool
+ {
+ \g__csvsim_hook_before_filter_tl
+ \g__csvsim_filter_tl
+ \bool_if:NT \g__csvsim_line_accepted_bool
+ {
+ \int_gincr:N \g_csvsim_row_int
+ \__csvsim_check_range:
+ \bool_if:NT \g__csvsim_line_accepted_bool
+ {
+ \bool_if:NTF \g__csvsim_line_firstline_bool
+ {
+ \bool_if:NT \g__csvsim_head_bool
+ {
+ \g__csvsim_hook_late_after_head_tl
+ }
+ \g__csvsim_hook_before_first_line_tl
+ \g__csvsim_body_tl
+ \g__csvsim_hook_after_first_line_tl
+ \bool_gset_false:N \g__csvsim_line_firstline_bool
+ }
+ {
+ \g__csvsim_hook_late_after_line_tl
+ \g__csvsim_hook_before_line_tl
+ \g__csvsim_body_tl
+ \g__csvsim_hook_after_line_tl
+ }
+ }
+ }
+ }
+ }
+ }
+
+ % close file
+ \ior_close:N \g__csvsim_ior
+
+ % clear macros
+ \int_step_inline:nn \g__csvsim_colmax_int
+ {
+ \tl_set:No \l_tmpa_tl {\cs:w csvcol\int_to_roman:n{##1} \cs_end:}
+ \use:x
+ {
+ \exp_not:N\tl_gclear:N \exp_not:V\l_tmpa_tl
+ }
+ }
+ \__csvsim_set_colnames:
+ \seq_gclear:N \g__csvsim_colname_seq
+ \bool_if:NF \g__csvsim_line_firstline_bool
+ {
+ \g__csvsim_hook_late_after_last_line_tl
+ }
+ \g__csvsim_hook_table_end_tl
+ \g__csvsim_hook_after_reading_tl
+ }
+
+
+\NewDocumentCommand \csvloop { +m }
+ {
+ \keys_set:nn { csvsim } { default, every~csv, #1}
+ \__csvsim_loop:
+ }
+
+
+\NewDocumentCommand \csvreader { +O{} m m +m }
+ {
+ \keys_set:nn { csvsim } { default, every~csv, #1, file={#2}, column~names={#3} }
+ \tl_gset:Nn \g__csvsim_body_tl {#4}
+ \__csvsim_loop:
+ }
+
+
+
+%---- auxiliary user macros
+
+\NewDocumentCommand \csvlinetotablerow { }
+ {
+ \tl_clear:N \l_tmpa_tl
+ \bool_set_false:N \l_tmpa_bool
+ \seq_map_inline:Nn \g__csvsim_line_seq
+ {
+ \bool_if:NTF \l_tmpa_bool
+ {
+ \tl_put_right:Nn \l_tmpa_tl { & ##1 }
+ }
+ {
+ \tl_put_right:Nn \l_tmpa_tl { ##1 }
+ \bool_set_true:N \l_tmpa_bool
+ }
+ }
+ \l_tmpa_tl
+ }
+
+
+\NewExpandableDocumentCommand \thecsvrow { }
+ {
+ \int_use:N \g_csvsim_row_int
+ }
+
+
+\NewExpandableDocumentCommand \thecsvcolumncount { }
+ {
+ \int_use:N \g_csvsim_columncount_int
+ }
+
+
+\NewExpandableDocumentCommand \thecsvinputline { }
+ {
+ \int_use:N \g_csvsim_inputline_int
+ }
+
+
+\NewExpandableDocumentCommand \ifcsvfirstrow { }
+ {
+ \bool_if:NTF \g__csvsim_firstline_bool
+ }
+
+% deprecated
+\NewExpandableDocumentCommand \csviffirstrow { }
+ {
+ \bool_if:NTF \g__csvsim_firstline_bool
+ }
+
+
+\NewExpandableDocumentCommand \ifcsvoddrow { }
+ {
+ \int_if_odd:nTF {\g_csvsim_row_int}
+ }
+
+% deprecated
+\NewExpandableDocumentCommand \csvifoddrow { }
+ {
+ \int_if_odd:nTF {\g_csvsim_row_int}
+ }
+
+
+\NewExpandableDocumentCommand \ifcsvstrcmp { m m }
+ {
+ \str_compare:eNeTF {#1} = {#2}
+ }
+
+
+\NewExpandableDocumentCommand \ifcsvnotstrcmp { m m +m +m }
+ {
+ \ifcsvstrcmp{#1}{#2}{#4}{#3}
+ }
+
+
+\NewDocumentCommand \ifcsvstrequal { m m }
+ {
+ \tl_set:Nx \l_tmpa_tl {#1}
+ \tl_set:Nx \l_tmpb_tl {#2}
+ \tl_if_eq:NNTF \l_tmpa_tl \l_tmpb_tl
+ }
+
+
+\NewDocumentCommand \ifcsvprostrequal { m m }
+ {
+ \protected@edef \l_tmpa_tl {#1}
+ \protected@edef \l_tmpb_tl {#2}
+ \tl_if_eq:NNTF \l_tmpa_tl \l_tmpb_tl
+ }
+
+
+\NewExpandableDocumentCommand \ifcsvfpcmp { m }
+ {
+ \fp_compare:nTF {#1}
+ }
+
+
+\NewExpandableDocumentCommand \ifcsvintcmp { m }
+ {
+ \int_compare:nTF {#1}
+ }
+
+
+%---- filename functions
+
+\cs_new_protected_nopar:Npn \__csvsim_set_temp_filename:nnn #1#2#3
+ {
+ \str_set:Nn \l__csvsim_temp_filename_str {#2#3}
+ \str_if_empty:NTF \l__csvsim_temp_filename_str
+ {
+ \str_set:Nn \l__csvsim_temp_filename_str {#1}
+ }
+ {
+ \str_set:Nn \l_tmpa_str {#1}
+ \str_if_empty:NF \l_tmpa_str
+ {
+ \str_compare:eNeF { \str_item:Nn \l_tmpa_str {-1} } = { / }
+ {
+ \str_put_right:Nn \l_tmpa_str {/}
+ }
+ \str_concat:NNN \l__csvsim_temp_filename_str
+ \l_tmpa_str \l__csvsim_temp_filename_str
+ }
+ }
+ }
+
+
+\cs_new_protected_nopar:Npn \__csvsim_set_temp_filename:n #1
+ {
+ \file_parse_full_name_apply:nN { #1 } \__csvsim_set_temp_filename:nnn
+ }
+
+
+\cs_new_protected_nopar:Npn \__csvsim_set_filename:Nn #1#2
+ {
+ \__csvsim_set_temp_filename:n { #2 }
+ \str_set_eq:NN #1 \l__csvsim_temp_filename_str
+ }
+
+
+\cs_new_protected_nopar:Npn \__csvsim_gset_filename:Nn #1#2
+ {
+ \__csvsim_set_temp_filename:n { #2 }
+ \str_gset_eq:NN #1 \l__csvsim_temp_filename_str
+ }
+
+
+
+%---- keys
+
+\NewDocumentCommand \csvset { +m }
+ {
+ \keys_set:nn { csvsim } { #1 }
+ }
+
+
+\NewDocumentCommand \csvstyle { m +m }
+ {
+ \keys_define:nn { csvsim }
+ {
+ #1 .meta:n = { #2 }
+ }
+ }
+
+
+\NewDocumentCommand \csvnames { m m }
+ {
+ \keys_define:nn { csvsim }
+ {
+ #1 .meta:n = { column~names={#2} }
+ }
+ }
+
+
+\keys_define:nn { csvsim }
+ {
+ file .code:n = \__csvsim_gset_filename:Nn \g__csvsim_filename_str {#1},
+ column~names~reset .code:n = \tl_gclear:N \g__csvsim_columnnames_tl,
+ column~names .code:n =
+ {
+ \tl_if_empty:NTF \g__csvsim_columnnames_tl
+ {
+ \tl_gset:Nn \g__csvsim_columnnames_tl {#1}
+ }
+ {
+ \tl_gput_right:Nn \g__csvsim_columnnames_tl {,#1}
+ }
+ },
+ command .tl_gset:N = \g__csvsim_body_tl,
+ check~column~count .bool_gset:N = \g__csvsim_check_column_count_bool,
+ on~column~count~error .tl_gset:N = \g__csvsim_hook_columncounterror_tl,
+ head .bool_gset:N = \g__csvsim_head_bool,
+ head~to~column~names~prefix .tl_gset:N = \g__csvsim_headname_prefix_tl,
+ head~to~column~names .bool_gset:N = \g__csvsim_head_to_colnames_bool,
+ column~count .int_gset:N = \g_csvsim_columncount_int,
+ separator .choice:,
+ separator/comma .code:n =
+ {
+ \tl_gset:Nn \g__csvsim_separator_tl {,}
+ },
+ separator/semicolon .code:n =
+ {
+ \tl_gset:Nn \g__csvsim_separator_tl {;}
+ },
+ separator/pipe .code:n =
+ {
+ \tl_gset:Nn \g__csvsim_separator_tl {|}
+ },
+ separator/tab .code:n =
+ {
+ \tl_gset:NV \g__csvsim_separator_tl \c__csvsim_tab_str
+ \csvset{respect~tab}
+ },
+ every~csv .meta:n = {},
+ no~head .meta:n = { head=false },
+ no~check~column~count .meta:n = { check~column~count=false },
+ warn~on~column~count~error .meta:n = { on~column~count~error=
+ {
+ \msg_warning:nnxxxx { csvsimple }{ column-wrong-count }
+ { \int_use:N\g__csvsim_col_int }
+ { \int_use:N\g_csvsim_columncount_int }
+ { \int_use:N\g_csvsim_inputline_int }
+ { \g__csvsim_filename_str }
+ }},
+ }
+
+
+%---- hooks
+
+\keys_define:nn { csvsim }
+ {
+ before~reading .tl_gset:N = \g__csvsim_hook_before_reading_tl,
+ after~head .tl_gset:N = \g__csvsim_hook_after_head_tl,
+ before~filter .tl_gset:N = \g__csvsim_hook_before_filter_tl,
+ late~after~head .tl_gset:N = \g__csvsim_hook_late_after_head_tl,
+ late~after~first~line .tl_gset:N = \g__csvsim_hook_late_after_first_line_tl,
+ late~after~last~line .tl_gset:N = \g__csvsim_hook_late_after_last_line_tl,
+ before~first~line .tl_gset:N = \g__csvsim_hook_before_first_line_tl,
+ after~first~line .tl_gset:N = \g__csvsim_hook_after_first_line_tl,
+ after~reading .tl_gset:N = \g__csvsim_hook_after_reading_tl,
+ late~after~line .code:n =
+ {
+ \tl_gset:Nn \g__csvsim_hook_late_after_line_tl {#1}
+ \tl_gset_eq:NN \g__csvsim_hook_late_after_first_line_tl \g__csvsim_hook_late_after_line_tl
+ \tl_gset_eq:NN \g__csvsim_hook_late_after_last_line_tl \g__csvsim_hook_late_after_line_tl
+ },
+ before~line .code:n =
+ {
+ \tl_gset:Nn \g__csvsim_hook_before_line_tl {#1}
+ \tl_gset_eq:NN \g__csvsim_hook_before_first_line_tl \g__csvsim_hook_before_line_tl
+ },
+ after~line .code:n =
+ {
+ \tl_gset:Nn \g__csvsim_hook_after_line_tl {#1}
+ \tl_gset_eq:NN \g__csvsim_hook_after_first_line_tl \g__csvsim_hook_after_line_tl
+ },
+ }
+
+
+%---- filter
+
+\cs_new_protected_nopar:Npn \__csvsim_set_filter:n #1
+ {
+ \tl_gset:Nn \g__csvsim_filter_tl
+ {
+ #1
+ }
+ }
+
+
+\NewDocumentCommand \csvfilteraccept { }
+ {
+ \__csvsim_set_filter:n
+ {
+ \bool_gset_true:N \g__csvsim_line_accepted_bool
+ }
+ }
+
+
+\NewDocumentCommand \csvfilterreject { }
+ {
+ \__csvsim_set_filter:n
+ {
+ \bool_gset_false:N \g__csvsim_line_accepted_bool
+ }
+ }
+
+
+\keys_define:nn { csvsim }
+ {
+ no~filter .code:n =
+ {
+ \csvfilteraccept
+ },
+ filter~reject~all .code:n =
+ {
+ \csvfilterreject
+ },
+ filter~accept~all .code:n =
+ {
+ \csvfilteraccept
+ },
+ full~filter. tl_gset:N = \g__csvsim_hook_before_filter_tl,
+ filter~test .code:n =
+ {
+ \__csvsim_set_filter:n
+ {
+ #1
+ { \bool_gset_true:N \g__csvsim_line_accepted_bool }
+ { \bool_gset_false:N \g__csvsim_line_accepted_bool }
+ }
+ },
+ filter~bool .code:n =
+ {
+ \__csvsim_set_filter:n
+ {
+ \bool_gset:Nn \g__csvsim_line_accepted_bool { #1 }
+ }
+ },
+ filter~fp .code:n =
+ {
+ \__csvsim_set_filter:n
+ {
+ \bool_gset:Nn \g__csvsim_line_accepted_bool { \fp_compare_p:n{#1} }
+ }
+ },
+ filter~strcmp .meta:n = { filter~test=\ifcsvstrcmp #1 },
+ filter~not~strcmp .meta:n = { filter~test=\ifcsvnotstrcmp #1 },
+ }
+
+
+\NewDocumentCommand \csvfilterbool { m m }
+ {
+ \keys_define:nn { csvsim }
+ {
+ #1 .meta:n = { filter~bool={#2} }
+ }
+ }
+
+
+% ifthen
+\keys_define:nn { csvsim }
+ {
+ filter~ifthen .code:n =
+ {
+ \__csvsim_set_filter:n
+ {
+ \ifthenelse{#1}
+ { \bool_gset_true:N \g__csvsim_line_accepted_bool }
+ { \bool_gset_false:N \g__csvsim_line_accepted_bool }
+ }
+ },
+ filter~equal .meta:n = { filter~ifthen=\equal #1 },
+ filter~not~equal .meta:n = { filter~ifthen=\not\equal #1 },
+ }
+
+
+% etoolbox
+\keys_define:nn { csvsim }
+ {
+ filter~expr .code:n =
+ {
+ \__csvsim_set_filter:n
+ {
+ \ifboolexpr{#1}
+ { \bool_gset_true:N \g__csvsim_line_accepted_bool }
+ { \bool_gset_false:N \g__csvsim_line_accepted_bool }
+ }
+ },
+ }
+
+
+
+%---- range
+
+
+\cs_new_protected_nopar:Npn \__csvsim_add_range:n #1
+ {
+ \tl_if_in:nnTF {#1}{-}
+ {
+ \seq_set_split:Nnn \l_tmpa_seq {-} {#1}
+ \seq_pop_left:NN \l_tmpa_seq \l_tmpa_tl
+ \seq_pop_left:NN \l_tmpa_seq \l_tmpb_tl
+ \tl_if_empty:NTF \l_tmpa_tl
+ {
+ \int_set_eq:NN \l_tmpa_int \c_one_int
+ }
+ {
+ \int_set:Nn \l_tmpa_int { \l_tmpa_tl }
+ }
+ \tl_if_empty:NTF \l_tmpb_tl
+ {
+ \int_set_eq:NN \l_tmpb_int \c_max_int
+ }
+ {
+ \int_set:Nn \l_tmpb_int { \l_tmpb_tl }
+ }
+ }
+ {
+ \tl_if_in:nnTF {#1}{+}
+ {
+ \seq_set_split:Nnn \l_tmpa_seq {+} {#1}
+ \seq_pop_left:NN \l_tmpa_seq \l_tmpa_tl
+ \seq_pop_left:NN \l_tmpa_seq \l_tmpb_tl
+ \tl_if_empty:NTF \l_tmpa_tl
+ {
+ \int_set:Nn \l_tmpa_int { 1 }
+ }
+ {
+ \int_set:Nn \l_tmpa_int { \l_tmpa_tl }
+ }
+ \tl_if_empty:NTF \l_tmpb_tl
+ {
+ \int_set_eq:NN \l_tmpb_int \l_tmpa_int
+ }
+ {
+ \int_set:Nn \l_tmpb_int { \l_tmpa_int + \l_tmpb_tl - 1 }
+ }
+ }
+ {
+ \int_set:Nn \l_tmpa_int {#1}
+ \int_set_eq:NN \l_tmpb_int \l_tmpa_int
+ }
+ }
+ \seq_gput_right:Nx \g__csvsim_range_seq {{\int_use:N \l_tmpa_int}{\int_use:N \l_tmpb_int}}
+ }
+
+
+\cs_new_protected_nopar:Npn \__csvsim_set_range:n #1
+ {
+ \seq_gclear:N \g__csvsim_range_seq
+ \keyval_parse:NNn
+ \__csvsim_add_range:n
+ \use_none:nn
+ { #1 }
+ }
+
+
+\keys_define:nn { csvsim }
+ {
+ range .code:n =
+ {
+ \__csvsim_set_range:n {#1}
+ },
+ }
+
+
+\prg_new_conditional:Npnn \__csvsim_if_in_range:nn #1#2 { p , T }
+ {
+ \if_int_compare:w #1 > \g_csvsim_row_int
+ \prg_return_false:
+ \else:
+ \if_int_compare:w #2 < \g_csvsim_row_int
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ \fi:
+ }
+
+
+\cs_new_protected_nopar:Npn \__csvsim_check_range:
+ {
+ \seq_if_empty:NF \g__csvsim_range_seq
+ {
+ \bool_gset_false:N \g__csvsim_line_accepted_bool
+ \seq_map_inline:Nn \g__csvsim_range_seq
+ {
+ \__csvsim_if_in_range:nnT ##1
+ {
+ \bool_gset_true:N \g__csvsim_line_accepted_bool
+ \seq_map_break:
+ }
+ }
+ }
+ }
+
+
+
+%---- catcodes
+
+\cs_new_protected_nopar:Npn \__csvsim_setup_catcode_list:
+ {
+ \tl_gclear:N \g__csvsim_catcode_tl
+ \bool_if:NT \l__csvsim_respect_tab_bool
+ {
+ \tl_gput_right:Nn \g__csvsim_catcode_tl { \char_set_catcode_other:n { 9 } }
+ }
+ \bool_if:NT \l__csvsim_respect_percent_bool
+ {
+ \tl_gput_right:Nn \g__csvsim_catcode_tl { \char_set_catcode_other:n { 37 } }
+ }
+ \bool_if:NT \l__csvsim_respect_sharp_bool
+ {
+ \tl_gput_right:Nn \g__csvsim_catcode_tl { \char_set_catcode_other:n { 35 } }
+ }
+ \bool_if:NT \l__csvsim_respect_dollar_bool
+ {
+ \tl_gput_right:Nn \g__csvsim_catcode_tl { \char_set_catcode_other:n { 36 } }
+ }
+ \bool_if:NT \l__csvsim_respect_and_bool
+ {
+ \tl_gput_right:Nn \g__csvsim_catcode_tl { \char_set_catcode_other:n { 38 } }
+ }
+ \bool_if:NT \l__csvsim_respect_backslash_bool
+ {
+ \tl_gput_right:Nn \g__csvsim_catcode_tl { \char_set_catcode_other:n { 92 } }
+ }
+ \bool_if:NT \l__csvsim_respect_underscore_bool
+ {
+ \tl_gput_right:Nn \g__csvsim_catcode_tl { \char_set_catcode_other:n { 95 } }
+ }
+ \bool_if:NT \l__csvsim_respect_tilde_bool
+ {
+ \tl_gput_right:Nn \g__csvsim_catcode_tl { \char_set_catcode_other:n { 126 } }
+ }
+ \bool_if:NT \l__csvsim_respect_circumflex_bool
+ {
+ \tl_gput_right:Nn \g__csvsim_catcode_tl { \char_set_catcode_other:n { 94 } }
+ }
+ \bool_if:NT \l__csvsim_respect_leftbrace_bool
+ {
+ \tl_gput_right:Nn \g__csvsim_catcode_tl { \char_set_catcode_other:n { 123 } }
+ }
+ \bool_if:NT \l__csvsim_respect_rightbrace_bool
+ {
+ \tl_gput_right:Nn \g__csvsim_catcode_tl { \char_set_catcode_other:n { 125 } }
+ }
+ }
+
+
+\keys_define:nn { csvsim }
+ {
+ respect~tab .bool_set:N = \l__csvsim_respect_tab_bool,
+ respect~percent .bool_set:N = \l__csvsim_respect_percent_bool,
+ respect~sharp .bool_set:N = \l__csvsim_respect_sharp_bool,
+ respect~dollar .bool_set:N = \l__csvsim_respect_dollar_bool,
+ respect~and .bool_set:N = \l__csvsim_respect_and_bool,
+ respect~backslash .bool_set:N = \l__csvsim_respect_backslash_bool,
+ respect~underscore .bool_set:N = \l__csvsim_respect_underscore_bool,
+ respect~tilde .bool_set:N = \l__csvsim_respect_tilde_bool,
+ respect~circumflex .bool_set:N = \l__csvsim_respect_circumflex_bool,
+ respect~leftbrace .bool_set:N = \l__csvsim_respect_leftbrace_bool,
+ respect~rightbrace .bool_set:N = \l__csvsim_respect_rightbrace_bool,
+ respect~all .meta:n =
+ {
+ respect~tab, respect~percent, respect~sharp, respect~dollar,
+ respect~and, respect~backslash, respect~underscore, respect~tilde,
+ respect~circumflex, respect~leftbrace, respect~rightbrace
+ },
+ respect~none .meta:n =
+ {
+ respect~tab=false, respect~percent=false, respect~sharp=false,
+ respect~dollar=false, respect~and=false, respect~backslash=false,
+ respect~underscore=false, respect~tilde=false, respect~circumflex=false,
+ respect~leftbrace=false, respect~rightbrace=false
+ },
+ }
+
+
+
+%---- tables
+
+\cs_new_protected_nopar:Npn \__csvsim_key_table:nn #1#2
+ {
+ \tl_gset:Nn \g__csvsim_hook_table_begin_tl {#1}
+ \tl_gset:Nn \g__csvsim_hook_table_end_tl {#2}
+ }
+
+
+\keys_define:nn { csvsim }
+ {
+ before~table .tl_gset:N = \g__csvsim_before_table_tl,
+ after~table .tl_gset:N = \g__csvsim_after_table_tl,
+ table~head .tl_gset:N = \g__csvsim_table_head_tl,
+ table~foot .tl_gset:N = \g__csvsim_table_foot_tl,
+ _table_ .code:n = \__csvsim_key_table:nn #1,
+ no~table .meta:n = { _table_={}{} },
+ tabular .meta:n =
+ {
+ _table_ = { \g__csvsim_before_table_tl\begin{tabular}{#1}\g__csvsim_table_head_tl }
+ { \g__csvsim_table_foot_tl\end{tabular}\g__csvsim_after_table_tl },
+ late~after~line = \\
+ },
+ centered~tabular .meta:n =
+ {
+ _table_ = { \begin{center}\g__csvsim_before_table_tl\begin{tabular}{#1}\g__csvsim_table_head_tl }
+ { \g__csvsim_table_foot_tl\end{tabular}\g__csvsim_after_table_tl\end{center} },
+ late~after~line = \\
+ },
+ longtable .meta:n =
+ {
+ _table_ = { \g__csvsim_before_table_tl\begin{longtable}{#1}\g__csvsim_table_head_tl }
+ { \g__csvsim_table_foot_tl\end{longtable}\g__csvsim_after_table_tl },
+ late~after~line = \\
+ },
+ tabbing .meta:n =
+ {
+ _table_ = { \g__csvsim_before_table_tl\begin{tabbing}\g__csvsim_table_head_tl }
+ { \g__csvsim_table_foot_tl\end{tabbing}\g__csvsim_after_table_tl },
+ late~after~line = \\,
+ late~after~last~line =
+ },
+ centered~tabbing .meta:n =
+ {
+ _table_ = { \begin{center}\g__csvsim_before_table_tl\begin{tabbing}\g__csvsim_table_head_tl }
+ { \g__csvsim_table_foot_tl\end{tabbing}\g__csvsim_after_table_tl\end{center} },
+ late~after~line = \\,
+ late~after~last~line =
+ },
+ _autotab_ .meta:n =
+ {
+ file = #1,
+ late~after~line = \\,
+ command = \csvlinetotablerow
+ },
+ _autotabular_ .meta:n =
+ {
+ _autotab_ = #1,
+ late~after~last~line = \g__csvsim_table_foot_tl
+ \end{tabular}
+ \g__csvsim_after_table_tl,
+ },
+ autotabular .meta:n =
+ {
+ _autotabular_ = #1,
+ head,
+ after~head = \g__csvsim_before_table_tl
+ \begin{tabular}{|*{\int_use:N\g__csvsim_col_int}{l|}}
+ \g__csvsim_table_head_tl,
+ table~head = \hline\csvlinetotablerow\\\hline,
+ table~foot = \\\hline,
+ },
+ autotabular* .meta:n =
+ {
+ _autotabular_ = #1,
+ no~head,
+ before~first~line = \g__csvsim_before_table_tl
+ \begin{tabular}{|*{\int_use:N\g__csvsim_col_int}{l|}}
+ \g__csvsim_table_head_tl,
+ table~head = \hline,
+ table~foot = \\\hline,
+ },
+ autobooktabular .meta:n =
+ {
+ _autotabular_ = #1,
+ head,
+ after~head = \g__csvsim_before_table_tl
+ \begin{tabular}{*{\int_use:N\g__csvsim_col_int}{l}}
+ \g__csvsim_table_head_tl,
+ table~head = \toprule\csvlinetotablerow\\\midrule,
+ table~foot = \\\bottomrule,
+ },
+ autobooktabular* .meta:n =
+ {
+ _autotabular_ = #1,
+ no~head,
+ before~first~line = \g__csvsim_before_table_tl
+ \begin{tabular}{*{\int_use:N\g__csvsim_col_int}{l}}
+ \g__csvsim_table_head_tl,
+ table~head = \toprule,
+ table~foot = \\\bottomrule,
+ },
+ _autolongtable_ .meta:n =
+ {
+ _autotab_ = #1,
+ late~after~last~line = \end{longtable}
+ \g__csvsim_after_table_tl,
+ },
+ autolongtable .meta:n =
+ {
+ _autolongtable_ = #1,
+ head,
+ after~head = \g__csvsim_before_table_tl
+ \begin{longtable}{|*{\int_use:N\g__csvsim_col_int}{l|}}
+ \g__csvsim_table_head_tl,
+ table~head = \hline\csvlinetotablerow\\\hline\endhead
+ \hline\endfoot,
+ },
+ autolongtable* .meta:n =
+ {
+ _autolongtable_ = #1,
+ no~head,
+ before~first~line = \g__csvsim_before_table_tl
+ \begin{longtable}{|*{\int_use:N\g__csvsim_col_int}{l|}}
+ \g__csvsim_table_head_tl,
+ table~head = \hline\endhead
+ \hline\endfoot,
+ },
+ autobooklongtable .meta:n =
+ {
+ _autolongtable_ = #1,
+ head,
+ after~head = \g__csvsim_before_table_tl
+ \begin{longtable}{*{\int_use:N\g__csvsim_col_int}{l}}
+ \g__csvsim_table_head_tl,
+ table~head = \toprule\csvlinetotablerow\\\midrule\endhead
+ \bottomrule\endfoot,
+ },
+ autobooklongtable* .meta:n =
+ {
+ _autolongtable_ = #1,
+ no~head,
+ before~first~line = \g__csvsim_before_table_tl
+ \begin{longtable}{*{\int_use:N\g__csvsim_col_int}{l}}
+ \g__csvsim_table_head_tl,
+ table~head = \toprule\endhead
+ \bottomrule\endfoot,
+ },
+ }
+
+
+\NewDocumentCommand \csvautotabular { s +O{} m }
+ {
+ \IfBooleanTF {#1}
+ {
+ \keys_set:nn { csvsim } { default, every~csv, autotabular*={#3}, #2}
+ }
+ {
+ \keys_set:nn { csvsim } { default, every~csv, autotabular={#3}, #2}
+ }
+ \__csvsim_loop:
+ }
+
+
+\NewDocumentCommand \csvautolongtable { s +O{} m }
+ {
+ \IfBooleanTF {#1}
+ {
+ \keys_set:nn { csvsim } { default, every~csv, autolongtable*={#3}, #2}
+ }
+ {
+ \keys_set:nn { csvsim } { default, every~csv, autolongtable={#3}, #2}
+ }
+ \__csvsim_loop:
+ }
+
+
+\NewDocumentCommand \csvautobooktabular { s +O{} m }
+ {
+ \IfBooleanTF {#1}
+ {
+ \keys_set:nn { csvsim } { default, every~csv, autobooktabular*={#3}, #2}
+ }
+ {
+ \keys_set:nn { csvsim } { default, every~csv, autobooktabular={#3}, #2}
+ }
+ \__csvsim_loop:
+ }
+
+
+\NewDocumentCommand \csvautobooklongtable { s +O{} m }
+ {
+ \IfBooleanTF {#1}
+ {
+ \keys_set:nn { csvsim } { default, every~csv, autobooklongtable*={#3}, #2}
+ }
+ {
+ \keys_set:nn { csvsim } { default, every~csv, autobooklongtable={#3}, #2}
+ }
+ \__csvsim_loop:
+ }
+
+
+
+%---- sorting
+
+\cs_new_protected_nopar:Npn \__csvsim_key_new_sorting_rule:nn #1#2
+ {
+ \keys_define:nn { csvsim }
+ {
+ sort~by~#1 .meta:n = { sort~by={#2} },
+ }
+ }
+
+
+\NewDocumentCommand \csvsortingrule { }
+ {
+ \__csvsim_key_new_sorting_rule:nn
+ }
+
+
+\keys_define:nn { csvsim }
+ {
+ preprocessor .tl_gset:N = \l__csvsim_preprocessor_tl,
+ preprocessed~file .code:n = \__csvsim_set_filename:Nn \l__csvsim_ppfilename_str {#1},
+ csvsorter~command .code:n = \__csvsim_set_filename:Nn \l__csvsim_csvsorter_command_str {#1},
+ csvsorter~configpath .code:n = \__csvsim_set_filename:Nn\l__csvsim_csvsorter_configpath_str {#1},
+ csvsorter~log .code:n = \__csvsim_set_filename:Nn \l__csvsim_csvsorter_log_str {#1},
+ csvsorter~token .code:n = \__csvsim_set_filename:Nn \l__csvsim_csvsorter_token_str {#1},
+ no~preprocessing .meta:n = { preprocessor= },
+ sort~by .meta:n =
+ {
+ preprocessor=
+ {
+ \__csvsim_processor_csvsorter:nnn {#1}
+ }
+ },
+ new~sorting~rule .code:n = \__csvsim_key_new_sorting_rule:nn #1,
+ new~sorting~rule .value_required:n = true ,
+}
+
+
+\keys_set:nn { csvsim }
+ {
+ preprocessed~file = \c_sys_jobname_str _sorted._csv,
+ csvsorter~command = csvsorter,
+ csvsorter~configpath = .,
+ csvsorter~log = csvsorter.log,
+ csvsorter~token = \c_sys_jobname_str.csvtoken,
+ }
+
+
+\cs_new_protected_nopar:Npn \__csvsim_processor_csvsorter:nnn #1#2#3
+ {
+ \sys_if_shell_unrestricted:TF
+ {
+ \__csvsim_set_temp_filename:n { #1 }
+ \msg_note:nnxx { csvsimple }{ sort-info }{ #2 }{ \l__csvsim_temp_filename_str }
+ \cs_if_exist:NF \g__csvsim_iow
+ {
+ \iow_new:N \g__csvsim_iow
+ }
+ \iow_open:Nn \g__csvsim_iow { \l__csvsim_csvsorter_token_str }
+ \iow_now:Nn \g__csvsim_iow { \ExplSyntaxOn \msg_error:nn { csvsimple }{ sort-error } \ExplSyntaxOff }
+ \iow_close:N \g__csvsim_iow
+ \sys_shell_now:x
+ {
+ "\l__csvsim_csvsorter_command_str" \c_space_tl
+ -c~ "\l__csvsim_csvsorter_configpath_str/\l__csvsim_temp_filename_str" \c_space_tl
+ -l~ "\l__csvsim_csvsorter_log_str" \c_space_tl
+ -t~ "\l__csvsim_csvsorter_token_str" \c_space_tl
+ -i~ "#2" \c_space_tl
+ -o~ "#3" \c_space_tl
+ -q~1
+ }
+ \file_input:n { \l__csvsim_csvsorter_token_str }
+ }
+ {
+ \msg_error:nn { csvsimple }{ sort-shell-escape }
+ }
+ }
+
+
+
+%---- default
+
+\keys_define:nn { csvsim }
+ {
+ % default for reset
+ default .meta:n =
+ {
+ file = unknown.csv,
+ no~preprocessing,
+ command = \csvline,
+ column~names~reset,
+ head,
+ check~column~count,
+ head~to~column~names~prefix = ,
+ head~to~column~names = false,
+ column~count = 0,
+ 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,
+ respect~none,
+ },
+ }
+
+\keys_set:nn { csvsim }
+ {
+ default
+ }
diff --git a/Master/texmf-dist/tex/latex/csvsimple/csvsimple-legacy.sty b/Master/texmf-dist/tex/latex/csvsimple/csvsimple-legacy.sty
new file mode 100644
index 00000000000..53a30ab9e36
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/csvsimple/csvsimple-legacy.sty
@@ -0,0 +1,795 @@
+%% The LaTeX package csvsimple - version 2.0.0 (2021/06/29)
+%% csvsimple-legacy.sty: Simple LaTeX CSV file processing (LaTeX2e)
+%%
+%% -------------------------------------------------------------------------------------------
+%% 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
+%%
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{csvsimple-legacy}[2021/06/29 version 2.0.0 LaTeX2e CSV file processing]
+
+
+%---- check package
+\ExplSyntaxOn
+\cs_if_exist:NT \c__csvsim_package_expl_bool
+ {
+ \msg_new:nnn { csvsimple }{ legacy / package-loaded }
+ { Package~'csvsimple-l3'~seems~already~be~loaded!~
+ 'csvsimple-legacy'~cannot~be~loaded~simultaneously.~
+ Therefore,~loading~of~'csvsimple-legacy'~stops~now.}
+ \msg_warning:nn { csvsimple }{ legacy / package-loaded }
+ \tex_endinput:D
+ }
+\bool_const:Nn \c__csvsim_package_expl_bool { 0 }
+\ExplSyntaxOff
+
+
+
+\RequirePackage{pgfrcs,pgfkeys,ifthen,etoolbox,shellesc}
+
+
+%---- general
+
+\def\csv@warning#1{\PackageWarning{csvsimple}{#1}}
+\def\csv@error#1#2{\PackageError{csvsimple}{#1}{#2}}
+
+\newread\csv@file
+\newcounter{csvinputline}
+\newcounter{csvrow}
+\newcounter{csvcol}
+
+\def\csv@empty{}
+
+\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@assemble@csvlinetotablerow{%
+ \global\c@csvcol 1\relax%
+ \xdef\csvlinetotablerow{\expandonce{\csname csvcol\romannumeral\c@csvcol\endcsname}}%
+ \ifnum\c@csvcol<\csv@columncount\relax%
+ \loop%
+ \global\advance\c@csvcol 1\relax%
+ \xappto\csvlinetotablerow{\noexpand&\expandonce{\csname csvcol\romannumeral\c@csvcol\endcsname}}%
+ \ifnum\c@csvcol<\csv@columncount\relax\repeat%
+ \fi%
+ \csvlinetotablerow%
+}
+
+
+%---- breaking lines
+
+% This command removes leading and trailing spaces from <Token>. 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@TrimBraces#1{\expandafter\csv@TrimBraces@#1\@nil{#1}}
+\def\csv@TrimBraces@#1\@nil#2{\def#2{#1}}
+
+\def\csv@breakline@kernel#1{%
+ \ifx\csv@termination#1\let\nextcol=\relax\else%
+ \let\nextcol=\csv@breakline%
+ \global\advance\c@csvcol 1\relax%
+ \def\csv@col@body{#1}%
+ \csv@TrimSpaces\csv@col@body%
+ \csv@TrimBraces\csv@col@body%
+ \toks@\expandafter{\csv@col@body}%
+ \expandafter\xdef\csname csvcol\romannumeral\c@csvcol\endcsname{\the\toks@}%
+ \fi%
+ \nextcol%
+}
+
+% comma
+\def\csv@breakline@A#1,{\csv@breakline@kernel{#1}}
+
+\def\csv@scanline@A#1{%
+ \global\c@csvcol 0\relax%
+ \csv@breakline#1,\csv@termination,%
+}
+
+% semi colon
+\def\csv@breakline@B#1;{\csv@breakline@kernel{#1}}
+
+\def\csv@scanline@B#1{%
+ \global\c@csvcol 0\relax%
+ \csv@breakline#1;\csv@termination;%
+}
+
+% pipe
+\def\csv@breakline@C#1|{\csv@breakline@kernel{#1}}
+
+\def\csv@scanline@C#1{%
+ \global\c@csvcol 0\relax%
+ \csv@breakline#1|\csv@termination|%
+}
+
+% tab
+\catcode`\^^I=12
+\def\csv@breakline@D#1^^I{\csv@breakline@kernel{#1}}
+
+\def\csv@scanline@D#1{%
+ \global\c@csvcol 0\relax%
+ \csv@breakline#1^^I\csv@termination^^I%
+}
+\catcode`\^^I=10
+
+% expands a CSV line and scans content
+\def\csv@escanline#1{%
+ \toks@\expandafter{#1}%
+ \edef\@csv@scanline{\noexpand\csv@scanline{\the\toks@}}%
+ \@csv@scanline%
+}
+
+{
+ \catcode`\"=12%
+ \gdef\csv@passivquotes{"}
+}
+
+\newwrite\csv@out
+
+\def\csv@preprocessor@csvsorter#1#2#3{%
+ \begingroup%
+ \typeout{<sort \csv@passivquotes#2\csv@passivquotes\space by \csv@passivquotes#1\csv@passivquotes>}%
+ \immediate\openout\csv@out=\csv@csvsorter@token%
+ \immediate\write\csv@out{\string\makeatletter\string\csv@error{Call of CSV-Sorter failed! Use '-shell-escape' option or check log file '\csv@csvsorter@log'.}{}}%
+ \immediate\closeout\csv@out%
+ \ShellEscape{\csv@csvsorter@command\space
+ -c \csv@passivquotes#1\csv@passivquotes\space
+ -l \csv@passivquotes\csv@csvsorter@log\csv@passivquotes\space
+ -t \csv@passivquotes\csv@csvsorter@token\csv@passivquotes\space
+ -i \csv@passivquotes#2\csv@passivquotes\space
+ -o \csv@passivquotes#3\csv@passivquotes\space -q 1}%
+ \input{\csv@csvsorter@token}%
+ \endgroup%
+}
+
+
+\def\csv@preprocss@none{%
+ \let\csv@input@filename=\csv@filename%
+}
+
+\def\csv@preprocss@procedure{%
+ \csv@preprocessor{\csv@filename}{\csv@ppfilename}%
+ \let\csv@input@filename=\csv@ppfilename%
+}
+
+
+%---- the loop
+
+\def\csv@AtEndLoop{\gappto\@endloophook}
+\let\@endloophook\csv@empty
+
+\def\csv@current@col{\csname csvcol\romannumeral\c@csvcol\endcsname}
+
+% auto head names
+\def\set@csv@autohead{%
+ \toks0=\expandafter{\csname\csv@headnameprefix\csv@current@col\endcsname}%
+ \toks1=\expandafter{\csname csvcol\romannumeral\c@csvcol\endcsname}%
+ \begingroup\edef\csv@temp{\endgroup\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\romannumeral\c@csvcol\endcsname}%
+ \begingroup\edef\csv@temp{\endgroup\noexpand\pgfkeysdef{/csv head/\csv@current@col}{\the\toks0{\the\toks1}\noexpand\csv@AtEndLoop{\the\toks0{}}}}%
+ \csv@temp%
+ \begingroup\edef\csv@temp{\endgroup\noexpand\pgfkeysdef{/csv head/\thecsvcol}{\the\toks0{\the\toks1}\noexpand\csv@AtEndLoop{\the\toks0{}}}}%
+ \csv@temp%
+}
+
+% head line
+\def\csv@processheadline{%
+ \csvreadnext%
+ \ifx\csv@par\csvline\relax%
+ \csv@error{File '\csv@input@filename' starts with an empty line!}{}%
+ \else\csv@escanline{\csvline}%
+ \fi%
+ \xdef\csv@columncount{\thecsvcol}%
+ \global\c@csvcol 0\relax%
+ \loop%
+ \global\advance\c@csvcol 1\relax%
+ \csv@opt@headtocolumnames%
+ \set@csv@head%
+ \ifnum\c@csvcol<\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\romannumeral\c@csvcol\endcsname}%
+ \begingroup\edef\csv@temp{\endgroup\noexpand\pgfkeysdef{/csv head/\thecsvcol}{\the\toks0{\the\toks1}\noexpand\csv@AtEndLoop{\the\toks0{}}}}%
+ \csv@temp%
+}
+
+% no head line
+\def\csv@noheadline{%
+ \global\c@csvcol 0\relax%
+ \loop%
+ \global\advance\c@csvcol 1\relax%
+ \set@csv@nohead%
+ \ifnum\c@csvcol<\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\c@csvcol=\csv@columncount\relax%
+ \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\relax%
+ \csv@do@postline%
+}
+
+\gdef\csvreadnext{%
+ \global\read\csv@file to\csvline%
+ \stepcounter{csvinputline}%
+}
+
+\def\csv@par{\par}
+
+% reads and processes a CSV file
+\long\def\csvloop#1{%
+ % reset
+ \global\let\@endloophook\csv@empty%
+ \global\let\csvlinetotablerow\csv@assemble@csvlinetotablerow%
+ % options
+ \csvset{default,every csv,#1}%
+ \csv@preprocss%
+ \csv@set@catcodes%
+ \csv@prereading%
+ \csv@table@begin%
+ \setcounter{csvinputline}{0}%
+ % start reading
+ \openin\csv@file=\csv@input@filename\relax%
+ \ifeof\csv@file%
+ \csv@error{File '\csv@input@filename' 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%
+ \ifx\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%
+ \csv@reset@catcodes%
+}
+
+% 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/.code={\gdef\csv@preprocessor{#1}\let\csv@preprocss=\csv@preprocss@procedure},%
+ no preprocessing/.code={\let\csv@preprocss=\csv@preprocss@none},
+ 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/.is choice,%
+ check column count/.default=true,%
+ check column count/true/.code={\global\let\csv@opt@checkcolumncount=\csv@checkcolumncount},%
+ check column count/false/.code={\global\let\csv@opt@checkcolumncount=\csv@nocheckcolumncount},%
+ on column count error/.gstore in=\csv@columncounterror,
+ head/.is choice,%
+ head/.default=true,%
+ head/true/.code={\global\let\csv@opt@processheadline=\csv@processheadline%
+ \pgfkeysalso{check column count}},%
+ head/false/.code={\global\let\csv@opt@processheadline=\csv@noheadline%
+ \pgfkeysalso{check column count=false,late after head=}},%
+ head to column names prefix/.store in=\csv@headnameprefix,%
+ head to column names/.is choice,%
+ head to column names/.default=true,%
+ head to column names/true/.code={\global\let\csv@opt@headtocolumnames=\set@csv@autohead},%
+ head to column names/false/.code={\global\let\csv@opt@headtocolumnames=\csv@empty},%
+ column count/.gstore in=\csv@columncount,%
+ filter/.code={\gdef\csv@iffilter{\ifthenelse{#1}}},
+ filter ifthen/.code={\gdef\csv@iffilter{\ifthenelse{#1}}},
+ filter test/.code={\gdef\csv@iffilter{#1}},
+ filter expr/.code={\gdef\csv@iffilter{\ifboolexpr{#1}}},
+ no filter/.code={\csvfilteraccept},
+ filter reject all/.code={\csvfilterreject},
+ filter accept all/.code={\csvfilteraccept},
+ before filter/.gstore in=\csv@prefiltercommand,
+ full 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},
+ separator/tab/.code={\global\let\csv@scanline=\csv@scanline@D%
+ \global\let\csv@breakline\csv@breakline@D%
+ \csvset{respect tab}},
+ %
+ csvsorter command/.store in=\csv@csvsorter@command,
+ csvsorter configpath/.store in=\csv@csvsorter@configpath,
+ sort by/.style={preprocessor={\csv@preprocessor@csvsorter{\csv@csvsorter@configpath/#1}}},
+ new sorting rule/.style 2 args={sort by #1/.style={sort by={#2}}},
+ csvsorter log/.store in=\csv@csvsorter@log,
+ csvsorter token/.store in=\csv@csvsorter@token,
+ csvsorter command=csvsorter,
+ csvsorter configpath=.,
+ preprocessed file={\jobname_sorted._csv},
+ csvsorter log={csvsorter.log},
+ csvsorter token={\jobname.csvtoken},
+ %
+ % default for reset
+ default/.style={
+ file=unknown.csv,
+ no preprocessing,
+ command=\csvline,
+ column names reset,
+ head,
+ head to column names prefix=,
+ 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 ifthen=\equal{#1}{#2}},
+ filter not equal/.style 2 args={filter ifthen=\not\equal{#1}{#2}},
+ filter strcmp/.style 2 args={filter test=\ifcsvstrcmp{#1}{#2}},
+ filter not strcmp/.style 2 args={filter test=\ifcsvnotstrcmp{#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},
+ autobooktabular/.style={
+ file=#1,
+ after head=\csv@pretable\begin{tabular}{*{\csv@columncount}{l}}\csv@tablehead,
+ table head=\toprule\csvlinetotablerow\\\midrule,
+ late after line=\\,
+ table foot=\\\bottomrule,
+ late after last line=\csv@tablefoot\end{tabular}\csv@posttable,
+ command=\csvlinetotablerow},
+ autobooklongtable/.style={
+ file=#1,
+ after head=\csv@pretable\begin{longtable}{*{\csv@columncount}{l}}\csv@tablehead,
+ table head=\toprule\csvlinetotablerow\\\midrule\endhead\bottomrule\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,
+}
+
+% catcodes
+\def\csv@set@catcodes{%
+ \csv@catcode@tab@set%
+ \csv@catcode@tilde@set%
+ \csv@catcode@circumflex@set%
+ \csv@catcode@underscore@set%
+ \csv@catcode@and@set%
+ \csv@catcode@sharp@set%
+ \csv@catcode@dollar@set%
+ \csv@catcode@backslash@set%
+ \csv@catcode@leftbrace@set%
+ \csv@catcode@rightbrace@set%
+ \csv@catcode@percent@set}
+
+\def\csv@reset@catcodes{\csv@catcode@percent@reset%
+ \csv@catcode@rightbrace@reset%
+ \csv@catcode@leftbrace@reset%
+ \csv@catcode@backslash@reset%
+ \csv@catcode@dollar@reset%
+ \csv@catcode@sharp@reset%
+ \csv@catcode@and@reset%
+ \csv@catcode@underscore@reset%
+ \csv@catcode@circumflex@reset%
+ \csv@catcode@tilde@reset%
+ \csv@catcode@tab@reset%
+}
+
+
+\csvset{
+ respect tab/.is choice,
+ respect tab/true/.code={%
+ \gdef\csv@catcode@tab@set{%
+ \xdef\csv@catcode@tab@value{\the\catcode`\^^I}%
+ \catcode`\^^I=12}%
+ \gdef\csv@catcode@tab@reset{\catcode`\^^I=\csv@catcode@tab@value}},
+ respect tab/false/.code={%
+ \global\let\csv@catcode@tab@set\csv@empty%
+ \global\let\csv@catcode@tab@reset\csv@empty},
+ respect tab/.default=true,
+ %
+ respect percent/.is choice,
+ respect percent/true/.code={%
+ \gdef\csv@catcode@percent@set{%
+ \xdef\csv@catcode@percent@value{\the\catcode`\%}%
+ \catcode`\%=12}%
+ \gdef\csv@catcode@percent@reset{\catcode`\%=\csv@catcode@percent@value}},
+ respect percent/false/.code={%
+ \global\let\csv@catcode@percent@set\csv@empty%
+ \global\let\csv@catcode@percent@reset\csv@empty},
+ respect percent/.default=true,
+ %
+ respect sharp/.is choice,
+ respect sharp/true/.code={%
+ \gdef\csv@catcode@sharp@set{%
+ \xdef\csv@catcode@sharp@value{\the\catcode`\#}%
+ \catcode`\#=12}%
+ \gdef\csv@catcode@sharp@reset{\catcode`\#=\csv@catcode@sharp@value}},
+ respect sharp/false/.code={%
+ \global\let\csv@catcode@sharp@set\csv@empty%
+ \global\let\csv@catcode@sharp@reset\csv@empty},
+ respect sharp/.default=true,
+ %
+ respect dollar/.is choice,
+ respect dollar/true/.code={%
+ \gdef\csv@catcode@dollar@set{%
+ \xdef\csv@catcode@dollar@value{\the\catcode`\$}%
+ \catcode`\$=12}%
+ \gdef\csv@catcode@dollar@reset{\catcode`\$=\csv@catcode@dollar@value}},
+ respect dollar/false/.code={%
+ \global\let\csv@catcode@dollar@set\csv@empty%
+ \global\let\csv@catcode@dollar@reset\csv@empty},
+ respect dollar/.default=true,
+ %
+ respect and/.is choice,
+ respect and/true/.code={%
+ \gdef\csv@catcode@and@set{%
+ \xdef\csv@catcode@and@value{\the\catcode`\&}%
+ \catcode`\&=12}%
+ \gdef\csv@catcode@and@reset{\catcode`\&=\csv@catcode@and@value}},
+ respect and/false/.code={%
+ \global\let\csv@catcode@and@set\csv@empty%
+ \global\let\csv@catcode@and@reset\csv@empty},
+ respect and/.default=true,
+ %
+ respect backslash/.is choice,
+ respect backslash/true/.code={%
+ \gdef\csv@catcode@backslash@set{%
+ \xdef\csv@catcode@backslash@value{\the\catcode`\\}%
+ \catcode`\\=12}%
+ \gdef\csv@catcode@backslash@reset{\catcode`\\=\csv@catcode@backslash@value}},
+ respect backslash/false/.code={%
+ \global\let\csv@catcode@backslash@set\csv@empty%
+ \global\let\csv@catcode@backslash@reset\csv@empty},
+ respect backslash/.default=true,
+ %
+ respect underscore/.is choice,
+ respect underscore/true/.code={%
+ \gdef\csv@catcode@underscore@set{%
+ \xdef\csv@catcode@underscore@value{\the\catcode`\_}%
+ \catcode`\_=12}%
+ \gdef\csv@catcode@underscore@reset{\catcode`\_=\csv@catcode@underscore@value}},
+ respect underscore/false/.code={%
+ \global\let\csv@catcode@underscore@set\csv@empty%
+ \global\let\csv@catcode@underscore@reset\csv@empty},
+ respect underscore/.default=true,
+ %
+ respect tilde/.is choice,
+ respect tilde/true/.code={%
+ \gdef\csv@catcode@tilde@set{%
+ \xdef\csv@catcode@tilde@value{\the\catcode`\~}%
+ \catcode`\~=12}%
+ \gdef\csv@catcode@tilde@reset{\catcode`\~=\csv@catcode@tilde@value}},
+ respect tilde/false/.code={%
+ \global\let\csv@catcode@tilde@set\csv@empty%
+ \global\let\csv@catcode@tilde@reset\csv@empty},
+ respect tilde/.default=true,
+ %
+ respect circumflex/.is choice,
+ respect circumflex/true/.code={%
+ \gdef\csv@catcode@circumflex@set{%
+ \xdef\csv@catcode@circumflex@value{\the\catcode`\^}%
+ \catcode`\^=12}%
+ \gdef\csv@catcode@circumflex@reset{\catcode`\^=\csv@catcode@circumflex@value}},
+ respect circumflex/false/.code={%
+ \global\let\csv@catcode@circumflex@set\csv@empty%
+ \global\let\csv@catcode@circumflex@reset\csv@empty},
+ respect circumflex/.default=true,
+ %
+ respect leftbrace/.is choice,
+ respect leftbrace/true/.code={%
+ \gdef\csv@catcode@leftbrace@set{%
+ \xdef\csv@catcode@leftbrace@value{\the\catcode`\{}%
+ \catcode`\{=12}%
+ \gdef\csv@catcode@leftbrace@reset{\catcode`\{=\csv@catcode@leftbrace@value}},
+ respect leftbrace/false/.code={%
+ \global\let\csv@catcode@leftbrace@set\csv@empty%
+ \global\let\csv@catcode@leftbrace@reset\csv@empty},
+ respect leftbrace/.default=true,
+ %
+ respect rightbrace/.is choice,
+ respect rightbrace/true/.code={%
+ \gdef\csv@catcode@rightbrace@set{%
+ \xdef\csv@catcode@rightbrace@value{\the\catcode`\}}%
+ \catcode`\}=12}%
+ \gdef\csv@catcode@rightbrace@reset{\catcode`\}=\csv@catcode@rightbrace@value}},
+ respect rightbrace/false/.code={%
+ \global\let\csv@catcode@rightbrace@set\csv@empty%
+ \global\let\csv@catcode@rightbrace@reset\csv@empty},
+ respect rightbrace/.default=true,
+ %
+ respect all/.style={respect tab,respect percent,respect sharp,respect dollar,
+ respect and,respect backslash,respect underscore,respect tilde,respect circumflex,
+ respect leftbrace,respect rightbrace},
+ respect none/.style={respect tab=false,respect percent=false,respect sharp=false,
+ respect dollar=false,respect and=false,respect backslash=false,
+ respect underscore=false,respect tilde=false,respect circumflex=false,
+ respect leftbrace=false,respect rightbrace=false},
+ respect none
+}
+
+
+\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[]}}
+
+\long\def\csv@autobooktabular[#1]#2{\csvloop{autobooktabular={#2},#1}}
+
+\def\csvautobooktabular{%
+ \@ifnextchar[{\csv@autobooktabular}{\csv@autobooktabular[]}}
+
+
+\long\def\csv@autobooklongtable[#1]#2{\csvloop{autobooklongtable={#2},#1}}
+
+\def\csvautobooklongtable{%
+ \@ifnextchar[{\csv@autobooklongtable}{\csv@autobooklongtable[]}}
+
+
+\def\csvstyle#1#2{\csvset{#1/.style={#2}}}
+
+\def\csvnames#1#2{\csvset{#1/.style={column names={#2}}}}
+
+% string comparison
+
+\newrobustcmd{\ifcsvstrequal}[2]{%
+ \begingroup%
+ \edef\csv@tempa{#1}%
+ \edef\csv@tempb{#2}%
+ \ifx\csv@tempa\csv@tempb%
+ \aftergroup\@firstoftwo%
+ \else%
+ \aftergroup\@secondoftwo%
+ \fi%
+ \endgroup%
+}%
+
+\newrobustcmd{\ifcsvprostrequal}[2]{%
+ \begingroup%
+ \protected@edef\csv@tempa{#1}%
+ \protected@edef\csv@tempb{#2}%
+ \ifx\csv@tempa\csv@tempb%
+ \aftergroup\@firstoftwo%
+ \else%
+ \aftergroup\@secondoftwo%
+ \fi%
+ \endgroup%
+}%
+
+\AtBeginDocument{%
+ \ifdefined\pdfstrcmp%
+ \let\csv@strcmp\pdfstrcmp%
+ \else\ifdefined\pdf@strcmp%
+ \let\csv@strcmp\pdf@strcmp%
+ \fi\fi%
+ \ifdefined\csv@strcmp%
+ \newrobustcmd{\ifcsvstrcmp}[2]{%
+ \ifnum\csv@strcmp{#1}{#2}=\z@\relax%
+ \expandafter\@firstoftwo%
+ \else%
+ \expandafter\@secondoftwo%
+ \fi%
+ }%
+ \else%
+ \let\ifcsvstrcmp\ifcsvstrequal%
+ \fi%
+}
+
+\newrobustcmd{\ifcsvnotstrcmp}[4]{\ifcsvstrcmp{#1}{#2}{#4}{#3}}
diff --git a/Master/texmf-dist/tex/latex/csvsimple/csvsimple.sty b/Master/texmf-dist/tex/latex/csvsimple/csvsimple.sty
index 98d1a328668..def091859f7 100644
--- a/Master/texmf-dist/tex/latex/csvsimple/csvsimple.sty
+++ b/Master/texmf-dist/tex/latex/csvsimple/csvsimple.sty
@@ -1,4 +1,4 @@
-%% The LaTeX package csvsimple - version 1.22 (2021/06/07)
+%% The LaTeX package csvsimple - version 2.0.0 (2021/06/29)
%% csvsimple.sty: Simple LaTeX CSV file processing
%%
%% -------------------------------------------------------------------------------------------
@@ -15,766 +15,35 @@
%%
%% This work has the LPPL maintenance status `author-maintained'.
%%
-%% This work consists of all files listed in README
+%% This work consists of all files listed in README.md
%%
-\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{csvsimple}[2021/06/07 version 1.22 LaTeX CSV file processing]
-
-\RequirePackage{pgfrcs,pgfkeys,ifthen,etoolbox,shellesc}
-
-
-%---- general
-
-\def\csv@warning#1{\PackageWarning{csvsimple}{#1}}
-\def\csv@error#1#2{\PackageError{csvsimple}{#1}{#2}}
-
-\newread\csv@file
-\newcounter{csvinputline}
-\newcounter{csvrow}
-\newcounter{csvcol}
-
-\def\csv@empty{}
-
-\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@assemble@csvlinetotablerow{%
- \global\c@csvcol 1\relax%
- \xdef\csvlinetotablerow{\expandonce{\csname csvcol\romannumeral\c@csvcol\endcsname}}%
- \ifnum\c@csvcol<\csv@columncount\relax%
- \loop%
- \global\advance\c@csvcol 1\relax%
- \xappto\csvlinetotablerow{\noexpand&\expandonce{\csname csvcol\romannumeral\c@csvcol\endcsname}}%
- \ifnum\c@csvcol<\csv@columncount\relax\repeat%
- \fi%
- \csvlinetotablerow%
-}
-
-
-%---- breaking lines
-
-% This command removes leading and trailing spaces from <Token>. 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@TrimBraces#1{\expandafter\csv@TrimBraces@#1\@nil{#1}}
-\def\csv@TrimBraces@#1\@nil#2{\def#2{#1}}
-
-\def\csv@breakline@kernel#1{%
- \ifx\csv@termination#1\let\nextcol=\relax\else%
- \let\nextcol=\csv@breakline%
- \global\advance\c@csvcol 1\relax%
- \def\csv@col@body{#1}%
- \csv@TrimSpaces\csv@col@body%
- \csv@TrimBraces\csv@col@body%
- \toks@\expandafter{\csv@col@body}%
- \expandafter\xdef\csname csvcol\romannumeral\c@csvcol\endcsname{\the\toks@}%
- \fi%
- \nextcol%
-}
-
-% comma
-\def\csv@breakline@A#1,{\csv@breakline@kernel{#1}}
-
-\def\csv@scanline@A#1{%
- \global\c@csvcol 0\relax%
- \csv@breakline#1,\csv@termination,%
-}
-
-% semi colon
-\def\csv@breakline@B#1;{\csv@breakline@kernel{#1}}
-
-\def\csv@scanline@B#1{%
- \global\c@csvcol 0\relax%
- \csv@breakline#1;\csv@termination;%
-}
-
-% pipe
-\def\csv@breakline@C#1|{\csv@breakline@kernel{#1}}
-
-\def\csv@scanline@C#1{%
- \global\c@csvcol 0\relax%
- \csv@breakline#1|\csv@termination|%
-}
-
-% tab
-\catcode`\^^I=12
-\def\csv@breakline@D#1^^I{\csv@breakline@kernel{#1}}
-
-\def\csv@scanline@D#1{%
- \global\c@csvcol 0\relax%
- \csv@breakline#1^^I\csv@termination^^I%
-}
-\catcode`\^^I=10
-
-% expands a CSV line and scans content
-\def\csv@escanline#1{%
- \toks@\expandafter{#1}%
- \edef\@csv@scanline{\noexpand\csv@scanline{\the\toks@}}%
- \@csv@scanline%
-}
-
-{
- \catcode`\"=12%
- \gdef\csv@passivquotes{"}
-}
-
-\newwrite\csv@out
-
-\def\csv@preprocessor@csvsorter#1#2#3{%
- \begingroup%
- \typeout{<sort \csv@passivquotes#2\csv@passivquotes\space by \csv@passivquotes#1\csv@passivquotes>}%
- \immediate\openout\csv@out=\csv@csvsorter@token%
- \immediate\write\csv@out{\string\makeatletter\string\csv@error{Call of CSV-Sorter failed! Use '-shell-escape' option or check log file '\csv@csvsorter@log'.}{}}%
- \immediate\closeout\csv@out%
- \ShellEscape{\csv@csvsorter@command\space
- -c \csv@passivquotes#1\csv@passivquotes\space
- -l \csv@passivquotes\csv@csvsorter@log\csv@passivquotes\space
- -t \csv@passivquotes\csv@csvsorter@token\csv@passivquotes\space
- -i \csv@passivquotes#2\csv@passivquotes\space
- -o \csv@passivquotes#3\csv@passivquotes\space -q 1}%
- \input{\csv@csvsorter@token}%
- \endgroup%
-}
-
-
-\def\csv@preprocss@none{%
- \let\csv@input@filename=\csv@filename%
-}
-
-\def\csv@preprocss@procedure{%
- \csv@preprocessor{\csv@filename}{\csv@ppfilename}%
- \let\csv@input@filename=\csv@ppfilename%
-}
-
-
-%---- the loop
-
-\def\csv@AtEndLoop{\gappto\@endloophook}
-\let\@endloophook\csv@empty
-
-\def\csv@current@col{\csname csvcol\romannumeral\c@csvcol\endcsname}
-
-% auto head names
-\def\set@csv@autohead{%
- \toks0=\expandafter{\csname\csv@headnameprefix\csv@current@col\endcsname}%
- \toks1=\expandafter{\csname csvcol\romannumeral\c@csvcol\endcsname}%
- \begingroup\edef\csv@temp{\endgroup\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\romannumeral\c@csvcol\endcsname}%
- \begingroup\edef\csv@temp{\endgroup\noexpand\pgfkeysdef{/csv head/\csv@current@col}{\the\toks0{\the\toks1}\noexpand\csv@AtEndLoop{\the\toks0{}}}}%
- \csv@temp%
- \begingroup\edef\csv@temp{\endgroup\noexpand\pgfkeysdef{/csv head/\thecsvcol}{\the\toks0{\the\toks1}\noexpand\csv@AtEndLoop{\the\toks0{}}}}%
- \csv@temp%
-}
-
-% head line
-\def\csv@processheadline{%
- \csvreadnext%
- \ifx\csv@par\csvline\relax%
- \csv@error{File '\csv@input@filename' starts with an empty line!}{}%
- \else\csv@escanline{\csvline}%
- \fi%
- \xdef\csv@columncount{\thecsvcol}%
- \global\c@csvcol 0\relax%
- \loop%
- \global\advance\c@csvcol 1\relax%
- \csv@opt@headtocolumnames%
- \set@csv@head%
- \ifnum\c@csvcol<\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\romannumeral\c@csvcol\endcsname}%
- \begingroup\edef\csv@temp{\endgroup\noexpand\pgfkeysdef{/csv head/\thecsvcol}{\the\toks0{\the\toks1}\noexpand\csv@AtEndLoop{\the\toks0{}}}}%
- \csv@temp%
-}
-
-% no head line
-\def\csv@noheadline{%
- \global\c@csvcol 0\relax%
- \loop%
- \global\advance\c@csvcol 1\relax%
- \set@csv@nohead%
- \ifnum\c@csvcol<\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\c@csvcol=\csv@columncount\relax%
- \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\relax%
- \csv@do@postline%
-}
-
-\gdef\csvreadnext{%
- \global\read\csv@file to\csvline%
- \stepcounter{csvinputline}%
-}
-
-\def\csv@par{\par}
-
-% reads and processes a CSV file
-\long\def\csvloop#1{%
- % reset
- \global\let\@endloophook\csv@empty%
- \global\let\csvlinetotablerow\csv@assemble@csvlinetotablerow%
- % options
- \csvset{default,every csv,#1}%
- \csv@preprocss%
- \csv@set@catcodes%
- \csv@prereading%
- \csv@table@begin%
- \setcounter{csvinputline}{0}%
- % start reading
- \openin\csv@file=\csv@input@filename\relax%
- \ifeof\csv@file%
- \csv@error{File '\csv@input@filename' 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%
- \ifx\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%
- \csv@reset@catcodes%
-}
-
-% 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/.code={\gdef\csv@preprocessor{#1}\let\csv@preprocss=\csv@preprocss@procedure},%
- no preprocessing/.code={\let\csv@preprocss=\csv@preprocss@none},
- 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/.is choice,%
- check column count/.default=true,%
- check column count/true/.code={\global\let\csv@opt@checkcolumncount=\csv@checkcolumncount},%
- check column count/false/.code={\global\let\csv@opt@checkcolumncount=\csv@nocheckcolumncount},%
- on column count error/.gstore in=\csv@columncounterror,
- head/.is choice,%
- head/.default=true,%
- head/true/.code={\global\let\csv@opt@processheadline=\csv@processheadline%
- \pgfkeysalso{check column count}},%
- head/false/.code={\global\let\csv@opt@processheadline=\csv@noheadline%
- \pgfkeysalso{check column count=false,late after head=}},%
- head to column names prefix/.store in=\csv@headnameprefix,%
- head to column names/.is choice,%
- head to column names/.default=true,%
- head to column names/true/.code={\global\let\csv@opt@headtocolumnames=\set@csv@autohead},%
- head to column names/false/.code={\global\let\csv@opt@headtocolumnames=\csv@empty},%
- column count/.gstore in=\csv@columncount,%
- filter/.code={\gdef\csv@iffilter{\ifthenelse{#1}}},
- filter ifthen/.code={\gdef\csv@iffilter{\ifthenelse{#1}}},
- filter test/.code={\gdef\csv@iffilter{#1}},
- filter expr/.code={\gdef\csv@iffilter{\ifboolexpr{#1}}},
- no filter/.code={\csvfilteraccept},
- filter reject all/.code={\csvfilterreject},
- filter accept all/.code={\csvfilteraccept},
- before filter/.gstore in=\csv@prefiltercommand,
- full 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},
- separator/tab/.code={\global\let\csv@scanline=\csv@scanline@D%
- \global\let\csv@breakline\csv@breakline@D%
- \csvset{respect tab}},
- %
- csvsorter command/.store in=\csv@csvsorter@command,
- csvsorter configpath/.store in=\csv@csvsorter@configpath,
- sort by/.style={preprocessor={\csv@preprocessor@csvsorter{\csv@csvsorter@configpath/#1}}},
- new sorting rule/.style 2 args={sort by #1/.style={sort by={#2}}},
- csvsorter log/.store in=\csv@csvsorter@log,
- csvsorter token/.store in=\csv@csvsorter@token,
- csvsorter command=csvsorter,
- csvsorter configpath=.,
- preprocessed file={\jobname_sorted._csv},
- csvsorter log={csvsorter.log},
- csvsorter token={\jobname.csvtoken},
- %
- % default for reset
- default/.style={
- file=unknown.csv,
- no preprocessing,
- command=\csvline,
- column names reset,
- head,
- head to column names prefix=,
- 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 ifthen=\equal{#1}{#2}},
- filter not equal/.style 2 args={filter ifthen=\not\equal{#1}{#2}},
- filter strcmp/.style 2 args={filter test=\ifcsvstrcmp{#1}{#2}},
- filter not strcmp/.style 2 args={filter test=\ifcsvnotstrcmp{#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},
- autobooktabular/.style={
- file=#1,
- after head=\csv@pretable\begin{tabular}{*{\csv@columncount}{l}}\csv@tablehead,
- table head=\toprule\csvlinetotablerow\\\midrule,
- late after line=\\,
- table foot=\\\bottomrule,
- late after last line=\csv@tablefoot\end{tabular}\csv@posttable,
- command=\csvlinetotablerow},
- autobooklongtable/.style={
- file=#1,
- after head=\csv@pretable\begin{longtable}{*{\csv@columncount}{l}}\csv@tablehead,
- table head=\toprule\csvlinetotablerow\\\midrule\endhead\bottomrule\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,
-}
-
-% catcodes
-\def\csv@set@catcodes{%
- \csv@catcode@tab@set%
- \csv@catcode@tilde@set%
- \csv@catcode@circumflex@set%
- \csv@catcode@underscore@set%
- \csv@catcode@and@set%
- \csv@catcode@sharp@set%
- \csv@catcode@dollar@set%
- \csv@catcode@backslash@set%
- \csv@catcode@leftbrace@set%
- \csv@catcode@rightbrace@set%
- \csv@catcode@percent@set}
-
-\def\csv@reset@catcodes{\csv@catcode@percent@reset%
- \csv@catcode@rightbrace@reset%
- \csv@catcode@leftbrace@reset%
- \csv@catcode@backslash@reset%
- \csv@catcode@dollar@reset%
- \csv@catcode@sharp@reset%
- \csv@catcode@and@reset%
- \csv@catcode@underscore@reset%
- \csv@catcode@circumflex@reset%
- \csv@catcode@tilde@reset%
- \csv@catcode@tab@reset%
-}
-
-
-\csvset{
- respect tab/.is choice,
- respect tab/true/.code={%
- \gdef\csv@catcode@tab@set{%
- \xdef\csv@catcode@tab@value{\the\catcode`\^^I}%
- \catcode`\^^I=12}%
- \gdef\csv@catcode@tab@reset{\catcode`\^^I=\csv@catcode@tab@value}},
- respect tab/false/.code={%
- \global\let\csv@catcode@tab@set\csv@empty%
- \global\let\csv@catcode@tab@reset\csv@empty},
- respect tab/.default=true,
- %
- respect percent/.is choice,
- respect percent/true/.code={%
- \gdef\csv@catcode@percent@set{%
- \xdef\csv@catcode@percent@value{\the\catcode`\%}%
- \catcode`\%=12}%
- \gdef\csv@catcode@percent@reset{\catcode`\%=\csv@catcode@percent@value}},
- respect percent/false/.code={%
- \global\let\csv@catcode@percent@set\csv@empty%
- \global\let\csv@catcode@percent@reset\csv@empty},
- respect percent/.default=true,
- %
- respect sharp/.is choice,
- respect sharp/true/.code={%
- \gdef\csv@catcode@sharp@set{%
- \xdef\csv@catcode@sharp@value{\the\catcode`\#}%
- \catcode`\#=12}%
- \gdef\csv@catcode@sharp@reset{\catcode`\#=\csv@catcode@sharp@value}},
- respect sharp/false/.code={%
- \global\let\csv@catcode@sharp@set\csv@empty%
- \global\let\csv@catcode@sharp@reset\csv@empty},
- respect sharp/.default=true,
- %
- respect dollar/.is choice,
- respect dollar/true/.code={%
- \gdef\csv@catcode@dollar@set{%
- \xdef\csv@catcode@dollar@value{\the\catcode`\$}%
- \catcode`\$=12}%
- \gdef\csv@catcode@dollar@reset{\catcode`\$=\csv@catcode@dollar@value}},
- respect dollar/false/.code={%
- \global\let\csv@catcode@dollar@set\csv@empty%
- \global\let\csv@catcode@dollar@reset\csv@empty},
- respect dollar/.default=true,
- %
- respect and/.is choice,
- respect and/true/.code={%
- \gdef\csv@catcode@and@set{%
- \xdef\csv@catcode@and@value{\the\catcode`\&}%
- \catcode`\&=12}%
- \gdef\csv@catcode@and@reset{\catcode`\&=\csv@catcode@and@value}},
- respect and/false/.code={%
- \global\let\csv@catcode@and@set\csv@empty%
- \global\let\csv@catcode@and@reset\csv@empty},
- respect and/.default=true,
- %
- respect backslash/.is choice,
- respect backslash/true/.code={%
- \gdef\csv@catcode@backslash@set{%
- \xdef\csv@catcode@backslash@value{\the\catcode`\\}%
- \catcode`\\=12}%
- \gdef\csv@catcode@backslash@reset{\catcode`\\=\csv@catcode@backslash@value}},
- respect backslash/false/.code={%
- \global\let\csv@catcode@backslash@set\csv@empty%
- \global\let\csv@catcode@backslash@reset\csv@empty},
- respect backslash/.default=true,
- %
- respect underscore/.is choice,
- respect underscore/true/.code={%
- \gdef\csv@catcode@underscore@set{%
- \xdef\csv@catcode@underscore@value{\the\catcode`\_}%
- \catcode`\_=12}%
- \gdef\csv@catcode@underscore@reset{\catcode`\_=\csv@catcode@underscore@value}},
- respect underscore/false/.code={%
- \global\let\csv@catcode@underscore@set\csv@empty%
- \global\let\csv@catcode@underscore@reset\csv@empty},
- respect underscore/.default=true,
- %
- respect tilde/.is choice,
- respect tilde/true/.code={%
- \gdef\csv@catcode@tilde@set{%
- \xdef\csv@catcode@tilde@value{\the\catcode`\~}%
- \catcode`\~=12}%
- \gdef\csv@catcode@tilde@reset{\catcode`\~=\csv@catcode@tilde@value}},
- respect tilde/false/.code={%
- \global\let\csv@catcode@tilde@set\csv@empty%
- \global\let\csv@catcode@tilde@reset\csv@empty},
- respect tilde/.default=true,
- %
- respect circumflex/.is choice,
- respect circumflex/true/.code={%
- \gdef\csv@catcode@circumflex@set{%
- \xdef\csv@catcode@circumflex@value{\the\catcode`\^}%
- \catcode`\^=12}%
- \gdef\csv@catcode@circumflex@reset{\catcode`\^=\csv@catcode@circumflex@value}},
- respect circumflex/false/.code={%
- \global\let\csv@catcode@circumflex@set\csv@empty%
- \global\let\csv@catcode@circumflex@reset\csv@empty},
- respect circumflex/.default=true,
- %
- respect leftbrace/.is choice,
- respect leftbrace/true/.code={%
- \gdef\csv@catcode@leftbrace@set{%
- \xdef\csv@catcode@leftbrace@value{\the\catcode`\{}%
- \catcode`\{=12}%
- \gdef\csv@catcode@leftbrace@reset{\catcode`\{=\csv@catcode@leftbrace@value}},
- respect leftbrace/false/.code={%
- \global\let\csv@catcode@leftbrace@set\csv@empty%
- \global\let\csv@catcode@leftbrace@reset\csv@empty},
- respect leftbrace/.default=true,
- %
- respect rightbrace/.is choice,
- respect rightbrace/true/.code={%
- \gdef\csv@catcode@rightbrace@set{%
- \xdef\csv@catcode@rightbrace@value{\the\catcode`\}}%
- \catcode`\}=12}%
- \gdef\csv@catcode@rightbrace@reset{\catcode`\}=\csv@catcode@rightbrace@value}},
- respect rightbrace/false/.code={%
- \global\let\csv@catcode@rightbrace@set\csv@empty%
- \global\let\csv@catcode@rightbrace@reset\csv@empty},
- respect rightbrace/.default=true,
- %
- respect all/.style={respect tab,respect percent,respect sharp,respect dollar,
- respect and,respect backslash,respect underscore,respect tilde,respect circumflex,
- respect leftbrace,respect rightbrace},
- respect none/.style={respect tab=false,respect percent=false,respect sharp=false,
- respect dollar=false,respect and=false,respect backslash=false,
- respect underscore=false,respect tilde=false,respect circumflex=false,
- respect leftbrace=false,respect rightbrace=false},
- respect none
-}
-
-
-\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[]}}
-
-\long\def\csv@autobooktabular[#1]#2{\csvloop{autobooktabular={#2},#1}}
-
-\def\csvautobooktabular{%
- \@ifnextchar[{\csv@autobooktabular}{\csv@autobooktabular[]}}
-
-
-\long\def\csv@autobooklongtable[#1]#2{\csvloop{autobooklongtable={#2},#1}}
-
-\def\csvautobooklongtable{%
- \@ifnextchar[{\csv@autobooklongtable}{\csv@autobooklongtable[]}}
-
-
-\def\csvstyle#1#2{\csvset{#1/.style={#2}}}
-
-\def\csvnames#1#2{\csvset{#1/.style={column names={#2}}}}
-
-% string comparison
-
-\newrobustcmd{\ifcsvstrequal}[2]{%
- \begingroup%
- \protected@edef\csv@tempa{#1}%
- \protected@edef\csv@tempb{#2}%
- \edef\csv@tempa{#1}%
- \edef\csv@tempb{#2}%
- \ifx\csv@tempa\csv@tempb%
- \aftergroup\@firstoftwo%
- \else%
- \aftergroup\@secondoftwo%
- \fi%
- \endgroup%
-}%
-
-\newrobustcmd{\ifcsvprostrequal}[2]{%
- \begingroup%
- \protected@edef\csv@tempa{#1}%
- \protected@edef\csv@tempb{#2}%
- \ifx\csv@tempa\csv@tempb%
- \aftergroup\@firstoftwo%
- \else%
- \aftergroup\@secondoftwo%
- \fi%
- \endgroup%
-}%
-
-\AtBeginDocument{%
- \ifdefined\pdfstrcmp%
- \let\csv@strcmp\pdfstrcmp%
- \else\ifdefined\pdf@strcmp%
- \let\csv@strcmp\pdf@strcmp%
- \fi\fi%
- \ifdefined\csv@strcmp%
- \newrobustcmd{\ifcsvstrcmp}[2]{%
- \ifnum\csv@strcmp{#1}{#2}=\z@\relax%
- \expandafter\@firstoftwo%
- \else%
- \expandafter\@secondoftwo%
- \fi%
- }%
- \else%
- \let\ifcsvstrcmp\ifcsvstrequal%
- \fi%
-}
-
-\newrobustcmd{\ifcsvnotstrcmp}[4]{\ifcsvstrcmp{#1}{#2}{#4}{#3}}
+\RequirePackage{l3keys2e}
+
+\ProvidesExplPackage{csvsimple}{2021/06/29}{2.0.0}
+ {LaTeX CSV file processing}
+
+\cs_if_exist:NT \c__csvsim_package_expl_bool
+ {
+ \msg_new:nnn { csvsimple }{ package-loaded }
+ { Package~'#1'~seems~already~be~loaded! }
+ \bool_if:NTF \c__csvsim_package_expl_bool
+ {
+ \msg_warning:nn { csvsimple }{ package-loaded }{ csvsimple-l3 }
+ }
+ {
+ \msg_warning:nn { csvsimple }{ package-loaded }{ csvsimple-legacy }
+ }
+ \tex_endinput:D
+ }
+
+\keys_define:nn { csvsimple }
+ {
+ l3 .code:n = \tl_set:Nn \l__csvsim_package_expl_tl { l3 },
+ legacy .code:n = \tl_set:Nn \l__csvsim_package_expl_tl { legacy },
+ }
+
+\keys_set:nn { csvsimple } { legacy }
+
+\ProcessKeysPackageOptions { csvsimple }
+
+\RequirePackage{csvsimple-\l__csvsim_package_expl_tl}