为 PDF 添加页码和行号

为 PDF 添加页码和行号

是否有任何快速脚本可以为 pdf 文档的每一页添加页码和行号?

  1. 我经常会收到 pdf 格式的文章来审阅,没有页码。我最终用手写它们,以便在指出错误时参考每一页。

  2. 当引用错误时,我最终会手动从头或尾计算行数,或复制上下文,以精确定位错误的位置。如果有一种标准方法可以向现有文档添加行号,那就更实用了。

我可以设法编辑 LaTeX 源来获得它,但当我收到 pdf 时则不行。PDF 格式本身不包含线条,因此识别它们需要对字母的 $y$ 坐标进行聚类,并且在边距中添加这些数字需要取 $x$ 坐标的最小值并从中删除一个固定量。有人已经使用过这个脚本,或者见过其他方法吗?

答案1

好吧,下面开始在无需访问源代码的情况下对 PDF(或任何其他图像格式)中的行进行编号。

我编写了一个小型 shell 脚本,使用 ImageMagick(至少版本 6.6.9-4),将给定的 PDF 转换为每页单独的光栅图像,将它们分成半页,将它们缩小为一个像素的宽度(因此基本上取水平平均值),将其转换为具有给定阈值的单色图像(黑色=文本,白色=无文本),将每个黑色序列缩小到一个像素(=一行的中间),将其作为文本输出,通过管道sed进行清理并删除所有非文本行,最后写入一个txt文件,其中每行的位置为文本高度的 1/1000。

findlines.sh

convert $1.pdf -crop 50x100% png:$1
for f in $1-*; do 
convert $f -flatten -resize 1X1000! -black-threshold 99% -white-threshold 10% -negate -morphology Erode Diamond -morphology Thinning:-1 Skeleton -black-threshold 50% txt:-| sed -e '1d' -e '/#000000/d' -e 's/^[^,]*,//' -e 's/[(]//g' -e 's/:.*//' -e 's/,/ /g' > $f.txt;
done

运行该脚本大约需要 1 秒钟才能处理一页,从而生成多个文件:basename-<number>.txt,其中奇数<numbers>包含左侧行号的位置,偶数包含<numbers>右侧页号的位置。然后这些文件可以被pgfplotstable(至少 v 1.4)读取,并用于在导入的文件顶部排版行号pdf。我定义了一个命令,该命令以页码和四个行号作为参数,其中四个行号用于告诉宏“真实”文本行在左列和右列中的哪个“原始”行号开始和结束。通过设置\pgfkeys{print raw line numbers=true},算法找到的原始行号显示为红色。

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplotstable}

\newif\ifprintrawlinenumbers
\pgfkeys{print raw line numbers/.is if=printrawlinenumbers,
  print raw line numbers=true}
\newcommand{\addlinenumbers}[5]{
  \pgfmathtruncatemacro{\leftnumber}{(#1-1)*2}
  \pgfmathtruncatemacro{\rightnumber}{(#1-1)*2+1}
  \pgfplotstableread{\pdfname-\leftnumber.txt}\leftlines
  \pgfplotstableread{\pdfname-\rightnumber.txt}\rightlines
  \begin{tikzpicture}[font=\tiny,anchor=east]
  \node[anchor=south west,inner sep=0] (image) at (0,0) {\includegraphics[width=14cm,page=#1]{\pdfname.pdf}};
    \begin{scope}[x={(image.south east)},y={(image.north west)}]
      \pgfplotstableforeachcolumnelement{[index] 0}\of\leftlines\as\position{
        \ifprintrawlinenumbers
          \node [font=\tiny,red] at (0.04,1-\position/1000)         {\pgfplotstablerow};
        \fi
        \pgfmathtruncatemacro{\checkexcluded}{
          (\pgfplotstablerow>=#2 && \pgfplotstablerow<=#3) ? 1 : 0)
        }
        \ifnum\checkexcluded=1
          \pgfmathtruncatemacro\linenumber{\pgfplotstablerow-#2+1}
          \node [font=\tiny,align=right,anchor=east] at (0.08,1-\position/1000) {\linenumber};
        \fi
      }
      \pgfplotstablegetrowsof{\leftlines}
      \pgfmathtruncatemacro\rightstart{min((\pgfplotsretval-#2),(#3-#2+1))}
      \pgfplotstableforeachcolumnelement{[index] 0}\of\rightlines\as\position{
        \ifprintrawlinenumbers
          \node [font=\tiny,red,anchor=east] at (1.0,1-\position/1000) {\pgfplotstablerow};
        \fi
        \pgfmathtruncatemacro{\checkexcluded}{
                  (\pgfplotstablerow>=#4 && \pgfplotstablerow<=#5) ? 1 : 0)
        }
        \ifnum\checkexcluded=1
          \pgfmathtruncatemacro\linenumber{\pgfplotstablerow-#4+\rightstart+1}
          \node [font=\tiny] at (0.96,1-\position/1000) {\linenumber};
        \fi
      }
    \end{scope}
  \end{tikzpicture}
}

\begin{document}

\def\pdfname{article}
\addlinenumbers{1}{20}{50}{2}{65}
\pgfkeys{print raw line numbers=false}
\addlinenumbers{2}{0}{69}{0}{64}
\addlinenumbers{3}{19}{47}{21}{48}

\end{document}

作为概念证明,以下是环境科学与技术杂志文章。我认为它确实很好用。不过,我还不能从findlines.shLaTeX 内部调用,这一步必须在编译.tex文件之前手动执行。

带有行号的 PDF 第一页

pdf 的第二页,带有行号

答案2

您可以使用以下方式轻松完成(1)pdfpages包裹。

\documentclass{article}
\usepackage{pdfpages}
\begin{document}
\includepdf[pages=1-,pagecommand={\thispagestyle{plain}}]{<pdffile>}
\end{document}

在示例文档中,我只是将页面样式传递plain给了pagecommand,但使用fancyhdr包,您可以制作任何您喜欢的额外页眉/页脚。要正确放置页码,您可能还需要使用包调整边距geometry。例如:

\documentclass{article}
\usepackage[margin=.5in]{geometry}
\usepackage{pdfpages}
\usepackage{fancyhdr}
\fancyhf{}
\renewcommand{\headrulewidth}{0pt}
\lfoot{\textit{My pdf document}}
\rfoot{\thepage}
\begin{document} 
\includepdf[pages=1-,pagecommand={\thispagestyle{fancy}}]{<pdffile>}
\end{document}

这将放置一个包含“我的 pdf 文档”在左边,页码在右边。页边距很小,这样页码就不会干扰所包含的文档。

为了确保输出 PDF 的纸张大小与包含的 PDF 相同,请将选项添加fitpaper\includepdf。摘自pdfpages手册:

fitpaper 将纸张尺寸调整为插入文档的尺寸。

请参阅 Jake 的回答,了解向现有 pdf 添加行号的非常巧妙的方法。

答案3

如果我理解您需要在 PDF 中添加行号,您可以使用该lineno包。但是,它只会根据 LaTeX 设置文本的方式添加行号,这可能与源代码有很大不同。

\documentclass[11pt,a4paper]{article}
\usepackage{lineno}
\usepackage{lipsum}
\begin{document}
    \linenumbers
    \lipsum
\end{document}

行号示例

答案4

您还可以考虑使用 PDF 注释来注释 PDF 文件。您不再需要 Adob​​e Acrobat。Adobe Reader X 现在支持 PDF 文本和高亮标记注释。还有其他替代方案,如 Foxit Reader 或 PDF X-Change viewer。如果您还有 LaTeX 源,您可以使用类似pdfcomment。它比 Adob​​e Reader 提供的功能更灵活、更强大。

在此处输入图片描述

相关内容