A tool that auto-detects Excel, Word, PowerPoint, PDF, Ichitaro, and image files and converts them to roughly adequate Markdown.
This tool was built using Devin.
For production-grade conversion, consider markitdown or docling.
For a feature comparison with docling and markitdown, see o2md_comparison.md.
Japanese documentation (README_JP.md)
o2md is a Python tool that converts Microsoft Office documents (Excel, Word, PowerPoint, MS Project), PDFs, Ichitaro documents (.jtd/.jtt/.jsw/.jaw/.jtw/.jbw/.juw/.jfw/.jvw), and image files (JPEG/PNG/GIF/BMP/TIFF/WebP) to roughly adequate Markdown. It auto-detects file types and selects the appropriate conversion engine. o2md does not use trendy machine learning-based conversion; instead, it performs good old-fashioned logic-based conversion. Image files and image-based PDFs (scanned documents, etc.) are processed with OCR (Tesseract/manga-ocr/sarashina2.2-ocr) for text extraction. Legacy formats (.xls, .doc, .ppt) and shape/image rendering depend on LibreOffice. Text-only conversion works without LibreOffice.
.xlsx/.xls, .docx/.doc, .pptx/.pptx2md): Convert worksheets including tables, charts, and shapesd2md): Convert documents with headings, tables, images, and listsp2md): Convert slides with shapes, tables, and textpdf2md): Convert PDFs with text extraction and OCR (Tesseract/manga-ocr/sarashina2.2-ocr)jtd2md): Parse OLE2 binary format (ver8+) and legacy binary format (ver4-7) to extract text, tables, and bold textmpp2md): Convert project files (.mpp/.mpt/.mpx) to Markdown tables with tasks, schedules, progress, and resource assignments. Uses mpxj via JPype (requires JDK 11+, optional dependency: pip install o2md[mpp])img2md): Extract text from images via OCR and convert to Markdown (Tesseract/manga-ocr/sarashina)o2md-filter): Convert documents to plain text for search engine indexing (stdin support with auto file type detection)sarashina2.2-ocr is amazing. Highly recommended if you have a GPU!
# Basic install
pip install o2md
# With manga-ocr
pip install o2md[manga-ocr]
# With sarashina2.2-ocr
pip install o2md[sarashina]
# With docling (AI table detection)
pip install o2md[docling]
# With MS Project support (requires JDK 11+)
pip install o2md[mpp]
# All optional dependencies
pip install o2md[manga-ocr,sarashina,docling,mpp]
Using uv:
# Basic install
uv pip install o2md
# With manga-ocr
uv pip install o2md[manga-ocr]
# With sarashina2.2-ocr
uv pip install o2md[sarashina]
# With MS Project support (requires JDK 11+)
uv pip install o2md[mpp]
# All optional dependencies
uv pip install o2md[manga-ocr,sarashina,docling,mpp]
# Install uv (if not installed)
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# Clone the repository
git clone https://github.com/matsu582/o2md.git
cd o2md
# Install dependencies
uv sync
# Include manga-ocr
uv sync --extra manga-ocr
# Include sarashina2.2-ocr
uv sync --extra sarashina
# Include docling (AI table detection)
uv sync --extra docling
# Include MS Project support (requires JDK 11+)
uv sync --extra mpp
# Include all optional dependencies
uv sync --all-extras
Used by default for OCR text extraction from PDFs and images. Without Tesseract, OCR is unavailable (manga-ocr or sarashina2.2-ocr can be used as alternatives).
# macOS
brew install tesseract tesseract-lang
# Ubuntu/Debian
sudo apt-get install tesseract-ocr tesseract-ocr-jpn tesseract-ocr-eng
# Windows
# Download from https://github.com/UB-Mannheim/tesseract/wiki
Required for legacy format (.xls, .doc, .ppt) conversion and shape/image rendering. Text-only conversion works without LibreOffice.
# macOS
brew install libreoffice
# Ubuntu/Debian
sudo apt-get install libreoffice
# Windows
# Download from https://www.libreoffice.org/download/download/
Without LibreOffice, a warning is displayed at startup and the following degraded behavior applies:
| Feature | With LibreOffice | Without LibreOffice |
|---|---|---|
| .docx / .xlsx / .pptx text conversion | OK | OK |
| .doc / .xls / .ppt conversion | OK | Error |
| Shape/vector image conversion | OK | Skipped |
| Slide image rendering | OK | Skipped |
| Chart image conversion | OK | Skipped |
Tip: Legacy files (.doc, .xls, .ppt) can be pre-converted to newer formats (.docx, .xlsx, .pptx) for text conversion without LibreOffice.
After installing from PyPI:
# Convert Excel file
o2md data.xlsx
# Convert Word file
o2md document.docx
# Convert PowerPoint file
o2md presentation.pptx
# Convert PDF file
o2md document.pdf
# Convert Ichitaro file
o2md document.jtd
# Convert MS Project file
o2md project.mpp
# Convert image file (OCR text extraction)
o2md photo.jpg
When running from a local clone (development):
uv run o2md input_files/data.xlsx
uv run o2md input_files/document.docx
uv run o2md input_files/presentation.pptx
uv run o2md input_files/document.pdf
uv run o2md input_files/document.jtd
uv run o2md input_files/photo.jpg
uv run o2md input_files/project.mpp
Each conversion engine can also be used as a standalone command:
# PyPI install
d2md document.docx
x2md data.xlsx
p2md presentation.pptx
pdf2md document.pdf
jtd2md document.jtd
img2md photo.jpg
mpp2md project.mpp
# Local clone
uv run d2md input_files/document.docx
uv run x2md input_files/data.xlsx
uv run p2md input_files/presentation.pptx
uv run pdf2md input_files/document.pdf
uv run jtd2md input_files/document.jtd
uv run img2md input_files/photo.jpg
uv run mpp2md input_files/project.mpp
o2md-filter)Converts documents to plain text and outputs to stdout.
# File path input
o2md-filter document.xlsx
o2md-filter report.pdf
o2md-filter manual.docx
# stdin input (auto file type detection via magic bytes)
cat document.xlsx | o2md-filter
cat report.pdf | o2md-filter
# Specify OCR engine
o2md-filter scanned.pdf --ocr-engine manga-ocr
o2md-filter image.jpg --ocr-engine sarashina
# Search engine integration example
find /docs -name "*.xlsx" -o -name "*.pdf" | while read f; do
o2md-filter "$f" | index-tool --source "$f"
done
| Option | Description |
|---|---|
file | File to convert (omit to read from stdin) |
--ocr-engine | OCR engine (tesseract/manga-ocr/sarashina, default: tesseract) |
# Specify output directory
o2md data.xlsx -o custom_output
# Use heading text for links in Word documents
o2md document.docx --use-heading-text
# Output images in PNG format (default: SVG)
o2md data.xlsx --format png
# Specify OCR engine for PDF/image conversion (default: tesseract)
o2md document.pdf --ocr-engine tesseract
o2md document.pdf --ocr-engine manga-ocr
o2md document.pdf --ocr-engine sarashina
# Use tessdata_best for high-accuracy OCR
o2md document.pdf --tessdata-dir ~/tessdata_best
# Text extraction mode (output .txt only)
o2md data.xlsx --text
o2md document.docx --text
o2md presentation.pptx --text
o2md document.pdf --text
o2md photo.jpg --text
Note: When running from a local clone, prefix commands with
uv run(e.g.,uv run o2md data.xlsx).
# Convert all supported files in a folder (top-level only)
o2md ./input_files/
# Recursively process subfolders
o2md ./input_files/ -r
# Specify output directory
o2md ./input_files/ -r -o output_all
Output structure for folder input:
input_files/
pdfs/a.pdf
b.xlsx
->
output/
pdfs/a.md + images/
b.md
# Legacy formats are automatically converted to newer formats before processing
o2md old_file.xls
o2md old_doc.doc
o2md old_presentation.ppt
| Option | Description |
|---|---|
file | Office file or folder to convert (required) |
-o, --output-dir | Output directory (default: ./output) |
-r, --recursive | [Folder mode] Recursively process subfolders |
--format | Image output format (svg or png, default: svg) |
--use-heading-text | [Word only] Use heading text instead of chapter numbers for links |
--shape-metadata | [Word/Excel only] Output shape metadata |
--ocr-engine | [PDF/Image] OCR engine (tesseract/manga-ocr/sarashina, default: tesseract) |
--tessdata-dir | [PDF only] Specify tessdata directory (for tessdata_best) |
--docling | [PDF only] Enable docling table detection (detects borderless tables) |
--text | Text extraction mode (output .txt only) |
-v, --verbose | Show detailed debug output |
-h, --help | Show help message |
| File Type | Extensions | Command | Key Features |
|---|---|---|---|
| Excel | .xlsx, .xls | x2md | Tables, charts, shapes, formulas |
| Word | .docx, .doc | d2md | Headings, tables, images, lists |
| PowerPoint | .pptx, .ppt | p2md | Slides, shapes, tables, text |
.pdf | pdf2md | Image conversion, text extraction, OCR | |
| Ichitaro | .jtd, .jtt, .jsw, .jaw, .jtw, .jbw, .juw, .jfw, .jvw | jtd2md | Text, tables, bold, headings |
| MS Project | .mpp, .mpt, .mpx, .xml (MSPDI) | mpp2md | Tasks, schedules, progress, resources |
| Image | .jpg, .jpeg, .png, .gif, .bmp, .tiff, .tif, .webp | img2md | OCR text extraction, image embedding |
After conversion, the following files are generated:
output/
+-- [filename].md # Markdown file
+-- images/ # Image folder
+-- [filename]_image_001.svg # SVG by default
+-- [filename]_image_002.svg
+-- ...
SVG is a vector format that maintains quality at any zoom level. Use --format png if PNG is needed.
x2md)d2md)#, ##, ###, etc.)p2md)Slides are rendered as full images when they contain mixed elements:
Visual decoration criteria:
This ensures callouts, colored rectangles, and other decorative elements are properly rendered as images.
jtd2md)##)**bold**)mpp2md)pip install o2md[mpp]CLASSPATH is set, user-provided JARs are preferred over automatic downloadsmpp2md command directlyo2md and o2md-filter commandsimg2md)--text option support (output .txt only)pdf2md)--tessdata-dir--docling option detects borderless tables
<details> tagsx2md)d2md)p2md)pdf2md)--tessdata-dir option)pip install o2md[docling] or uv sync --extra doclingpip install o2md[manga-ocr] or uv sync --extra manga-ocrpip install o2md[sarashina] or uv sync --extra sarashinajtd2md)mpp2md)pip install o2md[mpp]CLASSPATH is set, the user-provided JARs take precedenceimg2md)pip install o2md[manga-ocr] or uv sync --extra manga-ocrpip install o2md[sarashina] or uv sync --extra sarashina (GPU recommended)o2md/
+-- pyproject.toml # Project configuration and dependencies
+-- o2md/ # Main package
| +-- __init__.py
| +-- o2md.py # Unified CLI (auto file detection and conversion)
| +-- x2md.py # Excel conversion engine
| +-- d2md.py # Word conversion engine
| +-- p2md.py # PowerPoint conversion engine
| +-- pdf2md.py # PDF conversion engine
| +-- jtd2md.py # Ichitaro conversion engine
| +-- jtd2md_legacy.py # Ichitaro legacy (ver4-7) conversion engine
| +-- mpp2md.py # MS Project conversion engine
| +-- jar_manager.py # MPXJ JAR auto-download manager
| +-- img2md.py # Image OCR conversion engine
| +-- filter.py # Plain text filter for search engines
| +-- utils.py # Shared utilities
| +-- omml_converter/ # OMML to LaTeX conversion
+-- tests/ # Test suite
+-- input_files/ # Test input files
Python
99.9%
A tool that auto-detects Excel, Word, PowerPoint, PDF, Ichitaro, and image files and converts them to roughly adequate Markdown.
This tool was built using Devin.
For production-grade conversion, consider markitdown or docling.
For a feature comparison with docling and markitdown, see o2md_comparison.md.
Japanese documentation (README_JP.md)
o2md is a Python tool that converts Microsoft Office documents (Excel, Word, PowerPoint, MS Project), PDFs, Ichitaro documents (.jtd/.jtt/.jsw/.jaw/.jtw/.jbw/.juw/.jfw/.jvw), and image files (JPEG/PNG/GIF/BMP/TIFF/WebP) to roughly adequate Markdown. It auto-detects file types and selects the appropriate conversion engine. o2md does not use trendy machine learning-based conversion; instead, it performs good old-fashioned logic-based conversion. Image files and image-based PDFs (scanned documents, etc.) are processed with OCR (Tesseract/manga-ocr/sarashina2.2-ocr) for text extraction. Legacy formats (.xls, .doc, .ppt) and shape/image rendering depend on LibreOffice. Text-only conversion works without LibreOffice.
.xlsx/.xls, .docx/.doc, .pptx/.pptx2md): Convert worksheets including tables, charts, and shapesd2md): Convert documents with headings, tables, images, and listsp2md): Convert slides with shapes, tables, and textpdf2md): Convert PDFs with text extraction and OCR (Tesseract/manga-ocr/sarashina2.2-ocr)jtd2md): Parse OLE2 binary format (ver8+) and legacy binary format (ver4-7) to extract text, tables, and bold textmpp2md): Convert project files (.mpp/.mpt/.mpx) to Markdown tables with tasks, schedules, progress, and resource assignments. Uses mpxj via JPype (requires JDK 11+, optional dependency: pip install o2md[mpp])img2md): Extract text from images via OCR and convert to Markdown (Tesseract/manga-ocr/sarashina)o2md-filter): Convert documents to plain text for search engine indexing (stdin support with auto file type detection)sarashina2.2-ocr is amazing. Highly recommended if you have a GPU!
# Basic install
pip install o2md
# With manga-ocr
pip install o2md[manga-ocr]
# With sarashina2.2-ocr
pip install o2md[sarashina]
# With docling (AI table detection)
pip install o2md[docling]
# With MS Project support (requires JDK 11+)
pip install o2md[mpp]
# All optional dependencies
pip install o2md[manga-ocr,sarashina,docling,mpp]
Using uv:
# Basic install
uv pip install o2md
# With manga-ocr
uv pip install o2md[manga-ocr]
# With sarashina2.2-ocr
uv pip install o2md[sarashina]
# With MS Project support (requires JDK 11+)
uv pip install o2md[mpp]
# All optional dependencies
uv pip install o2md[manga-ocr,sarashina,docling,mpp]
# Install uv (if not installed)
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# Clone the repository
git clone https://github.com/matsu582/o2md.git
cd o2md
# Install dependencies
uv sync
# Include manga-ocr
uv sync --extra manga-ocr
# Include sarashina2.2-ocr
uv sync --extra sarashina
# Include docling (AI table detection)
uv sync --extra docling
# Include MS Project support (requires JDK 11+)
uv sync --extra mpp
# Include all optional dependencies
uv sync --all-extras
Used by default for OCR text extraction from PDFs and images. Without Tesseract, OCR is unavailable (manga-ocr or sarashina2.2-ocr can be used as alternatives).
# macOS
brew install tesseract tesseract-lang
# Ubuntu/Debian
sudo apt-get install tesseract-ocr tesseract-ocr-jpn tesseract-ocr-eng
# Windows
# Download from https://github.com/UB-Mannheim/tesseract/wiki
Required for legacy format (.xls, .doc, .ppt) conversion and shape/image rendering. Text-only conversion works without LibreOffice.
# macOS
brew install libreoffice
# Ubuntu/Debian
sudo apt-get install libreoffice
# Windows
# Download from https://www.libreoffice.org/download/download/
Without LibreOffice, a warning is displayed at startup and the following degraded behavior applies:
| Feature | With LibreOffice | Without LibreOffice |
|---|---|---|
| .docx / .xlsx / .pptx text conversion | OK | OK |
| .doc / .xls / .ppt conversion | OK | Error |
| Shape/vector image conversion | OK | Skipped |
| Slide image rendering | OK | Skipped |
| Chart image conversion | OK | Skipped |
Tip: Legacy files (.doc, .xls, .ppt) can be pre-converted to newer formats (.docx, .xlsx, .pptx) for text conversion without LibreOffice.
After installing from PyPI:
# Convert Excel file
o2md data.xlsx
# Convert Word file
o2md document.docx
# Convert PowerPoint file
o2md presentation.pptx
# Convert PDF file
o2md document.pdf
# Convert Ichitaro file
o2md document.jtd
# Convert MS Project file
o2md project.mpp
# Convert image file (OCR text extraction)
o2md photo.jpg
When running from a local clone (development):
uv run o2md input_files/data.xlsx
uv run o2md input_files/document.docx
uv run o2md input_files/presentation.pptx
uv run o2md input_files/document.pdf
uv run o2md input_files/document.jtd
uv run o2md input_files/photo.jpg
uv run o2md input_files/project.mpp
Each conversion engine can also be used as a standalone command:
# PyPI install
d2md document.docx
x2md data.xlsx
p2md presentation.pptx
pdf2md document.pdf
jtd2md document.jtd
img2md photo.jpg
mpp2md project.mpp
# Local clone
uv run d2md input_files/document.docx
uv run x2md input_files/data.xlsx
uv run p2md input_files/presentation.pptx
uv run pdf2md input_files/document.pdf
uv run jtd2md input_files/document.jtd
uv run img2md input_files/photo.jpg
uv run mpp2md input_files/project.mpp
o2md-filter)Converts documents to plain text and outputs to stdout.
# File path input
o2md-filter document.xlsx
o2md-filter report.pdf
o2md-filter manual.docx
# stdin input (auto file type detection via magic bytes)
cat document.xlsx | o2md-filter
cat report.pdf | o2md-filter
# Specify OCR engine
o2md-filter scanned.pdf --ocr-engine manga-ocr
o2md-filter image.jpg --ocr-engine sarashina
# Search engine integration example
find /docs -name "*.xlsx" -o -name "*.pdf" | while read f; do
o2md-filter "$f" | index-tool --source "$f"
done
| Option | Description |
|---|---|
file | File to convert (omit to read from stdin) |
--ocr-engine | OCR engine (tesseract/manga-ocr/sarashina, default: tesseract) |
# Specify output directory
o2md data.xlsx -o custom_output
# Use heading text for links in Word documents
o2md document.docx --use-heading-text
# Output images in PNG format (default: SVG)
o2md data.xlsx --format png
# Specify OCR engine for PDF/image conversion (default: tesseract)
o2md document.pdf --ocr-engine tesseract
o2md document.pdf --ocr-engine manga-ocr
o2md document.pdf --ocr-engine sarashina
# Use tessdata_best for high-accuracy OCR
o2md document.pdf --tessdata-dir ~/tessdata_best
# Text extraction mode (output .txt only)
o2md data.xlsx --text
o2md document.docx --text
o2md presentation.pptx --text
o2md document.pdf --text
o2md photo.jpg --text
Note: When running from a local clone, prefix commands with
uv run(e.g.,uv run o2md data.xlsx).
# Convert all supported files in a folder (top-level only)
o2md ./input_files/
# Recursively process subfolders
o2md ./input_files/ -r
# Specify output directory
o2md ./input_files/ -r -o output_all
Output structure for folder input:
input_files/
pdfs/a.pdf
b.xlsx
->
output/
pdfs/a.md + images/
b.md
# Legacy formats are automatically converted to newer formats before processing
o2md old_file.xls
o2md old_doc.doc
o2md old_presentation.ppt
| Option | Description |
|---|---|
file | Office file or folder to convert (required) |
-o, --output-dir | Output directory (default: ./output) |
-r, --recursive | [Folder mode] Recursively process subfolders |
--format | Image output format (svg or png, default: svg) |
--use-heading-text | [Word only] Use heading text instead of chapter numbers for links |
--shape-metadata | [Word/Excel only] Output shape metadata |
--ocr-engine | [PDF/Image] OCR engine (tesseract/manga-ocr/sarashina, default: tesseract) |
--tessdata-dir | [PDF only] Specify tessdata directory (for tessdata_best) |
--docling | [PDF only] Enable docling table detection (detects borderless tables) |
--text | Text extraction mode (output .txt only) |
-v, --verbose | Show detailed debug output |
-h, --help | Show help message |
| File Type | Extensions | Command | Key Features |
|---|---|---|---|
| Excel | .xlsx, .xls | x2md | Tables, charts, shapes, formulas |
| Word | .docx, .doc | d2md | Headings, tables, images, lists |
| PowerPoint | .pptx, .ppt | p2md | Slides, shapes, tables, text |
.pdf | pdf2md | Image conversion, text extraction, OCR | |
| Ichitaro | .jtd, .jtt, .jsw, .jaw, .jtw, .jbw, .juw, .jfw, .jvw | jtd2md | Text, tables, bold, headings |
| MS Project | .mpp, .mpt, .mpx, .xml (MSPDI) | mpp2md | Tasks, schedules, progress, resources |
| Image | .jpg, .jpeg, .png, .gif, .bmp, .tiff, .tif, .webp | img2md | OCR text extraction, image embedding |
After conversion, the following files are generated:
output/
+-- [filename].md # Markdown file
+-- images/ # Image folder
+-- [filename]_image_001.svg # SVG by default
+-- [filename]_image_002.svg
+-- ...
SVG is a vector format that maintains quality at any zoom level. Use --format png if PNG is needed.
x2md)d2md)#, ##, ###, etc.)p2md)Slides are rendered as full images when they contain mixed elements:
Visual decoration criteria:
This ensures callouts, colored rectangles, and other decorative elements are properly rendered as images.
jtd2md)##)**bold**)mpp2md)pip install o2md[mpp]CLASSPATH is set, user-provided JARs are preferred over automatic downloadsmpp2md command directlyo2md and o2md-filter commandsimg2md)--text option support (output .txt only)pdf2md)--tessdata-dir--docling option detects borderless tables
<details> tagsx2md)d2md)p2md)pdf2md)--tessdata-dir option)pip install o2md[docling] or uv sync --extra doclingpip install o2md[manga-ocr] or uv sync --extra manga-ocrpip install o2md[sarashina] or uv sync --extra sarashinajtd2md)mpp2md)pip install o2md[mpp]CLASSPATH is set, the user-provided JARs take precedenceimg2md)pip install o2md[manga-ocr] or uv sync --extra manga-ocrpip install o2md[sarashina] or uv sync --extra sarashina (GPU recommended)o2md/
+-- pyproject.toml # Project configuration and dependencies
+-- o2md/ # Main package
| +-- __init__.py
| +-- o2md.py # Unified CLI (auto file detection and conversion)
| +-- x2md.py # Excel conversion engine
| +-- d2md.py # Word conversion engine
| +-- p2md.py # PowerPoint conversion engine
| +-- pdf2md.py # PDF conversion engine
| +-- jtd2md.py # Ichitaro conversion engine
| +-- jtd2md_legacy.py # Ichitaro legacy (ver4-7) conversion engine
| +-- mpp2md.py # MS Project conversion engine
| +-- jar_manager.py # MPXJ JAR auto-download manager
| +-- img2md.py # Image OCR conversion engine
| +-- filter.py # Plain text filter for search engines
| +-- utils.py # Shared utilities
| +-- omml_converter/ # OMML to LaTeX conversion
+-- tests/ # Test suite
+-- input_files/ # Test input files
Python
99.9%