考虑以下 MWE:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\shcpoint}{ m }
{
\azetina_shcpoint:n { #1 }
}
\NewDocumentCommand{\printtotal}{ }
{
\int_to_arabic:n { \g_azetina_totalpoints_int }
}
\int_new:N \g_azetina_totalpoints_int
\box_new:N \l_azetina_points_box
\cs_new_protected:Npn \azetina_shcpoint:n #1
{
\int_gadd:Nn \g_azetina_totalpoints_int { #1 }
\hbox_set:Nn \l_azetina_points_box { (0 ~ \textit{points}) }
\makebox[\box_wd:N \l_azetina_points_box][l]
{
(\textit{#1 ~ point\int_compare:nT { #1 > 1 } { s }})
}
\quad
}
\ExplSyntaxOff
\begin{document}
Total points: \printtotal
\shcpoint{1} X
\shcpoint{3} X
\shcpoint{1} X
Total points: \printtotal
\end{document}
在上面的例子中,总分在最后计算正确,但如果我尝试在声明分之前调用命令,它会打印零。
重新定义这个的最佳方法是什么,以便可以在文档的任何位置访问总和?
注意解决方案是由@egreg提供的https://tex.stackexchange.com/a/160089/10898
答案1
您需要将总数保存到.aux
文件中(因此自然需要至少运行文档两次才能获得正确的总数)。我添加了一个新的计数器,因此您有一个计数器用于打印总数,当您添加/删除点时,该总数将是错误的,直到您重新运行文档为止,另一个计数器将在文档运行期间跟踪这些点。在运行结束时,它们会进行比较并发出警告,这样您就知道必须重新运行 LaTeX。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\shcpoint}{ m }
{
\azetina_shcpoint:n { #1 }
}
\NewDocumentCommand{\printtotal}{ }
{
\int_to_arabic:n { \g_azetina_totalpoints_int }
}
\NewDocumentCommand{\shcsettotal}{ m }
{
\int_gset:Nn \g_azetina_totalpoints_int {#1}
}
\int_new:N \g_azetina_totalpoints_int
\int_new:N \g__azetina_counttotal_int
\box_new:N \l_azetina_points_box
\cs_new_protected:Npn \azetina_shcpoint:n #1
{
\int_gadd:Nn \g__azetina_counttotal_int { #1 }
\hbox_set:Nn \l_azetina_points_box { (0 ~ \textit{points}) }
\makebox[\box_wd:N \l_azetina_points_box][l]
{
(\textit{#1 ~ point\int_compare:nT { #1 > 1 } { s }})
}
\quad
}
\makeatletter
\AtEndDocument
{
\iow_now:Nx \@auxout
{
\shcsettotal { \int_use:N \g__azetina_counttotal_int }
}
\int_compare:nNnF \g__azetina_counttotal_int = \g_azetina_totalpoints_int
{
\msg_warning:nn { azetina } { rerun-points }
}
}
\msg_new:nnn { azetina } { rerun-points }
{
Point~count~differs.~Rerun~LaTeX~to~get~it~right.
}
\makeatother
\ExplSyntaxOff
\begin{document}
Total points: \printtotal
\shcpoint{1} X
\shcpoint{3} X
\shcpoint{1} X
Total points: \printtotal
\end{document}
第一次运行后,您
并且出现警告.log
:
Package azetina Warning: Point count differs. Rerun LaTeX to get it right.
第二次运行后,没有警告,并且