Как найти путь к файлу в кодировке текста, используемой PosteRazor?
PosteRazor использует явно устаревший графический интерфейс, который не способен правильно отображать мои имена файлов:
Для удобства я хочу иметь возможность открывать любой файл в PosteRazor, копируя и вставляя его путь из Nautilus. Это работает в других приложениях, но, к сожалению, PosteRazor не может понять путь:
Как я могу преобразовать путь, который Nautilus генерирует в текстовую кодировку, совместимую с PosteRazor?
Пакет Ubuntu для PosteRazor перечисляет зависимость от Fast Light Toolkit (FLTK). Документация его программиста по Unicode выглядит так, как будто она может содержать необходимую информацию для ответа на мой вопрос, но я не уверен, как это интерпретировать.
подробности
Некоторые образцы контента:
Путь, как он изначально появляется в Nautilus:
/home/ak/café/north-america.jpg
Тот же путь, что и в родном виде, появляется в PosteRazor:
PosteRazor после копирования пути из PosteRazor и вставки его в PosteRazor:
Путь скопирован из PosteRazor и вставлен в Chromium:
/home/ak/café/norrth-america.jpg
Путь скопирован из PosteRazor и вставлен в Chromium, а затем скопирован из Chromium и вставлен обратно в PosteRazor:
Содержимое буфера обмена после копирования из Chromium:
$ xclip -out -selection clipboard -target TARGETS TIMESTAMP TARGETS MULTIPLE SAVE_TARGETS COMPOUND_TEXT STRING TEXT UTF8_STRING text/plain $ xclip -out -selection clipboard -target STRING | hexdump -C 00000000 2f 68 6f 6d 65 2f 61 6b 2f 63 61 66 c3 a9 2f 6e |/home/ak/caf../n| 00000010 6f 72 72 74 68 2d 61 6d 65 72 69 63 61 2e 6a 70 |orrth-america.jp| 00000020 67 |g| 00000021 $ xclip -out -selection clipboard -target UTF8_STRING | hexdump -C 00000000 2f 68 6f 6d 65 2f 61 6b 2f 63 61 66 c3 a9 2f 6e |/home/ak/caf../n| 00000010 6f 72 72 74 68 2d 61 6d 65 72 69 63 61 2e 6a 70 |orrth-america.jp| 00000020 67 |g| 00000021 $ xclip -out -selection clipboard -target text/plain | hexdump -C 00000000 2f 68 6f 6d 65 2f 61 6b 2f 63 61 66 c3 a9 2f 6e |/home/ak/caf../n| 00000010 6f 72 72 74 68 2d 61 6d 65 72 69 63 61 2e 6a 70 |orrth-america.jp| 00000020 67 |g| 00000021
Путь, скопированный из PosteRazor и вставленный в терминал GNOME:
Путь, скопированный из PosteRazor и вставленный в терминал GNOME, затем скопированный из терминала GNOME и вставленный обратно в PosteRazor:
Содержимое буфера обмена после копирования из терминала GNOME:
$ xclip -out -selection clipboard -target TARGETS TIMESTAMP TARGETS MULTIPLE SAVE_TARGETS UTF8_STRING COMPOUND_TEXT TEXT STRING text/plain;charset=utf-8 text/plain $ xclip -out -selection clipboard -target STRING | hexdump -C 00000000 2f 68 6f 6d 65 2f 61 6b 2f 63 61 66 e9 2f 6e 6f |/home/ak/caf./no| 00000010 72 74 68 2d 61 6d 65 72 69 63 61 2e 6a 70 67 |rth-america.jpg| 0000001f $ xclip -out -selection clipboard -target UTF8_STRING | hexdump -C 00000000 2f 68 6f 6d 65 2f 61 6b 2f 63 61 66 c3 a9 2f 6e |/home/ak/caf../n| 00000010 6f 72 74 68 2d 61 6d 65 72 69 63 61 2e 6a 70 67 |orth-america.jpg| 00000020 $ xclip -out -selection clipboard -target 'text/plain' | hexdump -C 00000000 2f 68 6f 6d 65 2f 61 6b 2f 63 61 66 5c 75 30 30 |/home/ak/caf\u00| 00000010 65 39 2f 6e 6f 72 74 68 2d 61 6d 65 72 69 63 61 |e9/north-america| 00000020 2e 6a 70 67 |.jpg| 00000024 $ xclip -out -selection clipboard -target 'text/plain;charset=utf-8' | hexdump -C 00000000 2f 68 6f 6d 65 2f 61 6b 2f 63 61 66 c3 a9 2f 6e |/home/ak/caf../n| 00000010 6f 72 74 68 2d 61 6d 65 72 69 63 61 2e 6a 70 67 |orth-america.jpg| 00000020
1 ответ
Обновление: Следующая команда может быть использована:
xclip -out -selection clipboard -target STRING | iconv - из кода ISO-8859-15 - в код UTF-8 | Буфер обмена xclip -in -selection
Для объяснения прочитайте полный ответ.
Чтобы полностью понять ответ, вы должны понимать кодовые точки Unicode и кодировку Unicode.
Ниже приведены краткие определения и объяснения необходимых терминов, но я рекомендую вам прочитать о них из источников, упомянутых в конце ответа.
Unicode Code Space: диапазон целых чисел от 0 до 10FFFF 16.
Кодовые точки Unicode: любое значение в кодовом пространстве Unicode. Кодовая точка соответствует символу, хотя не все кодовые точки назначаются кодированным символам.
UTF-8: UTF-8 (8-битный формат преобразования UCS) - это кодирование с переменной шириной, которое может представлять каждый символ в наборе символов Unicode. UCS обозначает универсальный набор символов.
Первые 128 символов (US-ASCII) требуют одного байта. Следующим 1920 символам нужно два байта для кодирования. Это охватывает почти все алфавиты латинского происхождения, а также алфавиты греческого, кириллического, коптского, армянского, иврита, арабского, сирийского и танского, а также сочетания диакритических знаков.
Это указывает на то, что персонаж
é
что вызывает проблемы занимает два байта для кодирования в UTF-8. Мы проверим это с помощью некоторых команд.ISO / IEC 8859-15: 8-битные однобайтовые наборы кодированных графических символов.
Чтобы проверить, я сделал каталог /home/green/Pictures/café/
,
После копирования местоположения из nautilus
, выходные данные команд были следующими:
Команда № 1:
Буфер обмена $ xclip -out -selection -target STRING | hexdump -C 00000000 2f 68 6f 6d 65 2f 67 72 65 65 6e 2f 50 69 63 74 |/home/green/Pict| 00000010 75 72 65 73 2f 63 61 66 e9 2f |ures/caf./| 0000001a
Обратите внимание, что кодировка café
является 63 61 66 e9
, что хорошо, так как кодовая точка Unicode U+00E9 представляет {LATIN SMALL LETTER E WITH ACUTE}
или же é
,
Команда № 2:
Буфер обмена $ xclip -out -selection -ttarget UTF8_STRING | hexdump -C 00000000 2f 68 6f 6d 65 2f 67 72 65 65 6e 2f 50 69 63 74 |/home/green/Pict| 00000010 75 72 65 73 2f 63 61 66 c3 a9 2f |ures/caf../| 0000001b
В приведенном выше выводе, café
кодируется как 63 61 66 c3 a9
, Это тоже хорошо, потому что кодировка UTF-8 кодовой точки U+00E9 (соответствует é
) является \xC3\xA9
(\x
используется для представления того, что следующие символы являются шестнадцатеричными числами).
\xC3
представляет 1 байт и так \xA9
, Таким образом, UTF-8 нужно 2 байта для представления é
,
После копирования того же текста из PosteRazor
выходы команд были:
Команда № 1:
Буфер обмена $ xclip -out -selection -target STRING | hexdump -C 00000000 2f 68 6f 6d 65 2f 67 72 65 65 6e 2f 50 69 63 74 |/home/green/Pict| 00000010 75 72 65 73 2f 63 61 66 c3 a9 2f |ures/caf../| 0000001b
Очевидно, что кодовые точки Unicode перепутаны. Теперь у нас есть две кодовые точки (c3
а также a9
) где должен быть только один (e9
).
Неудивительно, что две кодовые точки, т.е. U+00C3
а также U+00A9
стоять за {LATIN CAPITAL LETTER A WITH TILDE}
А ТАКЖЕ {COPYRIGHT SIGN}
что мы видели в PosteRazor
,
Команда № 2:
Буфер обмена $ xclip -out -selection -ttarget UTF8_STRING | hexdump -C 00000000 2f 68 6f 6d 65 2f 67 72 65 65 6e 2f 50 69 63 74 |/home/green/Pict| 00000010 75 72 65 73 2f 63 61 66 c3 a9 2f |ures/caf../| 0000001b
Вывод этой команды, похоже, остался неизменным, но есть небольшая разница.
В предыдущем выводе \xc3\xa9
образуется один символ, тогда как сейчас \xc3
формирует одного персонажа самостоятельно и \xa9
образует другого персонажа (которые Ã
а также ©
соответственно).
Теперь мы знаем, что происходит, но как это происходит? Чтобы смоделировать то же самое, мы будем использовать Python. Я использую Python 3.3.0 здесь.
>>> импорт unicodedata >>> a = u'/home/green/Pictures/cafe' >>> а "/ Дом / зеленый / Фотографии / кафе" >>> a = a.encode('utf-8') >>> а б '/ дом / зеленый / Фотографии / кафе \xc3\xA9' >>> a = a.decode('iso-8859-15') >>> а '/ Дом / зеленый / Фотография / Каф ©' >>> a = a.encode('utf-8') >>> а б '/ дом / зеленый / Фотографии / кафе \xc3\x83\xc2\xA9'
Вы можете видеть, что если мы сначала закодируем строку, используя UTF-8, а затем декодируем, используя ISO-8859-15, то мы получим ту же строку, которую мы получаем при использовании PosteRazor
,
Теперь обратите внимание на следующий код. Здесь мы также скопировали и вставили местоположение из nautilus:
>>> z = u '/ home / green / Pictures / cafe' >>> з "/ Дом / зеленый / Фотографии / кафе" >>> z = z.encode('iso-8859-15') >>> з б '/ дом / зеленый / Фотографии / кафе \ xE9' >>> z = z.decode('iso-8859-15') >>> з "/ Дом / зеленый / Фотографии / кафе"
Если бы мы изначально закодировали строку с использованием ISO-8859-15, мы бы получили идеальный результат.
Обратите внимание, что \xe9
это кодировка для é
в ISO-8859-15, который, по-видимому, нуждается в одном байте. Это то же самое, что и кодовая точка Unicode U+00E9, которая при кодировании в UTF-8 требует 2 байта и представлена \xc3\xa9
,
Теперь, когда мы знаем, что и как все происходит, как мы можем это исправить? Ну, вы можете либо преобразовать пути в набор символов ISO-8859-15, либо вы можете просто использовать графический интерфейс для выбора файлов.
Источники и дополнительная информация:
- Unicode 6.2.0 PDF - часть 3.4: символы и кодировка
- Юникод Глоссарий
- Википедия - UTF-8
- * Википедия - Список символов Юникода
- UTF-8 Полный список персонажей
- Википедия - ИСО / МЭК 8859-15
- Полный список символов ISO 8859-15
- StackOverflow - Ответ на "php to rtf, é становится Ã ©"
- * StackOverflow - Расшифровка двойного кодирования utf8 в Python