Skip to content

Instantly share code, notes, and snippets.

@rbistolfi
Created June 11, 2012 23:10
Show Gist options
  • Save rbistolfi/2913327 to your computer and use it in GitHub Desktop.
Save rbistolfi/2913327 to your computer and use it in GitHub Desktop.
Seaside like HTMLCanvas in Python
# coding: utf8
"""
Proof of concept of a Seaside like HTMLCanvas object
>>> html = HTMLCanvas()
>>> with html.div(id="content"):
>>> with html.ul():
>>> html.li("Foo")
>>> html.li("Bar")
>>> str(html)
<div><div id="content"><ul><li>Foo</li><li>Bar</li></ul></div></div>
"""
__all__ = [ "HTMLCanvas" ]
from xml.etree import ElementTree as et
class HTMLCanvas(object):
"""HTMLCanvas is a TagBrush factory with a root tag
"""
def __init__(self, root=None):
"""Set the root element
"""
self.root = root if root is not None else TagBrush("div", self)
self.nesting_level = 0
def __getattr__(self, name):
"""Create a new brush and append it to the root.
"""
return TagBrush(name, self)
def __str__(self):
"""The root contains the html
"""
return str(self.root)
def increase_nesting_level(self):
"""Increase the nesting level by one. If bigger than 0, new
elements will be added to the last element instead of the root.
"""
self.nesting_level += 1
def decrease_nesting_level(self):
"""Decrease the nesting level by one
"""
self.nesting_level -= 1
class TagBrush(object):
"""A Tag Brush for painting in the html canvas.
"""
def __init__(self, element, canvas=None):
self.element = et.Element(element)
self.canvas = canvas
def __call__(self, text=None, **attrs):
"""Set the contents of the element and add it to the tree root
"""
if text is not None:
self.element.text = text
self.element.attrib.update(attrs)
self.append_to_brush(self.canvas.root)
return self
def __str__(self):
"""Return the html string
"""
return et.tostring(self.element)
def __enter__(self):
"""Increase the nesting level. All the elements added after this
will be childs of the last element in the tree
"""
self.canvas.increase_nesting_level()
return self
def __exit__(self, *_):
"""Decrease the nesting level, producing the closing tag
"""
self.canvas.decrease_nesting_level()
def add_child_brush(self, brush):
"""Add a new element to the canvas root tree
"""
self.canvas.root.element.append(brush.element)
return brush
def append_brush(self, brush):
"""Add an element to the last element in the tree
"""
element = self.canvas.root.element
nesting_level = self.canvas.nesting_level
while nesting_level > 0:
element = element[-1]
nesting_level -= 1
element.append(brush.element)
return brush
def append_to_brush(self, brush):
"""Append self to the brush object
"""
if self.canvas.nesting_level == 0:
brush.add_child_brush(self)
else:
brush.append_brush(self)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment