如果您在 Postscript 中有一个大文档(500 页以上)并且想要添加页码,有人知道该怎么做吗?
15 回答
基于 rcs 提出的解决方案,我做了以下工作:
将文档转换为example.pdf
并运行pdflatex addpages
,其中addpages.tex
显示:
\documentclass[8pt]{article}
\usepackage[final]{pdfpages}
\usepackage{fancyhdr}
\topmargin 70pt
\oddsidemargin 70pt
\pagestyle{fancy}
\rfoot{\Large\thepage}
\cfoot{}
\renewcommand {\headrulewidth}{0pt}
\renewcommand {\footrulewidth}{0pt}
\begin{document}
\includepdfset{pagecommand=\thispagestyle{fancy}}
\includepdf[fitpaper=true,scale=0.98,pages=-]{example.pdf}
% fitpaper & scale aren't always necessary - depends on the paper being submitted.
\end{document}
或者,对于双面页面(即页码始终在外面):
\documentclass[8pt]{book}
\usepackage[final]{pdfpages}
\usepackage{fancyhdr}
\topmargin 70pt
\oddsidemargin 150pt
\evensidemargin -40pt
\pagestyle{fancy}
\fancyhead{}
\fancyfoot{}
\fancyfoot[LE,RO]{\Large\thepage}
\renewcommand{\headrulewidth}{0pt}
\renewcommand{\footrulewidth}{0pt}
\begin{document}
\includepdfset{pages=-,pagecommand=\thispagestyle{fancy}}
\includepdf{target.pdf}
\end{document}
更改页眉边距的简单方法:
% set margins for headers, won't shrink included pdfs
% you can remove the topmargin/oddsidemargin/evensidemargin lines
\usepackage[margin=1in,includehead,includefoot]{geometry}
你可以简单地使用
pspdf工具
这样:
pspdftool 'number(x=-1pt,y=-1pt,start=1,size=10)' input.pdf output.pdf
查看这两个示例(使用 pspdftool 的未编号和编号pdf)
未编号的pdf
编号的pdf
将此作为第一个命令行参数:
number(start=1, size=40, x=297.5 pt, y=10 pt)
我曾经像在接受的答案中那样使用乳胶将页码添加到我的 pdf 中。
现在我找到了一种更简单的方法:使用enscript
创建带有包含页码的标题的空页面,然后使用pdftk
选项multistamp
将标题放在文件中。
此 bash 脚本需要 pdf 文件,因为它是唯一的参数:
#!/bin/bash
input="$1"
output="${1%.pdf}-header.pdf"
pagenum=$(pdftk "$input" dump_data | grep "NumberOfPages" | cut -d":" -f2)
enscript -L1 --header='||Page $% of $=' --output - < <(for i in $(seq "$pagenum"); do echo; done) | ps2pdf - | pdftk "$input" multistamp - output $output
这可能是一个解决方案:
- 将 postscript 转换为 pdf 使用
ps2pdf
- 创建一个 LaTeX 文件并使用pdfpages包 (
\includepdf
)插入页面 - 在参数中使用
pagecommand={\thispagestyle{plain}}
或来自fancyhdr包的东西\includepdf
- 如果需要 postscript 输出,请通过以下方式将 pdflatex 输出转换回 postscript
pdf2ps
我一直在寻找一个 postscript-only 解决方案,使用 ghostscript。我需要它来合并多个 PDF 并在每一页上放置一个计数器。我发现的唯一解决方案是一个旧的 gs-devel 帖子,我对其进行了极大的简化:
%!PS
% add page numbers document bottom right (20 units spacing , harcoded below)
% Note: Page dimensions are expressed in units of the default user space (72nds of an inch).
% inspired by https://www.ghostscript.com/pipermail/gs-devel/2005-May/006956.html
globaldict /MyPageCount 1 put % initialize page counter
% executed at the end of each page. Before calling the procedure, the interpreter
% pushes two integers on the operand stack:
% 1. a count of previous showpage executions for this device
% 2. a reason code indicating the circumstances under which this call is being made:
% 0: During showpage or (LanguageLevel 3) copypage
% 1: During copypage (LanguageLevel 2 only)
% 2: At device deactivation
% The procedure must return a boolean value specifying whether to transmit the page image to the
% physical output device.
<< /EndPage {
exch pop % remove showpage counter (unused)
0 eq dup { % only run and return true for showpage
/Helvetica 12 selectfont % select font and size for following operations
MyPageCount =string cvs % get page counter as string
dup % need it twice (width determination and actual show)
stringwidth pop % get width of page counter string ...
currentpagedevice /PageSize get 0 get % get width from PageSize on stack
exch sub 20 sub % pagewidth - stringwidth - some extra space
20 moveto % move to calculated x and y=20 (0/0 is the bottom left corner)
show % finally show the page counter
globaldict /MyPageCount MyPageCount 1 add put % increment page counter
} if
} bind >> setpagedevice
如果将其保存到名为的文件pagecount.ps
中,则可以在命令行上使用它,如下所示:
gs \
-dBATCH -dNOPAUSE \
-sDEVICE=pdfwrite -dPDFSETTINGS=/prepress \
-sOutputFile=/path/to/merged.pdf \
-f pagecount.ps -f input1.pdf -f input2.pdf
请注意,必须首先给出 pagecount.ps(从技术上讲,就在页面计数应该开始的输入文件之前)。
如果您不想使用额外的.ps
文件,也可以使用这样的最小化形式:
gs \
-dBATCH -dNOPAUSE \
-sDEVICE=pdfwrite -dPDFSETTINGS=/prepress \
-sOutputFile=/path/to/merged.pdf \
-c 'globaldict /MyPageCount 1 put << /EndPage {exch pop 0 eq dup {/Helvetica 12 selectfont MyPageCount =string cvs dup stringwidth pop currentpagedevice /PageSize get 0 get exch sub 20 sub 20 moveto show globaldict /MyPageCount MyPageCount 1 add put } if } bind >> setpagedevice' \
-f input1.pdf -f input2.pdf
根据您的输入,您可能必须在 if 块的开头/结尾使用gsave
/ 。grestore
除了 Captaincomic 的解决方案之外,我还对其进行了扩展,以支持在任何页面上开始页码。
需要 enscript、pdftk 1.43 或更高版本以及 pdfjam(用于 pdfjoin 实用程序)
#!/bin/bash
input="$1"
count=$2
blank=$((count - 1))
output="${1%.pdf}-header.pdf"
pagenum=$(pdftk "$input" dump_data | grep "NumberOfPages" | cut -d":" -f2)
(for i in $(seq "$blank"); do echo; done) | enscript -L1 -B --output - | ps2pdf - > /tmp/pa$$.pdf
(for i in $(seq "$pagenum"); do echo; done) | enscript -a ${count}- -L1 -F Helvetica@10 --header='||Page $% of $=' --output - | ps2pdf - > /tmp/pb$$.pdf
pdfjoin --paper letter --outfile /tmp/join$$.pdf /tmp/pa$$.pdf /tmp/pb$$.pdf &>/dev/null
cat /tmp/join$$.pdf | pdftk "$input" multistamp - output "$output"
rm /tmp/pa$$.pdf
rm /tmp/pb$$.pdf
rm /tmp/join$$.pdf
例如.. 将其放在 /usr/local/bin/pagestamp.sh 并执行如下:
pagestamp.sh doc.pdf 3
这将从第 3 页开始页码。当您有封面、标题页和目录等时很有用。
不幸的是,enscript 的 --footer 选项已损坏,因此您无法使用此方法获取底部的页码。
我喜欢使用pspdftool ( man page ) 的想法,但我所追求的是页面 x out of y格式和字体样式以匹配页面的其余部分。
要了解文档中使用的字体名称:
$ strings input.pdf | grep Font
要获取页数:
$ pdfinfo input.pdf | grep "Pages:" | tr -s ' ' | cut -d" " -f2
pspdftool
用几个命令把它粘在一起:
$ in=input.pdf; \
out=output.pdf; \
indent=30; \
pageNumberIndent=49; \
pageCountIndent=56; \
font=LiberationSerif-Italic; \
fontSize=9; \
bottomMargin=40; \
pageCount=`pdfinfo $in | grep "Pages:" | tr -s ' ' | cut -d" " -f2`; \
pspdftool "number(x=$pageNumberIndent pt, y=$bottomMargin pt, start=1, size=$fontSize, font=\"$font\")" $in tmp.pdf; \
pspdftool "text(x=$indent pt, y=$bottomMargin pt, size=$fontSize, font=\"$font\", text=\"page \")" tmp.pdf tmp.pdf; \
pspdftool "text(x=$pageCountIndent pt, y=$bottomMargin pt, size=$fontSize, font=\"$font\", text=\"out of $pageCount\")" tmp.pdf $out; \
rm tmp.pdf;
结果如下:
哦,我已经很久没有使用 postscript 了,但是快速浏览一下蓝皮书会告诉你:) www-cdf.fnal.gov/offline/PostScript/BLUEBOOK.PDF
另一方面,Adobe Acrobat 和一些 javascript 也会创造奇迹;)
或者,我确实找到了这个:http ://www.ghostscript.com/pipermail/gs-devel/2005-May/006956.html ,这似乎符合要求(我没有尝试过)
您可以使用免费和开源的pdftools通过单个命令行将页码添加到 PDF 文件。
您可以使用的命令行是(在 GNU/Linux 上,您必须$
在 shell 中转义符号,在 Windows 上则不需要):
pdftools.py --input-file ./input/wikipedia_algorithm.pdf --output ./output/addtext.pdf --text "\$page/\$pages" br 1 1 --overwrite
关于--text
选项:
- 第一个参数是要添加的文本。一些占位符可用。
$page
代表当前页码,而$pages
代表 PDF 文件的总页数。因此,如此制定的选项将为 10 页 PDF 文档的第一页添加类似“1/10”的内容,以此类推为后续页面 - 第二个参数是文本框的锚点。"br" 将定位文本框的右下角
- 第三个参数是文本框锚点的水平位置占页面宽度的百分比。必须是 和 之间的数字
0
,1
用点.
分隔小数 - 第四个参数选项是文本框上锚点的垂直位置,以页面高度的百分比表示。必须是 和 之间的数字
0
,1
用点.
分隔小数
免责声明:我是pdftools的作者
我假设您正在寻找基于 PS 的解决方案。PS 中没有允许您执行此操作的页面级运算符。PageSetup
您需要在每个页面的部分中添加一个页脚类的东西。任何脚本语言都应该能够帮助您。
我试过 pspdftool ( http://sourceforge.net/projects/pspdftool )。
我最终让它工作,但起初我得到了这个错误:
pspdftool: xreftable read error
源文件是使用 pdfjam 的 pdfjoin 创建的,其中包含来自我的 Epson Workforce 的大量扫描以及生成的标签页面。我想不出修复外部参照表的方法,所以我用 pdf2ps 转换为 ps,然后用 pdf2ps 转换回 pdf。然后我可以用它在右下角获得漂亮的页码:
pspdftool 'number(start=1, size=20, x=550 pt, y=10 pt)' input.pdf output.pdf
不幸的是,这意味着任何文本可搜索的页面都不再可搜索,因为文本在 ps 转换中被光栅化了。幸运的是,就我而言,这并不重要。
有什么方法可以修复或清空 pdf 文件的外部参照表,而不会丢失可搜索的页面?
我采用了 Captaincomic 的解决方案并添加了对包含空格的文件名的支持,并提供了有关进度的更多信息
#!/bin/bash
clear
echo
echo This skript adds pagenumbers to a given .pdf file.
echo
echo This skript needs the packages pdftk and enscript
echo if not installed the script will fail.
echo use the command sudo apt-get install pdftk enscript
echo to install.
echo
input="$1"
output="${1%.pdf}-header.pdf"
echo input file is $input
echo output file will be $output
echo
pagenum=$(pdftk "$input" dump_data | grep "NumberOfPages" | cut -d":" -f2)
enscript -L1 --header='||Page $% of $=' --output - < <(for i in $(seq "$pagenum"); do echo; done) | ps2pdf - | pdftk "$input" multistamp - output "$output"
echo done.
我编写了以下shell
脚本来解决使用以下脚本LaTeX
beamer
制作的样式幻灯片的问题inkscape
(我pdftk cat
将幻灯片一起放入最终演示文稿PDF
,然后使用下面的脚本添加幻灯片编号):
#!/bin/sh
# create working directory
tmpdir=$(mktemp --directory)
# read un-numbered beamer slides PDF from STDIN & create temporary copy
cat > $tmpdir/input.pdf
# get total number of pages
pagenum=$(pdftk $tmpdir/input.pdf dump_data | awk '/NumberOfPages/{print $NF}')
# generate latex beamer document with the desired number of empty but numbered slides
printf '%s' '
\documentclass{beamer}
\usenavigationsymbolstemplate{}
\setbeamertemplate{footline}[frame number]
\usepackage{forloop}
\begin{document}
\newcounter{thepage}
\forloop{thepage}{0}{\value{thepage} < '$pagenum'}{
\begin{frame}
\end{frame}
}
\end{document}
' > $tmpdir/numbers.tex
# compile latex file into PDF (2nd run needed for total number of pages) & redirect output to STDERR
pdflatex -output-directory=$tmpdir numbers.tex >&2 && pdflatex -output-directory=$tmpdir numbers.tex >&2
# add empty numbered PDF slides as background to (transparent background) input slides (page by
# page) & write results to STDOUT
pdftk $tmpdir/input.pdf multibackground $tmpdir/numbers.pdf output -
# remove temporary working directory with all intermediate files
rm -r $tmpdir >&2
该脚本读取STDIN
和写入STDOUT
打印诊断pdflatex
输出到STDERR
.
因此,只需将上述代码复制粘贴到文本文件中,例如enumerate_slides.sh
,使其可执行(chmod +x enumerate_slides.sh
)并像这样调用它:
./enumerate_slides.sh < input.pdf > output.pdf [2>/dev/null]
通过调整LaTeX
模板以使用正确documentclass
的纸张大小和样式选项,应该很容易将其调整为任何其他类型的文档。
编辑:
我替换echo
为$(which echo)
因为在ubuntu
符号链接/bin/sh
中默认情况下通过shell内部解释转义序列dash
覆盖覆盖此行为的选项。请注意,您也可以将 LaTeX 模板中的所有内容转义为.echo
-E
\
\\
编辑:
我替换$(which echo)
为printf '%s'
since inzsh
,which echo
返回echo: shell built-in command
而不是/bin/echo
. 有关我最终决定使用的详细信息,请参阅此问题printf
。
也许 pstops ( psutils 的一部分)可以用于此?
我为此使用了 LibreOffice Calc。使用Insert->Field->Page Number添加页码字段很容易。然后您可以将此字段复制并粘贴到其他页面;幸运的是位置没有改变,复制和粘贴可以通过向下箭头键和Ctrl+V快速完成。为我工作了一篇 30 页的文章。500+ 可能容易出错!