
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:
- Eliminieren Sie Duplikate, so dass auf einer Seite nur auf den ersten Tabelleneintrag verwiesen wird.
- (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 \renewduplicates
Zeile etwa ein Dutzend Fehlermeldungen, die fehlende \endcsname
, zusätzliche \endcsname
und zusätzliche Fehlermeldungen \else
enthalten. Ich habe keine Ahnung, wie ich das debuggen soll.
Antwort1
Sie verwenden \edef
und \pageref
kö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 \next
when 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 \pageref
von 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 \blist
und 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}