我正在使用 expl3 语言编写一个 latex 考试课程。每个部分代表一个包含多个问题的练习。
每个练习都定义了给定的分数。
从这个结构中,我想自动显示给定练习的总分数。
例如,结果将是:
我想提供一个像这样的乳胶界面:
\excercise
\question{2}
...
\question{2}
...
为了实现这个接口,我需要找到一种方法来执行延迟到编译过程的最后一刻的表达式评估。这个解决方案将使我们能够获取在源代码中稍后定义的所有问题值。
下面的源代码是我实现这个想法的尝试。
\ExplSyntaxOn
\seq_new:N \g_points_per_question_seq % Store the point of each section
\int_zero_new:N \g_current_sec_int % Counter of the current exercise
\DeclareDocumentCommand{\addpoint} {m} % Add the arg to the current exercise total point
{
\pt_add_point:Nn \g_points_per_question_seq {#1}
}
\cs_new_protected:Npn \pt_add_point:Nn #1 #2 { % intern method
\group_begin:
\tl_set_eq:NN \l_foo_tl \c_empty_tl % create a temp token variable
\seq_gpop_right:NN \g_points_per_question_seq \l_foo_tl % get the current exercise total point
\fp_set:Nn \l_tmpk_fp {\tl_head:N \l_foo_tl } % Create a local float variable for addition purpose
\fp_add:Nn \l_tmpk_fp { #2 } % Add the argument value to the local variable
\seq_gput_right:Nx \g_points_per_question_seq { \fp_to_tl:N \l_tmpk_fp } % Push back the new total point of the current exercise
\group_end:
}
\DeclareDocumentCommand{\flush} {} % Declare a new exercise
{
\seq_gput_right:Nn \g_points_per_question_seq {0.0} % Set the total point of the new exercise
\int_gadd:Nn \g_current_sec_int 1 % Incr the exercise number
}
\DeclareDocumentCommand{\displaytotalpoint} {} % Display the total point of the current exercise.
{
\seq_item:Nn \g_points_per_question_seq {\int_use:N \g_current_sec_int} % Get the associeted seq element
}
\ExplSyntaxOff
\newcommand{\exercise}{
\flush
\section{Exercise : \displaytotalpoint~points}
}
\newcommand{\question}[1]{
\addpoint{#1}
\subsection{Question : #1 points}
}
\begin{document}
\maketitle
\exercise
\question{2.0}
.....
\question{2.0}
.....
结果如下:
如您所见,总点数并不好,因为它必须等于 4。但是,当我在最后绘制序列状态时,它成功地在第一个索引处包含数字 4。
所以我想我需要在评估完属于当前练习的所有问题之后推迟 seq_item 指令。
为了得到我想要的结果,我怎样才能尽可能地避免这个语句的表达式扩展?
\seq_item:Nn \g_points_per_question_seq {\int_use:N \g_current_sec_int}
您知道如何实现这个结构吗?
非常感谢那些阅读并回答我的人!
答案1
这种事情通常通过写入辅助文件来完成。一个简单的变体是
\documentclass{article}
\begin{document}
Exercise \ref{ex:points}pt
Questions
Questions
\makeatletter
\def\@currentlabel{4}% or for example your `int` variable.
\label{ex:points}%label
\makeatother
\end{document}
可能有更复杂的变体,例如使用 zref 包,但原理保持不变。