Avalie a expressão / macro no final

Sep 01 2020

Suponha que você tenha um documento no qual deseja mencionar quantas seções existem no início. Por exemplo, algo assim:

\documentclass{article}
\begin{document}

  Abstract\\There are ... sections in this document.

  \section{Section 1}
  \section{Section 2}
  \section{Section 3}

\end{document}

Aqui ... seria uma macro (ou outra coisa) que diz que existem 3 seções.

Eu, infelizmente, não consegui encontrar uma forma de ter essa macro avaliada no final (onde relata 3).

Neste exemplo, quero saber o número de seções no final. Pode haver uma solução usando contadores (de alguma forma), mas estou realmente procurando uma solução onde eu possa ter alguma influência na ordem de avaliação das macros.

Respostas

3 Rmano Sep 01 2020 at 16:12

Você pode usar \AtEndDocument(e \AtBeginDocumentpara definir a macro na primeira execução):

\documentclass{article}

\makeatletter
\AtEndDocument{
    \write\@auxout{\string\gdef\string\previousrunsections{\thesection}}%
}
\AtBeginDocument{%
    \ifcsname previousrunsections\endcsname
    \else
        \gdef\previousrunsections{??}%
    \fi
}
\makeatother
\begin{document}

  Abstract
  
  \noindent There are \previousrunsections{} sections in this document.

  \section{Section 1}
  \section{Section 2}
  \section{Section 3}

\end{document}

Depois de pelo menos duas execuções, você obtém:

Se você precisar de mais controle, o pacote etoolboxoferece muitos ganchos.

PD: não use \\para finalizar linhas ou parágrafos em texto normal !

6 egreg Sep 01 2020 at 17:19

Você pode colocar o número total onde quiser usando totcount.

\documentclass{article}
\usepackage{totcount}

\regtotcounter{section}

\begin{document}

\title{Title}
\author{Ömer}

\maketitle

\begin{abstract}
This is the abstract.

There are \total{section} sections in this document.
\end{abstract}

\section{Section 1}

\section{Section 2}

\section{Section 3}

\end{document}

2 StevenB.Segletes Sep 01 2020 at 16:33

Isso usa um xyzarquivo aux para salvar as informações.

\documentclass{article}
\newcommand\addxyzline[1]{\addtocontents {xyz}{#1}}
\makeatletter
\newcommand\writexyz{\@starttoc{xyz}}
\makeatother
\begin{document}
%\tableofcontents% CAN UNCOMMMENT TO SEE THAT toc WORKS FINE
\noindent Abstract\\There are \writexyz sections in this document.

\section{Introduction}
\section{Next}
\section{Third}
\addxyzline{\thesection}
\end{document}

Na compilação, o .xyzarquivo contém, neste caso, o número 3, e o .auxarquivo contém

\relax 
\@writefile{toc}{\contentsline {section}{\numberline {1}Introduction}{1}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {2}Next}{1}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {3}Third}{1}\protected@file@percent }
\@writefile{xyz}{3}

A saída é assim:

Observação: a versão fornecida funciona independentemente do nome do arquivo de entrada. Se você preferir não trabalhar com a abordagem toc, você poderia tê-lo conectado ao nome do seu documento, em vez de definir

\newcommand\writexyz{\input junk.xyz }

onde, neste caso, o documento deve ser junk.tex.