Skip to main content

Markdown Table Extractor

Python 3.11+ uv marimo License: MIT

Robust structured data extraction from markdown text, built with literate programming using marimo notebooks.

✨ Features

  • ✅ Proper separator detection - Handles :--:, ---:, :--- alignment syntax
  • ✅ Caption detection - Finds "Table 3. Results" patterns above tables
  • ✅ Continuation merging - Automatically merges "Table 3 (Continued)" tables
  • ✅ HTML cleanup - Removes <br> and other artifacts from headers
  • ✅ Sub-header handling - Merges multi-level headers properly
  • ✅ LLM extraction - AI-powered fallback for complex edge cases
  • ✅ Type-safe - Full type hints with py.typed marker
  • ✅ Literate programming - Each module is a marimo notebook

📚 Literate Programming with Marimo

Unlike traditional packages, every module is a marimo notebook:

src/markdown_table_extractor/core/
├── models.py      # 📓 Data classes notebook
├── parser.py      # 📓 Markdown parsing notebook  
├── cleaner.py     # 📓 Data cleaning notebook
├── merger.py      # 📓 Table merging notebook
└── extractor.py   # 📓 Main extraction notebook

Each file is simultaneously:

  • A Python module - Import normally: from markdown_table_extractor import extract_tables
  • A notebook - Edit interactively: marimo edit src/.../parser.py
  • Documentation - Read the code alongside explanations
  • A script - Run standalone: python src/.../parser.py

This follows the literate programming paradigm pioneered by Donald Knuth, similar to nbdev but with marimo's pure-Python notebooks.

Installation

# Using uv (recommended)
uv add markdown-table-extractor

# With LLM support (OpenAI/Anthropic)
uv add "markdown-table-extractor[llm]"

# Development with marimo
uv add "markdown-table-extractor[notebook]"

Quick Start

Simple Usage

from markdown_table_extractor import extract_tables

markdown = """
| Name | Age |
| --- | --- |
| Alice | 30 |
| Bob | 25 |
"""

tables = extract_tables(markdown)
print(tables[0])
#    Name  Age
# 0  Alice   30
# 1    Bob   25

Full API with Metadata

from markdown_table_extractor import extract_markdown_tables, TableMergeStrategy

result = extract_markdown_tables(
    markdown_text,
    merge_strategy=TableMergeStrategy.IDENTICAL_HEADERS,
    detect_captions=True,
    skip_sub_headers=True
)

for table in result:
    print(f"Caption: {table.caption}")
    print(f"Shape: {table.dataframe.shape}")
    print(table.dataframe)

Exploring the Notebooks

# Open any module as an interactive notebook
marimo edit src/markdown_table_extractor/core/parser.py

# Run the interactive demo
marimo edit src/markdown_table_extractor/core/extractor.py

API Reference

Core Functions

Function Description
extract_tables(text) Simple API returning list[DataFrame]
extract_markdown_tables(text, ...) Full API returning ExtractionResult

Models

Class Description
ExtractedTable Single table with metadata (caption, line numbers)
ExtractionResult Collection of tables with errors and merge count
TableMergeStrategy Enum: NONE, IDENTICAL_HEADERS, COMPATIBLE_COLUMNS

Utilities (from parser.py notebook)

Function Description
is_separator_row(line) Check if line is a table separator
is_table_row(line) Check if line is any table row
parse_table_row(line) Extract cell values from a row
detect_caption(lines, start) Find table caption

Utilities (from cleaner.py notebook)

Function Description
clean_column_name(name) Remove HTML artifacts from header
headers_match(h1, h2) Check if headers are compatible
normalize_headers(headers) Canonical form for comparison

Development

# Clone and setup
git clone https://github.com/username/markdown-table-extractor
cd markdown-table-extractor
uv sync --all-extras

# Run tests
uv run pytest

# Run linter
uv run ruff check src tests

# Type checking
uv run mypy src

# Edit any module interactively
uv run marimo edit src/markdown_table_extractor/core/parser.py

Project Structure

markdown-table-extractor/
├── pyproject.toml              # Package configuration
├── README.md
├── src/
│   └── markdown_table_extractor/
│       ├── __init__.py         # Public API
│       ├── py.typed            # Type hints marker
│       └── core/
│           ├── __init__.py     # Re-exports from notebooks
│           ├── models.py       # 📓 Data classes notebook
│           ├── parser.py       # 📓 Parsing utilities notebook
│           ├── cleaner.py      # 📓 Cleaning utilities notebook
│           ├── merger.py       # 📓 Merging logic notebook
│           └── extractor.py    # 📓 Main extraction notebook
└── tests/
    └── test_extractor.py

Why Marimo Notebooks?

Traditional Marimo Literate
Code in .py, docs separate Code + docs in same file
Read code, guess intent Read explanation alongside code
Tests in separate files Interactive tests in notebook
Static documentation Interactive documentation
Jupyter: JSON format Pure Python, Git-friendly

Why Not nbdev?

nbdev marimo
Jupyter notebooks (JSON) Pure Python files
Requires export step Direct import
`# export` directives
Complex build process Just Python

License

MIT License - see LICENSE for details.

Contributing

Contributions welcome! Edit the notebooks, add tests, and submit PRs.

Metadata

Release files for markdown-table-extractor 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for markdown-table-extractor 0.1.2
File Size Uploaded Provenance Actions
markdown_table_extractor-0.1.2.tar.gz 46.2 kB Without provenance Details for markdown_table_extractor-0.1.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for markdown-table-extractor 0.1.2
File Interpreter ABI Platform Actions
markdown_table_extractor-0.1.2-py3-none-any.whl Python 3 none any Details for markdown_table_extractor-0.1.2-py3-none-any.whl

Total release size: 101.9 kB

Release files / markdown_table_extractor-0.1.2.tar.gz

Download URL markdown_table_extractor-0.1.2.tar.gz
Size 46.2 kB
Tags Source
SHA-256 checksum
How to use checksums
19db4f1aa564d0191f8d4448993924830788a479546b86e261fb8bb54e79ee6e
BLAKE2b-256 checksum
How to use checksums
7801f15a169711fbe88227a6cd8b35fa97b81c6610e294498be978e412a3d484
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.0

Release files / markdown_table_extractor-0.1.2-py3-none-any.whl

Download URL markdown_table_extractor-0.1.2-py3-none-any.whl
Size 55.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ab45284af580c036e5b5b5624fd929dd653c5e09cd890cabe842b82bee0fea78
BLAKE2b-256 checksum
How to use checksums
5ae190a6cf6add3f92392dd18eb12cbe6650b3e07423e7d1d408e4454e15fe3e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.0

Security for markdown-table-extractor 0.1.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page