是否有任何快速脚本可以为 pdf 文档的每一页添加页码和行号?
我经常会收到 pdf 格式的文章来审阅,没有页码。我最终用手写它们,以便在指出错误时参考每一页。
当引用错误时,我最终会手动从头或尾计算行数,或复制上下文,以精确定位错误的位置。如果有一种标准方法可以向现有文档添加行号,那就更实用了。
我可以设法编辑 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.sh
LaTeX 内部调用,这一步必须在编译.tex
文件之前手动执行。
答案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 文件。您不再需要 Adobe Acrobat。Adobe Reader X 现在支持 PDF 文本和高亮标记注释。还有其他替代方案,如 Foxit Reader 或 PDF X-Change viewer。如果您还有 LaTeX 源,您可以使用类似pdfcomment
。它比 Adobe Reader 提供的功能更灵活、更强大。