通过命令行

时间:2015-05-18 13:37:46

标签: r macos pdf pdf-generation

我正在搜索命令行工具,以便将书签添加到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连接在一起。以前我使用pdfjoin包中的pdfjam,但这太慢了。最后,这就是我获取PDF的方式,我现在用Adobe Acrobat Professional手工添加书签。

4 个答案:

答案 0 :(得分:7)

您还可以使用 pdftk 。它也可用 for OS X

我现在并没有仔细阅读所有细节,因为它已经在其他地方完成了很长时间。简单地说:

  1. 从原始文件创建示例PDF(无书签)。
  2. 使用Adobe Acrobat(您似乎有权访问)添加部分书签。
  3. 运行以下命令之一:

    pdftk my.pdf dump_data output -
    pdftk my.pdf dump_data output bookmarks+otherdata.txt
    
  4. 研究输出的格式。

  5. 通过添加所需的所有条目来修改输出.txt文件。
  6. 再次运行PDFTK:

    pdftk my.pdf update_info bookmarks.txt output bookmarked.pdf
    
  7. 其他信息

    这是我在上面的步骤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...
    

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

答案 1 :(得分:2)

好的,这是一个快速的方法,可以同时完成三项工作:

  1. 合并您的400页单页PDF。
  2. 创建文档顶级ToC(目录)。
  3. 为每个页面创建一个PDF书签。
  4. 它涉及使用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}
      
    2. 如果您确定每个包含的PDF都是1页的文档,它会简化为:

      \includepdf[addtotoc{<pagenumber>,<section>,<level>,\
                           <heading>,<label>}]]{pdffilename.pdf}
      
    3. 这里需要{strong> 所有 以下五个addtotoc参数,按照给出的文件顺序显示在书签和ToC中。请参阅下面的具体示例:

      • <pagenumber> :要链接到的插入文档的页面编号。 (在您的情况下始终&#34; 1&#34;,因为您只插入1页文档;您可以插入5页文档并链接到插入PDF的第3页)。
      • <section> :LaTeX切片名称。可以是sectionsubsectionsubsubsection ...在您的情况下&#34;部分&#34;。
      • <level> :LaTeX部分的级别。在您的情况下&#34; 1&#34;。
      • <heading> :这是一个字符串。用于书签
      • 的文本
      • <label> :每个书签必须是唯一的。在内部使用PDF以在单击书签时跳转到正确的页面。

      为了快速测试,我使用Ghostscript生成了20页的1页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中显示如下:

      Screenshot: Preview.app with the bookmarks opened

      注意: LaTeX可通过两种方法用于OSX:

      如果我有更多时间,我会在命令行上添加一两个其他方法,以后或在接下来的几天内插入书签。

      现在这个必须要做,因为我从未在SO,AFAICR上展示过它。

      但我想是因为你给了背景&#34;我合并了1页的PDF,而且很慢;现在我想添加书签...&#34;,我可以用一种方法展示如何做到这一点。

      提示 其他一种方法是使用 IS 可用的pdftk Mac OS X!

答案 2 :(得分:2)

这是另一个答案。这个使用Ghostscript处理PDF到PDF和 pdfmark PostScript运算符来插入书签。

有关pdfmark主题的一些介绍,另请参阅:

此方法包含两个步骤:

  1. 使用一组有限的pdfmark命令创建一个文本文件(真的是一个PostScript文件),每行一个,并添加一个书签。
  2. 运行Ghostscript命令,将当前PDF文件与文本文件一起处理。
  3. 1

    文本文件中的内容应如下所示:

    [/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

    2

    现在运行此命令:

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

    生成的PDF bookmarked.pdf现在包含书签。见这个截图:

    Screenshot of bookmarks added with the help of Ghostscript and <code>pdfmark</code>

答案 3 :(得分:1)

这是用于将书签添加到目录的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)