littlefish/htmlutil.py
def pretty_print(html, max_line_length=110, tab_width=4):
    """
    Pretty print HTML, splitting it into lines of a reasonable length (if possible).

    This probably needs a whole lot more testing!

    :param html: The HTML to format
    :param max_line_length: The desired maximum line length. Will not be strictly adhered to
    :param min_line_length: The desired minimum line length
    :param tab_width: Essentially, the tabs that indent the code will be treated as this many
                      spaces when counting the length of each line

    :return: Beautifully formatted HTML
    """
    if tab_width < 2:
        raise ValueError('tab_width must be at least 2 (or bad things would happen!)')

    # Double curly brackets to avoid problems with .format()
    html = html.replace('{', '{{').replace('}', '}}')
    soup = BeautifulSoup(html, 'lxml')
    soup.html.unwrap()
    soup.body.unwrap()

    unformatted_tag_list = []
    
    # Here we are taking the tags out of the content and replacing them with placeholders,
    # and adding the tags to a list.  I didn't come up with this...
    for i, tag in enumerate(soup.find_all(INLINE_TAGS)):
        unformatted_tag_list.append(str(tag))
        tag.replace_with('{' + 'unformatted_tag_list[{0}]'.format(i) + '}')

    # If we prettify this, there will still be some weird indentation going on, based on
    # the original markup, so we need to convert it into a string again, and then parse
    # it again
    processed_html = str(soup)
    soup2 = BeautifulSoup(processed_html, 'lxml')
    soup2.html.unwrap()
    soup2.body.unwrap()

    # Prettify it, substitute in the unformatted tags
    pretty_markup = soup2.prettify().format(unformatted_tag_list=unformatted_tag_list)

    # Convert indendtations to a tab width of 4
    pretty_markup = re.sub(r'^(\s+)', r'\1' * tab_width, pretty_markup, flags=re.MULTILINE)

    # Final step - pass over the formatted html, convert the indentations into tabs and cut
    # the lines to length
    lines = pretty_markup.splitlines()
    out = ''
    for line in lines:
        for line_part in split_line(line, max_line_length=max_line_length):
            out += line_part
            out += '\n'
    
    # Final final step! Convert space indentations into tabs
    return out.replace(' ' * tab_width, '\t')
def pretty_print(html, max_line_length=110, tab_width=4):
    """
    Pretty print HTML, splitting it into lines of a reasonable length (if possible).

    This probably needs a whole lot more testing!

    :param html: The HTML to format
    :param max_line_length: The desired maximum line length. Will not be strictly adhered to
    :param min_line_length: The desired minimum line length
    :param tab_width: Essentially, the tabs that indent the code will be treated as this many
                      spaces when counting the length of each line

    :return: Beautifully formatted HTML
    """
    if tab_width < 2:
        raise ValueError('tab_width must be at least 2 (or bad things would happen!)')

    # Double curly brackets to avoid problems with .format()
    html = html.replace('{', '{{').replace('}', '}}')
    soup = BeautifulSoup(html, 'lxml')
    soup.html.unwrap()
    soup.body.unwrap()

    unformatted_tag_list = []
    
    # Here we are taking the tags out of the content and replacing them with placeholders,
    # and adding the tags to a list.  I didn't come up with this...
    for i, tag in enumerate(soup.find_all(INLINE_TAGS)):
        unformatted_tag_list.append(str(tag))
        tag.replace_with('{' + 'unformatted_tag_list[{0}]'.format(i) + '}')

    # If we prettify this, there will still be some weird indentation going on, based on
    # the original markup, so we need to convert it into a string again, and then parse
    # it again
    processed_html = str(soup)
    soup2 = BeautifulSoup(processed_html, 'lxml')
    soup2.html.unwrap()
    soup2.body.unwrap()

    # Prettify it, substitute in the unformatted tags
    pretty_markup = soup2.prettify().format(unformatted_tag_list=unformatted_tag_list)

    # Convert indendtations to a tab width of 4
    pretty_markup = re.sub(r'^(\s+)', r'\1' * tab_width, pretty_markup, flags=re.MULTILINE)

    # Final step - pass over the formatted html, convert the indentations into tabs and cut
    # the lines to length
    lines = pretty_markup.splitlines()
    out = ''
    for line in lines:
        for line_part in split_line(line, max_line_length=max_line_length):
            out += line_part
            out += '\n'
    
    # Final final step! Convert space indentations into tabs
    return out.replace(' ' * tab_width, '\t')
Pretty print HTML, splitting it into lines of a reasonable length (if possible).

    This probably needs a whole lot more testing!

    :param html: The HTML to format
    :param max_line_length: The desired maximum line length. Will not be strictly adhered to
    :param min_line_length: The desired minimum line length
    :param tab_width: Essentially, the tabs that indent the code will be treated as this many
                      spaces when counting the length of each line

    :return: Beautifully formatted HTML