textwrap — Formateando párrafos de texto

Propósito:Formatea párrafos de texto ajustando dónde ocurren los saltos de línea en un párrafo.

El módulo textwrap se puede usar para formatear texto para salida en situaciones donde se desea una impresión bonita. Ofrece funcionalidad programática similar a las características de envoltura o relleno de párrafo encontrada en muchos editores de texto y procesadores de texto.

Datos del ejemplo

Los ejempos en esta sección usan el módulo textwrap_example.py, que contiene la cadena sample_text.

textwrap_example.py
sample_text = '''
    The textwrap module can be used to format text for output in
    situations where pretty-printing is desired.  It offers
    programmatic functionality similar to the paragraph wrapping
    or filling features found in many text editors.
    '''

Rellenando párrafos

La función fill() toma el texto como entrada y produce el texto formateado como salida.

textwrap_fill.py
import textwrap
from textwrap_example import sample_text

print(textwrap.fill(sample_text, width=50))

Los resultados son algo menos que deseable. El texto ahora está justificado a la izquierda, pero la primera línea conserva su sangría y los espacios de el princio de cada línea subsecuente están incrustados en el párrafo.

$ python3 textwrap_fill.py

     The textwrap module can be used to format
text for output in     situations where pretty-
printing is desired.  It offers     programmatic
functionality similar to the paragraph wrapping
or filling features found in many text editors.

Eliminando la sangría existente

El ejemplo anterior tiene tabuladores y espacios adicionales mezclados en medio de la salida, por lo que no está formateado muy limpiamente. Eliminando el prefijo de espacio en blanco común de todas las líneas en el texto de muestra con dedent() produce mejores resultados y permite el uso de docstrings o cadenas multilíneas integradas directamente desde el código de Python al eliminar el formato del código en sí. La cadena de muestra tiene un nivel de sangría artificial introducido para ilustrar esta característica.

textwrap_dedent.py
import textwrap
from textwrap_example import sample_text

dedented_text = textwrap.dedent(sample_text)
print('Dedented:')
print(dedented_text)

Los resultados comienzan a verse mejor.

$ python3 textwrap_dedent.py

Dedented:

The textwrap module can be used to format text for output in
situations where pretty-printing is desired.  It offers
programmatic functionality similar to the paragraph wrapping
or filling features found in many text editors.

Como «dedent» es lo opuesto a «indent», el resultado es un bloque de texto con el espacio en blanco inicial común de cada línea eliminado. Si una línea ya está sangrada más que otra, algunos de los espacios en blanco no serán eliminados

Entrada como

␣Line one.
␣␣␣Line two.
␣Line three.

se convierte en

Line one.
␣␣Line two.
Line three.

Combinando dedenet y relleno

A continuacion, el texto dedentado puede ser pasado a través de fill() con algunos valores differentes de width.

textwrap_fill_width.py
import textwrap
from textwrap_example import sample_text

dedented_text = textwrap.dedent(sample_text).strip()
for width in [45, 60]:
    print('{} Columns:\n'.format(width))
    print(textwrap.fill(dedented_text, width=width))
    print()

Esto produce salidas de el ancho espicificado.

$ python3 textwrap_fill_width.py

45 Columns:

The textwrap module can be used to format
text for output in situations where pretty-
printing is desired.  It offers programmatic
functionality similar to the paragraph
wrapping or filling features found in many
text editors.

60 Columns:

The textwrap module can be used to format text for output in
situations where pretty-printing is desired.  It offers
programmatic functionality similar to the paragraph wrapping
or filling features found in many text editors.

Sangrando bloques

Usa la función indent() para agregar texto de prefijo consistente a todas las líneas en una cadena. Este ejemplo formatea el mismo texto de ejemplo como si fuera parte de un mensaje de correo electrónico que se cita en la respuesta, usando > como el prefijo para cada línea.

textwrap_indent.py
import textwrap
from textwrap_example import sample_text

dedented_text = textwrap.dedent(sample_text)
wrapped = textwrap.fill(dedented_text, width=50)
wrapped += '\n\nSecond paragraph after a blank line.'
final = textwrap.indent(wrapped, '> ')

print('Quoted block:\n')
print(final)

El bloque de texto se divide en líneas nuevas, el prefijo se agrega a cada línea que contiene texto, y luego las líneas se combinan nuevamente en una nueva cadena que devuelta.

$ python3 textwrap_indent.py

Quoted block:

>  The textwrap module can be used to format text
> for output in situations where pretty-printing is
> desired.  It offers programmatic functionality
> similar to the paragraph wrapping or filling
> features found in many text editors.

> Second paragraph after a blank line.

Para controlar qué líneas reciben el nuevo prefijo, pasa un invocable como el argumento predicate para indent(). El invocable se invocará para cada línea de texto por turno y el prefijo se agregará para las líneas donde el valor de retorno es verdadero.

textwrap_indent_predicate.py
import textwrap
from textwrap_example import sample_text


def should_indent(line):
    print('Indent {!r}?'.format(line))
    return len(line.strip()) % 2 == 0


dedented_text = textwrap.dedent(sample_text)
wrapped = textwrap.fill(dedented_text, width=50)
final = textwrap.indent(wrapped, 'EVEN ',
                        predicate=should_indent)

print('\nQuoted block:\n')
print(final)

Este ejemplo agrega el prefijo EVEN a las líneas que contienen un número par de caracteres.

$ python3 textwrap_indent_predicate.py

Indent ' The textwrap module can be used to format text\n'?
Indent 'for output in situations where pretty-printing is\n'?
Indent 'desired.  It offers programmatic functionality\n'?
Indent 'similar to the paragraph wrapping or filling\n'?
Indent 'features found in many text editors.'?

Quoted block:

EVEN  The textwrap module can be used to format text
for output in situations where pretty-printing is
EVEN desired.  It offers programmatic functionality
EVEN similar to the paragraph wrapping or filling
EVEN features found in many text editors.

Sangrías colgantes

De la misma manera que es posible establecer el ancho de la salida, se puede controlar la sangría de la primera línea independientemente de las líneas subsecuentes.

textwrap_hanging_indent.py
import textwrap
from textwrap_example import sample_text

dedented_text = textwrap.dedent(sample_text).strip()
print(textwrap.fill(dedented_text,
                    initial_indent='',
                    subsequent_indent=' ' * 4,
                    width=50,
                    ))

Esto hace posible producir una sangría colgante, donde la primera línea está indentada menos que las otras líneas.

$ python3 textwrap_hanging_indent.py

The textwrap module can be used to format text for
    output in situations where pretty-printing is
    desired.  It offers programmatic functionality
    similar to the paragraph wrapping or filling
    features found in many text editors.

Los valores de sangría también pueden incluir caracteres que no sean espacios en blanco. Por ejemplo, la sangría francesa puede tener el prefijo * para producir viñetas.

Truncando texto largo

Para truncar texto para crear un resumen o vista previa, usa shorten(). Todos los espacios en blanco existentes, como tabuladores, líneas nuevas y series de espacios múltiples, se estandarizarán en un solo espacio. Entonces el texto será truncado a una longitud menor o igual a la que es solicitada, entre los límites de las palabras para que no se incluya palabras parciales.

textwrap_shorten.py
import textwrap
from textwrap_example import sample_text

dedented_text = textwrap.dedent(sample_text)
original = textwrap.fill(dedented_text, width=50)

print('Original:\n')
print(original)

shortened = textwrap.shorten(original, 100)
shortened_wrapped = textwrap.fill(shortened, width=50)

print('\nShortened:\n')
print(shortened_wrapped)

Si el texto no en blanco se elimina del texto original como parte de el truncamiento, se reemplaza con un valor de marcador de posición. El valor por defecto [...] se puede reemplazar proporcionando un argumento placeholder para shorten().

$ python3 textwrap_shorten.py

Original:

 The textwrap module can be used to format text
for output in situations where pretty-printing is
desired.  It offers programmatic functionality
similar to the paragraph wrapping or filling
features found in many text editors.

Shortened:

The textwrap module can be used to format text for
output in situations where pretty-printing [...]