Metadata-Version: 2.4
Name: chordsketch
Version: 0.3.0
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Programming Language :: Rust
Classifier: Topic :: Multimedia :: Sound/Audio
Classifier: Topic :: Text Processing :: Markup
Summary: ChordPro file format parser and renderer
Keywords: chordpro,music,chord,parser,lyrics,rust,uniffi
Home-Page: https://github.com/koedame/chordsketch
Author: koedame
License: MIT
Requires-Python: >=3.8
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Homepage, https://github.com/koedame/chordsketch
Project-URL: Issues, https://github.com/koedame/chordsketch/issues
Project-URL: Repository, https://github.com/koedame/chordsketch

  ChordSketch

# chordsketch

[ChordSketch](https://github.com/koedame/chordsketch) Python bindings —
parse and render [ChordPro](https://www.chordpro.org/) files from Python via
native Rust extensions generated by [UniFFI](https://mozilla.github.io/uniffi-rs/).

**Native extension — no pure-Python fallback.**
The library compiles to a platform wheel; prebuilt wheels for common platforms
are published to PyPI so no Rust toolchain is needed to install.

## Installation

```bash
pip install chordsketch
```

Requires Python 3.8+ (CPython or PyPy).

## Quick Start

```python
import chordsketch

source = """{title: Amazing Grace}
{key: G}

[G]Amazing [G7]grace, how [C]sweet the [G]sound"""

html = chordsketch.parse_and_render_html(source)
text = chordsketch.parse_and_render_text(source)
pdf  = chordsketch.parse_and_render_pdf(source)   # bytes

print(chordsketch.version())
```

## API

### Rendering

All render functions accept the same three arguments:

| Parameter | Type | Description |
|-----------|------|-------------|
| `input` | `str` | ChordPro source text |
| `config_json` | `str \| None` | Preset name (`"guitar"`, `"ukulele"`) or inline RRJSON; `None` for defaults |
| `transpose` | `int \| None` | Semitone offset (-128..127); `None` defaults to 0 |

| Function | Returns | Description |
|----------|---------|-------------|
| `parse_and_render_text(input, config_json, transpose)` | `str` | Plain text output |
| `parse_and_render_html(input, config_json, transpose)` | `str` | Full HTML document |
| `parse_and_render_pdf(input, config_json, transpose)` | `bytes` | Raw PDF bytes |
| `parse_and_render_text_with_warnings(input, config_json, transpose)` | `TextRenderWithWarnings { output: str, warnings: list[str] }` | Plain text + captured warnings |
| `parse_and_render_html_with_warnings(input, config_json, transpose)` | `TextRenderWithWarnings { output: str, warnings: list[str] }` | HTML + captured warnings |
| `parse_and_render_pdf_with_warnings(input, config_json, transpose)` | `PdfRenderWithWarnings { output: bytes, warnings: list[str] }` | PDF + captured warnings |

The `*_with_warnings` variants return the render warnings (transpose
saturation, chorus recall limits, `{columns}` clamp, etc.) as a list
alongside the output instead of forwarding them to `sys.stderr` /
`NSLog` / `System.err` / `$stderr`. Use them when embedding ChordSketch
in an app that needs to surface warnings in the UI or aggregate them.
See #1827.

### Validation

```python
errors = chordsketch.validate(source)  # list[ValidationError] — empty if clean
for e in errors:
    print(f"line {e.line}, column {e.column}: {e.message}")
```

### Utility

```python
print(chordsketch.version())  # e.g. "0.2.0"
```

## Options

```python
# Transpose up 2 semitones with the ukulele preset
html = chordsketch.parse_and_render_html(source, "ukulele", 2)

# Inline RRJSON configuration
html = chordsketch.parse_and_render_html(
    source,
    '{"settings": {"notation": "solfege"}}',
    None,
)
```

## Error handling

Functions raise `chordsketch.ChordSketchError` on invalid configuration:

```python
try:
    html = chordsketch.parse_and_render_html(source, "{ bad json !!!", None)
except chordsketch.ChordSketchError as e:
    print(e)
```

`ChordSketchError` has two variants:
- `NoSongsFound` — the input produced no parseable songs (rare with lenient parsing)
- `InvalidConfig` — the `config_json` argument is not a known preset and not valid RRJSON

Parse errors in the ChordPro input are **not** raised — the renderer is lenient
and produces a best-effort result. Call `validate()` to surface diagnostics.

## Links

- **Project**: https://github.com/koedame/chordsketch
- **Playground**: https://chordsketch.koeda.me
- **Issues**: https://github.com/koedame/chordsketch/issues

## License

MIT

