Metadata-Version: 2.4
Name: ttsready
Version: 0.2.3
Summary: A source-neutral API for preparing text for speech.
Author: Holger Nahrstaedt
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/buchwandler/ttsready
Project-URL: Repository, https://github.com/buchwandler/ttsready
Project-URL: Issues, https://github.com/buchwandler/ttsready/issues
Keywords: tts,text-to-speech,spokenform,speech-preparation,reproducibility
Classifier: Development Status :: 3 - Alpha
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
Classifier: Topic :: Text Processing :: General
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: spokenform<0.5,>=0.4.5
Requires-Dist: phrasplit<1,>=0.3.9
Provides-Extra: dev
Requires-Dist: build<2,>=1; extra == "dev"
Requires-Dist: setuptools>=80; extra == "dev"
Requires-Dist: setuptools-scm[toml]>=8; extra == "dev"
Requires-Dist: pytest<10,>=8; extra == "dev"
Requires-Dist: ruff<1,>=0.16; extra == "dev"
Requires-Dist: mypy>=1.11; extra == "dev"
Requires-Dist: twine<7,>=6; extra == "dev"
Requires-Dist: tomli>=2.0.1; python_version < "3.11" and extra == "dev"
Provides-Extra: lexical
Requires-Dist: lexhint<0.3.0,>=0.1.2; extra == "lexical"
Dynamic: license-file

# ttsready

`ttsready` is a source-neutral Python library for preparing caller-owned text for speech. `prepare_run()` is the low-level compiler-facing primitive for already analyzed runs; `prepare_text()` and `prepare_units()` provide review-oriented results with changes, issues, context, QA, statistics, and reproducibility fingerprints.

The library does **not** read or write files, parse SSMD or other formats, expose a CLI, generate audio, or own a document workflow. Callers adapt their source format to `TextUnit` values and decide what to do with the returned data.

## Install

Python 3.10 or newer is required.

```bash
python -m pip install ttsready
```

The runtime dependencies are `spokenform>=0.4.5,<0.5` and `phrasplit>=0.3.9,<1`. Install the optional lexical extra when you need its lexical-evidence integrations:

```bash
python -m pip install 'ttsready[lexical]'
```

## Release versioning

`setuptools-scm` derives TTSReady versions from Git tags and writes `ttsready/_version.py` during builds. Release tags use `vX.Y.Z`. A bare source tree without generated SCM metadata reports the neutral version `0+unknown`; release artifacts must derive their version from the tag.

## Quickstart

```python
from ttsready import prepare_text

prepared = prepare_text("A young reader opened a book.", language="en-US")
print(prepared.spoken_text)

for change in prepared.changes:
    print(change.source, "→", change.replacement, change.source_start, change.source_end)
```

`prepare_text()` prepares one unit and returns a `PreparedUnit`. Use `prepare_units()` when you have multiple caller-owned units, possibly with different languages, roles, protected spans, or metadata. See [docs/quickstart.md](docs/quickstart.md) and the runnable [API example](examples/basic_prepare.py).

## Lexical review

Use `review_lexicon()` to collect pronunciation-review candidates from caller-owned units. The provider is optional; for example, heuristic candidates can be collected without downloading or loading a dataset:

```python
from ttsready import TextUnit, review_lexicon

review = review_lexicon(
    (TextUnit("chapter-1", "We met Siobhan.", "en"),),
    include_all_tokens=True,
)
for finding in review.findings:
    print(finding.surface, finding.reasons)
```

Install `ttsready[lexical]` to use the optional Lexhint integration with an explicitly constructed provider. See the [lexical review guide](docs/lexical-review.md) for findings, offsets, filters, and provider behavior.

### Compiler-facing run API

Pipelines that already own token and sentence analysis can use `prepare_run()` directly:

```python
from ttsready import LinguisticToken, prepare_run

source = "Dr. Smith recorded 2 kg."
run = prepare_run(
    source,
    language="en-US",
    linguistic_tokens=(LinguisticToken(0, 3, text="Dr.", pos="PROPN"),),
    preserve_run_boundaries=True,
)
print(run.spoken_text)
print(run.source_map.map_source_span(0, 3))
```

Hints are provider-neutral and source-relative to the supplied run; TTSReady never accepts a spaCy/provider object. `PreparedRun` has no overrides or sentence context. `SourceOutputMap` preserves exact forward/reverse boundary bias and can be concatenated across runs. See [Python API](docs/python-api.md) for detailed semantics and the distinction from `prepare_text()`/`prepare_units()`.

## Core contract

- `prepare_run()` accepts plain text, explicit language, protected spans, and source-relative `LinguisticToken` hints without requiring an NLP provider object.
- `prepare_text()` and `prepare_units()` accept immutable `TextUnit` records; `SpeechOverride` values express global, unit-scoped, or exact-occurrence pronunciation policy.
- `PreparedRun` returns exact `SourceOutputMap` boundary mappings; review-oriented results add context, QA, fingerprints, and aggregate statistics.
- Existing result JSON serialization and fingerprints are pure; run maps are in-memory/diagnostic values and persistence remains the caller's responsibility.
- `TextUnit` may carry validated provider-neutral linguistic-token hints; `prepare_units()` and `prepare_text()` forward them without provider loading. Bulk preparation optionally emits synchronous observation-only progress events and remains silent itself.

- `review_lexicon()` exposes provider-neutral lexical review; use [the lexical review guide](docs/lexical-review.md) for candidate reasons, filtering, and optional caller-owned evidence providers.
- `split_prepared_text()` chunks supplied text at sentence-aware boundaries while preserving exact source slices; see [Python API](docs/python-api.md).

```python
from ttsready import TextUnit, prepare_units

result = prepare_units(
    (
        TextUnit("chapter-1", "2 kg", "en-US", role="body"),
        TextUnit("caption-1", "Bonjour.", "fr-FR", role="caption"),
    )
)

for unit in result.units:
    print(unit.unit_id, unit.spoken_text)
```

## Documentation

- [Installation](docs/installation.md)
- [Quickstart](docs/quickstart.md)
- [Python API](docs/python-api.md)
- [Lexical review](docs/lexical-review.md)
- [Overrides](docs/overrides.md)
- [Residual QA](docs/qa.md)
- [Reproducibility and serialization](docs/reproducibility.md)
- [Ownership boundary](docs/ownership-boundary.md)
- [Migration from 0.1.x](docs/migration.md)

## Migrating from 0.1.x

Version 0.2 introduced a breaking, API-only boundary. SSMD/document APIs, the CLI, file and cache I/O, writers, planning, speaker/JEV workflows, and their application-owned models were removed. Convert or read source data in your application, pass text units to `prepare_text()` or `prepare_units()`, then persist or render results in your application. See the [migration guide](docs/migration.md).

## License

`ttsready` is licensed under the Apache License 2.0. See [LICENSE](LICENSE) for the full text.
