Created
October 7, 2012 03:24
Rendering ReST with Twisted Templates
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import const, fragments, renderer | |
class ContentPage(BasePage): | |
""" | |
Note that the BasePage class is not included in this | |
example. It and its parent class manage template | |
loading, slot-filling, etc. | |
""" | |
contentType = const.contentTypes["rst"] | |
contentData = "" | |
# Hobo caching | |
_cachedContent = "" | |
def renderContentData(self): | |
if not self._cachedContent: | |
if self.contentType == const.contentTypes["rst"]: | |
self._cachedContent = renderer.ReSTContent( | |
self.contentData) | |
elif self.contentType == const.contentTypes["html"]: | |
self._cachedContent = self.contentData | |
return self._cachedContent | |
@renderer | |
def topnav(self, request, tag): | |
return fragments.TopNavFragment() | |
@renderer | |
def contentarea(self, request, tag): | |
return fragments.ContentFragment(self.renderContentData()) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from twisted.web.iweb import IRenderable | |
from zope.interface import implements | |
class ReSTContent(object): | |
""" | |
Though not strictly necessary as a dedicated class, I wanted to | |
put this code here to assist with organization of content type | |
renderers, as this will not be the only one. | |
""" | |
implements(IRenderable) | |
def __init__(self, rstData): | |
self.rstData = rstData | |
def render(self, request): | |
return utils.rstToStan(self.rstData) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from docutils.core import publish_string as render_rst | |
from twisted.web.template import Tag, XMLString | |
def rstToHTML(rst): | |
overrides = { | |
'output_encoding': 'unicode', | |
'input_encoding': 'unicode' | |
} | |
return render_rst( | |
rst.decode("utf-8"), writer_name="html", | |
settings_overrides=overrides) | |
def checkTag(tag): | |
if isinstance(tag, basestring): | |
return False | |
return True | |
def rstToStan(rst): | |
html = rstToHTML(rst) | |
# fix a bad encoding in docutils | |
html = html.replace('encoding="unicode"', '') | |
stan = XMLString(html).load()[0] | |
# we're always going to get the same structure back, at least | |
# for the installed version of docutils, so let's trip out the | |
# crap that we don't need (also, let's safeguard against future | |
# changes) | |
if stan.tagName != "html": | |
raise ValueError("Unexpected top-level HTML tag.") | |
# let's ditch the children whose sole contents are "\n" strings | |
head, body = [x for x in stan.children if checkTag(x)] | |
if head.tagName != "head": | |
raise ValueError("Expected 'head' node, got '%s'" % ( | |
head.tagName)) | |
if body.tagName != "body": | |
raise ValueError("Expected 'body' node, got '%s'" % ( | |
body.tagName)) | |
# by just returning the contents of the body tag, we're avoiding | |
# all the CSS and, in fact, the complete HTML file that the | |
# docutils ReST renderer provides by default | |
return body.children |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment