-module(unicorn). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/unicorn.gleam"). -export([to_nfc/1, to_nfd/1, to_nfkc/1, to_nfkd/1, normalize/2]). -export_type([form/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( " A lightweight wrapper library around built-in Unicode normalization functions\n" " for both Erlang and JavaScript targets.\n" "\n" " For details on Unicode normalization, see:\n" " [Unicode Standard Annex #15: Unicode Normalization Forms](https://unicode.org/reports/tr15/)\n" ). -type form() :: n_f_c | n_f_d | n_f_k_c | n_f_k_d. -file("src/unicorn.gleam", 36). ?DOC( " Converts a `String` into its\n" " canonical composition form (NFC).\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " // NFC: \"e\" with a combining acute -> single \"é\"\n" " assert unicorn.to_nfc(\"e\\u{0301}\") == \"é\"\n" " ```\n" ). -spec to_nfc(binary()) -> binary(). to_nfc(S) -> er_ffi:to_nfc(S). -file("src/unicorn.gleam", 50). ?DOC( " Converts a `String` into its\n" " canonical decomposition form (NFD).\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " // NFD: single \"が\" -> \"か\" with a combining dakuten\n" " assert unicorn.to_nfd(\"が\") == \"か\\u{3099}\"\n" " ```\n" ). -spec to_nfd(binary()) -> binary(). to_nfd(S) -> er_ffi:to_nfd(S). -file("src/unicorn.gleam", 64). ?DOC( " Converts a `String` into its\n" " compatibility composition form (NFKC).\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " // NFKC: half-width \"カ\" + half-width dakuten -> full-width \"ガ\"\n" " assert unicorn.to_nfkc(\"ガ\") == \"ガ\"\n" " ```\n" ). -spec to_nfkc(binary()) -> binary(). to_nfkc(S) -> er_ffi:to_nfkc(S). -file("src/unicorn.gleam", 78). ?DOC( " Converts a `String` into its\n" " compatibility decomposition form (NFKD).\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " // NFKD: single ḕ -> \"e\" + macron + grave\n" " assert unicorn.to_nfkd(\"ḕ\") == \"e\\u{0304}\\u{0300}\"\n" " ```\n" ). -spec to_nfkd(binary()) -> binary(). to_nfkd(S) -> er_ffi:to_nfkd(S). -file("src/unicorn.gleam", 100). ?DOC( " Normalizes a `String` to the specified Unicode normalization `form`.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " // NFKC: fraction \"¼\" -> separate \"1\" + \"⁄\" + \"4\"\n" " assert unicorn.normalize(\"¼\", NFKC) == \"1⁄4\"\n" " ```\n" "\n" " ```gleam\n" " // NFKC: hangul conjoining jamo \"ᄀ\" + \"ᅡ\" + \"ᆨ\" -> single \"각\"\n" " assert unicorn.normalize(\"ᄀ\" <> \"ᅡ\" <> \"ᆨ\", NFKC) == \"각\"\n" " ```\n" "\n" " ```gleam\n" " // NFD: single \"が\" -> \"か\" with a combining dakuten\n" " // Note that `form` can be passed with a label in an explicit manner\n" " assert unicorn.normalize(\"が\", form: NFD) == \"か\\u{3099}\"\n" " ```\n" ). -spec normalize(binary(), form()) -> binary(). normalize(S, Kind) -> case Kind of n_f_c -> er_ffi:to_nfc(S); n_f_d -> er_ffi:to_nfd(S); n_f_k_c -> er_ffi:to_nfkc(S); n_f_k_d -> er_ffi:to_nfkd(S) end.