{
  "markdown": "# AILANG Parse\n\n[![AILANG Registry](https://img.shields.io/badge/ailang-sunholo%2Failang__parse-blue?logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0id2hpdGUiIHZpZXdCb3g9IjAgMCAxNiAxNiI+PHRleHQgeD0iMiIgeT0iMTMiIGZvbnQtc2l6ZT0iMTMiPkHwnZC+PC90ZXh0Pjwvc3ZnPg==)](https://github.com/sunholo-data/ailang)\n[![PyPI](https://img.shields.io/pypi/v/ailang-parse?logo=python&logoColor=white&label=PyPI)](https://pypi.org/project/ailang-parse/)\n[![npm](https://img.shields.io/npm/v/@ailang/parse?logo=npm&label=npm)](https://www.npmjs.com/package/@ailang/parse)\n[![Go](https://img.shields.io/github/v/tag/sunholo-data/ailang-parse-go?logo=go&logoColor=white&label=Go)](https://github.com/sunholo-data/ailang-parse-go)\n[![MCP Registry](https://img.shields.io/badge/MCP%20Registry-io.github.sunholo--data%2Fparse-1f6feb?logo=anthropic&logoColor=white)](https://registry.modelcontextprotocol.io/v0/servers?search=sunholo)\n[![CI](https://img.shields.io/github/actions/workflow/status/sunholo-data/ailang-parse/ci.yml?logo=github&label=CI)](https://github.com/sunholo-data/ailang-parse/actions/workflows/ci.yml)\n\nUniversal document parsing **and generation** in [AILANG](https://github.com/sunholo-data/ailang). Extracts structured content from DOCX, PPTX, XLSX, PDF, and image files into JSON and markdown — and writes documents back out in 9 formats. To author a document, write Markdown and convert it; see [Writing documents in Markdown](#writing-documents-in-markdown).\n\n**Office formats** (DOCX, PPTX, XLSX) use deterministic XML parsing — no AI, no cloud, instant results. **PDFs** default to the deterministic `pdftotext` backend (poppler) — also no AI, no cloud — with `docling` and `liteparse` as local alternatives and pluggable AI (Gemini, Claude, local Ollama) for scanned/image-only pages via `--pdf-backend ai`. **Images** delegate to whatever AI model you plug in. AILANG Parse is AI-agnostic: swap `--pdf-backend`/`--ai` to change the backend, zero code changes.\n\n## Install\n\n```bash\ncurl -fsSL https://www.sunholo.com/ailang-parse/install.sh | sh\n```\n\nFetches the published package (~400 KB), installs the\n[AILANG](https://github.com/sunholo-data/ailang) runtime if you do not have it,\nand puts `docparse` on your `PATH`. `--version`, `--prefix` and `--uninstall`\nare supported; re-running is a no-op.\n\nThat covers every deterministic format. PDF needs two more things, and they are\neasy to miss:\n\n```bash\nbrew install poppler        # pdftotext, the default PDF backend\n                            # (apt install poppler-utils on Debian/Ubuntu)\ndocparse --install-backends # docling + liteparse, for scans and layout\n```\n\n`--install-backends` matters even if you never pass `--pdf-backend`: when\n`pdftotext` finds no text layer the parser escalates to `docling` on its own, so\nwithout it a **scanned** PDF fails on the default backend. AI backends\nauthenticate with Google ADC (`gcloud auth application-default login`), not an\nAPI key.\n\n<details>\n<summary>Contributors: install from a clone instead</summary>\n\n```bash\ngit clone https://github.com/sunholo-data/ailang-parse.git\nln -s \"$(pwd)/ailang-parse/bin/docparse\" /usr/local/bin/docparse\n```\n\nThe wrapper finds the project root by walking up for `docparse/main.ail`, so it\nworks from a clone, an installed prefix, or a symlink chain. Note that the CLI\nwrapper and the PDF adapter live under `assets/` — the only path the AILANG\npublisher bundles verbatim — with symlinks at their historical locations.\n</details>\n\n## SDKs\n\nUse AILANG Parse from your language of choice:\n\n```bash\npip install ailang-parse          # Python\nnpm install @ailang/parse         # JavaScript/TypeScript\ngo get github.com/sunholo-data/ailang-parse-go  # Go\n```\n\n## Quick Start\n\n```bash\n# Office documents (deterministic, no AI needed)\ndocparse report.docx\ndocparse slides.pptx\ndocparse spreadsheet.xlsx\n\n# PDF (deterministic pdftotext by default — no AI); images (AI auto-enabled)\ndocparse document.pdf\ndocparse photo.png\n\n# Options\ndocparse report.docx describe        # AI image descriptions\ndocparse report.docx summarize       # AI document summary\ndocparse contract.pdf                # PDF: deterministic pdftotext (default)\ndocparse scan.pdf --pdf-backend ai --ai gemini-2.5-flash  # Scanned PDF needs AI\n\n# Format conversion\ndocparse report.docx --convert output.html\ndocparse data.csv --convert report.docx\ndocparse notes.md --convert slides.pptx\ndocparse notes.md --convert offer.docx --reference-doc letterhead.docx\n\n# AI document generation\nailang run --entry main --caps IO,FS,Env,AI --ai gemini-2.5-flash \\\n  docparse/main.ail --generate report.docx --prompt \"Q1 sales report with tables\"\n```\n\n## Output\n\nEvery run produces:\n- `docparse/data/output.json` — Structured JSON with typed blocks\n- `docparse/data/output.md` — LLM-ready markdown\n\n## What AILANG Parse Extracts\n\n| Feature | DOCX | PPTX | XLSX | Best Competitor |\n|---------|------|------|------|-----------------|\n| Tables with merged cells | Yes | Yes | Yes | Raw OOXML only |\n| Track changes (redlining) | Yes | — | — | Pandoc (3/3) |\n| Comments (interleaved) | Yes | — | — | Raw OOXML (2/2) |\n| Headers/footers | Yes | — | — | Kreuzberg (2/3) |\n| Text boxes / VML shapes | Yes | Yes | — | Raw OOXML (1/2) |\n| Equations (§22.1) | Yes | — | — | None |\n| Field codes (§17.16) | Yes | — | — | Kreuzberg, OOXML |\n| Speaker notes | — | Yes | — | None |\n| Multi-sheet extraction | — | — | Yes | Kreuzberg |\n\n**OfficeDocBench** (69 files, 11 formats, 7 metrics): AILANG Parse **93.9%** composite with 100% coverage vs nearest competitor 68.0% coverage-adjusted. 8 parsers compared including Raw OOXML, Pandoc, Kreuzberg, MarkItDown, Unstructured, Docling. Scores include aspirational ECMA-376 spec targets that intentionally lower our score.\n\n## Supported Formats\n\n**Parsing (16 formats):** DOCX, PPTX, XLSX, ODT, ODP, ODS, HTML, Markdown, CSV, EPUB, EML, MBOX, TEX, RTF, PDF, images (JPG/PNG)\n\n**Generation (9 formats):** DOCX, PPTX, XLSX, ODT, ODP, ODS, HTML, Markdown, QMD (Quarto)\n\n### Writing documents in Markdown\n\nMarkdown is the input an LLM can write, so it is the practical way to generate a\ndocument: write markdown, convert to any of the nine output formats.\n\n```bash\ndocparse report.md --convert report.docx\n```\n\nWhat survives the trip: YAML front matter (title/author/date → document\nproperties), **bold**/*italic*/`code`/~~strike~~ as real character formatting,\nlinks as real hyperlinks, images (local paths are read and embedded), fenced\ncode blocks, blockquotes, nested lists, thematic breaks, and tables with\nalignment and column spans.\n\nHeaders, footers, comments and tracked changes have no Markdown syntax; those\nare preserved when converting from a document that already contains them.\n\n### Styling a generated DOCX from a template\n\n`--reference-doc` is the Quarto/Pandoc `reference-doc` feature: an existing\n`.docx` supplies the look, the Markdown supplies the content.\n\n```bash\ndocparse annex.md --convert annex.docx --reference-doc letterhead.docx\n```\n\nThe template's `styles.xml`, `numbering.xml`, theme, embedded fonts, headers,\nfooters and page setup are applied to the new content. Everything the merge does\nnot regenerate is carried through byte-for-byte, so the letterhead, logo and\nlicensed fonts come out exactly as they went in.\n\nWhat comes from where:\n\n| | |\n|---|---|\n| Template | page size, margins, headers, footers, page numbering, fonts, theme, colours |\n| Your document | the body content, and `docProps/core.xml` (title/author) |\n| Merged | `styles.xml` (ours fill only the styleIds the template lacks), `numbering.xml` (our list definitions take ids above the template's), `[Content_Types].xml`, both `.rels` |\n\nTwo consequences worth knowing:\n\n- **The template's headers and footers win.** A source document's own headers are\n  dropped rather than mixed with the letterhead. The page furniture all lives in\n  the template's body `<w:sectPr>`, which is lifted whole.\n- **The template's comments are dropped** along with its body, and so are\n  `commentsExtended.xml` and `people.xml`. Comments in the *source* document\n  still come through.\n\nTwo flags refine a multi-section template:\n\n- `--reference-section N` picks which of the template's sections supplies the\n  page setup, headers and footers — 1 is the first section, Word's numbering.\n  The default is the last section (the body-level one, what the flag-less\n  behaviour has always lifted). A multi-section template's wanted furniture is\n  often an earlier section's — the master agreement's CONFIDENTIAL footer, not\n  the Annex's missing one.\n- `--table-style NAME` binds generated tables to a table style the template\n  defines (matched on styleId, then style name). Without it, the style named\n  `Table` is used if the template has one, else the first table style that is\n  not the implicit Normal Table. Under a bound style the generator stops\n  emitting its own hardcoded borders — the style carries them.\n\nAn unreadable or non-DOCX reference is an error and writes nothing — a silent\nfallback to the built-in styling would produce a plausible file missing exactly\nthe letterhead it was asked for. DOCX output only.\n\n## Architecture\n\n```\ndocparse/\n├── types/document.ail           # Block ADT (11 variants)\n├── services/\n│   ├── format_router.ail        # Format detection (36 inline tests)\n│   ├── zip_extract.ail          # ZIP layer (9 inline tests)\n│   ├── docx_parser.ail          # DOCX XML → Blocks (6 inline tests)\n│   ├── pptx_parser.ail          # PPTX slides → Blocks\n│   ├── xlsx_parser.ail          # XLSX worksheets → Blocks\n│   ├── direct_ai_parser.ail     # PDF/image → Blocks (AI)\n│   ├── layout_ai.ail            # AI self-healing (optional)\n│   ├── output_formatter.ail     # JSON + markdown output\n│   └── docparse_browser.ail     # WASM browser adapter\n└── main.ail                     # CLI entry point\n```\n\n91 contracts, 50+ inline tests. Of the 91, Z3 proves 14 outright; the rest are\nchecked at runtime under `--prove`/`--verify-contracts` in CI, and skip statically\nbecause parser code is recursive and higher-order, which is outside Z3's\ndecidable fragment.\n\n## AI Configuration\n\nAILANG Parse uses AILANG's AI effect — any model AILANG supports works:\n\n```bash\ndocparse scan.pdf --ai gemini-2.5-flash          # Google (default; fast)\ndocparse scan.pdf --ai gemini-3-flash-preview    # Google (slower; thinking model)\ndocparse scan.pdf --ai granite-docling           # Local Ollama (free)\ndocparse scan.pdf --ai claude-haiku-4-5          # Anthropic\n```\n\nAI usage is bounded by capability budgets (`AI @limit=200` on `main`), so costs are predictable.\n\n## Dev Commands\n\n```bash\ndocparse --check       # Type-check all modules\ndocparse --test        # Run inline tests\ndocparse --prove       # Static Z3 contract verification\n```\n\n## Benchmarks\n\n```bash\nuv run benchmarks/run_benchmarks.py --suite office     # Structural (no API, instant)\nuv run benchmarks/run_benchmarks.py --suite pdf         # PDF extraction (needs AI)\nuv run benchmarks/run_benchmarks.py --competitors       # Compare to Docling etc.\n```\n\nSee [benchmarks/](benchmarks/) for details.\n\n## License\n\nApache 2.0\n",
  "bytes": 11185,
  "sha": "91a08561232e62c29574b00dc106909643f2042d0cf6343782948447c571742f",
  "repo_slug": "sunholo-data/ailang-parse",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_sunholo_data_parse_09e76c8b/readme"
}