| 178 | } |
| 179 | |
| 180 | UniString NormalizeAndSimplifyString(std::string_view s) |
| 181 | { |
| 182 | UniString uniString = MakeUniString(s); |
| 183 | for (size_t i = 0; i < uniString.size(); ++i) |
| 184 | { |
| 185 | UniChar & c = uniString[i]; |
| 186 | switch (c) |
| 187 | { |
| 188 | // Replace "d with stroke" to simple d letter. Used in Vietnamese. |
| 189 | // (unicode-compliant implementation leaves it unchanged) |
| 190 | case 0x0110: |
| 191 | case 0x0111: c = 'd'; break; |
| 192 | // Replace small turkish dotless 'ı' with dotted 'i'. Our own |
| 193 | // invented hack to avoid well-known Turkish I-letter bug. |
| 194 | case 0x0131: c = 'i'; break; |
| 195 | // Replace capital turkish dotted 'İ' with dotted lowercased 'i'. |
| 196 | // Here we need to handle this case manually too, because default |
| 197 | // unicode-compliant implementation of MakeLowerCase converts 'İ' |
| 198 | // to 'i' + 0x0307. |
| 199 | case 0x0130: c = 'i'; break; |
| 200 | case 0x0152: // Œ |
| 201 | case 0x0153: // œ |
| 202 | c = 'o'; |
| 203 | uniString.insert(uniString.begin() + (i++) + 1, 'e'); |
| 204 | break; |
| 205 | case 0x2018: // ‘ |
| 206 | case 0x2019: // ’ |
| 207 | c = '\''; |
| 208 | break; |
| 209 | case 0x2116: // № |
| 210 | c = '#'; |
| 211 | break; |
| 212 | } |
| 213 | } |
| 214 | |
| 215 | MakeLowerCaseInplace(uniString); |
| 216 | NormalizeInplace(uniString); |
| 217 | TransliterateHiraganaToKatakana(uniString); |
| 218 | |
| 219 | // Remove accents that can appear after NFKD normalization. |
| 220 | uniString.erase_if([](UniChar const & c) |
| 221 | { |
| 222 | // ̀ COMBINING GRAVE ACCENT |
| 223 | // ́ COMBINING ACUTE ACCENT |
| 224 | return (c == 0x0300 || c == 0x0301); |
| 225 | }); |
| 226 | |
| 227 | // Replace sequence of spaces with single one. |
| 228 | base::Unique(uniString, [](UniChar l, UniChar r) { return (l == r && l == ' '); }); |
| 229 | |
| 230 | return uniString; |
| 231 | |
| 232 | /// @todo Restore this logic to distinguish и-й in future. |
| 233 | /* |
| 234 | // Just after lower casing is a correct place to avoid normalization for specific chars. |
| 235 | static auto const isSpecificChar = [](UniChar c) -> bool |
| 236 | { |
| 237 | return c == 0x0439; // й |