textwrap - Formattare Paragrafi di Testo

Scopo: Formatta il testo gestendo il punto dove occorrono le interruzioni di linea in un paragrafo

Il modulo textwrap può essere usto per formattare il testo in uscita dove necessiti una stampa pretty-printing, vale a dire l'applicazione di vari convenzioni di formattazione di stile per file di testo. Fornisce funzionalità programmatiche simili a quelle di impaginazione o distribuzione di un paragrafo, comuni a molti editor di testo.

Dati di Esempio

Gli esempi di seguito usano textwrap_example.py, che contiene la stringa 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.
	'''

Riempire Paragrafi

La funzione fill() prende il testo in input e produce testo formattato in uscita.

# textwrap_fill.py

import textwrap
from textwrap_example import sample_text

print('Nessuna deindentazione:\n')
print(textwrap.fill(sample_text, width=50))

I risultati sono molto meno che desiderabili. Il testo ora è giustificato a sinistra, ma la prima riga mantiene la sua indentazione e gli spazi davanti a ogni susseguente riga sono incorporati nel paragrafo.

$ python3 textwrap_fill.py

Nessuna deindentazione:

         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.

Rimuovere Indentazione Esistente

L'esempio precedente aveva delle tabulazioni incorporate e spazi supplementari nel mezzo dell'output, quindi non formattato in modo pulito. L'eliminazione di tutti gli spazi davanti a tutte le righe nel testo con dedent() produce migliori risultati e consente l'utilizzo di docstring o righe multiple incorporate direttamente dal codice Python rimuovendo la formattazione propria del codice. La stringa di esempio ha un livello di indentazione artificiale introdotto per illustrare questa caratteristica.

import textwrap
from textwrap_example import sample_text

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

Il risultato inizia ad avere un aspetto migliore.

$ python3 textwrap_dedent.py

Deindentato:

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.

Visto che la "deindentazione" è il contrario dell'indentazione, il risultato è un blocco di testo con gli spazi iniziali di ogni riga rimossi. Se una riga ha già una indentazione superiore alle altre alcuni degli spazi non saranno eliminati.

␣Riga uno.
␣␣␣Riga due.
␣Riga tre.

diventa.

Riga uno.
␣␣Riga due.
Riga tre.

Combinare Dedent e Fill

Proseguendo, il testo deindentato può essere passato attraverso fill() con diversi valori di larghezza 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('{} Colonne:\n'.format(width))
    print(textwrap.fill(dedented_text, width=width))
    print()

Si otterranno diversi tipi di ouput della larghezza specificata.

$ python3 textwrap_fill_width.py

45 Colonne:

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 Colonne:

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.

Indentare Blocchi

Si utilizza la funzione indent() per aggiungere un prefisso consistente a tutte le righe in una stringa. Questo esempio formatta lo stesso testo di esempio come se fosse parte di un messaggio email marcato nella risposta utilizzando > come prefisso per ciascuna riga.

# 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\nSecondo paragrafo dopo una riga vuota.'
final = textwrap.indent(wrapped, '> ')

print('Blocco marcato:\n')
print(final)

Il blocco di testo viene separato a ogni interruzione di riga, il prefisso viene aggiunto a ogni riga che contenga testo, quindi le righe sono assemblate nuovamente in una nuova stringa, quindi restituite.

$ python3 textwrap_indent.py

Blocco marcato:

>  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.

> Secondo paragrafo dopo una riga vuota.

Per controllare quale riga riceve il nuovo prefisso, si passi un callable come argomento predicato di indent(). Il callable sarà chiamato per ciascuna riga di testo e il prefisso verrà aggiunto per quelle righe dove il valore ritornato è True.

# textwrap_indent_predicate.py

import textwrap
from textwrap_example import sample_text


def should_indent(line):
    print('Indentato {!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, 'PARI ',
                        predicate=should_indent)

print('\nBlocco marcato:\n')
print(final)

Questo esempio aggiunge il prefisso PARI a righe che contengono un numero pari di caratteri.

$ python3 textwrap_indent_predicate.py

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

Blocco marcato:

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

Indentazioni Sospese

Così come si può impostare la larghezza dell'input, allo stesso modo è possibile controllare l'indentazione della prima riga indipendentemente da quella delle seguenti.

# 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,
                    ))

E' quindi possibile produrre una indentazione sospesa, dove la prima riga ha minor indentazione rispetto alle altre righe.

$ 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.

I valori di indentazione possono comprendere anche caratteri diversi da spazi. L'indentazione sospesa può essere prefissata da un * per generare elementi di lista, ecc.

Troncare un Testo Lungo

Per troncare il testo per creare un sommario o anteprima, si utilizza shorten(). Tutti i tipi di spazio esistenti (tabulatori, ritorni a capo e serie consecutive di spazi) sono ridotti a un singolo spazio. Poi il testo viene troncato a una lunghezza minore o uguale a quella richiesta, rispettando i confini delle parole in modo che non vengano incluse parole parziali.

# 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('Originale:\n')
print(original)

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

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

Se viene rimosso del testo diverso da spazio dal testo originale esso viene sostituito da un valore segnaposto. Il valore predefinito [...] può essere modificato fornendo l'argomento placeholder a shorten().

$ python3 textwrap_shorten.py

Originale:

 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.

Accorciato:

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

Vedere anche:

textwrap
La documentazione della libreria standard per questo modulo.