我印象非常深刻xparse
和expl3
,并使用编写了一个精彩的文档命令,\ProcessList
该命令采用逗号分隔的列表并将其转换为(基本上)1 列表。
\stacky{A,B,C,D}
-> \begin{tabular}{rr}
\tiny 1st & A \\
\tiny 2nd & B \\
\tiny 3rd & C \\
\tiny 4th & D
\end{tabular}
现在我对这种能力已经着迷,想要一次指定多个列。例如:
\stacksy{ 5: A,B,C,D ; 6: A,C,D,B ; 3: C,A,B,D }
-> \begin{tabular}{rrrr}
& 5 & 6 & 3 \\ \hline
\tiny 1st & A & A & C \\
\tiny 2nd & B & C & A \\
\tiny 3rd & C & D & B \\
\tiny 4th & D & B & D \\
\end{tabular}
一切都很好,除了输入是按列主序排列的,但 TeX(或表格环境)需要按行主序排列。
如何转置列表的输入列表?
答案1
这是一种生成以列形式给出的数字的矩形数组的方法。
- 语法是第 i 列,其中条目以逗号分隔的列表形式给出
stacksys{col 1;col 2;...;col n}
。col i
- 我稍微摆弄了一下输入来展示如何引入列和行标题。
array
tabular
如果需要的话,可以更改为。\stacksys{,r1,r2;c1,1,2;c2,3,4;c3,5,6}
生成:
代码:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\int_new:N \l_ss_num_cols_int
\int_new:N \l_ss_num_rows_int
\bool_new:N \l_has_run_bool
\NewDocumentCommand{\stacksys} {m}
{
\ss_make_table:n {#1}
\int_step_inline:nnnn {1}{1}{\l_ss_num_rows_int}
{
\tl_put_right:cn {l_row_{##1}_tl}{\\}
}
\begin{array}{*{\int_use:N \l_ss_num_cols_int}{c}}
\int_step_inline:nnnn {1}{1}{\l_ss_num_rows_int}
{
\tl_use:c {l_row_{##1}_tl}
}
\end{array}
\bool_gset_false:N \l_has_run_bool
}
\cs_new_protected:Npn \ss_make_table:n #1
{
\seq_set_split:Nnn \l_tmpa_seq {;} {#1}
\int_set:Nn \l_ss_num_cols_int {\seq_count:N \l_tmpa_seq}
\seq_map_function:NN \l_tmpa_seq \ss_process_cols:n
}
\cs_new_protected:Npn \ss_process_cols:n #1
{
\int_zero:N \l_tmpa_int
\seq_set_split:Nnn \l_tmpb_seq {,} {#1}
\int_set:Nn \l_ss_num_rows_int {\seq_count:N \l_tmpb_seq}
\seq_map_inline:Nn \l_tmpb_seq
{
\bool_if:NTF \l_has_run_bool
{
\int_incr:N \l_tmpa_int
\tl_put_right:cn {l_row_{\int_use:N \l_tmpa_int}_tl} {&##1}
}
{
\int_incr:N \l_tmpa_int
\tl_clear_new:c {l_row_{\int_use:N \l_tmpa_int}_tl}
\tl_put_right:cn {l_row_{\int_use:N \l_tmpa_int}_tl} {##1}
}
}
\bool_gset_true:N \l_has_run_bool
}
\ExplSyntaxOff
\begin{document}
\[
\stacksys{,r1,r2;c1,1,2;c2,3,4;c3,5,6}
\]
\end{document}