Add new module for preview renderers

master
Dustin 2015-03-07 17:12:34 -06:00
parent fc39747acc
commit 3f95de7e49
2 changed files with 76 additions and 15 deletions

View File

@ -1,4 +1,4 @@
import docutils.core
from . import markup
import jinja2
import milla.controllers
@ -37,7 +37,7 @@ class IndexController(BaseController):
response = request.ResponseClass()
try:
content = request.POST['content']
preview = PreviewController.rst2html(content)
preview = markup.get_previewer(content).preview()
except KeyError:
content = preview = ''
response.text = self.render('index.html.j2', **dict(
@ -49,24 +49,13 @@ class IndexController(BaseController):
class PreviewController(BaseController):
DOCUTILS_SETTINGS = {
'syntax_highlight': 'short',
}
allowed_methods = ('HEAD', 'POST')
def __call__(self, request):
return getattr(self, request.method)(request)
@classmethod
def rst2html(cls, source):
return docutils.core.publish_parts(
source=source,
writer_name='html4css1',
settings_overrides=cls.DOCUTILS_SETTINGS,
)['html_body']
def POST(self, request):
response = request.ResponseClass()
response.text = self.rst2html(request.text)
previewer = markup.get_previewer(request.text)
response.text = previewer.preview()
return response

72
src/rstpreview/markup.py Normal file
View File

@ -0,0 +1,72 @@
import markupsafe
try:
import docutils.core
except ImportError:
docutils = None
def get_previewer(source):
lines = source.splitlines()
for previewer in PreviewerMeta.previewers:
if previewer.detect(lines):
return previewer(source)
return DefaultPreviewer(source)
class PreviewerMeta(type):
previewers = []
def __new__(mcs, name, bases, attrs):
cls = type.__new__(mcs, name, bases, attrs)
if hasattr(cls, 'detect'):
mcs.previewers.append(cls)
return cls
Previewer = PreviewerMeta('Previewer', (), {})
class BasePreviewer(Previewer):
def __init__(self, source):
self.source = source
class ReStructuredTextPreviewer(BasePreviewer):
DOCUTILS_SETTINGS = {
'syntax_highlight': 'short',
}
@classmethod
def detect(cls, lines):
if docutils is None:
return False
for idx, line in enumerate(lines):
if line.startswith('.. '): # directives, comments
return True
if line.endswith('::'): # directive, literal block
return True
if '``' in line: # default role
return True
if ':`' in line: # role
return True
def preview(self):
return docutils.core.publish_parts(
source=self.source,
writer_name='html4css1',
settings_overrides=self.DOCUTILS_SETTINGS,
)['html_body']
class PlainTextPreviewer(BasePreviewer):
def preview(self):
return '<pre>{0}</pre>'.format(markupsafe.escape(self.source))
if docutils is not None:
DefaultPreviewer = ReStructuredTextPreviewer
else:
DefaultPreviewer = PlainTextPreviewer