我有下表,需要重新创建多次
由于其规模和复杂性(是的,我是 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}