X-Git-Url: https://git.mdrn.pl/librarian.git/blobdiff_plain/e9cdd3f1f653de79f94ddfcdf319fcc31e7f0cef..482477cced586463d7f342cdde8482a4d97d7685:/librarian/xmlutils.py diff --git a/librarian/xmlutils.py b/librarian/xmlutils.py index 8890f4e..ae3512a 100644 --- a/librarian/xmlutils.py +++ b/librarian/xmlutils.py @@ -12,26 +12,35 @@ class Xmill(object): Used instead of XSLT which is difficult and cumbersome. """ - def __init__(self, options=None): + def __init__(self, options=None, state=None): self._options = [] + self.state = state or {} if options: self._options.append(options) self.text_filters = [] + self.escaped_text_filters = [] def register_text_filter(self, fun): self.text_filters.append(fun) + def register_escaped_text_filter(self, fun): + self.escaped_text_filters.append(fun) + def filter_text(self, text): + for flt in self.text_filters: + if text is None: + return None + else: + text = flt(text) # TODO: just work on the tree and let lxml handle escaping. e = etree.Element("x") e.text = text # This whole mixing text with ML is so wrong. output = etree.tostring(e, encoding=unicode)[3:-4] - for flt in self.text_filters: + for flt in self.escaped_text_filters: output = flt(output) return output - def generate(self, document): """Generate text from node using handlers defined in class.""" output = self._handle_element(document) @@ -51,18 +60,17 @@ class Xmill(object): """ self._options.append(opts) - def _handle_for_element(self, element): ns = None tagname = None -# from nose.tools import set_trace + # from nose.tools import set_trace if element.tag[0] == '{': for nshort, nhref in element.nsmap.items(): try: if element.tag.index('{%s}' % nhref) == 0: ns = nshort - tagname = element.tag[len('{%s}' % nhref):] + tagname = element.tag[len('{%s}' % nhref):] break except ValueError: pass @@ -86,18 +94,22 @@ class Xmill(object): while True: sibling = element.getnext() - if sibling is not None: return sibling # found a new branch to dig into + if sibling is not None: + return sibling # found a new branch to dig into element = element.getparent() - if element is None: return None # end of tree + if element is None: + return None # end of tree def _handle_element(self, element): - if isinstance(element, etree._Comment): return None - + if isinstance(element, etree._Comment): + return None + handler = self._handle_for_element(element) + if self.state.get('mute') and not getattr(handler, 'unmuter', False): + return None # How many scopes + options_scopes = len(self._options) try: - options_scopes = len(self._options) - if handler is None: pre = [self.filter_text(element.text)] post = [self.filter_text(element.tail)] @@ -118,18 +130,20 @@ class Xmill(object): finally: # clean up option scopes if necessary self._options = self._options[0:options_scopes] + return out def tag_open_close(name_, classes_=None, **attrs): u"""Creates tag beginning and end. - + >>> tag_open_close("a", "klass", x=u"ą<") (u'', u'') """ if classes_: - if isinstance(classes_, (tuple, list)): classes_ = ' '.join(classes_) + if isinstance(classes_, (tuple, list)): + classes_ = ' '.join(classes_) attrs['class'] = classes_ e = etree.Element(name_) @@ -139,6 +153,7 @@ def tag_open_close(name_, classes_=None, **attrs): pre, post = etree.tostring(e, encoding=unicode).split(u"> <") return pre + u">", u"<" + post + def tag(name_, classes_=None, **attrs): """Returns a handler which wraps node contents in tag `name', with class attribute set to `classes' and other attributes according to keyword paramters @@ -153,13 +168,16 @@ def tagged(name, classes=None, **attrs): set to `classes' and other attributes according to keyword paramters """ if classes: - if isinstance(classes, (tuple,list)): classes = ' '.join(classes) + if isinstance(classes, (tuple, list)): + classes = ' '.join(classes) attrs['class'] = classes - a = ''.join([' %s="%s"' % (k,v) for (k,v) in attrs.items()]) + a = ''.join([' %s="%s"' % (k, v) for (k, v) in attrs.items()]) + def _decor(f): def _wrap(self, element): r = f(self, element) - if r is None: return + if r is None: + return prepend = "<%s%s>" % (name, a) append = "" % name @@ -184,6 +202,7 @@ def ifoption(**options): return _handler return _decor + def flatten(l, ltypes=(list, tuple)): """flatten function from BasicPropery/BasicTypes package """