"""
Functions to process content of lxml nodes.
"""
from text import normalize_space as normalize_space_func, find_number

def get_node_text(node, smart=False, normalize_space=True):
    """
    Extract text content of the `node` and all its descendants.

    In smart mode `get_node_text` insert spaces between <tag><another tag>
    and also ignores content of the script and style tags.

    In non-smart mode this func just return text_content() of node
    with normalized spaces
    """

    if smart:
        value = ' '.join(node.xpath(
            './descendant-or-self::*[name() != "script" and '\
            'name() != "style"]/text()[normalize-space()]'))
    else:
        value = node.text_content()
    if normalize_space:
        value = normalize_space_func(value)
    return value

def find_node_number(node, ignore_spaces=False):
    """
    Find number in text content of the `node`.
    """

    return find_number(get_node_text(node), ignore_spaces=ignore_spaces)


def truncate_tail(node, xpath):
    """
    Find sub-node by its xpath and remove it and all adjacent nodes following
    after found node.
    """

    subnode = node.xpath(xpath)[0]
    for item in subnode.xpath('following-sibling::*'):
        item.getparent().remove(item)
    subnode.getparent().remove(subnode)


def drop_node(node, xpath):
    """
    Find sub-node by its xpath and remove it.
    """

    for item in node.xpath(xpath):
        item.getparent().remove(item)

@@ -45,16 +45,64 @@
 es.%0A%22%22%22%0A
+from StringIO import StringIO%0Aimport lxml.html%0A%0A
 from tex
@@ -1493,28 +1493,674 @@
 em.getparent().remove(item)%0A
+%0A%0Adef parse_html(html):%0A    %22%22%22%0A    Parse html into ElementTree node.%0A    %22%22%22%0A%0A    return lxml.html.parse(StringIO(html),%0A                           lxml.html.HTMLParser(encoding='utf-8'))%0A%0A%0Adef render_html(node, encoding='utf-8'):%0A    return lxml.html.tostring(node, encoding=encoding)%0A%0A%0Adef truncate_html(html, limit, encoding='utf-8'):%0A    %22%22%22%0A    Truncate html data to specified length and then fix broken tags.%0A    %22%22%22%0A%0A    if isinstance(html, basestring):%0A        html = html.decode('utf-8')%0A    truncated_html = html%5B:limit%5D%0A    elem = parse_html(truncated_html)%0A    fixed_html = render_html(elem, encoding=encoding)%0A    return fixed_html%0A

Add parse_html, render_html and truncate_html methods to grab.tools.lxml_tools