pmacs3/mode/html.py

116 lines
4.5 KiB
Python

import os
import urllib.request, urllib.parse, urllib.error
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, '</(?=script>)', TagGrammar, '>'),
RegionRule('html.tag', '<(?=style[^a-zA-Z0-9_])', TagGrammar, '>',
CSSGrammar, '</(?=style>)', TagGrammar, '>'),
RegionRule('comment', r'<!--', CommentGrammar, r'-->'),
RegionRule('html.tag', r'<(?![\?!])', TagGrammar, r'/?>'),
RegionRule('html.metadata', r'<\?', MetadataGrammar, r'\?>'),
RegionRule('html.doctype', r'<!', DoctypeGrammar, r'>'),
PatternRule('html.entity', r'&[a-z]+;'),
RegionRule('html.cdata', r'<!\[CDATA\[', CDataGrammar, 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.parse.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