- Docs
- Guides
- Converters
- Reference
- Converter skills
Converter skills
Look up each converter’s accepted inputs, outputs, options, dependencies, and operational limitations.
The skills in the converters pack, their inputs, outputs, flags, and prerequisites. Each skill is a thin wrapper: the agent invokes a script and reports the result.
| Skill | Direction | Engine |
|---|---|---|
file-to-markdown | documents/images → Markdown | Docling / vision pipeline |
mermaid-renderer | Markdown → Markdown + images | Mermaid CLI (mmdc) |
markdown-to-html | Markdown → HTML | marked + highlight.js |
markdown-to-docx | Markdown → branded Word (template-fill) | docxtpl |
markdown-to-pptx | Markdown → branded PowerPoint (template-fill) | python-pptx |
markdown-to-xlsx | Markdown → branded Excel (template-fill) | openpyxl |
msg-to-markdown | Outlook .msg → Markdown | @nicecode/msg-reader / msgreader |
file-to-markdown
Section titled “file-to-markdown”Convert documents and images to Markdown. Two branches, selected by input type.
Source: packs/converters/.apm/skills/file-to-markdown/
Inputs
Section titled “Inputs”| Branch | Extensions | Path |
|---|---|---|
| Document | PDF, DOCX, PPTX, XLSX, XLS | scripts/convert.py (Docling) |
| Image | PNG, JPG, JPEG, TIFF, BMP, WEBP, GIF | scripts/split_image.py + agent vision + scripts/reconcile.py |
Prerequisites
Section titled “Prerequisites”| Branch | Needs | Install |
|---|---|---|
| Document | Docling, Pillow | python -m pip install docling Pillow |
| Image | Pillow | python -m pip install Pillow |
The first Docling run downloads ML models (~1–2 min); later runs are fast. Confirm Docling is importable with python -c "import docling" (exit 0 → proceed; non-zero → not installed).
Document branch
Section titled “Document branch”python scripts/convert.py "<input-file>"Writes <basename>.md next to the input. One file per call — loop for a batch. Stdout markers:
| Marker | Meaning |
|---|---|
OUTPUT: <path> | Path to the written Markdown file |
LINES: <n> / WORDS: <n> | Counts |
WARNING: <msg> | Non-fatal (e.g. sparse text); surfaced to the user |
Image branch
Section titled “Image branch”A two-pass sliding-window pipeline:
| Step | Command | Output |
|---|---|---|
| Recommend | split_image.py recommend --input <image> | JSON: source dims, single-pass flag, recommended viewport/stride |
| Overview | split_image.py overview --input <image> --output-dir <dir>/ --max-dim 1200 | <dir>/overview.png (agent reads it for a structural map) |
| Detail | split_image.py detail --input <image> --output-dir <dir>/ --viewport 1200 --stride 800 | tile_W0_R<row>_C<col>.png + detail_manifest.json |
| Reconcile | reconcile.py --manifest … --extractions … --strategy <name> --title "…" --output-json <dir>/merged.json --output-md <output>.md | merged JSON + final Markdown |
The agent reads each detail tile and writes <dir>/extractions.json, choosing one extraction strategy: architecture, event-storm, process, domain, or conceptual. reconcile.py then translates tile coordinates to global ones, collapses duplicates by (type, normalized_name) and by IoU ≥ 0.5, picks canonical records by confidence then tile-centrality, sorts by the structural map’s layout, and emits Markdown with YAML frontmatter. Reconcile stdout: OUTPUT_JSON, OUTPUT_MD, ELEMENTS, AMBIGUITIES.
Edge cases
Section titled “Edge cases”| Situation | Behavior |
|---|---|
| Image ≤ 1200 px on both dims | Skip overview; run a single detail tile (--viewport/--stride = max dim) |
| Source > 8000 px on a side | Script auto-prescales before tiling, records the factor in the manifest |
| Scanned PDF | Docling applies OCR automatically; surfaces any WARNING: |
| Password-protected file | Document branch fails fast; remove the password first |
| Detail pass > 100 tiles | split_image.py warns; raise --stride or lower --viewport |
| Tile read fails | Skipped; reconciler reports the gap in ambiguities |
mermaid-renderer
Section titled “mermaid-renderer”Extract ```mermaid fenced blocks from a Markdown file, render each to an image, and write a rewritten Markdown file with each fence replaced by an image reference. The original input is not modified.
Source: packs/converters/.apm/skills/mermaid-renderer/
Prerequisites
Section titled “Prerequisites”The Mermaid CLI (mmdc), installed via npm install -g @mermaid-js/mermaid-cli (or a project-local node_modules/ on PATH). No Python deps beyond the standard library. Verify with python scripts/render_mermaid.py --check (exit 0 → ready; exit 2 → not installed).
Command
Section titled “Command”python scripts/render_mermaid.py --input report.md --output-dir ./rendered [flags]| Flag | Meaning |
|---|---|
--input PATH | Source Markdown file. Required. |
--output-dir DIR | Directory for images and the rewritten Markdown. Default: ./mermaid-out. |
--format png|svg | Output format. Default: png. |
--theme default|forest|dark|neutral | Mermaid theme. Default: default. |
--background white|transparent|#hex | Background color. Default: white. |
--prefix NAME | Output filename prefix. Default: mermaid. |
--width N | Output width in px (passes to mmdc -w). |
--height N | Output height in px (passes to mmdc -H). |
--check | Verify mmdc is on PATH; exit 0 or 2. |
--verbose | Debug logging. |
Outputs
Section titled “Outputs”<output-dir>/<prefix>-1.<ext>,<prefix>-2.<ext>, … — one image per block, numbered in document order.<output-dir>/<input-basename>.md— rewritten copy with each fence replaced by a Markdown image reference.
Stdout: OUTPUT_DIR, REWRITTEN, DIAGRAMS.
Edge cases
Section titled “Edge cases”| Situation | Behavior |
|---|---|
| No Mermaid blocks | DIAGRAMS: 0, input copied through unchanged, exit 0 |
| A block fails to render | Writes mermaid-N.error.txt, leaves the fence intact, keeps going, exits non-zero with a failure count |
| Unknown theme | mmdc exits with the valid choices; surfaced |
mmdc not on PATH | --check exits 2 with the install command |
markdown-to-html
Section titled “markdown-to-html”Convert a Markdown file to a self-contained, styled HTML page (sticky header, sidebar nav, syntax-highlighted code, callout boxes, Mermaid diagrams, print-ready). For documents, not slides.
Source: packs/converters/.apm/skills/markdown-to-html/
Prerequisites
Section titled “Prerequisites”Node.js with marked and highlight.js (pinned in the skill’s package.json). Verify from the skill directory with node -e "require.resolve('marked'); require.resolve('highlight.js')" (exit 0 → ready; non-zero → run npm install once). Add the skill’s node_modules/ to .gitignore if the skill lives in a tracked directory.
Command
Section titled “Command”node scripts/render.js <input.md> [flags]| Flag | Meaning |
|---|---|
--output FILE | Output path. Default: input with .html extension. |
--title TEXT | Page title. Default: first H1, then filename. |
--subtitle TEXT | Header subtitle (small grey text). |
--theme navy|green|teal|amber|rose | Accent color. Default: navy. |
--no-mermaid | Skip the Mermaid CDN script. |
Outputs
Section titled “Outputs”Writes the HTML file and prints three stdout lines:
| Marker | Meaning |
|---|---|
OUTPUT: <path> | Path to the written HTML file |
SECTIONS: <n> | Number of h2/h3 anchors built |
MERMAID: yes|no | Whether Mermaid handling was emitted |
Handled automatically
Section titled “Handled automatically”- Headings get stable
idattributes for sidebar links and the print TOC. - Code blocks are syntax-highlighted;
```mermaidfences pass through as<div class="mermaid">for the runtime CDN renderer. - Tables are wrapped in
<div class="table-wrap">for horizontal scroll. - Paragraphs beginning with
**Note:**,**Tip:**,**Warning:**,**Important:**, or**Stop:**become styled callout boxes. - Every output includes an
@media printblock;Ctrl+P → Save as PDFworks out of the box.
Edge cases
Section titled “Edge cases”| Situation | Behavior |
|---|---|
| Missing dependencies | render.js exits 1 with an install hint |
| No headings | Sidebar shows (no sections); output still works |
| Unknown theme | Exits with the list of valid choices |
| Offline output wanted with Mermaid present | Pass --no-mermaid; the block falls back to a plain <pre> |
markdown-to-docx
Section titled “markdown-to-docx”Fill a branded Word template from a Markdown artifact. Template-fill via docxtpl — the designer’s cover page, styles, headers, and logo survive; the skill never converts Markdown into a fresh document.
Source: packs/converters/.apm/skills/markdown-to-docx/
Prerequisites
Section titled “Prerequisites”Tier-1 on docxtpl (exact canonical PyPI package). Install with python -m pip install 'docxtpl>=0.16.0' (the floor clears a version where get_undeclared_template_variables() was broken). The library installs into your environment, outside the repo’s SCA. Verify with python scripts/render.py --check (exit 0 → ready; exit 2 → not installed).
Commands
Section titled “Commands”python scripts/render.py --checkpython scripts/render.py inspect <template.docx>python scripts/render.py render <markdown> --template <template.docx> [--output <path>]| Verb | Purpose |
|---|---|
--check | Import-probe docxtpl; exit 0/2. |
inspect <template> | List the template’s declared Jinja variables. |
render <markdown> --template <tpl> | Fill the template and write a .docx. Default output: <basename>.docx in CWD. |
Fill-points and mapping
Section titled “Fill-points and mapping”A .docx has no fill-points until you add Jinja tags: {{ var }} (scalar), {%p for it in items %}…{%p endfor %} (paragraph loop), {%tr for r in rows %}…{%tr endfor %} (table-row loop). Mapping: front-matter key: value → {{ key }}; the first list → items; the first Markdown table → rows (list of {column: value} dicts). Author each tag in one uniform run or Word’s run-splitting will hide it.
Outputs and edge cases
Section titled “Outputs and edge cases”Stdout: OUTPUT:, FILLED:, WARNING:, and GUIDANCE: (emitted instead of OUTPUT: when the template has no tags). Renders with autoescape=True, so user content with </&/{{ is XML-escaped, not interpolated. A user-supplied template is trusted-author input — a malicious template author could embed SSTI; that (and XXE / zip-bomb) is an accepted, out-of-scope risk. The output write is confined under the working directory. Omit --template only on the user’s explicit opt-out — the skill then writes an unbranded .docx via python-docx (with a WARNING:).
markdown-to-pptx
Section titled “markdown-to-pptx”Fill a branded PowerPoint template from a Markdown artifact. Template-fill via python-pptx — the slide master, theme, fonts, and placed logo survive.
Source: packs/converters/.apm/skills/markdown-to-pptx/
Prerequisites
Section titled “Prerequisites”Tier-1 on python-pptx. Install with python -m pip install 'python-pptx>=1.0.0'. Installs outside the repo’s SCA. Verify with python scripts/render.py --check.
Commands
Section titled “Commands”python scripts/render.py --checkpython scripts/render.py inspect <template.pptx>python scripts/render.py render <markdown> --template <template.pptx> [--output <path>]| Verb | Purpose |
|---|---|
--check | Import-probe python-pptx; exit 0/2. |
inspect <template> | List the layout placeholders (layout/idx/type/name). |
render <markdown> --template <tpl> | Fill the deck and write a .pptx. Default output: <basename>.pptx in CWD. |
Fill-points and mapping
Section titled “Fill-points and mapping”PowerPoint layouts already carry placeholders, keyed by their stable idx — so every .pptx is fillable (no “untagged template” case). Mapping: front-matter title/subtitle → the title slide; each #/## heading → one slide; list items → bullet rows; a Markdown table → a TABLE placeholder if the layout has one, else a table added to the slide.
Outputs and edge cases
Section titled “Outputs and edge cases”Stdout: OUTPUT:, FILLED:, WARNING:. python-pptx evaluates no template content as code, so there is no SSTI surface; XXE / zip-bomb on a crafted archive is an accepted, out-of-scope risk. The output write is confined under the working directory. Omit --template only on the user’s explicit opt-out (renders with the python-pptx default master; unbranded).
markdown-to-xlsx
Section titled “markdown-to-xlsx”Fill a branded Excel template from a Markdown artifact. Template-fill via openpyxl — writes into named ranges and Excel Tables only, so formatting, formulas, and charts survive.
Source: packs/converters/.apm/skills/markdown-to-xlsx/
Prerequisites
Section titled “Prerequisites”Tier-1 on openpyxl. Install with python -m pip install 'openpyxl>=3.1.0'. Installs outside the repo’s SCA. Verify with python scripts/render.py --check.
Commands
Section titled “Commands”python scripts/render.py --checkpython scripts/render.py inspect <template.xlsx>python scripts/render.py render <markdown> --template <template.xlsx> [--output <path>]| Verb | Purpose |
|---|---|
--check | Import-probe openpyxl; exit 0/2. |
inspect <template> | List named ranges + Excel Tables (kind/name/ref). |
render <markdown> --template <tpl> | Fill the data ranges and write a .xlsx. Default output: <basename>.xlsx in CWD. |
Fill-points and mapping
Section titled “Fill-points and mapping”A workbook needs named ranges (for scalars) and/or Excel Tables (for tabular data) defined beforehand. Mapping: front-matter key: value → the single-cell named range called key; the first Markdown table → the first Excel Table’s data region (columns aligned by header, else by position).
Outputs and edge cases
Section titled “Outputs and edge cases”Stdout: OUTPUT:, FILLED:, WARNING:, and GUIDANCE: (when the workbook has no fill-points). The script writes only into data cells and never resizes a range, so a chart reading it keeps working; a Markdown table longer than the Excel Table is truncated with a WARNING:, never expanded. openpyxl preserves charts/images it can parse on round-trip, but its tutorial warns shapes it cannot read are lost — re-open and verify for complex templates. The output write is confined under the working directory. Omit --template only on the user’s explicit opt-out — the skill then writes an unbranded .xlsx via a bare openpyxl workbook (with a WARNING:).
msg-to-markdown
Section titled “msg-to-markdown”Convert Outlook .msg email files to Markdown, preserving headers (From, To, CC, Date), body content, and attachment metadata.
Source: packs/converters/.apm/skills/msg-to-markdown/
Prerequisites
Section titled “Prerequisites”Node.js with one of @nicecode/msg-reader (preferred) or msgreader; scripts/convert.js uses whichever is installed. Install with npm install @nicecode/msg-reader. Verify from the skill directory:
node -e "try{require.resolve('@nicecode/msg-reader')}catch{require.resolve('msgreader')}"Commands
Section titled “Commands”| Command | Purpose |
|---|---|
node scripts/convert.js "<file>.msg" | Convert one .msg to Markdown |
node scripts/extract-attachments.js "<file>.msg" | Extract attachments to a folder |
For a glob like emails/*.msg, loop over each file individually.
Output
Section titled “Output”Structured Markdown with a header table (From/To/CC/Date), the body, and attachment metadata. HTML bodies are converted (complex CSS or conditional Outlook markup may be simplified).
Edge cases
Section titled “Edge cases”| Situation | Behavior |
|---|---|
| RTF-only body | Flagged; re-save as HTML in Outlook or install an RTF parser |
| Winmail.dat / TNEF | May not parse; node-tnef suggested |
Inline images (cid:) | Stored as attachments; broken refs until extracted |
| Reply chains | Quoted replies preserved as nested blockquotes |
| Unusual encoding | Re-read as UTF-8 / UTF-16LE / Windows-1252 |
Calendar .ics attachment | Offered for parsing into a structured section |
| Sensitivity labels | Included in the metadata table when present |
For task recipes, see the how-to guides. Installing and upgrading the pack live in ../../_shared/.