Print a list of selected enumerated list labels
Here is a prototype. The idea is to save the special actions and results into LaTeX3 sequences \g_actions_seq
and \g_results_seq
and each time a subsection starts these are saved to the aux
file as entries of the form
\SetActionResult{actions}{0.1}{{{A2}}}
\SetActionResult{results}{0.1}{{{A1}}{{R2}},{{A3}}{{R2}}}
When the aux
file is read in, the \SetActionResult
command stores this data into two property lists, \g_special_actions_prop
and \g_special_results_prop
for actions and results. At the start of each subsection if the property lists contain keys for the current subsection then this information is automatically printed. With this in place, your MWE produces:
I left the hard-coded lists of special actions and results in the file for comparison.
Here is the code:
\documentclass{article}
\usepackage{enumitem}
\newlist{actions}{enumerate}{1}
\setlist[actions, 1]{label=A\arabic*}
\newlist{checks}{enumerate}{1}
\setlist[checks, 1]{label=R\arabic*}
\usepackage{xparse}
\usepackage{expl3}
\ExplSyntaxOn
\prop_new:N \g_special_actions_prop
\prop_new:N \g_special_results_prop
\seq_new:N \g_actions_seq
\seq_new:N \g_results_seq
\NewDocumentCommand\action{ sm }
{
\item
\IfBooleanTF{#1}
{ \emph{#2}\seq_gput_right:Nx \g_actions_seq {\theactionsi} }
{ #2 }
}
\NewDocumentCommand\result{ sm }
{
\item
\IfBooleanTF{#1}
{ \emph{#2}
\seq_gput_right:Nx \g_results_seq {\theactionsi\thechecksi} }
{ #2 }
}
\NewDocumentCommand\SetActionResult{mmm}
{
\prop_gput:cnn {g_special_#1_prop} {#2} {#3}
}
\NewDocumentCommand\SaveActionsResults{}{
% save special actions and results to the aux file
\seq_if_empty:NF \g_actions_seq
{
\iow_now:cx { @auxout }
{
\token_to_str:N\SetActionResult {actions}
{ \thesubsection }{\seq_use:Nn \g_actions_seq {,~}}
}
\seq_gclear:N \g_actions_seq
}
\seq_if_empty:NF \g_results_seq
{
\iow_now:cx { @auxout }
{
\token_to_str:N\SetActionResult {results}
{ \thesubsection }{\seq_use:Nn \g_results_seq {,~}}
}
\seq_gclear:N \g_results_seq
}
}
\NewDocumentCommand\Subsection{ m }
{
\SaveActionsResults
\subsection{ #1 }
% print all known special results and actions
\prop_if_in:NxT \g_special_actions_prop {\thesubsection} {
\prop_get:NxN \g_special_actions_prop {\thesubsection} \l_tmpa_tl
\noindent Special~actions:~\tl_use:N \l_tmpa_tl.
\newline
}
\prop_if_in:NxT \g_special_results_prop {\thesubsection} {
\prop_get:NxN \g_special_results_prop {\thesubsection} \l_tmpa_tl
\noindent Special~results:~\tl_use:N \l_tmpa_tl.
\newline
}
}
\cs_generate_variant:Nn \prop_if_in:NnT {NxT}
\cs_generate_variant:Nn \prop_get:NnN {NxN}
\ExplSyntaxOff
\begin{document}
\Subsection{First of many}
\noindent
Special actions: \textbf{A2}.\\
Special results: \textbf{A1R2, A3R2}.
\begin{actions}
\action{Make list references to `special' items automatically.}
\begin{checks}
\result{First attempt fails}
\result*{All other attempts fail}
\end{checks}
\action*{Turn to google\ldots}
\begin{checks}
\result{Still fails, can't find the right search terms}
\end{checks}
\action{Post a MWE to \TeX{} SE.}
\begin{checks}
\result{Someone produces automagic? There's a package for that\ldots}
\result*{Re-write the original document. Again.}
\result{Job done}
\end{checks}
\end{actions}
% save the data from the last subsection
\SaveActionsResults
\end{document}
At the risk of obfuscation, the code could be rationalised slightly because the actions and results are treated in almost exactly the same way. For example, the \SetActionResult
command shows how to combine the action and result code branches into one function.
LaTeX3 takes a little bit of getting used to but after a while you grow to like it as it is very powerful. The best place that I have found to learn about it is by typing texdoc interface3
.
You can use the datatool-package for maintaining a database with your special things.
Then you can use datatool-macros for iterating the database and "filtering" entries for "spitting out" desired lists.
In the example below actually two databases are used.
One database is written to. That database at the end of the LaTeX-run gets saved to external file. That database is named specialthingsinterim
.
The other database stems from the previous LaTeX-run/from the external file saved in the previous LaTeX-run and is used for iterating and printing lists etc. That database is named specialthings
.
This way you can both write to database and use the database at the same time.
But you need to compile the document at least twice.
\documentclass{article}
\usepackage{hyperref}
\usepackage{datatool}
\usepackage{atveryend}
\makeatletter
\newcommand\DATABASEFILECreateIfNotExistent[1]{%
\DTLifdbexists{#1}{}{%
\IfFileExists{\jobname.#1}{%
\DTLloaddb{#1}{\jobname.#1}%
}{%
\DTLnewdb{#1}%
}%
}%
\DTLifdbexists{#1interim}{}{%
\DTLnewdb{#1interim}%
\AtEndDocument{%
% This will save the interim-database to file with
% the last \shipout. The last \shipout is triggered
% by \end{document}/\enddocument.
\DTLsavedb{#1interim}{\jobname.#1}%
}%
\AfterLastShipout{%
% Check if content of database-token-register stemming from
% database-file of previous LaTeX-run differs from content of
% database-token-register stemming from database-file of
% the current LaTeX-run.
% If so, something changed and you need to re-run LaTeX.
% Probably this should be omitted with large databases.
\begingroup
\DTLgdeletedb{#1interim}%
\DTLloaddb{#1interim}{\jobname.#1}%
\edef\tempa{\the\csname dtldb@#1\endcsname}%
\edef\tempb{\the\csname dtldb@#1interim\endcsname}%
\ifx\tempa\tempb
\endgroup
\else
\endgroup
\@latex@warning@no@line{%
Database `#1' may have changed.
Rerun to get listings of entries etc right%
}%
\fi
}%
}%
}%
%-------------------------------------------------------------------------
\newcommand\SpecialThingsCount{0}%
\newcommand\AddSpecialThingToDatabase{%
\@bsphack
\xdef\SpecialThingsCount{\number\numexpr\SpecialThingsCount+1\relax}%
\DATABASEFILECreateIfNotExistent{specialthings}%
\DTLnewrow{specialthingsinterim}%
{%
\dtlexpandnewvalue
\DTLnewdbentry{specialthingsinterim}{PrimaryKey}{\SpecialThingsCount}%
\DTLnewdbentry{specialthingsinterim}{Subsection}{\thesubsection}%
\DTLnewdbentry{specialthingsinterim}{HSubsection}{\theHsubsection}%
\DTLnewdbentry{specialthingsinterim}{Environment}{\@currenvir}%
\DTLnewdbentry{specialthingsinterim}{Itemnumber}{\@currentlabel}%
\DTLnewdbentry{specialthingsinterim}{Superordinateitemnumber}{\previouscurrentlabel}%
\DTLnewdbentry{specialthingsinterim}{Destinationname}{\@currentHref}%
}%
\@esphack
}%
\newcommand\exchange[2]{#2#1}%
\newcommand\previouscurrentlabel{}%
\newcommand\ListOfSpecialThingsSeparator{}%
\newcommand\ListOfSpecialThings[2]{%
\xdef\ListOfSpecialThingsSeparator{}%
\DATABASEFILECreateIfNotExistent{specialthings}%
\DTLforeach{specialthings}{%
\PrimaryKeyField=PrimaryKey,
\SubsectionField=Subsection,
\HSubsectionField=HSubsection,
\EnvironmentField=Environment,
\ItemnumberField=Itemnumber,
\SuperordinateitemnumberField=Superordinateitemnumber,
\Destinationnamefield=Destinationname%
}{%
\begingroup
\edef\@tempa{\HSubsectionField}%
\edef\@tempb{#2}%
\ifx\@tempa\@tempb\expandafter\@firstofone\else\expandafter\@secondoftwo\fi
{%
\edef\@tempa{\EnvironmentField}%
\def\@tempb{#1}%
\ifx\@tempa\@tempb\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{%
\def\@tempa{checks}%
\ifx\@tempa\@tempb\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\exchange{\hyperlink{\Destinationnamefield}{\textbf{\SuperordinateitemnumberField\ItemnumberField}}}}%
{\exchange{\hyperlink{\Destinationnamefield}{\textbf{\ItemnumberField}}}}%
{%
\endgroup
\ListOfSpecialThingsSeparator
}%
\xdef\ListOfSpecialThingsSeparator{, }%
}%
}%
{\endgroup}%
}%
}%
\newcommand\ListOfSpecialActions{\ListOfSpecialThings{actions}{\theHsubsection}}%
\newcommand\ListOfSpecialChecks{\ListOfSpecialThings{checks}{\theHsubsection}}%
\usepackage{enumitem}
\newlist{actions}{enumerate}{1}
\setlist[actions, 1]{label=A\arabic*, before*={\def\previouscurrentlabel{}}}
\newlist{checks}{enumerate}{1}
\setlist[checks, 1]{label=R\arabic*, before*={\let\previouscurrentlabel=\@currentlabel}}
\newcommand*{\SpecialThingItem}{\item\@ifstar{\AddSpecialThingToDatabase\emph}{}}
\newcommand*{\action}{\SpecialThingItem}
\newcommand*{\result}{\SpecialThingItem}
\makeatother
\begin{document}
\subsection{First of many}
\noindent
Special actions: \ListOfSpecialActions.\\
Special results: \ListOfSpecialChecks.
\begin{actions}
\action{Make list references to `special' items automatically.}
\begin{checks}
\result{First attempt fails}
\result*{All other attempts fail}
\end{checks}
\action*{Turn to google\ldots}
\begin{checks}
\result{Still fails, can't find the right search terms}
\end{checks}
\action{Post a MWE to \TeX{} SE.}
\begin{checks}
\result{Someone produces automagic? There's a package for that\ldots}
\result*{Re-write the original document. Again.}
\result{Job done}
\end{checks}
\end{actions}
\subsection{Second of many}
\noindent
Special actions: \ListOfSpecialActions.\\
Special results: \ListOfSpecialChecks.
\begin{actions}
\action*{Make list references to `special' items automatically.}
\begin{checks}
\result{First attempt fails}
\result{Second attempt fails}
\result{Third attempt fails}
\result*{All other attempts fail}
\end{checks}
\action{Turn to google\ldots}
\begin{checks}
\result*{Still fails, can't find the right search terms}
\end{checks}
\action*{Post a MWE to \TeX{} SE.}
\begin{checks}
\result{Someone produces automagic? There's a package for that\ldots}
\result{Re-write the original document. Again.}
\result*{Job done}
\end{checks}
\end{actions}
\end{document}