22

Is there any way to extract highlighted text from a PDF file programmatically? Any language is welcome. I have found several libraries with Python, Java, and also PHP but none of them do the job.

Martin Thoma
  • 124,992
  • 159
  • 614
  • 958
user1183057
  • 229
  • 1
  • 2
  • 3
  • Thanks for the answer. I also found another way to solve this by a little bit long way :) Sticky notes that is created by Adobe Reader is easy to parse because sticky notes are appended to pdf files with both content and position information, but for highlights there is only rectangle infromation I should extract text by location. So I have to write some code for it. As base library I can use PDFMiner, which provides information about the postions of texts. – user1183057 Feb 07 '12 at 15:23
  • Sounds similar, but unrelated: [read, highlight, save PDF programmatically](https://stackoverflow.com/q/7605577/562769) – Martin Thoma Sep 01 '20 at 12:20

2 Answers2

14

To extract highlighted parts, you can use PyMuPDF. Here is an example which works with this pdf file:
Direct download

# Based on https://stackoverflow.com/a/62859169/562769

from typing import List, Tuple

import fitz  # install with 'pip install pymupdf'


def _parse_highlight(annot: fitz.Annot, wordlist: List[Tuple[float, float, float, float, str, int, int, int]]) -> str:
    points = annot.vertices
    quad_count = int(len(points) / 4)
    sentences = []
    for i in range(quad_count):
        # where the highlighted part is
        r = fitz.Quad(points[i * 4 : i * 4 + 4]).rect

        words = [w for w in wordlist if fitz.Rect(w[:4]).intersects(r)]
        sentences.append(" ".join(w[4] for w in words))
    sentence = " ".join(sentences)
    return sentence


def handle_page(page):
    wordlist = page.get_text("words")  # list of words on page
    wordlist.sort(key=lambda w: (w[3], w[0]))  # ascending y, then x

    highlights = []
    annot = page.first_annot
    while annot:
        if annot.type[0] == 8:
            highlights.append(_parse_highlight(annot, wordlist))
        annot = annot.next
    return highlights


def main(filepath: str) -> List:
    doc = fitz.open(filepath)

    highlights = []
    for page in doc:
        highlights += handle_page(page)

    return highlights


if __name__ == "__main__":
    print(main("PDF-export-example-with-notes.pdf"))
K J
  • 8,045
  • 3
  • 14
  • 36
Martin Thoma
  • 124,992
  • 159
  • 614
  • 958
9

Ok, after looking I found a solution for exporting highlighted text from a pdf to a text file. Is not very hard:

  1. First, you highlight your text with the tool you like to use (in my case, I highlight while I'm reading on an iPad using Goodreader app).

  2. Transfer your pdf to a computer and open it using Skim (a pdf reader, free and easy to find on the web)

  3. On FILE, choose CONVERT NOTES and convert all the notes of your document to SKIM NOTES.

  4. That's all: simply go to EXPORT an choose EXPORT SKIM NOTES. It will export you a list of your highlighted text. Once opened this list can be exported again to a txt format file.

Not much work to do, and the result is fantastic.

Tim M.
  • 53,671
  • 14
  • 120
  • 163
Angel
  • 99
  • 1
  • 2