我有一个文档,我链接到很多的外部 .pdf 和图像文件。使用此文档的人需要拥有所有链接文档和图像的硬拷贝。因此,我希望将所有链接文件包含在实际文档中,以便于打印,同时也提供文档的页面参考,以便于找到它们。
在 MWE 中,我手动将链接的文档包含在末尾。但是遇到了一些问题:
- 无法通过以下方式显示页面范围
cleverref
- 想要链接到任何包含的 .pdf 的第一页和最后一页
笔记:
- 在我的实际使用情况下,我将在每个页面上包含文件名和物理页码,但这里不包括这些,以减小 MWE 的大小。
- 我使用的文件可以从以下网址获取https://www.dropbox.com/sh/ibn44ut007gwzyl/AADGxdzSXvNTiKC-AJ22NLF1a?dl=0或者您可以使用自己的文件,因为问题并不特定于这些文件。
代码:
\documentclass{article}
\usepackage{hyperref}
\usepackage{xparse}
\usepackage{graphicx}
\usepackage{pdfpages}
\usepackage{xcolor}
\usepackage{lipsum}
\usepackage{xstring}
\usepackage{cleveref}
\usepackage[export]{adjustbox}% http://tex.stackexchange.com/questions/6073/scale-resize-large-images-graphics-that-exceed-page-margins
\NewDocumentCommand{\AddLinkToFile}{%
m% #1 = text to display
m% #2 = file to open upon clicking
}{%
\edef\ExpandedFileName{#2}%
\IfFileExists{"#2"}{%
\hspace*{1.0cm}File: \href{run:\ExpandedFileName}{\textcolor{blue}{#1}}%
\IfEndWith{#2}{.pdf}{% .pdf files has a page range
\hfill\Cpagerefrange{#1 Start}{#1 End}%
}{% non .pdf files are only a single page.
\hfill\Cpageref{#1}%
}%
}{%
\hspace*{1.0cm}File: \href{run:\ExpandedFileName}{\textcolor{orange}{#1}}%
\typeout{**** Warning: Failed to link file "\ExpandedFileName".}%
}%
}%
\begin{document}
\AddLinkToFile{Kant 1}{kant.pdf}
\AddLinkToFile{Eiffel 1}{../images/EiffelWide.jpg}
\AddLinkToFile{Lipsum 1}{lipsum.pdf}
\pagenumbering{gobble}
%% Now include the links files (eventually need to automate from here to end)
\newpage
\phantomsection\label{Kant 1 Start}%
\includepdf[pagecommand={\thispagestyle{plain}}, pages=1-last]{kant.pdf}
\phantomsection\label{Kant 1 End}%
%% If non .pdf we can have multiple images per page, so no \newpage here
\phantomsection\label{Eiffel 1}%
\includegraphics[max width=\linewidth,keepaspectratio=true]{../images/EiffelWide.jpg}
\newpage
\phantomsection\label{Lipsum 1 Start}%
\includepdf[pagecommand={\thispagestyle{plain}}, pages=1-last]{lipsum.pdf}
\phantomsection\label{Lipsum 1 End}%
\end{document}
答案1
感谢@cfr建议我确定 的页数.pdf
,我终于想出了一个解决方案。此版本用 标记 的每一<file>.pdf
页
\label{<file>.pdf <n>}
其中<n>
是一个计数器,从 1 开始一直到此页数.pdf
。在页码引用中,我获取外部 PDF 的页数并链接到
\Cpagerefrange{<file>.pdf 1}{<file>.pdf \the\pdflastximagepages}
- 使用该
background
包在右下角空白处添加页码,以便所包含的 .pdf 文件中的任何页码都不会被更改。 - 处理同一个文件被多次包含的情况(当第二阶段自动化时很有用)
.pdf
通过单页提供文件的特殊处理。- 我尝试自动化这个发布在使用 cleverref 自动解决扩展问题,显示包含的 .pdf 文件的页面范围。
代码:
\documentclass{article}
\usepackage{xparse}
\usepackage{graphicx}
\usepackage{pdfpages}
\usepackage{xcolor}
\usepackage{lipsum}
\usepackage{xstring}
\usepackage{etoolbox}
%\usepackage{fancyhdr}
\usepackage[export]{adjustbox}% https://tex.stackexchange.com/questions/6073/scale-resize-large-images-graphics-that-exceed-page-margins
\usepackage[all,nodeanchor={south east}, color=magenta, opacity=1]{background}
\usepackage{hyperref}
\usepackage{cleveref}
%% Use background package to add actual page numbers in bottom right hand of margin
\newcommand{\FileName}{}
\SetBgContents{\tikz \node at (0,0) {Page \thepage\rotatebox{90}{\hspace*{2.0em}\ttfamily\FileName}};}
\SetBgPosition{current page.south east}
\SetBgHshift{-0.5em}
\SetBgVshift{0.5ex}
\SetBgAngle{0.0}% Select rotation
\SetBgScale{2.0}% Select scale factor
\NewDocumentCommand{\AddLinkToFile}{%
m% #1 = text to display
m% #2 = file to open upon clicking
}{%
\edef\ExpandedFileName{#2}%
\par
\IfFileExists{"#2"}{%
File: \href{run:\ExpandedFileName}{\textcolor{blue}{#1}}%
\IfEndWith{#2}{.pdf}{% .pdf files has a page range
%% https://tex.stackexchange.com/questions/198091/get-number-of-pages-of-external-pdf
\pdfximage{#2}%
\edef\LastPage{\the\pdflastximagepages}%
\ifnum\LastPage=1
\hfill\Cpageref{#2 1}% Only a single page in this .pdf
\else
%% Page range is page "1" to \LastPage of this .pdf
\hfill\Cpagerefrange{#2 1}{#2 \LastPage}%
\fi
}{% non .pdf files are only a single page.
\hfill\Cpageref{#2}%
}%
}{%
File: \href{run:\ExpandedFileName}{\textcolor{orange}{#1}}%
\typeout{**** Warning: Failed to link file "\ExpandedFileName".}%
}%
}%
\newcounter{CurrentPageNumber}
\newcommand*{\LabeThisPage}[1]{%
% #1 = label prefix
\thispagestyle{empty}%
\stepcounter{CurrentPageNumber}%
\phantomsection%
\label{#1 \arabic{CurrentPageNumber}}%
}%
\newcommand*{\IncludePdfFile}[1]{%
% #1 = .pdf file name (with path)
\ifcsdef{#1 Previously Linked}{}{%
\newpage%
\setcounter{CurrentPageNumber}{0}%
\def\FileName{File = #1}%
\includepdf[pagecommand={\LabeThisPage{#1}}, pages=1-last]{#1}%
\csdef{#1 Previously Linked}{}% No need to re-include this file
}%
}%
\newcommand*{\IncludeImageFile}[1]{%
% #1 = image file name (with path) non .pdf)
%% For non .pdf file we can place multiple images per page, so no \newpage here
\phantomsection%
\label{#1}%
\def\FileName{File = #1}%
\includegraphics[max width=\linewidth,keepaspectratio=true]{#1}%
}%
\begin{document}
\AddLinkToFile{Kant 1}{kant.pdf}
\AddLinkToFile{Lipsum Single Page}{lipsum1.pdf}
\AddLinkToFile{Eiffel 1}{../images/EiffelWide.jpg}
\AddLinkToFile{Lipsum 1}{lipsum.pdf}
\AddLinkToFile{Kant 1 Duplicate Link}{kant.pdf}
%% --------------------------------------------------------------------------
%% Now include the linked files (eventually need to automate from here to end)
%%
\pagestyle{empty}
\IncludePdfFile{kant.pdf}%
\IncludePdfFile{lipsum1.pdf}%
\IncludeImageFile{../images/EiffelWide.jpg}%
\IncludePdfFile{lipsum.pdf}%
\IncludePdfFile{kant.pdf}%
\end{document}
答案2
这几乎是你能得到的最不优雅的了,但也许它会在某些方面提供有用的建议。
它不适用于cleveref
PDF 包含在文档末尾的情况,因为我无法弄清楚如何让它工作。相反,它使用标准\pageref
来处理这种情况,并引用了pageslts
。
为了实现这一点,您需要为每个文件分配一个标签,该标签在添加链接时使用,然后在包含 PDF 时使用。因此,包装器用于\includepdf
。从积极的一面来看,这意味着您不必明确添加pagecommand
。(您必须添加标签。)
\includelinkedpdf{<tag>}[<options>]{<file>}
包括 PDF 并添加了大量标签。注意:它添加的标签比添加的页面多。它还会在 PDF 之后的第一页上添加标签(如果有的话)。(这就是为什么如果 PDF 是文档中的最后一个,就会出现问题的原因。)
\AddLinkToFile{<tag>}{<text>}{<file>}
添加链接。第一页的链接很简单。最后一页的链接使用一组放置在所包含 PDF 页面上的标签。每个标签都有一个pg:p<no>
以 1 开头的形式的标签。该命令获取引用<tag> End
并获取该引用的标准页码(如果有)。如果页码为0
,我们假设这是文档中的最后一项并使用pageslts
的标签。否则,我们减去引用的页码pg:p1
。然后,我们将结果设置为一个计数器并使用它来创建指向的链接pg:p<result>
。这……呃……似乎有效……可能。
请注意,hyperref
最后加载时会出现某些例外,特别是cleveref
。pageslts
表示添加plainpages=false,pdfpagelabels=true
,所以我这样做了。如果未设置pageslts
则会出现错误,因此我将其添加到。\pagenumbering{}
\begin{document}
如果您不想在包含的 PDF 上显示页码,请使用\pagestyle{empty}
代替\pagestyle{plain}
。如果您使用\pagenumbering{gobble}
,编译将失败并出现错误。
\documentclass{article}
\usepackage{xparse,pageslts}
\usepackage{graphicx}
\usepackage{pdfpages}
\usepackage{xcolor}
\usepackage{lipsum}
\usepackage{xstring}
\usepackage[export]{adjustbox}% http://tex.stackexchange.com/questions/6073/scale-resize-large-images-graphics-that-exceed-page-margins
\usepackage[plainpages=false,pdfpagelabels=true]{hyperref}
\usepackage{cleveref}
\AtBeginDocument{\pagenumbering{arabic}}
\makeatletter
\NewDocumentCommand{\AddLinkToFile}{%
m% #1 = tag
m% #2 = text to display
m% #3 = file to open upon clicking
}{%
\edef\ExpandedFileName{#2}%
\IfFileExists{"#3"}{%
\hspace*{1.0cm}File: \href{run:\ExpandedFileName}{\textcolor{blue}{#2}}%
\IfEndWith{#3}{.pdf}{% .pdf files has a page range
\hfill
\edef\tempa{\hypergetpageref{#1 End}}%
\ifnum\tempa=0 Pages \pageref{#1 Start} to \lastpageref{VeryLastPage}%
\else
\edef\tempb{\hypergetpageref{pg:p1}}%
\setcounter{grill@pg}{\tempa}%
\addtocounter{grill@pg}{-\tempb}%
\Cpagerefrange{#1 Start}{pg:p\thegrill@pg}%
\fi
}{% non .pdf files are only a single page.
\hfill\Cpageref{#1}%
}%
}{%
\hspace*{1.0cm}File: \href{run:\ExpandedFileName}{\textcolor{orange}{#2}}%
\typeout{**** Warning: Failed to link file "\ExpandedFileName".}%
}%
}
\newcounter{grill@page}
\setcounter{grill@page}{0}
\newcounter{grill@pg}
\setcounter{grill@pg}{0}
\NewDocumentCommand\includelinkedpdf { m O {} m }{%
\def\makefirststyle{\phantomsection\label{#1 Start}}%
\def\makedynstyle{\makefirststyle\thispagestyle{plain}\stepcounter{grill@page}\phantomsection\label{pg:p\thegrill@page}\global\let\makefirststyle\relax}%
\includepdf[
pagecommand={\makedynstyle},
#2,
]{#3}%
\phantomsection\label{#1 End}%
\clearpage
}
\makeatother
\begin{document}
\AddLinkToFile{kant}{Kant 1}{kant.pdf}
\AddLinkToFile{eiffel}{Eiffel 1}{example-image-a.png}
\AddLinkToFile{lipsum}{Lipsum 1}{lipsum.pdf}
\includelinkedpdf{kant}[pages=1-last]{kant}
\includegraphics[max width=\linewidth,keepaspectratio=true]{example-image-a}\label{eiffel}
\includelinkedpdf{lipsum}[pages=1-last]{lipsum}
\end{document}
编辑
在上面,标签仅用于在开始和结束时创建标签。如果您确信文件名可以安全使用,则显然可以使用它,或者使用可选覆盖将其设为默认值。
在下面的代码中,我以这种方式指定标签为可选项。对于 PDF 包含,可选参数由 分隔,()
因为该宏已经有一个常规可选参数。显然,这可以进行调整以适应。
这次编辑的重点是展示如何\label
在包含的 PDF 的每一页上不添加额外的 s。代码假设
- 使用 pdfTeX 进行编译;
- 每个包含的 PDF 的每一页都被使用。
在这种情况下,我们可以使用 来计算页面数\pdfximage
。这样就无需创建结束标签。我们可以通过依赖用于hyperref
启用索引的机制来避免每页上的额外标签。这会在每个页面上添加一个锚点,索引条目可以将其作为 来访问\hyperpage{}
。我不确定如何让它与 一起工作cleveref
,但我不太了解那个包。
\documentclass{article}
\usepackage{xparse}
\usepackage{graphicx}
\usepackage{pdfpages}
\usepackage{xcolor}
\usepackage{lipsum}
\usepackage{xstring}
\usepackage[export]{adjustbox}% http://tex.stackexchange.com/questions/6073/scale-resize-large-images-graphics-that-exceed-page-margins
\usepackage{hyperref}
\usepackage{cleveref}
\makeatletter
\NewDocumentCommand{\AddLinkToFile}{%
o% #1 = tag
m% #2 = text to display
m% #3 = file to open upon clicking
}{%
\IfValueTF{#1}{%
\edef\grill@tag{#1}%
}{%
\edef\grill@tag{#3}%
}%
\edef\ExpandedFileName{#2}%
\IfFileExists{"#3"}{%
\hspace*{1.0cm}File: \href{run:\ExpandedFileName}{\textcolor{blue}{#2}}%
\IfEndWith{#3}{.pdf}{% .pdf files has a page range
\pdfximage {#3}%
\setcounter{grill@pg}{\the\pdflastximagepages}%
\edef\tempa{\hypergetpageref{\grill@tag Start}}%
\addtocounter{grill@pg}{\tempa-1}%
\hfill
Pages \pageref{\grill@tag Start} to \hyperpage{\thegrill@pg}
}{% non .pdf files are only a single page.
\hfill\Cpageref{\grill@tag}%
}%
}{%
\hspace*{1.0cm}File: \href{run:\ExpandedFileName}{\textcolor{orange}{#2}}%
\typeout{**** Warning: Failed to link file "\ExpandedFileName".}%
}%
}
\newcounter{grill@pg}
\setcounter{grill@pg}{0}
\NewDocumentCommand\includelinkedpdf { d () O {} m }{%
\IfValueTF{#1}{%
\edef\grill@tag{#1}%
}{%
\edef\grill@tag{#3.pdf}%
}%
\def\makefirststyle{\phantomsection\label{\grill@tag Start}}%
\def\makedynstyle{\makefirststyle\thispagestyle{plain}\global\let\makefirststyle\relax}%
\includepdf[
pagecommand={\makedynstyle},
#2,
]{#3}%
}
\makeatother
\begin{document}
\AddLinkToFile{Kant 1}{kant.pdf}
\AddLinkToFile{Eiffel 1}{example-image-a.png}
\AddLinkToFile{Lipsum 1}{lipsum.pdf}
\includelinkedpdf[pages=1-last]{kant}
\includegraphics[max width=\linewidth,keepaspectratio=true]{example-image-a}\label{example-image-a.png}
\includelinkedpdf[pages=1-last]{lipsum}
\end{document}
输出与以前相同。