Lout, otro lenguaje de marcas
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 esUTF
. Se hace necesario, si estás utilizando Emacs cambiar el encoding conset-codding-buffer-system
, (C-x C-m f
) y seleccionarlatin-1
. Sin embargo, a pesar de todo algunas fuentes, como laDingbats
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:
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.
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: 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 y
1 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 1f
2 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:
- Fuente: ./imagenes/prueba
- PostScript: ./imagenes/prueba.ps
PDF
: ./imagenes/prueba.pdf
Footnotes:
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.
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)...
Comentarios