带有 tabularx 的 expl3 代码

带有 tabularx 的 expl3 代码

简而言之:我见过使用 以编程方式创建表的代码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}

相关内容