aops-tools/skills/convert-to-md/SKILL.md
Batch convert documents (DOCX, PDF, XLSX, TXT, PPTX, MSG, DOC) to markdown, preserving tracked changes and comments.
npx skillsauth add nicsuzor/academicops convert-to-mdInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Taxonomy note: This skill provides domain expertise (HOW) for batch document conversion to markdown. See [[aops-core/skills/remember/references/TAXONOMY.md]] for the skill/workflow distinction.
Batch convert documents to markdown format, preserving tracked changes, comments, and other markup.
/convert-to-md [directory]
| Format | Method | Notes |
| ------ | ---------------------------- | ------------------------------------ |
| DOCX | pandoc --track-changes=all | Preserves comments & tracked changes |
| PDF | PyMuPDF | Text extraction |
| XLSX | pandas | Converts to markdown tables |
| TXT | rename | Direct rename to .md |
| PPTX | pandoc | Slide content to markdown |
| MSG | extract-msg | Email metadata + body |
| DOC | textutil | macOS native (fallback) |
| DOTX | pandoc | Word templates |
Install dependencies (if needed):
uv add pymupdf pandas openpyxl tabulate extract-msg
Convert DOCX (preserves comments/edits):
for f in *.docx; do
pandoc --track-changes=all -f docx -t markdown -o "${f%.docx}.md" "$f" && rm "$f"
done
Convert PDF:
import fitz
from pathlib import Path
for pdf in Path(".").glob("*.pdf"):
doc = fitz.open(pdf)
text = "\n\n".join(page.get_text() for page in doc)
pdf.with_suffix(".md").write_text(text.strip())
pdf.unlink()
Convert XLSX to tables:
import pandas as pd
for xlsx in Path(".").glob("*.xlsx"):
xls = pd.ExcelFile(xlsx)
content = f"# {xlsx.stem}\n\n"
for sheet in xls.sheet_names:
df = pd.read_excel(xlsx, sheet_name=sheet)
content += f"## {sheet}\n\n{df.to_markdown(index=False)}\n\n"
xlsx.with_suffix(".md").write_text(content)
xlsx.unlink()
Convert TXT: for f in *.txt; do mv "$f" "${f%.txt}.md"; done
Convert MSG:
import extract_msg
msg = extract_msg.Message("file.msg")
content = f"# {msg.subject}\n\n**From:** {msg.sender}\n**Date:** {msg.date}\n\n{msg.body}"
Clean up: Remove *:Zone.Identifier files (Windows metadata)
pandoc (system): DOCX, PPTX, DOTX conversiontextutil (macOS): DOC fallbackpymupdf (Python): PDF text extractionpandas, openpyxl, tabulate (Python): XLSX tablesextract-msg (Python): Outlook MSG filesdata-ai
Canonical session close — commit, push, PR, release_task, reflection blocks, handover. Use /dump for emergency bail (no commit/PR/reflection).
data-ai
Emergency session bail — fast resume task + short handover, no commit/PR/reflection. For when you (or the user) need a clean context now. Use /end-session for canonical close.
data-ai
Daily note lifecycle — compose and maintain a factual daily note. Reports the state of the day; does not prioritise or recommend. SSoT for daily note structure.
testing
Launder supervisor/worker task-log output into a Nic-facing narrative — what happened, where things are headed, and what (if anything) is genuinely his to decide. Never relays raw process detail (worker IDs, thread pointers, log paths) or verbatim task-log stream-of-consciousness.