Metadata-Version: 2.5
Name: pdf2mscz
Version: 0.1.0
Summary: Convert sheet music (PDF/PNG/JPG) to editable MuseScore (.mscz) and MusicXML via modular OMR + VLM providers
Project-URL: Homepage, https://github.com/marianwolf/pdf2mscz
Project-URL: Issues, https://github.com/marianwolf/pdf2mscz/issues
Author: pdf2mscz contributors
License-Expression: AGPL-3.0-or-later
License-File: LICENSE
Keywords: musescore,musicxml,omr,sheet-music,vlm
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Multimedia :: Sound/Audio
Classifier: Topic :: Scientific/Engineering :: Image Recognition
Requires-Python: >=3.10
Requires-Dist: httpx>=0.25
Requires-Dist: lxml>=5.0
Requires-Dist: numpy>=1.24
Requires-Dist: opencv-python<5,>=4.8
Requires-Dist: pillow>=10.0
Requires-Dist: pydantic>=2.0
Requires-Dist: pypdfium2>=4.0
Requires-Dist: python-dotenv>=1.0
Requires-Dist: typer>=0.9
Provides-Extra: all
Requires-Dist: anthropic>=0.30; extra == 'all'
Requires-Dist: google-genai>=0.3; extra == 'all'
Requires-Dist: oemer>=0.0.9; extra == 'all'
Requires-Dist: openai>=1.0; extra == 'all'
Requires-Dist: opencv-python-headless<5,>=4.8; extra == 'all'
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.30; extra == 'anthropic'
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: mypy>=1.8; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.3; extra == 'dev'
Requires-Dist: twine>=5.1; extra == 'dev'
Provides-Extra: gemini
Requires-Dist: google-genai>=0.3; extra == 'gemini'
Provides-Extra: nvidia
Requires-Dist: openai>=1.0; extra == 'nvidia'
Provides-Extra: oemer
Requires-Dist: oemer>=0.0.9; extra == 'oemer'
Requires-Dist: opencv-python-headless<5,>=4.8; extra == 'oemer'
Provides-Extra: ollama
Provides-Extra: openai
Requires-Dist: openai>=1.0; extra == 'openai'
Description-Content-Type: text/markdown

# pdf2mscz

[![PyPI](https://img.shields.io/pypi/v/pdf2mscz.svg)](https://pypi.org/project/pdf2mscz/)
[![CI](https://github.com/marianwolf/pdf2mscz/actions/workflows/ci.yml/badge.svg)](https://github.com/marianwolf/pdf2mscz/actions/workflows/ci.yml)

Convert sheet-music scans (**PDF / PNG / JPG**) into editable **MuseScore (`.mscz`)** and **MusicXML** using a modular multi-provider pipeline: classical open-source OMR (`oemer`) + vision LLMs (OpenAI, Anthropic, Gemini, NVIDIA, Ollama).

## Architecture

```mermaid
flowchart LR
    IN[PDF/PNG/JPG] --> PRE[Preprocess: render, deskew, denoise]
    PRE --> P{Provider}
    P -->|openai/anthropic/gemini/nvidia/ollama| VLM[VLM → MusicXML]
    P -->|oemer| OMR[Classical OMR → MusicXML]
    OMR -->|optional --refine| VLM
    VLM --> SAN[XML Sanitizer]
    SAN --> XML[.musicxml]
    XML -->|MuseScore CLI| MSC[.mscz]
    XML -.fallback, no MuseScore.-> XML
```

## Install

```bash
# PyPI — core plus the provider extra(s) you use:
pip install "pdf2mscz[openai]"     # GPT-4o / OpenAI
pip install "pdf2mscz[anthropic]"  # Claude
pip install "pdf2mscz[gemini]"     # Google Gemini
pip install "pdf2mscz[nvidia]"     # NVIDIA NIM hosted VLMs
pip install "pdf2mscz[ollama]"     # local Ollama (no key needed)
pip install "pdf2mscz[oemer]"      # classical local OMR
pip install "pdf2mscz[all]"        # everything

# from source (development):
# python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev,all]"

cp .env.example .env  # add API keys
```

See [docs/setup.md](docs/setup.md) for MuseScore/Ollama details.

## Usage

```bash
# VLM transcription → .mscz (needs MuseScore CLI installed)
pdf2mscz convert scan.pdf score.mscz --provider openai --model gpt-4o

# Pages 1-3 only, with preprocessing
pdf2mscz convert scan.pdf score.mscz --provider anthropic --pages 1-3 --preprocess

# Classical local OMR, no API key
pdf2mscz convert scan.pdf score.musicxml --provider oemer --format musicxml

# Hybrid: oemer transcribed, GPT-4o refined
pdf2mscz convert scan.pdf score.mscz --provider oemer --refine openai

# Local VLM
pdf2mscz convert scan.pdf score.musicxml --provider ollama --model llava:13b --format musicxml

# NVIDIA NIM hosted VLM (free credits at build.nvidia.com)
pdf2mscz convert scan.pdf score.mscz --provider nvidia
pdf2mscz convert scan.pdf score.mscz --provider nvidia --model meta/llama-3.2-11b-vision-instruct

# Helpers
pdf2mscz providers
pdf2mscz check-deps
```

## Python API

```python
from pdf2mscz import ConversionOptions, convert

out = convert("scan.pdf", "score.mscz", ConversionOptions(provider="openai"))
print(out.musicxml_path, out.mscz_path)
```

## License

AGPL-3.0-or-later (see [License](LICENSE)).
