unicode-casefold

    Unicode case folding and caseless matching for MoonBit

    unicode
    casefold
    caseless
    Download zip
    Version
    0.7.1
    License
    Apache-2.0
    Last updated
    8 days ago
    Downloads
    64

    #unicode-casefold

    Unicode 18.0.0 full case folding and caseless matching for MoonBit. The package depends on unicode-normalization for normalized folding keys.

    #Installation

    moon add moonbit-community/unicode-casefold

    import {
    "moonbit-community/unicode-casefold" @casefold,
    }

    #Usage

    let folded = @casefold.case_fold("Straße") // "strasse"
    let same_case = @casefold.caseless_match("Straße", "STRASSE") // true
    let same_text = @casefold.canonical_caseless_match("Å", "a\u{030A}") // true
    let search_key = @casefold.canonical_case_fold("Å") // "a\u{030A}"
    let folded_id = @casefold.nfkc_casefold("A\u{00AD}") // "a"
    let same_id = @casefold.identifier_caseless_match("A\u{00AD}", "a") // true

    These operations follow Unicode §3.13 and are locale-independent. Default full folding uses CaseFolding.txt statuses C and F, with expansions such as ß → ss; it does not normalize text or apply Turkic tailoring. I folds to i, while İ folds to i plus U+0307. Cherokee folds to uppercase, so a folded string is not necessarily lowercase.

    For canonically equivalent text, canonical_case_fold(s) computes NFD(case_fold(NFD(s))) (D145). Store and compare these keys, or search folded text with a folded query. Folding can change text length, so result offsets do not directly identify positions in the original text.

    nfkc_casefold(s) applies the official NFKC_CF mappings and then NFC (R5). This merges compatibility differences and removes default-ignorable characters. identifier_caseless_match(a, b) first applies NFD to both inputs before NFKC_Casefold (D147), including the Greek iota-subscript edge cases. It tests equality; identifier validation and confusable detection are separate operations.

    #API

    APIDescription
    case_fold(StringView) -> StringDefault full case folding (R4).
    caseless_match(StringView, StringView) -> BoolDefault caseless equality, without normalization (D144).
    canonical_case_fold(StringView) -> StringCanonical caseless comparison/search key (D145).
    canonical_caseless_match(StringView, StringView) -> BoolCaseless equality under canonical equivalence (D145).
    nfkc_casefold(StringView) -> StringOfficial NFKC_CF mapping followed by NFC (R5).
    identifier_caseless_match(StringView, StringView) -> BoolIdentifier caseless equality after initial NFD (D147).

    All text inputs accept StringView, including slices of larger strings. Existing calls with String arguments work through automatic view conversion. Text-producing operations still return String.

    canonical_case_fold

    fn canonical_case_fold(s : StringView) -> String

    A key for canonical caseless matching (D145): NFD(case_fold(NFD(s))). Both normalizations are needed, notably for Greek iota subscripts.

    canonical_caseless_match

    fn canonical_caseless_match(a : StringView, b : StringView) -> Bool

    Case-insensitive equality under canonical equivalence (D145).

    case_fold

    fn case_fold(s : StringView) -> String

    Unicode default full case folding (section 3.13, R4). Locale-independent: uses the C and F mappings in CaseFolding.txt, including expansions such as ß -> ss. Does not normalize or apply Turkic tailoring.

    caseless_match

    fn caseless_match(a : StringView, b : StringView) -> Bool

    Default caseless equality (D144), without normalization.

    identifier_caseless_match

    fn identifier_caseless_match(a : StringView, b : StringView) -> Bool

    Identifier caseless equality (D147): NFKC_Casefold(NFD(a)) equals NFKC_Casefold(NFD(b)). The initial NFD handles canonical equivalents with iota subscripts. This does not validate identifiers or detect confusables.

    nfkc_casefold

    fn nfkc_casefold(s : StringView) -> String

    Unicode NFKC_Casefold (R5). Applies the official NFKC_CF mapping, removing default-ignorable code points, then normalizes the concatenation to NFC. This is locale-independent and is not an identifier validity check.