Копирование кириллического текста из Matlab в LibreOffice Writer

Автор strekoza, 21 ноября 2015, 22:11:42

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

strekoza

Как Matlab, так и LibreOffice Writer, запускаю с локалями по умолчанию (т.е. UTF-8, без настройки окружения вроде LANG=ru_RU.CP1251 и т.п.).
M-файл сохранен в кодировке UTF-8.
LibreOffice, по идее, по умолчанию также должен использовать UTF-8, и при копировании из окна редактора Matlab в либру проблем быть не должно бы. Тем не менее, после вставки в окно LibreOffice, отображаются кракозябры.
Если сначала скопировать и вставить в блокнот (gedit, например), а потом уже из блокнота в либру, то всё нормально, но постоянно пользоваться таким костылем как-то не очень хочется.
Было подозрение, что проблема может быть в шрифтах. Пробовал менять шрифты в настройках Matlab - ничего не дало.
Самое интересное то, что если сохранить M-файл в CP1251, то при копировании в либру проблем нет. Можно было бы запускать Matlab с локалью ru_RU.CP1251, но тогда все пути, содержащие кириллические имена, в матлабе отображаются кракозябрами, что тоже не очень радует.

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

Может, кто-то уже сталкивался с подобной проблемой, или же имеет соображения по поводу возможных путей ее решения.
Заранее благодарен.
Debian 8.2 (Jessie), LXDE.

ihammers

Debian GNU/Linux Stretch, kernel 4.9.0-5-amd64,
LXQt/KDE/OpenBox AMD Phenon X4 / 16Gb RAM / ATI HD7750 Silent
_______________________________
Debian GNU/Linux Stretch, kernel 4.9.0-5-amd64, LXQt/KDE/OpenBox
Acer Aspire One 722 AMD C60 / 4Gb RAM / ATI HD6290

strekoza

#2
LANG=ru_RU.UTF-8
LANGUAGE=ru_UA:ru
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=


* Используйте теги для оформления сообщения, ihammers.
Debian 8.2 (Jessie), LXDE.

ihammers

Ненравиться мне запись LANGUAGE=ru_UA:ru, не встречал такие. Попробуйте убрать её и запустить Matlab:

~$ LANGUAGE=


А также проверяйте настройки Matlab, скорей всего он как-то странно определяет настройки системной локали, возможно после того как вы запустите с пустым параметром LANGUAGE все может заработать.

Доп. информация: 1, 2, 3.
Debian GNU/Linux Stretch, kernel 4.9.0-5-amd64,
LXQt/KDE/OpenBox AMD Phenon X4 / 16Gb RAM / ATI HD7750 Silent
_______________________________
Debian GNU/Linux Stretch, kernel 4.9.0-5-amd64, LXQt/KDE/OpenBox
Acer Aspire One 722 AMD C60 / 4Gb RAM / ATI HD6290

strekoza

#4
Сделал, как Вы предложили, однако ничего не изменилось.
Пробовал уже в запущенном матлабе выполнять команду feature('DefaultCharacterSet','UTF8') - это ровным счетом ничего не дает и не меняет.
Пробовал также feature('DefaultCharacterSet','CP-1251') - результат есть: кириллические пути становятся недоступными.
Пробовал устанавливать LANG=C - никаких изменений.
Пробовал очищать LANG (т.е. LANG=) - аналогично.

В итоге, решил посмотреть, что же вообще творится в буфере обмена.
Установил утилиту xclip для работы с буферами обмена.

В M-файле (сохранен в UTF-8) скопировал слово "сигнал", после чего вывел содержимое первого и второго буферов обмена в файл:

# xclip -o > buf1
# xclip -o -sel c > buf2


При открытии файлов в блокноте (Leafpad), в обоих случаях верно отображается слово "сигнал".
При открытии этих файлов в HEX-редакторе (GHex), отображается следующее:



D181 - это код буквы "с" в UTF-8, D0B8 - "и" и т.д. Следовательно, копируется действительно текст в UTF-8, и копируется правильно.
(коды кириллицы в UTF-8)

В первый буфер копируется то, что было выделено, во второй - то, что было выделено при нажатии Ctrl+C. Тут всё понятно.

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

Вид в либре:


Нужный кусок в HEX-редакторе:


Очевидно, что вставилось явно не то, что нужно. Но... Если присмотреться, то будет видно:
Слово "сигнал" состоит из 6 символов - в UTF-8 будет занимать 6 слов (12 байт). Именно это мы и видим при открытии в HEX-редакторе файлов buf1 и buf2.
Здесь же мы видим, что после 12 слов идет слово OD00 (Enter), потом 4 слова, соответствующие "сигнатуре", потом снова OD00, а потом нули.

Следовательно, у нас теперь одному символу соответствует 2 слова (4 байта), а не 1 слово, как должно бы быть.

Потом было замечено, что если кликнуть в трее иконку менеджера буфера обмена (Cliplt), то в самом верху будет находиться "сигнал". Если кликнуть по этой строке, окно менеджера закроется, и если потом нажать Ctrl+V в либре, то будет корректно вставлено слово "сигнал".

Вот что теперь отображается в HEX-редакторе:


Видим, что после "сигнатуры" что-то появилось, но это явно не D181D0B8... - т.е., в либре использована (в данном случае) не UTF-8, хотя отображается текст корректно.

4104 (первое слово) - это 0441 (если байты поменять местами), а это символ "с" в UNICODE.

Итого, с матлаба в буфер все копируется верно - копируется в UTF-8 - это первое.
С буфера в либру копируется вовсе не то, что было в буфере, и если в буфере было одно слово, то скопируется из него два слова - все удваивается. Это второе.
Третье - либра интерпретирует все в кодировке UNICODE. Интерпретируя как UNICODE тот удвоенный хлам, что чудным образом копируется из буфера, либра отображает созерцаемую нами ересь.
Четвертое: "ересь" в фале либры представлена также в юникоде, о чем говорит второй байт (04) в каждом слове (2104 0304 и т.д.).

Итак, у нас есть D181 (к примеру), и возникает вопрос: как, при копировании из буфера, мы получаем 2104 0304?

D181 -> 2104 0304 ?

D181 - это UTF-8, а 2104 0304 - это два символа в UNICODE. Следовательно, когда мы пихаем в либру из буфера один символ в UTF-8, то либра "порождает" ему взамен два символа в UNICODE. Как? А, по всей видимости, вот так:

D1 - это 209. 209 в CP-1251 - это буква "С". В UNICODE это 0421. Наоборот будет - 2104. Где-то мы это уже видели.

Вывод: либра думает, что мы ей из буфера пихаем текст в CP-1251, и пытается его преобразовать в UNICODE. В итоге получается очень забавная вещь: текст в UTF-8 либра воспринимает как CP-1251 и преобразует в UNICODE.

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

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

Хотя, можно просто каждый раз тыкать на менеджер БО в трее, и выбирать нужную строку, а потом в либре нажимать Ctrl+V. Но интереснее докопаться до сути, и сделать по-человечески.
Debian 8.2 (Jessie), LXDE.

ihammers

Цитата: strekoza от 24 ноября 2015, 10:38:20На основании всего этого "расследования", для дальнейшего движения наиболее разумным кажется копание в сторону каких-то глюков/особенностей в работе менеджера буфера обмена, а также в направлении глюков/особенностей работы либры и ее настроек. К матлабу вопросов нет.

Скорее всего, что проблема в либре. Но пока мыслей по поводу того, что именно нужно менять в либре, у меня нет...
Мощное исследование. Попробуйте поставить/отключить в настройках LibreOffice -> Настройки языка -> Языки -> Игнорировать язык ввода ОС.

Цитата: https://help.libreoffice.org/Common/Languages
Ignore system input language

Indicates whether changes to the system input language/keyboard will be ignored. If ignored, when new text is typed that text will follow the language of the document or current paragraph, not the current system language.
Debian GNU/Linux Stretch, kernel 4.9.0-5-amd64,
LXQt/KDE/OpenBox AMD Phenon X4 / 16Gb RAM / ATI HD7750 Silent
_______________________________
Debian GNU/Linux Stretch, kernel 4.9.0-5-amd64, LXQt/KDE/OpenBox
Acer Aspire One 722 AMD C60 / 4Gb RAM / ATI HD6290

strekoza

#6
Спасибо, попробовал, но, к сожалению, также не помогло...

На данный момент нашел два более-менее приемлемых способа решения проблемы (хотя, полностью проблема еще не решена):
1. Выделить текст в матлабе (можно и без нажатия Ctrl+C), перейти в окно либры, нажать колесико мыши - текст будет вставлен корректно, хотя и без сохранения форматирования. Это самый быстрый способ.
2. Выделить текст в матлабе, нажать Ctrl+C, перейти в окно либры, выбрать пункт меню Правка - Вставить как - Текст без форматирования, либо нажать Ctrl+Shift+V, а затем выбрать "Текст без форматирования". - Текст вставится корректно, но, соответственно, без сохранения форматирования.

Детальное описание процесса поиска решения приведено ниже.
Открыть содержимое (спойлер)
Ни снятая галочка "Игнорировать язык ввода ОС", ни поставленная, дела не меняют.
Изменение языка документов по умолчанию также ничего не дает.
Изменение языка пользовательского интерфейса и локальных настроек на английский просто меняет характер проблемы: текст в UTF-8 начинает интерпретироваться как Windows-1252.
Запуск LibreOffice Writer из консоли с указанием окружения (LANG=ru_RU.UTF-8), равно как и запуск без указания окружения, ничего не меняет (прим. по умолчанию в файле /usr/share/applications/libreoffice-writer.desktop запуск у меня прописан с окружением LANG=ru_RU.UTF-8).

При написании предыдущего сообщения думал, что в Линуксе всего два буфера обмена, и спутал вторичный буфер и clipboard, в то время, как это разные вещи. Теперь сделал для себя открытие, что буферов аж целых четыре (а то и больше):

primary (первичный, основной) - сюда текст попадает сразу после выделения; вставляется путем нажатия колесика мыши или же нажатия сразу левой и правой кнопок (второй вариант у меня не получается);
secondary (вторичный) - зачем он нужен, не ясно. Якобы, X-сервер позволяет использовать еще и третий, четвертый и т.д. буферы обмена. Возможно, это сделано просто на тот случай, если в контексте функционала какой-то программы существование кучи буферов будет актуальным.
clipboard - привычный для Windows-пользователей буфер обмена (Ctrl+C - копировать, Ctrl+V - вставить).
buffer-cut - по идее, в него должны помещаться "вырезанные" (Ctrl+X) данные, но у меня в него при вырезании (в той же либре или матлабе) ничего не помещается.

Итого, выделяю в матлабе всё то же слово "сигнал", нажимаю Ctrl+C, и сохраняю значения всех буферов:
# xclip -o -sel primary > buf1
# xclip -o -sel secondary > buf2
Error: target STRING not available
# xclip -o -sel clipboard > buf3
# xclip -o -sel buffer-cut > buf4


primary и clipboard сохраняются в файлы без проблем. Как и отмечалось выше, сохранение происходит в UTF-8 (в UTF-8 текст хранится в М-файле, в UTF-8 он попадает в буферы, в UTF-8 он сохраняется в файлы buf*).
buffer-cut как бы сохраняется (даже если вырезать текст, нажав Ctrl+X), т.е. ошибок xclip не выдает, но файл buf4 получается пустой.
При чтении из вторичного буфера видим ошибку - по всей видимости, в этот буфер ничего и не попадало, потому и вылетает ошибка.

Теперь перехожу в либру.
Нажимаю Ctrl+V - вижу старые добрые кракозябры. Вставка осуществляется из clipboard.
Еще раз нажимаю Ctrl+V - ничего не вставляется, и вылетает ошибка: "Недоступен желаемый формат буфера обмена." Видимо, после первой вставки буфер автоматически очистился.
Нажимаю колесико мыши - вставляется вполне читабельный текст. Вставка из первичного буфера.
Выбираю только что скопированный текст с помощью менеджера БО, и опять нажимаю Ctrl+V - вставляется читабельный текст.

Теперь снова сохраняю в файлы все буферы выше описанным способом. Вижу, что содержимое буферов ровным счетом никак не изменилось, в то время, как реакция либры изменилась. Вывод: что-то изменилось "на лету", "в процессе". Возможно, изменилось что-то, что определяет способ общения либры с системным БО (точнее, буферами). Скорее всего, это "что-то" - способ интерпретации данных клипборда: теперь данные стали интерпретироваться как текст без форматирования, а до этого интерпретировались как форматированный текст (см. ниже).

Гугление подсказывает, что у либры есть свой собственный буфер обмена, в добавок к буферам иксов (в приведенном материале речь идет только об одном из буферов - клипбоарде, который назван системным буфером). Отличия "системного буфера" от буфера либры приведены в таблице ниже:



Из таблицы видим, что:
при нажатии Ctrl+C происходит копирование выделенного в либре объекта в клипбоард
при нажатии Ctrl+V происходит вставка из клипбоарда
при выделении текста (в общем случае, объекта) происходит вставка в собственный буфер либры
нажатие колесика (средней кнопки) мыши приводит к вставке из собственного буфера

Отсюда видно, что собственный буфер либры и первичный буфер иксов либо запараллелены, либо это вообще одно и то же (возможно, в линуксе это одно и то же, а в винде у либры действительно свой буфер обмена). В любом случае, нам это сейчас не принципиально.

Вопрос:
Почему из первичного буфера / собственного б. либры текст вставляется нормально (нажатие колесика), а при вставке из клипбоарда / системного б. (Ctrl+V) текст вставляется кракозябрами?

Как выяснилось, в либре есть два способа вставки: тупо Ctrl+V (или же Правка - Вставить), и Ctrl+Shift+V (Правка - Вставить как).

При нажатии Ctrl+V, текст из буфера интерпретируется как форматированный (RTF) (не забываем, что, на самом деле, текст в буфере чистый - без форматирования).
При нажатии Ctrl+Shift+V, открывается диалог, в котором предлагается выбрать способ вставки: как форматированный текст, или как текст без форматирования. Если выбрать текст без форматирования, то всё вставляется нормально (хотя, цвет и шрифт текста из редактора Матлаб действительно игнорируются). Удивительно вот что: при копировании текста из матлаба, в буфер попадает сам текст в UTF-8, и ничего более, НО кракозябры в либру вставляются того же цвета, какого цвета и текст в матлабе, и в том же шрифте. Через что из матлаба в либру была передана информация о цвете, раз ее не было в буфере обмена, я не знаю (может, там используются какие-то дебри вроде именованных каналов, сокетов или еще чего-то в этом роде, и именно через них передается информация о цвете, шрифте и т.д.).

Итого, что-то уже нащупано:при нажатии Ctrl+V, текст копируется из клипбоарда, интерпретируется как форматированный (RTF), а данные о цвете и шрифте, по всей видимости, попадают из матлаба в либру "окольными путями". Цвет и шрифт определены верно, а вот сам текст интерпретирован как текст в CP1251, хотя он в UTF-8, что было показано выше.
[свернуть]

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

UPD: Стоит отметить, что та же самая проблема имеется и в случае работы в ворде из-под вайна: если вставлять только текст (Параметры Word - Дополнительно - Вставка из других программ - Сохранить только текст), то текст вставляется корректно, хотя, естественно, и без сохранения форматирования. Если же выбрать "Сохранить исходное форматирование", то вставка выполняется с сохранением шрифта и цвета из редактора Матлаб, но русскоязычные комментарии отображаются неправильно.
Debian 8.2 (Jessie), LXDE.