Гуглопочта считает, что банк мне присылает уведомления на разных языках: английском, казахском и словацком.
Архив рубрики: english
Трудности перевода
Всё-таки в английском с его вагоном значений для каждого слова, не всегда легко.
Вот, скажем, есть фотография с местными птицами:
И как её подписать? Вот по-русски можно вообще не задумываясь написать «Синицы». Или, обчитавшись википедии — «Большие синицы». А по-английски? Одна птица — tit. Или даже great tit. А две? Great tits? Гугл, например, по такому запросу выдаёт не только синиц 🙂
Бэс и бейс
Как читать слово 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:
Ишь как англичанка гадит! Теперь, значит, Челябинск в Великобритании?
Многоязычное
За прошедшие сутки, как и почти в любой другой день, читал тексты и слушал речь на двух естественных языках — русском и английском — и держал в голове ещё кучу других: языков программирования да языков разметки. Как минимум, пришлось читать код на Perl, PHP, Bash и Ruby. Ну и, вроде, чё-то в браузерном отладчике смотрел — значит, ещё и HTML с CSS. И, наверное, JavaScript там же.
Два плюс семь — получается девять языков параллельно. Добавим LilyPond — будет десять. Это не вредно? 🙂
Указание языка в URL страниц в Open Journal Systems
Open Journal Systems — система управления электронными научными журналами — имеет одинаковые адреса страниц, написанных на разных языках. Посетитель, зашедший на сайт научного журнала, работающего на OJS, либо увидит страницу на языке по умолчанию либо, если раньше уже заходил и менял язык, на том, что выбрал. Кому-то такой подход нравится, кому-то — нет. На самом деле — вполне нормальная ситуация.
Тем не менее, возникла задача всё-таки получить возможность явно указать язык в адресе страниц. Переключение выбранного языка делается средствами самой OJS — достаточно зайти (то есть, выполнить GET-запрос) по адресу вида адрес-журнала/user/setLocale/локаль?source=путь/куда/идти/дальше, например, http://vestnik.susu.ru/cmi/user/setLocale/ru_RU?source=/cmi/issue/current — переход по этой ссылке приведёт к выведенному на русском языке оглавлению текущего выпуска серии «Вычислительная математика и информатика» Вестника Южно-Уральского государственного университета.
С одной стороны, всё украдено до нас ничего делать не надо — URL с указанием языка уже доступен. Но какой-то он длинный, неаккуратный. Хочется сделать покороче. Чтоб не лезть во внутренности OJS, можно исправить настройки сервера. Для случая, когда используется Apache, а адрес журнала имеет вид http://hostname/journal, достаточно добавить пару правил для mod_rewrite:
RewriteRule ^en(glish)?/(\w+)(/?.*)$ /$2/user/setLocale/en_US?source=/$2$3 [L]
RewriteRule ^ru(ssian)?/(\w+)(/?.*)$ /$2/user/setLocale/ru_RU?source=/$2$3 [L]
Это даст возможность использовать URL вида http://hostname/язык/journal/путь, где язык может быть как названием нужного языка, так и его двухбуквенным кодом. Для уже рассмотренной серии «Вестника ЮУрГУ» теперь можно применять такие ссылки:
- http://vestnik.susu.ru/english/cmi — первая страница журнала на английском языке,
- http://vestnik.susu.ru/en/cmi/issue/archive — список выпусков на английском языке,
- http://vestnik.susu.ru/russian/cmi/about/contact — контактная информация на русском языке,
- http://vestnik.susu.ru/ru/cmi/issue/current — текущий выпуск на русском языке.
Perl Debugger Cheatsheet
Как назвать дверь?
У универсалов всё, что открывается (кроме, разве что, капота) — это дверь. Как их при этом назвать так, чтоб было понятно — неясно. Ну с передней-то понятно — передняя дверь. А с задней? Какая задняя? Задняя пассажирская или задняя багажная? Так в универсале, особенно в высоком, любая дверь может быть пассажирской — мне во всех своих универсалах (а особенно в Пежо) доводилось ходить через все имеющиеся двери.
Вот в американском руководстве по ремонту и эксплуатации поступили просто и понятно: сдвижная дверь, предназначенная для пассажиров — slide door, а пара самых задних дверей — tailgate, то есть, хвостовые ворота. Всё понятно! 🙂