LINUX.ORG.RU

Написал статью «Как жить если у вас юникод»

 ,


5

4

Собственно, сабж. Статья про то самое, что мы с Eddy_Em не могли осилить в прежние времена. В этом году я это, внезапно, осилил. Ну и написал статью.

https://saahriktu.ru/pdf/kak_jit_esli_u_vas_yunikod.pdf

★★★★★

Ответ на: комментарий от bugfixer

Я больше скажу - мне бы очень было интересно посмотреть на эффективную реализацию без поддержки со стороны ядра…

Смотри исходники Erlang.

monk ★★★★★
()
Ответ на: комментарий от monk

Собственно, речь о том, что в юникоде нет адекватного способа посчитать буквы или получить первые N букв (например, для словаря нужны страницы с заголовками вида «{первые две буквы первого слова}..{первые две буквы последнего слова}» и легко можно получить вместо «af» что-то вроде «affi» или «aff».

monk ★★★★★
()
Ответ на: комментарий от monk

От того, что три буквы выведены лигатурой, их количество не должно уменьшатся.

Это ненастоящая лигатура. Для работы с устаревшими символами нужно применять нормализацию.

pasquale
()

В качестве бонуса перечислю два новшества Си, которые стали доступны в последнее время:
Наряду с префиксом 0x для шестнадцатеричных чисел появился префикс 0b для двоичных чисел

Могу ошибаться, но «в последнее время» в данном контексте — это как бы не C99…

hobbit ★★★★★
()
Ответ на: комментарий от cumvillain

Тема про юникод для программистов. Это несколько иное. Тут в C и C++ до недавнего времени было не так шоколадно.

Другое дело, что в 2023 году, говоря на эту тему, надо бы упомянуть std::u8string. Но он появился только в C++20, и как текущие компиляторы его поддерживают — вопрос очень интересный. И примеры его употребления, которые я видел, походили на лютейшее вырвиглазие, кутешники не зря в своё время сделали QString, в котором гарантируется работа с распакованным юникодом (для линукса - 32-разрядный).

hobbit ★★★★★
()
Ответ на: комментарий от no-such-file

При том, что ветка началась с того, что wstring не умеет считать буквы. В качестве решения кто-то предложил считать графемы, мол это «буквы». Я показываю, что считать графемы тоже не очень осмысленно.

monk ★★★★★
()
Ответ на: комментарий от pasquale

Это ненастоящая лигатура.

А как выглядит настоящая?

Для работы с устаревшими символами нужно применять нормализацию.

Какую? Обе, которые умеют разбивать лигатуры, из 2⁵ делают 25 и ещё портят строку по мелочи.

monk ★★★★★
()
Ответ на: комментарий от monk

тоже не очень осмысленно

Ещё раз для тупых, смысл в том, чтобы посчитать сколько знакомест занимает текст при отображении. Философские рассуждения о том, является ли лигатура самостоятельной «буквой» никого не интересуют.

ветка началась с того, что wstring не умеет считать буквы

С каких пор рожа является стала буквой?

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 2)
Ответ на: комментарий от monk

С буквами в wchar_t* всё OK. И уж для len() в Python'е это вообще не проблема. Тот пример выше иллюстрировал другое:

  • В юникоде есть составные из нескольких кодепоинтов глифы.
  • В юникоде есть и модификаторы, которые нужно отсеивать при подсчёте графем.

И вот эти вот моменты массив кодепоинтов сам по себе не решает. Но если каждый кодепоинт в нём соответствует конкретной букве, то проблем в этом случае, собственно, никаких и нет. Проблемы (которые, собственно, являются таковыми если нужно работать с рандомными юникодными строками и поддерживать 100% совместимость со всем юникодом) возникают именно из-за составных глифов и модификаторов.

saahriktu ★★★★★
() автор топика
Ответ на: комментарий от alex1101

качать компилятор Паскаля

Компиляторы и интерпретаторы и так должны быть установлены. Это же первое дело после установки дистрибутива доустановить интерпретаторы и компиляторы.

Да даже если и докачать. Зачем вообще нужен такой дистрибутив если у юзера проблемы с установкой его пакетов?

saahriktu ★★★★★
() автор топика
Последнее исправление: saahriktu (всего исправлений: 1)
Ответ на: комментарий от saahriktu

Проблемы (которые, собственно, являются таковыми если нужно работать с рандомными юникодными строками и поддерживать 100% совместимость со всем юникодом) возникают именно из-за составных глифов и модификаторов.

Я именно про это и пишу. В юникоде, фактически, с одной стороны, ликвидировали понятие «буквы», так как местами один кодпоинт является несколькими буквами, местами несколько кодпоинтов собираются в одну букву, причём, в отличие от графем, общего правила здесь нет.

В юникоде есть отдельные символы для для i, і, i, 𝚒, 𝗶, 𝗂, 𝔦, ⅰ или ; и ; и при этом не различаются китайские иероглифы и кандзи. Юникод позволяет изменять направление ввода внутри строки для любых символов…

monk ★★★★★
()
Ответ на: комментарий от saahriktu

Проблемы (которые, собственно, являются таковыми если нужно работать с рандомными юникодными строками и поддерживать 100% совместимость со всем юникодом) возникают именно из-за составных глифов и модификаторов.

Проблема у тебя в том что ты считаешь юникодную строку массивом вместо потока байт.

cumvillain
()
Ответ на: комментарий от cumvillain

Проблема у тебя в том что ты считаешь юникодную строку массивом вместо потока байт.

Проблема в том, что с этим потоком байт, кроме как вывести на экран, почти ничего сделать нельзя.

monk ★★★★★
()
Ответ на: комментарий от monk

Ещё одна проблема юникода: сколько байтов надо зарезервировать для назначения платежа, если по закону в нём может быть не более 210 символов? Как посчитать?

monk ★★★★★
()
Ответ на: комментарий от no-such-file

А зачем это знать?

Я же тебе привёл пример. Нужен, например, индекс по тэгам с кнопками типа «Ab..Af», «Af..Al», …, «Ba..Fa», …

А если «буквой» считать лигатуру, то будет «Аffi..Al» а для арабского может вообще попасть ﷺ. Буква, понимаешь, такая.

monk ★★★★★
()
Ответ на: комментарий от monk

Какую? И как мне это позволит из «affine» (61ef ac83 6e65) получить «af» (6166)?

const char *str = "залупа коня";
const char *g1, *g2;
size_t &g1_len, &g2_len;

grapheme(str, 1, &g1, &g1_len);
grapheme(str, 2, &g2, &g2_len);

И вот у тебя есть две графемы. То, что в юникоде соотвествует «читаемой букве».

cumvillain
()
Ответ на: комментарий от cumvillain

И вот у тебя есть две графемы. То, что в юникоде соотвествует «читаемой букве».

В том-то и дело, что графема не буква. Там вообще может быть целая фраза. Потому что лигатуры являются допустимой частью юникода.

monk ★★★★★
()
Ответ на: комментарий от monk

Не, пажжи. Вот нам цитата из юникода:

This annex describes guidelines for determining default segmentation boundaries between certain significant text elements: grapheme clusters (“user-perceived characters”), words, and sentences. For line boundaries, see [UAX14] .

grapheme cluster («user-perceived characters»). То есть, это должно быть минимальной человекочитаемой единицей.

cumvillain
()
Ответ на: комментарий от monk

Нужен, например, индекс

И что? Тебя наверное не смущает что есть заглавные буквы и строчные и для индекса это тоже важно. Очевидно чтобы делать индекс нужно данные нормализовать так, как требует логика индекса. При чём тут именно юникод вообще не понятно, проблема возникает независимо от кодировки.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

В любой другой кодировке можно выделить буквы. Если бы Юникод делался весь по принципу кодпоинт = буква, в нëм тоже 90% проблем бы не было.

Но воткнули модификаторы и лигатуры, хотя по-нормальному это всё должно быть уровнем выше (странно, что весь TeX не утрамбовали).

monk ★★★★★
()