pmacs3/mode/html.py

112 lines
4.2 KiB
Python

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'<!--', CommentGrammar, 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'</(?=script>)', TagGrammar, r'>'),
RegionRule(r'style', r'<(?=style[^a-zA-Z0-9_])', TagGrammar, r'>', CSSGrammar, r'</(?=style>)', TagGrammar, r'>'),
RegionRule(r'tag', r'</?', TagGrammar, 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