Заставьте emacs не удалять BOM из файлов XML

8

Я использую Emacs для редактирования XML-файла, который также читается другим приложением. Другое приложение требует, чтобы файл начинался с маркера порядка байтов (BOM). Однако Emacs, похоже, удаляет спецификацию каждый раз, когда я редактирую файл. Есть ли способ заставить Emacs оставить специализацию в покое?

Вебьорн Лёса
источник
Поэтому, когда я редактирую xml-файл для schtasks, он меняет кодировку с юникода на unicode с прямым порядком байтов и затем не работает?
js2010

Ответы:

9

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

Вы можете изменить систему кодирования на utf-8-with-signature, которая скажет Emacs написать спецификацию.

Чтобы изменить систему кодирования посещаемого файла:

C-x RET r utf-8-with-signature RET

Вы можете установить систему кодирования, которую Emacs использует для определенного файла, установив переменную файла . Обратитесь к разделу 57.3.4 «Локальные переменные в файлах», чтобы узнать, как это сделать.

Ричард Хоскинс
источник
Круто, именно такой ответ, на который я надеялся! Спасибо!
Вебьерн Льоса
5

Продолжение ответа Ричарда Хоскинса: если вы никогда не хотите, чтобы спецификация была скрыта emacs, вы можете отключить кодировки * -with-signature с помощью этого фрагмента:

(setq auto-coding-regexp-alist
  (delete (rassoc 'utf-16be-with-signature auto-coding-regexp-alist)
  (delete (rassoc 'utf-16le-with-signature auto-coding-regexp-alist)
  (delete (rassoc 'utf-8-with-signature auto-coding-regexp-alist)
          auto-coding-regexp-alist))))

Спецификация - это U + FEFF, «неразрывный пробел нулевой ширины», и она не отображается как поле в моем emacs 23.1.1 - вместо этого верхняя строка файла перемещается немного вниз, а иногда поле появляется вокруг первой строки, но вы можете видеть, что спецификация есть, и удалить ее при необходимости.


источник
1

Emacs «сам» не должен связываться с спецификацией; если это действительно так, то это должен быть код, реализующий «режим» Emacs, который вы используете для редактирования ваших XML-файлов, удаляющих спецификацию. Поскольку вы не говорите, какой это, я могу только отослать вас к документации для этого режима, или что вы открываете файлы в fundamental-mode(или аналогичном неразрушающем режиме). Или попробуйте, M-x find-file-literallyесли ничего не помогает.

Тедди
источник
использовать xml-режим (то есть sgml-режим), но эта проблема, похоже, в другом месте: если я открою файл, find-file-literallyа затем сделаю M-x sgml-mode, спецификация не будет удалена. Поскольку специальные символы не кодируются в UTF-8 при буквальном посещении файла, было бы неплохо выяснить, где в базовом преобразовании формата и коде преобразования кода символа удаляется спецификация.
Вебьерн Льоса
0

В моем тесте редактирование UTF-8файла не меняет кодировку, и спецификация остается ( efbb bf). (nxml-режим)

Ну, это может варьироваться между xml-modeи nxml-mode, или версия Emacs (24 против 26). Это говорит о режиме внизу.

Если вы отредактируете Emacs XML-файл, закодированный в юникоде (с UTF-16прямым порядком байтов), он изменит кодировку с UTF-16прямым порядком байтов. Может быть, это то, о чем он говорит.

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

Образец XML-файла. Атрибут encoding направляет кодировку, когда emacs сохраняет ее в режиме xml или nxml. Будущая версия будет исправлена ​​для проверки спецификации в первую очередь.

<?xml version="1.0" encoding="UTF-16"?>
<hi />

Похоже, что Emacs принимает UTF-16как UTF-16BE, в то время как Windows принимает его как UTF-16LE(BE и LE не работают в Emacs для атрибута кодирования). Атрибут кодирования, вероятно, является ключом к проблемам здесь.

Сохранение его в powershell преобразует его обратно в utf-16le.

[xml]$xml = get-content test.xml; $xml.save('test.xml')

При кодировании = "UTF-16LE" и кодировке = "UTF-16BE" бомба удаляется, что делает файл не распознаваемым в emacs. Это подтвержденная ошибка, которая будет исправлена: http://lists.gnu.org/archive/html/bug-gnu-emacs/2019-05/msg00892.html

js2010
источник