内容超过两页时出现问题

内容超过两页时出现问题

当目录超过两页时,我收到此警告:

具有相同标识符 (name{page.i}) 的目标已被使用,忽略重复 \relax l.36 ...on}{\numberline {5.6}test}{9}{section.5.6} [1])pdfTeX 警告 (ext4): d

如果文档不太长,我们就不会收到警告,例如:

\documentclass[a4paper]{memoir}




\title{Test}
\usepackage{hyperref}

\begin{document}

\frontmatter
\begin{titlingpage}
    \maketitle
    \end{titlingpage}

\tableofcontents


\mainmatter
\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}



\end{document}

但是,如果我们增加文档以致内容超过几页,我们就会收到警告,给出警告的文档示例如下:

\documentclass[a4paper]{memoir}




\title{Test}
\usepackage{hyperref}

\begin{document}

\frontmatter
\begin{titlingpage}
    \maketitle
    \end{titlingpage}

\tableofcontents


\mainmatter
\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}



\end{document}

有没有办法来解决这个问题?

答案1

造成错误的主要原因是titlingpage环境,它明确地用重置了页码\setcounter{page}{\@ne}——这会混淆设置的超锚点hyperref

在类似的答案中,我跟踪了此类页码更改(请参阅https://tex.stackexchange.com/a/355883/31729),在这里我使用了同样的方法,但根据titlingpage环境进行了调整,通过修补\mem@titlingpage及其“朋友” \endmem@titlingpage

最后,只要没有\setcounter{page}发生其他明确的操作,这将消除警告并提供正确的超锚点。

另一个可能的解决方案(但未经测试):使用或 中的hypertexnames=false选项。hyperref\hypersetup

\documentclass[a4paper]{memoir}


\usepackage{xpatch}

\newcounter{pagenumberingcalls}
\newcommand{\pagenumberingchanges}{\thepagenumberingcalls}

\makeatletter

\AtBeginDocument{%
  \xpretocmd{\pagenumbering}{\edef\@previouspagenumberingcalls{\thepagenumberingcalls}\stepcounter{pagenumberingcalls}}{}{}

\@ifpackageloaded{hyperref}{%
  \xpatchcmd{\Hy@EveryPageAnchor}{%
    \hyper@@anchor{page.\@the@H@page}%
  }{%
    \hyper@@anchor{page.\pagenumberingchanges.\@the@H@page}%
  }{\typeout{Patch 1 succeeded}}{\typeout{Patch failure for EveryPageAnchor}}
  \xpatchcmd{\Hy@EveryPageAnchor}{%
    \hyper@@anchor{page.\the\c@page}%
  }{%
    \hyper@@anchor{page.\pagenumberingchanges.\the\c@page}%
  }{\typeout{Patch 2 succeeded}}{}
  \xpatchcmd{\Hy@EveryPageAnchor}{%
    \hyper@@anchor{page.\the\Hy@pagecounter}%
  }{%
    \hyper@@anchor{page.\pagenumberingchanges.\the\Hy@pagecounter}%
  }{\typeout{Patch 3 succeeded}}{}
  }{%Nope, no hyperref loaded --> just be silent%
  }


\xpatchcmd{\mem@titlingpage}{%
  \if\mem@titlpg@reset\setcounter{page}{\@ne}\fi
}{%
  \if\mem@titlpg@reset\stepcounter{pagenumberingcalls}\setcounter{page}{\@ne}\fi
}{\typeout{Successfully patched \string\mem@titlingpage}}{}


\xpatchcmd{\endmem@titlingpage}{%
   \if\mem@titlpg@reset\setcounter{page}{\@ne}\fi
 }{%
   \if\mem@titlpg@reset\stepcounter{pagenumberingcalls}\setcounter{page}{\@ne}\fi
 }{\typeout{Successfully patched \string\endmem@titlingpage}}{}
}



\makeatother


\title{Test}
\usepackage{hyperref}

\begin{document}

\frontmatter
\begin{titlingpage}
  \maketitle
\end{titlingpage}

\tableofcontents

\mainmatter
\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}



\end{document}

答案2

要消除警告,您只需在前两页中使用合适的 来欺骗 hyperref 即可\pagenumbering。任何不同于arabicroman的东西都在之后使用。

\documentclass[a4paper]{memoir}

\title{Test}
\usepackage{hyperref}

\begin{document}

\frontmatter
\pagenumbering{Roman}

\begin{titlingpage}
    \maketitle
\end{titlingpage}

\pagenumbering{roman}
\tableofcontents


\mainmatter


\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\chapter{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}
\section{test}

\end{document}

相关内容