///| Re-exports from the `unicode` sub-package so existing core consumers can
///| keep using the same unqualified names.
///|
/// The grapheme boundary scanner, backed by the Unicode 17.0 property table.
pub type TextGraphemeBoundaries = @unicode.TextGraphemeBoundaries
///| Stabilize caret positions so that carets inside a grapheme cluster share
///|
/// the cluster's leading caret coordinate.
pub fn fallback_stabilize_grapheme_cluster_carets(
text : String,
carets : Array[Double],
) -> Array[Double] {
@unicode.stabilize_grapheme_cluster_carets(text, carets)
}
///|
/// Returns the previous grapheme boundary before `caret`.
pub fn text_previous_grapheme_caret_boundary(text : String, caret : Int) -> Int {
@unicode.previous_grapheme_caret_boundary(text, caret)
}
///|
/// Returns the next grapheme boundary after `caret`.
pub fn text_next_grapheme_caret_boundary(text : String, caret : Int) -> Int {
@unicode.next_grapheme_caret_boundary(text, caret)
}
///| Normalizes a `TextRange` to grapheme boundaries. This bridges the core
///|
/// `TextRange` contract to the unicode package's `GraphemeRange` API.
pub fn normalize_grapheme_range(
boundaries : TextGraphemeBoundaries,
range : TextRange,
) -> TextRange {
let result = boundaries.normalize_range(
@unicode.GraphemeRange::new(start=range.start, end=range.end),
)
TextRange::new(start=result.start, end=result.end)
}
///| Computes the deletion range around `caret` in grapheme boundaries. This
///|
/// bridges the core `TextRange` contract to the unicode package's API.
pub fn delete_grapheme_range(
boundaries : TextGraphemeBoundaries,
caret : Int,
before : Int,
after : Int,
) -> TextRange {
let result = boundaries.delete_range(caret, before, after)
TextRange::new(start=result.start, end=result.end)
}