Metadata-Version: 2.4
Name: normalizer-tr
Version: 0.4.0
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python :: 3
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: Programming Language :: Rust
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS
Classifier: Topic :: Text Processing
Classifier: Typing :: Typed
License-File: LICENSE-PROJECT
License-File: THIRD_PARTY_NOTICES-PROJECT.md
License-File: licenses/aho-corasick-1.1.5/COPYING
License-File: licenses/aho-corasick-1.1.5/LICENSE-MIT
License-File: licenses/heck-0.5.0/LICENSE-APACHE
License-File: licenses/heck-0.5.0/LICENSE-MIT
License-File: licenses/libc-0.2.189/LICENSE-APACHE
License-File: licenses/libc-0.2.189/LICENSE-MIT
License-File: licenses/memchr-2.8.3/COPYING
License-File: licenses/memchr-2.8.3/LICENSE-MIT
License-File: licenses/portable-atomic-1.15.0/LICENSE-APACHE
License-File: licenses/portable-atomic-1.15.0/LICENSE-MIT
License-File: licenses/proc-macro2-1.0.107/LICENSE-APACHE
License-File: licenses/proc-macro2-1.0.107/LICENSE-MIT
License-File: licenses/pyo3-0.29.3/LICENSE-APACHE
License-File: licenses/pyo3-0.29.3/LICENSE-MIT
License-File: licenses/pyo3-build-config-0.29.3/LICENSE-APACHE
License-File: licenses/pyo3-build-config-0.29.3/LICENSE-MIT
License-File: licenses/pyo3-ffi-0.29.3/LICENSE-APACHE
License-File: licenses/pyo3-ffi-0.29.3/LICENSE-MIT
License-File: licenses/pyo3-macros-0.29.3/LICENSE-APACHE
License-File: licenses/pyo3-macros-0.29.3/LICENSE-MIT
License-File: licenses/pyo3-macros-backend-0.29.3/LICENSE-APACHE
License-File: licenses/pyo3-macros-backend-0.29.3/LICENSE-MIT
License-File: licenses/quote-1.0.47/LICENSE-APACHE
License-File: licenses/quote-1.0.47/LICENSE-MIT
License-File: licenses/regex-1.13.1/LICENSE-APACHE
License-File: licenses/regex-1.13.1/LICENSE-MIT
License-File: licenses/regex-automata-0.4.18/LICENSE-APACHE
License-File: licenses/regex-automata-0.4.18/LICENSE-MIT
License-File: licenses/regex-syntax-0.8.11/LICENSE-APACHE
License-File: licenses/regex-syntax-0.8.11/LICENSE-MIT
License-File: licenses/rust-std-1.99.0/COPYRIGHT-library.html
License-File: licenses/rust-std-1.99.0/LICENSE-APACHE
License-File: licenses/rust-std-1.99.0/LICENSE-MIT
License-File: licenses/syn-2.0.119/LICENSE-APACHE
License-File: licenses/syn-2.0.119/LICENSE-MIT
License-File: licenses/syn-3.0.6/LICENSE-APACHE
License-File: licenses/syn-3.0.6/LICENSE-MIT
License-File: licenses/target-lexicon-0.13.5/LICENSE
License-File: licenses/tinyvec-1.13.3/LICENSE-APACHE.md
License-File: licenses/tinyvec-1.13.3/LICENSE-MIT.md
License-File: licenses/tinyvec-1.13.3/LICENSE-ZLIB.md
License-File: licenses/unicode-ident-1.0.26/LICENSE-APACHE
License-File: licenses/unicode-ident-1.0.26/LICENSE-MIT
License-File: licenses/unicode-ident-1.0.26/LICENSE-UNICODE
License-File: licenses/unicode-normalization-0.1.25/LICENSE-APACHE
License-File: licenses/unicode-normalization-0.1.25/LICENSE-MIT
License-File: licenses/unicode-segmentation-1.13.3/LICENSE-APACHE
License-File: licenses/unicode-segmentation-1.13.3/LICENSE-MIT
Summary: Typed Python binding for the bounded Rust Turkish text normalizer
License-Expression: Apache-2.0
Requires-Python: >=3.11, <3.15
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Issues, https://github.com/erdemtuna/normalizer-tr/issues
Project-URL: Repository, https://github.com/erdemtuna/normalizer-tr

# normalizer-tr

[![CI](https://github.com/erdemtuna/normalizer-tr/actions/workflows/ci.yml/badge.svg)](https://github.com/erdemtuna/normalizer-tr/actions/workflows/ci.yml)

Turkish text normalization for speech, with a Rust core and a typed Python API.
Convert numbers, money, dates, measurements and other supported notation into
spoken Turkish while preserving ordinary prose. Runs offline, without a speech
model or service. Decimal and money arithmetic is exact.

```text
saat 09:30'da 5 kg malzeme ve %12,5'lik fark
→ saat dokuz otuzda beş kilogram malzeme ve yüzde on iki virgül beşlik fark
```

## Python

```sh
python -m pip install normalizer-tr
```

```python
from normalizer_tr import Normalizer

normalizer = Normalizer()
result = normalizer.normalize("25 TL; 5 kg")
assert result.normalized_text == "yirmi beş Türk lirası; beş kilogram"
assert result.complete
```

Wheels support CPython 3.11 to 3.14 on Windows and Linux x64, and macOS
x64 and arm64. Compatible wheels need no Rust compiler.
[Platform requirements and source builds](https://github.com/erdemtuna/normalizer-tr/blob/main/bindings/python/README.md).

## Rust

Requires Rust 1.94 or newer. Add to `Cargo.toml`:

```toml
[dependencies]
normalizer-tr = "0.4"
```

```rust
use normalizer_tr::{NormalizeOptions, Normalizer};

let normalizer = Normalizer::new()?;
let result = normalizer.normalize("25 TL; 5 kg", &NormalizeOptions::default())?;
assert_eq!(result.normalized_text(), "yirmi beş Türk lirası; beş kilogram");
assert!(result.complete());
# Ok::<(), normalizer_tr::NormalizeError>(())
```

Reuse a `Normalizer` across calls. It is cloneable and `Send + Sync`.
Enable the optional `serde` feature to serialize results.

## Choose how to handle ambiguity

| Policy | Behavior |
|---|---|
| `preserve` (default) | Keep unresolved spans as written. Return `complete=false` and `issues`. |
| `reject` | Return an error if any span is unresolved. |
| `fallback` | Render unresolved notation and symbols. Return handled assumptions in `fallbacks`. |

```python
result = normalizer.normalize("1.234; AB12", ambiguity_policy="fallback")
assert result.normalized_text == "bin iki yüz otuz dört; a be bir iki"
assert result.complete and not result.issues
assert result.fallback_used
```

In Rust, set `NormalizeOptions.ambiguity_policy` to
`AmbiguityPolicy::Fallback` or `AmbiguityPolicy::Reject`.

Fallback prefers clear formats, then literal readings and named symbols, then
spoken Unicode codes. It does not correct invalid facts or certify identifiers.
Check `fallbacks` when those assumptions matter. Invalid input or hints,
cancellation and resource limits remain errors in every policy.

Hints provide explicit intent. All hint and diagnostic ranges are original
UTF-8 byte offsets, not character positions.

## Documentation

| Guide | Contents |
|---|---|
| [Rust API](https://docs.rs/normalizer-tr) | Types, methods and examples |
| [Python API](https://github.com/erdemtuna/normalizer-tr/blob/main/bindings/python/README.md) | Hints, errors, cancellation and building |
| [Normalization reference](https://github.com/erdemtuna/normalizer-tr/blob/main/docs/normalization.md) | Supported formats and boundaries |
| [Fallback](https://github.com/erdemtuna/normalizer-tr/blob/main/docs/fallback.md) | Reading strategies and diagnostics |
| [Contributing](https://github.com/erdemtuna/normalizer-tr/blob/main/CONTRIBUTING.md) | Setup, architecture and verification |

This is a pre 1.0 library with bounded coverage, not a universal pronunciation
engine. See [performance](https://github.com/erdemtuna/normalizer-tr/blob/main/PERFORMANCE.md) for measurements and
[release notes](https://github.com/erdemtuna/normalizer-tr/blob/main/docs/release.md) for changes.

## License

[Apache-2.0](https://github.com/erdemtuna/normalizer-tr/blob/main/LICENSE),
with [third party notices](https://github.com/erdemtuna/normalizer-tr/blob/main/THIRD_PARTY_NOTICES.md).

Thanks to [@canberk7](https://github.com/canberk7) for his contribution to fallback support.

