def render(self, container, descender, state, space_below=0,
               first_line_only=False):
        """Typeset the paragraph

        The paragraph is typeset in the given container starting below the
        current cursor position of the container. When the end of the container
        is reached, the rendering state is preserved to continue setting the
        rest of the paragraph when this method is called with a new container.

        Args:
            container (Container): the container to render to
            descender (float or None): descender height of the preceeding line
            state (ParagraphState): the state where rendering will continue
            first_line_only (bool): typeset only the first line

        """
        indent_first = (float(self.get_style('indent_first', container))
                        if state.initial else 0)
        line_width = float(container.width)
        line_spacing = self.get_style('line_spacing', container)
        text_align = self.get_style('text_align', container)
        tab_stops = self.get_style('tab_stops', container)
        if not tab_stops:
            tab_width = 2 * self.get_style('font_size', container)
            tab_stops = DefaultTabStops(tab_width)

        # `saved_state` is updated after successfully rendering each line, so
        # that when `container` overflows on rendering a line, the words in that
        # line are yielded again on the next typeset() call.
        saved_state = copy(state)
        prev_state = copy(state)
        max_line_width = 0

        def typeset_line(line, last_line=False):
            """Typeset `line` and, if no exception is raised, update the
            paragraph's internal rendering state."""
            nonlocal state, saved_state, max_line_width, descender, space_below
            max_line_width = max(max_line_width, line.cursor)
            advance = (line.ascender(container) if descender is None
                       else line_spacing.advance(line, descender, container))
            descender = line.descender(container)   # descender <= 0
            line.advance = advance
            total_advance = advance + (space_below if last_line else 0) - descender
            if container.remaining_height < total_advance:
                raise EndOfContainer(saved_state)
            assert container.advance2(advance)
            line.typeset(container, text_align, last_line)
            assert container.advance2(- descender)
            state.initial = False
            saved_state = copy(state)
            return Line(tab_stops, line_width, container,
                        significant_whitespace=self.significant_whitespace)

        first_line = line = Line(tab_stops, line_width, container,
                                 indent_first, self.significant_whitespace)
        while True:
            try:
                word = state.next_word()
            except StopIteration:
                break
            try:
                if not line.append_word(word):
                    for first, second in word.hyphenate(container):
                        if line.append_word(first):
                            state.prepend_word(second)  # prepend second part
                            break
                    else:
                        state = prev_state
                    line = typeset_line(line)
                    if first_line_only:
                        break
                    continue
            except NewLineException:
                line.append(word.glyphs_span)
                line = typeset_line(line, last_line=True)
                if first_line_only:
                    break
            prev_state = copy(state)
        if line:
            typeset_line(line, last_line=True)

        # Correct the horizontal text placement for auto-width paragraphs
        if self._width(container) == FlowableWidth.AUTO:
            if text_align == TextAlign.CENTER:
                container.left -= float(container.width - max_line_width) / 2
            if text_align == TextAlign.RIGHT:
                container.left -= float(container.width - max_line_width)

        return max_line_width, first_line.advance, descender
Typeset the paragraph

        The paragraph is typeset in the given container starting below the
        current cursor position of the container. When the end of the container
        is reached, the rendering state is preserved to continue setting the
        rest of the paragraph when this method is called with a new container.

        Args:
            container (Container): the container to render to
            descender (float or None): descender height of the preceeding line
            state (ParagraphState): the state where rendering will continue
            first_line_only (bool): typeset only the first line