import os, urllib import color, default, method, mode from lex import Grammar, PatternRule, RegionRule from mode.xml import TagGrammar from mode.javascript import JavascriptGrammar from mode.css import CSSGrammar class CommentGrammar(Grammar): rules = [PatternRule(r'data', r'(?:[^-]|-(?!-)|--(?!>))+')] class HTMLGrammar(Grammar): rules = [ # TODO: how does cdata work again? RegionRule(r'comment', r''), # BUG: not all scripts are javascript and not all styles are CSS but # dynamically choosing a grammar based on the 'type' attribute (which # may be on a different line) is impractical. RegionRule(r'script', r'<(?=script[^a-zA-Z0-9_])', TagGrammar, r'>', JavascriptGrammar, r')', TagGrammar, r'>'), RegionRule(r'style', r'<(?=style[^a-zA-Z0-9_])', TagGrammar, r'>', CSSGrammar, r')', TagGrammar, r'>'), RegionRule(r'tag', r''), PatternRule(r'entity', r'&.*?;'), ] class HtmlViewPage(method.Method): '''View the HTML data in a browser (curses or external)''' def _execute(self, w, **vargs): viewcmd = w.application.config.get('html.viewcmd') viewbg = viewcmd.endswith('&') if viewbg: viewcmd = viewcmd[:-1] argv = (viewcmd, w.buffer.path) if viewbg: if os.fork() == 0: try: os.execvp(viewcmd, argv) except OSError: os._exit(1) else: w.application.run_external(*argv) class HtmlValidatePage(method.Method): '''View the HTML data in a browser (curses or external)''' args = [method.arg('url', dv=default.build_mode_var('url'), ld=True, h='')] base = 'http://validator.w3.org/check?' def _execute(self, w, **vargs): w.mode.url = vargs['url'] viewcmd = w.application.config.get('html.viewcmd') viewbg = viewcmd.endswith('&') if viewbg: viewcmd = viewcmd[:-1] urlarg = urllib.urlencode({'uri': w.mode.url}) argv = (viewcmd, self.base + urlarg) if viewbg: if os.fork() == 0: try: os.execvp(viewcmd, argv) except OSError: os._exit(1) else: w.application.run_external(*argv) class HtmlCheckSpelling(method.Method): """Check the spelling of the document via ispell -t""" def _execute(self, w, **vargs): # -x no backup file # -M show context menu # -H treat input document as HTML if w.buffer.changed(): w.set_error("There are unsaved changes; please save first.") return w.application.run_external('ispell', '-x', '-M', '-H', w.buffer.path) if w.buffer.changed_on_disk(): w.buffer.reload() class HTML(mode.Fundamental): modename = 'HTML' extensions = ['.html', '.htm', '.shtml', '.shtm', '.xhtml'] grammar = HTMLGrammar colors = { 'entity': ('magenta', 'default', 'bold'), } config = { 'html.viewcmd': 'firefox&', #'html.viewcmd': 'links', } _colorbase = { 'start': ('default', 'default', 'bold'), 'namespace': ('magenta', 'default', 'bold'), 'name': ('blue', 'default', 'bold'), 'attrname': ('cyan', 'default', 'bold'), 'string.start': ('green', 'default', 'bold'), 'string.null': ('green', 'default', 'bold'), 'string.end': ('green', 'default', 'bold'), 'end': ('default', 'default', 'bold'), } for _name in _colorbase: colors['script.%s' % _name] = _colorbase[_name] colors['style.%s' % _name] = _colorbase[_name] colors['tag.%s' % _name] = _colorbase[_name] actions = [HtmlViewPage, HtmlValidatePage, HtmlCheckSpelling] def __init__(self, w): mode.Fundamental.__init__(self, w) self.add_bindings('close-paren', (')',)) self.add_bindings('close-brace', ('}',)) self.add_bindings('close-bracket', (']',)) self.add_bindings('xml-create-tag', ('M-t',)) self.url = None install = HTML.install