Как правильно сделать поддержку юникода в программе

2008-12-30 Thread Alexey Pechnikov
Hello!

Хорошо известный кроссплатформенный способ добавить в программу поддержку 
юникода - использовать 
библиотеку libicu. С ней все работает, но... весит это счастье более 10 
мегабайт. В то же время 
тикль, питон и проч. интерпретаторы имеют поддержку юникода, не используют эту 
либу и весят 
значительно меньше. Вопрос: как они это делают? Явно есть какое-то более легкое 
решение.

P.S. Собранный с поддержкой русского языка (с помощью libicu) tksqlite весит 
9,1 Мб - и это 
упакованный в starpack. Ну, положим, в дебиане libicu можно с собой не таскать, 
но как это не 
печально, существуют и другие дистрибутивы и платформы.

Best regards, Alexey.


--
To UNSUBSCRIBE, email to debian-russian-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org



Re: Как правильно сделать поддержку юникода в программе

2008-12-30 Thread Alexey Pechnikov
Hello!

В сообщении от Tuesday 30 December 2008 21:55:53 Eugene V. Lyubimkin написал(а):
> А сказать, что, дескать, моя программа хочет libicu, и тогда в нужный
> дистриб её положат, можно попробовать? Если твоя софтина окажется нужной и
> полезной, вряд ли пакетирование libicu станет главной проблемой для
> дистрибутивов.

Как выяснилось, собрать, к примеру, sqlite с libicu на отличном от дебиана 
дистрибутиве не совсем 
просто. Да и сам размер libicu убивает - многие из программ, прекрасно 
работающих с юникодом, весят 
в разы меньше! Опять же интересно распространение программы в независимом от 
дистрибутива виде - 
тиклевский старпак это обеспечивает, но мне не нравится размер программы в 9 Мб.

Best regards, Alexey.


--
To UNSUBSCRIBE, email to debian-russian-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org



Re: Как правильно сделать поддержку юникода в программе

2008-12-30 Thread Serhiy Storchaka
Alexey Pechnikov wrote:
> Хорошо известный кроссплатформенный способ добавить в программу поддержку
> юникода - использовать библиотеку libicu. С ней все работает, но... весит
> это счастье более 10 мегабайт. В то же время тикль, питон и проч.
> интерпретаторы имеют поддержку юникода, не используют эту либу и весят
> значительно меньше. Вопрос: как они это делают? Явно есть какое-то более
> легкое решение.
> 
> P.S. Собранный с поддержкой русского языка (с помощью libicu) tksqlite
> весит 9,1 Мб - и это упакованный в starpack. Ну, положим, в дебиане libicu
> можно с собой не таскать, но как это не печально, существуют и другие
> дистрибутивы и платформы.

ICU — это стрельба по воробьям межконтинентальной баллистической ракетой.
Библиотека, первоначально написанная для Java и потом портированная для C++
и C. Большинство функций вряд ли понадобятся (некоторые довольно
экзотические, как например запись чисел словами на разных языках).

Что имеется ввиду под поддержкой уникода? Обычно требуется только:
1) Унифицированное представление текста на разных языках. Обычно UCS2, UCS4
или UTF-8. Иногда используют wchar_t и/или мультибайтовые строки.
2) Ввод/вывод в разных кодировках. Достаточно iconv или recode. Тикль и
питон тащат свои таблицы перекодировки. Львиную долю тут занимают всякие
китайские и японские кодировки, если очень жмёт, то можно сэкономить.
3) Определение класса символа (буква, цифра, пробел и т. п.), преобразование
регистра. Для wchar_t есть стандартные локалезависимые функции в C99. Для
уникода можно взять нетяжёлую libunicode.
4) Чисто уникодные функции. Комбинированные символы, названия каждого
символа и т. п. Тут уже нужна специальная библиотека. И немаленькая.


-- 
To UNSUBSCRIBE, email to debian-russian-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org



Re: Как правильно сделать поддержку юникода в программе

2008-12-30 Thread Alexey Pechnikov
Hello!

> ICU — это стрельба по воробьям межконтинентальной баллистической ракетой.
> Библиотека, первоначально написанная для Java и потом портированная для C++
> и C. Большинство функций вряд ли понадобятся (некоторые довольно
> экзотические, как например запись чисел словами на разных языках).

Не знал таких подробностей. Немного поковыряв, удалось ICU скомпилить с 
эскулайт под линукс и 
виндоус, теперь в рассылке эскулайт периодически подсказываю, как это делается, 
а сам мечтаю 
избавиться от такого балласта. Эскулайтом я постепенно в своих проектах 
постгрес заменяю, нужные 
расширения написал (не много и нужно, в сущности - работа с ip-адресами, md5 
суммы для текстовой 
строки, для строки таблицы и целой таблицы, сжатие/распаковка данных, генерация 
uuid и т.п.), пора 
бы и "отбросить хвост" в виде libicu. Кстати, разработчик ГИС-модуля к sqlite 
использует iconv для 
перекодирования. А вот полнотекстовый поиск работает с юникодом через ICU.

> Что имеется ввиду под поддержкой уникода? Обычно требуется только:
> 1) Унифицированное представление текста на разных языках. Обычно UCS2, UCS4
> или UTF-8. Иногда используют wchar_t и/или мультибайтовые строки.

Попробую конкретизировать. Итак, юникод - UTF-8. Хотелось бы еще UTF16, хотя я 
ни разу его не 
использовал и не видел, чтобы кто-то использовал. Но движок sqlite имеет 
нативную поддержку UTF16, 
может пригодиться.

Требуется ввод/вывод  - смотрел примеры перекодирования через iconv, вроде 
устраивает.
Далее, нужно сравнение символов, сортировка строк, смена регистра. 

Вот что требуется от функций смены регистра:

** upper('ABC') -> 'abc'
** lower('abc') -> 'ABC'

** lower('I', 'en_us') -> 'i'
** lower('I', 'tr_tr') -> 'ı' (small dotless i)

Сравнение с шаблоном, как я понимаю, через вышеперечисленное пишется, но 
хотелось бы пример, чтобы 
грамотно реализовать функции LIKE и REGEXP - они и так медленные, писать надо 
аккуратно.


> 2) Ввод/вывод в разных кодировках. Достаточно iconv или recode. Тикль и
> питон тащат свои таблицы перекодировки. Львиную долю тут занимают всякие
> китайские и японские кодировки, если очень жмёт, то можно сэкономить.

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

> 3) Определение класса символа (буква, цифра, пробел и т. п.),
> преобразование регистра. Для wchar_t есть стандартные локалезависимые
> функции в C99. Для уникода можно взять нетяжёлую libunicode.

Наверное, мне это и надо, если с этими функциями можно выполнить преобразования 
вида 
lower('I', 'en_us') -> 'i'

> 4) Чисто уникодные функции. Комбинированные символы, названия каждого
> символа и т. п. Тут уже нужна специальная библиотека. И немаленькая.

Названия символов в движке СУБД знать не требуется. А что такое 
"комбинированные символы"?

P.S. Есть кроссплатформенный способ реализации - забиндить нужные функции из 
тикля (питона, etc.). 
Но, во-первых, для сравнения символов такой метод получается медленнее раза в 2 
- 4, чем через 
libicu. Во-вторых, иногда нужно вызвать sqlite просто из консоли и хотелось бы 
иметь встроенные 
функции. 

Best regards, Alexey.


--
To UNSUBSCRIBE, email to debian-russian-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org



Re: Как правильно сделать поддержку юникода в программе

2008-12-31 Thread Serhiy Storchaka
Alexey Pechnikov wrote:
> Попробую конкретизировать. Итак, юникод - UTF-8. Хотелось бы еще UTF16,
> хотя я ни разу его не использовал и не видел, чтобы кто-то использовал. Но
> движок sqlite имеет нативную поддержку UTF16, может пригодиться.

Ну значит UTF16 и следует использовать. Иначе ведь наверняка он будет
рассчитывать на 8-битовые строки, а значит поиск в UTF-8 будет работать не
так, как надо.

> Требуется ввод/вывод  - смотрел примеры перекодирования через iconv, вроде
> устраивает. Далее, нужно сравнение символов, сортировка строк, смена
> регистра.
> 
> Вот что требуется от функций смены регистра:
> 
> ** upper('ABC') -> 'abc'
> ** lower('abc') -> 'ABC'
> 
> ** lower('I', 'en_us') -> 'i'
> ** lower('I', 'tr_tr') -> 'ı' (small dotless i)
> 
> Сравнение с шаблоном, как я понимаю, через вышеперечисленное пишется, но
> хотелось бы пример, чтобы грамотно реализовать функции LIKE и REGEXP - они
> и так медленные, писать надо аккуратно.

LIKE и особенно REGEXP зависят от кодировки символов. Если есть уже в sqlite
поддержка UTF16, то и встроенные функции будут с ним работать как надо
(если sqlite будет знать, что это не 8 бит). Если использовать самому
библиотеку работы с регэкспами, то она должна быть рассчитана на уникод,
иначе ничего не получится.

В Linux представление wchar_t совпадает с уникодом (man unicode), поэтому
можно использовать towlower и т.п. В Windows вроде тоже (но только 16 бит),
на других платформах всё хуже. См. недавнее обсуждение в
fido7.ru.unix.prog. Вопрос, кстати, именно для той конференции.

Иначе довольно симпатичной выглядит небольшая библиотека libunicode.

> Названия символов в движке СУБД знать не требуется. А что такое
> "комбинированные символы"?

Уже ответили. Некоторые символы могут быть записаны комбинацией двух кодов
уникода — кода буквы и кода диакритического знака (ô = o + «шапочка»). Для
некоторых из них есть и собственный код, поэтому они могут быть записаны
двумя способами. Нужно канонизировать перед сравнением строк.

А ещё бывают «невидимые» символы. Например «мягкий перенос» (U+00AD). При
выводе не отображается, но может использоваться для указания возможности
переноса слова. При сравнении строк очевидно должен быть пропущен. Ещё
бывают символы, указывающие направление письма, и т. п. Всё это можно
игнорировать и решать проблемы по мере возникновения (но помнить, что они
будут).

> P.S. Есть кроссплатформенный способ реализации - забиндить нужные функции
> из тикля (питона, etc.).

Зависит от приложения. Если уже есть зависимость от какого-то большого
графического тулкита или скриптового языка, то в них уже есть работа с
уникодом.


-- 
To UNSUBSCRIBE, email to debian-russian-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org



Re: Как правильно сделать поддержку юникода в программе

2009-01-01 Thread Alexey Pechnikov
Hello!

Нашел модуль для работы с utf8
http://ioannis.mpsounds.net/blog/2007/12/19/sqlite-native-unicode-like-support/
регистро-независимая сортировка работает, за исключением буквы "ё". Видимо, 
из-за того, что эта 
буква может быть как составным, там и одним символом (операцией "снятия 
акцента" ё успешно 
превращается в е). Автор на письмо откликнулся, попробуем разобраться и 
поправить. 

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

А вот прямая ссылка на файлик
http://ioannis.mpsounds.net/blog/2007/12/19/sqlite-native-unicode-like-support/?dl=sqlite3_unicode.c

P.S. В принципе, можно таблицы символов в служебной таблице в БД хранить, тоже 
довольно интересный 
вариант.

Best regards, Alexey.


--
To UNSUBSCRIBE, email to debian-russian-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org



Re: Как правильно сделать поддержку юникода в программе

2009-01-01 Thread Serhiy Storchaka
Alexey Pechnikov wrote:
> Нашел модуль для работы с utf8
>
http://ioannis.mpsounds.net/blog/2007/12/19/sqlite-native-unicode-like-support/
> регистро-независимая сортировка работает, за исключением буквы "ё".
> Видимо, из-за того, что эта буква может быть как составным, там и одним
> символом (операцией "снятия акцента" ё успешно превращается в е). Автор на
> письмо откликнулся, попробуем разобраться и поправить.

Вообще-то сортировка локалезависима. Например в русском «Я» перед «Ь», в
украинском — наоборот. Можно сортировать по кодам символов уникода,
большинство русских букв расположены в порядке русского алфавита, но
буква «Ё» — отдельно. Поэтому такая сортировка не будет алфавитной.



-- 
To UNSUBSCRIBE, email to debian-russian-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org



Re: Как правильно сделать поддержку юникода в программе

2009-01-01 Thread Alexey Pechnikov
Hello!

В сообщении от Thursday 01 January 2009 16:30:14 Mikhail Gusarov написал(а):
>  SS> Вообще-то сортировка локалезависима.
>
> И вот после десятка-другого таких уточнений как раз и получим нечто,
> похожее на libicu :)

Тем не менее, интерпретатор тикля весит на порядок меньше, чем ICU. Так что как 
ни крути, а ICU есть 
монстр.

Best regards, Alexey.


--
To UNSUBSCRIBE, email to debian-russian-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org



Re: Как правильно сделать поддержку юникода в программе

2009-01-01 Thread Serhiy Storchaka
Alexey Pechnikov wrote:
> Тем не менее, интерпретатор тикля весит на порядок меньше, чем ICU. Так
> что как ни крути, а ICU есть монстр.

Тикль поддерживает уникод ограниченно. Только 16 бит, наверняка никаких
операций с комбинированными символами. Во многих случаях этого достаточно.


-- 
To UNSUBSCRIBE, email to debian-russian-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org



Re: Как правильно сделать поддержку юникода в программе

2009-01-01 Thread Serhiy Storchaka
Victor Wagner wrote:
> On 2009.01.01 at 18:59:58 +0200, Serhiy Storchaka wrote:
>> Тикль поддерживает уникод ограниченно. Только 16 бит, наверняка никаких
> 
> Что-то я там не припомню ограничения на 16 бит. Везде внутреннее
> представление - utf-8

man 3tcl encoding
> Strings in Tcl are encoded using 16-bit Unicode characters.

Формат файлов кодировок — 2-байтный уникод. Ещё где-то вроде было замечание
о UTF-8, мол 1-3 байта на символ.


-- 
To UNSUBSCRIBE, email to debian-russian-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org