![更新:软件包现已在 CTAN 上发布](https://linux22.com/image/373406/%E6%9B%B4%E6%96%B0%EF%BC%9A%E8%BD%AF%E4%BB%B6%E5%8C%85%E7%8E%B0%E5%B7%B2%E5%9C%A8%20CTAN%20%E4%B8%8A%E5%8F%91%E5%B8%83.png)
我需要为大型 PDF 文件添加注释。建议的方法这个答案扩展性不佳:
\documentclass[12pt]{article}
\usepackage{pdfpages}
\usepackage{tikz}
\begin{document}
\includepdf[pagecommand=
{\begin{tikzpicture}[remember picture,overlay]
\node at (current page.center) {overlayed text};
\end{tikzpicture}},pages=1]{filename.pdf}
\includepdf[pages=2-]{filename.pdf}
\end{document}
我的 PDF 文件有 700 页。我随意在文件页面上添加注释(50 多个注释)。现在我的源代码具有以下结构:
第 X 页的注释
\includepdf[pages=(X+1)-(Y-1)]{filename.pdf}
第 Y 页的注释
\includepdf[pages=(Y+1)-(Z-1)]{filename.pdf}
第 Z 页的注释
额外的操作\includepdf
既烦人又容易出错。有没有办法让这个过程自动化?
答案1
更新:软件包现已在 CTAN 上发布
我终于有时间整理我的pdfoverlay
软件包并将其发布到 CTAN。它也在 TeXLive 和 MikTeX 中。请参阅https://ctan.org/pkg/pdfoverlay。
我重新实现了它expl3
并写了一些适当的文档。考虑到下面评论中的一些反馈,语法略有不同。
下面的 MWE 示例现在变成:
\documentclass{article}
\usepackage{pdfoverlay}
\pdfoverlaySetPDF{filename.pdf}
\begin{document}
Annotation on page 1.
\pdfoverlayIncludeToPage{10}
Annotation on page 10.
\pdfoverlayIncludeToPage{50}
Annotation on page 50.
\pdfoverlayIncludeToLastPage
\end{document}
原始答案
我编写了一个专门用于此类用途的包。除了几条注释外,没有其他文档,并且不在 CTAN 中。(我可以添加它,但要等上几周。)它可能还需要进行一些错误检查,以使其更加健壮。
它允许这种事情:
\documentclass{article}
\usepackage{pdfoverlay}
\pdfoverlaySetPDF{filename.pdf}
\begin{document}
Annotation on page 1.
\pdfoverlayMoveToPage{10}
Annotation on page 10.
\pdfoverlayMoveToPage{50}
Annotation on page 50.
\pdfoverlayMoveToLastPage
\end{document}
只需将其保存为pdfoverlay.sty
并将其放在与文件相同的目录中tex
。
%%
%% This file is pdfoverlay.sty'
%%
%% Copyright (c) 2017-2018
%% by David Purton <[email protected]>
%%
%% This work may be distributed and/or modified under the conditions of
%% the LaTeX Project Public License, either version 1.3c of this license
%% or (at your option) any later version. The latest version of this
%% license is in
%% http://www.latex-project.org/lppl.txt
%% and version 1.3c or later is part of all distributions of LaTeX
%% version 2005/12/01 or later.
%%
%% This work is "maintained" (as per the LPPL maintenance status)
%% by David Purton.
%%
%% This work consists of the file pdfoverlay.sty.
%%
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{pdfoverlay}
[2018/04/04 Package for overlaying text on an existing PDF document (DCP)]
\RequirePackage{everypage}
\RequirePackage{graphicx}
\RequirePackage{etoolbox}
\RequirePackage{pdfpages}
\newcounter{pdfoverlay@page}
\newtoggle{pdfoverlay@outputpage}
\toggletrue{pdfoverlay@outputpage}
\newcommand{\pdfoverlay@setpdf}{%
\iftoggle{pdfoverlay@outputpage}
{\ifcsvoid{pdfoverlay@pdf}
{\PackageError{pdfoverlay}
{No PDF file set}
{Set a PDF file using \protect\pdfoverlaySetPDF}}
{\AddToShipoutPictureBG*{%
\ifnum \thepdfoverlay@page>\z@
\unless\ifnum \thepdfoverlay@page>\pdfoverlay@pagecount
\includegraphics[page=\thepdfoverlay@page,
width=\paperwidth,
height=\paperheight]{\pdfoverlay@pdf}%
\fi
\fi}}%
\stepcounter{pdfoverlay@page}}
{}}
\def\pdfoverlay@pdf{}
% set the PDF to output in the background
% \pdfoverlaySetPDF{filename.pdf}
\newcommand{\pdfoverlaySetPDF}[1]{%
\IfFileExists{#1}
{\gdef\pdfoverlay@pdf{#1}%
\edef\AM@currentdocname{#1}%
\AM@getpagecount
\xdef\pdfoverlay@pagecount{\AM@pagecount}}
{\PackageError{pdfoverlay}
{PDF file #1 not found}
{}}}
\setcounter{pdfoverlay@page}{0}%
\AddEverypageHook{\pdfoverlay@setpdf}
% jump to page in background PDF without outputting pages in between
% \pdfovrlaySetPage{n}
% where n is an integer
% NOTE: The page will not actually be outputted
% unless there is some text overlayed on it
\newcommand{\pdfoverlaySetPage}[1]{%
\setcounter{pdfoverlay@page}{#1}%
\addtocounter{pdfoverlay@page}{-1}}
% Move through the PDF to the specified page
% \pdfoverlayMoveToPage{n}
% where n is an integer
% NOTE: The page will not actually be outputted
% unless there is some text overlayed on it
\newcommand{\pdfoverlayMoveToPage}[1]{%
\whileboolexpr
{test {\ifnumcomp{\value{pdfoverlay@page}}<{#1-1}}}
{\null
\clearpage}}
% Move through the PDF to the last page
% NOTE: Any further text will be output on the next page
\newcommand{\pdfoverlayMoveToLastPage}{%
\whileboolexpr
{test {\ifnumcomp{\value{pdfoverlay@page}}<{\pdfoverlay@pagecount-1}}}
{\null
\clearpage}%
\null}
% Toggle outputting the PDF
\newcommand{\pdfoverlayOutputToggle}{%
\iftoggle{pdfoverlay@outputpage}
{\togglefalse{pdfoverlay@outputpage}}
{\toggletrue{pdfoverlay@outputpage}}}
% Resume outputting the PDF
\newcommand{\pdfoverlayOutputToggleTrue}{%
\toggletrue{pdfoverlay@outputpage}}
% Pause outputting the PDF
\newcommand{\pdfoverlayOutputToggleFalse}{%
\togglefalse{pdfoverlay@outputpage}}
% Set page style to empty
\pagestyle{empty}
\endinput
答案2
假设你关于可扩展性的陈述仅仅指手工操作繁琐且容易出错,那么不是为了提高大型 pdf 文件的效率,我向您提出了一个想法,可用于根据您的具体情况实现您自己的命令。
换句话说,它是关于利用计数器来跟踪哪个页面已被注释,并构建一个在给定页面上进行注释的命令,打印所有先前未注释的页面。
坏处:您必须\makeAnnotation
按顺序排列命令(相对于带注释的页面),但这不是什么大问题,我认为您无论如何都会这样做。
\documentclass{article}
\usepackage{etoolbox}
\newcounter{PageOfPdf}
\newcommand{\makeAnnotation}[1]{%
\ifnumequal{#1}{1}{}{%
\stepcounter{PageOfPdf}%
\ifnumequal{#1}{\thePageOfPdf}{}{
\thePageOfPdf-\the\numexpr #1-1 \\
}
}%
annotate on #1 \\
\addtocounter{PageOfPdf}{\numexpr #1-\thePageOfPdf}
}
\newcommand{\lastAnnotation}[1]{%
\makeAnnotation{#1}
{\the\numexpr #1 +1}- \\
}
\begin{document}
\noindent
\makeAnnotation{1}
\makeAnnotation{11}
\makeAnnotation{12}
\lastAnnotation{16}
\end{document}
几点补充说明:
- 如果你需要注释 pdf 文件的第一页,则命令
if
中的外部子句是必需的\makeAnnotation
- 相反,需要使用内部
if
子句来避免在以下两个注释位于连续页面上的情况下打印未注释的 pdf 页面范围 - 该
\lastAnnotation
命令应该打印剩余的页面
还有一些评论:
- 在这里我稍后添加了子句
etoolbox
的包if
;它非常强大,可以用来改进代码 - 可能还有其他我没有考虑到的情况,但主要思想就在这里,你应该能够应付它们,以防万一
- 可能存在更好的想法/方法,欢迎随时提出建议:)