Issue #18585: Add :func:`textwrap.shorten` to collapse and truncate a piece of text to a given length.
diff --git a/Doc/library/textwrap.rst b/Doc/library/textwrap.rst
index c625254..486d5db 100644
--- a/Doc/library/textwrap.rst
+++ b/Doc/library/textwrap.rst
@@ -10,11 +10,11 @@
 
 --------------
 
-The :mod:`textwrap` module provides two convenience functions, :func:`wrap` and
-:func:`fill`, as well as :class:`TextWrapper`, the class that does all the work,
-and two utility functions, :func:`dedent` and :func:`indent`.  If you're just wrapping or filling one
-or two  text strings, the convenience functions should be good enough;
-otherwise,  you should use an instance of :class:`TextWrapper` for efficiency.
+The :mod:`textwrap` module provides some convenience functions,
+as well as :class:`TextWrapper`, the class that does all the work.
+If you're just wrapping or filling one or two text strings, the convenience
+functions should be good enough; otherwise, you should use an instance of
+:class:`TextWrapper` for efficiency.
 
 .. function:: wrap(text, width=70, **kwargs)
 
@@ -39,19 +39,24 @@
    In particular, :func:`fill` accepts exactly the same keyword arguments as
    :func:`wrap`.
 
-Both :func:`wrap` and :func:`fill` work by creating a :class:`TextWrapper`
-instance and calling a single method on it.  That instance is not reused, so for
-applications that wrap/fill many text strings, it will be more efficient for you
-to create your own :class:`TextWrapper` object.
 
-Text is preferably wrapped on whitespaces and right after the hyphens in
-hyphenated words; only then will long words be broken if necessary, unless
-:attr:`TextWrapper.break_long_words` is set to false.
+.. function:: shorten(text, width=70, *, placeholder=" (...)")
 
-Two additional utility function, :func:`dedent` and :func:`indent`, are
-provided to remove indentation from strings that have unwanted whitespace
-to the left of the text and to add an arbitrary prefix to selected lines
-in a block of text.
+   Collapse and truncate the given text to fit in the given width.
+
+   The text first has its whitespace collapsed.  If it then fits in
+   the *width*, it is returned unchanged.  Otherwise, as many words
+   as possible are joined and then the *placeholder* is appended::
+
+      >>> textwrap.shorten("Hello  world!", width=12)
+      'Hello world!'
+      >>> textwrap.shorten("Hello  world!", width=11)
+      'Hello (...)'
+      >>> textwrap.shorten("Hello world", width=10, placeholder="...")
+      'Hello...'
+
+   .. versionadded:: 3.4
+
 
 .. function:: dedent(text)
 
@@ -102,6 +107,16 @@
       + world
 
 
+:func:`wrap`, :func:`fill` and :func:`shorten` work by creating a
+:class:`TextWrapper` instance and calling a single method on it.  That
+instance is not reused, so for applications that process many text
+strings, it may be more efficient to create your own
+:class:`TextWrapper` object.
+
+Text is preferably wrapped on whitespaces and right after the hyphens in
+hyphenated words; only then will long words be broken if necessary, unless
+:attr:`TextWrapper.break_long_words` is set to false.
+
 .. class:: TextWrapper(**kwargs)
 
    The :class:`TextWrapper` constructor accepts a number of optional keyword
@@ -235,7 +250,7 @@
       was to always allow breaking hyphenated words.
 
 
-   :class:`TextWrapper` also provides two public methods, analogous to the
+   :class:`TextWrapper` also provides some public methods, analogous to the
    module-level convenience functions:
 
    .. method:: wrap(text)
@@ -252,3 +267,14 @@
       Wraps the single paragraph in *text*, and returns a single string
       containing the wrapped paragraph.
 
+
+   .. function:: shorten(text, *, placeholder=" (...)")
+
+      Collapse and truncate the given text to fit in :attr:`width`
+      characters.
+
+      The text first has its whitespace collapsed.  If it then fits in
+      :attr:`width`, it is returned as-is.  Otherwise, as many words
+      as possible are joined and then the *placeholder* is appended.
+
+      .. versionadded:: 3.4