I'm using sublime text for my HTML editing but I found that I needed to re-format my old code and sublime-text doesn't have that functionality built in.
Sublime-text does have rather nice python integration for easy plugin development so I did a little search, found this chap's website (http://www.bergspot.com/blog/2012/05/formatting-xml-in-sublime-text-2-xmllint/) and adapted his code, which makes use of xmllint (a unix tool but here's a windows version: http://code.google.com/p/xmllint/).
My version doesn't need the text to be selected (if text is selected, only that part will be beautified) and will shows a pop-up error message and also takes you to the error line.
Anyhow, here's the code:
import sublime, sublime_plugin, subprocess
def find_lint_error_line(errString):
startpos = errString.find("-:")
endpos = -1
err_line = -1;
if startpos != -1:
startpos += 2
endpos = errString.find(":", startpos)
if endpos != -1:
numstr = errString[startpos:endpos]
if numstr.isdigit():
err_line = int(numstr)
return err_line
class TidyXmlLintCommand(sublime_plugin.TextCommand):
def run(self, edit):
command = "XMLLINT_INDENT='\t' xmllint --format --encode utf-8 -"
self.view.set_status('self', "")
#xmllint.view.set_status('Hey there Tim', "Hey hey hey")
# help from http://www.sublimetext.com/forum/viewtopic.php?f=2&p=12451
xmlRegion = sublime.Region(0, self.view.size())
p = subprocess.Popen(command, bufsize=-1, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=True)
sel_regions = self.view.sel()
selection = sel_regions[0]
sel_region_count = len(selection)
if sel_region_count == 0:
selection = xmlRegion
result, err = p.communicate(self.view.substr(selection).encode('utf-8'))
if err != "":
self.view.set_status('xmllint', "xmllint: "+err)
error_line = find_lint_error_line(err)
#err.parse()
#lines[] = parse("line {}", err)
if error_line != -1:
pt = self.view.text_point(error_line, 0)
self.view.sel().clear()
self.view.sel().add(sublime.Region(pt))
self.view.show_at_center(pt)
#self.view.set_viewport_position((0, error_line * 16), True)
else:
sublime.message_dialog('could not find error line')
sublime.message_dialog('xmllint, error at line: '+ str(error_line) + " \n" + err )
sublime.set_timeout(self.clear,10000)
else:
self.view.replace(edit, self.view.sel()[0], result.decode('utf-8'))
sublime.set_timeout(self.clear,0)
def clear(self):
self.view.erase_status('xmllint')
And if you're wondering how I did that nice syntax colouring on the python code, check this out:
SyntaxHighlighter