Create bookmarks in a PDF from its headings

Be clear about what the headings option is: a considered guess. A PDF records no such thing as a heading — it records glyphs, at positions, in fonts, at sizes, and “Chapter One” is a heading only because it is set larger than the paragraph beneath it. So that is what is measured. The size most of each line’s characters are set in is compared with the size most of the document is set in, and the lines that stand out become bookmarks. It works well on reports, books and contracts, and not at all on a document typeset entirely in one size — where it says so rather than inventing an outline.

Headings are inferred from type size and nothing else, because a PDF stores nothing else about them. A document set entirely in one size has no headings to find, and you get a message saying so rather than an invented outline.

Build the bookmarks

No account. Your upload is deleted after 2 hours, the result after 24 hours.

How it works

  1. Pick how the bookmarks are found. Headings for a report or a book that uses larger type for its titles. A pattern for a batch where the titles are predictable — invoices, chapters, schedules. Every page for a document with no structure to find, which is unglamorous and never wrong.
  2. Run it once and read what it says. With headings, the result tells you the body text size it measured — “the body text of this document is set in 10.5pt”. That number is the thing to know if the first attempt catches too much or too little.
  3. Set the heading size if the guess was off. Put the size you actually want treated as a heading into the type size box and run it again. Everything at that size or above becomes a bookmark, and the guessing stops.

What the options do

The form above lists the options this tool is running today, straight from the server. This is what they are for.

Make a bookmark for
Headings measures type sizes and takes the lines that stand out from the body text, joining a title that wraps onto a second line back into one bookmark. Every page makes one bookmark per sheet and uses the document’s own page labels where it has them, so a book with roman-numbered front matter is bookmarked i, ii, iii and then 1, 2, 3 — the least clever option and the one that never fails. Every line matching a pattern is for documents whose titles are recognisable by their wording rather than their size: a batch of invoices, a contract with numbered schedules, a bundle of letters. Choose that one and fill in the pattern box.
Pattern to match
A regular expression, matched case-insensitively against each page’s text, and used only with ‘every line matching a pattern’. Whatever it matches becomes the bookmark’s name, so keep the pattern tight: ‘Chapter \d+’ produces bookmarks reading “Chapter 1”, “Chapter 2”, while ‘^Schedule .*’ takes the whole line including the schedule’s title. Watch out for anything that also matches a running header — a pattern that catches the header finds it on all two hundred pages and gives you two hundred bookmarks. The same match twice on one page is ignored, and there is a ceiling of twenty matches per page.
Heading type size (points)
Leave it at 0 and each page’s largest text is treated as that page’s heading, provided it is also more than half a point larger than the document’s body size — that second condition is what stops every line of a single-size page becoming a bookmark. Set it and the guessing stops: everything at that size or above is a heading, page by page. The number to type is usually one you already know (a Word document’s Heading 1 at 16 pt) or one the tool has just told you, since running it once at 0 reports the body size it measured. Set it a point below your headings rather than exactly on them, because type sizes in a PDF are rarely the round numbers they were in the word processor.

What this tool does not do

  • Headings are inferred from type size and nothing else, because a PDF stores nothing else about them. A document set entirely in one size has no headings to find, and you get a message saying so rather than an invented outline.
  • The outline is flat — one level, no nesting. There is no chapter with sections underneath it, and no way to assign a level to a particular heading.
  • Bookmarks the file already had are replaced rather than added to, and the result tells you when that happened. There is no merging with an existing outline.
  • Five hundred bookmarks per run, twenty matches per page, and names cut to 120 characters. Reaching the five hundred is nearly always a sign that the heading size or the pattern is matching body text.
  • A scanned page has no text at all, so there is nothing to measure or to match. It needs OCR first — and on this deployment the OCR tool reports which pages would need a text layer rather than adding one.
  • It does not read your table of contents. The lines on a contents page are body text like any other; if those are the titles you want, match them with a pattern instead.
  • Each bookmark points at the top of the page its heading is on, fitted to the page width. It does not scroll to the heading’s own position partway down the page.

What happens to your file

The file is uploaded because Create PDF bookmarks runs on our server rather than in the browser tab. It is kept for at most 2 hours and the result you download for 24 hours, then a scheduled job deletes both — a job has to be able to read the file while it runs, and you have to be able to retry a failed conversion without re-uploading. Neither needs longer.

Nothing about the contents is logged, and no one reads your documents. The retention page lists the same numbers the code enforces, and the privacy policy says who can reach the storage they sit in.

Questions

It said nothing on the pages stands out as a heading.
The document is set in one size throughout — common in scanned typescript, in plain exports and in anything typed rather than typeset. Either set the heading size by hand if some lines really are larger, match the titles with a pattern, or bookmark every page, which is always available and always correct.
Can I have sub-bookmarks under each chapter?
No. The outline produced here is one flat level. Nesting needs a reliable notion of heading levels, and type size alone does not give one on real documents — a pull quote is often larger than a section title.
How do I bookmark every invoice in a batch?
Use the pattern option with something like ‘Invoice \d+’. Each match becomes a bookmark named after the invoice, which also sets you up to split the file by bookmarks afterwards and get one PDF per invoice.
Will it keep the bookmarks the file already has?
No — the new outline replaces the old one entirely, and the result says so when there was one to replace. If the existing bookmarks are worth keeping, keep the original file too.
Will the bookmark panel be open when someone opens the file?
It asks for it. The document is set to open with its outline showing, because bookmarks nobody notices are bookmarks nobody uses. A reader configured to ignore that instruction will ignore it, and the panel is a keystroke away in every reader.
Can I split the document by the bookmarks afterwards?
Yes, and it is a good pairing. Build the outline here, check that the entries fall where you expect, then run split by bookmarks to get one file per entry, named after it.