Pdf2md
Custom agent skills that could be used by AI agents
npx -y skills add dimonier/skills --skill pdf2mdAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Convert PDF files to Markdown — extracts text with pdfplumber and describes images/diagrams via a local vision-language model. Use when the user asks to extract PDF content, convert presentation slides to text, transcribe conference talks from PDFs, or OCR diagrams and charts from documents.
SKILL.md
4.6 KB, as published. Nobody here has run it
PDF -> Markdown (pdf2md)
Extracts PDF content into Markdown: text as-is + image/diagram meaning via a Vision Language Model.
When to Use
- User asks to "extract from PDF", "convert PDF to text/Markdown", "transcribe slides"
- Presentation decks (text + graphics + diagrams)
- Conference talks, workshops, technical reports
- PDFs where plain text extraction produces garbled output
When NOT to Use
- PDFs that are purely text (use pdfplumber directly — faster, no VL needed)
- One-page forms or invoices (use pdfplumber tables)
- Filling PDF forms (use well known
pdfskill instead) - Scanned documents without selectable text (this skill works, but OCR-only tools may be faster)
Dependencies
Install once per environment:
pip install pdfplumber pypdfium2 pillow requests
VL Model Setup
Default: LM Studio with qwen/qwen3-vl-8b loaded on localhost:1234.
Any OpenAI-compatible endpoint works — Ollama, vLLM, cloud providers. To switch:
python scripts/extract_pdfs.py --source "<path>" --model "llama3.2-vision" --api-url "http://localhost:11434/v1/chat/completions"
Workflow
Step 1: Verify VL model is reachable
python -c "import requests; r = requests.get('http://localhost:1234/v1/models'); print([m['id'] for m in r.json()['data']])"
If you don't see your VL model, load it in LM Studio before proceeding.
Step 2: Test on 1-2 PDFs first
python scripts/extract_pdfs.py --source "<path-to-pdfs>" --first 2
Check the output in _markdown/. If quality is poor (too much "water", missing text, or style descriptions leaking through), edit the prompt in references/vl-prompt.md and the VL_PROMPT variable in the script, then re-run with --force.
Step 3: Run on everything
python scripts/extract_pdfs.py --source "<path-to-pdfs>"
Already-processed PDFs are skipped automatically. Use --force to overwrite.
Step 4: If something fails
- VL call fails (3 retries exhausted): page is left with fallback text from pdfplumber, or marked
[VL error] - Rendering fails: page is skipped, counted as error
- Output file corrupted: delete the
.mdand re-run — the script will re-process it - Model runs out of VRAM: reduce
RENDER_SCALEin the script (1.5 or 1.0)
Script Arguments
| Argument | Default | Description |
|---|---|---|
--source | (required) | Directory with PDF files (recursive) |
--output | _markdown/ inside source | Output directory for .md files |
--model | qwen/qwen3-vl-8b | VL model ID |
--api-url | http://localhost:1234/v1/chat/completions | API endpoint |
--first N | (all) | Process only first N PDFs |
--files "s1,s2" | (all) | Filter by filename substring |
--force | false | Overwrite existing output |
Output Structure
_source/
_markdown/
subfolder/
presentation1.md
presentation2.md
Folder structure mirrors the source. Each .md file:
# Presentation Title
---
## Page 1 / 40
**[VL slide description]**
<content extracted by VL model>
---
## Page 2 / 40
...
VL Prompt Rules (hard-won lessons)
- Never describe fonts, colors, margins, backgrounds — only content
- Never write intros like "This slide shows..." — start with content
- Never invent "Conclusions" or "Overall assessment" sections
- Extract ALL text verbatim
- For diagrams/charts: describe MEANING, not appearance
- Concise, dense, no filler — every sentence must carry information
- Do NOT limit output tokens — let the model decide
See references/vl-prompt.md for the full prompt template and tuning guide.
Performance
| GPU | Sec/page | 1000 pages |
|---|---|---|
| RTX 3090/4090 | ~7-10s | ~2 hours |
| M1/M2 Mac (LM Studio) | ~15-20s | ~4-5 hours |
| CPU-only | ~60-120s | Not recommended |
See Also
- VL Prompt (references/vl-prompt.md) — prompt template + iteration history + tuning tips
- Script (scripts/extract_pdfs.py) — the extraction tool
Evolution rule: If you are dissatisfied with the extraction quality or the workflow, identify what to change (prompt, script parameters, dependencies) and offer to update this skill. The prompt lives in
references/vl-prompt.md; the extraction logic inscripts/extract_pdfs.py.