LaTeX выводит локальные списки в корневом документе

LaTeX выводит локальные списки в корневом документе

Это дополнительный вопрос дляэтот вопрос, гдеКристиан Хупфердал мне отличное решение для определенной проблемы: я хотел перечислить вхождения специальных команд в разделе в начале этого раздела. Это работает отлично.

Теперь я хочу немного расширить область действия этой штуки, отобразив содержимое всех этих списков на одной странице, желательно в начале документа. Я вижу, что код работает, используя локальные списки с ограниченной областью действия. Возможно ли как-то добавить глобальные списки для каждого раздела, чтобы к ним можно было получить доступ извне раздела? Я не смог найти никакой полезной информации по этому поводу в сети.

Заранее большое спасибо!

решение1

Это расширяет предыдущее решение, которое я дал в ответе, на который ссылается OP.

По сути, я применяю ту же стратегию, что и при повторном сохранении внешнего вида человека на основе разделов, собирая номера разделов, в которых появляется человек, с метками, а затем снова извлекая этот список и создавая таблицу \ListOfPersons, сделанную с помощью длинной таблицы, с гиперссылками на соответствующие разделы.

Я думаю, код можно немного сократить, но вот он:

\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}

введите описание изображения здесь

Связанный контент