简而言之:我见过使用 以编程方式创建表的代码tabular
。可以使用 来完成吗tabularx
?如果可以,怎么做?
我是一名数学老师,我想创建一个“问题集”环境,在其中我可以列出将被格式化为表格的问题。
此外,我希望环境有一个参数来指定表应具有的列数。这种模块化正是我更喜欢使用的原因tabularx
。
下面的代码受到我在这里读过的其他答案的启发,使用tabular
和几乎按照我的要求运行。包含该tabularx
包会导致下面的代码失败并出现错误Illegal pream-token
(更新:这是正确的陈述,尽管问题出在 中array
,它被 所使用tabularx
。)
我需要以下任何方面的帮助:
(1)我可以用tabularx
代替 吗tabular
?我需要做哪些改变才能做到这一点?
(2) 如果不是,我希望表格的宽度相同 ( \textwidth
),无论有多少列。此代码不是这样运行的。我在当前tabular
环境中做错了什么?
(3) 与表格创建无关,但也需要修复:我对这些项目的编号方案是使用计数器和\int_use:N
,但结果是排版输出始终具有计数器的最后一个值。就像我说的,我是 expl3 编程的新手;对我来说,这段代码看起来应该可以工作。
(4)当然,我也愿意接受有关更好的实现方法的建议。
谢谢大家!
代码:
\documentclass{article}
\usepackage{xparse}
\usepackage{environ}
\usepackage{lipsum}
\usepackage{tabularx}
\ExplSyntaxOn
\NewEnviron{problemset}[1]{\jermer_pset:V \BODY #1}
\seq_new:N \l_jermer_items_seq
\int_new:N \l_jermer_ncol_int
\int_new:N \l_jermer_ctr_int
\tl_new:N \l_jermer_tblpreamble_tl
\tl_new:N \l_jermer_tblcontent_tl
\cs_new_protected:Npn \jermer_pset:n #1 #2
{
\seq_set_split:Nnn \l_jermer_items_seq { \item } { #1 }
\seq_pop_left:NN \l_jermer_items_seq \l_tmpa_tl % remove empty element
\int_set:Nn \l_jermer_ncol_int { #2 }
\int_zero:N \l_jermer_ctr_int
\tl_clear:N \l_jermer_tblpreamble_tl
\tl_clear:N \l_jermer_tblcontent_tl
\seq_map_inline:Nn \l_jermer_items_seq
{
\int_incr:N \l_jermer_ctr_int
\tl_put_right:Nn \l_jermer_tblcontent_tl { \makebox[1.5em][r]{\__int_value:w \l_jermer_ctr_int}.~ ##1} % ??
\int_compare:nNnTF {\int_mod:nn {\l_jermer_ctr_int} {\l_jermer_ncol_int}} = {0}
{\tl_put_right:Nn \l_jermer_tblcontent_tl { \\ }}
{\tl_put_right:Nn \l_jermer_tblcontent_tl { & }}
}
\int_zero:N \l_jermer_ctr_int
\fp_new:N \l_jermer_wfrac_fp
\fp_set:Nn \l_jermer_wfrac_fp {1 / \l_jermer_ncol_int}
\tl_put_right:Nn \l_jermer_tblpreamble_tl { | }
\int_while_do:nn {\l_jermer_ctr_int < \l_jermer_ncol_int}
{
\tl_put_right:Nn \l_jermer_tblpreamble_tl { p{ \fp_to_decimal:N \l_jermer_wfrac_fp \textwidth} | } % Even col widths?
% \tl_put_right:Nn \l_jermer_tblpreamble_tl { X } % Would prefer this!
\int_incr:N \l_jermer_ctr_int
}
\jermer_draw_table:
}
\cs_generate_variant:Nn \jermer_pset:n { V }
\cs_new:Npn \jermer_draw_table:
{
\begin{center}
% Would prefer to use tabularx here.
\begin{tabular}{\l_jermer_tblpreamble_tl}
\tl_use:N \l_jermer_tblcontent_tl
\end{tabular}
\end{center}
}
\ExplSyntaxOff
\begin{document}
\noindent
\lipsum[1]
\begin{problemset}{3}
\item Alpha
\item Beta
\item Gamma
\item Delta
\item Epsilon
\item Zeta
\item Eta
\item Theta
\item Iota
\end{problemset}
\noindent
\lipsum[1]
\end{document}
答案1
以下解决方案也可以解决产品编号问题:
\documentclass{article}
\usepackage{xparse}
\usepackage{environ}
\usepackage{lipsum}
\usepackage{tabularx}
\ExplSyntaxOn
\NewEnviron{problemset}[1]{\jermer_pset:Vn \BODY {#1}}
\seq_new:N \l_jermer_items_seq
\int_new:N \l_jermer_ncol_int
\int_new:N \l_jermer_ctr_int
\tl_new:N \l_jermer_tblpreamble_tl
\tl_new:N \l_jermer_tblcontent_tl
\cs_new_protected:Npn \jermer_pset:nn #1 #2
{
\seq_set_split:Nnn \l_jermer_items_seq { \item } { #1 }
\seq_pop_left:NN \l_jermer_items_seq \l_tmpa_tl % remove empty element
\int_set:Nn \l_jermer_ncol_int { #2 }
\int_zero:N \l_jermer_ctr_int
\tl_clear:N \l_jermer_tblpreamble_tl
\tl_clear:N \l_jermer_tblcontent_tl
\seq_map_inline:Nn \l_jermer_items_seq
{
\int_incr:N \l_jermer_ctr_int
\tl_put_right:Nx \l_jermer_tblcontent_tl
{
\exp_not:N \makebox[1.5em][r]{\int_to_arabic:n { \l_jermer_ctr_int }}.~\exp_not:n {##1}
}
\int_compare:nTF {\int_mod:nn {\l_jermer_ctr_int} {\l_jermer_ncol_int} = 0 }
{\tl_put_right:Nn \l_jermer_tblcontent_tl { \\ }}
{\tl_put_right:Nn \l_jermer_tblcontent_tl { & }}
}
\tl_put_right:Nn \l_jermer_tblpreamble_tl { | }
\prg_replicate:nn { #2 } { \tl_put_right:Nn \l_jermer_tblpreamble_tl { X| } }
\jermer_draw_table:
}
\cs_generate_variant:Nn \jermer_pset:nn { V }
\cs_new:Npn \jermer_draw_table:
{
\begin{center}
% Would prefer to use tabularx here.
\use:x { \exp_not:n {\begin{tabularx}{\textwidth}}{\l_jermer_tblpreamble_tl}}
\tl_show:N \l_jermer_tblcontent_tl
\tl_use:N \l_jermer_tblcontent_tl
\end{tabularx}
\end{center}
}
\ExplSyntaxOff
\begin{document}
\noindent
\lipsum[1]
\begin{problemset}{3}
\item Alpha
\item Beta
\item Gamma
\item Delta
\item Epsilon
\item Zeta
\item Eta
\item Theta
\item Iota
\end{problemset}
\noindent
\lipsum[1]
\end{document}
\jermer_pset:nn
请注意二参数。我删除了一些特定于列宽计算的部分,因为tabularx
现在可以使用了(正如 David 所解释的那样,诀窍是扩展表格序言)。
答案2
不要怪我!:-)
问题不是加载,tabularx
而是加载array
(由使用tabularx
)并array
防止表格前言的过早扩展(以便在@
单元格中使用时扩展或> {...}`中的宏,而不是在构建前言时扩展。
因此,您需要在调用表时将宏扩展一个级别,可以使用 latex3 实用程序,也可以使用旧方法:
% Would prefer to use tabularx here.
\def\tmp{\begin{tabular}}%
\expandafter\tmp\expandafter{\l_jermer_tblpreamble_tl}