Generating statistics on a command with totcount

Assuming just sections and subsections, my idea is to define \element so that it stores the status of section/subsection when it is called in a sequence.

At end document, the sequence is processed to get totals.

Each item is of the form {<section>}{<subsection>} and I map the sequence once for each section; for items matching the current section index, I increment the counter and also set an intarray item for the corresponding subsection.

At the end of the job a line is written on the terminal for each section and each subsection where \element appears, with the number of entries. The same information is written out in the .aux file, from where it can be easily retrieved.

\documentclass{article}
\usepackage{xparse}

\newcommand{\realelement}{I'm an element}

\ExplSyntaxOn

\NewDocumentCommand{\element}{}
 {
  \seq_gput_right:Nx \g_element_section_seq { {\arabic{section}}{\arabic{subsection}} }
  \realelement
 }
\AtEndDocument{\__element_process:}

\seq_new:N \g_element_section_seq
\int_new:N \l__element_section_int
\int_new:N \l__element_subsection_int
\intarray_new:Nn \g__element_subsection_intarray { 1000 } 

\cs_new_protected:Nn \__element_process:
 {
  \int_step_inline:nn { \value{section} }
   {
    \__element_process_section:n { ##1 }
   }
 }

\cs_new_protected:Nn \__element_process_section:n
 {
  \int_zero:N \l__element_section_int
  \int_zero:N \l__element_subsection_int
  \intarray_gzero:N \g__element_subsection_intarray
  \seq_map_inline:Nn \g_element_section_seq
   {
    \__element_process_item:nnn { #1 } ##1
   }
  \__element_write_section:n { #1 }
 }

\cs_new_protected:Nn \__element_process_item:nnn
 {
  \str_if_eq:nnT { #1 } { #2 }
   {
    \int_incr:N \l__element_section_int
    \int_compare:nT { #3 > \l__element_subsection_int }
     {
      \int_set:Nn \l__element_subsection_int { #3 }
     }
    \intarray_gset:Nnn \g__element_subsection_intarray { #3 }
     { \intarray_item:Nn \g__element_subsection_intarray { #3 } + 1 }
   }
 }

\cs_new_protected:Nn \__element_write_section:n
 {
  \typeout{Section~#1:~\int_to_arabic:n { \l__element_section_int } }
  \iow_now:cx { @auxout }
   {
    \token_to_str:N \elementsection {#1} { \int_to_arabic:n { \l__element_section_int } }
   }
  \int_step_inline:nn { \l__element_subsection_int }
   {
    \typeout{Subsection~#1.##1:~\intarray_item:Nn \g__element_subsection_intarray { ##1 }}
    \iow_now:cx { @auxout }
     {
      \token_to_str:N \elementsubsection {#1} {##1} { \intarray_item:Nn \g__element_subsection_intarray { ##1 } }
     }
   }
 }

\NewDocumentCommand{\elementsection}{mm}{}
\NewDocumentCommand{\elementsubsection}{mmm}{}

\ExplSyntaxOff

\begin{document}

\section{A}
\subsection{a}
\element\element
\subsection{b}
\element\element\element
\subsection{c}
\element\element\element\element

\section{B}
\subsection{a}
\element\element
\subsection{b}
\element

\end{document}

The output on the terminal will be

Section 1: 9
Subsection 1.1: 2
Subsection 1.2: 3
Subsection 1.3: 4
Section 2: 3
Subsection 2.1: 2
Subsection 2.2: 1

In the .aux file we'll have

\elementsection{1}{9}
\elementsubsection{1}{1}{2}
\elementsubsection{1}{2}{3}
\elementsubsection{1}{3}{4}
\elementsection{2}{3}
\elementsubsection{2}{1}{2}
\elementsubsection{2}{2}{1}

Tags:

Totcount