TransWikia.com

Print a list of selected enumerated list labels

TeX - LaTeX Asked on September 26, 2021

I’m working on a document which lists actions to expected results, in enumerated lists. Some of the actions are noteworthy, as are some of the results. I’d like the noteworthy actions’ and results’ labels to be listed, where noteworthyness is determined by using the starred action/result macro used when defining the actions and results, to avoid manually typesetting them. Current MWE:

documentclass{article}

usepackage{enumitem}
newlist{actions}{enumerate}{1}
setlist[actions, 1]{label=Aarabic*}
newlist{checks}{enumerate}{1}
setlist[checks, 1]{label=Rarabic*}

usepackage{xparse}
NewDocumentCommand{action}{s m}{IfBooleanTF #1 {itememph{#2}}{item #2}}
NewDocumentCommand{result}{s m}{IfBooleanTF #1 {itememph{#2}}{item #2}}

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 googleldots}
 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 thatldots}
  result*{Re-write the original document. Again.}
  result{Job done}
 end{checks}
end{actions}
end{document}

which produces (bold text to become automagic) :
Output

What is the best approach here? My current failures involve generating labels and producing a list of them, use of imakeidx and maintaining a list of enumi/enumii as text.

A complication is that the document will contain many of these sections (~50), each subsection should only list it’s own noteworthy items.

2 Answers

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:

enter image description here

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=Aarabic*}
newlist{checks}{enumerate}{1}
setlist[checks, 1]{label=Rarabic*}

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

NewDocumentCommandaction{ sm }
{
item 
  IfBooleanTF{#1}
    { emph{#2}seq_gput_right:Nx g_actions_seq {theactionsi} }
    { #2 }
}

NewDocumentCommandresult{ sm }
{
item 
  IfBooleanTF{#1}
    { emph{#2}
      seq_gput_right:Nx g_results_seq {theactionsithechecksi} }
    { #2 }
}

NewDocumentCommandSetActionResult{mmm}
{ 
   prop_gput:cnn {g_special_#1_prop} {#2} {#3} 
}

NewDocumentCommandSaveActionsResults{}{
  % save special actions and results to the aux file
  seq_if_empty:NF g_actions_seq
  {
    iow_now:cx { @auxout }
    {
      token_to_str:NSetActionResult {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:NSetActionResult {results} 
         { thesubsection }{seq_use:Nn g_results_seq {,~}}
    }
    seq_gclear:N g_results_seq
  }
}

NewDocumentCommandSubsection{ 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 googleldots}
 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 thatldots}
  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.

Correct answer by user30471 on September 26, 2021

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
newcommandDATABASEFILECreateIfNotExistent[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}%
      edeftempa{thecsname dtldb@#1endcsname}%
      edeftempb{thecsname dtldb@#1interimendcsname}%
      ifxtempatempb
        endgroup
      else
        endgroup
        @latex@warning@no@line{%
           Database `#1' may have changed.
           Rerun to get listings of entries etc right%
         }%
      fi
    }%
  }%
}%
%-------------------------------------------------------------------------
newcommandSpecialThingsCount{0}%
newcommandAddSpecialThingToDatabase{%
  @bsphack
  xdefSpecialThingsCount{numbernumexprSpecialThingsCount+1relax}%
  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
}%

newcommandexchange[2]{#2#1}%
newcommandpreviouscurrentlabel{}%

newcommandListOfSpecialThingsSeparator{}%
newcommandListOfSpecialThings[2]{%
  xdefListOfSpecialThingsSeparator{}%
  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@tempbexpandafter@firstofoneelseexpandafter@secondoftwofi
    {%
      edef@tempa{EnvironmentField}%
      def@tempb{#1}%
      ifx@tempa@tempbexpandafter@firstoftwoelseexpandafter@secondoftwofi
      {%
        def@tempa{checks}%
        ifx@tempa@tempbexpandafter@firstoftwoelseexpandafter@secondoftwofi
        {exchange{hyperlink{Destinationnamefield}{textbf{SuperordinateitemnumberFieldItemnumberField}}}}%
        {exchange{hyperlink{Destinationnamefield}{textbf{ItemnumberField}}}}%
        {%
          endgroup
          ListOfSpecialThingsSeparator
        }%
        xdefListOfSpecialThingsSeparator{, }%
      }%
    }%
    {endgroup}%
   }%
}%
newcommandListOfSpecialActions{ListOfSpecialThings{actions}{theHsubsection}}%
newcommandListOfSpecialChecks{ListOfSpecialThings{checks}{theHsubsection}}%


usepackage{enumitem}
newlist{actions}{enumerate}{1}
setlist[actions, 1]{label=Aarabic*, before*={defpreviouscurrentlabel{}}}
newlist{checks}{enumerate}{1}
setlist[checks, 1]{label=Rarabic*,  before*={letpreviouscurrentlabel=@currentlabel}}

newcommand*{SpecialThingItem}{item@ifstar{AddSpecialThingToDatabaseemph}{}}

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 googleldots}
 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 thatldots}
  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 googleldots}
 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 thatldots}
  result{Re-write the original document. Again.}
  result*{Job done}
 end{checks}
end{actions}

end{document}

enter image description here

Answered by Ulrich Diez on September 26, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP