Varia's website
https://varia.zone
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
70 lines
2.3 KiB
70 lines
2.3 KiB
2 weeks ago
|
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):
|
||
|
# Buffer the events so we can pass in the following one
|
||
|
previous = None
|
||
|
for event in self.tree:
|
||
|
if previous is not None:
|
||
|
for token in self.tokens(previous, event):
|
||
|
yield token
|
||
|
previous = event
|
||
|
|
||
|
# Don't forget the final 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)
|