emacs可以为我重新缩进HTML一大块吗?


69

在emacs中编辑HTML时,有没有一种方法可以自动漂亮地格式化标记的blob,并进行如下更改:

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

...变成这样:

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

1
在新版本的emacs中,这要容易得多。这是向下滚动的情况。
亚伦·霍尔

Answers:


30

默认情况下,当您.html在Emacs(22或23)中访问文件时,它将进入html-mode。那可能不是您想要的。您可能想要nxml-mode,这真是太花哨了。nxml-mode似乎仅随Emacs 23一起提供,尽管您可以从nXML网站上下载它以用于早期版本的emacs 。还有一个名为的Debian和Ubuntu软件包nxml-mode。您可以输入nxml-mode

M-x nxml-mode

您可以使用以下方法查看nxml模式文档:

C-h i g (nxml-mode) RET

话虽如此,您可能必须使用Tidy之类的格式来重新格式化xhtml示例。 nxml-mode会让你从

<!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>

<!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>

但是我没有看到更通用的工具来根据需要对某些xml标签进行换行。请注意,这C-j会插入带有适当缩进的新行,因此您可以执行快速宏操作或修改defun将用于表的内容。


12
进入nxml-mode后,我使用Cx h选择整个区域,然后选择Mx'indent-region'。您将获得正确缩进的HTML。感谢nxml-mode!
zhanxw

2
nxml-mode无法正确缩进html片段,可能是因为它们没有doctype。一旦您得到换行符,如下面的
@nevcx

106

如果您处于html模式或nxml模式sgml-pretty-print,则可以indent-for-tab在相同的区域/缓冲区上执行操作。

sgml-pretty-print在适当的位置添加新行,并indent-for-tab添加漂亮的缩进。它们一起导致正确格式化的html / xml。


5
好答案。只要记住要暂时切换到sgml-mode即可运行sgml-pretty-print。然后回到nxml-mode。
cayhorstmann

5
sgml-pretty-print从HTML wode为我工作,没有任何模式切换,谢谢!
dolzenko

1
唯一有效的答案。我的意思是即使使用无效的XML(即只是HTML文件的一部分)。
Misha Tavkhelidze 2015年

13

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

选择要修复的区域后。(要选择整个缓冲区,请使用Cx h)

q

重新缩进一个括号组(indent-sexp)中的所有行。

厘米-\

重新缩进该区域(缩进区域)中的所有行。


4
这对我不起作用-在上面的示例中,CMq不执行任何操作,而CM- \则给出了完全不正确的缩进。
raldi

在nxml模式下也对我不起作用。index-sexp和indent-region将缩进已经有换行符的代码,此示例缺少一些。
贾斯汀·坦纳

1
CX h <ESC> x缩进区域
Richard Gomes

10

我自己编写了一个函数来针对xml进行此操作,该功能在nxml-mode下运行良好。对于html也应该很好地工作:

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

谢谢。我一直想要这个!
Christian Madsen

这实际上是最简单,最好的解决方案。我将经常使用它!谢谢!!!
本杰明·

为我工作。感觉也是最简单的解决方案。ta非常
cammil

8

您可以执行替换正则表达式

 M-x replace-regexp

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

 \1C-q-j

缩进整个缓冲区

 C-x h
 M-x indent-region

7

这个问题已经很老了,但是我对各种各样的答案并不满意。考虑到您正在运行相对较新版本的emacs(我正在运行24.4.1),一种重新缩进HTML文件的简单方法是:

  • 在emacs中打开文件
  • 标记整个文件C-x h(请注意:如果您想查看所标记的内容,请添加(setq transient-mark-mode t).emacs文件中)
  • 执行 M-x indent-region

这种方法的优点是它不需要任何插件(Conway的建议),不需要替换的regexp(nevcx的建议),也不需要切换模式(jfm3的建议)。Jay的建议是朝正确的方向进行的-通常来说,执行C-M-q将根据模式的规则进行缩进-例如C-M-q,以我的经验js-mode以及其他几种模式都可以工作。但是似乎html-modenxml-mode没有实现C-M-q


1
好答案。两行。完美地完成了所有工作!
托尼

跟进问题,您的解决方案不会缩进html中的javascript。您对此有任何简单快速的解决方案吗?谢谢。
托尼2015年

如果换行符已经在正确的位置,则此方法有效。sgml-pretty-print可以帮助解决此问题(但我认为仍然没有做出最佳选择)。
pnj 2015年


6

在我目前从源代码构建的emacs 25中,假设您处于HTML模式,请使用
Ctrl-x
h

选择全部,然后按Tab


4

您可以使用以下方法将区域通过管道传递给xmllint(如果有):

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

结果将最终存储在新缓冲区中。

尽管XMLlint需要某些其他选项才能与HTML或其他不完美的XML一起使用,但我使用XML做到了这一点,并且可以工作。nxml-mode会告诉您是否有格式正确的文档。


并使用前缀参数,shell-command-on-region将原始区域替换为shell命令的输出。即:C-u M-|
phils

谢谢,朋友,我知道该功能在那里,但不记得如何调用它!
Geoff

0

最简单的方法是通过命令行。

  • 确保您已安装整洁
  • 类型 tidy -i -m <<file_name>>

注意 -m选项将新整理的文件替换为旧的文件。如果您不想要,可以输入tidy -i -o <<tidied_file_name>> <<untidied_file_name>>

-i是缩进。或者,您可以创建一个.tidyrc具有以下设置的文件:

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

这样,您要做的就是输入 tidy -o <<tidied_file_name>> <<untidied_file_name>>

有关更多信息man tidy,请在命令行中键入。


Afaiu,这是从外壳中调用的。我认为他想要emacs中的解决方案。
Nikana Reklawyks 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.