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
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