Архив рубрики: язык

Compose не работает в musescore

Для того, чтоб изредка набрать буквы соседних языков (рәхим итәгеҙ!) достаточно настроить нужные последовательности для клавиши Compose и пользоваться ими. Но такой фокус не всегда удаётся: например, нотный редактор musescore (во всяком случае, в версии 2.0.2) как-то по-своему обрабатывает клавиатурные события и при нажатии клавиши Compose сразу же отображает ?!, воспринимая следующие клавиши как совершенно обычные. Поэтому при попытке ввести i десятеричное получается ?!ии. Получается, что в musescore нельзя ни дореволюціонные тексты вводить, ни украинские.

Самый простой выход в такой ситуации — поставить украинскую раскладку.

Трудности перевода

Всё-таки в английском с его вагоном значений для каждого слова, не всегда легко.

Вот, скажем, есть фотография с местными птицами:

Синицы

И как её подписать? Вот по-русски можно вообще не задумываясь написать «Синицы». Или, обчитавшись википедии — «Большие синицы». А по-английски? Одна птица — tit. Или даже great tit. А две? Great tits? Гугл, например, по такому запросу выдаёт не только синиц 🙂

Из одной бочки разливали

Как и ожидалось, Open Conference Systems, якобы не имеющая русской локализации, при должном применении напильника вполне способна использовать великий и могучий. В каталоге lib/pkp даже можно найти русские локализационные XML-файлы. Вообще весь этот каталог lib/pkp — общий и для OCS, и для OJS, что видно по гитхабу. Правда, в свежей версии Open Journal Systems переводов всё-таки побольше. Похоже, OCS, как не особо активно развиваемый продукт, содержит в себе копию lib/php трёхлетней давности, во всяком случае файлы lib/php/locale/ru_RU/*.xml — как раз 2012 года. Надо провести эксперимент — подсунуть в древнюю OCS 2.3 переводы из свежей OJS 2.4.7-1 — скорее всего, хуже не будет. Я пока заметил только один недостаток, мешающий тупо скопировать локализационные файлы: “User Home” переведено как «Мои журналы» — как-то неправильно показывать такое на сайте конференции.

Кстати, коллеги, кто-нибудь пробовал использовать Open Conference Systems для создания сайтов конференций? WordPress и mojowka для этого плохо подходят (хотя можно и с ними — я так делал) — хочется всё-таки использовать специализированное решение, избежав при этом танцев по граблям.

Бэс и бейс

bass

Как читать слово bass? Только сейчас узнал, что есть разные варианты и от того, как произнесёшь, зависит смысл:

[bæs] — это всего лишь окунь. Или липа и всякие связанные слова: лыко, луб, мочало (а как англоговорящие всё это различают?)

А вот бас, а также прилагательные басовый и низкий — это [beɪs].

Karta ne po-russki

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

Для того, чтоб иметь контроль над внешним видом подложки, не зависеть от размещающих тайлы (квадратные растровые фрагменты карт) сторонних сервисов, и не платить им денег в конце концов, тайлы генерируются из геоданных OpenStreetMap самостоятельно. OpenStreetMap для любого объекта может содержать множество имён — это и то, что хранится с ключом name — имя вообще, и int_name — международное имя, и куча имён с ключами вида name:ru, name:en, name:что_попало. Если делать тайлы с помощью TileMill, а свой стиль создавать на основе OSM Bright, то доступно только одно имя — name, однако в настройках сопоставления для imposm можно выбрать нужный язык — по умолчанию эта строка в файле imposm-mapping.py закомментирована:

set_default_name_type(LocalizedName(['name:en', 'int_name', 'name']))

Запускаем импорт, английские имена попадают в базу… Однако английских имён мало, сильно меньше, чем объектов с именами, записанными кириллицей.

Выхода из этой ситуации два — правильный и быстрый.
Правильный заключается в аккуратном переводе имён в OSM — слишком долго, да и неохота руками ковыряться.
Быстрый способ — не трогать OSM, а имена транслитерировать локально, в своём экземпляре базы данных. Так и поступим: создадим функцию транслитерации (прообраз подсмотрел на sql.ru) и выполним кучу UPDATE, вызывающих эту функцию. Мне, как перловому программисту, больше был симпатичен вариант с написанием перловой функции внутри PostgreSQL, но сразу такой вариант у меня не заработал, а разбираться было лень.

Итак, скармливаем постгресу такой код:

CREATE OR REPLACE FUNCTION ru_translit(p_string character varying)
  RETURNS character varying AS
$BODY$
-- Transliteration of Cyrillic letters
select
replace(
  replace(
    replace(
      replace(
        replace(
          replace(
            replace(
              replace(
                replace(
                  replace(
                    replace(
                      replace(
                        replace(
                          replace(
                            replace(
                              replace(
                                replace(
                                  replace(
                                    replace(
                                      replace(
                                        replace(
                                          replace(
                                            replace(
                                              replace(
                                                translate(
                                                  $1, 
                                                  'АБВГДЕЗИЙКЛМНОПРСТУФЫЭабвгдезийклмнопрстуфыэ',
                                                  'ABVGDEZIYKLMNOPRSTUFYEabvgdeziyklmnoprstufye'
                                                ),
                                              'ё', 'yo'),
                                            'ж', 'zh'),
                                          'х', 'kh'),
                                        'ц', 'ts'),
                                      'ч', 'ch'),
                                    'ш', 'sh'),
                                  'щ', 'shch'),
                                'ъ', ''),
                              'ь', ''),
                            'э', 'e'),
                          'ю', 'yu'),
                        'я', 'ya'),
                      'Ё', 'Yo'),
                    'Ж', 'Zh'),
                  'Х', 'Kh'),
                'Ц', 'Ts'),
              'Ч', 'Ch'),
            'Ш', 'Sh'),
          'Щ', 'Shch'),
        'Ъ', ''),
      'Ь', ''),
    'Э', 'E'),
  'Ю', 'Yu'),
'Я', 'Ya');
$BODY$
  LANGUAGE sql IMMUTABLE
  COST 100;

UPDATE osm_admin            SET name=ru_translit(name);
UPDATE osm_aeroways         SET name=ru_translit(name);
UPDATE osm_amenities        SET name=ru_translit(name);
UPDATE osm_barrierpoints    SET name=ru_translit(name);
UPDATE osm_barrierways      SET name=ru_translit(name);
UPDATE osm_buildings        SET name=ru_translit(name);
UPDATE osm_landusages       SET name=ru_translit(name);
UPDATE osm_landusages_gen0  SET name=ru_translit(name);
UPDATE osm_landusages_gen1  SET name=ru_translit(name);
UPDATE osm_mainroads        SET name=ru_translit(name);
UPDATE osm_mainroads_gen0   SET name=ru_translit(name);
UPDATE osm_mainroads_gen1   SET name=ru_translit(name);
UPDATE osm_minorroads       SET name=ru_translit(name);
UPDATE osm_motorways        SET name=ru_translit(name);
UPDATE osm_motorways_gen0   SET name=ru_translit(name);
UPDATE osm_motorways_gen1   SET name=ru_translit(name);
UPDATE osm_places           SET name=ru_translit(name);
UPDATE osm_railways         SET name=ru_translit(name);
UPDATE osm_railways_gen0    SET name=ru_translit(name);
UPDATE osm_railways_gen1    SET name=ru_translit(name);
UPDATE osm_transport_points SET name=ru_translit(name);
UPDATE osm_waterareas       SET name=ru_translit(name);
UPDATE osm_waterareas_gen0  SET name=ru_translit(name);
UPDATE osm_waterareas_gen1  SET name=ru_translit(name);
UPDATE osm_waterways        SET name=ru_translit(name);

Если мы добавляли номера домов на карту — транслитерируем и их заодно:

UPDATE osm_buildings SET "addr:housenumber"=ru_translit("addr:housenumber");

После чего можно запускать отрисовку своих тайлов — кириллицы там уже не будет.

Карта без кириллицы

Где находится Chelyabinsk?

Зашёл недавно в магазин за хозтоварами, расплатился карточкой — в отчёте интернет-банка написано, что место совершения транзакции — Соединённое королевство, Chelyabinsk:
Соединённое королевство, Chelyabinsk

Ишь как англичанка гадит! Теперь, значит, Челябинск в Великобритании?

Многоязычное

За прошедшие сутки, как и почти в любой другой день, читал тексты и слушал речь на двух естественных языках — русском и английском — и держал в голове ещё кучу других: языков программирования да языков разметки. Как минимум, пришлось читать код на Perl, PHP, Bash и Ruby. Ну и, вроде, чё-то в браузерном отладчике смотрел — значит, ещё и HTML с CSS. И, наверное, JavaScript там же.

Два плюс семь — получается девять языков параллельно. Добавим LilyPond — будет десять. Это не вредно? 🙂

Собственные переводы интерфейса OJS

Open Journal Systems — многоязычная система: многие её части могут быть переведены на разные языки. Не все, конечно: например, в материалах статей некоторые поля по странной прихоти разработчиков (или просто по невнимательности) остались одноязычными и добавить в них возможность правильно хранить данные на нескольких языках — не самая простая задача: я, например, так её и не завершил. В версиях 2.4.* нормальной многоязычности статей не будет — возможно, такое положение и объясняет тот факт, что в России OJS не особо популярна — она без применения напильника непригодна даже для тех журналов, где надо всего лишь продублировать имя русского автора статьи латинскими буквами.

С переводом интерфейса дела обстоят чуть получше: переведено может быть почти всё. Но и тут не всё гладко: вместо gettext применяется другой механизм локализации, где ключами служат не фразы на естественном языке (например, английском), а строки вида where.what.someItem. Переводы хранятся в XML-файлах, раскиданных по дереву каталогов. Впрочем, бо́льшая их часть сосредоточена в locale/ и lib/pkp/locale.

Есть два пути внедрения своих собственных переводов: первый, очевидный — отредактировать системные XML-файлы с переводами, плох тем, что при первом же обновлении OJS собственные переводы могут пропасть или вызвать конфликт слияния, если обновление проводится через git. Другой, более правильный — использовать плагин Custom Locale: он позволяет заменить системные переводы своими, не трогая системные файлы. Для того, чтоб заменить какой-либо фрагмент, надо знать ключ, а также файл, где перевод определён. Процесс замены переводов получается таким: сначала ищем, где и как определён нужный текст, затем идём на http://some-ojs-site/journal_name/manager/plugin/generic/customlocaleplugin/edit/ru_RU (если меняем русский текст), ищем в увиденном списке нужный файл, затем пытаемся найти в нём нужный ключ. Поиск там, вроде, есть, но, во-первых, ищет только в пределах текущего файла и умеет искать только точное соответствие с ключом — ничего более. Понятно, что такой интерфейс не нужен: лучше обходиться без него. Плагин хранит изменённые переводы в виде XML-файлов, которые складывает в public/journals/journal_id/customLocale/locale/path, где journal_id — номер журнала, locale — язык в виде язык_СТРАНА, например en_US — американский английский, а path — путь к заменяемым XML-файлам относительно каталога, где установлена OJS.

Пример: некий файл public/journals/1/customLocale/ru_RU/lib/pkp/locale/ru_RU/common.xml заменяет строки из файла lib/pkp/locale/ru_RU/common.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE locale SYSTEM "../../../../../../../../../lib/pkp/dtd/locale.dtd">
<locale name="ru_RU">
	<message key="navigation.about">О журнале</message>
	<message key="navigation.setup">Настройка журнала</message>
	<message key="common.notApplicableShort"> </message>
</locale>

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