Hi everyone, I’m working on a macro to chunk PDFs using a Python script, but I’m hitting a wall. When I run the macro, it prompts me for input, I click "OK," and then... nothing. No results window appears, and no files are created. KM should be telling me something about my mistakes, but that window is also not appearing.
Here is a human explanation of what I'm doing. I'm doing something that's way over my head. But, it works sometimes. I want to put reference books into Devonthink. If I can find specific chapters, I will be much closer to the information that I'm looking for. So I'm trying to chunk these books into chapters. I have many of these reference books, so I'm trying to make a generic chunker that will chunk many different books using a table of contents. It works enough of the time for me to keep trying to do this. I can do it for one book, but then I can't do the same thing for the next book. That's where I started making this generic chunker with the help of Gemini. I'm sure this would be easy for a human to do, but I couldn't pay a human as much as it would cost to do this. I'm just guessing.
I have tried doing this with the terminal alone, but every time there is some problem with the Macintosh terminal. A different version of Python is needed and the versions are somehow extremely complicated. That's when I started trying to do it with Keyboard Maestro. I'm learning a lot as I'm doing it, but I'm learning a lot about the weakness of AI.
If you could tell me where I'm making some mistake, I will tell Gemini and somehow make a change.
The Setup:
- The Goal: Pass two local variables (
Local_CurrentLineandLocal_EndPage) from a KM Prompt to a Python script located in a dynamic subfolder.
02 Chunker_pdf for Single book.kmmacros (10.1 KB)
TOC example
[[Acari (Mites & Ticks)]] ((1))
[[Crustaceans]] ((89))
[[Insects]] ((181))
[[Myriapods (Centipedes & Millipedes)]] ((837))
[[Scorpions]] ((857))
My Python script looks like this:
import os
import sys
import datetime
import re
# --- 1. LIBRARY CHECK ---
try:
from pypdf import PdfReader, PdfWriter
except ImportError:
print("\n❌ CRITICAL ERROR: 'pypdf' library not found.")
print("Please run: /opt/homebrew/bin/python3 -m pip install pypdf")
sys.exit(1)
# --- 2. ENVIRONMENT LOCK ---
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
os.chdir(SCRIPT_DIR)
BOOK_IDENTITY = os.path.basename(SCRIPT_DIR)
OUTPUT_FOLDER = "CHUNKS_FINISHED"
def detect_pdf():
"""Finds the main book PDF."""
all_files = os.listdir('.')
pdfs = [f for f in all_files if f.lower().endswith('.pdf')
and not f.startswith('._')
and f != 'rawTOC.pdf']
if not pdfs:
print(f"❌ ERROR: Main PDF not found in: {BOOK_IDENTITY}")
sys.exit(1)
return pdfs[0]
def run_chunking():
source_pdf = detect_pdf()
# Handshake with Keyboard Maestro
if len(sys.argv) < 3:
print("❌ ERROR: Keyboard Maestro failed to send data.")
sys.exit(1)
raw_line = sys.argv[1]
try:
# Pulls text out of [[ ]] and page out of (( ))
# This disregards the brackets and cleans the name
clean_chapter = re.search(r'\[\[(.*?)\]\]', raw_line).group(1).strip()
start_page = int(re.search(r'\(\((.*?)\)\)', raw_line).group(1)) - 1
end_page = int(sys.argv[2])
except Exception:
print(f"❌ ERROR: Could not read Wiki-Line: {raw_line}")
sys.exit(1)
# FORMULA: ChapterName_BookFolderName.pdf
full_name = f"{clean_chapter}_{BOOK_IDENTITY}"
clean_filename = re.sub(r'[\\/*?:"<>|]', "", full_name).replace(" ", "_") + ".pdf"
# Automatic Folder Creation
if not os.path.exists(OUTPUT_FOLDER):
os.makedirs(OUTPUT_FOLDER)
print(f"🛡️ AUDIT: Processing {clean_chapter}...")
try:
reader = PdfReader(source_pdf)
writer = PdfWriter()
actual_page_count = len(reader.pages)
# Safety check for page numbers
if start_page < 0: start_page = 0
if end_page > actual_page_count: end_page = actual_page_count
for page_num in range(start_page, end_page):
writer.add_page(reader.pages[page_num])
output_path = os.path.join(OUTPUT_FOLDER, clean_filename)
with open(output_path, "wb") as output_pdf:
writer.write(output_pdf)
print(f"🏁 SUCCESS: Saved {clean_filename} to {OUTPUT_FOLDER}\n")
except Exception as e:
print(f"❌ PDF ERROR: {e}")
if __name__ == "__main__":
run_chunking()





