|
|
from __future__ import absolute_import, division, unicode_literals |
|
|
|
|
|
from genshi.core import QName |
|
|
from genshi.core import START, END, XML_NAMESPACE, DOCTYPE, TEXT |
|
|
from genshi.core import START_NS, END_NS, START_CDATA, END_CDATA, PI, COMMENT |
|
|
|
|
|
from . import base |
|
|
|
|
|
from ..constants import voidElements, namespaces |
|
|
|
|
|
|
|
|
class TreeWalker(base.TreeWalker): |
|
|
def __iter__(self): |
|
|
|
|
|
previous = None |
|
|
for event in self.tree: |
|
|
if previous is not None: |
|
|
for token in self.tokens(previous, event): |
|
|
yield token |
|
|
previous = event |
|
|
|
|
|
|
|
|
if previous is not None: |
|
|
for token in self.tokens(previous, None): |
|
|
yield token |
|
|
|
|
|
def tokens(self, event, next): |
|
|
kind, data, _ = event |
|
|
if kind == START: |
|
|
tag, attribs = data |
|
|
name = tag.localname |
|
|
namespace = tag.namespace |
|
|
converted_attribs = {} |
|
|
for k, v in attribs: |
|
|
if isinstance(k, QName): |
|
|
converted_attribs[(k.namespace, k.localname)] = v |
|
|
else: |
|
|
converted_attribs[(None, k)] = v |
|
|
|
|
|
if namespace == namespaces["html"] and name in voidElements: |
|
|
for token in self.emptyTag(namespace, name, converted_attribs, |
|
|
not next or next[0] != END or |
|
|
next[1] != tag): |
|
|
yield token |
|
|
else: |
|
|
yield self.startTag(namespace, name, converted_attribs) |
|
|
|
|
|
elif kind == END: |
|
|
name = data.localname |
|
|
namespace = data.namespace |
|
|
if namespace != namespaces["html"] or name not in voidElements: |
|
|
yield self.endTag(namespace, name) |
|
|
|
|
|
elif kind == COMMENT: |
|
|
yield self.comment(data) |
|
|
|
|
|
elif kind == TEXT: |
|
|
for token in self.text(data): |
|
|
yield token |
|
|
|
|
|
elif kind == DOCTYPE: |
|
|
yield self.doctype(*data) |
|
|
|
|
|
elif kind in (XML_NAMESPACE, DOCTYPE, START_NS, END_NS, |
|
|
START_CDATA, END_CDATA, PI): |
|
|
pass |
|
|
|
|
|
else: |
|
|
yield self.unknown(kind) |
|
|
|