str
Unicode-aware string utilities for Gleam.
This is the main public API for the str library. All functionality is
re-exported from internal modules for your convenience.
Quick Start
import str
str.truncate("Hello 👨👩👧👦 World", 10, "...") // "Hello 👨👩👧👦..."
str.slugify("Crème Brûlée") // "creme-brulee"
str.similarity("hello", "hallo") // 0.8
Core Functions
- Grapheme operations:
take,drop,at,reverse,length - Truncation:
truncate,ellipsis,truncate_strict,truncate_preserve - Padding:
pad_left,pad_right,center - Search:
index_of,last_index_of,contains,starts_with,ends_with - Validation:
is_blank,is_empty,is_ascii,is_uppercase, etc. - Similarity:
distance,similarity,hamming_distance - Text manipulation:
words,lines,capitalize,normalize_whitespace - HTML:
escape_html,unescape_html
Extra Functions
- Slugification:
slugify,slugify_opts - ASCII folding:
ascii_fold,ascii_fold_no_decompose - Case conversion:
to_snake_case,to_camel_case,to_pascal_case,to_kebab_case,to_title_case
Advanced Features
- Search strategies: KMP and sliding window algorithms with automatic selection
- Grapheme tokenization: Pure Gleam Unicode segmentation
- Configuration: Customizable search heuristics via
str/config
Note on Internal Modules
The str/internal/* modules are implementation details and should not be
imported directly. They may change without notice between minor versions.
Always use import str for stable public API.
Types
Position for fill operations.
pub type FillPosition {
Left
Right
Both
}
Constructors
-
Left -
Right -
Both
Search strategy selection (automatic, KMP, or sliding window).
pub type SearchStrategy {
Sliding
Kmp
}
Constructors
-
Sliding -
Kmp
Values
pub fn ascii_fold(text: String) -> String
Converts text to ASCII equivalents.
Examples
ascii_fold("Café")
// -> "Cafe"
pub fn ascii_fold_no_decompose(text: String) -> String
ASCII folding without Unicode decomposition.
pub fn ascii_fold_no_decompose_with_normalizer(
text: String,
normalizer: fn(String) -> String,
) -> String
ASCII folding without decomposition, with custom normalizer.
pub fn ascii_fold_with_normalizer(
text: String,
normalizer: fn(String) -> String,
) -> String
ASCII folding with custom normalizer.
pub fn at(text: String, index: Int) -> Result(String, Nil)
Returns the grapheme cluster at the given index (0-based).
Examples
at("Hello", 1)
// -> Ok("e")
pub fn build_kmp_maps(
pattern: String,
) -> #(dict.Dict(Int, String), dict.Dict(Int, Int))
Builds optimized KMP lookup maps.
pub fn build_prefix_table(pattern: String) -> List(Int)
Builds KMP prefix table for pattern.
pub fn capitalize(text: String) -> String
Capitalizes text: first letter uppercase, rest lowercase.
Examples
capitalize("hello WORLD")
// -> "Hello world"
pub fn center(text: String, width: Int, pad: String) -> String
Centers text within the specified width.
Examples
center("Hi", 6, " ")
// -> " Hi "
pub fn chars(text: String) -> List(String)
Pure Gleam grapheme tokenizer (approximates Unicode segmentation).
This is an experimental pure-Gleam implementation that approximates Unicode grapheme cluster segmentation without external dependencies.
pub fn chars_stdlib(text: String) -> List(String)
BEAM stdlib grapheme tokenizer (uses platform’s Unicode support).
This wraps the standard library’s grapheme segmentation for comparison and compatibility.
pub fn choose_search_strategy(
text: String,
pattern: String,
) -> SearchStrategy
Chooses optimal search strategy based on input.
pub fn chunk(text: String, size: Int) -> List(String)
Splits text into chunks of the specified size.
pub fn common_prefix(strings: List(String)) -> String
Finds common prefix of all strings.
pub fn common_suffix(strings: List(String)) -> String
Finds common suffix of all strings.
pub fn contains(text: String, needle: String) -> Bool
Returns True if needle is found in text (grapheme-aware).
pub fn contains_all(text: String, needles: List(String)) -> Bool
Returns True if all of the needles appear in text.
pub fn contains_any(text: String, needles: List(String)) -> Bool
Returns True if any of the needles appear in text.
pub fn count(
haystack: String,
needle: String,
overlapping: Bool,
) -> Int
Counts occurrences of needle in haystack.
pub fn count_auto(
haystack: String,
needle: String,
overlapping: Bool,
) -> Int
Automatic search strategy selection for count.
pub fn count_simple(
haystack: String,
needle: String,
overlapping: Bool,
) -> Int
Simple (direct) count algorithm — stable, straightforward implementation.
Use count_auto for heuristic/optimized selection.
pub fn count_strategy(
haystack: String,
needle: String,
overlapping: Bool,
strategy: SearchStrategy,
) -> Int
Count with explicit strategy selection.
pub fn distance(a: String, b: String) -> Int
Calculates Levenshtein distance between two strings.
Examples
distance("kitten", "sitting")
// -> 3
pub fn drop(text: String, n: Int) -> String
Drops the first N grapheme clusters from text.
Examples
drop("Hello World", 6)
// -> "World"
pub fn drop_right(text: String, n: Int) -> String
Drops the last N grapheme clusters from text.
pub fn ellipsis(text: String, max_len: Int) -> String
Truncates text with ellipsis (…).
pub fn ends_with(text: String, suffix: String) -> Bool
Returns True if text ends with suffix on grapheme boundaries.
pub fn ends_with_any(
text: String,
suffixes: List(String),
) -> Bool
Returns True if text ends with any of the suffixes.
pub fn ensure_prefix(text: String, prefix: String) -> String
Ensures text starts with prefix.
pub fn ensure_suffix(text: String, suffix: String) -> String
Ensures text ends with suffix.
pub fn escape_html(text: String) -> String
Escapes HTML special characters.
Examples
escape_html("<div>Hello & goodbye</div>")
// -> "<div>Hello & goodbye</div>"
pub fn fill(
text: String,
width: Int,
pad: String,
position: FillPosition,
) -> String
Fills text to specified width with padding at position.
pub fn hamming_distance(a: String, b: String) -> Result(Int, Nil)
Calculates Hamming distance between strings of equal length.
pub fn index_of(text: String, needle: String) -> Result(Int, Nil)
Finds the index of the first occurrence of needle (grapheme-aware).
Examples
index_of("Hello World", "World")
// -> Ok(6)
pub fn index_of_auto(
text: String,
needle: String,
) -> Result(Int, Nil)
Automatic search strategy selection for index_of.
pub fn index_of_simple(
text: String,
needle: String,
) -> Result(Int, Nil)
Simple (direct) index algorithm — stable, straightforward implementation.
Use index_of_auto for heuristic/optimized selection.
pub fn index_of_strategy(
text: String,
needle: String,
strategy: SearchStrategy,
) -> Result(Int, Nil)
Search with explicit strategy selection.
pub fn is_alpha(text: String) -> Bool
Checks if text contains only alphabetic characters.
pub fn is_alphanumeric(text: String) -> Bool
Checks if text contains only alphanumeric characters.
pub fn is_lowercase(text: String) -> Bool
Checks if all cased characters are lowercase.
pub fn is_numeric(text: String) -> Bool
Checks if text contains only numeric characters.
pub fn is_printable(text: String) -> Bool
Checks if text contains only printable characters.
pub fn is_title_case(text: String) -> Bool
Checks if text is in Title Case format.
pub fn is_uppercase(text: String) -> Bool
Checks if all cased characters are uppercase.
pub fn kmp_border_multiplier() -> Int
Multiplier applied to max border to decide repetitiveness.
pub fn kmp_index_of(
text: String,
pattern: String,
) -> Result(Int, Nil)
KMP search for first occurrence.
pub fn kmp_index_of_with_maps(
text: String,
pattern: String,
pmap: dict.Dict(Int, String),
pimap: dict.Dict(Int, Int),
) -> Result(Int, Nil)
KMP search with pre-built maps.
pub fn kmp_large_text_min_pat() -> Int
Minimum pattern length to consider KMP on large texts.
pub fn kmp_large_text_threshold() -> Int
Threshold for “large” text lengths where KMP may be preferred.
pub fn kmp_min_pattern_len() -> Int
Minimum pattern length to consider KMP algorithm.
pub fn kmp_search_all(text: String, pattern: String) -> List(Int)
Finds all occurrences using KMP algorithm.
pub fn kmp_search_all_with_maps(
text: String,
pmap: dict.Dict(Int, String),
pimap: dict.Dict(Int, Int),
) -> List(Int)
KMP search with pre-built maps for better performance.
pub fn last_index_of(
text: String,
needle: String,
) -> Result(Int, Nil)
Finds the index of the last occurrence of needle.
pub fn length(text: String) -> Int
Returns the number of grapheme clusters in text.
Examples
length("Hello 👨👩👧👦")
// -> 7
pub fn normalize_whitespace(text: String) -> String
Normalizes whitespace: collapses to single spaces and trims.
pub fn pad_left(text: String, width: Int, pad: String) -> String
Pads text on the left to reach the specified width.
Examples
pad_left("Hi", 5, " ")
// -> " Hi"
pub fn pad_right(text: String, width: Int, pad: String) -> String
Pads text on the right to reach the specified width.
pub fn partition(
text: String,
sep: String,
) -> #(String, String, String)
Splits text at separator, returning before, separator, and after.
pub fn remove_prefix(text: String, prefix: String) -> String
Removes prefix from text if present.
pub fn remove_suffix(text: String, suffix: String) -> String
Removes suffix from text if present.
pub fn replace_first(
text: String,
old: String,
new: String,
) -> String
Replaces only the first occurrence of old with new.
pub fn replace_last(
text: String,
old: String,
new: String,
) -> String
Replaces only the last occurrence of old with new.
pub fn reverse(text: String) -> String
Reverses text at grapheme cluster boundaries.
Examples
reverse("Hello 👋")
// -> "👋 olleH"
pub fn rpartition(
text: String,
sep: String,
) -> #(String, String, String)
Splits text at last occurrence of separator.
pub fn similarity(a: String, b: String) -> Float
Calculates similarity as a percentage (0.0 to 1.0).
Examples
similarity("hello", "hallo")
// -> 0.8
pub fn sliding_index_of(
text: String,
pattern: String,
) -> Result(Int, Nil)
Sliding window search for first occurrence.
pub fn sliding_search_all(
text: String,
pattern: String,
) -> List(Int)
Finds all occurrences using sliding window algorithm.
pub fn slugify(text: String) -> String
Creates a URL-friendly slug from text.
Examples
slugify("Crème Brûlée")
// -> "creme-brulee"
pub fn slugify_opts(
text: String,
max_len: Int,
sep: String,
preserve_unicode: Bool,
) -> String
Creates slug with detailed options.
pub fn slugify_opts_with_normalizer(
text: String,
max_len: Int,
sep: String,
preserve_unicode: Bool,
normalizer: fn(String) -> String,
) -> String
Creates slug with options and custom normalizer.
pub fn slugify_with_normalizer(
text: String,
normalizer: fn(String) -> String,
) -> String
Creates slug with custom normalizer.
pub fn smart_search_enabled() -> Bool
Returns True when smart search is enabled.
pub fn splitn(text: String, sep: String, n: Int) -> List(String)
Splits text into at most n parts.
pub fn squeeze(text: String, char: String) -> String
Reduces consecutive occurrences of char to a single occurrence.
pub fn starts_with(text: String, prefix: String) -> Bool
Returns True if text starts with prefix on grapheme boundaries.
pub fn starts_with_any(
text: String,
prefixes: List(String),
) -> Bool
Returns True if text starts with any of the prefixes.
pub fn strip(text: String, chars: String) -> String
Strips specified characters from both ends.
pub fn surround(
text: String,
prefix: String,
suffix: String,
) -> String
Adds prefix and suffix to text.
pub fn take(text: String, n: Int) -> String
Returns the first N grapheme clusters from text.
Examples
take("Hello 👨👩👧👦", 6)
// -> "Hello "
pub fn take_right(text: String, n: Int) -> String
Returns the last N grapheme clusters from text.
pub fn to_snake_case(text: String) -> String
Converts text to snake_case.
Examples
to_snake_case("HelloWorld")
// -> "hello_world"
pub fn truncate(
text: String,
max_len: Int,
suffix: String,
) -> String
Truncates text to max_len graphemes, adding suffix if truncated.
Examples
truncate("Hello World", 8, "...")
// -> "Hello..."
pub fn truncate_default(text: String, max_len: Int) -> String
Truncates to max_len with empty suffix.
pub fn truncate_preserve(
text: String,
max_len: Int,
suffix: String,
) -> String
Truncates preserving emoji sequences, may exceed max_len slightly.
pub fn truncate_strict(
text: String,
max_len: Int,
suffix: String,
) -> String
Truncates strictly at max_len, even if it breaks emoji sequences.
pub fn truncate_with_flag(
text: String,
max_len: Int,
suffix: String,
keep_whole_emoji: Bool,
) -> String
Truncates with emoji handling control.
pub fn unwrap(
text: String,
prefix: String,
suffix: String,
) -> String
Removes prefix and suffix from text if present.