LaTeX produz listas locais no documento raiz

LaTeX produz listas locais no documento raiz

Esta é uma pergunta de acompanhamento paraessa questão, ondeChristian Hupferme forneceu uma ótima solução para um determinado problema: eu queria listar as ocorrências de comandos especiais dentro de uma seção no início dessa seção. Isso funciona perfeitamente bem.

Agora quero expandir um pouco o escopo disso, exibindo o conteúdo de todas essas listas em uma página, de preferência no início do documento. Vejo que o código funciona usando listas locais com escopo limitado. É de alguma forma possível adicionar listas globais para cada seção, para que possam ser acessadas de fora da seção? Não consegui encontrar nenhuma informação útil sobre isso na rede.

Muito obrigado antecipadamente!

Responder1

Isso amplia a solução anterior que dei na resposta vinculada pelo OP

Basicamente, eu aplico a mesma estratégia de armazenar novamente a aparência de uma pessoa em uma base por seção, coletando os números das seções em que uma pessoa aparece com rótulos e depois extraio essa lista novamente e montando uma \ListOfPersonstabela, feita com tabela longa, com hiperlinks para as seções relevantes.

Acho que o código pode ser um pouco condensado, mas aqui vai:

\documentclass{scrartcl}

\usepackage{array}
\usepackage{longtable}
\usepackage{xcolor}
\usepackage{refcount}
\usepackage{xparse}
\usepackage{hyperref}

\newcolumntype{L}[1]{>{\raggedright}p{#1}}
\newcolumntype{R}[1]{>{\raggedleft}p{#1}}

\newif\ifusehyperlinks

\ExplSyntaxOn
\seq_new:N \g_luke_listofpersons_seq
\seq_new:N \l_luke_listofpersons_seq 


\NewDocumentCommand{\addperson}{m}{%
  \seq_if_in:NnF \g_luke_listofpersons_seq {#1} {
    \seq_gput_right:Nn \g_luke_listofpersons_seq {#1}
    \seq_gremove_duplicates:N \g_luke_listofpersons_seq
    \seq_new:c {g_luke_#1_scene_seq }
  }
  \int_compare:nNnT {\number\value{section}} > {0} {
    \seq_gput_right:cx {g_luke_#1_scene_seq } {\thesection}
  }
}


\NewDocumentCommand{\addpersonlocal}{m}{%
  \seq_gput_right:Nn \l_luke_listofpersons_seq {#1}
  \int_compare:nNnT {\number\value{section}} > {0} {
    \seq_gput_right:cx {g_luke_#1_scene_seq } {\thesection}
  }
%  \seq_show:c {g_luke_#1_scene_seq }
}

\cs_new:Npn \IfPersonCalledAlreadyF #1#2 {%
  \seq_if_in:NnF \l_luke_listofpersons_seq {#1} {#2}
}

\NewDocumentCommand{\DisplayPersons}{}{%
  \seq_clear:N \l_luke_listofpersons_seq
  \group_begin:
  \seq_clear:N \l_tmpa_seq
  \seq_map_inline:Nn \g_luke_listofpersons_seq {%
    \IfRefUndefinedExpandable{##1\thesection}{}{
      \seq_put_right:Nn \l_tmpa_seq {\use:c{##1h}}
     }
   }
   \seq_if_empty:NF \l_tmpa_seq {
     \PrePersonList
     \seq_use:Nn \l_tmpa_seq {,~} 
     \PostPersonList
   }
   \group_end:
}

\cs_generate_variant:Nn \seq_set_from_clist:Nn {Nx}

% This creates the table entry line per person, by 'cracking' the stored list of sections into the relevant section number and then provides a hyper link
\cs_new:Npn \generatelistofpersonstableline {
  \seq_map_inline:Nn \g_luke_listofpersons_seq  {
    \seq_set_from_clist:Nx \l_tmpa_seq {\getrefnumber{person::##1}}
    \seq_if_empty:NF \l_tmpa_seq {
    \use:c{##1h} &     \seq_set_from_clist:Nx \l_tmpa_seq {\getrefnumber{person::##1}}
    \int_set:Nn \l_tmpa_int {\seq_count:N \l_tmpa_seq} 
    \int_zero:N \l_tmpb_int
    \seq_map_inline:Nn \l_tmpa_seq {
      \int_incr:N \l_tmpb_int
      \ifusehyperlinks
      \hyperlink{section.####1}{####1}
      \else
      ####1
      \fi
      \int_compare:nNnF {\l_tmpa_int} = {\l_tmpb_int} {
        ,\space
      }
    }
    \tabularnewline
    }
  }
}

\NewDocumentCommand{\ListOfPersons}{}{%
 \begin{longtable}{L{5cm}R{10cm}}
   \bfseries Person & \bfseries Sections \tabularnewline
   \endhead
   \generatelistofpersonstableline
  \end{longtable}
}
\makeatletter

\NewDocumentCommand{\storelistofpersons}{}{%
  \seq_map_inline:Nn \g_luke_listofpersons_seq  {
    \protected@edef\@currentlabel{\seq_use:cn {g_luke_##1_scene_seq}{,}}
    \label{person::##1}%
    % ##1 \space \seq_use:cn {g_luke_##1_scene_seq}  {,}
    % \par
  }
}
\makeatother


\AtEndDocument{%
  \storelistofpersons%
}

\ExplSyntaxOff



\NewDocumentCommand{\PostPersonList}{}{%
  \bigskip%

}

\NewDocumentCommand{\displayindividualperson}{m}{%
  \textbf{#1}%
}

\NewDocumentCommand{\PrePersonList}{}{%
  {\large \bfseries Persons in Section \thesection}

}

\makeatletter
\NewDocumentCommand{\NewPerson}{m+m}{%
  % Add this person to the global list
  \addperson{#1}%
  % Now define the personal \...x command 
  \expandafter\NewDocumentCommand\csname #1x\endcsname{+m}{%
    %Check if the person has been called in the local section already
    \IfPersonCalledAlreadyF{#1}{%
      \addpersonlocal{#1}
      % Add the personal to the local list, i.e. per section
      % Check whether the label has been defined already
        \protected@edef\@currentlabel{\thesection.#1}\label{#1\thesection}
    }%
    \textsc{#1:} ##1%
  }% End of the \...x command
  \expandafter\NewDocumentCommand\csname #1h\endcsname{}{%
    #2{#1}%
  }
}% End of \NewPerson
\makeatother


\NewPerson{tom}{\colorbox{green}}
\NewPerson{frodo}{\colorbox{yellow}}
\NewPerson{Gandalf}{\fcolorbox{yellow}{yellow!60!blue}}
\NewPerson{Paulo}{\colorbox{green}}
\NewPerson{David}{\colorbox{orange}}

\usehyperlinkstrue

\begin{document}

\ListOfPersons

\section{In the supermarket}
\DisplayPersons
\tomx{Hi, I'm Tom!}

\frodox{Hi, I'm Frodo!}

\section{At TeX.SE}

\DisplayPersons

\frodox{Hi, I'm Frodo!}

\frodox{I am going to Mordor}

\Gandalfx{Cast the ring into the fire!}

\tomx{Waiting for Godot}

\section{In TeX.SE Chat}

\DisplayPersons

\Paulox{Quack!}

\Gandalfx{Quack!}

\Davidx{I've got a recipe for Duck in Orange Sauce}

\tomx{That's marvellous}

\frodox{Pineapple pizza!}

\end{document}

insira a descrição da imagem aqui

informação relacionada