import py |
from py.__.rest import rst |
from py.xml import html |
|
class RestTransformer(object): |
def __init__(self, tree): |
self.tree = tree |
self._titledepths = {} |
self._listmarkers = [] |
|
def parse(self, handler): |
handler.startDocument() |
self.parse_nodes(self.tree.children, handler) |
handler.endDocument() |
|
def parse_nodes(self, nodes, handler): |
for node in nodes: |
name = node.__class__.__name__ |
if name == 'Rest': |
continue |
getattr(self, 'handle_%s' % (name,))(node, handler) |
|
def handle_Title(self, node, handler): |
depthkey = (node.abovechar, node.belowchar) |
if depthkey not in self._titledepths: |
if not self._titledepths: |
depth = 1 |
else: |
depth = max(self._titledepths.values()) + 1 |
self._titledepths[depthkey] = depth |
else: |
depth = self._titledepths[depthkey] |
handler.startTitle(depth) |
self.parse_nodes(node.children, handler) |
handler.endTitle(depth) |
|
def handle_ListItem(self, node, handler): |
|
startlist = False |
c = node.parent.children |
nodeindex = c.index(node) |
if nodeindex == 0: |
startlist = True |
else: |
prev = c[nodeindex - 1] |
if not isinstance(prev, rst.ListItem): |
startlist = True |
elif prev.indent < node.indent: |
startlist = True |
endlist = False |
if nodeindex == len(c) - 1: |
endlist = True |
else: |
next = c[nodeindex + 1] |
if not isinstance(next, rst.ListItem): |
endlist = True |
elif next.indent < node.indent: |
endlist = True |
type = isinstance(node, rst.OrderedListItem) and 'o' or 'u' |
handler.startListItem('u', startlist) |
self.parse_nodes(node.children, handler) |
handler.endListItem('u', endlist) |
|
def handle_Transition(self, node, handler): |
handler.handleTransition() |
|
def handle_Paragraph(self, node, handler): |
handler.startParagraph() |
self.parse_nodes(node.children, handler) |
handler.endParagraph() |
|
def handle_SubParagraph(self, node, handler): |
handler.startSubParagraph() |
self.parse_nodes(node.children, handler) |
handler.endSubParagraph() |
|
def handle_LiteralBlock(self, node, handler): |
handler.handleLiteralBlock(node._text) |
|
def handle_Text(self, node, handler): |
handler.handleText(node._text) |
|
def handle_Em(self, node, handler): |
handler.handleEm(node._text) |
|
def handle_Strong(self, node, handler): |
handler.handleStrong(node._text) |
|
def handle_Quote(self, node, handler): |
handler.handleQuote(node._text) |
|
def handle_Link(self, node, handler): |
handler.handleLink(node._text, node.target) |
|
def entitize(txt): |
for char, repl in (('&', 'amp'), ('>', 'gt'), ('<', 'lt'), ('"', 'quot'), |
("'", 'apos')): |
txt = txt.replace(char, '&%s;' % (repl,)) |
return txt |
|
class HTMLHandler(object): |
def __init__(self, title='untitled rest document'): |
self.title = title |
self.root = None |
self.tagstack = [] |
self._currlist = None |
|
def startDocument(self): |
h = html.html() |
self.head = head = html.head() |
self.title = title = html.title(self.title) |
self._push(h) |
h.append(head) |
h.append(title) |
self.body = body = html.body() |
self._push(body) |
|
def endDocument(self): |
self._pop() |
self._pop() |
|
def startTitle(self, depth): |
h = getattr(html, 'h%s' % (depth,))() |
self._push(h) |
|
def endTitle(self, depth): |
self._pop() |
|
def startParagraph(self): |
self._push(html.p()) |
|
def endParagraph(self): |
self._pop() |
|
def startSubParagraph(self): |
self._push(html.p(**{'class': 'sub'})) |
|
def endSubParagraph(self): |
self._pop() |
|
def handleLiteralBlock(self, text): |
pre = html.pre(text) |
if self.tagstack: |
self.tagstack[-1].append(pre) |
else: |
self.root = pre |
|
def handleText(self, text): |
self.tagstack[-1].append(text) |
|
def handleEm(self, text): |
self.tagstack[-1].append(html.em(text)) |
|
def handleStrong(self, text): |
self.tagstack[-1].append(html.strong(text)) |
|
def startListItem(self, type, startlist): |
if startlist: |
nodename = type == 'o' and 'ol' or 'ul' |
self._push(getattr(html, nodename)()) |
self._push(html.li()) |
|
def endListItem(self, type, closelist): |
self._pop() |
if closelist: |
self._pop() |
|
def handleLink(self, text, target): |
self.tagstack[-1].append(html.a(text, href=target)) |
|
def _push(self, el): |
if self.tagstack: |
self.tagstack[-1].append(el) |
else: |
self.root = el |
self.tagstack.append(el) |
|
def _pop(self): |
self.tagstack.pop() |
|
def _html(self): |
return self.root.unicode() |
html = property(_html) |
|
|