Home
Get a clickable table of contents (bookmarks) for a PDF that has none: let SumatraPDF build one from the numbered headings for reading, or save real bookmarks into the PDF with a short script.
Available in pre-release 3.7
Press Ctrl + K and run Generate Table Of Contents to get bookmarks for a paper or report without an outline. At a glance:
  • Generate Table Of Contents (CmdAutoGenerateTOC): builds bookmarks from numbered headings and shows them in the sidebar. Not saved into the file.
  • AutoGenerateTOC setting: does the same every time you open a PDF without an outline.
  • Save bookmarks into the PDF: sumatrapdf-tool run add-toc.js in.pdf out.pdf, a script that writes the outline you list.
  • Show / hide Bookmarks: F12

Generate a table of contents from headings #

  1. Open the PDF.
  2. Press Ctrl + K and run Generate Table Of Contents in Command Palette. The command is only in the Command Palette, and only for PDF-like documents.
  3. The Bookmarks sidebar opens once the headings are found. On a long document this takes a moment; you can keep reading meanwhile.
If the PDF already has a table of contents, the command just shows it.
SumatraPDF looks for lines that start with a section number and a period, followed by a word that doesn’t start with a lowercase letter:
  • 1. Introduction, 2.3. Results, 1.2 Scope
  • Roman numerals: IV. Discussion, II.A. Setup
Numbering decides nesting: 2.3. goes under 2., II.A. goes under II.. Headings without a number (Chapter One, Abstract) are not found, and a scanned PDF without a text layer gives no headings.
Note: the generated table of contents exists only while the document is open. It is not written into the PDF, so other PDF readers don’t see it. To keep bookmarks in the file, see Save bookmarks into the PDF.

Generate it automatically #

To build the table of contents every time you open a PDF that has none, set AutoGenerateTOC = true in advanced settings (Settings → Advanced Settings…). It is off by default because badly scanned (OCRed) text makes the scan slow and the result useless.

Save bookmarks into the PDF #

SumatraPDF can’t edit bookmarks in the window. Use the run command-line tool with a script that writes the outline and saves a new PDF.
  1. Save this as add-toc.js and edit the list: title is the bookmark text, page the page number (1 is the first page), children the nested bookmarks.
   // usage: sumatrapdf-tool run add-toc.js in.pdf out.pdf
   var toc = [
       { title: "Chapter 1", page: 1 },
       { title: "Chapter 2", page: 2, children: [
           { title: "Section 2.1", page: 3 },
       ]},
       { title: "Chapter 3", page: 4 },
   ];

   function addItems(it, items) {
       for (var i = 0; i < items.length; i++) {
           var t = items[i];
           it.insert({ title: t.title, uri: "#page=" + t.page, open: true });
           if (t.children) {
               it.prev(); // move to the item just inserted
               it.down(); // its (empty) list of children
               addItems(it, t.children);
               it.up();
               it.next();
           }
       }
   }

   var doc = Document.openDocument(scriptArgs[0]);
   var it = doc.outlineIterator();
   while (it.item()) {
       it.delete(); // remove the existing outline, if any
   }
   addItems(it, toc);
   doc.save(scriptArgs[1], "garbage,compress");
  1. Run it:
   sumatrapdf-tool run add-toc.js report.pdf report-toc.pdf
  1. Check the result without opening the file:
   sumatrapdf-tool show report-toc.pdf outline
   |	"Chapter 1"	#page=1
   +	"Chapter 2"	#page=2
   |		"Section 2.1"	#page=3
   |	"Chapter 3"	#page=4
The script replaces any existing outline. To add to it instead, remove the while loop: new bookmarks are then inserted before the first existing one.
Use SumatraPDF.exe run instead of sumatrapdf-tool run if you only have SumatraPDF installed (see Tools).

Make bookmarks from large text #

If the headings are set in a bigger font than the body text, this script adds a bookmark for every line at least a given size (18 points by default):
// usage: sumatrapdf-tool run toc-from-headings.js in.pdf out.pdf [min-font-size]
var minSize = scriptArgs.length > 2 ? parseFloat(scriptArgs[2]) : 18;
var doc = Document.openDocument(scriptArgs[0]);
var it = doc.outlineIterator();
while (it.item()) {
    it.delete();
}
var n = doc.countPages();
for (var i = 0; i < n; i++) {
    var text = JSON.parse(doc.loadPage(i).toStructuredText().asJSON(1));
    text.blocks.forEach(function (block) {
        (block.lines || []).forEach(function (line) {
            var title = line.text.trim();
            if (line.font.size >= minSize && title.length > 0) {
                it.insert({ title: title, uri: "#page=" + (i + 1), open: true });
            }
        });
    });
}
doc.save(scriptArgs[1], "garbage,compress");
sumatrapdf-tool run toc-from-headings.js report.pdf report-toc.pdf 20
It makes a flat list. Run sumatrapdf-tool show report-toc.pdf outline to see what it picked up, and adjust the size.

Tips #

  • Use Shift + F12 (Command Palette: Table Of Contents) to jump to a bookmark by typing part of its title.
  • Write the output to a new file. Saving over the PDF you opened fails with Permission denied.
  • Use Generate Table Of Contents first to see which headings a document has, then copy them into add-toc.js.
  • Open a bookmark from the command line with -named-dest "Chapter 2" (see Open a PDF at a page or search term).

See also #