在我的 Latex 文档中,我定义了一个如下所示的嵌套列表:
\def\recipes{
{
test1@
test2@
test3@
test4@
test5a*test5b@
test6a*test6b
},
{
test1@
test2@
test3@
test4@
test5a*test5b@
test6a*test6b
}%
}
我不想在 Latex 文档中定义此列表,而是想从 CSV 文件中解析这些数据。我研究了各种库,但到目前为止,我只能找到从 CSV 文件制作表格的示例,或者我无法理解该示例。难道没有一种简单而明显的方法来转换上述列表中的 CSV 文件吗?
test1,test2,test3,test4,test5a*test5b,test6a*test6b
test1,test2,test3,test4,test5a*test5b,test6a*test6b
答案1
下面是使用 的实现expl3
。我尽力使生成的宏与您手动构建的宏完全相同,尽管可能有几个空格是不需要的。
\begin{filecontents*}{\jobname.csv}
test1,test2,test3,test4,test5a*test5b,test6a*test6b
test1,test2,test3,test4,test5a*test5b,test6a*test6b
\end{filecontents*}
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\makelistfromcsv}{mm}
{% #1 = control sequence, #2 = file name
\scm_listcsv_make:nn { #1 } { #2 }
}
\ior_new:N \g_scm_listcsv_input_ior
\clist_new:N \l__scm_listcsv_temp_in_clist
\clist_new:N \l__scm_listcsv_temp_out_clist
\tl_new:N \l__scm_listcsv_temp_tl
\cs_new_protected:Nn \scm_listcsv_make:nn
{
% clear the "out" clist
\clist_clear:N \l__scm_listcsv_temp_out_clist
% open the input csv file
\ior_open:Nn \g_scm_listcsv_input_ior { #2 }
% read one line at a time
\ior_map_inline:Nn \g_scm_listcsv_input_ior
{
% store the current line as a clist
\clist_set:Nn \l__scm_listcsv_temp_in_clist { ##1 }
% store the items to the temporary tl adding "@ space"
\tl_set:Nx \l__scm_listcsv_temp_tl { {{ ~ \clist_use:Nn \l__scm_listcsv_temp_in_clist { @~ } ~ }} }
% add the tokens as an item of the "out" clist
\clist_put_right:NV \l__scm_listcsv_temp_out_clist \l__scm_listcsv_temp_tl
}
% now build the final token list
\tl_new:N #1
\tl_set:Nx #1 { ~ \clist_use:Nn \l__scm_listcsv_temp_out_clist { , ~ } }
}
\ExplSyntaxOff
\def\recipes{
{
test1@
test2@
test3@
test4@
test5a*test5b@
test6a*test6b
},
{
test1@
test2@
test3@
test4@
test5a*test5b@
test6a*test6b
}%
}
\makelistfromcsv{\newrecipes}{\jobname.csv}
\ifx\recipes\newrecipes % are they equal?
\typeout{EQUAL :-D}
\else
\typeout{UNEQUAL :-(}
\fi
输出为
EQUAL :-D
这filecontents*
环境仅用于使示例自包含,您可以使用系统上的任何文件。
“无虚假空间”版本:
\begin{filecontents*}{\jobname.csv}
test1,test2,test3,test4,test5a*test5b,test6a*test6b
test1,test2,test3,test4,test5a*test5b,test6a*test6b
\end{filecontents*}
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\makelistfromcsv}{mm}
{% #1 = control sequence, #2 = file name
\scm_listcsv_make:nn { #1 } { #2 }
}
\ior_new:N \g_scm_listcsv_input_ior
\clist_new:N \l__scm_listcsv_temp_in_clist
\clist_new:N \l__scm_listcsv_temp_out_clist
\tl_new:N \l__scm_listcsv_temp_tl
\cs_new_protected:Nn \scm_listcsv_make:nn
{
% clear the "out" clist
\clist_clear:N \l__scm_listcsv_temp_out_clist
% open the input csv file
\ior_open:Nn \g_scm_listcsv_input_ior { #2 }
% read one line at a time
\ior_map_inline:Nn \g_scm_listcsv_input_ior
{
% store the current line as a clist
\clist_set:Nn \l__scm_listcsv_temp_in_clist { ##1 }
% store the items to the temporary tl adding "@"
\tl_set:Nx \l__scm_listcsv_temp_tl { {{\clist_use:Nn \l__scm_listcsv_temp_in_clist { @ } }} }
% add the tokens as an item of the "out" clist
\clist_put_right:NV \l__scm_listcsv_temp_out_clist \l__scm_listcsv_temp_tl
}
% now build the final token list
\tl_new:N #1
\tl_set:Nx #1 { \clist_use:Nn \l__scm_listcsv_temp_out_clist { , } }
}
\ExplSyntaxOff
\def\recipes{%
{%
test1@%
test2@%
test3@%
test4@%
test5a*test5b@%
test6a*test6b%
},%
{%
test1@%
test2@%
test3@%
test4@%
test5a*test5b@%
test6a*test6b%
}%
}
\makelistfromcsv{\newrecipes}{\jobname.csv}
\ifx\recipes\newrecipes % are they equal?
\typeout{EQUAL :-D}
\else
\typeout{UNEQUAL :-(}
\fi
使用此代码,替换文本\newrecipes
为
{test1@test2@test3@test4@test5a*test5b@test6a*test6b},{test1@test2@test3@test4@test5a*test5b@test6a*test6b}
没有空格。