后续我之前的问题感谢@egreg 的回答。(也许 Gregorio 教授也能在这里帮助我。)
情况
我正在创建一个问题表 (ToQ) 宏,用于在考试或作业的封面上创建标记表。它工作得很好,tabular
但我换成了 Tabularray 的tblr
,我爱上了它。不幸的是,因为我习惯于totcount
在遇到每个新问题时为其分数创建计数器,所以我遇到了扩展问题,今天这些问题让我很困惑。
问题
循环不能放在tblr
环境中(参见§3.2.3手册中的说明),就像普通表格的情况一样。但似乎适用于普通表格的解决方案:
- 使用 LaTeX 原始循环,
- 在表格外部构建由 \edefs 组成的 \gdef,并且
- 将主体构建为一个令牌登记册,
尚未对 起作用tblr
。此外,tblr
还允许指定一个expand
选项,在处理正文之前指定要扩展的标记。(我将在后面的 MWE 中展示这一点。)
我想要的
受到@frougon 答案的启发这里,我想采用完全 expl3 的方法,因为我无论如何都在尝试学习 expl3。但我不知所措,希望得到一些帮助。不仅仅是一个解决方案,如果您能帮忙的话,我想要一个简要的概述,这样我就可以通过抓取文档来研究解决方案。
平均能量损失
\documentclass{article}
\usepackage{tabularray}
\usepackage{xcolor}
\usepackage{totcount}
% Stuff for keeping account of questions and their scores
% ........................................................<<<
\newcounter{questioncount}
\setcounter{questioncount}{0}
\regtotcounter{questioncount}%
\newcounter{scoretotal}
\setcounter{scoretotal}{0}
\regtotcounter{scoretotal}%
\newcommand{\setquestionpoints}[2]{%
\expanded{\noexpand\newtotcounter{qpoints#1}}%
\expanded{\noexpand\setcounter{qpoints#1}}{#2}%
}
\newcommand{\getquestionpoints}[1]{%
\ifnum\value{qpoints#1}>0
\arabic{qpoints#1}%
\else
0%
\fi
}
\newcommand{\TOTAL}[1]{%
\ifcsname c@#1@totc\endcsname
\total{#1}%
\else
??%
\fi
}
% ........................................................>>>
% Typesetting questions
% ........................................................<<<
\newcommand{\nquestion}[1]{%
\stepcounter{questioncount}%
\setquestionpoints{\arabic{questioncount}}{#1}%
\addtocounter{scoretotal}{#1}%
Question~\thequestioncount (#1 marks.)%
}
% ........................................................>>>
\ExplSyntaxOn
\cs_new_protected:Npn \my_typeset_table_generic:nn #1#2
{
\group_begin:
\cs_set_protected:Npn \__my_typeset_table_generic_tmp_func:n ##1 {#1}
\__my_typeset_table_generic_tmp_func:n {#2}
\group_end:
}
\cs_generate_variant:Nn \my_typeset_table_generic:nn { nV }
\ExplSyntaxOff
\begin{document}
\ExplSyntaxOn
% This works, but I would like to know how expl3 can help me build this
% list automatically, looping for
% q ∈ [1, \totvalue{questioncount}]
% to obtain \TOTAL{qpoints\theq} in each cell of the middle column.
\tl_set:Nn \l_my_tabular_tl {%
1 & \TOTAL{qpoints1} & \null \\ \hline
2 & \TOTAL{qpoints2} & \null \\ \hline
3 & \TOTAL{qpoints3} & \null \\ \hline
}
\my_typeset_table_generic:nV
{
\SetTblrInner{rowsep=1ex}%
\begin{tblr}{colspec={|ccX[c]|}, width=0.35\linewidth}
\SetRow{black, rowsep=0.25ex}
\color{white}\textit{Q}\textnumero & \color{white}Marks & \color{white}Grade \\ \hline
#1
\SetCell[c=2]{c}~TOTAL:~&~\null\\\cline[r]{3-3}
&& {\TOTAL{scoretotal}}\\\hline
\end{tblr}
}
\l_my_tabular_tl
\ExplSyntaxOff
%%% Make some questions:
\vspace{2cm}
\noindent
\nquestion{10}\\
\nquestion{12}\\
\nquestion{15}\\
\end{document}
生成:
答案1
最后\\
导致\nquestion{15}
了 Badbox,因此将其删除。
环境可以放在 expl3 代码之外。使用环境中的tblr
选项。然后不再需要。expand
tblr
\my_typeset_table_generic:nn
在tblr
环境中,选项rowsep=1ex
放在选项列表中,第一行的设置用 键确定row{1}
。那么就不需要写\color{white}
三次了。
宏\null
已被删除。
周围的括号\TOTAL{scoretotal}
已被拆除。
在命令中\nquestion
,{}
后面添加\thequestioncount
, 以便括号不会紧跟在数字后面。
宏\l_my_tabular_tl
未使用 进行初始化\tl_new:N
。现在已使用 进行初始化\tl_new:N \tblrbody
。
内容以 收集\tl_build_put_right:Nn
。此过程以 开始\tl_build_begin:N
并以 结束\tl_build_end:N
。
由于初始值已经是0,所以\setcounter{questioncount}{0}
后面不需要再加。\newcounter{questioncount}
不使用\newcounter
和,而可以使用\regtotcounter
简写。\newtotcounter
无需定义命令\TOTAL
。它由 代替\total
。
命令\setquestionpoints
集成在命令 中\nquestion
。此处,\arabic{questioncount}
替换为\thequestioncount
。对于\setcounter
,\expanded
和\noexpand
是不必要的。
在 之后\SetCell
,&
添加了 ,因为使用\SetCell
,所以不能删除省略的单元格。
\documentclass{article}
\usepackage{xcolor}
\usepackage{tabularray}
\usepackage{totcount}
% Stuff for keeping account of questions and their scores
% ........................................................<<<
\newtotcounter{questioncount}
\newtotcounter{scoretotal}
\newcommand{\getquestionpoints}[1]{%
\ifnum\value{qpoints#1}>0
\arabic{qpoints#1}%
\else
0%
\fi
}
% ........................................................>>>
% Typesetting questions
% ........................................................<<<
\newcommand{\nquestion}[1]{%
\stepcounter{questioncount}%
\expanded{\noexpand\newtotcounter{qpoints\thequestioncount}}%
\setcounter{qpoints\thequestioncount}{#1}%
\addtocounter{scoretotal}{#1}%
Question~\thequestioncount{} (#1 marks.)%
}
% ........................................................>>>
\begin{document}
\ExplSyntaxOn
\tl_new:N \tblrbody
\tl_build_begin:N \tblrbody
\int_step_inline:nn { \totvalue { questioncount } }
{
\tl_build_put_right:Nn \tblrbody { #1 & \total { qpoints#1 } & \\ \hline }
}
\tl_build_end:N \tblrbody
\ExplSyntaxOff
\begin{tblr}[expand=\tblrbody]{
colspec={|ccX[c]|},
width=0.35\linewidth,
rowsep=1ex,
row{1}={bg=black,fg=white,rowsep=0.25ex}
}
\emph{Q}\textnumero & Marks & Grade\\\hline
\tblrbody
\SetCell[c=2]{c} ~TOTAL:~ & & \\\cline[r]{3-3}
& & \total{scoretotal}\\\hline
\end{tblr}
%%% Make some questions:
\vspace{2cm}
\noindent
\nquestion{10}\\
\nquestion{12}\\
\nquestion{15}
\end{document}
答案2
我找到了一个解决方案,其中我在 expl3 中构建了宏的行。我认为这不是最优雅的,但它有效。我对改进它的提示/评论很感兴趣,所以我不接受这个答案,看看是否有人能提出一些漂亮的东西。
\ExplSyntaxOn
\NewDocumentCommand{\ToQ}{}{
\tl_set:Nn \l_tmpa_tl {
\SetTblrInner{rowsep=1ex}%
\begin{tblr}[b]{colspec={|ccX[c]|}, width=0.35\linewidth}
\SetRow{black, rowsep=0.25ex}
\color{white}\textit{Q}\textnumero
& \color{white}Marks
& \color{white}Grade \\ \hline
}
\int_step_inline:nn {\totvalue{questioncount}} {
\tl_put_right:Nn \l_tmpa_tl { ##1 & \fromaux{qpoints##1} & \null \\ \hline }
}
\tl_put_right:Nn \l_tmpa_tl {
\SetCell[c=2]{c}~TOTAL:~&~\null\\\cline[r]{3-3}
&& {\fromaux{scoretotal}}\\\hline
\end{tblr}
}
\l_tmpa_tl
}
\ExplSyntaxOff
生产
答案3
生活不必那么复杂。始终要明确输入和输出的格式。即提供 API。
- 您不需要 LaTeX2e 计数器,请使用模块
int
。 - 当您想要存储值时,请考虑
csname
。 - 创建一系列命令
\Q1
..\Qn
存储值,就\Q1-marks
好像您希望的那样,您也可以\Q1-question
存储实际的问题。
这是一个快速解决方案。我使用了表格,只是为了演示概念。通常我会尽量减少使用的软件包。请修改以向 l3 命令添加前缀,这是很好的做法。
\documentclass{article}
%------------------------------------------------------------
% INPUT : \AddQuestion{name}{marks}
% OUTPUT: PrintScoreSheet
%------------------------------------------------------------
\ExplSyntaxOn
\int_new:N \g_questions_total_int
\clist_new:N \g_questions_clist
\prop_new:N \g_questions_marks_prop
\cs_new_protected:Npn \questions_add:nn #1 #2
{
\clist_gput_right:Nn \g_questions_clist {#1}
\prop_gput:Nnn \g_questions_marks_prop {#1} {#2}
}
\cs_new_protected:Npn \questions_printlist:
{
\begin{tabular}{lrr}
\hline
\clist_map_inline:Nn \g_questions_clist
{
\prop_get:NnN \g_questions_marks_prop {##1} \l_tmpa_tl
\int_gadd:Nn \g_questions_total_int { \l_tmpa_tl }
##1 & \use:c{##1-marks} &\\ %Row
}
\\\noalign{\vskip-10pt}
\cline{2-3}
Total & \int_use:N\g_questions_total_int &\\
\hline
\end{tabular}
}
\let\AddQuestion\questions_add:nn
\let\PrintScoreSheet\questions_printlist:
\ExplSyntaxOff
\begin{document}
\AddQuestion {Q1}{10}
\AddQuestion {Q2}{20}
\AddQuestion {Q3}{5}
\AddQuestion{Q4}{5}
\PrintScoreSheet
\end{document}