Wie dedupliziert und sortiert man eine Liste von \pagerefs?

Wie dedupliziert und sortiert man eine Liste von \pagerefs?

Ich habe ein Dokument, das aus drei großen, mehrseitigen Tabellen besteht, die alle Links zu Elementen in einer Liste von Abbildungen am Ende haben. Indem ich MD5-Labels generiere, wenn ich das Latex für die Tabellen generiere, kann ich Links zurück zu den ursprünglichen Tabellen einfügen. Mehrere Elemente, die auf eine Abbildung verweisen, befinden sich jedoch häufig auf derselben Seite, was zu Monstrositäten wie dieser führt:

Figure 31 - This figure was referenced on pages 4, 4, 4, 14, 17, 17, 27, 30, 30, 6, 6, 6, 6, 6, 6, 8, 8, 8, 19, 19, 20, 20, 21, 21, 21, 21, 21, 32, 32, 33, 33, 34, 34, 34 34, and 34.

Im generierten Dokument stellt jede dieser Seitenzahlen einen Link zurück zur Tabellenzeile dar, die auf diese Abbildung verweist.

Ich möchte zwei Dinge erreichen:

  1. Eliminieren Sie Duplikate, so dass auf einer Seite nur auf den ersten Tabelleneintrag verwiesen wird.
  2. (optional) Sortieren Sie die Liste nach der Seitenzahl

Ich habe die Frage zur Listendeduplizierung gesehenHier, aber ich bin neu bei Latex und schaffe es nicht einmal, mein unten gepostetes minimales funktionierendes Beispiel zum Laufen zu bringen:

\documentclass[letterpaper,11pt,openany,oneside]{book}

\makeatletter
\def\removeduplicates#1#2{\begingroup
  \let\@tempa#1%
  \def\@tempb{}%
  \@for\next:=\@tempa\do
    {\@ifundefined{lstel@\next}
      {\edef\@tempb{\@tempb,\next}
       \expandafter\let\csname lstel@\next\endcsname\@empty}
      {}%
    }%
  \edef\x{\endgroup\def\noexpand#2{\@tempb}}\x
  \expandafter\strip@comma#2\@nil#2}
\def\strip@comma,#1\@nil#2{\def#2{#1}}
\makeatother

\begin{document}
% some labels on page 1
\section{John} \label{john}
john doe
\section{Mary} \label{mary}
mary sue

%move to page 2
\clearpage
\section{George} \label{george}
george weasley
\section{Australia} \label{australia}
crocodile dundee

%new page, where the references are
\clearpage
\section{References}

\def\alist{\pageref{john},\pageref{mary},\pageref{george},\pageref{australia},\pageref{australia},\pageref{john}}   
\removeduplicates\alist\blist

\show\blist
\show\alist

\removeduplicates\alist\alist
\show\alist

\end{document}

Wenn ich versuche, das auszuführen, eine einfache Modifikation des Beispiels aus dem Link, erhalte ich für jede \renewduplicatesZeile etwa ein Dutzend Fehlermeldungen, die fehlende \endcsname, zusätzliche \endcsnameund zusätzliche Fehlermeldungen \elseenthalten. Ich habe keine Ahnung, wie ich das debuggen soll.

Antwort1

Sie verwenden \edefund \pagerefkönnen in diesem Kontext nicht verwendet werden, noch kann es erscheinen in\csname...\endcsname

Das Vermeiden der vollständigen Erweiterung funktioniert zusammen mit der Stringifizierung der Erweiterung der ersten Ebene von \nextwhen in \csname...\endcsname.

\providecommand{\expandonce}{\unexpanded\expandafter}
\makeatletter
\def\removeduplicates#1#2{\begingroup
  \let\@tempa#1%
  \def\@tempb{}%
  \@for\next:=\@tempa\do
    {\@ifundefined{lstel@\detokenize\expandafter{\next}}
      {\edef\@tempb{\expandonce{\@tempb},\expandonce{\next}}
       \expandafter\let\csname lstel@\detokenize\expandafter{\next}\endcsname\@empty}
      {}%
    }%
  \edef\x{\endgroup\def\noexpand#2{\expandonce{\@tempb}}}\x
  \expandafter\strip@comma#2\@nil#2}
\def\strip@comma,#1\@nil#2{\def#2{#1}}
\makeatother

Es gibt jedoch einen eleganteren Weg:

\documentclass[letterpaper,11pt,openany,oneside]{book}

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\removeduplicates}{mm}
 {
  \seq_set_split:NnV \l_tmpa_seq { , } #1
  \seq_remove_duplicates:N \l_tmpa_seq
  \tl_set:Nx #2 { \seq_use:Nn \l_tmpa_seq { , } }
 }
\ExplSyntaxOff

\begin{document}
% some labels on page 1
\section{John} \label{john}
john doe
\section{Mary} \label{mary}
mary sue

%move to page 2
\clearpage
\section{George} \label{george}
george weasley
\section{Australia} \label{australia}
crocodile dundee

%new page, where the references are
\clearpage
\section{References}

\def\alist{\pageref{john},\pageref{mary},\pageref{george},%
  \pageref{australia},\pageref{australia},\pageref{john}}   

\removeduplicates\alist\blist

\show\blist
\show\alist

\removeduplicates\alist\alist
\show\alist

\end{document}

Hier ist die Ausgabe auf meinem Terminal:

> \blist=macro:
->\pageref {john},\pageref {mary},\pageref {george},\pageref {australia}.
l.37 \show\blist

? 
> \alist=macro:
->\pageref {john},\pageref {mary},\pageref {george},\pageref {australia},\pager
ef {australia},\pageref {john}.
l.38 \show\alist

? 
> \alist=macro:
->\pageref {john},\pageref {mary},\pageref {george},\pageref {australia}.
l.41 \show\alist

? 

Eine Sortierung ist auf dieser Ebene nicht möglich.


Wenn Sie die Seitenzahl-Duplikate und nicht die \pageref{...}Duplikate entfernen möchten, benötigen Sie die erweiterbare Version von , die \pagerefvon bereitgestellt wird refcount. Ich zeige den Code in den beiden Versionen. Zuerst expl3:

\documentclass[letterpaper,11pt,openany,oneside]{book}
\usepackage{refcount}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\removeduplicates}{mm}
 {
  \clist_set:Nx \l_tmpa_clist { #1 }
  \clist_remove_duplicates:N \l_tmpa_clist
  \tl_set:NV #2 \l_tmpa_clist
 }
\ExplSyntaxOff

\begin{document}
% some labels on page 1
\section{John} \label{john}
john doe
\section{Mary} \label{mary}
mary sue

%move to page 2
\clearpage
\section{George} \label{george}
george weasley
\section{Australia} \label{australia}
crocodile dundee

%new page, where the references are
\clearpage
\section{References}

\def\alist{\getpagerefnumber{john},\getpagerefnumber{mary},\getpagerefnumber{george},%
  \getpagerefnumber{australia},\getpagerefnumber{australia},\getpagerefnumber{john}}   

\removeduplicates\alist\blist

\show\blist
\show\alist

\removeduplicates\alist\alist
\show\alist

\alist

\blist

\end{document}

Dann die „klassische“ Version:

\documentclass[letterpaper,11pt,openany,oneside]{book}
\usepackage{refcount}

\makeatletter
\def\removeduplicates#1#2{\begingroup
  \let\@tempa#1%
  \def\@tempb{}%
  \@for\next:=\@tempa\do
    {\@ifundefined{lstel@\next}
      {\edef\@tempb{\@tempb,\next}%
       \expandafter\let\csname lstel@\next\endcsname\@empty}
      {}%
    }%
  \edef\x{\endgroup\def\noexpand#2{\@tempb}}\x
  \expandafter\strip@comma#2\@nil#2}
\def\strip@comma,#1\@nil#2{\def#2{#1}}
\makeatother

\begin{document}
% some labels on page 1
\section{John} \label{john}
john doe
\section{Mary} \label{mary}
mary sue

%move to page 2
\clearpage
\section{George} \label{george}
george weasley
\section{Australia} \label{australia}
crocodile dundee

%new page, where the references are
\clearpage
\section{References}

\def\alist{\getpagerefnumber{john},\getpagerefnumber{mary},\getpagerefnumber{george},\getpagerefnumber{australia},\getpagerefnumber{australia},\getpagerefnumber{john}}   
\removeduplicates\alist\blist

\show\blist
\show\alist

\removeduplicates\alist\alist
\show\alist

\blist

\alist

\end{document}

Beide Versionen definieren \blistund definieren neu \alist, um „1,2“ zu enthalten.


Eine Version, die die erstellte Liste zum Drucken von Hyperlinks zu den Seiten verwendet.

\documentclass[letterpaper,11pt,openany,oneside]{book}
\usepackage{refcount}
\usepackage{xparse}
\usepackage{hyperref}

\ExplSyntaxOn
\NewDocumentCommand{\createlinks}{m}
 {
  \seq_set_split:Nnx \l_tmpa_seq { , } { #1 }
  \seq_remove_duplicates:N \l_tmpa_seq
  \seq_clear:N \l_tmpb_seq
  \seq_map_inline:Nn \l_tmpa_seq
   {
    \seq_put_right:Nn \l_tmpb_seq { \hyperlink { page.##1 } { ##1 } }
   }
  \seq_use:Nn \l_tmpb_seq { ,~ }
 }
\cs_generate_variant:Nn \seq_set_split:Nnn { Nnx }
\ExplSyntaxOff

\begin{document}
% some labels on page 1
\section{John} \label{john}
john doe
\section{Mary} \label{mary}
mary sue

%move to page 2
\clearpage
\section{George} \label{george}
george weasley
\section{Australia} \label{australia}
crocodile dundee

%new page, where the references are
\clearpage
\section{References}

\def\alist{\getpagerefnumber{john},\getpagerefnumber{mary},\getpagerefnumber{george},%
  \getpagerefnumber{australia},\getpagerefnumber{australia},\getpagerefnumber{john}}   

\createlinks\alist

\end{document}

verwandte Informationen