I have a file with xml all on one line. Does the functionality already exist to reformat this buffer to be somewhat user-readable?
Does the functionality already exist to reformat this buffer to be somewhat user-readable?
Of course, and you have plenty of options. I'd probably feed it to an external program using:
C-x h C-u M-| xmllint --format - RET
This program comes with
libxml2. You could also use
tidy. Here's a list of commandline xml formatting tools: https://stackoverflow.com/questions/16090869/how-to-pretty-print-xml-from-the-command-line
You could also do a search and replace and then indent:
M-% > < RET > C-q C-j < RET ! C-M-\
Neat trick: you can copy and paste the above string into
eval-expression) like this:
(execute-kbd-macro (kbd "M-% > < RET > C-q C-j < RET ! C-M-\\"))
sgml-mode has a command to do this:
sgml-pretty-print. If you're in
nxml-mode it looks like you need switch to
sgml-mode first. You could write a command to temporarily switch to sgml-mode, run pretty-print, then switch back to nxml-mode.
For example, here is a command that will pretty-print the region, optionally with auto-fill enabled:
(defun xml-pretty-print (beg end &optional arg) "Reformat the region between BEG and END. With optional ARG, also auto-fill." (interactive "*r\nP") (let ((fill (or (bound-and-true-p auto-fill-function) -1))) (sgml-mode) (when arg (auto-fill-mode)) (sgml-pretty-print beg end) (nxml-mode) (auto-fill-mode fill)))
write this into your
(require 'sgml-mode) (defun ninrod/reformat-xml () (interactive) (save-excursion (sgml-pretty-print (point-min) (point-max)) (indent-region (point-min) (point-max))))
reload emacs, then just call
M-x reformat-xml on the badly formatted xml buffer.
Following the hint of the answer above, and assuming you have
tidy installed a variation could be:
`C-x h M-| tidy -quiet -xml -utf8 -indent -`
This will open a new buffer
*Shell Command Output* instead of directly replacing the contents of the buffer. After checking the result, replace the old contents with the new with:
C-x h M-insert-buffer
choose the suggested default which will probably be
*Shell Command Output*. You can save the command for later with a keyboard macro:
C-x ( C-x h M-| tidy -quiet -xml -utf8 -indent - C-x) C-x C-k n pretty-xml
With this you can execute
M-x pretty-xml to reformat the buffer.