def split_inline_level(context, box, position_x, max_x, bottom_space,
                       skip_stack, containing_block, absolute_boxes,
                       fixed_boxes, line_placeholders, waiting_floats,
                       line_children):
    """Fit as much content as possible from an inline-level box in a width.

    Return ``(new_box, resume_at, preserved_line_break, first_letter,
    last_letter)``. ``resume_at`` is ``None`` if all of the content
    fits. Otherwise it can be passed as a ``skip_stack`` parameter to resume
    where we left off.

    ``new_box`` is non-empty (unless the box is empty) and as big as possible
    while being narrower than ``available_width``, if possible (may overflow
    is no split is possible.)

    """
    resolve_percentages(box, containing_block)
    float_widths = {'left': 0, 'right': 0}
    if isinstance(box, boxes.TextBox):
        box.position_x = position_x
        if skip_stack is None:
            skip = 0
        else:
            (skip, skip_stack), = skip_stack.items()
            skip = skip or 0
            assert skip_stack is None

        is_line_start = len(line_children) == 0
        new_box, skip, preserved_line_break = split_text_box(
            context, box, max_x - position_x, skip,
            is_line_start=is_line_start)

        if skip is None:
            resume_at = None
        else:
            resume_at = {skip: None}
        if box.text:
            first_letter = box.text[0]
            if skip is None:
                last_letter = box.text[-1]
            else:
                last_letter = box.text.encode()[:skip].decode()[-1]
        else:
            first_letter = last_letter = None
    elif isinstance(box, boxes.InlineBox):
        if box.margin_left == 'auto':
            box.margin_left = 0
        if box.margin_right == 'auto':
            box.margin_right = 0
        (new_box, resume_at, preserved_line_break, first_letter,
         last_letter, float_widths) = split_inline_box(
             context, box, position_x, max_x, bottom_space, skip_stack,
             containing_block, absolute_boxes, fixed_boxes, line_placeholders,
             waiting_floats, line_children)
    elif isinstance(box, boxes.AtomicInlineLevelBox):
        new_box = atomic_box(
            context, box, position_x, skip_stack, containing_block,
            absolute_boxes, fixed_boxes)
        new_box.position_x = position_x
        resume_at = None
        preserved_line_break = False
        # See https://www.w3.org/TR/css-text-3/#line-breaking
        # Atomic inlines behave like ideographic characters.
        first_letter = '\u2e80'
        last_letter = '\u2e80'
    elif isinstance(box, boxes.InlineFlexBox):
        box.position_x = position_x
        box.position_y = 0
        for side in ('top', 'right', 'bottom', 'left'):
            if getattr(box, f'margin_{side}') == 'auto':
                setattr(box, f'margin_{side}', 0)
        new_box, resume_at, _, _, _ = flex_layout(
            context, box, -inf, skip_stack, containing_block, False,
            absolute_boxes, fixed_boxes, False)
        preserved_line_break = False
        first_letter = '\u2e80'
        last_letter = '\u2e80'
    elif isinstance(box, boxes.InlineGridBox):
        box.position_x = position_x
        box.position_y = 0
        for side in ('top', 'right', 'bottom', 'left'):
            if getattr(box, f'margin_{side}') == 'auto':
                setattr(box, f'margin_{side}', 0)
        new_box, resume_at, _, _, _ = grid_layout(
            context, box, -inf, skip_stack, containing_block, False,
            absolute_boxes, fixed_boxes)
        preserved_line_break = False
        first_letter = '\u2e80'
        last_letter = '\u2e80'
    else:  # pragma: no cover
        raise TypeError(f'Layout for {type(box).__name__} not handled yet')
    return (
        new_box, resume_at, preserved_line_break, first_letter, last_letter,
        float_widths)
Fit as much content as possible from an inline-level box in a width.

Return ``(new_box, resume_at, preserved_line_break, first_letter,
last_letter)``. ``resume_at`` is ``None`` if all of the content
fits. Otherwise it can be passed as a ``skip_stack`` parameter to resume
where we left off.

``new_box`` is non-empty (unless the box is empty) and as big as possible
while being narrower than ``available_width``, if possible (may overflow
is no split is possible.)
weasyprint/layout/inline.py