Exemplo n.º 1
0
class Css(CssBase):
    '''A :class:`css` element in python.

    .. attribute:: attributes

        List of css attributes for the css element.

    .. attribute:: children

        An ordered dictionary of children for this :class:`css` element.
        Children are either other :class:`css` elements or :class:`Mixin`.

    .. attribute:: parent

        The :class:`css` ancestor for this :class:`css` element.

    '''
    rendered = False
    _app = None
    _css_libs = None

    def __init__(self, tag=None, vars=None, app=None, known_libraries=None):
        self._tag = tag
        self._http = None
        self._parent = None
        self._children = OrderedDict()
        self._attributes = []
        if app:
            assert tag is None, 'app should be passed to the root element only'
            self._app = app
        if self._tag is None:
            known_libraries = known_libraries or lux.media_libraries
            self._css_libs = wsgi.Css(self.config('MEDIA_URL', '/media/'),
                                      known_libraries=known_libraries)
            self.variables = Variables() if vars is None else vars
            self.classes = Variables()
            self.classes.hover = 'hover'
            self.classes.active = 'active'
        elif not tag:
            raise ValueError('A tag must be defined')

    def clone(self):
        c = copy(self)
        c._parent = None
        c._children = OrderedDict(((name, [c.clone() for c in children])
                                   for name, children in
                                   self._children.items()))
        c._attributes = copy(self._attributes)
        return c

    @property
    def tag(self):
        '''The tag for this :class:`Css` element.

        Always defined unless this is the root instance.
        '''
        return self._full_tag(self._tag)

    @property
    def code(self):
        '''The code for this css tag.'''
        return self._tag or 'ROOT'

    @property
    def attributes(self):
        '''Css attributes for this element.'''
        return self._attributes

    @property
    def children(self):
        ''':class:`Css` children of this element.'''
        return self._children

    @property
    def parent(self):
        return self._parent

    @property
    def root(self):
        if self._parent:
            return self._parent.root
        else:
            return self

    @property
    def app(self):
        return self.root._app

    @property
    def http(self):
        if self._parent:
            return self._parent.http
        else:
            if self._http is None:
                self._http = HttpClient(loop=asyncio.new_event_loop())
            return self._http

    def __setitem__(self, name, value):
        if value is None or isinstance(value, Variables):
            return
        if isinstance(value, Mixin):
            raise TypeError('Cannot assign a Mixin to {0}. Use add instead.'
                            .format(name))
        name = name.replace('_', '-')
        self._attributes.append((name, value))

    def __getitem__(self, name):
        raise NotImplementedError('cannot get item')

    def config(self, name, default=None):
        return self.app.config.get(name, default) if self.app else default

    def css(self, tag, *components, **attributes):
        '''A child :class:`Css` elements.'''
        if tag:
            elems = [Css(t) for t in alltags(tag)]
        else:
            elems = [Css(tag)]
        for clone, css in enumerate(elems):
            for name, value in iteritems(attributes):
                css[name] = value
            css.set_parent(self)
            # Loop over components to add them to self
            for cl in components:
                if not isinstance(cl, list):
                    cl = (cl,)
                for c in cl:
                    css.add(c.clone() if clone else c)
        return elems[0] if len(elems) == 1 else elems

    def get_media_url(self, path):
        '''Build the url for a media path.
        '''
        libs = self.root._css_libs
        if libs:
            path = libs.absolute_path(path)
            if not path.startswith('http'):
                path = 'http:%s' % path
            return path
        else:
            raise RuntimeError('No css libs configured')

    def update(self, iterable):
        for name, value in mapping_iterator(iterable):
            self[name] = value

    def add(self, c):
        '''Add a child :class:`css` or a class:`Mixin`.'''
        if isinstance(c, CssBase):
            c.set_parent(self)

    def add_child(self, child):
        clist = self._children.get(child.code)
        if isinstance(clist, list) and child not in clist:
            clist.append(child)
        else:
            self._children[child.code] = [child]

    def add_stream(self, stream):
        '''Add css text to the element.'''
        self._children[stream] = stream

    def set_parent(self, parent):
        # Get the element if available
        if getattr(self, 'tag', False) is None:
            if parent:
                raise ValueError('Body cannot have parent')
            return self
        assert parent is not self, 'cannot set self as parent'
        # When switching parents, remove itself from current parent children
        if self._parent and self._parent is not parent:
            self._parent.remove(self)
        self._parent = parent
        self._parent.add_child(self)

    def destroy(self):
        '''Safely this :class:`css` from the body tree.'''
        parent = self.parent
        if parent:
            parent.remove(self)

    def remove(self, child):
        '''Safely remove *child* form this :class:`css` element.'''
        clist = self._children.get(child.code)
        if clist:
            try:
                clist.remove(child)
            except ValueError:
                pass
            if not clist:
                self._children.pop(child.code)

    def extend(self, elem):
        '''Extend by adding *elem* attributes and children.'''
        self._attributes.extend(elem._attributes)
        for child_list in itervalues(elem._children):
            for child in child_list:
                child.set_parent(self)

    def stream(self, whitespace=''):
        '''This function convert the :class:`css` element into a string.'''
        # First we execute mixins
        if self.rendered:
            raise RuntimeError('%s already rendered' % self)
        self.rendered = True
        children = self._children
        self._children = OrderedDict()
        for tag, clist in iteritems(children):
            for c in clist:
                c._parent = None
                s = c.set_parent(self)
                if s:   # the child (mixin) has return a string, added it.
                    yield (None, s)
        data = []
        for k, v in self._attributes:
            v = as_value(v)
            if v is not None:
                data.append('%s    %s: %s;' % (whitespace, k, v))
        if data:
            yield (self.tag, '\n'.join(data))
        # yield Mixins and children
        for child_list in itervalues(self._children):
            if isinstance(child_list, list):
                child = child_list[0]
                for c in child_list[1:]:
                    child.extend(c)
                for s in child.stream(whitespace):
                    yield s
            else:
                yield None, child_list

    def render(self, whitespace=''):
        '''Render the :class:`css` component and all its children'''
        od = OrderedDict()
        for tag, data in self.stream(whitespace):
            if data not in od:
                od[data] = []
            if tag:
                od[data].append(tag)

        def _():
            for data, tags in iteritems(od):
                if tags:
                    yield ',\n'.join(('%s%s' % (whitespace, t) for t in tags)
                                     ) + ' {'
                    yield data
                    yield whitespace + '}\n'
                else:
                    yield data
        return '\n'.join(_())

    def render_all(self, media_url=None, charset='utf-8'):
        root = self.root
        if media_url:
            root.variables.MEDIAURL = media_url
        start = time.time()
        body = root.render()
        created = datetime.fromtimestamp(int(start))
        nice_dt = round(time.time() - start, 2)
        intro = '''\
/*
------------------------------------------------------------------
------------------------------------------------------------------
Created by lux {0} in {1} seconds.
------------------------------------------------------------------
------------------------------------------------------------------ */

'''.format(created.isoformat(' '), nice_dt)
        return intro + body

    def dump(self, theme=None, dump_variables=False):
        root = self.root
        app = root.app
        if app:
            module = None
            # Import applications styles if available
            for extension in app.config['EXTENSIONS']:
                try:
                    module = import_module(extension)
                    if hasattr(module, 'add_css'):
                        module.add_css(root)
                        app.write('Imported style from "%s".' % extension)
                except ImportError as e:
                    app.write_err('Cannot import style %s: "%s".' %
                                   (extension, e))
        if dump_variables:
            data = root.variables.tojson()
            return json.dumps(data, indent=4)
        else:
            return root.render_all()

    ########################################################################
    ##    PRIVATE METHODS
    ########################################################################
    def _full_tag(self, tag):
        if self._parent and self._parent.tag:
            tag = '%s%s' % (self._parent.tag, tag)
        if tag:
            return tag[1:] if tag.startswith(' ') else tag
Exemplo n.º 2
0
def create_datagram_endpoint(event_loop, protocol_factory, local_addr,
                             remote_addr, family, proto, flags):
    if not (local_addr or remote_addr):
        if family == socket.AF_UNSPEC:
            raise ValueError('unexpected address family')
        addr_pairs_info = (((family, proto), (None, None)),)
    else:
        # join address by (family, protocol)
        addr_infos = OrderedDict()
        for idx, addr in enumerate((local_addr, remote_addr)):
            if addr is not None:
                assert isinstance(addr, tuple) and len(addr) == 2, (
                    '2-tuple is expected')
                infos = yield event_loop.getaddrinfo(
                    *addr, family=family, type=socket.SOCK_DGRAM,
                    proto=proto, flags=flags)
                if not infos:
                    raise OSError('getaddrinfo() returned empty list')
                for fam, _, pro, _, address in infos:
                    key = (fam, pro)
                    if key not in addr_infos:
                        addr_infos[key] = [None, None]
                    addr_infos[key][idx] = address

        # each addr has to have info for each (family, proto) pair
        addr_pairs_info = [
            (key, addr_pair) for key, addr_pair in addr_infos.items()
            if not ((local_addr and addr_pair[0] is None) or
                    (remote_addr and addr_pair[1] is None))]

        if not addr_pairs_info:
            raise ValueError('can not get address information')
    exceptions = []
    for ((family, proto),
         (local_address, remote_address)) in addr_pairs_info:
        sock = None
        l_addr = None
        r_addr = None
        try:
            sock = socket.socket(
                family=family, type=socket.SOCK_DGRAM, proto=proto)
            sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            sock.setblocking(False)
            if local_addr:
                sock.bind(local_address)
                l_addr = sock.getsockname()
            if remote_addr:
                yield event_loop.sock_connect(sock, remote_address)
                r_addr = remote_address
        except OSError as exc:
            if sock is not None:
                sock.close()
            exceptions.append(exc)
        else:
            break
    else:
        raise exceptions[0]
    protocol = protocol_factory()
    transport = SocketDatagramTransport(event_loop, sock, protocol, r_addr,
                                        extra={'addr': l_addr})
    yield transport, protocol
Exemplo n.º 3
0
class Css(CssBase):
    '''A :class:`css` element in python.

    .. attribute:: attributes

        List of css attributes for the css element.

    .. attribute:: children

        An ordered dictionary of children for this :class:`css` element.
        Children are either other :class:`css` elements or :class:`Mixin`.

    .. attribute:: parent

        The :class:`css` ancestor for this :class:`css` element.

    '''
    rendered = False
    theme = None
    _app = None
    _css_libs = None

    def __init__(self, tag=None, vars=None, app=None):
        self._tag = tag
        self._http = None
        self._parent = None
        self._children = OrderedDict()
        self._attributes = []
        if app:
            assert tag is None, 'app should be passed to the root element only'
            self._app = app
        if self._tag is None:
            self._css_libs = wsgi.Links(self.config('MEDIA_URL', '/media/'))
            self.variables = Variables() if vars is None else vars
            self.classes = Variables()
            self.classes.hover = 'hover'
            self.classes.active = 'active'
        elif not tag:
            raise ValueError('A tag must be defined')

    def clone(self):
        c = copy(self)
        c._parent = None
        c._children = OrderedDict(((name, [c.clone() for c in children])
                                   for name, children in
                                   self._children.items()))
        c._attributes = copy(self._attributes)
        return c

    @property
    def tag(self):
        '''The tag for this :class:`Css` element.

        Always defined unless this is the root instance.
        '''
        tag = self._tag
        if self._parent:
            ptag = self._parent.tag
            if ptag:
                tag = '%s%s' % (ptag, tag)
        if tag:
            return tag[1:] if tag.startswith(' ') else tag

    @property
    def code(self):
        '''The code for this css tag.'''
        return self._tag or 'ROOT'

    @property
    def attributes(self):
        '''Css attributes for this element.'''
        return self._attributes

    @property
    def children(self):
        ''':class:`Css` children of this element.'''
        return self._children

    @property
    def parent(self):
        return self._parent

    @property
    def root(self):
        if self._parent:
            return self._parent.root
        else:
            return self

    @property
    def app(self):
        return self.root._app

    @property
    def http(self):
        if self._parent:
            return self._parent.http
        else:
            if self._http is None:
                self._http = HttpClient(loop=asyncio.new_event_loop())
            return self._http

    def __setitem__(self, name, value):
        if value is None or isinstance(value, Variables):
            return
        if isinstance(value, Mixin):
            raise TypeError('Cannot assign a Mixin to {0}. Use add instead.'
                            .format(name))
        name = name.replace('_', '-')
        self._attributes.append((name, value))

    def __getitem__(self, name):
        raise NotImplementedError('cannot get item')

    def config(self, name, default=None):
        return self.app.config.get(name, default) if self.app else default

    def css(self, tag, *components, **attributes):
        '''A child :class:`Css` elements.'''
        if tag:
            elems = [Css(t) for t in alltags(tag)]
        else:
            elems = [Css(tag)]
        for clone, css in enumerate(elems):
            for name, value in attributes.items():
                css[name] = value
            css.set_parent(self)
            # Loop over components to add them to self
            for cl in components:
                if not isinstance(cl, list):
                    cl = (cl,)
                for c in cl:
                    css.add(c.clone() if clone else c)
        return elems[0] if len(elems) == 1 else elems

    def media(self, *type, **query):
        assert len(type) <= 1
        media = Media(type[0] if type else 'all', query)
        self.add(media)
        return media

    def get_media_url(self, path):
        '''Build the url for a media path.
        '''
        libs = self.root._css_libs
        if libs:
            path = libs.absolute_path(path)
            if not path.startswith('http'):
                path = 'http:%s' % path
            return path
        else:
            raise RuntimeError('No css libs configured')

    def update(self, iterable):
        for name, value in mapping_iterator(iterable):
            self[name] = value

    def add(self, c):
        '''Add a child :class:`css` or a class:`Mixin`.'''
        if isinstance(c, CssBase):
            c.set_parent(self)

    def add_child(self, child):
        clist = self._children.get(child.code)
        if isinstance(clist, list) and child not in clist:
            clist.append(child)
        else:
            self._children[child.code] = [child]

    def add_stream(self, stream):
        '''Add css text to the element.'''
        self._children[stream] = stream

    def set_parent(self, parent):
        # Get the element if available
        if getattr(self, 'tag', False) is None:
            if parent:
                raise ValueError('Body cannot have parent')
            return self
        assert parent is not self, 'cannot set self as parent'
        # When switching parents, remove itself from current parent children
        if self._parent and self._parent is not parent:
            self._parent.remove(self)
        self._parent = parent
        self._parent.add_child(self)

    def destroy(self):
        '''Safely this :class:`css` from the body tree.'''
        parent = self.parent
        if parent:
            parent.remove(self)

    def remove(self, child):
        '''Safely remove *child* form this :class:`css` element.'''
        clist = self._children.get(child.code)
        if clist:
            try:
                clist.remove(child)
            except ValueError:
                pass
            if not clist:
                self._children.pop(child.code)

    def extend(self, elem):
        '''Extend by adding *elem* attributes and children.'''
        self._attributes.extend(elem._attributes)
        for child_list in tuple(elem._children.values()):
            for child in child_list:
                child.set_parent(self)

    def stream(self, whitespace=''):
        '''This function convert the :class:`css` element into a string.'''
        # First we execute mixins
        if self.rendered:
            raise RuntimeError('%s already rendered' % self)
        self.rendered = True
        children = self._children
        self._children = OrderedDict()
        for tag, clist in children.items():
            for c in clist:
                c._parent = None
                s = c.set_parent(self)
                if s:   # the child (mixin) has return a string, added it.
                    yield (None, s)
        data = []
        for k, v in self._attributes:
            v = as_value(v)
            if v is not None:
                data.append('%s    %s: %s;' % (whitespace, k, v))
        if data:
            yield (self.tag, '\n'.join(data))
        # Mixins and children
        for child_list in self._children.values():
            if isinstance(child_list, list):
                child = child_list[0]
                for c in child_list[1:]:
                    child.extend(c)
                for s in child.stream(whitespace):
                    yield s
            else:
                yield None, child_list

    def render(self, whitespace=''):
        '''Render the :class:`css` component and all its children'''
        od = OrderedDict()
        for tag, data in self.stream(whitespace):
            if data not in od:
                od[data] = []
            if tag:
                od[data].append(tag)

        def _():
            for data, tags in od.items():
                if tags:
                    yield ',\n'.join(('%s%s' % (whitespace, t) for t in tags)
                                     ) + ' {'
                    yield data
                    yield whitespace + '}\n'
                else:
                    yield data
        return '\n'.join(_())

    def render_all(self, media_url=None, charset='utf-8'):
        root = self.root
        if media_url:
            root.variables.MEDIAURL = media_url
        start = time.time()
        body = root.render()
        created = datetime.fromtimestamp(int(start))
        nice_dt = round(time.time() - start, 2)
        intro = '''@charset "UTF-8";
/*
------------------------------------------------------------------
Created by lux in {1} seconds
Date: {0}

http://quantmind.github.io/lux/
------------------------------------------------------------------ */

'''.format(created.isoformat(' '), nice_dt)
        return intro + body

    def dump(self, theme=None, dump_variables=False):
        root = self.root
        root.theme = theme
        app = root.app
        if app:
            module = None
            # Import applications styles if available
            exclude = app.config['EXCLUDE_EXTENSIONS_CSS'] or ()
            for extension in app.config['EXTENSIONS']:
                if extension in exclude:
                    continue
                try:
                    module = import_module(extension)
                    if hasattr(module, 'add_css'):
                        module.add_css(root)
                        app.write('Imported style from "%s".' % extension)
                except ImportError as e:
                    app.write_err('Cannot import style %s: "%s".' %
                                  (extension, e))
        if dump_variables:
            data = root.variables.tojson()
            return json.dumps(data, indent=4)
        else:
            return root.render_all()
Exemplo n.º 4
0
class Css(CssBase):
    """A :class:`css` element in python.

    .. attribute:: attributes

        List of css attributes for the css element.

    .. attribute:: children

        An ordered dictionary of children for this :class:`css` element.
        Children are either other :class:`css` elements or :class:`Mixin`.

    .. attribute:: parent

        The :class:`css` ancestor for this :class:`css` element.

    """

    rendered = False
    theme = None
    _app = None
    _css_libs = None

    def __init__(self, tag=None, vars=None, app=None):
        self._tag = tag
        self._http = None
        self._parent = None
        self._children = OrderedDict()
        self._attributes = []
        if app:
            assert tag is None, "app should be passed to the root element only"
            self._app = app
        if self._tag is None:
            self._css_libs = wsgi.Links(self.config("MEDIA_URL", "/media/"))
            self.variables = Variables() if vars is None else vars
            self.classes = Variables()
            self.classes.hover = "hover"
            self.classes.active = "active"
        elif not tag:
            raise ValueError("A tag must be defined")

    def clone(self):
        c = copy(self)
        c._parent = None
        c._children = OrderedDict(((name, [c.clone() for c in children]) for name, children in self._children.items()))
        c._attributes = copy(self._attributes)
        return c

    @property
    def tag(self):
        """The tag for this :class:`Css` element.

        Always defined unless this is the root instance.
        """
        tag = self._tag
        if self._parent:
            ptag = self._parent.tag
            if ptag:
                tag = "%s%s" % (ptag, tag)
        if tag:
            return tag[1:] if tag.startswith(" ") else tag

    @property
    def code(self):
        """The code for this css tag."""
        return self._tag or "ROOT"

    @property
    def attributes(self):
        """Css attributes for this element."""
        return self._attributes

    @property
    def children(self):
        """:class:`Css` children of this element."""
        return self._children

    @property
    def parent(self):
        return self._parent

    @property
    def root(self):
        if self._parent:
            return self._parent.root
        else:
            return self

    @property
    def app(self):
        return self.root._app

    @property
    def http(self):
        if self._parent:
            return self._parent.http
        else:
            if self._http is None:
                self._http = HttpClient(loop=asyncio.new_event_loop())
            return self._http

    def __setitem__(self, name, value):
        if value is None or isinstance(value, Variables):
            return
        if isinstance(value, Mixin):
            raise TypeError("Cannot assign a Mixin to {0}. Use add instead.".format(name))
        name = name.replace("_", "-")
        self._attributes.append((name, value))

    def __getitem__(self, name):
        raise NotImplementedError("cannot get item")

    def config(self, name, default=None):
        return self.app.config.get(name, default) if self.app else default

    def css(self, tag, *components, **attributes):
        """A child :class:`Css` elements."""
        if tag:
            elems = [Css(t) for t in alltags(tag)]
        else:
            elems = [Css(tag)]
        for clone, css in enumerate(elems):
            for name, value in attributes.items():
                css[name] = value
            css.set_parent(self)
            # Loop over components to add them to self
            for cl in components:
                if not isinstance(cl, list):
                    cl = (cl,)
                for c in cl:
                    css.add(c.clone() if clone else c)
        return elems[0] if len(elems) == 1 else elems

    def media(self, *type, **query):
        assert len(type) <= 1
        media = Media(type[0] if type else "all", query)
        self.add(media)
        return media

    def get_media_url(self, path):
        """Build the url for a media path.
        """
        libs = self.root._css_libs
        if libs:
            path = libs.absolute_path(path)
            if not path.startswith("http"):
                path = "http:%s" % path
            return path
        else:
            raise RuntimeError("No css libs configured")

    def update(self, iterable):
        for name, value in mapping_iterator(iterable):
            self[name] = value

    def add(self, c):
        """Add a child :class:`css` or a class:`Mixin`."""
        if isinstance(c, CssBase):
            c.set_parent(self)

    def add_child(self, child):
        clist = self._children.get(child.code)
        if isinstance(clist, list) and child not in clist:
            clist.append(child)
        else:
            self._children[child.code] = [child]

    def add_stream(self, stream):
        """Add css text to the element."""
        self._children[stream] = stream

    def set_parent(self, parent):
        # Get the element if available
        if getattr(self, "tag", False) is None:
            if parent:
                raise ValueError("Body cannot have parent")
            return self
        assert parent is not self, "cannot set self as parent"
        # When switching parents, remove itself from current parent children
        if self._parent and self._parent is not parent:
            self._parent.remove(self)
        self._parent = parent
        self._parent.add_child(self)

    def destroy(self):
        """Safely this :class:`css` from the body tree."""
        parent = self.parent
        if parent:
            parent.remove(self)

    def remove(self, child):
        """Safely remove *child* form this :class:`css` element."""
        clist = self._children.get(child.code)
        if clist:
            try:
                clist.remove(child)
            except ValueError:
                pass
            if not clist:
                self._children.pop(child.code)

    def extend(self, elem):
        """Extend by adding *elem* attributes and children."""
        self._attributes.extend(elem._attributes)
        for child_list in tuple(elem._children.values()):
            for child in child_list:
                child.set_parent(self)

    def stream(self, whitespace=""):
        """This function convert the :class:`css` element into a string."""
        # First we execute mixins
        if self.rendered:
            raise RuntimeError("%s already rendered" % self)
        self.rendered = True
        children = self._children
        self._children = OrderedDict()
        for tag, clist in children.items():
            for c in clist:
                c._parent = None
                s = c.set_parent(self)
                if s:  # the child (mixin) has return a string, added it.
                    yield (None, s)
        data = []
        for k, v in self._attributes:
            v = as_value(v)
            if v is not None:
                data.append("%s    %s: %s;" % (whitespace, k, v))
        if data:
            yield (self.tag, "\n".join(data))
        # Mixins and children
        for child_list in self._children.values():
            if isinstance(child_list, list):
                child = child_list[0]
                for c in child_list[1:]:
                    child.extend(c)
                for s in child.stream(whitespace):
                    yield s
            else:
                yield None, child_list

    def render(self, whitespace=""):
        """Render the :class:`css` component and all its children"""
        od = OrderedDict()
        for tag, data in self.stream(whitespace):
            if data not in od:
                od[data] = []
            if tag:
                od[data].append(tag)

        def _():
            for data, tags in od.items():
                if tags:
                    yield ",\n".join(("%s%s" % (whitespace, t) for t in tags)) + " {"
                    yield data
                    yield whitespace + "}\n"
                else:
                    yield data

        return "\n".join(_())

    def render_all(self, media_url=None, charset="utf-8"):
        root = self.root
        if media_url:
            root.variables.MEDIAURL = media_url
        start = time.time()
        body = root.render()
        created = datetime.fromtimestamp(int(start))
        nice_dt = round(time.time() - start, 2)
        intro = """@charset "UTF-8";
/*
------------------------------------------------------------------
Created by lux in {1} seconds
Date: {0}

http://quantmind.github.io/lux/
------------------------------------------------------------------ */

""".format(
            created.isoformat(" "), nice_dt
        )
        return intro + body

    def dump(self, theme=None, dump_variables=False):
        root = self.root
        root.theme = theme
        app = root.app
        if app:
            module = None
            # Import applications styles if available
            exclude = app.config["EXCLUDE_EXTENSIONS_CSS"] or ()
            for extension in app.config["EXTENSIONS"]:
                if extension in exclude:
                    continue
                try:
                    module = import_module(extension)
                    if hasattr(module, "add_css"):
                        module.add_css(root)
                        app.write('Imported style from "%s".' % extension)
                except ImportError as e:
                    app.write_err('Cannot import style %s: "%s".' % (extension, e))
        if dump_variables:
            data = root.variables.tojson()
            return json.dumps(data, indent=4)
        else:
            return root.render_all()