hyperref-pdfpages 交互 addtotoc 在章节级别存在问题

hyperref-pdfpages 交互 addtotoc 在章节级别存在问题

我正在使用以下代码将 pdf 作为附录插入:

\documentclass{memoir}
\usepackage{hyperref}
\usepackage{pdfpages}

\begin{document}
\chapter{one}
text
\appendix
\phantomsection
\includepdf[pages=-,addtotoc={1,chapter,0,{Common Parameters},mylabel}]{mypdf}

\end{document}

\ignorespaces在目录中获得了命令(来自辅助):

\@writefile{toc}{\contentsline {appendix}{\chapternumberline {A}\ignorespaces Common Parameters}{287}{appendix.A}}

hyperref 不喜欢哪个(来自日志):

Package hyperref Warning: Token not allowed in a PDF string (PDFDocEncoding)

所以我查看了 pdfpages.sty 并看到\ignorespaces

\AM@toc@title{\ignorespaces #4}% 

我不喜欢更换包装,但如果我去掉标签,就不会出现任何问题。

这似乎仅当我想要章节级别的目录条目时才会发生,因为这(部分级别)可以正常工作:

\includepdf[pages=-,addtotoc={1,section, 1,{Common Parameters},mylabel}{mypdf}

处理这个问题的正确方法是什么?

答案1

初步分析,问题出在寄存器pdfpages的使用上,由于 的使用导致其内容的扩展被延迟,从而导致 hyperref 对 中执行的处理( )的机制被破坏。(我承认,我并没有追根溯源,只是粗略地看了一眼,然后进行了大胆的猜测)。toks\AM@toc@title\the\ignorespaces\let\ignorespaces\HyPsd@ignorespaces\pdfstringdef

这是残酷的“摆脱”

\documentclass{memoir}
\usepackage{pdfpages}
\usepackage{hyperref}

\makeatletter
\def\AM@parse@toclisti#1,#2,#3,#4,#5,#6\END{%
  \def\AM@toc@page{\AM@trim@space{#1}}%
  \def\AM@toc@section{\AM@trim@space{#2}}%
  \def\AM@toc@level{\AM@trim@space{#3}}%
  \AM@toc@title{#4}% remove \ignorespaces to please hyperref
  \def\AM@toc@label{\AM@trim@space{#5}}%
  \AM@checkinteger{\AM@toc@page}%
  \ifAM@integer\else
    \PackageError{pdfpages}
         {Missing number.\MessageBreak
          Page number in option `addtotoc' is not a number}
         {See the pdfpages manual for explanation.}%
   \fi
}
\makeatother

\begin{document}

%\tracingmacros1

\chapter{one}
text
\appendix
\phantomsection
\includepdf[pages=-,addtotoc={1,chapter,0,{Common Parameters},mylabel}]{example-image.pdf}

\end{document}

但请注意,显然pdfpages\ignorespaces因为#4是分隔参数,因此可能有一个前导空格。因此,不要在中使用前导空格{Common Parameters}

有多种方法可以删除前导空格,这些方法可以合并到中pdfpages,或者更好的是,pdfpages可以添加钩子以使用任何令人愉悦的超链接。(也许\texorpdfstring在某处使用一些?)

无论如何,忽略的警告\ignorespaces只是一个无害的警告。

更成问题的是,任何一个 token 在#4(你所占据的位置){Common parameters}都可能引发类似的问题。


编辑:

也许这可以用来

\makeatletter
\def\AM@parse@toclisti#1,#2,#3,#4,#5,#6\END{%
  \def\AM@toc@page{\AM@trim@space{#1}}%
  \def\AM@toc@section{\AM@trim@space{#2}}%
  \def\AM@toc@level{\AM@trim@space{#3}}%
  \AM@toc@title\expandafter{\romannumeral-`0#4}%
  \def\AM@toc@label{\AM@trim@space{#5}}%
  \AM@checkinteger{\AM@toc@page}%
  \ifAM@integer\else
    \PackageError{pdfpages}
         {Missing number.\MessageBreak
          Page number in option `addtotoc' is not a number}
         {See the pdfpages manual for explanation.}%
   \fi
}
\makeatother

因为它将吞噬来自的一个前导太空标记#4

这只是一种头脑简单的事情,它会有它的缺点。


使用包,xinttools您可以帮助pdfpages移除空间标记,而无需\ignorespaces

\documentclass{memoir}
\usepackage{pdfpages}
\usepackage{hyperref}

\usepackage{xinttools}
\makeatletter
\def\AM@parse@toclisti#1,#2,#3,#4,#5,#6\END{%
  \def\AM@toc@page{\AM@trim@space{#1}}%
  \def\AM@toc@section{\AM@trim@space{#2}}%
  \def\AM@toc@level{\AM@trim@space{#3}}%
  \AM@toc@title\expandafter{\romannumeral0\xintzapfirstspaces{#4}}%
  \def\AM@toc@label{\AM@trim@space{#5}}%
  \AM@checkinteger{\AM@toc@page}%
  \ifAM@integer\else
    \PackageError{pdfpages}
         {Missing number.\MessageBreak
          Page number in option `addtotoc' is not a number}
         {See the pdfpages manual for explanation.}%
   \fi
}
\makeatother

\begin{document}    
\chapter{one}
text
\appendix
\phantomsection
\includepdf[pages=-,addtotoc={1,chapter,0,{Common Parameters},mylabel}]{example-image.pdf}

\end{document}

当然,还有更简单的技巧来删除前导空格:

\makeatletter
\def\AM@parse@toclisti#1,#2,#3,#4#5,#6,#7\END{%
  \def\AM@toc@page{\AM@trim@space{#1}}%
  \def\AM@toc@section{\AM@trim@space{#2}}%
  \def\AM@toc@level{\AM@trim@space{#3}}%
  \AM@toc@title{#4#5}%
  \def\AM@toc@label{\AM@trim@space{#6}}%
  \AM@checkinteger{\AM@toc@page}%
  \ifAM@integer\else
    \PackageError{pdfpages}
         {Missing number.\MessageBreak
          Page number in option `addtotoc' is not a number}
         {See the pdfpages manual for explanation.}%
   \fi
}
\makeatother

但随后您将面临牙套拆除问题。这可能不重要(或不重要)。


为了说明我的观点,即不兼容性很深,请考虑以下情况

\includepdf[pages=-,addtotoc={1,chapter,0,{Common \textbf{Parameters}},mylabel}]{example-image.pdf}

那么你将hyperref抱怨\textbf。事实上,在第四个参数中放入任何类型的标记(通常hyperref知道如何在 PDF 书签中处理)都会触发警告。因为标记在重新定义时未展开hyperref,后来 hyperref 看到它并抱怨。这是一个需要在包方面修复的问题pdfpages

相关内容