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 in Adobe Acrobat Pro. Just follow the steps below, which works for Acrobat on Windows and Mac.

UPDATE: 2022-06-21 If you don't have or want Adobe Acrobat Pro, you can now sort your PDF bookmarks for free, using python. See my Stack Overflow post https://stackoverflow.com/a/72705107/1231693.

UPDATE: 2022-06-16 This still doesn't work on Acrobat's free Adobe Acrobat Reader DC--at least on Mac, since I haven't tested it yet on Windows--because it can't run the insert() method, given that Acrobat Reader can't create bookmarks.

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; see below for Mac paths).
  3. Restart Acrobat and click Edit > Sort Bookmarks

Troubleshooting:

  1. When you copy and paste, ensure that the "blank" lines don't contain an extra character. If so, Acrobat DC complains about bad characters upon opening.
  2. First load your PDF, then wait a few seconds, and THEN click the Edit menu, where you'll see "Sort Bookmarks."

Script:

// Copyright Sean Wingert, February 11, 2019. Updated September 26, 2022.
// 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++) {
    // bmArray[i].style=2; // make bold
 
    // if children exist
    if (bmArray[i].children !== null) {
        for (var j=0; j < bmArray[i].children.length; j++) bmArray[i].children[j].style=2; // bold them
    }
    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 with Acrobat Pro DC, looks like this:

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

OR for Reader

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

These are sometimes called "App-level" scripts or Folder-Level scripts

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

Is it possible to have it sort by Date Newest to oldest? If so what would I change in the script? Thank you for your work on this!

This works great for Alphabetical! I was wondering if there was a way to sort by dates Newest to oldest? Thank you!

Your work around looks great! I've worked with scripts in the past but I'm firmly in the "upper" beginner category. When you say save the script below, do you simply mean to save it to a txt file with extension .js? Or do I need a script editor program?

Also I'm working on a Mac with acrobat Pro DC I'm trying to find the location in the path above but I stall out at "/Macintosh HD/Applications/Adobe Acrobat DC" there are no other folders (i.e. contents/resources etc.) what aim I missing?

Thanks in advance for your time and consideration. Feel free to text me directly at wlsimpson2nd@yahoo.com as well.

holy smokes DUDE you just made my life WAY better.

Thank you! I needed to figure out how to create a javascript (.js) file with notepad, but got it done. It worked for me in Acrobat Pro DC version 2020.013.20064.

Hi, thanks for creating the script.

Is it possible to make the script sort sublevel bookmarks ie. bookmarks within sub-categories?

Nice

Thank you! It worked perfectly as you said.

Is there something else that I need to do to get it to come up in the "Edit" menu? Using Acrobat Pro. And it doesn't seem to have access to the js file.

Is there something else that I need to do to get it to come up in the "Edit" menu? Using Acrobat Pro. And it doesn't seem to have access to the js file.

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.