0001# -*- coding: utf-8 -*-
0002
0003"""Kid tranformations"""
0004
0005__revision__ = "$Rev: 492 $"
0006__date__ = "$Date: 2007-07-06 21:38:45 -0400 (Fri, 06 Jul 2007) $"
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 kid.parser import ElementStream, START, XML_DECL, document, _coalesce
0012from kid.namespace import Namespace
0013from kid.template_util import generate_content
0014
0015__all__ = ['transform_filter']
0016
0017
0018def transform_filter(stream, template):
0019    templates = template._get_match_templates()
0020    def apply_func(item):
0021        return transform_filter(generate_content(item), template)
0022    stream = ElementStream.ensure(stream)
0023    return ElementStream(apply_matches(stream, template, templates, apply_func))
0024
0025def apply_matches(stream, template, templates, apply_func):
0026    for ev, item in stream:
0027        if ev == START:
0028            matched = False
0029            for i in range(0, len(templates)):
0030                match, call = templates[i]
0031                if match(item):
0032                    item = stream.expand()
0033                    newstream = _coalesce(call(template, item, apply_func),
0034                        template._get_assume_encoding())
0035                    if len(templates) < 2:
0036                        for ev, item in newstream:
0037                            yield ev, item
0038                    else:
0039                        for ev, item in apply_matches(
0040                                ElementStream(newstream), template,
0041                                templates[:i] + templates[i+1:], apply_func):
0042                            yield ev, item
0043                    matched = True
0044                    break
0045            if matched:
0046                continue
0047        yield ev, item
0048
0049# XXX haven't tested this yet..
0050def xinclude_filter(stream, template):
0051    xi = Namespace('http://www.w3.org/2001/XInclude')
0052    include = xi.include
0053    fallback = xi.fallback
0054    for ev, item in stream:
0055        if ev == START and item.tag == include:
0056            item = item.expand()
0057            href = item.get('href')
0058            try:
0059                doc = document(href, template._get_assume_encoding())
0060            except:
0061                fallback_elm = item.find(fallback)
0062                for ev, item in ElementStream(fallback_elm).strip(1):
0063                    yield ev, item
0064            else:
0065                for ev, item in doc:
0066                    if ev != XML_DECL:
0067                        yield ev