import os import urllib import default import method from mode import Fundamental from lex import Grammar, PatternRule, RegionRule from mode.xml import TagGrammar, CommentGrammar, MetadataGrammar, CDataGrammar from mode.javascript import JavascriptGrammar from mode.css import CSSGrammar class DoctypeGrammar(Grammar): rules = [PatternRule('data', '[^>]+')] class HTMLGrammar(Grammar): rules = [ PatternRule(r'escaped', r'&[^;]+;'), PatternRule(r'html.data', 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('html.tag', '<(?=script[^a-zA-Z0-9_])', TagGrammar, '>', JavascriptGrammar, ')', TagGrammar, '>'), RegionRule('html.tag', '<(?=style[^a-zA-Z0-9_])', TagGrammar, '>', CSSGrammar, ')', TagGrammar, '>'), RegionRule('comment', r''), RegionRule('html.tag', r'<(?![\?!])', TagGrammar, r'/?>'), RegionRule('html.metadata', r'<\?', MetadataGrammar, r'\?>'), RegionRule('html.doctype', r''), PatternRule('html.entity', r'&[a-z]+;'), RegionRule('html.cdata', 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(Fundamental): name = 'HTML' extensions = ['.html', '.htm', '.shtml', '.shtm', '.xhtml', '.xhtm'] grammar = HTMLGrammar colors = { 'html.entity': ('magenta', 'default', 'bold'), 'html.metadata.start': ('magenta', 'default', 'bold'), 'html.metadata.data': ('magenta', 'default', 'bold'), 'html.metadata.end': ('magenta', 'default', 'bold'), 'html.doctype.start': ('magenta', 'default', 'bold'), 'html.doctype.data': ('magenta', 'default', 'bold'), 'html.doctype.end': ('magenta', 'default', 'bold'), 'html.tag.start': ('default', 'default', 'bold'), 'html.tag.namespace': ('magenta', 'default', 'bold'), 'html.tag.name': ('blue', 'default', 'bold'), 'html.tag.attrname': ('cyan', 'default', 'bold'), 'html.tag.end': ('default', 'default', 'bold'), } config = { 'html.viewcmd': 'firefox&', #'html.viewcmd': 'links', } actions = [HtmlViewPage, HtmlValidatePage, HtmlCheckSpelling] _bindings = { 'close-paren': (')',), 'close-brace': ('}',), 'close-bracket': (']',), 'xml-create-tag': ('M-t',), } url = None install = HTML.install