Skip to content

Stampa un elenco di etichette di elenchi enumerati selezionati

Dopo aver consultato esperti del settore, programmatori di diverse aree e docenti, abbiamo trovato la risposta alla domanda e la catturiamo in questo post.

Soluzione:

Ecco un prototipo. L'idea è quella di salvare le azioni speciali e i risultati in sequenze LaTeX3 g_actions_seq e g_results_seq e ogni volta che inizia una sottosezione queste vengono salvate nella sequenza aux come voci della forma

SetActionResult{actions}{0.1}{{{A2}}}
SetActionResult{results}{0.1}{{{A1}}{{R2}},{{A3}}{{R2}}}

Quando il file aux viene letto, il file SetActionResult memorizza questi dati in due elenchi di proprietà, g_special_actions_prop e g_special_results_prop per le azioni e i risultati. All'inizio di ogni sottosezione, se gli elenchi di proprietà contengono chiavi per la sottosezione corrente, queste informazioni vengono stampate automaticamente. Con questo sistema, il vostro MWE produce:

enter image description here

Ho lasciato gli elenchi codificati di azioni speciali e risultati nel file per il confronto.

Ecco il codice:

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}

A rischio di offuscamento, il codice potrebbe essere leggermente razionalizzato, perché le azioni e i risultati sono trattati quasi esattamente allo stesso modo. Ad esempio, l'azione SetActionResult mostra come combinare i rami di codice delle azioni e dei risultati in un'unica funzione.

LaTeX3 richiede un po' di tempo per abituarsi, ma dopo un po' ci si abitua perché è molto potente. Il posto migliore che ho trovato per imparare a conoscerlo è digitare texdoc interface3.

È possibile utilizzare il pacchetto datatool per mantenere un database con i propri oggetti speciali.

Poi si possono usare le macro di datatool per iterare il database e "filtrare" le voci per "sputare" gli elenchi desiderati.

Nell'esempio che segue vengono utilizzati due database.

Un database viene scritto. Questo database alla fine dell'esecuzione di LaTeX viene salvato in un file esterno. Questo database è chiamato specialthingsinterim.

L'altro database deriva dalla precedente esecuzione LaTeX/dal file esterno salvato nella precedente esecuzione LaTeX ed è usato per iterare e stampare elenchi ecc. Questo database si chiama specialthings.

In questo modo è possibile scrivere sul database e utilizzare il database allo stesso tempo.

Ma è necessario compilare il documento almeno due volte.

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 [email protected]#1endcsname}%
      edeftempb{thecsname [email protected]#1interimendcsname}%
      ifxtempatempb
        endgroup
      else
        endgroup
        @[email protected]@[email protected]{%
           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

Valutazioni e recensioni

Se ritieni che questo articolo sia stato utile, ti saremmo grati se lo condividessi con più anziani in modo che tu possa aiutare a diffondere le nostre informazioni.



Utilizzate il nostro motore di ricerca

Ricerca
Generic filters

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.