Why Markdown is the authoring format
Generating an Office document usually means one of two bad options: drive a headless Office install and inherit its licensing and crash surface, or hand-assemble OOXML and discover that Word is stricter than the spec. Both are heavy for what is normally a simple job — turn some content into a file someone can open.
AILANG Parse takes a different route. Markdown is the one format a human or a language model can write fluently, and the Markdown parser here is a full authoring front end, not a text-extraction afterthought. Write Markdown, convert it, and the structure becomes real document structure: character runs, working hyperlinks, embedded image parts, table grids with column spans.
How it works
One source file fans out to 9 output formats. Headings become slides in PPTX; tables become sheets in XLSX and ODS; everything else maps to the closest native construct.
# Write the document in Markdown, then convert it to any of the 9 formats.
# Front matter sets the document properties.
cat > report.md <<'MD'
---
title: Q1 Revenue Review
author: Finance
date: 2026-04-02
---
# Q1 Revenue Review
Revenue grew **31%** against a [flat forecast](https://example.com/plan).
| Region | Q4 | Q1 | Change |
|:-------|--------:|--------:|:------:|
| EMEA | 1.20M | 1.61M | +34% |
| AMER | 0.90M | 1.14M | +27% |
> Renewals, not new logos, drove the quarter.
MD
# One source, every output format
docparse report.md --convert report.docx # Word
docparse report.md --convert deck.pptx # headings become slides
docparse report.md --convert report.xlsx # tables become sheets
docparse report.md --convert report.odt # OpenDocument
docparse report.md --convert report.html # HTML
docparse report.md --convert report.qmd # Quarto
# Read the structure back to check it survived —
# "the file opens" is not the same as "the file is correct"
docparse report.docx
No Office install, no headless browser, no subprocess. The generators write OOXML and OpenDocument containers directly from the parsed block structure.
What survives the trip
These are not rendered as literal characters — they become real formatting in the output container.
| Markdown | Becomes | Status |
|---|---|---|
| YAML front matter | title/author/date document properties | Preserved |
**bold** *italic* `code` ~~strike~~ | real character runs | Preserved |
[text](url) | real hyperlinks (OOXML HYPERLINK fields) | Preserved |
 | image read from disk and embedded | Preserved |
| Fenced code blocks | monospaced code paragraphs | Preserved |
| Blockquotes, nested lists, rules | native quote/list/separator styles | Preserved |
Tables with :---: alignment | table grid with alignment and colspan | Preserved |
What Markdown can't say
Headers, footers, comments and tracked changes have no Markdown syntax, so they cannot be authored this way. They are preserved when you convert from a document that already contains them — DOCX to DOCX, or DOCX to ODT.
| Feature | From Markdown | From a document that has it |
|---|---|---|
| Running headers / footers | No syntax | Preserved |
| Comments with author attribution | No syntax | Preserved |
| Tracked changes | No syntax | Preserved |
If you need a generated document to carry a running header, start from a source document rather than a Markdown file. See comment extraction and track changes for how those survive a conversion.
Over the API
POST /api/v1/convert takes the same four input modes as the parse endpoint — multipart upload, a sample ID, an https:// URL the server fetches, or a gs:// reference on Business tier — plus a target.
# Generate a DOCX from Markdown via the hosted API.
# The document comes back inside the JSON, not as a binary body.
curl -s -X POST https://docparse.ailang.sunholo.com/api/v1/convert \
-F "filepath=@report.md" \
-F "target=docx" \
-F "apiKey=$DOCPARSE_API_KEY" > response.json
# `encoding` is load-bearing: "base64" for the six ZIP container targets
# (docx, pptx, xlsx, odt, odp, ods) and "utf8" for the three text targets
# (html, md, qmd). Branch on the field, never on the target.
python3 - <<'PY'
import base64, json
r = json.load(open("response.json"))
# Unwrap the serve-api envelope, same as /api/v1/parse
if isinstance(r.get("result"), str):
r = json.loads(r["result"])
data = (base64.b64decode(r["content"]) if r["encoding"] == "base64"
else r["content"].encode("utf-8"))
open(r["filename"], "wb").write(data)
print(f'{r["filename"]} {r["content_type"]} {r["size_bytes"]} bytes')
PY
# Other input modes — a sample ID, or a URL the server fetches itself
curl -s -X POST https://docparse.ailang.sunholo.com/api/v1/convert \
-H "Content-Type: application/json" \
-d '{"filepath":"sample_docx_tables","target":"html","apiKey":"'"$DOCPARSE_API_KEY"'"}'
curl -s -X POST https://docparse.ailang.sunholo.com/api/v1/convert \
-H "Content-Type: application/json" \
-d '{"sourceUrl":"https://example.com/notes.md","target":"pptx","apiKey":"'"$DOCPARSE_API_KEY"'"}'
The generated document comes back inside the JSON, not as a binary body:
{
"status": "success",
"target": "docx",
"filename": "report.docx",
"content_type": "application/vnd...wordprocessingml.document",
"encoding": "base64",
"size_bytes": 8213,
"content": "UEsDBBQ..."
}
encoding is load-bearing. It is base64 for the six ZIP container targets and utf8 for the three text targets. Branch on the field, never on the target name — decoding a utf8 payload as base64 fails silently and writes garbage.Conversion is charged per generated document on the same counters as parsing. Output size does not affect the cost, and the AI sub-quota is only touched when the source needs AI — a PDF or an image. Generating from Markdown is pure compute.
For AI agents
Over MCP the tool is mcpConvert, and the workflow is the one you would expect: write the Markdown yourself, then convert it.
mcpConvert(input: "report.md", outputFormat: "docx", apiKey: "dp_...")
Prompt-based generation (--generate report.docx --prompt "...") exists in the local CLI only. It is deliberately absent from the hosted API, which is deterministic conversion with a matching price. If a user wants a document authored from a prompt, write the Markdown and convert it. See the MCP server guide and llms-full.txt.
Try it
Parse any of 16 input formats, generate any of 9:
# Markdown to a Word document
curl -X POST https://docparse.ailang.sunholo.com/api/v1/convert \
-F "filepath=@report.md" -F "target=docx" -F "apiKey=YOUR_API_KEY"
# Or convert a built-in sample, no upload needed
curl -X POST https://docparse.ailang.sunholo.com/api/v1/convert \
-H "Content-Type: application/json" \
-d '{"filepath":"sample_docx_tables","target":"pptx","apiKey":"YOUR_API_KEY"}'
Frequently Asked Questions
How do I generate a DOCX from Markdown?
Run docparse report.md --convert report.docx, or POST the file to /api/v1/convert with target=docx. Front matter becomes document properties, and bold, links, images and tables become real Word formatting.
Can I convert Markdown to PowerPoint?
Yes — docparse notes.md --convert slides.pptx turns headings into slides. The same source also converts to XLSX, ODT, ODP, ODS, HTML and Quarto.
Can generated documents have headers, footers or tracked changes?
Not from Markdown — those have no Markdown syntax. They survive when you convert from a document that already contains them, such as DOCX to ODT.
Can AILANG Parse write a document from a prompt?
The local CLI can, via --generate with --prompt. The hosted API cannot — it is deterministic conversion only. Have your model write the Markdown, then convert it.
Do I need Microsoft Office or LibreOffice installed?
No. The generators write OOXML and OpenDocument containers directly — no headless Office, no subprocess, no license.