Notxor tiene un blog

Defenestrando la vida

Lout, otro lenguaje de marcas

2021-04-21

El otro día, acabando el minicurso de LaTeX y comentándolo en el grupo de Telegram donde comentamos los artículos, salió la conversación sobre Lout. Ya hablé brevemente sobre este sistema en este blog hace un tiempo y conté una breve experiencia con él, pero no abundé mucho en cómo se usa, para qué sirve o por qué debería interesarte. En este artículo intentaré completar la información para todo aquel curioso que quiera, introducirse un poco más en esta herramienta. Como en el pasado artículo ya hablé un poco sobre la historia y procedencia de Lout, en este me centraré en los aspectos más prácticos.

¿Qué es Lout?

Lout es un sistema de marcado se genera documentos para impresión. El formato que utiliza de salida es PostScript, si se necesita un pdf se apoya en ghoscript para convertirlo. Puedes utilizar ps2pdf o cualquier otra herramienta similar.

Se podría decir que es una especie de LaTeX, pues prácticamente sirve para lo mismo. Sin embargo, está muy lejos de TeX en muchos aspectos: unos positivos y otros negativos. Entre los puntos positivos cuenta con la ligereza del sistema:

Contenido Espacio Unidad
lout.lib 5.4 Mb
lout 692.0 Kb
prg2lout 915.2 Kb
doc 7.6 Mb
Total 14.6 Mb

Es decir, todo el sistema está contenido en un poco más de catorce megas y media. En lout.lib está todo lo necesario para generar los documentos: las fuentes, las definiciones de documentos, etc. El fichero lout es el ejecutable que formatea nuestro documento pasándolo de texto plano con sus etiquetas a PostScript. Puede utilizar el ejecutable auxiliar prg2lout que a partir de un fichero de código genera una salida para que Lout pueda mostrar adecuadamente listados de código con coloreado de sintaxis y otros aditivos como número de línea, etc. Y por último, doc contiene toda la documentación sobre Lout. El contenido de la documentación es el siguiente:

Nombre Páginas
design 40
expert 120
slides 42
user 327

En el documento design hay unas breves explicaciones de cómo funciona el concepto de caja y cómo fluyen esas cajas en el diseño general, cómo se alinean y cómo pueden incluirse unas dentro de otras. En el documento expert se explican todos los comandos, se amplía el concepto de cajas y se añade un poco de bajo nivel (PostScript), diseño de páginas, definición de estructura de documentos, ampliación o importación de nuevas fuentes, etc. Por contra, slides presenta el sistema en formato de diapositivas haciendo una introducción sencilla de entender. Por último, el fichero user contiene toda la información relevante para el usuario final, desde cómo iniciar un documento, los comandos para dar formato a las páginas y a las fuentes, utilización de herramientas como prg2lout, o los comandos para utilizar color, o diseños gráficos, importar imágenes, hacer cuadros de texto y tablas; en resumen, toda la documentación que necesitas para utilizarlo escribiendo un documento, desde un simple resumen a todo un libro.

Instalación

La instalación es sencilla. Encontré que en OpenSuse puedes instalarlo porque tiene el paquete en su repositorio. Sin embargo, con mi habitual tendencia a complicarme la vida por cualquier tontería, con el único propósito de aprender más, me decidí a bajarlo y compilarlo. El código lo puedes encontrar en:

https://savannah.nongnu.org/projects/lout/

También considero parte de la instalación el preparar Emacs para poder utilizarlo. En este caso, no encontré ningún paquete en MELPA, sin embargo, en http://emarsden.chez.com/lout/ encontré un paquete que me proporciona un mínimo de utilidad para encontrarme cómodo editando documentos lout. Su instalación es algo más compleja, porque no consiste en llamar a package-install y ya.

Para instalarlo, descargué el paquete y descomprimí el contenido en el directorio ~/.emacs.d/lout-mode. En ese directorio se encuentra el fichero lout-mode.el y otro README. En el README se puede encontrar documentación sobre la instalación en nuestro sistema, pero hay que recordar que es un paquete de 1999 y el modo que ahí explica no funcionará en la actualidad, a poco actualizado que tengas Emacs. En mi configuración he añadido las siguientes líneas, en lugar del código recomendado en su documentación:

;; Configuración para Lout
(require 'lout-mode)
(add-to-list 'auto-mode-alist '("\\.lout\\'" . lout-mode))
(add-to-list 'auto-mode-alist '("\\.lt\\'" . lout-mode))

Como se puede ver, utilizo require para cargar el modo y añado dos extensiones (.lout y .lt) para que se inicie automáticamente el modo al abrir un fichero con esa extensión.

Limitaciones y ventajas

Tan reducido sistema de descripción de documentos, si lo comparamos con las gigas que puede ocupar TeX y sus derivados, no puede alcanzar todas las opciones que nos proporciona éste último. Sin embargo, se pueden hacer la mayoría de las cosas que se necesitan para editar un documento completo, con la ventaja de poder llevarlo todo en un espacio muy reducido. ¿Cuáles son las pegas, entonces? Por poner las que se me ocurren así a bote pronto:

  • No tiene editores dedicados, aunque como he explicado más arriba sí podemos encontrar un modo de Emacs que nos facilite el trabajo.
  • Encondings: El sistema espera que los ficheros estén escritos con el encoding latin-1. Si estás utilizando GNU/Linux o MacOS el encoding por defecto es UTF. Se hace necesario, si estás utilizando Emacs cambiar el encoding con set-codding-buffer-system, (C-x C-m f) y seleccionar latin-1. Sin embargo, a pesar de todo algunas fuentes, como la Dingbats no se verá correctamente, dependiendo de qué visor de documentos tengas.
  • Tipos de letra: Los tipos de letra son bastante más reducidos, pues de base sólo proporciona los definidos en PostScript.
  • Tipos de documento: Los tipos de documento que se pueden generar es más reducido, aunque con el genérico Doc se pueden realizar otros muchos y permite que derivemos de él los pripios.
  • Gráficos PostScript: Lout utiliza como lenguaje de programación para la descripción de las páginas el lenguaje PostScript. Un estándar que se ha ido dejando de lado en favor del PDF. Eso hace que las imágenes y todo lo que queramos que dibuje en nuestra página deba estar convertido a PostScript (.ps) o PostScript encapsulado (.eps).

Entre las ventajas, podemos enumerar también algunas que le hacen compañía a lo escueto de su instalación:

  • Sistema de diagramas, ─cajas, flechas, círculos─.
  • Sistema de gráficos, ─histogramas, gráficos de tarta─, perfectamente integrados desde la base del documento sin paquetes adicionales.
  • Sistema de tablas más flexible que en LaTeX.

Tipos de letra

Los tipos de letra que se pueden encontrar en Lout son los siguientes, especificando la familia y las formas que se pueden utilizar:

AvantGarde
Base Slope Bold BoldSlope BoldObl Book BookOblique CondBold CondBook CondDemi CondMedium Demi DemiOblique ExtraLight ExtraLightObl Medium MediumObl
Bookman
Base Slope Bold BoldSlope BoldItalic Demi DemiItalic Light LightItalic Medium MediumItalic
Chancery
Base Slope Bold BoldSlope Roman Bold Italic Light Demi LightItalic MediumItalic
Courier
Base Slope Bold BoldSlope BoldOblique Oblique
Helvetica
Base Slope Bold BoldSlope Black BlackOblique BoldOblique Compressed Cond CondBlack CondBlackObl CondBold CondBoldObl CondLight CondLightObl CondOblique ExtraCompressed Light LightOblique Narrow NarrowBold NarrowBoldObl NarrowObl Oblique UltraCompressed
Schoolbook
Base Slope Bold BoldSlope BoldItalic Italic Roman
Palatino
Base Slope Bold BoldSlope BoldItalic BoldItalicOsF BoldOsF Italic ItalicOsF Roman SC
Symbol
Base Slope Bold BoldSlope
Times
Base Slope Bold BoldSlope BoldItalic BoldItalicOsF BoldSC ExtraBold Italic ItalicOsF Roman RomanSC Semibold SemiboldItalic
Dingbats
Base Slope Bold BoldSlope

Como se puede apreciar, algunas familias cuentan con un gran número de formas externas y otras menos. Son los tipos de fuente que se definen y se cargan por defecto en los documentos PostScript. Todas proceden de Adobe y es posible que no se visualicen correctamente si no las tienes instaladas en tu ordenador. Por ejemplo, utilizando diferentes visualizadores de documentos podemos obtener resultados distintos:

Captura-pantalla_comparativa-visores.png

En la imagen vemos dos visores abriendo el mismo fichero, ─el manual de usuario─, por la misma página, donde se muestra una tabla de símbolos. A la izquierda, xpdf no tiene problemas para interpretar correctamente todos los caracteres especiales, sin embargo, a la derecha, Okular no muestra aquellos que provienen de la fuente Symbol de Adobe.

Por lo que he podido ver, al exportar a pdf, el comando ps2pdf incrusta las fuentes pero hay algunas, como Symbol, que no lo hace, así que depende del visor encontrar una fuente adecuada para sustituirla al visualizar el documento. Los documentos generados con Lout se visualizan mejor con gv si es PostScript o con xpdf si es pdf.

Tipos de documento

Los tipos de documentos que vienen por defecto son:

  • doc. Cualquier tipo de documento, puede ser una nota, un artículo o cualquier otro tipo.
  • report. Un tipo de documento que se utiliza para informes sencillos. No tiene tantos tipos de sección definida como para un libro.
  • book. Este paquete contiene todas las secciones definidas para generar un libro.
  • slides. Este paquete contiene las definiciones necesarias para definir presentaciones.
  • picture. Este tipo de documento está pensado para utilizar el código para generar un gráfico o un diagrama con las herramientas que proporciona Lout. Lo habitual es convertir la salida a encapsulated PostScript para poder usarlo en otros documentos.

No son muchos tipos de documento, pero se pueden personalizar muy fácilmente definiendo parámetros en la cabecera. Además, basándonos en ellos, podemos armar nuestro propio tipo de documento fácilmente.

Tratamiento de los idiomas

El sistema provee diversos lenguajes con los que trabajar en los documentos. Así nos traduce las cabeceras del documento como capítulo o sección, o nos proporciona en esa lengua fechas. Los idiomas son los siguientes:

Croatian Hrvatski Italian Italiano it
Czech Cesky Cestina cs Norwegian Norsk no
Danish Dansk da Polish Polski pl
Dutch Nederlands nl Portuguese Português pt
English en Programming
EnglishUK en-GB Russian ru
Esperanto eo Slovak Slovensky Slovencina
Finnish Suomi fi Slovenian Slovenia Slovenija sl
French Francais Français fr Spanish Español es
German Deutsch de Swedish Svenska sv
Hungarian Magyar hu UpperSorbian hornjoserbsce serbsce

Cada uno de ellos se pueden llamar por cualquiera de esos nombres. Es decir, para seleccionar el idioma español podemos utilizar cualquiera de los siguientes nombres: Spanish, Español o es. Sin embargo, cuando alguno de esos nombres contiene algún carácter especial como la ñ si creas el documento desde utf es posible que no comprenda el comando.

Posteriormente, en el texto se pueden intercalar otros lenguajes llamando al comando @Language con el texto. Pero hay que recordar que para visualizar los textos en cirílico hay que importar el paquete latin2.

¿Cómo funciona?

Si vienes de LaTeX verás que el funcionamiento general sigue ciertas pautas parecidas: hay una serie de macros o comandos que describen un documento final. Además, esos macros o comandos pueden recibir opciones para funcionar. ¿Cuáles son las diferencias? Pues básicamente, hay que contar con que el carácter que determina un macro o comando es @, en lugar del carácter \ que se utiliza en TeX. En realidad, el carácter @ es un adorno pues podemos definir comandos que no lo lleven y funcionarán correctamente sin él.

La manera más sencilla de utilizar este sistema es elegir un tipo de documento en la cabecera y comenzar a escribir texto.

Lout lo que hace es ir reservando espacio formando marcos que van incluyéndose unos dentro de otros, de izquierda a derecha y de arriba hacia abajo. Cada contenido se va añadiendo al anterior y va rellenando la página, cuando esta se completa, continúa en la página siguiente. Por supuesto, podemos delimitar cada bloque que se verá afectado por ese flujo o por un comando, utilizando los caracteres {}.

Si me permitís, voy a poner un ejemplo amplio, aunque no exhaustivo de las capacidades de Lout. Después, lo comentaré y será más fácil de entender que hablando de forma abstracta.

# -*- lout -*-
# El enconding Latin-1 es necesario para que todo funcione como corresponde.
@SysInclude { tbl }
@SysInclude { diag }
@SysInclude { math }
@SysInclude { doc }

def @Comillas right x { @Char guillemotleft{x}@Char guillemotright }
def @Cuadro left y right x {
  @Box
    margin { 1f }
    paint { y }
  {x}
}

@Document
  @InitialFont { Palatino Base 12p }
  @InitialLanguage { Spanish }
//

@Text @Begin
@PP
En este párrafo se puede utilizar por ejemplo el tipo en @B negrita o
en @I itálica. También se podía cambiar el tipo de texto con de la
siguiente manera: { Helvetica Base } @Font { este texto se mostrará en
Helvetica }.

@PP
Podemos cambiar sobre la marcha la fuente, el color, el tamaño o
incluso hacer diagramas de cajas y flechas. Podemos escribir por
ejemplo @F "{ 20p } @Font Grande" para conseguir el efecto 20p @Font
Grande en nuestro texto. También podemos alinear ese baselinemark
@Font { texto más 20p @Font grande con el resto del texto }.

@PP @CentredDisplay
@Math { int from { 0 } to { 1 } dx over sqrt {1 - x sup 2} = pi over 2 }

@BeginSections
@Section @Title {Primera sección}
  @Tag { sec:primera }
@Begin
@LP @Comillas { Hola Mundo! }

@LP { lightgray } @Cuadro { Hola Mundo! }
@LP { lightblue } @Cuadro { Hola Mundo! }

@PP
Podemos escribir un documento en un lenguaje @I Base pero podemos
intercalar frases o textos en otro idioma utilizando el comando @F
"@Language", como por ejemplo escribir la fecha en Esperanto
@Comillas { Esperanto @Language @Date } utilizando el comando @F
{"Esperanto @Language @Date"} y luego seguir escribiendo en
el idioma base.

@End @Section

@Section @Title { Segunda sección }
  @Tag { sec:segunda }
@Begin

@PP
Un parrafo que es el contenido de la sección, aunque también lo podríamos
dividir en subsecciones. Los párrafos se marcan con @F "@"PP

@PP Tipos de legra:
@LP
{ AvantGarde Base } @Font AvantGarde, @LP
{ Bookman Base }    @Font Bookman,    @LP
{ Chancery Base }   @Font Chancery,   @LP
{ Courier Base }    @Font Courier,    @LP
{ Helvetica Base }  @Font Helvetica,  @LP
{ Schoolbook Base } @Font Schoolbook, @LP
{ Palatino Base }   @Font Palatino,   @LP
{ Symbol Base }     @Font Symbol,     @LP
{ Times Base }      @Font Times,      @LP
{ Dingbats Base }   @Font Dingbats.

@End @Section

@EndSections

@End @Text

Para generar el documento PostScript he utilizado el siguiente comando:

lout -S prueba > prueba.ps

El parámetro -S es un seguro de ejecución (safety). Evita que Lout ejecute ningún comando del sistema. Eso nos permite mirar en la salida del programa qué comandos necesita ejecutar y determinar si es seguro hacerlo. Todo esto porque Lout puede ejecutar código awk, o incluso groff, para generar la salida y eso podría hacer que se ejecute en el sistema cualquier programa de manera maliciosa. En este caso, como es un documento sencillo, no tiene llamadas a ningún programa externo, como prg2lout, se consigue la salida de manera directa y se genera en modo seguro.

El código de ejemplo que se muestra arriba produce el siguiente documento.

Captura-pantalla_documento-postcript.png

La captura de la imagen anterior se ha hecho sobre el viejuno visor de PostScript gv, que supongo que a estas alturas prácticamente nadie tendrá instalado en su ordenador. El código que mostré anteriormente está situado en un fichero que he llamado prueba, sin ninguna extensión. Por esto, en el código le indico en la primera linea a Emacs que es un fichero Lout para que active el modo correspondiente cuando lo abro con el editor.

# -*- lout -*-

Como se puede apreciar, en Lout los comentarios se introducen con el carácter #.

Después, en el documento se realiza una serie de importaciones de código. En este sentido es similar a LaTeX: cuenta con una cabecera separada del cuerpo del documento, donde se hace la importación de paquetes y se programan los macros que se necesitarán luego.

@SysInclude { tbl }
@SysInclude { diag }
@SysInclude { math }
@SysInclude { doc }

def @Comillas right x { @Char guillemotleft{x}@Char guillemotright }
def @Cuadro left y right x {
  @Box
    margin { 1f }
    paint { y }
  {x}
}

Las importaciones son:

  • tbl: Importa los comandos necesarios para dibujar tablas. Luego no lo he usado en el cuerpo de texto. Iba a ser más exhaustivo presentando el sistema pero casi da para hacer otro minicurso en lugar de un artículo introductorio como me he planteado este.
  • diag: Importa todos los comandos para dibujar diagramas, cajas, flechas, etc.
  • math: Importa todos los comandos necesarios para escribir fórmulas matemáticas.
  • doc: Importa todo lo necesario para escribir un documento, como los tipos de letra, los estilos de texto, los encabezados, etc.

Si fuera un grupo de ficheros, para hacer la importación del contenido, se utilizará @Include, dejando el comando @SysInclude para importar ficheros del sistema.

Después de las importaciones, vemos un par de macros definidos con def. El primero lo he definido igual que se hizo en LaTeX. Para explicarlo mejor podemos comparar las siguientes líneas:

En LaTeX:

\newcommand{\comillas}[1]{\guillemotleft{#1}\guillemotright}

En Lout:

def @Comillas right x { @Char guillemotleft{x}@Char guillemotright }

Podemos ver que hemos definido un comando @Comillas que recibe un parámetro x; right x significa que el comando se aplicará al elemento que aparezca directamente a la derecha del comando. En este caso, como en el de LaTeX se introduce el parámetro entre los caracteres de comillas angulares o guillemot: «». Podemos apreciar que cuando lo llamamos en el texto del documento con @Comillas { Hola Mundo! } produce de salida «Hola Mundo!».

Por ilustrar cómo hacer una macro un poco más compleja, he definido un comando @Cuadro, que toma una opción de color y dibuja un marco de ese color al rededor del texto que se pasa como parámetro. La opción se define a la izquierda como left y1 y el contenido viene definido como right x. Se pueden definir parámetros con nombre también, pero sólo merecen la pena si te planteas utilizar este sistema hasta hacerte un usuario (muy) avanzado. El código de esta segunda definición es sencillo de entender:

def @Cuadro left y right x {
  @Box
    margin { 1f }
    paint { y }
  {x}
}

Como vemos, el macro @Box recibe dos parámetros: uno con nombre margin que se establece a 1f2 y otro paint que pintará el fondo de la caja con el color que se especifique en el parámetro y. Y dicha caja la rellenará con el contenido el parámetro x. En la imagen, podemos apreciar que hemos dibujado dos cajas con el mismo contenido pero con distinto color de fondo de la siguiente manera:

@LP { lightgray } @Cuadro { Hola Mundo! }
@LP { lightblue } @Cuadro { Hola Mundo! }

La secuencia de comando establece un nuevo párrafo sin sangría (@LP), y después se proporciona un comando con la estructura simplificada de color @Cuadro texto. Los colores utilizados están definidos en el fichero xrgb del sistema Lout.

Después de la cabecera viene el cuerpo del documento. Tiene la siguiente forma:

@Document
  @InitialFont { Palatino Base 12p }
  @InitialLanguage { Spanish }
//

@Text @Begin

...

@End @Text

Como se puede apreciar, el comando @Document recibe algunos parámetros con nombre, concretamente, he definido el tipo de fuente base y el lenguaje inicial del texto. Igualmente se podrían definir muchos otros parámetros. Debo recordar que las opciones aquí definidas se establecen de manera general, pero pueden ser modificadas puntualmente. El documento de ejemplo muestra más adelante cómo podemos cambiar el idioma puntualmente o el tipo de letra o su tamaño. También hay que recordar que el contenido del documento se encontrará entre las etiquetas @Text @Begin de inicio y @End @Text para finalizar.

Al llamar a Esperanto @Language @Date nos devuelve la fecha del día con el formato definido para Esperanto: 21a de aprilo de 2021, aunque el idioma del documento se estableció a Spanish. Los idiomas se pueden establecer con varias palabras clave, como por ejemplo: Spanish, Español, es. Sin embargo, me he encontrado con algunas dificultades por el empleo de caracteres especiales como la ñ que al no coincidir el código UTF con el Latin1 es posible que dé errores.

También podemos establecer algunos cambios en las fuentes, como el estilo:

Macro Estilo
@B Negrita (Bold)
@I Itálica (Italic)
@R Regular o Roman
@S Mayúsculas (Small Caps)
@F Fija (Fixed)
@BI Negrita e Itálica
@II Énfasis

En el último caso, @II produce un estilo de itálica cuando se encuentra rodeado de texto en roman, pero produce un estilo roman si se encuentra rodeado de texto en itálica. Sería el equivalente al comando emph de otros sistemas. Los demás estilos son los habituales.

Si miramos en el ejemplo también se puede apreciar cómo se ha cambiado puntualmente a texto de paso más grande con el comando simplificado de tamaño @Font texto o incluso cómo se ha cambiado la familia de la fuente con familia @Font texto.

Conclusión

Como se puede apreciar en esta introducción el sistema de creación de documentos de Lout es bastante sencillo, aunque completo. Es sencillo crear nuevas macros y tiene la potencia suficiente como para generar cualquier tipo de salida.

Me he dejado en el tintero varios aspectos avanzados para la generación de documentos, como su propio sistema de gráficos: histogramas, líneas, gráficos de tarta. Un sistema completo de dibujo de diagramas: diagramas de análisis de sintaxis, cajas, flechas, círculos. También un sistema completo para generar tablas complejas, con diferentes estilos de líneas, columnas y celdas. Además de contar con un completo sistema para representar fórmulas matemáticas.

Tampoco he hablado de sus capacidades para generar bibliografía y contar con un índice temático alfabético. Ni sobre la posibilidad de hacer referencias internas.

Puedes descargar los ficheros del ejemplo:

Footnotes:

1

Se podría haber definido con cualquier nombre, por ejemplo left color, pero no quería inducir a pensar que pudiera ser alguna palabra clave.

2

f es la unidad de medida que representa el tamaño de letra actual definido en el documento. También podría haberse definido en base a c (centrímetros), i (pulgadas), p (puntos)...

Categoría: lout documentos

Comentarios

Debido a algunos ataques mailintencionados a través de la herramienta de comentarios, he decidido no proporcionar dicha opción en el Blog. Si alguien quiere comentar algo, me puede encontrar en Mastodon y en Diaspora con el nick de Notxor.

También se ha abierto un grupo en Telegram, para usuarios de esa red.

Disculpen las molestias.