Skip to content

Commit a0ccffc

Browse files
committed
README: unify public API to str and update docs
Update README to reflect API and documentation changes: switch examples and imports from `str/core` and `str/extra` to the unified `str` module, update KMP/strategy examples to use `str` identifiers, and change the CI badge to the new GitHub Actions workflow URL. Adjust wording from “Zero Dependencies” to “Minimal Dependencies”, revise module table and structure to list `str`, `str/advanced`, `str/config` and internal implementation layout, and update usage guidance for advanced users. Also bump the release note reference from 1.2.3 to 2.0.0 and update examples that show integrating an OTP normalizer (otp_nfd) with `str` functions.
1 parent 2371a97 commit a0ccffc

1 file changed

Lines changed: 40 additions & 41 deletions

File tree

README.md

Lines changed: 40 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<p align="center">
1212
<a href="https://hex.pm/packages/str"><img src="https://img.shields.io/hexpm/v/str" alt="Package Version"></a>
1313
<a href="https://hexdocs.pm/str/"><img src="https://img.shields.io/badge/hex-docs-ffaff3" alt="Hex Docs"></a>
14-
<a href="https://github.com/lupodevelop/str/actions"><img src="https://img.shields.io/github/workflow/status/lupodevelop/str/CI?label=ci&logo=github" alt="CI"></a>
14+
<a href="https://github.com/lupodevelop/str/actions"><img src="https://img.shields.io/github/actions/workflow/status/lupodevelop/str/ci.yml?branch=main&label=ci&logo=github" alt="CI"></a>
1515
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
1616
</p>
1717

@@ -32,7 +32,7 @@
3232
| 📏 **Similarity** | Levenshtein `distance`, percentage `similarity`, `hamming_distance` |
3333
| 🧩 **Splitting** | `splitn`, `partition`, `rpartition`, `chunk`, `lines`, `words` |
3434
| 📐 **Padding** | `pad_left`, `pad_right`, `center`, `fill` |
35-
| 🚀 **Zero Dependencies** | Pure Gleam implementation with no OTP requirement |
35+
| 🚀 **Minimal Dependencies** | Pure Gleam implementation with no OTP requirement |
3636

3737
---
3838

@@ -47,34 +47,33 @@ gleam add str
4747
## 🚀 Quick Start
4848

4949
```gleam
50-
import str/core
51-
import str/extra
50+
import str
5251
5352
pub fn main() {
5453
// 🎯 Grapheme-safe truncation preserves emoji
5554
let text = "Hello 👩‍👩‍👧‍👦 World"
56-
core.truncate(text, 10, "...")
55+
str.truncate(text, 10, "...")
5756
// → "Hello 👩‍👩‍👧‍👦..."
5857
5958
// 🔗 ASCII transliteration and slugification
60-
extra.slugify("Crème Brûlée — Recipe 2025!")
59+
str.slugify("Crème Brûlée — Recipe 2025!")
6160
// → "creme-brulee-recipe-2025"
6261
6362
// 🔤 Case conversions
64-
extra.to_camel_case("hello world") // → "helloWorld"
65-
extra.to_snake_case("Hello World") // → "hello_world"
66-
core.capitalize("hELLO wORLD") // → "Hello world"
63+
str.to_camel_case("hello world") // → "helloWorld"
64+
str.to_snake_case("Hello World") // → "hello_world"
65+
str.capitalize("hELLO wORLD") // → "Hello world"
6766
6867
// 🔍 Grapheme-aware search
69-
core.index_of("👨‍👩‍👧‍👦 family test", "family")
68+
str.index_of("👨‍👩‍👧‍👦 family test", "family")
7069
// → Ok(2) - counts grapheme clusters, not bytes!
7170
7271
// 📏 String similarity
73-
core.similarity("hello", "hallo")
72+
str.similarity("hello", "hallo")
7473
// → 0.8 (80% similar)
7574
7675
// 🛡️ HTML escaping
77-
core.escape_html("<script>alert('xss')</script>")
76+
str.escape_html("<script>alert('xss')</script>")
7877
// → "&lt;script&gt;alert(&#39;xss&#39;)&lt;/script&gt;"
7978
}
8079
```
@@ -134,10 +133,10 @@ pub fn main() {
134133

135134
```gleam
136135
// Force KMP explicitly
137-
core.index_of_strategy("long text...", "pattern", core.Kmp)
136+
str.index_of_strategy("long text...", "pattern", str.Kmp)
138137
139138
// Let heuristic decide (experimental)
140-
core.index_of_auto("some text", "pat")
139+
str.index_of_auto("some text", "pat")
141140
```
142141

143142
> **Note:** `_auto` variants use heuristics and may not always choose optimally. For performance-critical code, use `_strategy` variants. Configure thresholds in `src/str/config.gleam`.
@@ -228,34 +227,34 @@ core.index_of_auto("some text", "pat")
228227

229228
---
230229

231-
## 🔤 Extra Module (str/extra)
230+
## 🔤 Case Conversions & ASCII Folding
232231

233232
### Case Conversions
234233

235234
```gleam
236-
import str/extra
235+
import str
237236
238-
extra.to_snake_case("Hello World") // → "hello_world"
239-
extra.to_camel_case("hello world") // → "helloWorld"
240-
extra.to_pascal_case("hello world") // → "HelloWorld"
241-
extra.to_kebab_case("Hello World") // → "hello-world"
242-
extra.to_title_case("hello world") // → "Hello World"
237+
str.to_snake_case("Hello World") // → "hello_world"
238+
str.to_camel_case("hello world") // → "helloWorld"
239+
str.to_pascal_case("hello world") // → "HelloWorld"
240+
str.to_kebab_case("Hello World") // → "hello-world"
241+
str.to_title_case("hello world") // → "Hello World"
243242
```
244243

245244
### ASCII Folding (Deburr)
246245

247246
```gleam
248-
extra.ascii_fold("Crème Brûlée") // → "Creme Brulee"
249-
extra.ascii_fold("straße") // → "strasse"
250-
extra.ascii_fold("æon") // → "aeon"
247+
str.ascii_fold("Crème Brûlée") // → "Creme Brulee"
248+
str.ascii_fold("straße") // → "strasse"
249+
str.ascii_fold("æon") // → "aeon"
251250
```
252251

253252
### Slug Generation
254253

255254
```gleam
256-
extra.slugify("Hello, World!") // → "hello-world"
257-
extra.slugify_opts("one two three", 2, "-", False) // → "one-two"
258-
extra.slugify_opts("Hello World", 0, "_", False) // → "hello_world"
255+
str.slugify("Hello, World!") // → "hello-world"
256+
str.slugify_opts("one two three", 2, "-", False) // → "one-two"
257+
str.slugify_opts("Hello World", 0, "_", False) // → "hello_world"
259258
```
260259

261260
---
@@ -266,24 +265,22 @@ extra.slugify_opts("Hello World", 0, "_", False) // → "hello_world"
266265

267266
| Module | When to use | Import |
268267
|--------|-------------|--------|
269-
| **`str`** | Most common operations | `import str` |
270-
| **`str/core`** | Full grapheme-aware API, advanced features | `import str/core` |
271-
| **`str/extra`** | ASCII folding, slugs, case conversions | `import str/extra` |
272-
| **`str/tokenize`** | Reference implementation (pedagogic only) | `import str/tokenize` |
268+
| **`str`** | All string operations (recommended) | `import str` |
269+
| **`str/advanced`** | Low-level KMP algorithms, caching | `import str/advanced` |
270+
| **`str/config`** | Search heuristics configuration | `import str/config` |
273271

274-
**Quick start:** Use `import str` for everyday needs. The main `str` module re-exports commonly used functions from `core` and `extra`.
272+
**Quick start:** Use `import str` for all your needs. The main `str` module provides the complete public API including grapheme operations, ASCII folding, slugs, and case conversions.
275273

276-
**Advanced users:** Import `str/core` and `str/extra` directly when you need the complete API or want explicit control.
274+
**Advanced users:** Import `str/advanced` for explicit control over search algorithms and KMP map caching.
277275

278276
### Module structure
279277

280278
```
281279
str/
282-
├── str.gleam # Main module (re-exports common functions)
283-
├── core.gleam # Grapheme-aware utilities
284-
├── extra.gleam # ASCII folding, slugs, case conversions
285-
├── tokenize.gleam # Pure-Gleam tokenizer (reference)
286-
└── internal_* # Character tables (not public API)
280+
├── str.gleam # Main module (complete public API)
281+
├── advanced.gleam # Low-level search algorithms
282+
├── config.gleam # Search heuristics configuration
283+
└── internal/ # Implementation details (not public API)
287284
```
288285

289286
---
@@ -305,15 +302,17 @@ str/
305302
The library core is OTP-free by design. For production Unicode normalization (NFC/NFD):
306303

307304
```gleam
305+
import str
306+
308307
// In your application code:
309308
pub fn otp_nfd(s: String) -> String {
310309
// Call Erlang's :unicode module
311310
s
312311
}
313312
314313
// Use with str:
315-
extra.ascii_fold_with_normalizer("Crème", otp_nfd)
316-
extra.slugify_with_normalizer("Café", otp_nfd)
314+
str.ascii_fold_with_normalizer("Crème", otp_nfd)
315+
str.slugify_with_normalizer("Café", otp_nfd)
317316
```
318317

319318
---
@@ -328,7 +327,7 @@ gleam test
328327
python3 scripts/generate_character_tables.py
329328
```
330329

331-
Note: as of **1.2.3**, `escape_html` now uses the `houdini` library for fast, allocation‑friendly escaping, and `unescape_html` uses `odysseus` for comprehensive entity support (named, decimal and hex numeric entities). See [CHANGELOG.md](CHANGELOG.md) for details.
330+
Note: as of **2.0.0**, `escape_html` now uses the `houdini` library for fast, allocation‑friendly escaping, and `unescape_html` uses `odysseus` for comprehensive entity support (named, decimal and hex numeric entities). See [CHANGELOG.md](CHANGELOG.md) for details.
332331

333332
---
334333

0 commit comments

Comments
 (0)