我想使用 hyperref 中的 contentline 命令添加对文档的引用,并能够创建一个目录(列表),其中的条目不一定按引用条目的顺序出现(例如,第一个条目可能指向第 7 页,第二个条目指向第 5 页,举个例子)。为此,我使用了\contentsline
中定义的第四个参数版本hyperref
。
如果我手动设置第四个参数的值,则会很好用,如下面的工作示例所示。
最小工作示例。下面我提供了目前正在使用的代码的最小示例,其中我手动设置了目标链接:
\documentclass[a4paper,twoside]{book}
\usepackage[final]{pdfpages}
\usepackage[bookmarks=true, bookmarksnumbered=true, bookmarksopen=true]{hyperref}
\usepackage{tocloft}
\begin{document}
\pagenumbering{Roman}
\newcommand{\indexNumberOne}{}
\newlistof{myIndexOne}{myIndOne}{\indexNumberOne}
\setcounter{myIndOnedepth}{4}
\newlistentry{myIndexOnechapter}{myIndOne}{0}
\newlistentry[myIndexOnechapter]{myIndexOnesection}{myIndOne}{1}
\newlistentry[myIndexOnesection]{myIndexOnesubsection}{myIndOne}{2}
\newlistentry[myIndexOnesubsection]{myIndexOnesubsubsection}{myIndOne}{3}
\pagenumbering{arabic}
\setcounter{page}{1}
\pdfbookmark[1]{Main TOC (documents appear in sequential order)}{MainTOC}
\tableofcontents
\cleardoublepage
\pdfbookmark[1]{Additional index (documents DO NOT appear in sequential order)}{AdditionalIndex}
\listofmyIndexOne
\cleardoublepage
\addtocontents{myIndOne}{\centerline{\underline{Additional Index}}}
\addtocontents{myIndOne}{\string\contentsline{subsection}{Document 2}{\pageref*{docTwo}}{section*.2}}
\cleardoublepage
\addtocontents{myIndOne}{\string\contentsline{subsection}{Document 1}{\pageref*{docOne}}{section*.1}}
\cleardoublepage
\phantomsection
\label{docOne}
\addcontentsline{toc}{section}{Document 1}
\includepdf[pages=-,fitpaper=true]{doc1.pdf}
\cleardoublepage
\phantomsection
\label{docTwo}
\addcontentsline{toc}{section}{Document 2}
\includepdf[pages=-,fitpaper=true]{doc2.pdf}
\cleardoublepage
\end{document}
问题。我想要一个通用的解决方案来替换诸如“section*.2”和“section*.1”之类的内容,以便自动从标签计算(当前链接是手动设置的,如果移动文档顺序,它们最终将指向错误的位置)。有没有办法根据标签自动计算包\contentsline
中最后一个参数的正确超链接hyperref
?或者还有其他替代方法可以实现我的目标(避免使用像 section*.1 和 section*.2 这样的文字目标链接)?
我尝试过的另一种方法(但没有成功)。我尝试过类似的事情:
\addtocontents{myList}{\string\contentsline{subsection}{Title of the entry}{\pageref*{labelForTheEntry}}{\ref{labelForTheEntry}}}
但它不起作用。
我尝试过的另一种替代方法(但没有成功)。我尝试在最小工作示例中使用 \csname r@labelForTheEntry\endcsname。但是,它似乎不起作用,正如我在下面解释的那样:
通过更换
\addtocontents{myIndOne}{\string\contentsline{subsection}{Document 2}{\pageref*{docTwo}}{section*.2}}
经过
\addtocontents{myIndOne}{\string\contentsline{subsection}{Document 2}{\pageref*{docTwo}}{\csname r@labelForTheEntry\endcsname}}
.myIndOne 文件中生成的行是
\contentsline {subsection}{Document 2}{\pageref *{docTwo}}{{}{7}{}{section*.2}{}}
代替
\contentsline {subsection}{Document 2}{\pageref *{docTwo}}{section*.2}
因此,这两种策略并不等同。直接指定 {section*.2} 有效,但使用 {\csname r@labelForTheEntry\endcsname} 则无效。
这个问题与hyperref 中的 contentline:设置目标链接。这里我提供了可以编译的代码和所需的所有细节,如建议的那样。
有任何想法吗?
答案1
\documentclass[a4paper,twoside]{book}
\usepackage[T1]{fontenc}
% \usepackage[utf8]{inputenc}% not needed with recent latex
\usepackage[final]{pdfpages}
\usepackage[bookmarks=true, bookmarksnumbered=true, bookmarksopen=true]{hyperref}
% \usepackage[titles]{tocloft}
\usepackage{etoc}% only to get toc contents stored
\makeatletter
\newcommand{\storetocentries}{%
\begingroup
\def\contentsline##1##2##3##4{%
\global\@namedef{tOcEnTrY-\detokenize{##2}}%
{\contentsline{##1}{##2}{##3}{##4}}%
}%
\setbox0\vbox{{\the\Etoc@toctoks}}% uses an internal etoc register
\endgroup
}
\newcommand{\tocentry}[1]{%
\begingroup
\let \label \@gobble \let \index \@gobble \let \glossary \@gobble
\let \protect \@unexpandable@protect
\edef\x{\endgroup\noexpand\csname
tOcEnTrY-\noexpand\detokenize{#1}\endcsname}%
\x
}
\makeatother
\begin{document}
\pagenumbering{arabic}
\setcounter{page}{1}
\pdfbookmark[1]{Main TOC (documents appear in sequential order)}{MainTOC}
\tableofcontents
\storetocentries
\cleardoublepage
\pdfbookmark[1]{Additional index (documents DO NOT appear in
sequential order)}{AdditionalIndex}
\markboth{Additional Index}{Additional Index}
\centerline{\underline{Additional Index}}
% ids must be unique
\tocentry{ééçàù 3}
\tocentry{Document 2}
\tocentry{Document 1}
\tocentry{I do not exist, but no error raised}
\cleardoublepage
\markboth{}{}
\phantomsection
\addcontentsline{toc}{section}{Document 1}
\includepdf[pages=-,fitpaper=true]{example-image-a.pdf}
\cleardoublepage
\phantomsection
\addcontentsline{toc}{section}{Document 2}
\includepdf[pages=-,fitpaper=true]{example-image-b.pdf}
\cleardoublepage
\phantomsection
\addcontentsline{toc}{section}{ééçàù 3}
\includepdf[pages=-,fitpaper=true]{example-image-c.pdf}
\cleardoublepage
\end{document}