I wrote code to extract PDF resumes using PyMuPDF. It works for single-column resumes, but for double-column resumes like those from Canva, the extraction is messy and disorganized. I need help to properly extract the resume with the correct information. Here is an example of a resume: example image I made two files: an extract file and a main file. Here is my extraction file for resumes (extract.py): import fitz # PyMuPDF import re import sys from pathlib import Path def extract_text_from_pdf(pdf_path: str) -> str: doc = fitz.open(pdf_path) text = "" for page in doc: blocks = page.get_text("blocks") # Retrieve the text blocks # Sorting by vertical position to maintain the order blocks.sort(key=lambda b: b[1]) for b in blocks: text += b[4].strip() + "\n" # b[4] Contains the text of the block text += "\n" # Page separator return text def clean_text(text: str) -> str: # Remove multiple spaces but keep line breaks text = re.sub(r"[ \t]+", " ", text) # Multiple spaces → single space text = re.sub(r"\n{2,}", "\n\n", text) # 2+ empty lines → 2 lines text = text.strip() return text def save_text_to_file(text: str, output_path: str): with open(output_path, "w", encoding="utf-8") as f: f.write(text) main.py: import sys from pathlib import Path from extract import extract_text_from_pdf, clean_text, save_text_to_file def main(pdf_path: str): raw_text = extract_text_from_pdf(pdf_path) cleaned_text = clean_text(raw_text) output_path = Path(pdf_path).with_suffix(".txt") save_text_to_file(cleaned_text, output_path) print(f"[OK] Extracted and cleaned text → {output_path}") if __name__ == "__main__": if len(sys.argv) < 2: print("Usage: python extract.py path/to/file.pdf") else: main(sys.argv[1]) Continue reading...