Skip to main content
CocoaPDF document-and-cocoa-bean mark

CocoaPDF

Turn structured PDFs into accurate, editable documents—without OCR or AI.

CocoaPDF recovers the text, layout, tables, links, notes, forms, and images already present inside a PDF, then rebuilds them as readable Markdown, structured HTML, and detailed JSON.


Download for Windows Download for Linux Download for macOS

Verified OpenDataLoader score Verified OpenDataLoader conversion time ODL verification workflow

Python 3.9 or later OCR None MIT License Markdown, HTML, and JSON output

How it works    Capabilities    Installation    Usage    Python API    Diagnostics



CocoaPDF converts digitally born, structured text-layer PDFs into semantic Markdown, loss-aware HTML, and provenance-rich JSON. It parses PDF bytes directly with Python's standard library, reconciles geometry with Tagged-PDF structure, and carries available source-page, region, glyph, MCID, and PDF-object references alongside confidence, evidence, and warnings.

It does not use OCR, AI, or runtime PDF frameworks. Raster images remain images, with their PDF placement, dimensions, alignment, links, captions, and alternative text preserved whenever available.

At a glance

01 RECOVER

Recover document structure

Reading order, paragraphs, headings, lists, tables, figures, notes, forms, and links from PDF-native evidence.

02 PRESERVE

Preserve available evidence

Retain available source pages, regions, glyph and MCID references, PDF objects, confidence, evidence, and warnings.

03 EXPORT

Export faithfully

Drive Markdown, independent semantic HTML, JSON, reports, and extracted assets from one reconciled document graph.

Best fit: digitally born reports, manuals, papers, office exports, accessible PDFs, forms, and multi-column documents with selectable text.

Unlike positional text extraction, CocoaPDF reconciles PDF tags with page geometry and falls back conservatively when evidence is ambiguous.

[!IMPORTANT] CocoaPDF does not transcribe text that exists only in raster pixels. It preserves raster content as images, including placement, dimensions, links, captions, and alternative text when encoded by the PDF.


Capability demo

Browse this revision's committed inputs and exact outputs. On main, open the rendered, side-by-side capability demo. Same-repository pull requests receive a commit-pinned rendered-demo link in their description, so reviewing a child branch never silently opens main. For security, fork pull requests expose the generated review artifact but not a one-click third-party rendering of contributor-controlled HTML.

The three complex source PDFs, fixture prose, and assets are first-party project material under the bundled MIT license; no downloaded content, OCR, AI, or ML is used. They remain separate because Tagged-PDF structure trees, AcroForm fields, and outlines are document-catalog semantics: concatenating their pages would change the evidence being tested rather than merely combine examples.

The committed examples/ tree is distinct from temporary pull-request review artifacts. CI regenerates it from the same case definitions and fails if any checked-in source or output becomes stale.


Benchmark results

CocoaPDF 0.1.0 at commit 59a544a measured on all 200 documents of the DP-Bench corpus using the unmodified OpenDataLoader-Bench evaluator at 7af1d8f4, run twice on 2026-08-02.

Metric Mean Eligible documents
Overall document-macro score 0.9020490607 200
NID (reading order) 0.9086028983 200
NID-S (tables removed) 0.8897361669 200
TEDS (table structure) 0.9251323351 42
TEDS-S (structure only) 0.9300636650 42
MHS (heading structure) 0.8791989022 107
MHS-S (structure only) 0.9415827438 107

200 evaluated, 200 prediction files, 0 missing, 0 empty, and 0 conversion failures. TEDS is scored only on the 42 documents whose ground truth contains a table, and MHS only on the 107 that contain a heading; overall_mean is the mean of each document's available metrics, not the mean of the three aggregates.

Overall, NID, TEDS, and MHS clear the enforced 0.80 floors, and the document-macro score clears 0.90. Two full runs produced byte-identical Markdown for all 200 documents and identical aggregate and per-document scores. The live speed badge is recomputed by trusted CI as total timed conversion seconds divided by the audited 200-page denominator bound to the hash-verified corpus; it is one page-weighted s/page observation, not a per-file range. See validation/benchmarks/opendataloader_bench/RESULTS.md for exact deltas, determinism evidence, and remaining no-OCR limitations.

Evaluation artifacts — result.json, evaluation.json, evaluation.csv, summary.json, provenance.json, prediction-hashes.json, determinism.json, the adapter, and the benchmark integration patch — are committed under examples/benchmarks/opendataloader-bench/7af1d8f4…. No source PDFs, ground truth, or predicted Markdown are redistributed. The benchmark-only output-schema adapter lives in validation/benchmarks/opendataloader_bench/adapter.py and never changes CocoaPDF's default conversion.


How it works

Every output is generated from one reconciled semantic document graph:

PDF bytes and operators
        │
        ▼
COS objects, streams, resources, fonts, glyphs,
graphics, images, annotations, forms, and tags
        │
        ▼
Normalized source representation
        │
        ▼
Layout, regions, reading order, and page structure
        │
        ▼
Tagged-PDF and geometric reconciliation
        │
        ▼
Authoritative semantic document graph
        ├── Markdown
        ├── HTML
        ├── semantic JSON
        └── report and assets

The graph may contain:

  • headings and paragraphs;
  • inline styles and links;
  • ordered, unordered, and nested lists;
  • quotations and code;
  • tables, cells, captions, and notes;
  • figures and preserved image assets;
  • footnotes and endnotes;
  • references, citations, and cross-references;
  • outlines and table-of-contents entries;
  • form fields and widgets;
  • anchors and explicit page boundaries.

Markdown remains the preferred output. Structured HTML is used when Markdown cannot safely express table spans, nested cell content, vertical writing, dimensions, alignment, or other document semantics.


Scope and safety policy

CocoaPDF operates directly on the information already encoded in the PDF.

Supported document class

CocoaPDF is intended for:

  • reports and manuals;
  • academic and technical documents;
  • business and financial documents;
  • exported office documents;
  • tagged and accessible PDFs;
  • forms with existing field values;
  • documents containing tables, figures, notes, references, and multiple columns.

Deliberately excluded

CocoaPDF does not:

  • perform OCR;
  • infer text from image pixels;
  • use AI or machine-learning models;
  • execute JavaScript, form actions, launch actions, or embedded programs;
  • invent missing Unicode characters, cells, destinations, labels, or form values;
  • submit, reset, calculate, or validate PDF forms.

Raster images are preserved as images. Their placement, dimensions, alignment, links, captions, and alternative text are retained when available.

Encrypted PDFs are refused unless their contents can be validated safely. Unsupported or malformed constructs produce warnings and conservative fallbacks rather than silent fabrication.


Capabilities

Semantic document recovery

CocoaPDF can reconstruct:

  • paragraphs across visually wrapped PDF lines;
  • hard and soft line breaks;
  • hyphenated line wraps;
  • heading levels and numbered headings;
  • bold, italic, monospace, underline, strike, highlight, superscript, and subscript evidence;
  • inline and fenced code;
  • block quotations;
  • horizontal separators;
  • ordered, unordered, mixed, and nested lists;
  • multiple columns, sidebars, callouts, figures, tables, and footnote regions;
  • repeated headers, footers, logos, page numbers, and other page furniture.

Reading order is determined from page geometry, regions, tags, and source evidence rather than raw object order alone.

Tables

CocoaPDF supports both ruled and carefully accepted borderless tables.

Capabilities include:

  • grid and lattice detection;
  • precision-gated borderless table detection;
  • conservative missing-border span inference;
  • rowspans and colspans;
  • rotated headers;
  • multiline and nested cell content;
  • typed table captions and notes;
  • cell alignment;
  • per-cell provenance, evidence, warnings, and confidence;
  • guarded continuation across page boundaries;
  • GFM output for simple tables;
  • structured HTML fallback for tables Markdown cannot represent faithfully.

Article columns, bibliographies, aligned prose, and other table-like layouts are rejected when the evidence is insufficient.

Figures and images

CocoaPDF preserves raster images without attempting to read text from them.

It can retain:

  • the original image bytes or an embedded data URI;
  • PDF placement quads;
  • displayed width and height;
  • page alignment;
  • image links;
  • figure captions;
  • Tagged-PDF alternative text;
  • source-page and object provenance;
  • repeated-asset deduplication.

A conservative vector-to-SVG approximation is available for supported vector figures.

Notes, references, and navigation

CocoaPDF can reconstruct:

  • footnote and endnote references;
  • note definitions and continuation blocks;
  • reference and bibliography sections;
  • citations;
  • references to figures, tables, sections, equations, appendices, and notes;
  • PDF outlines and bookmarks;
  • visible tables of contents;
  • named and direct destinations;
  • anchors and internal links.

Targets are linked only when resolution is sufficiently reliable. Unresolved references remain readable text with diagnostic metadata.

AcroForm semantics

CocoaPDF reads AcroForm field trees without executing field actions.

Supported field semantics include:

  • text fields;
  • multiline values;
  • choice fields;
  • selected options;
  • checkboxes;
  • radio buttons;
  • push-button identification;
  • signature fields;
  • inherited field attributes;
  • widget provenance;
  • password-value redaction.

CocoaPDF never submits, resets, calculates, validates, imports, launches, or executes a form action.


Tagged PDF support

Tagged-PDF information is treated as a strong semantic prior and checked against page geometry and marked-content ownership.

Supported structures include:

  • StructTreeRoot;
  • global and namespace RoleMap;
  • ClassMap;
  • ParentTree;
  • StructParents and StructParent;
  • MCIDs;
  • MCR and OBJR references;
  • /Pg and /Stm;
  • /ActualText;
  • /Alt;
  • /E;
  • /Lang;
  • artifact markers;
  • structure attributes;
  • list numbering;
  • table row and column spans.

Reconciliation can materialize tagged:

  • headings;
  • paragraphs;
  • lists;
  • tables;
  • figures;
  • captions;
  • links;
  • TOC entries;
  • notes;
  • artifacts.

Broken or incomplete tag trees fall back to geometric reconstruction rather than overriding credible page evidence.


PDF and text foundation

PDF object, stream, graphics, and font support

PDF structure

  • Classic cross-reference tables.
  • Cross-reference streams.
  • Hybrid and incremental chains.
  • Object streams.
  • Indirect stream lengths.
  • Page trees and inherited resources.
  • Content arrays.
  • Form XObjects.
  • Stream-aware malformed-file recovery.
  • Configurable object, recursion, decompression, glyph, path, and image limits.

Stream filters

  • Flate.
  • ASCII85.
  • ASCIIHex.
  • RunLength.
  • LZW.
  • Pass-through handling for supported image filters.

Content and graphics

  • Text-state operators.
  • Geometry and transformation matrices.
  • Paths and painted rectangles.
  • Clipping bounds.
  • Graphics-state alpha.
  • Images and image masks where safely representable.
  • Form recursion protection.
  • Link and non-link annotation metadata.
  • Marked-content properties.
  • Inline images.

Fonts and Unicode

  • Standard-14 fonts and metrics.
  • PDFDocEncoding.
  • WinAnsi and Differences encodings.
  • ToUnicode CMaps.
  • Composite CID fonts.
  • Selected predefined Unicode CMaps.
  • Ligature normalization.
  • Vertical DW2 and W2 metrics.
  • Geometry-derived spacing.
  • TJ displacements.
  • Duplicate and faux-bold suppression.
  • Invisible-text handling.
  • Unicode bidirectional reordering.

Bidirectional and vertical text

CocoaPDF includes source-preserving bidirectional processing for mixed left-to-right and right-to-left text.

The implementation handles:

  • paragraph direction;
  • explicit embeddings and overrides;
  • directional isolates;
  • weak and neutral resolution;
  • paired-bracket behavior;
  • implicit embedding levels;
  • visual line reordering.

Vertical writing support includes:

  • vertical CMaps;
  • vertical glyph origins and displacements;
  • DW2 and W2 metrics;
  • vertical TJ movement;
  • vertical geometry;
  • loss-aware HTML using vertical writing modes.

The repository includes a checker for the official Unicode BidiCharacterTest.txt and BidiTest.txt corpus formats.


Outputs

Markdown

Markdown output is CommonMark-oriented and uses GFM-compatible tables where appropriate.

Generated HTML is inserted only where Markdown cannot safely preserve the original structure, such as:

  • rowspan or colspan tables;
  • nested cell content;
  • vertical text;
  • image sizing and alignment;
  • complex figures;
  • unsupported native Markdown semantics.

HTML

HTML is emitted directly from the semantic graph rather than being reconstructed from Markdown.

This preserves:

  • typed sections and headings;
  • semantic lists;
  • table structure;
  • cell spans;
  • captions and notes;
  • figures;
  • form semantics;
  • anchors and internal navigation;
  • vertical writing;
  • source and diagnostic metadata where configured.

JSON and reports

Semantic JSON exposes the document graph in a machine-readable form.

Reports can include:

  • semantic nodes;
  • source references;
  • source pages and regions;
  • glyph identifiers;
  • MCIDs;
  • PDF object references;
  • bounding boxes;
  • confidence;
  • evidence;
  • warnings;
  • page processing modes;
  • extracted assets;
  • graph-validation results;
  • low-confidence decisions.

For image nodes, the report explicitly records:

{
  "ocr_used": false,
  "text_extraction_attempted": false
}

Installation

Native downloads

Use the platform buttons at the top of this README to download the latest published release.

The published release packages are:

cocoapdf-windows-x86_64.zip
cocoapdf-linux-x86_64.tar.gz
cocoapdf-macos.tar.gz

The macOS package contains separate Apple Silicon and Intel executables. The Linux x86_64 binary uses an Ubuntu 22.04 build baseline for broader glibc compatibility.

Before execution, verify the package against SHA256SUMS.txt and inspect its per-binary provenance in RELEASE.json. Downloads are intentionally lean: Windows and Linux contain one executable, the MIT license, and the exact third-party notices captured by that build; macOS contains its Apple Silicon and Intel executables, the MIT license, and notices for both runtimes. The Windows executable embeds the CocoaPDF icon and product/version metadata.

Install from source

CocoaPDF requires Python 3.9 or later and has no runtime dependencies.

python -m pip install .

Run from the repository

Linux and macOS:

export PYTHONPATH=src
python -m cocoapdf.cli input.pdf

Windows PowerShell:

$env:PYTHONPATH = "src"
python -m cocoapdf.cli input.pdf

The repository launcher is equivalent:

python run_cocoapdf.py input.pdf

Usage

Common conversions

# Convert to Markdown and print to stdout
cocoapdf input.pdf

# Write Markdown, extracted assets, and a diagnostic report
cocoapdf input.pdf \
  -o document.md \
  --assets assets \
  --report report.json

# Produce semantic HTML
cocoapdf input.pdf \
  --format html \
  -o document.html

# Produce a Markdown, HTML, JSON, and report package
cocoapdf input.pdf \
  --format both \
  -o output

# Produce a JSON envelope containing the graph, report, Markdown, and HTML
cocoapdf input.pdf \
  --format json \
  -o result.json

# Convert selected pages and preserve explicit page boundaries
cocoapdf input.pdf \
  --pages 1,3-5 \
  --page-breaks \
  -o excerpt.md

When --format both targets a directory, CocoaPDF writes:

output/
├── document.md
├── document.html
├── document.json
└── report.json

Referenced assets are written to the directory supplied through --assets.


Image handling

# Extract image files and reference them from the output
cocoapdf input.pdf \
  --image-mode reference \
  --assets assets

# Embed image bytes as data URIs
cocoapdf input.pdf \
  --image-mode embed

# Preserve dimensions and alignment inside the Markdown file when needed
cocoapdf input.pdf \
  --image-markup auto

# Native Markdown image syntax (default)
cocoapdf input.pdf \
  --image-markup markdown

# Force generated HTML figure and image markup
cocoapdf input.pdf \
  --image-markup html

--image-markup markdown is the default. The Markdown projection stays portable, while CocoaPDF's independent HTML projection still preserves figure dimensions, alignment, captions, placement, and links. Use auto or html only when that controlled HTML must also be embedded in the Markdown file itself.


Independent HTML projection

Markdown and HTML are sibling projections of the reconciled semantic graph. HTML is not produced by converting CocoaPDF's Markdown back into a document. The HTML renderer emits native headings, sections, lists and disabled task controls, figures and captions, table header scopes and spans, footnote and bibliography roles, language and direction attributes, documentary form fields, MathML, and responsive/print CSS. Semantic elements also carry stable node, confidence, and source-page data attributes for inspection. If the rich HTML renderer fails, the emergency path emits only escaped text from the semantic graph; it does not fall back to reparsing Markdown.

A closed allowlist retains internally generated HTML-only fragments when the typed graph cannot yet represent their complete geometry, including styled column and callout containers and printed form appearances. PDF text is still escaped, unsafe link schemes are dropped, PDF actions are never executed, and AcroForm extraction does not create a submit-capable browser form.

Markdown keeps its established lossless layout reconciliation path. Changes to HTML projection therefore cannot rewrite Markdown bytes.


Python API

from cocoapdf import ConvertOptions, convert_file

result = convert_file(
    "input.pdf",
    ConvertOptions(
        assets_dir="assets",
        image_mode="reference",
        image_markup="auto",
        page_breaks=False,
    ),
)

print(result.markdown)
print(result.html)

semantic_document = result.semantic
semantic_json = semantic_document.to_dict()
report = result.report

A single conversion result contains:

result.markdown
result.html
result.semantic
result.report
result.assets
result.warnings

Diagnostics and explainability

CocoaPDF is designed to make uncertain decisions visible.

# Write a detailed report and print explanations
cocoapdf input.pdf \
  --report report.json \
  --explain

# Surface semantic nodes below a confidence threshold
cocoapdf input.pdf \
  --show-low-confidence \
  --min-confidence 0.85

# Explain the reconstructed document
cocoapdf explain input.pdf

# Trace a page through the extraction pipeline
cocoapdf trace input.pdf --page 1

# Draw a page-region overlay
cocoapdf overlay input.pdf --page 1 -o overlay.svg

# Inspect PDF objects, resources, and interpreted content
cocoapdf inspect input.pdf

Additional diagnostic commands include:

cocoapdf diff expected.md actual.md
cocoapdf score v1
cocoapdf bench v1

Every accepted non-container semantic node is expected to carry at least one source reference containing a page number and, where available:

  • glyph IDs;
  • region IDs;
  • MCIDs;
  • PDF object references;
  • bounding boxes.

Graph-validation errors are reported rather than silently discarded.


Development and verification

Required verification gate

GitHub Actions enforces this gate on every pull request targeting main and again on every update to main. A merge cannot rely on the checklist alone: branch protection requires the Version policy, both endpoint-version Quality checks (Python 3.9 and 3.13), and all four native Binary checks to pass.

python -m pip install --disable-pip-version-check -e .
python scripts/check_repository_invariants.py
python -m unittest discover -s tests -v
python -m compileall -q src tests tools scripts
python -m cocoapdf --version

Unicode bidirectional verification

python tools/check_unicode_bidi.py /path/to/BidiCharacterTest.txt
python tools/check_unicode_bidi.py /path/to/BidiTest.txt

The checker exits with a non-zero status when it finds paragraph-level, resolved-level, or visual-order mismatches. It also records the Unicode database version used by the running Python interpreter.

Development method

CocoaPDF follows a generate–inspect–verify workflow:

  1. Create known Markdown, HTML, Typst, LaTeX, or office-document sources.
  2. Generate PDFs through materially different producer engines.
  3. Inspect objects, streams, operators, fonts, glyphs, graphics, tags, and layout.
  4. Convert each PDF through CocoaPDF.
  5. Compare normalized semantic output with locked expected output.
  6. Add adversarial near-miss fixtures before changing a detector.
  7. Run the complete regression and resource-limit suite after every correction.

The objective is not to optimize for one showcase PDF. Each change must improve general PDF behavior without silently damaging another producer dialect.

Semantic detector changes must include positive evidence, an adversarial near-miss, and provenance/confidence assertions where applicable. Producer- or fixture-specific shortcuts are not accepted.


Releases

CocoaPDF uses semantic version numbers in the form:

MAJOR.MINOR.PATCH

Every accepted update to main is versioned, tested, built natively, smoke-tested, and published automatically. The release class is selected as follows:

  • compatible fixes use release:patch, a fix: PR title, or a fix/, bugfix/, hotfix/, or patch/ branch and increment PATCH;
  • all other compatible changes use release:minor by default and increment MINOR while resetting PATCH to zero;
  • MAJOR can change only when the repository owner increments VERSION_MAJOR by exactly one and applies the breaking label; automation then publishes MAJOR.0.0.

Published releases include:

  • native Windows, Linux, and macOS packages;
  • per-binary provenance manifests;
  • RELEASE.json;
  • SHA256SUMS.txt;
  • source archives;
  • release notes.

Until platform signing and notarization are available, users should verify published checksums when binary provenance matters.


Project principles

  1. Semantic fidelity over visual text dumping.
  2. PDF-native evidence before heuristic inference.
  3. Geometry validates tags; tags inform geometry.
  4. Markdown when sufficient, HTML when necessary.
  5. One semantic graph for every output.
  6. No OCR or text guessing from images.
  7. No AI or machine-learning dependency.
  8. No fabricated Unicode or document structure.
  9. Low-confidence decisions remain inspectable.
  10. Deterministic output from identical inputs and options.

License

CocoaPDF is released under the MIT License.

The installable package declares no runtime dependencies: conversion uses only Python's standard library and CocoaPDF code. Optional standalone builds use a pinned PyInstaller release; its Bootloader Exception allows bundling without requiring CocoaPDF source to be relicensed. Distributions remain multi-license artifacts and carry their notices. Project attribution is available in NOTICE; incorporated data and standalone-runtime licenses are recorded in THIRD_PARTY_NOTICES.txt, and release archives carry the exact CPython and PyInstaller license texts verified by each native build.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cocoapdf-0.10.3.tar.gz (522.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cocoapdf-0.10.3-py3-none-any.whl (344.5 kB view details)

Uploaded Python 3

File details

Details for the file cocoapdf-0.10.3.tar.gz.

File metadata

  • Download URL: cocoapdf-0.10.3.tar.gz
  • Upload date:
  • Size: 522.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for cocoapdf-0.10.3.tar.gz
Algorithm Hash digest
SHA256 53eb2c1a3ff1e3a5d4f9d2a9476c2753a8bc37ee0f2585a58f4b189e27f3cb5a
MD5 31ada2e497aae45776baf1b716ee6212
BLAKE2b-256 34e2da0258a606ccafa6ed3f0ff586636d9960d214d3c3f7e5645f782cb1f7e1

See more details on using hashes here.

File details

Details for the file cocoapdf-0.10.3-py3-none-any.whl.

File metadata

  • Download URL: cocoapdf-0.10.3-py3-none-any.whl
  • Upload date:
  • Size: 344.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for cocoapdf-0.10.3-py3-none-any.whl
Algorithm Hash digest
SHA256 0fede6469828cc0de1966e77cf4357731b4ad86e63bc3e37e44730e35c26be3d
MD5 12ed3e8418d256b8502e2c0367d0e789
BLAKE2b-256 19ce6afe77373b8d4673ea4c7b4926f38e340051c44795ac383ecd22fce8ad76

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page