def parse(tree, parse_funcs): """Parse placeables from the given string or sub-tree by using the parsing functions provided. The output of this function is **heavily** dependent on the order of the parsing functions. This is because of the algorithm used. An over-simplification of the algorithm: the leaves in the ``StringElem`` tree are expanded to the output of the first parsing function in ``parse_funcs``. The next level of recursion is then started on the new set of leaves with the used parsing function removed from ``parse_funcs``. :type tree: unicode|StringElem :param tree: The string or string element sub-tree to parse. :type parse_funcs: A list of parsing functions. It must take exactly one argument (a ``unicode`` string to parse) and return a list of ``StringElem``s which, together, form the original string. If nothing could be parsed, it should return ``None``. """ if isinstance(tree, unicode): tree = StringElem(tree) if not parse_funcs: return tree parse_func = parse_funcs[0] for leaf in tree.flatten(): # FIXME: we might rather want to test for editability, but for now this # works better if not leaf.istranslatable: continue unileaf = unicode(leaf) if not unileaf: continue subleaves = parse_func(unileaf) if subleaves is not None: if len(subleaves) == 1 and isinstance(subleaves[0], type(leaf)) and leaf == subleaves[0]: pass elif isinstance(leaf, unicode): parent = tree.get_parent_elem(leaf) if parent is not None: if len(parent.sub) == 1: parent.sub = subleaves leaf = parent else: leafindex = parent.sub.index(leaf) parent.sub[leafindex] = StringElem(subleaves) leaf = parent.sub[leafindex] else: leaf.sub = subleaves parse(leaf, parse_funcs[1:]) if isinstance(leaf, StringElem): leaf.prune() return tree
def parse(tree, parse_funcs): """Parse placeables from the given string or sub-tree by using the parsing functions provided. The output of this function is B{heavily} dependent on the order of the parsing functions. This is because of the algorithm used. An over-simplification of the algorithm: the leaves in the C{StringElem} tree are expanded to the output of the first parsing function in C{parse_funcs}. The next level of recursion is then started on the new set of leaves with the used parsing function removed from C{parse_funcs}. @type tree: unicode|StringElem @param tree: The string or string element sub-tree to parse. @type parse_funcs: A list of parsing functions. It must take exactly one argument (a C{unicode} string to parse) and return a list of C{StringElem}s which, together, form the original string. If nothing could be parsed, it should return C{None}.""" if isinstance(tree, unicode): tree = StringElem(tree) if not parse_funcs: return tree parse_func = parse_funcs[0] for leaf in tree.flatten(): #FIXME: we might rather want to test for editability, but for now this # works better if not leaf.istranslatable: continue unileaf = unicode(leaf) if not unileaf: continue subleaves = parse_func(unileaf) if subleaves is not None: if len(subleaves) == 1 and type(leaf) is type( subleaves[0]) and leaf == subleaves[0]: pass elif isinstance(leaf, unicode): parent = tree.get_parent_elem(leaf) if parent is not None: if len(parent.sub) == 1: parent.sub = subleaves leaf = parent else: leafindex = parent.sub.index(leaf) parent.sub[leafindex] = StringElem(subleaves) leaf = parent.sub[leafindex] else: leaf.sub = subleaves parse(leaf, parse_funcs[1:]) if isinstance(leaf, StringElem): leaf.prune() return tree
def _rewrite_prepend_append(self, string, prepend, append=None): if append is None: append = prepend if not isinstance(string, StringElem): string = StringElem(string) string.sub.insert(0, prepend) if six.text_type(string).endswith(u'\n'): # Try and remove the last character from the tree try: lastnode = string.flatten()[-1] if isinstance(lastnode.sub[-1], six.text_type): lastnode.sub[-1] = lastnode.sub[-1].rstrip(u'\n') except IndexError: pass string.sub.append(append + u'\n') else: string.sub.append(append) return string
def _rewrite_prepend_append(self, string, prepend, append=None): if append is None: append = prepend if not isinstance(string, StringElem): string = StringElem(string) string.sub.insert(0, prepend) if six.text_type(string).endswith(u'\n'): # Try and remove the last character from the tree try: lastnode = string.flatten()[-1] if isinstance(lastnode.sub[-1], six.text_type): lastnode.sub[-1] = lastnode.sub[-1].rstrip(u'\n') except IndexError: pass string.sub.append(append + u'\n') else: string.sub.append(append) return string