更新:软件包现已在 CTAN 上发布

更新:软件包现已在 CTAN 上发布

我需要为大型 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;它非常强大,可以用来改进代码
  • 可能还有其他我没有考虑到的情况,但主要思想就在这里,你应该能够应付它们,以防万一
  • 可能存在更好的想法/方法,欢迎随时提出建议:)

相关内容