Spraw, aby emacs nie usuwał BOM z plików XML

8

Używam Emacsa do edycji pliku XML, który jest również odczytywany przez inną aplikację. Druga aplikacja wymaga, aby plik zaczynał się od znacznika kolejności bajtów (BOM). Jednak wydaje się, że Emacs usuwa BOM za każdym razem, gdy edytuję plik. Czy istnieje sposób, aby Emacs opuścił BOM w spokoju?

Vebjorn Ljosa
źródło
Czy to dlatego, gdy edytuję plik xml dla schtasks, zmienia kodowanie z Unicode na Unicode Big Endian, a następnie nie działa?
js2010

Odpowiedzi:

9

Emacs napisze BOM lub nie, w zależności od używanego systemu kodowania. Emacs automatycznie wybiera system kodowania, którego używa podczas odwiedzania pliku.

Możesz zmienić system kodowania na utf-8-with-podpis, który powie Emacsowi napisanie BOM.

Aby zmienić system kodowania odwiedzanego pliku:

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

Możesz ustawić system kodowania używany przez Emacsa dla określonego pliku, ustawiając zmienną pliku . Zobacz dokładną instrukcję w rozdziale 57.3.4 Zmienne lokalne w plikach, aby dowiedzieć się, jak to zrobić.

Richard Hoskins
źródło
Niesamowite, dokładnie taka odpowiedź, na jaką liczyłem! Dziękuję Ci!
Vebjorn Ljosa
5

Kontynuacja odpowiedzi Richarda Hoskinsa: jeśli nigdy nie chcesz ukrywać BOM przez emacsa, możesz wyłączyć * -z kodowaniem podpisu za pomocą tego fragmentu:

(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))))

LM to U + FEFF, „przestrzeń niezniszczalna o zerowej szerokości”, i nie wyświetla się jako pole w emacsie 23.1.1 - zamiast tego górna linia pliku przesunęła się nieco w dół, a czasami pole pojawia się wokół pierwszego wiersza - ale widać, że BOM tam jest i usuń go, jeśli to konieczne.


źródło
1

Emacs „sam” nie powinien zadzierać z BOM; jeśli naprawdę to robi, to musiałby to być kod implementujący „tryb” Emacsa, którego używasz do edycji plików XML, co usuwa BOM. Ponieważ nie mówisz, który to jest, mogę jedynie odesłać cię do dokumentacji tego trybu lub otworzyć pliki w fundamental-mode(lub w podobnym trybie nieniszczącym). Lub spróbuj, M-x find-file-literallyjeśli wszystko inne zawiedzie.

Miś
źródło
użyj trybu xml (tj. tryb sgml), ale ten problem wydaje się być gdzie indziej: jeśli otworzę plik za pomocą, find-file-literallya następnie zrobię M-x sgml-mode, BOM nie zostanie usunięty. Ponieważ znaki specjalne nie są kodowane w UTF-8 podczas odwiedzania pliku dosłownie, dobrze byłoby dowiedzieć się, gdzie w podstawowym formacie konwersji i kodzie konwersji kodu znaków BOM jest usuwany.
Vebjorn Ljosa
0

W moim teście edycja UTF-8pliku nie zmienia kodowania, a BOM pozostaje ( efbb bf). (tryb nxml)

No, może ulec zmianie między xml-modei nxml-mode, lub wersja emacs (24 vs 26). Mówi tryb na dole.

Jeśli edytujesz plik XML Emacsa zakodowany w Unicode ( UTF-16little endian), zmieni on kodowanie na UTF-16big endian. Może o tym on mówi.

Ale BOM wciąż tam jest, zmieniony z fffena ffef, a wartości zerowe są na nieparzystym bajcie zamiast parzystym. Możesz to zobaczyć w trybie szesnastkowym.

Przykładowy plik XML. Atrybut kodowania kieruje kodowaniem, gdy emacs zapisuje je w trybie xml lub nxml. Przyszła wersja zostanie załatana, aby najpierw sprawdzić BOM.

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

Wygląda na to, że Emacs przyjmuje UTF-16jako UTF-16BE, podczas gdy Windows przyjmuje to jako UTF-16LE(BE i LE nie działają w Emacsie dla atrybutu kodowania). Atrybut kodowania jest prawdopodobnie kluczem do problemów tutaj.

Zapisanie go w PowerShell spowoduje konwersję z powrotem do utf-16le.

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

Przy kodowaniu = „UTF-16LE” i kodowaniu = „UTF-16BE” bom jest usuwany, co powoduje, że plik nie jest rozpoznawany w emacsie. To jest potwierdzony błąd, który zostanie załatany: http://lists.gnu.org/archive/html/bug-gnu-emacs/2019-05/msg00892.html

js2010
źródło