miércoles, 7 de septiembre de 2016

fmt - Un formateador de texto simple

El programa fmt también maqueta el texto, pero un poco más. Acepta tanto archivos como entrada estándar y realiza formateo de párrafos en la secuencia de texto. Básicamente, rellena y junta líneas de texto mientras que mantiene líneas en blanco y sangrías.

Para demostrarlo, necesitaremos algún texto. Tomemos algo de la página info de fmt:

    `fmt' reads from the specified FILE arguments (or standard input if none are given), and writes to standard output.

    By default, blank lines, spaces between words, and indentation are preserved in the output; successive input lines with different indentation are not joined; tabs are expanded on input and introduced on output.

    `fmt' prefers breaking lines at the end of a sentence, and tries to avoid line breaks after the first word of a sentence or before the last word of a sentence. A "sentence break" is defined as either the end of a paragraph or a word ending in any of `.?!', followed by two spaces or end of line, ignoring any intervening parentheses or quotes. Like TeX, `fmt' reads entire "paragraphs" before choosing line breaks; the algorithm is a variant of that given by Donald E. Knuth and Michael F. Plass in "Breaking Paragraphs Into Lines", `Software--Practice & Experience' 11, 11 (November 1981), 1119-1184.

Copiaremos este texto en nuestro editor de texto y guardaremos el archivo como fmt-info.txt. Ahora, digamos que queremos reformatear este texto para ajustarlo a una columna de cincuenta caracteres de ancho. Podríamos hacerlo procesando el archivo con fmt y la opción -w:

[me@linuxbox ~]$ fmt -w 50 fmt-info.txt | head
   `fmt' reads from the specified FILE arguments
   (or standard input if
none are given), and writes to standard output.

   By default, blank lines, spaces between words,
   and indentation are
preserved in the output; successive input lines
with different indentation are not joined; tabs
are expanded on input and introduced on output.

Bien, es un resultado poco manejable. Quizá deberíamos leer realmente este texto, ya que explica lo que está pasando:

Por defecto, las líneas en blanco, los espacios entre palabras y las sangrías se mantienen en la salida; las líneas de entrada sucesivas con diferentes sangrías no se unen; las tabulaciones se expanden en la entrada y se pasan a la salida.

Así que, fmt mantiene la sangría de la primera línea. Afortunadamente, fmt proporciona una opción para corregir ésto:

[me@linuxbox ~]$ fmt -cw 50 fmt-info.txt
   `fmt' reads from the specified FILE arguments
(or standard input if none are given), and writes
to standard output.

   By default, blank lines, spaces between words,
and indentation are preserved in the output;
successive input lines with different indentation
are not joined; tabs are expanded on input and
introduced on output.

   `fmt' prefers breaking lines at the end of a
sentence, and tries to avoid line breaks after
the first word of a sentence or before the
last word of a sentence. A "sentence break"
is defined as either the end of a paragraph
or a word ending in any of `.?!', followed
by two spaces or end of line, ignoring any
intervening parentheses or quotes. Like TeX,
`fmt' reads entire "paragraphs" before choosing
line breaks; the algorithm is a variant of
that given by Donald E. Knuth and Michael F.
Plass in "Breaking Paragraphs Into Lines",
`Software--Practice & Experience' 11, 11
(November 1981), 1119-1184.

Mucho mejor. Añadiendo la opción -c, ahora tenemos el resultado deseado.

fmt tiene algunas opciones interesantes:

Tabla 21-3: Opciones fmt
Opción Descripción
-c Opera en modo margen de corona (crown margin mode). Esto preserva la sangría de las dos primeras líneas de un párrafo. Las siguientes líneas se alinean con la sangría de la segunda línea.
-p string Solo formatea aquellas líneas que comienzan con el prefijo string. Tras formatear, el contenido de string se antepone a cada línea reformateada. Esta opción puede usarse para formatear texto en comentarios de código fuente. Por ejemplo, cualquier lenguaje de programación o archivo de configuración que use un carácter "#" para delimitar un comentario podría formatearse especificando -p '# ' de forma que sólo los comentarios se formatearán. Mira el ejemplo a continuación.
-s Modo sólo-división. En este modo, las líneas sólo se dividirán para ajustarse al ancho especificado de columna. Las líneas cortas no se unirán para rellenar líneas. Este modo es útil cuando formateamos texto de tipo código donde no queremos que se unan las líneas.
-u Realiza espaciado uniforme. Esto aplicará el estilo tradicional de "máquina de escribir" al texto. Esto significa que se aplica un espacio entre palabras y dos espacios entre frases. Este modo es útil para eliminar la "justificación", es decir, el texto que se ha rellenado con espacios para forzar la alineación tanto en el margen derecho como izquierdo.
-w ancho Formatea el texto para ajustarlo a un ancho de columna en caracteres. La opción por defecto es 75 caracteres. Nota: fmt en realidad formatea líneas ligeramente más cortas que el ancho especificado para permitir el equilibrio entre líneas.

La opción -p es particularmente interesante. Con ella, podemos formatear fragmentos seleccionados de un archivo, siempre que las líneas a formatear comiencen con la misma secuencia de caracteres. Muchos lenguajes de programación usan el símbolo de la almohadilla (#) para indicar el comienzo de un comentario y así pueden ser formateados usando esta opción. Creemos un archivo que simule un programa que use comentarios:

[me@linuxbox ~]$ cat > fmt-code.txt
# This file contains code with comments.

# This line is a comment.
# Followed by another comment line.
# And another.

This, on the other hand, is a line of code.
And another line of code.
And another.

Nuestro archivo de ejemplo contiene comentarios que comienzan con la cadena "# " (una # seguida por un espacio) y líneas de "código" que no. Ahora, usando fmt, podemos formatear los comentarios y dejar el código intacto:

[me@linuxbox ~]$ fmt -w 50 -p '# ' fmt-code.txt
# This file contains code with comments.

# This line is a comment. Followed by another
# comment line. And another.

This, on the other hand, is a line of code.
And another line of code.
And another.

Fíjate que las líneas de comentarios contiguas se unen, mientras que las líneas en blanco y las que no comienzan con el prefijo especificado se conservan.

5 comentarios: