LINUX.ORG.RU

Одна code point (или последовательность) == одна графема

 , ,


0

2

Здрасьте. Чтобы не было путаницы в терминологии - под графемой понимаю что-то рисуемое на экране, занимаемое ровно одно знакоместо. Нужен алгоритм, который принимает на вход utf-8 строку и выдаёт на выходе число, которое равно количеству знакомест, которые занимает данная строка будучи отрисованной в терминале.

Но тут подстава со всякими управляющими символами, например Tab, котороый займет некоторое число знакомест, лазить в кишках terminfo для определения этого числа я точно не хочу. Решил поступить проще - итерироваться по символам и проверять является ли символ управляющим и если да, то менять его на пробел. И вот здесь встает вопрос - есть ли управляющие символы выше ASCII диапазона, которые могуть выдать что-то в терминал занимающее более одного знакоместа? Т.е. речь идёт о том, что делать ли std::iscntrl(char_sym, get_locale()) напрямую или конвертить предварительно всю последовательность в wchar_t и уже потом тестить. Естественно, что первое проще, а может второе и вовсе смысла не имеет. Управляющие символы там точно есть (U+2028, например), но рисуется в терминале одним знакоместом.

Я уже почти созрел до того, чтобы закрыть для себя вопрос юникода навсегда и остановиться лишь на в ASCII в софте, по крайней мере до момента, пока не появится адекватная либа, а не ICU. Была зыбкая надежда на boost.locale, но оказалось, что тот же U+2028 она не считет управляющим (тогда как локаль созданная дефолтными с++ средствами считает)

    wchar_t w = L'\u2028';
    cout << std::boolalpha 
        << std::iscntrl(w, boost::locale::generator()("en_US.UTF-8")) << endl
        << std::iscntrl(w, std::locale("en_US.UTF-8")) << endl;

$ ./a.out
false
true

В общем вопросы к ней появились.

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

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

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

Конечно буду на нормальном аски, как и множество других адекватных прогеров. А ты, хомяк, будешь пользоваться этими поделками и будешь ограничен лишь аски набором, т.к. вертели мы на одном месте такой юникод вместе со всем комитетом.

Вон, юникод не пускают даже в С/С++ исходники, только базовый символы из ASCII. Достандартизировались, кусок коричневого непотребного ненужно.

kvpfs ★★
() автор топика

Я уже почти созрел до того, чтобы закрыть для себя вопрос юникода навсегда и остановиться лишь на в ASCII в софте, по крайней мере до момента, пока не появится адекватная либа

С какого перепуга что то появиться ? Сначала картельным сговором мнимого свч чсв вытеснить дистрибутив что бы его как следует не за донатили и не подняли человека до уровня ричарда , а потом пенять на лапти ? Или как ? Дело в том что такие библиотеки получаются сложнейшими меинфреимовыми билдами так что сумеешь ли ты с ними совладать уже проблемы твой и сообщества вошедшего в сговор начударивать эту библиотеку киркой

anonymous
()

считай составные символы как отдельные, больше знакомест - не меньше.

deep-purple ★★★★★
()
Ответ на: комментарий от kvpfs

Безграмотно и наивно, извини - больше нечего сказать. Почитай стандарт, там даже есть примеры и картинки, сразу и кругозор расширишь за рамки «условной й», и станет понятно почему предлагаемый тобой обрубок работать не будет.

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

Херня какая-то. Для начала — Юникод вообще не про «знакоместа» и «ширину символа». Пока ты этого не поймёшь, будешь страдать.

Для начала сам вопросе разберись. Юникод для азиатских код поинтов назначает ширину (Wide, Narrow, Fullwidth, Halfwidth, etc) http://unicode.org/reports/tr11/#Adding

kvpfs ★★
() автор топика

Видимо я в окончательном замешательстве. Подумал - ну ладно, пусть через костыли wcwidth() ширину символа я таки узнаю, но тут меня жда эпический фейл - есть такой code point из Гуджарати алфавита, занимает два места, но

assert(wcwidth((wchar_t)0xa94) == -1); // assert will never fire

Гугление ничего не говорит о возможности запросить ширину через ICU.

Всё, успехов всем любителям Юникода. Конечно, может быть сгодится для чего нибудь неответсвенного, но уж точно для рисования таблиц вот это вот недоразумение не подходит.

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

Проверил бы, прежде чем фигню молоть.

echo $'WTF\nWTF'
А то фиксированное, фиксированное. Вертели они твоё фиксированное

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

Ты и по вечерам упарываешься? Широкий символ занимает две ячейки фиксированного размера. От шрифта не зависит.

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

ઔ вот тебе не широкий символ на 2 знакоместа, знакомьтесь юникод. И да не 2, а 1,5, по крайней мере в части терминалов

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

ઔ вот тебе не широкий символ на 2 знакоместа, знакомьтесь юникод.

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

И да не 2, а 1,5, по крайней мере в части терминалов

Нет таких терминалов, разупорись.

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

Вон, юникод не пускают даже в С/С++ исходники, только базовый символы из ASCII. Достандартизировались, кусок коричневого непотребного ненужно.

УМВР

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

Нет таких терминалов, разупорись.

В гноме частично работает. Налезает на следующий знак. Если два раза подряд поставить, то занимает три знакоместа.

PS после топика стал уважать гном-терминал. Интересно, во всех терминалах такая шикарная поддержка юникода?

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

Это баг, а не фича. Терминалы думают, что ширина символа ઔ — одна ячейка, потому что в нынешней версии Юникода он не считается широким. Но глиф в одну ячейку не умещается, и при отрисовке возникают разные артефакты из-за наложения глифов.

Примерно то же самое бывает, если в ячейку поместить широкий иероглиф, а в следующую — другой символ:

echo $'猫\bx'

В зависимости от терминала, либо x перекрывает правую половину 猫, либо видно только x, либо только 猫. Это не фича, просто неопределённое поведение.

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

А зачем шрифты его широко рисуют тогда? пусть рисуют в одну ячейку, смотреться это будет так себе, но это другой вопрос уже.

Ещё пока читал, порадовали символы с неопределённой шириной, ширина которых завист от контекста. Всё это какой-то адовый ад.

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

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

В техническом комитете Юникода в основном американцы, они индийскими алфавитами в терминале не пользуются. А самим индийцам просто пофиг, полагаю.

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

А зачем шрифты его широко рисуют тогда? пусть рисуют в одну ячейку, смотреться это будет так себе, но это другой вопрос уже.

Нет, надо выкинуть нах терминальные шрифты туда-же, куда и ASCII, а терминалы перевести на вывод в HTML: нужен текст для последующего грепа - на здоровье, нужны таблички - пожалуйста

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

И кнопку лайк от фейсбука прямо в стандарт добавить.

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

Ну если два подряд поставить, то влезают ровно в 3 символа (и следующий уже четвёртым идёт).

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

Умершие языки как раз нельзя вычищать. Они представляют историческую и научную ценность. Представьте что вы учёный-лингвист работающий над каким-нибудь «умершим» древнешумерским или древнеегипетским. Ваши действия?

cobold ★★★★★
()
Последнее исправление: cobold (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.