Add new module for preview renderers
parent
fc39747acc
commit
3f95de7e49
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue