How to Sort PDF bookmarks for free

There's no need to pay for Autobookmark or Evermap if you just need to sort your bookmarks alphabetically.

UPDATE: 2020-02-02 I added symbol handling, which wasn't done previously. Now you get __a__, __b__, instead of __a__, a, ab, abc... . However, Acrobat seems to handle the other symbols (mostly) in its own order. For example, + and = aren't sorted as shown in the order below. For my usecase, this doesn't really matter. If it does for you, you can try removing all the symbols listed below (under var reA), just keeping _.

Steps:

  1. Open Adobe Acrobat Standard or Professional (Acrobat Reader won't work because: it can't create bookmarks )
  2. Save the script below as C:\Program Files (x86)\Adobe\Acrobat 11.0\Acrobat\Javascripts\freesort.js (adjust the path as needed).
  3. Restart Acrobat and click Edit > Sort Bookmarks

Script:

// Copyright Sean Wingert, February 11, 2019
// Based largely on http://www.adobe.com/devnet/acrobat/pdfs/batch_sequences.pdf
// and https://wiki.med.umich.edu/display/UMHSHELPDESK/Acrobat+-+Using+Acrobat+JavaScript+to+Sort+PDF+Pages
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
 
// Create a separator in the Edit menu and add a Sort Bookmarks entry. This loads a few moments after Acrobat does.
app.addMenuItem({cName:"-", cParent:"Edit", cExec:" "}); 
app.addMenuItem({cName:"Sort Bookmarks", cParent: "Edit", cExec: "freesort()"});
 
// Create a utility function to see if a PDF has been loaded first, which is a prerequisite
// https://coderwall.com/p/_g3x9q/how-to-check-if-javascript-object-is-empty
function isEmpty(obj) {
    for(var key in obj) {
        if(obj.hasOwnProperty(key))
            return false;
    }
    return true;
}
 
// Create a function to sort the parent bookmarks (not their children or grandchildren) by name
function freesort() {
if(isEmpty(this.bookmarkRoot)) { app.alert("Error. Please open a PDF first."); return; }
 
// set variables
bm = this.bookmarkRoot;  // the current PDF document
bmArray = new Array();   // array to hold collected bookmarks
 
// write bookmarks to an array because you can't sort this.bookmarkRoot.children.sort(compare)
for (var i=0; i < bm.children.length; i++) bmArray[i] = bm.children[i];
 
// Use Natural Sort, AKA Human Sort (1,2,11,22), not Alphabetical sort (1,11,2,22) 
// Note: toLowerCase() makes this a case-insensitive sort.
// https://stackoverflow.com/questions/4340227/sort-mixed-alpha-numeric-array
var reA = /[^~`!@#\$%\^&*()\-+=\[\]{}\\|;:'",<.>/?_a-zA-Z\s]/g;
var reN = /[^0-9]/g;
 
function compare(a, b) {
  var a=a.name.toLowerCase();
  var b=b.name.toLowerCase();
 
  var aA = a.replace(reA, "");
  var bA = b.replace(reA, "");
  if (aA === bA) {
    var aN = parseInt(a.replace(reN, ""), 10);
    var bN = parseInt(b.replace(reN, ""), 10);
    return aN === bN ? 0 : aN > bN ? 1 : -1;
  } else {
    return aA > bA ? 1 : -1;
  }
}
 
// sort the array
bmArray.sort(compare);
 
// Move the bookmarks to the end of the list in their sorted order
for (var i=0; i < bmArray.length; i++) bm.insertChild(bmArray[i], bm.children.length);
 
// troubleshooting: print the results
// for (var i=0; i < bmArray.length; i++) console.println(bmArray[i]);
}

Mac

Note: Step 2 on a Mac looks like this:

/Applications/Adobe Acrobat Reader DC.app/Contents/Resources/JavaScripts/freesort.js

Comments

Thank you! It worked immediately and exactly as you said.

Hi I am trying to use your excellent bit of code to resort a set of bookmarks that are already in a large PDF. Is there any way to implement this using reader? Following your instructions I do get the link in the edit menu, but it gives an error "An internal error occurred." Is there any way to edit the bookmarks for a PDF outside of adobe?
Thanks!
Nate

Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.