PDF Expert Markdown format to tab-delimited text

May 4, 2025

Here’s a Python script I wrote to convert annotation summaries from PDF Expert, formatted as Markdown, to tab-delimited text. You will need to modify the path names toward the end for the output. I intend to demonstrate its use on another page. No, I don’t know how to use GitHub.

#! python3
# PDFExpertMarkdown2Tab.py - converts Markdown annotation summaries
# from PDF Expert Markdown format to tab-delimited text
# Zachary Schrag
# 2023-12-25

import pyperclip # imports functions for copying, pasting
import re # imports functions for RegEx
from pathlib import Path # imports the function for saving a new document


def parseMD(mdLine): # this function parses four kinds of lines that PDF Expert produces: file names, headers, highlights, and notes and outputs clean, tab-delimited text
newLineNote =""
if re.search(r' (Annotation Summary of )(.*)(.pdf)', mdLine):
oldExcerpt = re.search(r' (.*)(Annotation Summary of )(.*)(.pdf)', mdLine)
newLineNote = str(oldExcerpt.group(3)) +'\n'
elif re.search(r'(THISLINEISAHEADER)(.*)',mdLine):
oldExcerpt = re.search(r'(THISLINEISAHEADER)(\s)(.*)', mdLine)
newLineNote = '∞∞∞\t' + str(oldExcerpt.group(3)) +'\n'
elif re.search(r'(.*)(Highlight)(.*)',mdLine):
oldExcerpt = re.search(r' (\*)(.*\s)(.*)(\[)(.*)(\]:\*\s)(.*)', mdLine)
newLineNote = str(oldExcerpt.group(5))+'\t'+str(oldExcerpt.group(7)) + '\n'
elif re.search(r'(.*)(\*Note)(.*)',mdLine):
oldExcerpt = re.search(r' (\*)(.*\s)(.*)(\[)(.*)(\]:\*\s)(.*)', mdLine)
newLineNote = (str(oldExcerpt.group(5))+'\t • Note: '+str(oldExcerpt.group(7))) +'\n'
if newLineNote:
return newLineNote
else:
return ""

# here the user needs to copy the Annotation Summary from PDF expert in Markdown format
text = pyperclip.paste() # pastes the Markdown Annotation Summary from the clipboard

# these lines clean up the PDF Expert output, which can vary depending on what kind of document you are marking up
text = re.sub(r'(\[page )', ('['), text)
text = re.sub(r'(\#\#\#\#)', ('THISLINEISAHEADER'), text)
text = re.sub(r'(\n\n)', ('\n'), text)

newNotes = "" # creates a string that will receive the reformatted lines
splitText = text.split('\n') # splits the copied and cleaned text at line breaks

for i in range(len(splitText)): #this loop runs the parseMD function for each line, adding the tab-delimited text to the newNotes string . You can take out the print if you don't need to see the results on screen
newNotes = newNotes + str(parseMD (splitText[i]))
print(str(parseMD (splitText[i])), end='')

# copies the newNotes string, which is this program's main output, onto the clipboard
pyperclip.copy(str(newNotes))

# saves the newNotes string to a .tab file, with the title of the original document if possible. I use utf-16 encoding so characters will show up correctly in Excel
firstLine = re.search(r' (Annotation Summary of )(.*)(.pdf)', text)
if firstLine != "":
newFileDocuments = Path(r'/Users/zach/Documents/Annotation summaries/' + str(firstLine.group(2)) + '.tab')
else:
newFileDocuments = Path(r'/Users/zach/Documents/Annotation summaries/' + 'PDF_annotation_summary.tab')
newFileDocuments.write_text(newNotes, encoding='utf-16')