我有一个文本文件中约 1000 个单词的列表。这些单词在文本文件中列出,"my_words.txt"
没有换行符,如下所示:
word1, word2, word3, etc.
我想在图形/表格中以垂直对齐(以及每列的中央对齐)显示这些单词,即
word1 word2 word3 word4
word5 word6 word7 word7
word8
我可以指定行数或列数,或者 LaTeX 根据我为表格指定的宽度计算出它们。
我以为 datatool 包可以帮助解决这个问题,但我无法让它工作。我试过:
\usepackage{datatool}
% ...
\begin{document}
% ...
\DTLsetseparator{,}
\DTLloaddb[noheader,keys={source,package,target,brokenpkg,impactset,brokensource}]{mytable}{full_concept_list.csv}
\begin{table}[htbp]
\centering
\DTLdisplaydb{mytable}
\caption{CSV Table test}
\end{table}
但我收到了错误:
Missing $ inserted
\DTLdisplaydb{mytable}
为什么 datatool 不起作用?还有其他更适合此任务的工具吗?
答案1
expl3
以下是Heiko Oberdiek 的方法catchfile
:
\documentclass{article}
\usepackage[T1]{fontenc} % for the underscore
\usepackage{catchfile}
\usepackage{xparse}
\ExplSyntaxOn
\cs_set_eq:NN \egreg_catchfiledef:nnn \CatchFileDef
\cs_generate_variant:Nn \egreg_catchfiledef:nnn { c }
\cs_generate_variant:Nn \seq_set_split:Nnn { Nnv }
\NewDocumentCommand{\storefile}{ m m } % #1 = symbolic name, #2 = file name
{
\egreg_catchfiledef:cnn { l_egreg_ #1 _list_tl } { #2 } { \char_set_catcode_other:N \_ }
}
\NewDocumentCommand{\printtable}{ m m } % #1 = number of columns, #2 = symbolic name
{
\egreg_printtable:nn { #1 } { #2 }
}
\tl_new:N \l_egreg_temp_table_tl
\seq_new:N \l_egreg_temp_list_seq
\int_new:N \l_egreg_col_count_int
\cs_new_protected:Npn \egreg_printtable:nn #1 #2
{
\seq_set_split:Nnv \l_egreg_temp_list_seq { , } { l_egreg_ #2 _list_tl }
\tl_clear:N \l_egreg_temp_table_tl
\int_zero:N \l_egreg_col_count_int
\seq_map_inline:Nn \l_egreg_temp_list_seq
{
\int_incr:N \l_egreg_col_count_int
\tl_put_right:Nn \l_egreg_temp_table_tl { ##1 }
\int_compare:nTF { \l_egreg_col_count_int = #1 }
{ \tl_put_right:Nn \l_egreg_temp_table_tl { \\ } \int_zero:N \l_egreg_col_count_int }
{ \tl_put_right:Nn \l_egreg_temp_table_tl { & } }
}
\begin{tabular}{*{#1}{c}}
\l_egreg_temp_table_tl
\end{tabular}
}
\ExplSyntaxOff
\begin{document}
\storefile{words}{my_words.txt}
\noindent Three words per line
\noindent\printtable{3}{words}
\bigskip
\noindent Five words per line
\noindent\printtable{5}{words}
\bigskip
\noindent Eight words per line
\noindent\printtable{8}{words}
\end{document}
将\storefile
文件内容存储在一个符号名称下(在本例中为words
)。然后\printtable
可以使用数据打印表格。
我们首先定义一个expl3
等价于的,\CatchFileDef
以便能够为其生成变体。然后\storefile
定义命令:它以单词列表的符号名称和文件名作为参数。它将整个文件存储在标记列表变量中(下划线将被吸收为可打印字符)。
获取\printtable
所需的列数和列表的符号名称作为参数。像往常一样,它只是被转换成函数调用。
该函数将与符号名称对应的标记列表以逗号分隔,并对由此获得的序列进行映射。在每一步中,我们都会递增一个计数器,并将单词添加到临时标记列表中;如果计数器的值不是列数,我们还会添加一个&
,否则我们添加\\
并将计数器重置为零。
最后,整个列表打印在 中。如果单词列表很长,tabular
您可能需要加载longtable
并更改tabular
为。longtable
为了在“行”和“列”顺序之间进行选择,您可以像这样修改它:
\documentclass{article}
\usepackage[T1]{fontenc} % for the underscore
\usepackage{catchfile,multicol}
\usepackage{xparse}
\ExplSyntaxOn
\cs_set_eq:NN \egreg_catchfiledef:nnn \CatchFileDef
\cs_generate_variant:Nn \egreg_catchfiledef:nnn { c }
\cs_generate_variant:Nn \seq_set_split:Nnn { Nnv }
\NewDocumentCommand{\storefile}{ m m } % #1 = symbolic name, #2 = file name
{
\egreg_catchfiledef:cnn { l_egreg_ #1 _list_tl } { #2 } { \char_set_catcode_other:N \_ }
}
\NewDocumentCommand{\printtable}{ s m m } % #2 = number of columns, #3 = symbolic name
{
\IfBooleanTF{#1}
{ \egreg_printtablev:nn { #2 } { #3 } }
{ \egreg_printtable:nn { #2 } { #3 } }
}
\tl_new:N \l_egreg_temp_table_tl
\seq_new:N \l_egreg_temp_list_seq
\int_new:N \l_egreg_col_count_int
\cs_new_protected:Npn \egreg_printtable:nn #1 #2
{
\seq_set_split:Nnv \l_egreg_temp_list_seq { , } { l_egreg_ #2 _list_tl }
\tl_clear:N \l_egreg_temp_table_tl
\int_zero:N \l_egreg_col_count_int
\seq_map_inline:Nn \l_egreg_temp_list_seq
{
\int_incr:N \l_egreg_col_count_int
\tl_put_right:Nn \l_egreg_temp_table_tl { ##1 }
\int_compare:nTF { \l_egreg_col_count_int = #1 }
{ \tl_put_right:Nn \l_egreg_temp_table_tl { \\ } \int_zero:N \l_egreg_col_count_int }
{ \tl_put_right:Nn \l_egreg_temp_table_tl { & } }
}
\begin{tabular}{*{#1}{c}}
\l_egreg_temp_table_tl
\end{tabular}
}
\cs_new_protected:Npn \egreg_printtablev:nn #1 #2
{
\seq_set_split:Nnv \l_egreg_temp_list_seq { , } { l_egreg_ #2 _list_tl }
\begin{multicols}{3}\centering
\seq_map_inline:Nn \l_egreg_temp_list_seq { ##1 \par }
\end{multicols}
}
\ExplSyntaxOff
\begin{document}
\storefile{words}{my_words.txt}
\noindent Three words per line
\noindent\printtable{3}{words}
\bigskip
\noindent Five words per line
\noindent\printtable{5}{words}
\bigskip
\noindent Three equispaced columns (column order)
\noindent\printtable*{14}{words}
\end{document}
答案2
\documentclass{article}
\makeatletter
\def\wordtable{{%
\everyeof{,\relax,}%
\dimen@\z@
\def\word@{\setbox\z@\hbox}%
\def\word@@{}%
\expandafter\@wordtable\@@input words.txt
\def\word@{\hbox to \dimen@}%
\def\word@@{ \hfill}%
\noindent\expandafter\@wordtable\@@input words.txt
}}
\def\@wordtable#1,{%
\ifx\relax#1\else
\word@{\ignorespaces#1\unskip\hfill}\word@@
\ifdim\dimen@<\wd\z@\dimen@\wd\z@\fi
\expandafter\@wordtable\fi}
\makeatother
\begin{document}
\wordtable
\end{document}
来自 Word 文件
red, yellow, blue, Automatically, formatting, a, table, from, a, file, with, a, list, of, words