Unicode и итерация по символам
От: пффф  
Дата: 18.01.23 16:24
Оценка:
Привет!

Хз в какой форум с такой темой, если что — перенесите куда правильно.

Вопрос — как правильно итерироваться по юникодному тексту? По символам я умею, как в UTF-8 (линупсы), так и по виндовому WCHAR* — UTF-16 вроде же?

Но ведь это ничего не значит, потому что один глиф (или как правильно сказать?) может состоять из нескольких codepoints, так?

В винде, допустим, должны быть какие-то функции на эту тему (кстати, какие?).

А как быть в линупсе? Я немного почитал про composition/decomposition, там про какие-то таблицы декомпозиции пишут. Самому с этим возиться неохота. Есть какое-то стандартное API, которое всегда есть или может быть легко установлено?

Кстати, некоторые раскладки в винде могут генерить целые пачки символов — лигатуры, например в персидском аж до 4х WCHAR может быть за одно нажатие. А отображается — как один символ. Тут явно больше одного UTF-32 codepoints. Если они могут быть подвергнуты композиции — то почему это не сделано? А если не могут, то как по ним корректно итерироваться?
Re: Unicode и итерация по символам
От: σ  
Дата: 18.01.23 16:56
Оценка:
П>Вопрос — как правильно итерироваться по юникодному тексту?

П>один глиф (или как правильно сказать?) может состоять из нескольких codepoints, так?


П>Есть какое-то стандартное API, которое всегда есть или может быть легко установлено?


https://unicode-org.github.io/icu/userguide/boundaryanalysis/
https://www.gnu.org/software/libunistring/manual/libunistring.html#unigbrk_002eh
  Скрытый текст
Ничем из этого не пользовался 🤣
Re[2]: Unicode и итерация по символам
От: пффф  
Дата: 18.01.23 16:59
Оценка:
Здравствуйте, σ, Вы писали:

П>>Есть какое-то стандартное API, которое всегда есть или может быть легко установлено?


σ>https://unicode-org.github.io/icu/userguide/boundaryanalysis/

σ>https://www.gnu.org/software/libunistring/manual/libunistring.html#unigbrk_002eh

Блин, а попроще никак? Мне бы для начала под винду только, остальное подождёт
Re[3]: Unicode и итерация по символам
От: σ  
Дата: 18.01.23 17:02
Оценка: +1
П>>>Есть какое-то стандартное API, которое всегда есть или может быть легко установлено?

σ>>https://unicode-org.github.io/icu/userguide/boundaryanalysis/

σ>>https://www.gnu.org/software/libunistring/manual/libunistring.html#unigbrk_002eh

П>Блин, а попроще никак? Мне бы для начала под винду только


Вот прям только под винду? А то ICU типа для винды есть https://learn.microsoft.com/en-us/windows/win32/intl/international-components-for-unicode--icu-
Re[4]: Unicode и итерация по символам
От: пффф  
Дата: 19.01.23 17:21
Оценка:
Здравствуйте, σ, Вы писали:

П>>Блин, а попроще никак? Мне бы для начала под винду только


σ>Вот прям только под винду? А то ICU типа для винды есть https://learn.microsoft.com/en-us/windows/win32/intl/international-components-for-unicode--icu-


Вот таскать ICU за собой точно не хочется
Re[5]: Unicode и итерация по символам
От: σ  
Дата: 19.01.23 19:52
Оценка: 4 (1)
П>Вот таскать ICU за собой точно не хочется



https://learn.microsoft.com/en-us/windows/win32/intl/international-components-for-unicode--icu- :
> ICU was integrated into Windows
Отредактировано 19.01.2023 19:55 σ . Предыдущая версия .
Re[6]: Unicode и итерация по символам
От: пффф  
Дата: 19.01.23 19:54
Оценка:
Здравствуйте, σ, Вы писали:

σ>https://learn.microsoft.com/en-us/windows/win32/intl/international-components-for-unicode--icu-:


404 паге нот фаунд


>> ICU was integrated into Windows


В десятку или в 11? Восьмерка, семерка, виста, XP, прости осподя, с этим как?
Re[7]: Unicode и итерация по символам
От: σ  
Дата: 19.01.23 19:57
Оценка:
П>В десятку или в 11? Восьмерка, семерка, виста, XP, прости осподя, с этим как?

Можно закапывать. Впрочем, венда вообще не нужна.
Re[8]: Unicode и итерация по символам
От: пффф  
Дата: 19.01.23 19:58
Оценка:
Здравствуйте, σ, Вы писали:

П>>В десятку или в 11? Восьмерка, семерка, виста, XP, прости осподя, с этим как?


σ>Можно закапывать. Впрочем, венда вообще не нужна.


Нельзя
Re: Unicode и итерация по символам
От: Sinclair Россия https://github.com/evilguest/
Дата: 21.01.23 22:42
Оценка:
Здравствуйте, пффф, Вы писали:

П>Но ведь это ничего не значит, потому что один глиф (или как правильно сказать?) может состоять из нескольких codepoints, так?

АФАИК, глиф составляется из нескольких codepoints только одним способом: все, кроме первого — это combining characters.
Поэтому навигируемcя путём анализа категории уникода для каждого code point до тех пор, пока не наткнёмся на не-combining character (что-то вне категорий Mc/Mn/Me).


П>В винде, допустим, должны быть какие-то функции на эту тему (кстати, какие?).

Ну, в дотнете это делается легко: https://learn.microsoft.com/en-us/dotnet/api/system.globalization.charunicodeinfo.getunicodecategory?view=net-7.0#system-globalization-charunicodeinfo-getunicodecategory(system-int32)
Внутри оно устроено не шибко сложно:https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Globalization/CharUnicodeInfo.cs#L384
То есть идёт некий лукап по таблице. Полагаю, что при нежелании писать на дотнете таблицу можно выковырять из исходников и перенести в любой язык программирования.

П>Кстати, некоторые раскладки в винде могут генерить целые пачки символов — лигатуры, например в персидском аж до 4х WCHAR может быть за одно нажатие. А отображается — как один символ. Тут явно больше одного UTF-32 codepoints. Если они могут быть подвергнуты композиции — то почему это не сделано? А если не могут, то как по ним корректно итерироваться?

Я в арабских языках не силён, но насколько я знаю, там преобладают именно что лигатуры. Но если там действительно речь идёт не о визуальном соединении нескольких символов вязи, а о комбинациях — то да, значит для них в уникоде нету precomposed characters.
Итерироваться корректно — именно вот так, по базовым символам.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Unicode и итерация по символам
От: vsb Казахстан  
Дата: 21.01.23 23:06
Оценка: 78 (1)
Здравствуйте, Sinclair, Вы писали:

S>АФАИК, глиф составляется из нескольких codepoints только одним способом: все, кроме первого — это combining characters.


Кажется нет.

% m='\xf0\x9f\x91\xa8'
% f='\xf0\x9f\x91\xa9'
% c='\xf0\x9f\x91\xa6'
% z='\xe2\x80\x8d'
% echo "$m $f $c $m$z$f$z$c"
👨 👩 👦 👨‍👩‍👦
Отредактировано 21.01.2023 23:23 vsb . Предыдущая версия .
Re[3]: Unicode и итерация по символам
От: Sinclair Россия https://github.com/evilguest/
Дата: 21.01.23 23:25
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Здравствуйте, Sinclair, Вы писали:


S>>АФАИК, глиф составляется из нескольких codepoints только одним способом: все, кроме первого — это combining characters.


vsb>Кажется нет.


vsb>
vsb>% m='\xf0\x9f\x91\xa8'
vsb>% f='\xf0\x9f\x91\xa9'
vsb>% c='\xf0\x9f\x91\xa6'
vsb>% z='\xe2\x80\x8d'
vsb>% echo "$m$f$c$m$z$f$z$c"
vsb>👨👩👦👨‍👩‍👦
vsb>

Да, точно, нужно ещё учитывать zero-width joiner. И ещё несколько экзотических сценариев
Так что, наверное, всё же придётся таскать за собой ICU.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Unicode и итерация по символам
От: пффф  
Дата: 21.01.23 23:31
Оценка:
Здравствуйте, Sinclair, Вы писали:

П>>Но ведь это ничего не значит, потому что один глиф (или как правильно сказать?) может состоять из нескольких codepoints, так?

S>АФАИК, глиф составляется из нескольких codepoints только одним способом: все, кроме первого — это combining characters.
S>Поэтому навигируемcя путём анализа категории уникода для каждого code point до тех пор, пока не наткнёмся на не-combining character (что-то вне категорий Mc/Mn/Me).

Апостроф и аккут — одни из популярных символов, которые используются для составных символов. Возможно, кроме ASCII версий, есть и юникодовые код поинты для них. Окей. Как тогда мне отобразить аккут? На ум приходит только комбинация из пробела и аккута, если аккут обладает бузусловным признаком combining character.


П>>В винде, допустим, должны быть какие-то функции на эту тему (кстати, какие?).

S>Ну, в дотнете это делается легко: https://learn.microsoft.com/en-us/dotnet/api/system.globalization.charunicodeinfo.getunicodecategory?view=net-7.0#system-globalization-charunicodeinfo-getunicodecategory(system-int32)

Спс, гляну.


S>Внутри оно устроено не шибко сложно:https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Globalization/CharUnicodeInfo.cs#L384

S>То есть идёт некий лукап по таблице. Полагаю, что при нежелании писать на дотнете таблицу можно выковырять из исходников и перенести в любой язык программирования.

Винда вроде и до дотнета поддерживала кучу языков, и арабский, и персидский, и кучу справа налево. Тогда в каждой аппе свои таблицы держали?


S>Я в арабских языках не силён, но насколько я знаю, там преобладают именно что лигатуры. Но если там действительно речь идёт не о визуальном соединении нескольких символов вязи, а о комбинациях — то да, значит для них в уникоде нету precomposed characters.


Пошерстил по раскладкам — нифига, у арабов и персов только несколько кнопок генерят лигатуры, остальные клавиши генерят вполне конкретный код. Вот, например — https://kbdlayout.info/kbda1


S>Итерироваться корректно — именно вот так, по базовым символам.


Меня интересует что-то системное. С ICU буду разбираться, когда на линупсы захочу, а пока и на винде проблем хватает. Своё колхозить тоже как-то не особо
Re[3]: Unicode и итерация по символам
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.01.23 01:00
Оценка:
Здравствуйте, пффф, Вы писали:

П>Апостроф и аккут — одни из популярных символов, которые используются для составных символов. Возможно, кроме ASCII версий, есть и юникодовые код поинты для них. Окей. Как тогда мне отобразить аккут? На ум приходит только комбинация из пробела и аккута, если аккут обладает бузусловным признаком combining character.

Для комбинации пробела и аккута есть отдельный precomposed character U+00B4.
Но можно и как U+0020 U+0301.
П>Спс, гляну.
Там, кстати, вроде бы ещё что-то завезли как раз для детектирования Grapheme Clusters, но я ещё не разбирался.

П>Винда вроде и до дотнета поддерживала кучу языков, и арабский, и персидский, и кучу справа налево. Тогда в каждой аппе свои таблицы держали?

Наверняка, т.к. большинство аппов ничего особенного и не поддерживали. В древних виндах всё держалось на сплошных кодировках — а там наверняка всё просто как угол дома: вот тебе байт, вот тебе его интерпретация.
Полноценную поддержку уникода со всеми этими нормализациями и декомпозициями умели только отдельные приложения, и они ессно всё таскали с собой.

П>Пошерстил по раскладкам — нифига, у арабов и персов только несколько кнопок генерят лигатуры, остальные клавиши генерят вполне конкретный код. Вот, например — https://kbdlayout.info/kbda1

А где там посмотреть, что за лигатуры генерируются?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Unicode и итерация по символам
От: пффф  
Дата: 22.01.23 04:55
Оценка:
Здравствуйте, Sinclair, Вы писали:

П>>Апостроф и аккут — одни из популярных символов, которые используются для составных символов. Возможно, кроме ASCII версий, есть и юникодовые код поинты для них. Окей. Как тогда мне отобразить аккут? На ум приходит только комбинация из пробела и аккута, если аккут обладает бузусловным признаком combining character.

S>Для комбинации пробела и аккута есть отдельный precomposed character U+00B4.

Дык, вроде почти для всего есть свои отдельные precomposed chars. И аккут — просто как пример. Гипотеза, что есть отдельно условный аккут, который для composite'а и готовый precomposed аккут с пробелом — имеет право на жизнь, но с арабскими лигатурами так не проходит

S>Но можно и как U+0020 U+0301.

П>>Спс, гляну.
S>Там, кстати, вроде бы ещё что-то завезли как раз для детектирования Grapheme Clusters, но я ещё не разбирался.

П>>Винда вроде и до дотнета поддерживала кучу языков, и арабский, и персидский, и кучу справа налево. Тогда в каждой аппе свои таблицы держали?

S>Наверняка, т.к. большинство аппов ничего особенного и не поддерживали. В древних виндах всё держалось на сплошных кодировках — а там наверняка всё просто как угол дома: вот тебе байт, вот тебе его интерпретация.
S>Полноценную поддержку уникода со всеми этими нормализациями и декомпозициями умели только отдельные приложения, и они ессно всё таскали с собой.

NT вроде с рождения была юникодная с кодировкой UCS-2, которую сменили на UTF-16 в районе Win2K. А конвертации MultiByteToWideChar/WideCharToMultiByte c MB_COMPOSITE/MB_PRECOMPOSED были в WinAPI как минимум начиная с 95ой винды. Вероятно, с высоты нынешних позиций те реализации были кривоватыми, но работали же. Сейчас наверное работают получше. Ну так на той же базе по идее можно было бы выставить в API и итерацию по символам, и на тот момент она наверное даже была бы не кривая

П>>Пошерстил по раскладкам — нифига, у арабов и персов только несколько кнопок генерят лигатуры, остальные клавиши генерят вполне конкретный код. Вот, например — https://kbdlayout.info/kbda1

S>А где там посмотреть, что за лигатуры генерируются?

Мышкой над кнопкой с лигатурой зависаешь и смотришь
  Арабская 401

  Персидская 429


U+0644 LAM в арабской раскладке ведущая, в персидской — ведомая
Re[5]: Unicode и итерация по символам
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.01.23 07:31
Оценка:
Здравствуйте, пффф, Вы писали:

П>Дык, вроде почти для всего есть свои отдельные precomposed chars.

Я потерял нить рассуждений. Я думал, что речь о том, чтобы пилить на графемные кластеры произвольный уникодный текст.
Если достаточно просто умения изображать ограниченный набор типовых символов с умляутами, то ничего этого не надо — просто не пользуйтесь композитными последовательностями и всё.

П>И аккут — просто как пример. Гипотеза, что есть отдельно условный аккут, который для composite'а и готовый precomposed аккут с пробелом — имеет право на жизнь,

Это не гипотеза — посмотрите на страничке https://www.compart.com/en/unicode/U+00B4 раздел Based on " " (U+0020). Вот там собственно собраны все "акуты", предкомпозированные с пробелом.

П>NT вроде с рождения была юникодная с кодировкой UCS-2, которую сменили на UTF-16 в районе Win2K.

Ну, может быть. Я в те времена с уникодом не сталкивался, все наши приложения честно работали в системной кодовой странице.
П>А конвертации MultiByteToWideChar/WideCharToMultiByte c MB_COMPOSITE/MB_PRECOMPOSED были в WinAPI как минимум начиная с 95ой винды. Вероятно, с высоты нынешних позиций те реализации были кривоватыми, но работали же. Сейчас наверное работают получше. Ну так на той же базе по идее можно было бы выставить в API и итерацию по символам, и на тот момент она наверное даже была бы не кривая
По идее да. Более того, если винда действительно умела в уникод, то где-то внутри такая механика должна была быть, хотя бы для собственно отображения уникодных строк.
Но это предположение неплохо бы проверить — например, попробовав отрендерить zalgo-text на какой-нибудь VM со старой версией винды.
Очень может быть, что на практике там был сделан хак, который принудительно композировал известные композиты, а на всё остальное рисовал квадратики.

П>>>Пошерстил по раскладкам — нифига, у арабов и персов только несколько кнопок генерят лигатуры, остальные клавиши генерят вполне конкретный код. Вот, например — https://kbdlayout.info/kbda1

S>>А где там посмотреть, что за лигатуры генерируются?

П>Мышкой над кнопкой с лигатурой зависаешь и смотришь

Спасибо, понял.
Короче, там всё сложно
Возьмём прямо ту кнопку с вашего скриншота, которая с шифтом отдаёт U+0644 U+0622.
Выглядит так, что при нажатии кнопки в буфер уезжает два "символа". Но при этом второй из них — это precomposed пара из ا (U+0627) и  ◌ٓ (U+0653). Интересно, что для полной комбинации U+0644 U+0622 есть прекомпозиты U+FEF5 и U+FEF6.
Как я понимаю, клавиатура не порождает эти прекомпозиты потому, что непонятно, какой из них использовать — это зависит от положения буквы; она может быть либо отдельной, либо финальной (стало быть, такое сочетание не может встречаться в начале или середине слова).
И вообще, эти прекомпозиты, похоже, предназначены были как раз для тех сред, где нельзя полагаться на автокомпозицию и шрифтовые лигатуры.

То, что визуально оно выглядит как один символ, обеспечивается шрифтом. Шрифты в opentype могут лигатурить всё, что угодно, независимо от уникода. См. всякие модные шрифты, которые объединяют вполне себе ascii-шные >= в .

В общем, возникает всё же вопрос о том, в чём именно состоит задача — отображение, редактирование, ещё что-то?
Предыдущее обсуждение уникода на этом сайте началось с эмоджи, а закончилось выводом о необходимости добавления в стандарт кириллической буквы ё без точек
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: Unicode и итерация по символам
От: пффф  
Дата: 22.01.23 13:39
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>В общем, возникает всё же вопрос о том, в чём именно состоит задача — отображение, редактирование, ещё что-то?


Да, отображение и редактирование
Re[7]: Unicode и итерация по символам
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.01.23 13:50
Оценка:
Здравствуйте, пффф, Вы писали:

П>Да, отображение и редактирование

Произвольного unicode-текста или можно чем-то пожертвовать? Эмоджи, залго, сочетания LTR с RTL?
Что является принципиальным?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: Unicode и итерация по символам
От: пффф  
Дата: 22.01.23 13:52
Оценка:
Здравствуйте, Sinclair, Вы писали:

П>>Да, отображение и редактирование

S>Произвольного unicode-текста или можно чем-то пожертвовать? Эмоджи, залго, сочетания LTR с RTL?
S>Что является принципиальным?

Произвольный именно текст, эмоджи идут в жопу, LTR/RTL нужно, вперемешку — скорее да
Re[3]: Unicode и итерация по символам
От: Pzz Россия https://github.com/alexpevzner
Дата: 22.01.23 16:59
Оценка:
Здравствуйте, пффф, Вы писали:

П>Блин, а попроще никак? Мне бы для начала под винду только, остальное подождёт


for c := range str {
        . . .
}


Впрочем, это Go, не Си...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.