def split_text_box(context, box, available_width, skip, is_line_start=True):
    """Keep as much text as possible from a TextBox in a limited width.

    Try not to overflow but always have some text in ``new_box``.

    Return ``(new_box, skip, preserved_line_break)``. ``skip`` is the number of
    UTF-8 bytes to skip form the start of the TextBox for the next line, or
    ``None`` if all of the text fits.

    Also break on preserved line breaks.

    """
    assert isinstance(box, boxes.TextBox)
    font_size = box.style['font_size']
    text = box.text.encode()[skip:]
    if font_size == 0 or not text:
        return None, None, False
    layout, length, resume_index, width, height, baseline = split_first_line(
        text.decode(), box.style, context, available_width,
        box.justification_spacing, is_line_start=is_line_start)
    assert resume_index != 0

    if length > 0:
        box = box.copy_with_text(layout.text)
        box.width = width
        box.pango_layout = layout
        # "The height of the content area should be based on the font,
        #  but this specification does not specify how."
        # https://www.w3.org/TR/CSS21/visudet.html#inline-non-replaced
        # We trust Pango and use the height of the LayoutLine.
        box.height = height
        # "only the 'line-height' is used when calculating the height
        #  of the line box."
        # Set margins so that margin_height() == line_height
        line_height, _ = strut_layout(box.style, context)
        half_leading = (line_height - height) / 2
        box.margin_top = half_leading
        box.margin_bottom = half_leading
        # form the top of the content box
        box.baseline = baseline
        # form the top of the margin box
        box.baseline += box.margin_top
    else:
        box = None

    if resume_index is None:
        preserved_line_break = False
    else:
        between = text[length:resume_index].decode()
        preserved_line_break = (
            (length != resume_index) and between.strip(' '))
        if preserved_line_break:
            # See https://unicode.org/reports/tr14/
            # \r is already handled by process_whitespace
            line_breaks = ('\n', '\t', '\f', '\u0085', '\u2028', '\u2029')
            assert between in line_breaks, (
                'Got %r between two lines. '
                'Expected nothing or a preserved line break' % (between,))
        resume_index += skip

    return box, resume_index, preserved_line_break
Keep as much text as possible from a TextBox in a limited width.

Try not to overflow but always have some text in ``new_box``.

Return ``(new_box, skip, preserved_line_break)``. ``skip`` is the number of
UTF-8 bytes to skip form the start of the TextBox for the next line, or
``None`` if all of the text fits.

Also break on preserved line breaks.
weasyprint/layout/inline.py