Ответ 1
Я использую режим nXML для редактирования и Tidy, когда я хочу форматировать и отступать XML или HTML. Существует также интерфейс Emacs для Tidy.
Я использую emacs для редактирования моих xml файлов (nxml-mode), и файлы были сгенерированы машиной, не имеют никакого довольно форматирования тегов.
Я искал довольно полную распечатку всего файла с отступом и сохранил его, но не смог найти автоматический путь.
Есть ли способ? Или, по крайней мере, некоторый редактор на linux, который может это сделать.
Я использую режим nXML для редактирования и Tidy, когда я хочу форматировать и отступать XML или HTML. Существует также интерфейс Emacs для Tidy.
Вам даже не нужно писать свою собственную функцию - sgml-mode (основной модуль gnu emacs) имеет встроенную симпатичную функцию печати (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 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
здесь несколько настроек, которые я сделал для версии Бенджамина Феррари:
search-forward-regexp
не указывал конец, поэтому он работал бы с материалом от начала области до конца буфера (вместо конца области).end
правильно, как отметил Чисо.<tag></tag>
, который изменяет его значение. Да, технически мы изменяем ценности всего здесь, но пустая старт/конец гораздо более значима. Теперь для этого нужно использовать два отдельных, немного более строгих поиска.Тем не менее, "не полагается на внешний порядок" и т.д. Однако для макроса incf
для incf
требуется cl
.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 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 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=
Надеюсь, что это поможет.
НТН
Я принял версию Джейсона Вирса и добавил логику, чтобы помещать объявления 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 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!"))
Tidy выглядит как хороший режим. Надо смотреть на это. Будет использовать его, если мне действительно нужны все функции, которые он предлагает.
Во всяком случае, эта проблема проталкивала меня около недели, и я не искал должным образом. После публикации я начал поиск и нашел один сайт с elisp function, который делает это довольно хорошо. Автор также предлагает использовать Tidy.
Спасибо за ответ Marcel (слишком плохо, что у меня недостаточно очков, чтобы продвигать вас).
Будет опубликован в ближайшее время в моем блоге. разместите об этом (со ссылкой на Марсель).
Я использую xml-reformat-tags
от xml-parse.el. Обычно вы хотите иметь точку в начале файла при выполнении этой команды.
Интересно, что файл включен в Emacspeak. Когда я ежедневно использовал Emacspeak, я думал, что xml-reformat-tags
- встроенный Emacs. Однажды я потерял его и должен был сделать интернет-поиск для этого и, таким образом, ввел указанную выше страницу вики.
Я также добавляю свой код для запуска 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/