1 # -*- coding: utf-8 -*-
3 # This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
4 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
7 from . import UnicodeException
8 from .utils import extend_element
11 class UnknownElement(UnicodeException):
15 class Renderer(object):
16 """ Renders an element in a context to some kind of container. """
17 def render(self, element, ctx):
18 """ Renders the element in the context. """
21 def render_text(self, text, ctx):
22 """ Renders the text in the context. """
26 class TreeRenderer(Renderer):
27 """ Renders insides as XML in a <_/> container. """
30 def __init__(self, tag_name=None, attrib=None):
31 self.tag_name = tag_name
32 self.attrib = attrib or {}
35 root = etree.Element(self.root_name)
37 inner = etree.Element(self.tag_name, **self.attrib)
43 def text_container(self):
44 root = etree.Element(self.root_name)
47 def subcontext(self, element, ctx):
50 def get_insides(self, element, ctx):
51 subctx = self.subcontext(element, ctx)
53 yield self.render_text(element.text, ctx)
56 yield ctx.format.render(child, subctx)
57 except UnknownElement:
60 yield self.render_text(child.tail, ctx)
62 def render(self, element, ctx):
63 root, inner = self.container()
64 for inside in self.get_insides(element, ctx):
65 extend_element(inner, inside)
68 def render_text(self, text, ctx):
69 root, inner = self.text_container()
74 class Register(object):
75 """ Class-renderer register.
77 >>> from librarian.core import Div
78 >>> renderer = Renderer()
80 >>> reg.register(Div, 'a.b', renderer)
81 >>> reg.get(Div, 'a.b.c') is renderer
88 def register(self, tag, klass, renderer):
89 self.classes[tag, klass] = renderer
91 def get(self, tag, klass=None):
94 return self.classes[tag, klass]
97 klass = klass.rsplit('.', 1)[-2]
101 return self.classes[tag, None]
103 raise UnknownElement(tag)
105 def get_for(self, element):
106 return self.get(type(element), element.get('class'))