6 Replies Latest reply on Apr 12, 2010 6:35 AM by ReinhardF

    Batch creation of bookmarks?

    John Hawkinson Level 5

      Moved from the Acrobat Macintosh forum (Batch creation of bookmarks?)


      I would like to add 107 bookmarks to a 250-page PDF in an automated  fashion. I have a list of the bookmarks titles, pages, and their  hiearchy level.


      What's my best bet? [This is with Acrobat 9 on a Mac, but I can use any platform...]


      Obviously I don't want to create them by  hand with New Bookmark in Acrobat Pro.

      My document is not tagged,  and I don't see an easy way to mass create tags (is there one?).

      It  appears that the Acrobat Pro scripting DOM does support creating  bookmarks with the Bookmark createChild()method, but it's looking a little  dicey to me how to use that straightforwardly, so if it's easy to  provide a few pointers, I would be greatful.


      I'd like to avoid buying a  plugin (or using one on a free trial basis, since I don't really intend  to buy one).

      I initially planned on using pdftk's update_info functionality, but it turns out that while pdftk's dump_data subcommand dumps bookmark info, it's corresponding update command  doesn't handle bookmarks at all.

      I considered writing some Java  code with iText and/or PDFBox, but I didn't see any good examples of  exactly how to create bookmarks that point to pages, and it seemed like  it might be a big pain to figure out.


      I'm comfortable scripting other  Adobe products in JavaScript, but I've never dealt with Acrobat.


      Hopefully  that sets the stage. Any advice is appreciated!



        • 1. Re: Batch creation of bookmarks?
          ReinhardF Level 3



          here an VBA example: http://forums.adobe.com/message/2253395


          HTH, Reinhard

          • 2. Re: Batch creation of bookmarks?
            John Hawkinson Level 5

            Hmm...thanks for that reference. I do feel like I'm in a set of twisty passages, though.

            The thread links to http://www.ReFob.de/downloads/Acrobat/AcroJsBookmarksVBA.zip

            which contains an Excel file containing some VBScript.


            I haven't gotten around to figuring out how best to adapt this to my problem (and while I guess I'll settle for a Windows solution, I'd really prefer a portable solution or a Mac solution), and I will admit that some parts of this are dissapointing, like sending a Control-B to Acrobat to cause it to create a bookmark. Surely that's not the best way!


            Anyhow, since it might aid others and I find it somewhat cathartic, here's the VBScript from that file (hrmm, I guess there's not a good syntax highlighting choice to use...):


            Attribute VB_Name = "Module1"
            ' ---------------------------------------------------------------------------
            ' Macros for automatic bookmark hierarchy creation from VBA via Javascript
            ' (C) Grunenthal GmbH, Stolberg / Germany
            ' Author: Jens Kammerath - Jens.Kammerath@grunenthal.de, kammera@t-online.de
            ' ---------------------------------------------------------------------------
            ' Acrobat (full version >= 5.0, not only reader) must be opened
            ' with PDF file to be processed in foreground window
            ' ---------------------------------------------------------------------------
            Option Explicit
            ' ---------------------------------------------------------------------------
            ' MakeBookmarks - Creates Bookmarks on respective pages, no hierarchy so far
            ' ---------------------------------------------------------------------------
            ' Why not with JSObject?
            ' 1. Attaching bookmarks to pages much easier with Acrobat interface
            ' 2. Incorrect handling of international char's with bookmark.name assignment
            ' ---------------------------------------------------------------------------
            Sub MakeBookmarks()
            Dim i%
                AppActivate "Adobe Acrobat", True
                With Range("LstBookmarks")
                    For i = 1 To .Rows.Count
                        ' Goto page
                        SendKeys "^n" & .Cells(i, 1) & "{Enter}", True
                        ' Create bookmark
                        SendKeys "^b" & Trim(.Cells(i, 3)) & "{Enter}", True
                    Next i
                End With
                AppActivate "Microsoft Excel"
            End Sub
            ' ---------------------------------------------------------------------------
            ' ArrangeBookmarks - Builds hierarchy
            ' ---------------------------------------------------------------------------
            Sub ArrangeBoookmarks()
            Dim gApp As Acrobat.CAcroApp
            Dim gPDDoc As Acrobat.CAcroPDDoc
            Dim gAVDoc As Acrobat.CAcroAVDoc
            Dim jso As Object, bmRoot As Object, bm As Object
            Dim children As Variant, children1 As Variant
            Dim i%, nBM%, XNodes%(16), iLev%, BMText$, iPos%, XLev%(16)
                Set gApp = CreateObject("AcroExch.App")
                Set gAVDoc = gApp.GetActiveDoc
                Set gPDDoc = gAVDoc.GetPDDoc
                ' Javascript object
                Set jso = gPDDoc.GetJSObject
                ' Root of bookmark tree
                Set bmRoot = jso.bookmarkroot
                ' Children of root, all bookmarks on level 1 so far
                children = bmRoot.children
                nBM = UBound(children) - LBound(children) + 1
                ' temporary root for rearranging bookmarks
                bmRoot.createchild "Temp Root", "", nBM
                children = bmRoot.children
                XNodes(0) = nBM
                ' XLev(i): counter number of children on level i
                For i = 1 To 16
                    XLev(i) = 0
                Next i
                For i = LBound(children) To UBound(children) - 1
                    iLev = Range("LstBookmarks").Cells(i + 1, 2)
                    XLev(iLev) = XLev(iLev) + 1
                    children(XNodes(iLev)).insertchild children(i), XLev(iLev)
                    ' XNodes(i): current parent bookmark on level i
                    XNodes(iLev + 1) = i
                Next i
                ' Move bookmarks from temp to actual root
                children1 = children(XNodes(0)).children
                For i = LBound(children1) To UBound(children1)
                    bmRoot.insertchild children1(i), i + 1
                Next i
                ' remove temp root
                Set jso = Nothing
                Set gPDDoc = Nothing
                Set gAVDoc = Nothing
                Set gApp = Nothing
            End Sub



            • 3. Re: Batch creation of bookmarks?
              ReinhardF Level 3



              I used it only a short time.

              Nowaday I use mbtpdfasm, a free command line tool: http://thierry.schmit.free.fr/spip/spip.php?article15&lang=en

              If you want to use a ready made solution use: http://www.becyhome.de/download_eng.htm#becypdfasm


              If you prefer a protable solution look into iText: http://itextpdf.com/


              HTH, Reinhard

              • 4. Re: Batch creation of bookmarks?
                John Hawkinson Level 5

                Just to be clear, I want to add bookmarks to a single monolithic PDF file. I am not trying preserve bookmarks while aggregating many small PDF files.


                It does not look like mbtpdfasm has support for doing bookmark manipulation. Oh, is that what they mean by outlines? Seems a bit weak on documentation, but I'll download it and give it a whirl.


                As for iText, well, yes, see my initial post:


                I considered writing some Java  code with iText and/or PDFBox, but I didn't see any good examples of  exactly how to create bookmarks that point to pages, and it seemed like  it might be a big pain to figure out.




                • 5. Re: Batch creation of bookmarks?
                  John Hawkinson Level 5

                  Well, that initially looked promising, but not so much. Version 1.0.28.


                  Under Windows,  the best case, with the precompiled binaries, I get:


                  C:\...\mbtPdfAsm-1.0.28\bin>mbtPdfAsmEn.exe -Minput.pdf -dx.pdf -oat3.txt
                  mbtPdfAsm version 1.0.28
                  error with file .\input.pdf <--------------
                  signets integres
                  end of process, 0 page(s) assembled


                  Under Solaris, it builds fine but core dumps:

                  /tmp/mbtpdfasm> ./mbtPdfAsm -minput.pdf -dx.pdf -oat3.txt
                  mbtPdfAsm version 1.0.28
                  constructeur liste fichier
                  nbMask: 1
                  offset null, objet 15
                  Segmentation fault (core dumped)


                  This seems to happen irrespective of the format of the input, even giving the first line of the sample input file from http://thierry.schmit.free.fr/spip/spip.php?article18:


                  1 0 1 1 introduction


                  Under Linux, it doesn't even build:

                  pdfFile.cpp: In member function 'int C_pdfFile::makeAttrib(C_pdfFile*, char*, i:
                  pdfFile.cpp:948: warning: deprecated conversion from string constant to 'char*'
                  pdfFile.cpp:976: error: cast from 'char*' to 'int' loses precision


                  All in all, not too promising... Am I doing something obviously wrong?

                  • 6. Re: Batch creation of bookmarks?
                    ReinhardF Level 3



                    under Windows - for what it is developed - it works fine.

                    You may download the GUI "BeCymbtPdfAsm" to see how it works.


                    In general I found it's better to work with a file-list file (otherwise look at the option -b).


                    Here a file list for the files which will be merged:



                    C:\Temp\pdf\Sales_A.pdf 1
                    C:\Temp\pdf\Sales_B.pdf *

                    C:\Temp\pdf\Sales_C.pdf 6-9


                    (where ... 1 stands for take first page; ... * take all pages; .... take pages 6-9)



                    1 0 1 1 Sales Overview
                    2 0 2 2 Net Sales B
                    3 0 3 3 Sales by Region


                    Command: (via cmd, Shellexecute(..), run(..) or whatever)

                    c:\tools\pdf\mbtPdfAsm.exe -sC:\Test.txt -oC:\Outlines.txt -dC:\Result.pdf


                    HTH, Reinhard


                    PS: Adobe call it bookmarks, the PDF-specification call it outlines, so you may get use to both.