Go Unicode объединяет символы (кластеры графем) и консоль MS Windows cmd.exe
В следующем коде ü
не является единственным символом Unicode U+00FC, но представляет собой один кластер графем, состоящий из двух символов Unicode, простого ASCII u
U + 0075 с последующим комбинированным диарезом U+0308.
fmt.Println("Jürgen Džemal")
fmt.Println("Ju\u0308rgen \u01c5emel")
Если я запускаю его на игровой площадке, он работает как положено.
Если я запускаю его в окне "Командная строка" MS Windows 10, он визуально не объединяет объединяющий символ с предыдущим. Однако, когда я вырезал и вставил текст сюда, он выглядит правильно:
C:\> ver
Microsoft Windows [Version 10.0.17134.228]
C:\> test
Jürgen Džemal
Jürgen Džemel
На экране в окне "Командная строка" это выглядело так:
Ju¨rgen Džemel
Изменение кодовой страницы (chcp) с 850 до 65001 не имеет значения. Смена шрифтов (Consolas, Courier и т. Д.) Не имела никакого значения.
В прошлом у меня возникали проблемы, которые в основном были связаны с тем, что Microsoft требует, чтобы программы Windows использовали другой API для вывода символов в STDOUT в зависимости от того, подключен ли STDOUT к консоли или к файлу. Я не знаю, является ли это другим проявлением той же самой проблемы.
Что я могу сделать, чтобы этот графемный кластер Unicode выглядел правильно?
1 ответ
Как прокомментировал eryksun и Peter,
- Консоль Windows (conhost.exe) не поддерживает комбинирование кодов. Вы должны сначала нормализовать эквивалентную строку, которая использует предварительно составленные символы.
- ты можешь использовать
golang.org/x/text/unicode/norm
сделать нормализацию (например,norm.NFC.String("Jürgen Džemal")
)
Я пробовал это
s := "Ju\u0308rgen \u01c5emel"
fmt.Println(s) // dieresis not combined with u by conhost.exe
s = norm.NFC.String(s)
fmt.Println(s) // shows correctly
И вывод выглядел так
или, для слабовидящих с невероятно сложными программами чтения с экрана - примерно так:
Ju¨rgen Džemel
Jürgen Džemel
Обратите внимание, что Unicode имеет четыре различные нормализованные формы, но NFC наиболее часто используется в Интернете на веб-страницах и также подходит для этой ситуации.
В этом пакете есть и другие методы, которые могут быть более эффективными или более полезными
Я читал, что используются визуальные символы, которые могут быть представлены только в Юникоде с использованием комбинированных символов. Другими словами, для которых нет заранее составленного символа. Необходим более тщательный подход, чтобы сделать что-то соответствующее с ними. По существу, сложности Unicode (или, точнее, человеческих языков и их типографики) практически не имеют конца. Иногда мне так кажется.
Рекомендации
- https://blog.golang.org/normalization
- https://godoc.org/golang.org/x/text/unicode/norm
Например, некоторые символы, используемые при написании литовского языка, имеют двойные диакритические знаки, поскольку имеют только разложенные формы. Примером является строчная буква U с макроном и тильдой ("ū̃", U+016b U+0303, где первая кодовая точка - это строчная буква U с макроном, а вторая - комбинированный острый акцент).