全局声明总和

全局声明总和

考虑以下 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.

第二次运行后,没有警告,并且

在此处输入图片描述

相关内容