R语言 通过命令行创建书签到PDF文件

50pmv0ei  于 2023-09-27  发布在  其他
关注(0)|答案(5)|浏览(172)

我正在寻找一个命令行工具添加书签到PDF文件。
我有page numberlabel。想创建书签称为label链接到页面page number
有没有人知道一个命令行工具(最好是OSX)来做到这一点?
我有大约4000页的PDF文件和大约150个书签,我很乐意将其自动化。
我的计划是在r-script中使用系统调用。

编辑

我创建了大约4000个带有图形的PDF文件,并使用OSX系统命令/System/Library/Automator/Combine PDF Pages.action/Contents/Resources/join.py将PDF连接在一起。以前我使用的是pdfjam包中的pdfjoin,但这太慢了。最后,这就是我如何得到我的PDF,我用Adobe Acrobat Professional手动添加书签的时刻。

4bbkushb

4bbkushb1#

也可以使用**pdftk。它也可以for OS X**使用。
我不打算在这里和现在通过所有的细节,因为它已经在其他地方做了很长时间。简单地说:
1.从您的原始文件创建一个示例PDF(不带书签)。
1.使用Adobe Acrobat添加 * 一些 * 书签(您似乎可以访问)。
1.运行以下命令之一:

pdftk my.pdf dump_data output -
pdftk my.pdf dump_data output bookmarks+otherdata.txt

1.研究输出的格式。
1.通过添加所需的所有条目来修改输出.txt文件。
1.再次运行PDFTK:

pdftk my.pdf update_info bookmarks.txt output bookmarked.pdf

其他信息

这是我在上面的步骤4中检查后注意到的书签格式。

BookmarkBegin
BookmarkTitle: -- Your Title 1 --
BookmarkLevel: 1
BookmarkPageNumber: 1
BookmarkBegin
BookmarkTitle: -- Your Title 2 --
BookmarkLevel: 1
BookmarkPageNumber: 2
BookmarkBegin
BookmarkTitle: -- Your Title 3 --
...
...
and so on...

并替换上述。在适当的地方。

643ylb08

643ylb082#

这是另一个答案。这一个使用Ghostscript处理PDF到PDF,并使用**pdfmark**PostScript操作符插入书签。
有关pdfmark主题的一些介绍,请参阅:

该方法包括两个步骤:
1.创建一个文本文件(实际上是一个pdfmark文件),使用有限的pdfmark命令集,每行一个,并添加您想要添加的书签。
1.运行Ghostscript命令,处理您当前的PDF文件以及文本文件。

第一名。

文本文件上的内容应该类似于以下内容:

[/Page 1   /View [/XYZ null null null] /Title (This is page 1)         /OUT pdfmark
[/Page 2   /View [/XYZ null null null] /Title (Dunno which page this is....) /OUT pdfmark
[/Page 3   /View [/XYZ null null null] /Title (Some other name)        /OUT pdfmark
[/Page 4   /View [/XYZ null null null] /Title (File 4)                 /OUT pdfmark
[/Page 5   /View [/XYZ null null null] /Title (File 5)                 /OUT pdfmark
[/Page 6   /View [/XYZ null null null] /Title (File 6)                 /OUT pdfmark
[/Page 7   /View [/XYZ null null null] /Title (File 7)                 /OUT pdfmark
% more lines for more pages to bookmark...
[/Page 13  /View [/XYZ null null null] /Title (File 13)                /OUT pdfmark
[/Page 14  /View [/XYZ null null null] /Title (Bookmark for page 14)   /OUT pdfmark
% more lines for more pages to bookmark...

例如,将此文件命名为:addmybookmarks.txt

二号。

现在运行以下命令:

gs -o bookmarked.pdf   \
   -sDEVICE=pdfwrite   \
    addmybookmarks.txt \
   -f original.pdf

生成的PDF bookmarked.pdf现在包含书签。请参阅此屏幕截图:

lp0sw83n

lp0sw83n3#

好吧,这里有一个快速而肮脏的方法可以同时做三份工作:
1.合并您的400个单页PDF。
1.创建文档顶层目录(目录)。
1.为每个页面创建一个PDF书签。
它涉及使用LaTeX安装。
你从一个像下面这样的空LaTeX模板开始:

\documentclass[]{article}
\usepackage{pdfpages}
\usepackage{hyperref}
    \hypersetup{breaklinks=true,
                bookmarks=true,
                pdfauthor={},
                pdftitle={},
                colorlinks=true,
                citecolor=blue,
                urlcolor=blue,
                linkcolor=magenta,
                pdfborder={0 0 0}}
\begin{document}

{
    \hypersetup{linkcolor=black}
    \setcounter{tocdepth}{3}
    % Comment next line in or out if you want a ToC or not:
    \tableofcontents
}

%% Here goes your additional code:
%% 1 line per included PDF!

\end{document}

现在,就在此模板的最后一行之前,为每个要包含的外部PDF文件插入一行。
1.如果你想生成一个ToC,它必须像这样格式化:

\includepdf[pages={<pagenumber>},addtotoc{<pagenumber>,<section>,<level>,\
                   <heading>,<label>}]{pdffilename.pdf}

1.如果您确定每个包含的PDF都是1页文档,则可以简化为:

\includepdf[addtotoc{<pagenumber>,<section>,<level>,\
                     <heading>,<label>}]]{pdffilename.pdf}

这里addtotoc的以下五个参数 * 全部 * 都是必需的,按照文件在书签和目录中出现的顺序。具体示例进一步参见下文:

*<pagenumber>:要链接到的插入文档的页码。(在您的情况下总是“1”,因为您只插入1页文档;您可以插入一个5页的文档,并链接到插入的PDF的第3页)。
*<section>:LaTeX分区名称。可能是sectionsubsectionsubsubsection...在你的案子里是“部门”。
*<level>:LaTeX部分的级别。在你的情况下是“1”。
*<heading>:这是一个字符串。用于书签的文本
*<label>:对于每个书签,此值必须唯一。在PDF内部使用,用于在单击书签时跳转到正确的页面。

为了快速测试,我使用Ghostscript生成了20个单页PDF文档:

for i in {1..20}; do
   gs -o p${i}.pdf -sDEVICE=pdfwrite               \
      -c "/Helvetica findfont 30 scalefont setfont \
          100 600 moveto                           \
          (Page ${i}) show                         \
          showpage"; 
done

有了这些测试文件,我可以使插入到模板中的行看起来像这样:

\includepdf[addtotoc={1,section,1,Page 1 (First),p1}]{p1.pdf}
\includepdf[addtotoc={1,section,1,Page 2,p2}]{p2.pdf}
\includepdf[addtotoc={1,section,1,Page 3,p3}]{p3.pdf}
[...]
\includepdf[addtotoc={1,section,1,Page 11 (In the Middle),p11}]{p11.pdf}
[...]
\includepdf[addtotoc={1,section,1,Page 20 (Last),p20}]{p20.pdf}

保存插入行的模板,然后运行以下命令 * 两次 *:

pdflatex template.tex
 pdflatex template.tex

生成的文件将包含书签,在Preview.app中如下所示:

  • 注:* LaTeX可通过两种方法在OSX上使用:
  • MacPorts
  • TeXLive/MacTex
  • 我将添加一个或两个其他方法来插入书签在命令行上太,以后或在未来几天,如果我有更多的时间。*
  • 现在这一个必须做,因为我从来没有在这里显示它在SO,AFAICR。*
  • 但我认为,因为你给的背景“我合并1页PDF,它是缓慢的;现在我也想添加书签......”,我可以用一个方法来演示如何做到这一点。
  • 提示 另一种方法是使用pdftk,它**可用于Mac OS X!*
n7taea2i

n7taea2i4#

下面是向目录添加书签的python方法。在MacOS上运行,无需任何其他安装。

#!/usr/bin/python    
from Foundation import  NSURL, NSString
import Quartz as Quartz
import sys

# You will need to change these filepaths to a local test pdf and an output file.
infile = "/path/to/file.pdf"
outfile = "/path/to/output.pdf"

def getOutline(page, label):
    # Create Destination
    myPage = myPDF.pageAtIndex_(page)
    pageSize = myPage.boundsForBox_(Quartz.kCGPDFMediaBox)
    x = 0
    y = Quartz.CGRectGetMaxY(pageSize)
    pagePoint = Quartz.CGPointMake(x,y)
    myDestination = Quartz.PDFDestination.alloc().initWithPage_atPoint_(myPage, pagePoint)
    myLabel = NSString.stringWithString_(label)
    myOutline = Quartz.PDFOutline.alloc().init()
    myOutline.setLabel_(myLabel)
    myOutline.setDestination_(myDestination)
    return myOutline

pdfURL = NSURL.fileURLWithPath_(infile)
myPDF = Quartz.PDFDocument.alloc().initWithURL_(pdfURL)
if myPDF:
    # Here's where you list your page index (starts at 0) and label.
    outline1 = getOutline(0, 'Page 1')
    outline2 = getOutline(1, 'Page 2')
    outline3 = getOutline(2, 'Page 3')

    # Create a root Outline and add each outline. (Needs a loop.)
    rootOutline = Quartz.PDFOutline.alloc().init()
    rootOutline.insertChild_atIndex_(outline1, 0)
    rootOutline.insertChild_atIndex_(outline2, 1)
    rootOutline.insertChild_atIndex_(outline3, 2)
    myPDF.setOutlineRoot_(rootOutline)
    myPDF.writeToFile_(outfile)
zkure5ic

zkure5ic5#

交叉发布from here
更好的方法是使用cpdf和LLM(大型语言模型),如GPT4。要使用PDF的目录(TOC)和cpdf将书签添加到PDF,请执行以下步骤:
1.提取目录:使用光学字符识别(OCR)工具(例如ocrmypdf),然后以文本形式从PDF中提取TOC。

*cpdf目录格式:该工具需要特定格式level page "Title"

其中:

  • 级别为0表示主要章节,1表示子章节等。
  • page是页码。
  • 标题是章节或子章节的名称。

例如:

0 5 "Introduction"
1 6 "History"
0 10 "Main Content"
1 11 "Sub-topic 1"

您通常可以使用LLM的提示来从1获取文本。in this format格式.

*保存格式化目录:将数据保存到文本文件中,例如toc_cpdf. txt。
*使用cpdf添加书签

cpdf -add-bookmarks toc_cpdf.txt in.pdf -o out.pdf

这需要in.pdf,使用toc_cpdf.txt作为书签,并输出到out.pdf
现在,out.pdf将根据原始文档的TOC拥有书签。
有关cpdf的详细信息(包括安装说明),请参考cpdf usage examples

相关问题