0001"""Kid tranformations"""
0002
0003from __future__ import generators
0004
0005__revision__ = "$Rev: 53 $"
0006__date__ = "$Date: 2005-02-15 08:10:35 -0500 (Tue, 15 Feb 2005) $"
0007__author__ = "Ryan Tomayko (rtomayko@gmail.com)"
0008__copyright__ = "Copyright 2004-2005, Ryan Tomayko"
0009__license__ = "MIT <http://www.opensource.org/licenses/mit-license.php>"
0010
0011from types import GeneratorType
0012from kid.pull import ElementStream, START, XML_DECL,  _coalesce
0013from kid.namespace import Namespace
0014from template_util import generate_content
0015
0016def transform_filter(stream, template):
0017    templates = template._get_match_templates()
0018    def apply_func(item):
0019        return transform_filter(generate_content(item), template)
0020    stream = ElementStream.ensure(stream)
0021    for ev, item in apply_matches(stream, template, templates, apply_func):
0022        yield ev, item
0023
0024def apply_matches(stream, template, templates, apply_func):
0025    for ev, item in stream:
0026        if ev == START:
0027            matched = 0
0028            for i in range(0, len(templates)):
0029                (match, call) = templates[i]
0030                if match(item):
0031                    item = stream.expand()
0032                    newstream = _coalesce(call(template, item, apply_func), template._get_assume_encoding())
0033                    if i+1 < len(templates):
0034                        for ev, item in apply_matches(ElementStream(newstream),
0035                                                      template,
0036                                                      templates[i+1:],
0037                                                      apply_func):
0038                            yield ev, item
0039                    else:
0040                        for ev, item in newstream:
0041                            yield (ev, item)
0042                    matched = 1
0043                    break
0044            if matched: continue
0045        yield (ev, item)
0046
0047# XXX haven't tested this yet..
0048def xinclude_filter(stream, template):
0049    xi = Namespace('http://www.w3.org/2001/XInclude')
0050    include = xi.include
0051    fallback = xi.fallback
0052    for ev, item in stream:
0053        if ev == START and item.tag == xi.include:
0054            item = item.expand()
0055            href = item.get('href')
0056            try:
0057                doc = document(href, template._get_assume_encoding())
0058            except:
0059                fallback_elm = item.find(fallback)
0060                for ev, item in ElementStream(fallback_elm).strip(1):
0061                    yield ev, item
0062            else:
0063                for ev, item in doc:
0064                    if ev != XML_DECL:
0065                        yield ev