自动创建表

自动创建表

我有下表,需要重新创建多次

在此处输入图片描述

由于其规模和复杂性(是的,我是 tex 新手),我正在研究如何自动创建该表。我尝试想办法实现自动化,但我的 tex-fu 太弱了,无法用它做任何事情。我最终想做的是以下

  • 拥有排版表格的命令或环境
  • 能够对三处(24、36 和 60)的点数进行求和并存储其值
  • 如果问题数量超过给定阈值(例如 10-12),则添加额外的一行。使用考试包不是一个选项,因为根据所述时间,它无法显示子问题的分数。现在我存储了所有问题的标签(oppgave = 问题,Poeng = 分数/分数),并且可以将它们称为 \label(1.1.a)、\label(1.1.b) 等。所以如果可能的话,使用这些值会很棒,但是我不知道如何将其变成循环。

我也可以输入每个问题的分数和数字,但随后我遇到了处理困难,exparse并且\SplitList命令理解起来相当复杂。尤其是当我不知道需要多少问题/行时。不过可以肯定的是,无论是第一部分还是第二部分,部分和子部分的数量都不会超过 36 个。

我还研究了使用 lat3x 语法来\ExplSyntaxOn获得类似的东西

\TypeSettable{ Del1 = 1a1,1a2,1a3, ... , PDel1 = 1,1,1,1, ... , Del2 = 2a, 2b ... }

这是我用来创建图像中的表格的代码

\documentclass[12pt,a4paper]{article}
\usepackage{xparse}
\usepackage{xstring}
\usepackage{booktabs}
\usepackage{mathtools}
\usepackage{tabularx}
\usepackage{multirow}
\usepackage{caption}
\begin{document}
\begin{table}
\caption*{\bf Gjeldende poengfordeling}
{ \noindent \begin{tabular*}{\textwidth}{@{}cl*{18}{@{\;}c@{\;}}}
  \toprule
  & & &  & & &  & & &  & & &  & & & & Sum  \\
  \cmidrule{1-1} \cmidrule(l){2-15} \cmidrule(l){16-17}
  \multirow{2}{*}{Del $1$} & & Oppgave &  $1$a  &  $1$b  &  $1$c
                                       &  $2$a  &  $2$b  &  $2$c 
                                       &  $3$a  &  $3$b  
                                       &  $4$a  &  $4$b  
                                       &  &       \\
                           & & Poeng   &  $1$   &  $1$   &  $1$       
                                       &  $1$   &  $2$   &  $2$  
                                       &  $2$   &  $2$     
                                       &  $2$   &  $2$   &        &      &  & $24$  \\
                             \cmidrule(l){1-17}
  \multirow{2}{*}{}        & &         &  $5$a  &  $5$b  
                                       &  $6$a  &  $6$b   
                                       &  $7$a  &  $7$b  &  &   &    &   &  &         \\
                           & &         &  $2$   &  $2$    
                                       &  $2$   &  $2$ 
                                       &  $2$   &  $2$   &  &   &    &   &  &        \\
  \cmidrule{1-1}\cmidrule(l){2-17}
  \multirow{2}{*}{Del $2$} & & Oppgave &  $1$a  &  $1$b  &  $1$c
                                       &  $2$a  &  $2$b  &  $2$c 
                                       &  $3$a  &  $3$b  &  $3$c \\
%                                      
                           & & Poeng   &  $2$   &  $2$   &  $2$
                                       &  $1$   &  $2$   &  $2$
                                       &  $2$   &  $3$   &  $2$ &   &    &  & &  $36$       \\
%                                       
  \cmidrule(l){1-17}
  \multirow{2}{*}{}        & &         & $4$a   &  $4$b  & $4$c   
                                       & $5$a   &  $5$b   
                                       & $6$a   &  $6$b  & $6$c &       &       &       &      &  &     \\
                           & &         & $3 $   &  $2$   & $3 $  
                                       & $2 $   &  $2$   
                                       & $2 $   &  $2$   & $2$ &       &       &       &      & &   &     \\
  \cmidrule(l){1-15}\cmidrule(l){16-17}
                                                                & \multicolumn{14}{r}{Total antall poeng} &  & $60$  \\
  \bottomrule
  \end{tabular*}}
\end{table}
\end{document}

我确实看过一些与自动创建表类似的问题,但没有什么真正让我印象深刻的=(

简而言之,我不知道自动化给定表的最佳路径是什么,但非常欢迎任何帮助、提示和想法!

答案1

这将创建与您的表相同的表。该\TypesetTable命令还有一个可选参数,用于设置列数的阈值,请参阅示例。

\documentclass{article}
\usepackage[a4paper,margin=1cm]{geometry}
\usepackage{xparse,booktabs}

\ExplSyntaxOn
\NewDocumentCommand{\TypesetTable}{ O{10} m }
 {
  \nebu_typeset_table:nn { #1 } { #2 }
 }

\keys_define:nn { nebutable }
 {
  Del1 .tl_set:N = \l__nebu_deli_tl,
  PDel1 .tl_set:N = \l__nebu_pdeli_tl,
  Del2 .tl_set:N = \l__nebu_delii_tl,
  PDel2 .tl_set:N = \l__nebu_pdelii_tl,
 }

\int_new:N \l__nebu_columns_int
\int_new:N \l__nebu_pdeli_total_int
\int_new:N \l__nebu_pdelii_total_int
\int_new:N \l_nebu_countrows_int
\seq_new:N \l__nebu_deli_seq
\seq_new:N \l__nebu_pdeli_seq
\seq_new:N \l__nebu_delii_seq
\seq_new:N \l__nebu_pdelii_seq
\tl_new:N \l__nebu_preamble_tl
\tl_new:N \l__nebu_table_body_tl

\cs_new_protected:Npn \nebu_typeset_table:nn #1 #2
 {
  \keys_set:nn { nebutable } { #2 }
  \seq_set_split:NnV \l__nebu_deli_seq { , } \l__nebu_deli_tl
  \seq_set_split:NnV \l__nebu_pdeli_seq { , } \l__nebu_pdeli_tl
  \seq_set_split:NnV \l__nebu_delii_seq { , } \l__nebu_delii_tl
  \seq_set_split:NnV \l__nebu_pdelii_seq { , } \l__nebu_pdelii_tl
  % Compute the number of inner columns
  \int_set:Nn \l__nebu_columns_int
   {
    \int_min:nn { #1 }
     {
      \int_max:nn { \seq_count:N \l__nebu_deli_seq }
                  { \seq_count:N \l__nebu_delii_seq }
     }
   }
  % Define the table preamble
  \tl_set:Nx \l__nebu_preamble_tl
   { l c *{ \int_to_arabic:n { \l__nebu_columns_int } } { c } c }
  % Compute the total for Del1
  \int_zero:N \l__nebu_pdeli_total_int
  \seq_map_inline:Nn \l__nebu_pdeli_seq
   { \int_set:Nn \l__nebu_pdeli_total_int { \l__nebu_pdeli_total_int + ##1 } }
  % Compute the total for Del2
  \int_zero:N \l__nebu_pdelii_total_int
  \seq_map_inline:Nn \l__nebu_pdelii_seq
   { \int_set:Nn \l__nebu_pdelii_total_int { \l__nebu_pdelii_total_int + ##1 } }
  % Start building the table contents
  \tl_clear:N \l__nebu_table_body_tl
  \tl_put_right:Nx \l__nebu_table_body_tl
   { \exp_not:N \multicolumn { \int_to_arabic:n { \l__nebu_columns_int + 2 } } { c } { } }
  \tl_put_right:Nn \l__nebu_table_body_tl { & Sum \\ \midrule }

  % Insert Del1
  \__nebu_insert_table_part:nn { deli } { Del~1 }
  \tl_put_right:Nn \l__nebu_table_body_tl { \midrule }
  % Insert Del2
  \__nebu_insert_table_part:nn { delii } { Del~2 }

  % Add total
  \tl_put_right:Nx \l__nebu_table_body_tl
   {
    \exp_not:N \midrule
    \exp_not:N \multicolumn
                { \int_to_arabic:n { 2 + \l__nebu_columns_int } }
                { r }
                { Total~antall~poeng }
    &
    \int_to_arabic:n { \l__nebu_pdeli_total_int + \l__nebu_pdelii_total_int }
    \exp_not:N \\
   }

  % Print the table
  \use:x{ \exp_not:N \begin{tabular}{\l__nebu_preamble_tl} }
  \toprule
  \l__nebu_table_body_tl
  \bottomrule
  \end{tabular}
}

\cs_new_protected:Npn \__nebu_insert_table_part:nn #1 #2
 {
  \int_set:Nn \l_nebu_countrows_int
   {
    \seq_count:c { l__nebu_#1_seq } / \l__nebu_columns_int
   }
  \int_step_inline:nnnn { 1 } { 1 } { \l_nebu_countrows_int }
   {
    % First line
    \int_compare:nTF { ##1 = 1 }
     {
      \tl_put_right:Nn \l__nebu_table_body_tl { #2 & Oppgave & }
     }
     {
      \tl_put_right:Nx \l__nebu_table_body_tl
       { \exp_not:N \cmidrule{3-\int_to_arabic:n { \l__nebu_columns_int + 3 }} }
      \tl_put_right:Nn \l__nebu_table_body_tl { & & }
     }
    \int_step_inline:nnnn 
     { (##1 - 1)*\l__nebu_columns_int + 1 } 
     { 1 }
     { ##1 * \l__nebu_columns_int }
     {
      \tl_put_right:Nx \l__nebu_table_body_tl 
       { \seq_item:cn { l__nebu_#1_seq } { ####1 } & }
     }
     \tl_put_right:Nn \l__nebu_table_body_tl { \\ }
     % Second line
    \int_compare:nTF { ##1 = 1 }
     { \tl_put_right:Nn \l__nebu_table_body_tl { & Poeng & } }
     { \tl_put_right:Nn \l__nebu_table_body_tl { & & } }
     \int_step_inline:nnnn 
      { (##1 - 1)*\l__nebu_columns_int + 1 }
      { 1 }
      { ##1 * \l__nebu_columns_int }
      {
       \tl_put_right:Nx \l__nebu_table_body_tl
        { \seq_item:cn { l__nebu_p#1_seq } { ####1 } & }
      }
      \tl_put_right:Nx \l__nebu_table_body_tl
       {
        \int_compare:nT { ##1 = 1 }
         { \int_to_arabic:n { \use:c { l__nebu_p#1_total_int } } }
        \exp_not:N \\
       }
   }
 }

\ExplSyntaxOff

\setlength{\parindent}{0pt} % just for the example

\begin{document}

\TypesetTable{
  Del1= {1a1,1a2,1a3,1b1,1b2,1b3,1c,1d1,1d2,1d3,1e1,1e2,1f,1g1,1g2,1g3},
  PDel1={1,  1,  1,  1,  2,  2,  2, 2,  0,  2,  2,  2,  2, 2,  2,  0},
  Del2= {2a,2b,2c,2d,2e,2f,3a1,3a2,3b,4a,4b,4c,4d,5a,5b,5c,6a,6b},
  PDel2={2, 2, 2, 2, 2, 2, 2,  2,  3, 2, 2, 2, 2, 1, 2, 2, 2, 2}
}

\bigskip

\TypesetTable[8]{
  Del1= {1a1,1a2,1a3,1b1,1b2,1b3,1c,1d1,1d2,1d3,1e1,1e2,1f,1g1,1g2,1g3},
  PDel1={1,  1,  1,  1,  2,  2,  2, 2,  0,  2,  2,  2,  2, 2,  2,  0},
  Del2= {2a,2b,2c,2d,2e,2f,3a1,3a2,3b,4a,4b,4c,4d,5a,5b,5c,6a,6b},
  PDel2={2, 2, 2, 2, 2, 2, 2,  2,  3, 2, 2, 2, 2, 1, 2, 2, 2, 2}
}


\end{document}

在此处输入图片描述


这是一个新的实现,允许在文档中收集练习标签和成绩并在任何地方打印表格;由于它使用该.aux文件,因此需要两次运行才能稳定。

\addtoDel宏接收三个参数;第一个参数是 1 或 2(对于这两种类型),第二个参数是标签,第三个参数是等级。您可能会在宏中使用它来排版练习。

\TypesetTable命令只有一个可选参数来设置内部列的阈值数。

\documentclass{article}
\usepackage[a4paper,margin=1cm]{geometry}
\usepackage{xparse,booktabs}

\ExplSyntaxOn

\NewDocumentCommand{\TypesetTable} { O{10} }
 {
  \seq_if_empty:NT \g__nebu_deli_seq
   {
    \seq_gput_right:Nn \g__nebu_deli_seq { X }
    \seq_gput_right:Nn \g__nebu_pdeli_seq { 0 }
    \seq_gput_right:Nn \g__nebu_delii_seq { X }
    \seq_gput_right:Nn \g__nebu_pdelii_seq { 0 }
   }
  \nebu_typeset_table:n { #1 }
 }

\NewDocumentCommand{\addtoDel}{mmm}
 {
  \clist_gput_right:cn { g__nebu_del\int_to_roman:n { #1 }_clist } { #2 }
  \clist_gput_right:cn { g__nebu_pdel\int_to_roman:n { #1 }_clist } { #3 }
 }

\AtEndDocument{
  \iow_shipout:cx { @auxout }
   { \exp_not:N \LoadDel { i } { \g__nebu_deli_clist } }
  \iow_shipout:cx { @auxout }
   { \exp_not:N \LoadPDel { i } { \g__nebu_pdeli_clist } }
  \iow_shipout:cx { @auxout }
   { \exp_not:N \LoadDel { ii } { \g__nebu_delii_clist } }
  \iow_shipout:cx { @auxout }
   { \exp_not:N \LoadPDel { ii } { \g__nebu_pdelii_clist } }
}
\cs_generate_variant:Nn \iow_shipout:Nx { c }
\NewDocumentCommand{\LoadDel}{mm}
 {
  \seq_gset_split:cnn { g__nebu_del#1_seq } { , } { #2 }
 }
\NewDocumentCommand{\LoadPDel}{mm}
 {
  \seq_gset_split:cnn { g__nebu_pdel#1_seq } { , } { #2 }
 }
\cs_generate_variant:Nn \seq_gset_split:Nnn { c }

\int_new:N \l__nebu_columns_int
\int_new:N \l__nebu_pdeli_total_int
\int_new:N \l__nebu_pdelii_total_int
\int_new:N \l_nebu_countrows_int
\seq_new:N \g__nebu_deli_seq
\seq_new:N \g__nebu_pdeli_seq
\seq_new:N \g__nebu_delii_seq
\seq_new:N \g__nebu_pdelii_seq
\clist_new:N \g__nebu_deli_clist
\clist_new:N \g__nebu_pdeli_clist
\clist_new:N \g__nebu_delii_clist
\clist_new:N \g__nebu_pdelii_clist
\tl_new:N \l__nebu_preamble_tl
\tl_new:N \l__nebu_table_body_tl

\cs_new_protected:Npn \nebu_typeset_table:n #1
 {
  % Compute the number of inner columns
  \int_set:Nn \l__nebu_columns_int
   {
    \int_min:nn { #1 }
     {
      \int_max:nn { \seq_count:N \g__nebu_deli_seq }
                  { \seq_count:N \g__nebu_delii_seq }
     }
   }
  % Define the table preamble
  \tl_set:Nx \l__nebu_preamble_tl
   { l c *{ \int_to_arabic:n { \l__nebu_columns_int } } { c } c }
  % Compute the total for Del1
  \int_zero:N \l__nebu_pdeli_total_int
  \seq_map_inline:Nn \g__nebu_pdeli_seq
   { \int_set:Nn \l__nebu_pdeli_total_int { \l__nebu_pdeli_total_int + ##1 } }
  % Compute the total for Del2
  \int_zero:N \l__nebu_pdelii_total_int
  \seq_map_inline:Nn \g__nebu_pdelii_seq
   { \int_set:Nn \l__nebu_pdelii_total_int { \l__nebu_pdelii_total_int + ##1 } }
  % Start building the table contents
  \tl_clear:N \l__nebu_table_body_tl
  \tl_put_right:Nx \l__nebu_table_body_tl
   { \exp_not:N \multicolumn { \int_to_arabic:n { \l__nebu_columns_int + 2 } } { c } { } }
  \tl_put_right:Nn \l__nebu_table_body_tl { & Sum \\ \midrule }

  % Insert Del1
  \__nebu_insert_table_part:nn { deli } { Del~1 }
  \tl_put_right:Nn \l__nebu_table_body_tl { \midrule }
  % Insert Del2
  \__nebu_insert_table_part:nn { delii } { Del~2 }

  % Add total
  \tl_put_right:Nx \l__nebu_table_body_tl
   {
    \exp_not:N \midrule
    \exp_not:N \multicolumn
                { \int_to_arabic:n { 2 + \l__nebu_columns_int } }
                { r }
                { Total~antall~poeng }
    &
    \int_to_arabic:n { \l__nebu_pdeli_total_int + \l__nebu_pdelii_total_int }
    \exp_not:N \\
   }

  % Print the table
  \use:x{ \exp_not:N \begin{tabular}{\l__nebu_preamble_tl} }
  \toprule
  \l__nebu_table_body_tl
  \bottomrule
  \end{tabular}
}

\cs_new_protected:Npn \__nebu_insert_table_part:nn #1 #2
 {
  \int_set:Nn \l_nebu_countrows_int
   {
    \seq_count:c { g__nebu_#1_seq } / \l__nebu_columns_int
   }
  \int_step_inline:nnnn { 1 } { 1 } { \l_nebu_countrows_int }
   {
    % First line
    \int_compare:nTF { ##1 = 1 }
     {
      \tl_put_right:Nn \l__nebu_table_body_tl { #2 & Oppgave & }
     }
     {
      \tl_put_right:Nx \l__nebu_table_body_tl
       { \exp_not:N \cmidrule(lr){3-\int_to_arabic:n { \l__nebu_columns_int + 2 }} }
      \int_compare:nT { ##1 = 2 }
       {\tl_put_right:Nx \l__nebu_table_body_tl
         { \exp_not:N \cmidrule(l{3em}r)
            {\int_to_arabic:n { \l__nebu_columns_int + 2 }-
             \int_to_arabic:n { \l__nebu_columns_int + 3 }}
         }
       }
      \tl_put_right:Nn \l__nebu_table_body_tl { & & }
     }
    \int_step_inline:nnnn 
     { (##1 - 1)*\l__nebu_columns_int + 1 } 
     { 1 }
     { ##1 * \l__nebu_columns_int }
     {
      \tl_put_right:Nx \l__nebu_table_body_tl 
       { \seq_item:cn { g__nebu_#1_seq } { ####1 } & }
     }
     \tl_put_right:Nn \l__nebu_table_body_tl { \\ }
     % Second line
    \int_compare:nTF { ##1 = 1 }
     { \tl_put_right:Nn \l__nebu_table_body_tl { & Poeng & } }
     { \tl_put_right:Nn \l__nebu_table_body_tl { & & } }
     \int_step_inline:nnnn 
      { (##1 - 1)*\l__nebu_columns_int + 1 }
      { 1 }
      { ##1 * \l__nebu_columns_int }
      {
       \tl_put_right:Nx \l__nebu_table_body_tl
        { \seq_item:cn { g__nebu_p#1_seq } { ####1 } & }
      }
      \tl_put_right:Nx \l__nebu_table_body_tl
       {
        \int_compare:nT { ##1 = 1 }
         { \int_to_arabic:n { \use:c { l__nebu_p#1_total_int } } }
        \exp_not:N \\
       }
   }
 }

\ExplSyntaxOff

\setlength{\parindent}{0pt} % just for the example

\begin{document}

\TypesetTable

\bigskip

\TypesetTable[6]

\addtoDel{1}{1a1}{2}
\addtoDel{1}{1a2}{1}
\addtoDel{1}{1a3}{1}
\addtoDel{1}{1b}{2}
\addtoDel{1}{1c}{2}

\addtoDel{2}{a1}{2}
\addtoDel{2}{a2}{1}
\addtoDel{2}{a3}{1}
\addtoDel{2}{b}{2}
\addtoDel{2}{c}{2}
\addtoDel{2}{d1}{2}
\addtoDel{2}{d2}{2}
\addtoDel{2}{e}{2}
\addtoDel{2}{f1}{2}
\addtoDel{2}{f2}{2}
\addtoDel{2}{f4}{2}
\addtoDel{2}{f5}{2}

\end{document}

在此处输入图片描述

答案2

我对格式有点厌倦了,但是

在此处输入图片描述

\maketab{
{1a1,1; 1a2,1;1a3,1;1b1,1;1b3,2;1c,2;1d1,2;1d2,2;1d3,0;1e1,2;1e2,2;
     1e3,2;1f,2;1g1,2;1g2,2;1g3,2;}
{2a,2;2b,2;2c,2;2d,2;2e,2;2f,2;3a1,2;3a2,2;3b,3;4a,2;4b,2;
     4c,2;4d,2;5a,1;5b,2;5c,2;6a,2;6b,2;}}

完整文档:

\documentclass{article}
\usepackage{array}

\newcount\delcnt
\newcount\thistot
\newcount\tottot
\extrarowheight3pt
\makeatletter

\def\maketab#1{%
\delcnt\z@
\global\tottot\z@
\begin{tabular}{|c|p{20em}|c|}
\@maketab#1\relax
\multicolumn{2}{r|}{Total}&\the\tottot
\end{tabular}}

\def\@maketab#1{%
\ifx\relax#1%
\expandafter\@gobble
\else
\global\thistot\z@
\expandafter\@firstofone
\fi
{\global\advance\delcnt\@ne
Del \the\delcnt&%
\@maketb@#1\relax,;%
&
\global\advance\tottot\thistot
\the\thistot\\\hline\@maketab}}


\def\@maketb@#1,#2;{%
\ifx\relax#1\else
\global\advance\thistot#2\relax
\parbox[t]{2em}{\centering
\strut\ignorespaces#1\par\vskip2pt\hrule\vskip2pt
\strut\ignorespaces#2}\hfil\penalty\z@\hfilneg
\expandafter\@maketb@
\fi}

\makeatother

\begin{document}

\maketab{
{1a1,1; 1a2,1;1a3,1;1b1,1;1b3,2;1c,2;1d1,2;1d2,2;1d3,0;1e1,2;1e2,2;1e3,2;1f,2;1g1,2;1g2,2;1g3,2;}
{2a,2;2b,2;2c,2;2d,2;2e,2;2f,2;3a1,2;3a2,2;3b,3;4a,2;4b,2;4c,2;4d,2;5a,1;5b,2;5c,2;6a,2;6b,2;}}


\end{document}

相关内容