defmodule Unicode.String.Case.Mapping.Greek do @moduledoc """ Implements the special upper casing rules for for the Greek language. """ @remove_accents Unicode.Regex.compile!("[^[:ccc=Not_Reordered:][:ccc=Above:]]*?[\\u0313\\u0314\\u0301\\u0300\\u0306\\u0342\\u0308\\u0304]") @remove_iota Unicode.Regex.compile!("[^[:ccc=Not_Reordered:][:ccc=Iota_Subscript:]]*?[\\u0345]") @doc """ This implementation currently implements the `el-Upper` transform from CLDR. ### CLDR algorithm According to CLDR all accents on all characters are are omitted when upcasing. Remove 0301 following Greek, with possible intervening 0308 marks. ::NFD(); For uppercasing (not titlecasing!) remove all greek accents from greek letters. This is done in two groups, to account for canonical ordering. [:Greek:] [^[:ccc=Not_Reordered:][:ccc=Above:]]*? { [\u0313\u0314\u0301\u0300\u0306\u0342\u0308\u0304] → ; [:Greek:] [^[:ccc=Not_Reordered:][:ccc=Iota_Subscript:]]*? { \u0345 → ; ::NFC(); That transform basically says remove all accents except a subscripted iota. It doesn't handle dipthongs correctly. ### Mozilla algorithm Mozilla has a thread on a [bug report](https://bugzilla.mozilla.org/show_bug.cgi?id=307039) that: > Greek accented letters should be converted to the respective non-accented uppercase > letters. The required conversions are the following (in Unicode): > > ά -> Α > έ -> Ε > ή -> Η > ί -> Ι > ΐ -> Ϊ > ό -> Ο > ύ -> Υ > ΰ -> Ϋ > ώ -> Ω > > Also diphthongs (two-vowel constructs) should be converted as follows, when the > first vowel is accented: > > άι -> ΑΪ > έι -> ΕΪ > όι -> ΟΪ > ύι -> ΥΪ > άυ -> ΑΫ > έυ -> ΕΫ > ήυ -> ΗΫ > όυ -> ΟΫ That thread seems to align with current-day [Mozilla](https://developer.mozilla.org/en-US/docs/Web/CSS/text-transform) which says the rules are: > In Greek (el), vowels lose their accent when the whole word is in > uppercase (ά/Α), except for the disjunctive eta (ή/Ή). Also, diphthongs > with an accent on the first vowel lose the accent and gain a diaeresis > on the second vowel (άι/ΑΪ). """ def upcase(string) do string |> String.normalize(:nfd) |> String.replace(@remove_accents, "") |> String.replace(@remove_iota, "") |> String.normalize(:nfc) |> Unicode.String.Case.Mapping.upcase(:any) end end