Can emacs re-indent a big blob of HTML for me?

HtmlEmacs

Html Problem Overview


When editing HTML in emacs, is there a way to automatically pretty-format a blob of markup, changing something like this:

  <table>
  <tr>
<td>blah</td></tr></table>

...into this:

<table>
 <tr>
  <td>
   blah
  </td>
 </tr>
</table>

Html Solutions


Solution 1 - Html

You can do sgml-pretty-print and then indent-for-tab on the same region/buffer, provided you are in html-mode or nxml-mode.

sgml-pretty-print adds new lines to proper places and indent-for-tab adds nice indentation. Together they lead to properly formatted html/xml.

Solution 2 - Html

By default, when you visit a .html file in Emacs (22 or 23), it will put you in html-mode. That is probably not what you want. You probably want nxml-mode, which is seriously fancy. nxml-mode seems to only come with Emacs 23, although you can download it for earlier versions of emacs from the nXML web site. There is also a Debian and Ubuntu package named nxml-mode. You can enter nxml-mode with:

M-x nxml-mode

You can view nxml mode documentation with:

C-h i g (nxml-mode) RET

All that being said, you will probably have to use something like Tidy to re-format your xhtml example. nxml-mode will get you from

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head></head>
<body>
<table>
  <tr>
<td>blah</td></tr></table>
</body>

to

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head></head>
  <body>
    <table>
      <tr>
    <td>blah</td></tr></table>
</body>
</html>

but I don't see a more general facility to do line breaks on certain xml tags as you want. Note that C-j will insert a new line with proper indentation, so you may be able to do a quick macro or hack up a defun that will do your tables.

Solution 3 - Html

<http://www.delorie.com/gnu/docs/emacs/emacs_277.html>

After selecting the region you want to fix. (To select the whole buffer use C-x h)

> C-M-q > > Reindent all the lines within one parenthetical grouping(indent-sexp). > > C-M-\ > > Reindent all lines in the region (indent-region).

Solution 4 - Html

i wrote a function myself to do this for xml, which works well in nxml-mode. should work pretty well for html as well:

(defun jta-reformat-xml ()
  "Reformats xml to make it readable (respects current selection)."
  (interactive)
  (save-excursion
    (let ((beg (point-min))
          (end (point-max)))
      (if (and mark-active transient-mark-mode)
          (progn
            (setq beg (min (point) (mark)))
            (setq end (max (point) (mark))))
        (widen))
      (setq end (copy-marker end t))
      (goto-char beg)
      (while (re-search-forward ">\\s-*<" end t)
        (replace-match ">\n<" t t))
      (goto-char beg)
      (indent-region beg end nil))))

Solution 5 - Html

You can do a replace regexp

 M-x replace-regexp

 \(</[^>]+>\)

 \1C-q-j

Indent the whole buffer

 C-x h
 M-x indent-region

Solution 6 - Html

This question is quite old, but I wasn't really happy with the various answers. A simple way to re-indent an HTML file, given that you are running a relatively newer version of emacs (I am running 24.4.1) is to:

  • open the file in emacs
  • mark the entire file with C-x h (note: if you would like to see what is being marked, add (setq transient-mark-mode t) to your .emacs file)
  • execute M-x indent-region

What's nice about this method is that it does not require any plugins (Conway's suggestion), it does not require a replace regexp (nevcx's suggestion), nor does it require switching modes (jfm3's suggestion). Jay's suggestion is in the right direction — in general, executing C-M-q will indent according to a mode's rules — for example, C-M-q works, in my experience, in js-mode and in several other modes. But neither html-mode nor nxml-mode do not seem to implement C-M-q.

Solution 7 - Html

In emacs 25, which I'm currently building from source, assuming you are in HTML mode, use
Ctrl-x
h

to select all, and then press Tab.

Solution 8 - Html

Tidy can do what you want, but only for whole buffer it seems (and the result is XHTML)

M-x tidy-buffer

Solution 9 - Html

You can pipe a region to xmllint (if you have it) using:

M-|
Shell command on region: xmllint --format -

The result will end up in a new buffer.

I do this with XML, and it works, though I believe xmllint needs certain other options to work with HTML or other not-perfect XML. nxml-mode will tell you if you have a well-formed document.

Solution 10 - Html

The easiest way to do it is via command line.

  • Make sure you have tidy installed
  • type tidy -i -m <<file_name>>

Note that -m option replaces the newly tidied file with the old one. If you don't want that, you can type tidy -i -o <<tidied_file_name>> <<untidied_file_name>>

The -i is for indentation. Alternatively, you can create a .tidyrc file that has settings such as

indent: auto
indent-spaces: 2
wrap: 72
markup: yes
output-xml: no
input-xml: no
show-warnings: yes
numeric-entities: yes
quote-marks: yes
quote-nbsp: yes
quote-ampersand: no
break-before-br: no
uppercase-tags: no
uppercase-attributes: no

This way all you have to do is type tidy -o <<tidied_file_name>> <<untidied_file_name>>.

For more just type man tidy on the command line.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionraldiView Question on Stackoverflow
Solution 1 - HtmlvavaView Answer on Stackoverflow
Solution 2 - Htmljfm3View Answer on Stackoverflow
Solution 3 - HtmlJayView Answer on Stackoverflow
Solution 4 - HtmljtahlbornView Answer on Stackoverflow
Solution 5 - HtmlnevcxView Answer on Stackoverflow
Solution 6 - HtmlabhillmanView Answer on Stackoverflow
Solution 7 - HtmlRussia Must Remove PutinView Answer on Stackoverflow
Solution 8 - HtmlChris ConwayView Answer on Stackoverflow
Solution 9 - HtmlGeoffView Answer on Stackoverflow
Solution 10 - Htmluser1454331View Answer on Stackoverflow