Skip to content
Development
Skill

/to-markdown

Convert any file or URL to clean Markdown: PDF, DOCX, XLSX, PPTX, HTML, images (OCR), audio, CSV, YouTube. Optimised for LLM pipelines. Triggers on: "convert to markdown", "extract text from PDF", "parse this document", "ingest for RAG".

From plugin
armory
31181 skills2 agents1 command
Install
$ npx -y skills add Mathews-Tom/armory --skill to-markdown --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/to-markdown

Context preview

The summary Claude sees to decide when to auto-load this skill.

Convert any file or URL to clean Markdown: PDF, DOCX, XLSX, PPTX, HTML, images (OCR), audio, CSV, YouTube. Optimised for LLM pipelines. Triggers on: "convert to markdown", "extract text from PDF", "parse this document", "ingest for RAG".

SKILL.md

to-markdown.SKILL.md
name: to-markdown
description: 'Convert any file or URL to clean Markdown: PDF, DOCX, XLSX, PPTX, HTML, images (OCR), audio, CSV, YouTube. Optimised for LLM pipelines. Triggers on: "convert to markdown", "extract text from PDF", "parse this document", "ingest for RAG".'
metadata:
  version: 1.0.1
  category: visualization
  tags: [conversion, markdown, document-ingestion, pdf]
  difficulty: beginner

To Markdown

Convert any file or URL to clean Markdown using [MarkItDown](https://github.com/microsoft/markitdown) as the conversion engine, with a lightweight fetch layer for URLs.

Reference Files

| File | Purpose | | ----------------------- | ------------------------------------------------------- | | `references/formats.md` | Per-format handling notes, internal engines, known gaps | | `references/fetch.md` | URL fetch layer: trafilatura + Playwright strategies | | `references/install.md` | Dependency install guide for all variants |

Decision Tree

Determine the input type before touching any tool:

Input type?
  Local file path        -> markitdown directly
  URL
    YouTube URL          -> markitdown directly (transcript extraction built-in)
    Static page          -> trafilatura fetch -> markitdown on HTML result
    JS-rendered / auth   -> Playwright fetch -> markitdown on result
  Pasted HTML string     -> markitdown directly on string

Do not use `web_fetch` or `WebFetch` for URLs — route through the fetch layer described in `references/fetch.md` to preserve the conversion pipeline.

Core Conversion Workflow

Step 1: Ensure dependencies

uv pip show markitdown || uv pip install 'markitdown[all]' trafilatura

See `references/install.md` for selective installs and full dependency table.

Step 2: Convert

from markitdown import MarkItDown

md = MarkItDown(enable_plugins=False)
result = md.convert("path/to/file.pdf")
print(result.text_content)

Step 3: Workflow

1. Detect input type (file path, URL, raw HTML). 2. If URL, run fetch layer first (see `references/fetch.md`). 3. Run markitdown conversion on the local file or fetched content. 4. Post-process if needed (strip boilerplate, trim to main content). 5. Write output or return inline per output conventions below.

Output Conventions

| Context | Output behaviour | | ---------------------------- | ------------------------------------------------------- | | Single file, user wants file | Write `<input_stem>.md` to same directory | | Single file, inline request | Return Markdown in conversation | | Batch (multiple files) | Write each to `<stem>.md`, summarise what was produced | | URL | Write `<slug>.md` to current directory or return inline | | Piped into another workflow | Return `result.text_content` string only |

Default: "convert this file" -> write a file. "Read this" or "what does this say" -> return inline.

Output Example

**Source** (two-column PDF with a table):

Annual Report 2024                    Financial Highlights
Revenue grew 12% year-over-year...    | Metric   | 2023  | 2024  |
                                      | Revenue  | $4.2B | $4.7B |
                                      | EBITDA   | $1.1B | $1.3B |

**Converted Markdown**:

# Annual Report 2024

Revenue grew 12% year-over-year...

## Financial Highlights

| Metric  | 2023  | 2024  |
| ------- | ----- | ----- |
| Revenue | $4.2B | $4.7B |
| EBITDA  | $1.1B | $1.3B |

Multi-column layouts merge into linear flow. Tables are preserved as Markdown tables. Headings are inferred from font size/weight.

LLM Image Description (opt-in)

Markitdown supports an `llm_client` for image description in PPTX and image files. **Never enable by default** — it incurs cost, latency, and unexpected API calls. Prompt the user first: "This file contains images. Do you want me to use Claude to describe them? This will make additional API calls."

import anthropic
from markitdown import MarkItDown

client = anthropic.Anthropic()
md = MarkItDown(llm_client=client, llm_model="claude-sonnet-4-6")
result = md.convert("presentation.pptx")

> **Opus 4.7 vision ceiling:** Opus 4.7 accepts images up to 2,576 pixels on the long edge (~3.75 MP), roughly 3× prior Claude models. When routing image-heavy documents through `llm_model="claude-opus-4-7"`, retain higher-resolution source images rather than pre-downsampling — text in screenshots and diagrams that previously required OCR may now be readable directly.

Error Handling

| Severity | Condition | Action | | ------------ | --------------------------------------------- | ---------------------------------------------------------------- | | **Terminal** | Unsupported format (no converter exists) | Report to user immediately; do not retry | | **Terminal** | Password-protected Office file | Report to user; no programmatic workaround | | **Terminal** | File not found / path invalid | Report exact path; ask user to verify | | **Recover** | Empty output from PDF | Likely scanned — escalate to OCR path in `references/formats.md` | | **Recover** | Missing optional dependency (e.g. playwright) | Install the dependency, then retry the conversion | | **Recover** | URL fetch returns paywall page | Report fetch limitation; do not retry or attempt bypass | | **Recover** | trafilatura returns empty | Escalate to Playwright fetch strategy per `references/fetch.md` |

result = md.convert(path)
if not resu
Read more
Ships witharmory

Curated, production-grade skills, agents, hooks, rules, commands, utilities, and presets for AI coding agents. No magic, no demos — battle-tested workflows built for developers who use AI seriously.

Get the whole plugin

Other skills on armory.