Довольно печать XML-файлов на Emacs



Я использую emacs для редактирования моих xml-файлов (nxml-mode), и файлы, созданные машиной, не имеют красивого форматирования тегов.



Я искал довольно печать всего файла с отступом и сохранить его, но не смог найти автоматический способ.



есть ли способ? Или, по крайней мере, какой-то редактор на linux, который может это сделать.

699   15  

15 ответов:

Я использую режим nXML для редактирования и порядок когда я хочу отформатировать и отступить XML или HTML. Есть также интерфейс Emacs для очистки.

вам даже не нужно писать свою собственную функцию-sgml-mode (модуль ядра gnu emacs) имеет встроенную функцию pretty printing (sgml-pretty-print ...) который принимает аргументы начала и конца области.

Если вы режете и вставляете xml, и вы обнаружите, что ваш терминал рубит строки в произвольных местах, вы можете использовать это довольно принтера который исправляет ломаные линии в первую очередь.

Если вам нужно только довольно отступ без введения каких-либо новых разрывов строк, вы можете применить indent-region команда для всего буфера с этими нажатиями клавиш:

C-x h
C-M-\

Если Вам также нужно ввести разрывы строк, так что открытие и закрытие тегов находятся на отдельных строках, вы можете использовать следующую очень хорошую функцию elisp, написанную Бенджамин Феррари. Я нашел его в своем блоге и надеюсь, что это нормально для меня, чтобы воспроизвести его здесь:

(defun bf-pretty-print-xml-region (begin end)
  "Pretty format XML markup in region. You need to have nxml-mode
http://www.emacswiki.org/cgi-bin/wiki/NxmlMode installed to do
this.  The function inserts linebreaks to separate tags that have
nothing but whitespace between them.  It then indents the markup
by using nxml's indentation rules."
  (interactive "r")
  (save-excursion
      (nxml-mode)
      (goto-char begin)
      (while (search-forward-regexp "\>[ \t]*\<" nil t) 
        (backward-char) (insert "\n"))
      (indent-region begin end))
    (message "Ah, much better!"))

Это не полагайтесь на внешний инструмент, такой как Tidy.

Emacs может выполнять произвольные команды с помощью M -|. Если у вас установлен xmllint:

"M-| xmllint --format -" будет форматировать выбранный регион

"C-u M| / xmllint --format -" будет делать то же самое, заменяя область с выходом

спасибо Тиму Хельмштедт выше я сделал ст такой:

(defun nxml-pretty-format ()
    (interactive)
    (save-excursion
        (shell-command-on-region (point-min) (point-max) "xmllint --format -" (buffer-name) t)
        (nxml-mode)
        (indent-region begin end)))

быстро и легко. Большое спасибо.

для введения разрывов строк, а затем довольно печати

M-x sgml-mode
M-x sgml-pretty-print

вот несколько настроек, которые я сделал для версии Бенджамина Феррари:

  • the search-forward-regexp не указывал конец, поэтому он будет работать на материале от начала области до конца буфера (вместо конца области)
  • теперь шагом end правильно, как Cheeso отметил.
  • он вставил бы перерыв между <tag></tag>, что изменяет его значение. Да, технически мы изменяем значения всего здесь, но пустое начало / конец гораздо более вероятно значительное. Теперь использует два отдельных, немного более строгих поиска, чтобы избежать этого.

все еще имеет "не полагается на внешнее аккуратное", etc. Однако для этого требуется cl на incf макрос.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; pretty print xml region
(defun pretty-print-xml-region (begin end)
  "Pretty format XML markup in region. You need to have nxml-mode
http://www.emacswiki.org/cgi-bin/wiki/NxmlMode installed to do
this.  The function inserts linebreaks to separate tags that have
nothing but whitespace between them.  It then indents the markup
by using nxml's indentation rules."
  (interactive "r")
  (save-excursion
    (nxml-mode)
    (goto-char begin)
    ;; split <foo><foo> or </foo><foo>, but not <foo></foo>
    (while (search-forward-regexp ">[ \t]*<[^/]" end t)
      (backward-char 2) (insert "\n") (incf end))
    ;; split <foo/></foo> and </foo></foo>
    (goto-char begin)
    (while (search-forward-regexp "<.*?/.*?>[ \t]*<" end t)
      (backward-char) (insert "\n") (incf end))
    (indent-region begin end nil)
    (normal-mode))
  (message "All indented!"))

один из способов сделать это Если у вас есть что-то в формате ниже

<abc>     <abc><abc>   <abc></abc> </abc></abc>       </abc>

в Emacs, попробуйте

M-x nxml-mode
M-x replace-regexp RET  > *< RET >C-q C-j< RET 
C-M-\ to indent

это будет отступ над примером xml ниже

<abc>
  <abc>
    <abc>
      <abc>
      </abc>
    </abc>
  </abc>
</abc>

в VIM вы можете сделать это с помощью

:set ft=xml
:%s/>\s*</>\r</g
ggVG=

надеюсь, что это помогает.

  1. Emacs nxml-mode может работать в представленном формате, но вам придется разделить строки.
  2. для более длинных файлов, которые просто не стоит. Запустите эту таблицу стилей (в идеале с Saxon который IMHO получает отступы строки справа) против более длинных файлов чтобы получить хороший красивый отпечаток. Для любых элементов, где вы хотите сохранить пробел добавьте их имена рядом с "programlisting", как в "programlisting yourElementName"

HTH

взял Джейсон Viers' версия и добавлена логика, чтобы поместить объявления xmlns на свои собственные строки. Это предполагает, что у вас есть xmlns= и xmlns: без промежуточных пробелов.

(defun cheeso-pretty-print-xml-region (begin end)
  "Pretty format XML markup in region. You need to have nxml-mode
http://www.emacswiki.org/cgi-bin/wiki/NxmlMode installed to do
this.  The function inserts linebreaks to separate tags that have
nothing but whitespace between them.  It then indents the markup
by using nxml's indentation rules."
  (interactive "r")
  (save-excursion
    (nxml-mode)
    ;; split <foo><bar> or </foo><bar>, but not <foo></foo>
    (goto-char begin)
    (while (search-forward-regexp ">[ \t]*<[^/]" end t)
      (backward-char 2) (insert "\n") (incf end))
    ;; split <foo/></foo> and </foo></foo>
    (goto-char begin)
    (while (search-forward-regexp "<.*?/.*?>[ \t]*<" end t)
      (backward-char) (insert "\n") (incf end))
    ;; put xml namespace decls on newline
    (goto-char begin)
    (while (search-forward-regexp "\(<\([a-zA-Z][-:A-Za-z0-9]*\)\|['\"]\) \(xmlns[=:]\)" end t)
      (goto-char (match-end 0))
      (backward-char 6) (insert "\n") (incf end))
    (indent-region begin end nil)
    (normal-mode))
  (message "All indented!"))

аккуратный выглядит как хороший режим. Надо посмотреть на него. Использую его, если мне действительно нужны все его функции.

в любом случае, эта проблема мучила меня около недели, и я не искал должным образом. После публикации я начал поиск и нашел один сайт с функции elisp что делает его довольно хорошо. Автор также предлагает использовать аккуратно.

Спасибо за ответ Марсель (жаль, что у меня нет достаточно очков, чтобы upmod вас).

скоро опубликует об этом в своем блоге. здесь сообщение об этом (со ссылкой на сайт Марселя).

Я использую xml-reformat-tags С xml-parse.Эл. Обычно вы хотите иметь точку в начале файла при выполнении этой команды.

интересно, что файл включен в Emacspeak. Когда я использовал Emacspeak на ежедневной основе, я думал xml-reformat-tags это Emacs встроенный. Однажды я потерял его и должен был сделать поиск в интернете для этого, и, таким образом, вошел в упомянутую страницу wiki выше.

Я также прикрепляю свой код для запуска xml-parse. Не уверен, что это лучший кусок кода Emacs, но, кажется, работает для меня.

(if (file-exists-p "~/.emacs.d/packages/xml-parse.el")
  (let ((load-path load-path))
    (add-to-list 'load-path "~/.emacs.d/packages")
    (require 'xml-parse))
)

Если вы используете spacemacs, просто используйте команду 'spacemacs / indent-region-or-buffer'.

M-x spacemacs/indent-region-or-buffer

боюсь, мне больше нравится версия Бенджамина Феррари. Внутренняя симпатичная печать всегда помещает конечный тег в новую строку после значения, вставляя нежелательный CR В значения тегов.

С 2017 года emacs уже поставляется с этой возможностью по умолчанию, но вы должны написать эту маленькую функцию в свой ~/.emacs.d/init.el:

(require 'sgml-mode)

(defun reformat-xml ()
  (interactive)
  (save-excursion
    (sgml-pretty-print (point-min) (point-max))
    (indent-region (point-min) (point-max))))

тогда просто позвоните M-x reformat-xml

источник: https://davidcapello.com/blog/emacs/reformat-xml-on-emacs/

Comments

    Ничего не найдено.