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}