Summe global deklarieren

Nov 03 2020

Betrachten Sie die folgende 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}

Im obigen Beispiel werden die Gesamtpunkte am Ende korrekt berechnet, aber wenn ich versuche, den Befehl vor der Deklaration der Punkte aufzurufen, wird Null ausgegeben.

Was ist der beste Weg, um dies neu zu definieren, damit auf die Summe überall im Dokument zugegriffen werden kann?

Beachten Sie, dass die Lösung von @egreg in bereitgestellt wurde https://tex.stackexchange.com/a/160089/10898

Antworten

2 LaTeXer Nov 03 2020 at 06:10

Sie müssen die Gesamtsumme in der .auxDatei speichern (daher müssen Sie das Dokument natürlich mindestens zweimal ausführen, um die richtige Summe zu erhalten). Ich habe einen neuen Zähler hinzugefügt, sodass Sie einen haben, um die Summe zu drucken, was falsch ist, wenn Sie Punkte hinzufügen / entfernen, bis Sie das Dokument erneut ausführen, und einen anderen, der die Punkte während des Dokumentlaufs verfolgt. Am Ende des Laufs werden sie verglichen und eine Warnung ausgegeben, damit Sie wissen, dass Sie LaTeX erneut ausführen müssen.

\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}

Nach dem ersten Lauf haben Sie

und eine Warnung in der .log:

Package azetina Warning: Point count differs. Rerun LaTeX to get it right.

und nach dem zweiten Lauf keine Warnung und