DocBook: un original, múltiples formatos
De las numerosas tecnologías existentes utilizables por artistas de la palabra escrita
para una autoedición independiente, he tenido a bien elegir la que aquí se presenta.
Tal vez pueda parecerte algo enrevesado y complicado si careces de ciertos conocimientos
sobre informática, pero a mí me va de perlas. No vayas a creer que pretendo que tú
también la uses; una cosa es el estilo adoptado y otra mis intenciones. Simplemente trato
de explicarte la manera en que consigo los diferentes formatos de los volúmenes que
puedes encontrar en la biblioteca, con idea de
mitigar tu curiosidad si por esta causa no pudieses conciliar el sueño alguna que otra
noche. Caso de ser contraria tu muy digna y respetable opinión, te hago saber que me da
igual, ya que en esta ocasión mi elección no depende de lo que tú piensas sino de lo que
yo prefiero.
- ¿Qué es DocBook?
- Con DocBook todo es texto
- Breve introducción al lenguaje XML
- Instalando DocBook
- Estructura de la documentación de DocBook5
- DocBook XSL: el cómo
- Las entidades XML en DocBook
- Escribiendo en DocBook
- Imágenes en DocBook
- Matemáticas en DocBook
- Obteniendo los formatos elegidos
- Consideraciones sobre la tipografía
- Organizándolo todo
- El programa make y los archivos Makefile
- Sugerencia final
¿Qué es DocBook?
Deberíamos empezar por definir, o explicar de alguna forma, qué cosa en el universo conocido es DocBook. Pero eso ya está hecho en varios sitios, así que veamos lo que dice al respecto la Wikipedia en inglés:
DocBook es un lenguaje de marcado semántico para la documentación técnica. Originalmente fue diseñado para escribir documentos técnicos relacionados con hardware y software, pero puede usarse para cualquier otro tipo de documentación. Como lenguaje semántico, DocBook permite crear documentos en una forma neutral de presentación que captura la estructura lógica del contenido; ese contenido puede publicarse en una variedad de formatos, incluyendo HTML, XHTML, EPUB, PDF, páginas de manual, Ayuda Web y Ayuda HTML, sin requerir ningún cambio en el original. En otras palabras, cuando un documento está escrito en formato DocBook, se puede transportar fácilmente a otros formatos. Resuelve el problema de reformatear escribiendo el texto una sola vez utilizando elementos XML.
DocBook recoge el contenido y la estructura lógica del escrito, y a partir de ahí
se pueden obtener los diferentes formatos mediante la aplicación de determinadas
plantillas de presentación, procesadas por ciertos programas a los que podríamos
llamar conversores
. Pero no solamente es útil para la escritura de documentación
técnica, veamos lo que se dice al respecto en su propio sitio web
(el resaltado en negrita es mío):
DocBook proporciona un sistema para escribir documentos estructurados utilizando XML. Es particularmente adecuado para libros y documentos sobre hardware y software, aunque de ninguna manera se limita a ellos. Debido a que es un formato grande y robusto, y a que sus estructuras principales corresponden a la noción general de lo que constituye un libro, DocBook ha sido adoptado por una gran y creciente comunidad de artífices. Es compatiblede fábricacon una amplia gama de herramientas, tanto de código abierto como comercial. En resumen, DocBook es un esquema fácil de entender y ampliamente utilizado. En todo el mundo, cientos (quizás miles) de organizaciones usan DocBook para millones de páginas de documentación en una amplia variedad de formatos impresos y en línea.
Los manuales están en inglés y es necesario consultarlos. Es lo que tienen estas
tecnologías: el inglés es el idioma internacional de la informática y así hay que
aceptarlo. Traducir este tipo de documentación no sería práctico, ya que suelen
aparecer nuevas versiones cada cierto tiempo y, dado su volumen, podríamos acabar
realizando la traducción interminable
. Pero, si no sabes inglés, ten presente
que los traductores automáticos pueden ayudar bastante (a mi propia experiencia me
remito).
DocBook no es perfecto, ya veremos que tiene sus carencias y dificultades, pero cumple sobradamente los propósitos de autoedición de este modesto digituense, que es de lo que se trata.
Con DocBook todo es texto
Una —para mí importante— ventaja de usar DocBook, es que el texto siempre será accesible
de una forma u otra. Un escrito en DocBook permanecerá tal cual
, estando
disponible sin depender en absoluto del software de escritura utilizado o de su versión,
ya que es, pura y simplemente, texto.
Para escribir algo en DocBook se necesita una herramienta informática denominada
editor de texto, a la que no hay que confundir con otra denominada procesador
de texto. Un editor es para crear y modificar textos sin aplicarles ningún tipo de
formato, mientras que un procesador es para crear y modificar textos a los que se les
aplican algunos formatos, como pueden ser el tipo, tamaño y grosor de letra, colores,
subrayados y otros detalles que pasarán a formar parte del documento una vez guardado.
Un editor de texto únicamente guarda los caracteres que hallamos escrito con el teclado
tal cual
, sin ningún tipo de especificación adicional. El que más acostumbro a
usar es Emacs, pero hay muchos
otros editores y eres libre
de elegir tu preferido. Aviso: no confundas un editor de texto con un
IDE. Un
entorno de desarrollo integrado es parecido —solo parecido— a un editor de texto, pero
tiene funcionalidades específicas para la programación informática, las cuales lo hacen
más complicado de lo realmente necesario para acometer escritos con pretensiones
literarias.
Para utilizar DocBook, mi recomendación es dejar aparte los procesadores de texto y los
IDE, centrándonos en la elección de un sencillo y cómodo editor de texto que reconozca
la sintaxis del lenguaje XML.
Los editores de texto suelen estar asociados a la programación, debido a que un
compilador no interpreta otra
cosa que el texto del programa escrito tal cual
, de la misma manera que lo hacen
los programas que procesan las plantillas de presentación de DocBook. En cierta forma,
podría decirse que escribir utilizando DocBook tiene algún tipo de lejano parecido con
programar. Pero si no queremos molestarnos en buscar y no nos importa el
resaltado de sintaxis,
podemos utilizar algo tan simple como el Bloc de Notas
(notepad) de los sistemas
Windows (por poner un ejemplo de algo bastante conocido) o, si hablamos de sistemas
basados en GNU/Linux, el socorrido
nano.
Breve introducción al lenguaje XML
Se supone que XML es entendible tanto para las personas como para las máquinas, pero
como en este mundo nada es perfecto, no falta quien opine que no es comprensible de
manera eficiente
ni para las unas ni para las otras. Sea como fuere, la realidad es
que ha llegado para quedarse, así que algunos someros conocimientos sobre qué es y como
funciona no nos vendrán mal, por poco que nos interesemos por las tecnologías que han
dado en llamar de la información y la comunicación
(TIC).
Marcas o elementos
Decíamos que DocBook es un lenguaje de marcado, así que empecemos por ver qué son las
marcas XML. Cada marca (o elemento) se compone de dos etiquetas: la de apertura y la
de cierre. Una etiqueta XML está formada por el signo <
, el nombre
de la marca y el signo >
si se trata de la etiqueta de apertura. En
el caso de la etiqueta de cierre, se debe incluir la barra inclinada al principio:
</
, quedando todo en esta forma:
<nombreMarca>contenido al que aplicar la marca</nombreMarca>
Se pueden incluir unas marcas dentro de otras —también llamado anidar
marcas—, pero
tiene que estar permitido en el esquema del tipo de documento, y siempre teniendo en
cuenta que deben ser cerradas en orden inverso a como fueron abiertas. Por ejemplo:
<marcaUno><marcaDos>>contenido</marcaDos></marcaUno>
será correcto si el esquema del documento —digamos DocBook— lo permite, pero:
<marcaUno><marcaDos>contenido</marcaUno></marcaDos>
será siempre incorrecto, porque las etiquetas de cierre no aparecen en el orden
exigido. Como regla general podríamos decir que, una vez abierta una marca, la misma
no debe cerrarse sin que esté cerrada cualquier otra marca que haya sido abierta a
continuación, o dentro
de ella. También es importante tener en cuenta que los
nombres de las marcas han de ser escritos respetando mayúsculas y minúsculas.
En DocBook las especificaciones de formato se indican utilizando las marcas definidas para ello, obteniendo el resultado final al procesar nuestro escrito aplicándole la correspondiente plantilla de presentación o de estilo.
En muchos otros sitios, los términos marca
y etiqueta
son utilizados
indistintamente. Sin embargo aquí nos parece apropiado, con el objetivo de ayudar a
evitar confusiones, utilizar marca
para el nombre de la misma, y etiqueta
para cada una de las dos que componen la marca: la de apertura y la de cierre. No
obstante dejamos claro que se puede —y tal vez se debería— sustituir marca
por
elemento
, pero el criterio adoptado es que marca
alude más claramente a la
acción de marcar (valga la redundancia) una porción de texto para aplicarle unas
determinadas características.
Cuando el escrito sea procesado a través de la plantilla para el formato escogido,
se aplicarán las modificaciones adecuadas al texto contenido en cada marca, para así
obtener el resultado final. Por ejemplo, en el formato HTML la marca
link genera un enlace de
hipertexto normal, pero esa misma marca en el formato PDF imprime el texto de la
dirección enlazada, porque si estamos leyendo en papel no podemos hacer clic
con
ningún ratón sobre el mismo.
Las reglas del XML obligan a cerrar toda marca que haya sido abierta, pero en la mayoría
de ellas es posible indicar que no tienen contenido —o que su contenido es nulo—,
colocando la barra al final del nombre en la etiqueta de apertura, con lo que se evita
tener que escribir la etiqueta de cierre. Las dos primeras líneas del ejemplo siguiente
son interpretadas de igual manera por el
analizador sintáctico
(parser en inglés), esto es: marca con contenido nulo
, pero si incluyéramos
aunque solo fuera un único espacio entre las etiquetas dejaría de ser contenido nulo,
porque para una máquina el espacio en blanco es un carácter como cualquier otro. Si
incluyéramos muchos espacios en blanco seguidos, todos ellos serían interpretados como
uno solo, debido a que XML es un lenguaje que se ocupa del contenido y de la estructura
de la información, pero no de su presentación. Para añadir más espacios visibles habría
que utilizar la entidad non-break-space (espacio irrompible) que se representa
como
<nombreMarca></nombreMarca> <!-- Contenido nulo (o sin contenido) -->
<nombreMarca/> <!-- Contenido nulo (o sin contenido) -->
<nombreMarca> </nombreMarca> <!-- Un único espacio visible -->
<nombreMarca> </nombreMarca> <!-- Cuatro espacios visibles -->
<!--
Esto es un ejemplo de comentario con varias líneas.
Los comentarios no son visibles en el documento final producido
tras procesar el escrito DocBook con la plantilla adecuada.
-->
La existencia de marcas con contenido nulo, o vacías, se justifica por el hecho de que puede haber esquemas de documento que obliguen a incluir determinadas marcas, tengan o no contenido. El programa analizador produciría errores si no se incluyen, pero no tenemos por qué tener la obligación de escribir la etiqueta de cierre de una marca vacía.
En el ejemplo anterior hemos introducido sin previo aviso los comentarios para XML. Un
comentario es cualquier texto incluido entre las secuencias de signos <!--
y
-->
. Está permitido escribir comentarios de varias líneas, pero no se pueden
anidar comentarios (señalizar un comentario dentro de otro), ni tampoco mezclar
comentarios con las etiquetas. Su utilidad radica en proporcionar un medio de anotar
explicaciones, o información que se considere relevante, para una correcta comprensión de
la estructura del documento, como por ejemplo recordar el porqué algo se hizo de un
determinado modo y no de otro. Naturalmente, pueden ser usados para cualquier propósito
que se nos ocurra y que requiera texto no visible, pero sí legible por dentro
,
para entendernos.
Atributos
Además de contenido, una marca XML también puede poseer atributos. Los atributos son datos relativos a un elemento (o marca) específico, debiendo ir siempre en la etiqueta de apertura. Constan de dos partes, nombre y valor, separadas por el signo de igual sin espacios. El valor tiene que estar entrecomillado, ya sea con comillas dobles ("valor") o simples ('valor'). Los atributos también están definidos en el esquema de tipo de documento. El valor de cada atributo puede ser elegido de una lista de opciones predeterminadas, o puede consistir en un texto que debamos proporcionar, como por ejemplo el nombre y ubicación de un archivo de imagen. Si una marca contiene varios atributos, éstos deben estar separados por espacios sin que el orden importe. Al igual que las marcas, pueden ser obligatorios u opcionales dependiendo del esquema del documento. Veamos como ejemplo el atributo role de la marca emphasis para conseguir texto en negrita:
<para> <!-- Apertura de la marca para, abreviación de paragraph (párrafo) -->
El texto final tendrá <emphasis role="bold">estas tres palabras</emphasis>
en negrita pero sin el atributo role="bold" estarían en cursiva.
</para> <!-- Cierre (fin) de párrafo -->
Las marcas de párrafo (para)
son de las principales a tener en cuenta para la escritura de nuestra obra en DocBook.
Cada nuevo párrafo deja un espacio vertical en el documento definitivo, siendo
normalmente utilizado tras el punto y aparte. No hay forma de controlar la longitud de
las líneas, de eso se encarga el dispositivo que se use como lector, ya que unas
pantallas pueden ser más anchas, otras más estrechas, y el usuario puede decidir
redimensionar la ventana. No importa que se escriba una palabra por línea, diez mil, o
incluso el documento completo en una sóla línea: cada párrafo será ajustado al ancho de
la ventana en que se visualice. Pero entonces, ¿cómo se pueden escribir versos? Pues
utilizando la marca literallayout,
que hará que el texto se visualice tal cual
.
Instalando DocBook
Hay al menos dos formas de instalar DocBook, las cuales diferenciaremos llamando a una
hazlo todo por tu cuenta
y a la otra tu sistema ya lo incluye
. En ambos casos es
conveniente echarle un vistazo a las
instrucciones de instalación y también a la DocBook Wiki.
Si eliges hacerlo todo por tu cuenta, lee atentamente dichas instrucciones de
instalación, síguelas lo más fielmente que puedas, y que la suerte te acompañe, joven
digituense.
Si tu sistema ya incluye DocBook, que debería ser lo normal si está basado en GNU/Linux, debes instalarte como mínimo los paquetes para XML y XSL. En Arch Linux, distribución que he usado durante algún tiempo, se denominan docbook-xml y docbook-xsl. Los nombres pueden variar algo de una distribución a otra y podría ser necesario instalar más, o menos, paquetes. En el caso de Debian, a la que he vuelto después del escarceo con Arch, serían docbook5-xml y docbook-xsl-ns, pero no conozco todas las distribuciones —sería imposible— como para saber cuantos paquetes son necesarios en cada una y como se llaman. Si ya usas GNU/Linux no debería serte difícil encontrar en la documentación de tu distro la forma de instalar DocBook XML (también hay una versión SGML, pero no nos interesa). Como soy adicto al terminal, en mi caso lo haría como el usuario root, administrador del sistema, tal que así (Arch):
~# pacman -S docbook-xml docbook-xsl
o así (Debian):
~# apt install docbook5-xml docbook-xsl-ns
En Arch Linux, docbook-xsl se encuentra en el
AUR.
Estuve usando
Trizen
como ayudante del AUR
, que en el argot se suele llamar
AUR helper.
Pero si no quieres empezar escribiendo cosas raras
en una consola de texto, aunque
ya te aviso de que tendrás que hacerlo si decides usar DocBook, siempre puedes utilizar
Synaptic, que funciona muy bien sobre
modo gráfico pero solo en Debian (si usas Arch se presupone que has pasado la iniciación
a la magia
del terminal). La última vez que instalé Debian desde cero,
rama en pruebas), docbook5-xml
fue incluido directamente, así que solo necesité añadir docbook-xsl-ns. El resto
de paquetes necesarios, o dependencias, se instalarán automáticamente junto con los
principales. Mas si acaso alguno no fuese instalado como se espera, cuando utilices los
programas de conversión te apercibirás de ello, y sabe, diligente digituense,
que leyendo con atención las líneas que han aparecido en el terminal, alguna de ellas te
contará sobre lo buscado y no hallado, la cual cosa es aquello que tú deberás instalar
denodadamente.
Estructura de la documentación de DocBook5
Hora es ya de decir que todo lo que estamos escribiendo sobre DocBook se refiere a su versión 5.0 o posterior. A partir de esta versión DocBook utiliza Relax NG para la definición, considerando la DTD como no estándar, por lo cual ya no necesita ser incluida. Además, el usuario debe añadir su propio archivo de entidades, dado que por defecto no se proporciona ninguno.
Si a duras apenas has podido entender algo del párrafo anterior, considéralo para gente experta y no te preocupes, que pasito a paso iremos avanzando.
Como una imagen vale más que mil palabras, utilizaremos la que aparece a continuación
para tratar de proporcionar una visión acerca de cómo hay que entender los diversos
apartados en los que se divide la
documentación proporcionada por DocBook.
Tomemos como ejemplo la marca chapter
(capítulo).
Los apartados encuadrados se corresponden con la estructura de un esquema Relax NG —cuya sintaxis es también XML—, pero esto no nos afecta como digituenses, así que dejaremos los detalles para amantes de la ingeniería, intentando por nuestra parte dar algunas sencillas directrices sobre su interpretación:
- One of: Es obligatorio incluir solo una de las marcas de la lista.
- Zero or more of: Es opcional incluir alguna o más de las marcas de la lista.
- One or more of: Es obligatorio incluir una o más de las marcas de la lista.
Si un apartado pertenece a otro, lo que se denota porque está debajo del mismo y más a la derecha, se le aplica lo mismo que al apartado al cual pertenece además de lo que por sí mismo especifique.
A continuación, moviéndonos hacia abajo, encontramos los atributos de la marca. Si Damos
clic
sobre el enlace
common attributes,
iremos a parar hacia la mitad de una página donde se explica la estructura de los
elementos que aparecen en la documentación. En inglés, claro está. Dicha página describe
los atributos comunes de los elementos y sus posibles valores. Aquí encontramos, entre
otros, xml:lang, cuyo valor hay que escoger de entre los códigos de idiomas y
países. A continuación están los Additional attributes, o atributes específicos
de esa marca. Y surge la pregunta: ¿cómo se pueden encontrar estas cosas? cuya respuesta
es: buscándolas. Trataré de explicar la manera en que lo hago, no sin advertir de que a
partir de ahora tenemos que digerir inglés.
Al final de la página que documenta las propiedades de cada elemento suele venir un
ejemplo de uso, como el de la siguiente imagen, que corresponde a chapter.
De los atributos incluidos en chapter, resaltados con fondo amarillo, puede
resultar conveniente utilizar xmlns="http://docbook.org/ns/docbook" y version="5.0"
(o la que estemos usando, "5.2" a la fecha de la última revisión),
con objeto de evitar que algún analizador se queje
si no los encuentra. Los otros no
son necesarios, salvo que queramos etiquetar internamente el capítulo (label) y/o
dotarlo de una identificación para poder enlazarlo (xml:id), como se explica en el
apartado relativo a la inclusión de imágenes. La marca
info no es imprescindible
aquí, pero deberíamos añadir title
aunque la dejemos vacía. Los ejemplos que DocBook proporciona suelen incluir elementos
opcionales, pensamos que con intención de mostrar algunas posibilidades además de las
básicas.
En 2020 ha aparecido una nueva versión de la documentación,
DocBook 5.2, lo que me ha llevado a
revisar una vez más este artículo, actualizando los enlaces a la misma. No la he
comparado a fondo con la 5.0, pero las diferencias no serán grandes, puesto que no se
trata de una versión mayor, como sería la 6.0 por ejemplo, sino de una menor, ya que
únicamente ha cambiado a la 5.2
.
DocBook XSL: el cómo
La documentación mencionada hasta ahora podemos considerarla referente a que
marcas
incluir y a dónde
incluirlas, pero todavía falta conocer algo sobre el cómo
se consiguen los distintos formatos finales. Para ello es necesario tener en cuenta una
segunda parte: DocBook XSL.
Solo leyendo el índice ya podemos hacernos una idea de por dónde van las cosas. El manual
XSL contiene información sobre (casi) todo lo necesario, incluidos los programas para
realizar las conversiones. Si algo se resiste, una hábil búsqueda en la web de habla
inglesa (o sea, en inglés) seguro que nos dará respuesta.
XSLT es el lenguage de
transformación que se emplea para convertir un documento XML en un formato diferente, que
lo mismo puede ser otro XML con características distintas o, más habitualmente, HTML y
también EPUB. Viene a ser un conjunto de herramientas, de las cuales XSLT es la que se
usa para las transformaciones y que a su vez engloba a
XPATH. Los archivos que lo
utilizan acostumbran a tener la extensión .xsl y no .xslt. Aquí no nos
vamos a extender en explicaciones, baste con decir que es lo que se utiliza en las hojas
de estilo, o plantillas, para obtener y personalizar los formatos HTML, EPUB y PDF. Para
el PDF no se usa XSL exactamente de la misma forma que para los otros dos, sino a través
del software Apache Fop, de mayor
complejidad que XSL tal cual
. Uno puede tener algo de idea de cómo usar XSL, pero
no tanto de Apache Fop. No obstante, la documentación XSL de DocBook está bien
provista de ejemplos, y hasta ahora no he tenido difultades más allá de localizar lo que
necesito y copiarlo, quizás con alguna pequeña adaptación. Apache Fop únicamente
lo emplearemos para obtener y personalizar un poco el formato PDF.
En octubre de 2020 aparece una versión llamada
DocBook xslTNG Reference,
también de Norman Walsh,
en la que que se detalla el uso de las hojas de estilo y que incluye un apartado donde se
referencian los parámetros utilizados, principalmente para la conversión a HTML. Por lo
que a mí respecta, DocBook XSL: The Complete Guide, anteriormente enlazada, sigue
siendo el principal punto de apoyo para estos menesteres. En esta versión de octubre de 2020
se menciona únicamente a Saxon
como programa de conversión, junto con un
entorno Java,
aunque se comenta de paso que con el procesador XSLT de su elección puede transformar
los documentos DocBook usando la correspondiente hoja de estilo docbook.xsl
.
Pensamos que puede ser debido al interés de los responsables de DocBook en que su
tecnología se utilice en la mayor cantidad de sistemas posible, despegándose
de
Linux como Sistema Operativo de referencia, cosa que me parece muy bien siempre que
continúe funcionando en el mismo como hasta ahora. No voy a callarme mi muy
personalísima, y por supuesto muy discutible, opinión acerca de Java, al que considero un
sistema (o entorno) que libera a quienes programan de tener que lidiar con las
características específicas de cada Sistema Operativo, pero a costa de descargar en
quienes administran el sistema, que en la mayoría de computadoras domésticas son las
propias personas usuarias, la tarea de resolver los problemas que casi toda aplicación
medianamente compleja plantea para su instalación y funcionamiento. No todo el mundo
conoce, ni tiene por qué conocer, el significado de los mensajes que lanza Java. Tampoco
me parece una buena forma de solucionarlo que Oracle haya publicado
estos consejos
para la solución
de algunos de los problemas que puede causar Java. ¿Todo el mundo
está obligado a saber lo que es un plugin o una caché? En fin, aquí
no voy a extenderme más sobre este asunto, aunque no descarto explayarme sobre el mismo
en otra ocasión.
Las entidades XML en DocBook
Cuando se decide utilizar esta tecnología para nuestros escritos no se suele caer en la
cuenta de los pequeños
detalles. Un buen día nos podemos encontrar queriendo
escribir la raya y no sabemos cómo hacerlo, o si existe siquiera la posibilidad de
usarla; o deseamos incluir los signos <
o >
, pero comprobamos que no
parece haber forma de conseguir que se vean cuando los escribimos; y así con cualquier
carácter que no figure en el teclado, pero que consideramos necesario para una correcta
composición del texto o, simplemente, porque queremos utilizarlo.
Las entidades XML
son unas expresiones, o conjuntos de caracteres, que nos van a
permitir hacer visible cualquier cosa escribible, desde un único carácter, como el caso
de los signos <
, >
o &
, hasta un montón de texto como los
capítulos de un libro. Las entidades correspondientes a los caracteres especiales las
podemos encontrar, entre otros sitios, en
esta página de oasis-open.org, en cuyo apartado Appendixes están
clasificadas en diferentes categorías señalizadas desde la A
a la X
. Por
ejemplo, vamos a buscar la raya: hagamos clic en el apéndice A. Added Latin 1, y
bajemos pacientemente, busca buscando, hasta encontrar dos posibilidades: la que tiene
como nombre horbar y código Unicode
2015, y la denominada mdash con código 2014. La correcta, en
nuestra desinteresada opinión, es la del código 2014 (mdash), porque la otra
parece ser el carácter a utilizar para componer una línea continua horizontal. Podríamos
escribirla (hacerla visible) de dos formas: utilizando el nombre o el código. Con el
nombre sería —
y con el código —
.
Vemos que en ambos casos se trata de lo mismo: anteponer el carácter &
(et) y finalizar con el punto y coma.
(Lo de #x0 lo veremos pronto).
Si estás de acuerdo en que es buena idea anotar en algun sitio las entidades de los
caracteres especiales que vayamos necesitando, para volver a encontrarlas rápidamente
cuando nos vuelvan a hacer falta, has de saber que la versión 5 de DocBook te da la
razón, dado que ha previsto la incorporación de un archivo de entidades como elemento
accesible desde el documento escrito. Yo lo llamo simplemente entidades.xml
, pero
puedes llamarlo como más te guste y mejor te acomode. En versiones anteriores las
entidades ya estaban incorporadas por defecto, pero esta forma me agrada más porque
carga solamente lo necesario en lugar de la colección disponible al completo. Ejemplo
de un archivo de entidades:
entidades.xml
<!ENTITY nbsp " "> <!-- Espacio irrompible normal -->
<!ENTITY nbsp0 ""> <!-- Espacio irrompible de ancho cero -->
<!ENTITY nbhy "-"> <!-- Guion más espacio irrompible de ancho cero -->
<!ENTITY mdash "—"> <!-- Raya -->
Con esto haremos visible la entidad (el carácter denotado por ella) mediante su nombre y
es declarada mediante el código. Cuando escribamos, por ejemplo, —
obtendremos la raya, identificada por el número hexadecimal 2014. El signo #,
la x y el cero de la izquierda denotan formato hexadecimal, lo que no tiene que
importarnos para nada siempre y cuando lo escribamos de esta forma en el archivo de
entidades: anteponiendo � al código Unicode, finalizando con el punto y
coma, y todo ello encerrado entre comillas.
Las dos primeras entidades del ejemplo nos pueden resultar especialmente útiles. Son
nbsp (non-break space y sí, es la misma que vimos antes) y la que hemos
llamado nbsp0 (de non-break space más 0). La primera es un
espacio irrompible, porque como en HTML no se puede controlar la longitud de la línea,
podríamos encontrarnos con que al escribir una cantidad separando los millares con el
espacio (como se recomienda) la misma se rompa
al coincidir con el final de línea.
Escribiendo esta entidad en lugar del espacio normal nos aseguramos de que las cifras de
una cantidad (o los caracteres de cualquier otra expresión) permanezcan inseparables
aunque estén entre espacios. La segunda es útil cuando queremos utilizar un guion, por
ejemplo, pero sin que pueda servir como separador al final de la línea, como en
super-algo o en teórico-práctico. Se trata de añadir a continuación del
guion normal el carácter feff (en hexadecimal), llamado en Unicode
zero width no-break space
(espacio sin rotura de ancho cero), el cual actúa como pegamento
. He hecho la
composición de la tercera línea por considerarla bastante común y para ilustrar las
posibilidades de las entidades, pero el espacio sin rotura de ancho cero lo podemos
utilizar con cualquier carácter, no tiene por qué acompañar necesariamente al guion.
Para poder utilizar nuestro archivo de entidades tenemos que incluirlo en el escrito DocBook así:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book [
<!ENTITY % ent SYSTEM "entidades.xml">
%ent;
]>
<book>
</book>
Vemos que, en lugar de cerrar la declaración del tipo de documento (!DOCTYPE book)
con el corchete angular derecho, escribimos un corchete normal izquierdo y en la línea
siguiente, entre corchetes angulares, declaramos un tipo entidad (!ENTITY) al que
hemos llamado internamente % ent
(el espacio es necesario), y que en nuestro
sistema (SYSTEM) se encuentra en el archivo entidades.xml
, el cual podría
estar en otra carpeta, por ejemplo: SYSTEM "otra/carpeta/entidades.xml".
En la siguiente línea repetimos el nombre interno (%ent;) sin espacio esta vez
y terminado en punto y coma, concluyendo con los correspondientes corchetes de cierre
(los derechos), tanto normal como angular.
Una vez correctamente incluido nuestro archivo de entidades, para hacer visible cualquier
carácter cuya entidad haya sido declarada en el mismo, solo tendremos que escribir
el nombre de la entidad precedido por &
y acabado en ;
.
Tomando como ejemplo la raya, escribiendo —
obtenemos —
,
a diferencia del guion -
. Ahora bien, si tu sistema operativo y tu editor de
texto te permiten obtener cualquier carácter con una determinada combinación de pulsaciones
de teclas —como Emacs—,
y tienes medios de saber cuales son esas teclas y como combinarlas para cada carácter que
necesites, puedes olvidarte de la mayoría de este tipo de entidades XML. Solo necesitarás
utilizar aquéllas cuyos caracteres no sean visibles al escribirlos directamente, como por
ejemplo los signos &, <, > y pocos más.
Escribiendo en DocBook
Hasta aquí hemos hecho una especie de introducción a la tecnología DocBook, tratando de explicar la manera en que la misma hace uso de otra tecnología más genérica denominada XML. Resumiendo: DocBook utiliza el metalenguaje XML para crear su propio lenguaje de marcas, con el que podemos conseguir múltiples formatos a partir de un único texto escrito siguiendo sus directrices, las cuales consisten en atenerse a las reglas del lenguage XML utilizando las marcas definidas por DocBook.
Veamos un ejemplo esquemático de un libro compuesto por varios capítulos (en este caso solo dos para abreviar), con cada capítulo escrito en un archivo diferente.
Documento para el capítulo numero uno: Capitulo1.xml
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"><title>Capítulo I</title>
<para>
En un lugar de la Mancha, de cuyo nombre no quiero acordarme, no ha mucho
tiempo que vivía un hidalgo de los de lanza en astillero, adarga antigua,
rocín flaco y galgo corredor.
</para>
</chapter>
Documento para el capítulo numero dos: Capitulo2.xml
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0">
<title>
Capítulo II
</title>
<para>
Hechas, pues, estas prevenciones, no quiso aguardar más tiempo a poner en
efecto su pensamiento, apretándole a ello la falta que él pensaba que hacía
en el mundo su tardanza, según eran los agravios que pensaba deshacer,
tuertos que enderezar, sinrazones que enmendar, y abusos que mejorar, y
deudas que satisfacer.
</para>
</chapter>
Archivo de entidades: entidades.xml
<!ENTITY nbsp " "> <!-- Espacio irrompible -->
<!ENTITY nbhy "-"> <!-- Guion más espacio inseparable -->
<!ENTITY mdash "—"> <!-- Raya -->
<!ENTITY cap1 SYSTEM "Capitulo1.xml">
<!ENTITY cap2 SYSTEM "Capitulo2.xml">
Documento para componer el libro completo: ejemplo.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book [
<!ENTITY % ent SYSTEM "entidades.xml">
%ent;
]>
<book version="5.0" xml:lang="es"
xmlns="http://docbook.org/ns/docbook"
xmlns:xl="http://www.w3.org/1999/xlink">
<info>
<title>EL INGENIOSO HIDALGO DON QUIJOTE DE LA MANCHA</title>
<author>
<personname>Miguel de Cervantes Saavedra</personname>
</author>
<pubdate>1605</pubdate>
</info>
&cap1; <!-- El capítulo uno se insertará en este punto -->
&cap2; <!-- El capítulo dos se insertará en este punto -->
</book>
Dividir un libro en capítulos es algo bastante común, por lo que si éstos tienen una extensión más bien larga puede resultar conveniente, y hasta diría que necesario en algunos casos, escribir cada capítulo por separado. Pero no vayas a pensar que en DocBook es obligatorio hacerlo así. Puedes escribir todo en el mismo documento, el libro final, y situar las marcas de capítulos (chapter) y/o partes (part) en ese mismo archivo sin ningún tipo de problema.
Seguro que habrás observado —y si no ya te lo digo yo—, que en cada documento la marca title y su contenido se muestran de manera diferente. En el capítulo uno se sitúa directamente a continuación de chapter, en la misma línea. En el dos las etiquetas están en líneas distintas a la del contenido, y en el libro final tanto las etiquetas como el contenido están en su propia y misma línea. El motivo de esto es un intento por mi parte de despejar cualquier duda de principiante respecto a dónde han de colocarse las etiquetas XML que van a formar parte de nuestro escrito: las etiquetas XML pueden ir exactamente donde nos dé la gana, siempre que cumplan con las reglas de apertura y cierre que explicamos antes. Podemos situarlas donde mejor nos convenga para reconocerlas más fácilmente y guardar un cierto orden, aunque una práctica común, y digna de ser recomendada, es utilizar línea aparte en las marcas que tengan contenido superior a una línea, o que han de contener otras marcas (como en el ejemplo de los atributos para imágenes), situándolas en la misma línea que el contenido si éste es lo suficientemente breve.
Hecho el inciso de los dos párrafos anteriores, vamos a tratar de elaborar una explicación, que esperamos sea comprensible, de los tres documentos utilizados en nuestro primer ejemplo de un escrito con DocBook, aunque en realidad sean cuatro, porque en el archivo de las entidades hay que añadir las concernientes a los capítulos.
Insistimos en remachar, por si quedase alguna duda, que en un documento XML (y DocBook lo es) todo tiene que estar marcado, por consiguiente cualquier cosa que escribamos estará comprendida entre una etiqueta de apertura y su correspondiente etiqueta de cierre a no ser, claro está, que se trate de una marca vacía, en cuyo caso podemos ahorrarnos la escritura de la etiqueta de cierre colocando la barra al final de la de apertura (<marca/>).
En todo documento XML debe aparecer en primer lugar la línea del siguiente ejemplo
escrita tal cual
. Voy a insistirte en que esta primera línea es obligatorio
que la escribas así, tú me haces caso y seguimos adelante.
Documento DocBook: ejemplo.xml
<?xml version="1.0"?>
Como en la informática no es extraño encontrarse complicaciones con toda lengua que no sea inglés, un servidor, a fuerza de llevarse palos, ha implementado la costumbre de especificar todo aquello que tenga que ver con el idioma. La codificación de caracteres no es estrictamente necesario añadirla, pero como la añado, y se trata de explicar cómo hago las cosas, pues ahí queda. Aunque sea por si acaso.
Documento DocBook: ejemplo.xml
<?xml version="1.0" encoding="UTF-8"?>
La codificación UTF-8 es de las más usadas, por no decir la que más, ya que con ella es posible representar prácticamente todos los caracteres de todas las lenguas humanas. Si tienes curiosidad, puedes consultar sobre otras codificaciones.
En la siguiente línea se declara el tipo de documento: book en este caso. También se puede utilizar article si lo que vamos escribir es un artículo, pero article no admite chapter. Más adelante explicaremos como averiguar qué marcas contienen a, o son contenidas por, otras marcas. Las entidades no son obligatorias, solo se incluyen si se necesitan.
Documento DocBook: ejemplo.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book>
Ahora toca añadir la primera marca DocBook propiamente dicha, ya que las dos anteriores
entran en una categoría especial de elementos XML sin etiqueta de cierre, como las
declaraciones y entidades (con signo de exclamación), y los que van entre signos de
interrogación (<? ... ?>). Estos últimos son considerados
instrucciones de procesamiento,
en lugar de limitarse a tomar nota
del contenido y su estructura, que es lo que
hacen los elementos normales.
A la primera marca o elemento se le denomina raíz. Dentro de ella debe estar todo el contenido del documento, incluidas las demás marcas. Este nombre es debido a que los programas analizadores de XML construyen un árbol para manipular los elementos de todo el documento, constituyendo la primera marca la raíz de dicho árbol. Análogamente al tipo de documento, para un libro la marca raíz será book y para un artículo, article.
Escribimos, pues, las dos etiquetas de la marca raíz —para asegurarnos de que no se olvida la de cierre— cada una en su propia línea. Por cierto: lo de escribir las dos etiquetas antes que el contenido que encierran es otra cosa que podríamos marcar como recomendable. Añadiremos también el archivo con las entidades, ya que su uso es bastante frecuente, teniendo en cuenta que hay que incluir como parte del nombre la ruta a la carpeta donde esté situado. En este caso entidades.xml se encuentra en la misma carpeta que el documento ejemplo.xml.
Documento DocBook: ejemplo.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book [
<!ENTITY % ent SYSTEM "entidades.xml">
%ent;
]>
<book version="5.0" xml:lang="es"
xmlns="http://docbook.org/ns/docbook"
xmlns:xl="http://www.w3.org/1999/xlink">
</book>
Los dos primeros atributos de la marca raíz, versión e idioma, no son estrictamente necesarios, pero los considero convenientes; el siguiente, xmlns, es prácticamente obligatorio, ya que de no incluirlo podríamos obtener errores con algunos programas de los utilizados para la obtención de los distintos formatos, y el último, xmlns:xl, sirve para poder utilizar enlaces, ya sea a otro lugar del propio documento o a cualquier sitio de internet. El atributo de idioma (xml:lang) junto con la codificación UTF-8, nos dará la tranquilidad de escribir en la lengua elegida sin que aparezcan problemas con los caracteres especiales que dicha lengua pueda contener, como podrían ser, tomando al español como ejemplo, la eñe, acentos, diéresis y algunos otros, además de conseguir que los nombres de los días y de los meses aparezcan en el idioma elegido en lugar del inglés, ya que se puede incrustar automáticamente la fecha en la que el documento es procesado. Este atributo parece interesante para la realización de traducciones, ya que también está contenido en la marca para, lo que permite escribir documentos multilingües respetando las pautas de accesibilidad. El valor "es" referencia al español genérico (o de España), pero se puede indicar una variante concreta añadiendo un guion más el código de país, por ejemplo: "es-MX" para el español de México o "es-AR" para el de la Argentina. Enlace a los códigos de idioma, enlace a los códigos de país.
Los dos puntos en un nombre de marca o atributo, por ejemplo xml:lang, significan que el nombre lang (a la derecha) pertenece al espacio de nombres xml (a la izquierda). El uso de espacios de nombres permite un nombre único para elementos y atributos. Si quisiéramos definir un nuevo esquema de documento que contemple la posibilidad de especificar el idioma, bastaría con añadirle su propio espacio de nombres, por ejemplo midoc (midoc:lang), para conservar el significado del término lang (lengua o idioma) y no interferir con el atributo del mismo nombre especificado en el espacio xml (xml:lang), pudiendo ser usados ambos en el mismo documento cada uno en su contexto. Hay que indicar el URI del espacio de nombres como atributo de la marca (preferiblemente de más alto nivel) en cuyo contenido va a ser utilizado el prefijo. Por ejemplo: xmlns:xl="http://www.w3.org/1999/xlink" significa que "xl" es el prefijo a usar para incluir enlaces a otros sitios, ya sean partes del documento o incluso páginas web, y que en www.w3.org/1999/xlink es donde está definido ese espacio de nombres. Lo de xmlns vendría a significar: XMLNameSpace (espacio de nombres xml).
<chapter xmlns:xl="http://www.w3.org/1999/xlink">
<para>
... texto ...
<link xl:href="https://google.es">Google</link>
... texto ...
</para>
</chapter>
Esto hará que en el escrito aparezca un enlace de hipertexto (marca <link>
con su atributo xl:href) y que pinchando
en el mismo vayamos a la página
de ese buscador.
En nuestro documento solo podremos incluir las marcas que DocBook tenga definidas como
hijas
(en inglés children) de la marca raíz. Esto lo podemos saber
consultando el manual. Bajamos
por la página hasta encontrar, por ejemplo, book, le damos clic para ver
sus características, volviendo a
bajar hasta llegar a children, y veremos todos los elementos que pueden ser
incluidos dentro de book. Entre ellos está chapter, por lo que si le
damos clic accederemos a las especificaciones del mismo.
Obviamente, parents (padres) muestra todos los elementos en los que la marca
consultada puede ser incluida. La marca book solo puede ser anidada en
set, que sería una obra con
varios tomos, mientras que la marca chapter puede ir dentro de book y de part,
pero no de article
(puesto que no aparece). Esto se indica de la misma forma para todas las marcas, no
existiendo más límite de anidamiento que el impuesto por el esquema de DocBook.
Imágenes en DocBook
Hay varias formas de incluir imágenes dentro de un documento DocBook, es cuestión de
elegir la que mejor se adapte a nuestras necesidades. Veamos un ejemplo, al que
consideraremos como típico
, usando la marca
figure:
<figure xml:id="Imagen prueba"><title>Prueba de imagen</title>
<mediaobject>
<imageobject>
<imagedata align="center" scale="100" fileref="imagenes/prueba.png"/>
</imageobject>
<textobject>
<phrase>Texto para el caso de que la imagen no pueda ser visualizada.</phrase>
</textobject>
<caption>
<para>
Explicación o comentario, visible en el documento, sobre la imagen.
</para>
</caption>
</mediaobject>
</figure>
Si se considera conveniente, la marca figure puede ser incluida dentro de un párrafo (elemento para).
El atributo xml:id="Imagen prueba" sirve para dotar a la imagen de una identificación única, de manera que pueda ser referenciada desde otras partes del documento. Por ejemplo:
<para>
... bla, bla... ver imagen: <xref linkend="Imagen prueba"/>
</para>
y en el documento final aparecerá: ... bla, bla... ver imagen: Figura 1,
. Si posteriormente añadimos otra imagen en un lugar anterior al que
ocupa esta, al procesar de nuevo el documento aparecerá: Prueba
de imagen
... bla, bla... ver imagen:
Figura 2,
, porque ahora la figura 1 será la que hemos
añadido. Si cambiamos el título de la imagen el cambio se aplicará a todas sus
referencias, pero si modificamos el valor del atributo xml:id, el elemento no podrá
ser localizado y seguramente obtendremos errores al procesar el escrito, a no ser que
sean modificadas de la misma forma todas las referencias a la imagen. Este atributo de
identificación no sólo es utilizable con figure, también está disponible en muchas
otras marcas.
Prueba de imagen
Continuando con la marca imagedata, que debe pertenecer a imageobject, la cual a su vez es parte de mediaobject, vemos que tiene tres atributos y contenido nulo. El primero, fileref="imagenes/prueba.png", sirve para indicar dónde se encuentra el archivo de imagen en nuestro sistema y cual es su nombre. Con el segundo, align="center" centramos la imagen horizontalmente, y con el tercero, scale="100", conseguimos que el tamaño de la imagen sea el cien por cien del original, sin ningún escalado. Si hubiese sido, por ejemplo, scale="90", la imagen ocuparía el noventa por ciento del area de visualización, que a a efectos prácticos es el ancho de página; el alto sería calculado automáticamente para mantener las proporciones. La marca phrase, que debe ser incluida dentro de textobject, se utiliza para que los dispositivos de lectura dispongan de un modo de hacerle saber al usuario lo que hay en ese lugar, en caso de no poder mostrar la imagen o de utilización de algún lector de pantalla para personas con discapacidad visual. Para los navegadores web (formato HTML) genera el atributo alt del elemento img.
Si en lugar del atributo scale usáramos width (ancho), el valor tendría que especificar las unidades de medida, por ejemplo width="120px", que sería 120 píxeles de ancho. Como siempre, el alto se calculará automáticamente para mantener las proporciones y que la imagen no aparezca distorsionada.
No es obligatorio utilizar todas las marcas del ejemplo, se pueden eliminar las que se consideren superfluas (por ejemplo caption) y también añadir algunas más. Mostrar todas las posibilidades puede ser tedioso además de prolijo, así que sugerimos consultar la documentación, probar las variaciones que puedan parecernos atractivas, y decidir lo que consideremos más adecuado para cada una de las imágenes que vayan a formar parte de nuestra obra.
Existe también la marca informalfigure,
que difiere de figure en que no muestra el título y alguna que otra cosa. Hay
unas cuantas marcas que incluyen las denominaciones nombre
e informalnombre
. La
denominada informalnombre
suele mostrar menos detalles que la otra.
El problema de distribuir texto alrededor de una imagen, que representaremos esquemáticamente así:
xxx xxxxxxx xxx xx xxxxxxxxx xx xxxxx xxx xx xxxxx
xxxxx x xxx xxxxx xxx xxxxxx xxx xxxxxxx x xxxxx
xxxx xxx xxx xxx xxx xxxx +−−−−−−−−−−−−−−−−−−−−+
xx xxxxxxx xxxxxxx xxx xxx | |
xxxxxx xxxxxx xxxx xxxxxx | |
xxxxxxxx xxxxxxxxxxx xxx | Imagen |
xxxxxxxx xxxx xx x xxxx xx | |
xxxxx xxxx xx x xxxx xxx | |
xx xxxxxxxxxx xxx xxxx xxx +−−−−−−−−−−−−−−−−−−−−+
xxxxx xxxxxxxx xxxxxxxxxxx xxxxxxxxxx xx xxx xx
xx xxxxxxx xxxxxxxxxxx xxxxxxxxx xx xxxx xxxx
xxxxx xxxxxxxxxx xxxxxx xxxxxxxx xxxxxxx xx x xxxx
es bastante difícil de resolver. Personalmente no lo he intentado; me limito a incluir la imagen en su contexto sin más. Puedo dimensionarla a un tamaño acorde con la anchura del texto (caja tipográfica) en PDF, aplicando los ajustes necesarios mediante el atributo role del elemento imageobject cuyo uso veremos más adelante. El programa fop parece ser que aporta alguna forma de conseguirlo, pero es específico para PDF y requiere incluir las imágenes en otro archivo además del original DocBook. Así pues, como la perspectiva no me parece demasiado halagüeña, prefiero evitar este tipo de complicaciones.
El elemento inlinemediaobject, que no pertenece a figure pero sí a para, puede ser usado para ubicar una imagen en la misma línea. Naturalmente, la altura de la imagen debe ser adecuada a la de una línea de texto. Lo veremos con más detalle en el siguiente apartado dedicado a las fórmulas matemáticas.
Matemáticas en DocBook
Desafortunadamente, DocBook no cuenta con elementos propios para escribir expresiones matemáticas, pero con las herramientas adecuadas, un poco de habilidad y algo de paciencia, es posible incluir cualquier fórmula en nuestros escritos. Ahora bien, si tu obra va a tratar específicamente de matemáticas, física, química, ingeniería, arquitectura o cualquier otra rama científica o tecnológica altamente dependiente de fórmulas, es muy recomendable que le des un vistazo a LATEX, si es que todavía no lo conoces.
Empezaremos enlazando el capítulo 22 del libro DocBook XSL: The Complete Guide, donde se explican diversos métodos para incluir fórmulas matemáticas que resumiendo son: texto llano, imágenes y usando MathML. Por ejemplo, la fórmula de la ecuación de segundo grado, que en texto llano podría escribirse así: x=(−b±√(b2−4ac))/2a, en MatML sería:
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mrow>
<mi>x</mi>
<mo>=</mo>
<mfrac>
<mrow>
<mo>−</mo> <!-- Signo menos -->
<mi>b</mi>
<mo>±</mo> <!-- Signo másmenos -->
<msqrt>
<msup><mi>b</mi><mn>2</mn></msup>
<mo>−</mo> <!-- Signo menos -->
<mn>4</mn>
<mo>⁢</mo> <!-- Signo de multiplicar invisible -->
<mi>a</mi>
<mo>⁢</mo> <!-- Signo de multiplicar invisible -->
<mi>c</mi>
</msqrt>
</mrow>
<mrow>
<mn>2</mn>
<mo>⁢</mo> <!-- Signo de multiplicar invisible -->
<mi>a</mi>
</mrow>
</mfrac>
</mrow>
</math>
Como bien dice la página de Wikipedia antes enlazada, esto no está hecho para ser usado
por las personas. Aunque tratándose de pequeñas fórmulas sería posible escribirlas
directamente, es aconsejable la utilización de algún programa que las genere, como por
ejemplo LibreOffice Math.
El manual de DocBook indica que hay que utilizar el espacio de nombres
mml en cada marca
MathML, pero he podido comprobar personalmente que en la versión 5.0 de DocBook no es
necesario (ni me ha funcionado). El código utilizado en el ejemplo anterior no debería
dar errores. Pero claro, no iba a ser todo tan fácil, ya que las fórmulas han de verse en
el navegador web y algunos navegadores no parecen estar por la labor. Mis pruebas solo
han funcionado bien en el navegador Firefox de Mozilla (que utiliza el motor
Gecko), únicamente durante un
tiempo, porque a partir de una actualización los espacios verticales entre el numerador y
la raya de las fracciones, y dentro de los signos radicales, se agrandaron sobremanera.
Comprobé que era posible volver a ajustarlos, pero no estoy dispuesto a corregir
detallitos con cada actualización del navegador. Google Chrome (de Microsoft IE
mejor ni hablar) no visualiza MathML directamente, sino que se hace necesario utilizar
otras herramientas, como por ejemplo MathJax.
El inconveniente de esto (dejando aparte mi manía de no incluir enlaces de terceras
partes), es la obligación de añadir algún código —normalmente Javascript— a la página, lo
cual no es posible hacer directamente desde DocBook. Así que un servidor, para mostrar
las expresiones matemáticas de la manera en que se acostumbra a escribirlas, ha optado
por las imágenes, que funcionan en cualquier formato donde puedan verse (HTML, PDF,
EPUB…) y en cualquier navegador medianamente decente. Pero no un formato de imágenes
cualquiera, sino SVG,
que permite escalarlas sin pérdida de calidad. Empecé utilizando una extensión que tenía
el programa Inkscape para escribir fórmulas
matemáticas con TeXmacs, pero TeXmacs se ha ido quedando obsoleto, así que ahora genero
las fórmulas directamente con LaTeX, las importo con
Inkscape y desde ahí las guardo como SVG y las exporto al formato PNG.
LaTeX crea un PDF de una página por fórmula, pero como esto no quedaría muy bien en un escrito, las exporto a PNG con el tamaño que me ha parecido adecuado, tomando como referencia 40 píxeles de alto para una ecuación básica tipo A+B=C. A partir de aquí calculo la altura aproximada para las demás, haciendo que el ancho se adapte automáticamente. El formato SVG lo guardo duplicando el tamaño que toma por defecto.
Ejemplo de un archivo llamado prueba.tex con la fórmula cuadrática (la extensión .tex es necesaria):
prueba.tex
\documentclass{article}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsfonts}
\thispagestyle{empty}
\begin{document}
\[
x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
\]
\end{document}
Las cuatro primeras líneas se encargan de definir el tipo de documento (artículo en este caso) y de cargar algunos paquetes necesarios. Las dos siguientes sirven para indicar que la página no tiene un estilo en particular y el inicio del documento. La fórmula es la línea que está entre los corchetes de apertura y cierre, cada uno en una línea para mayor claridad, y la última línea indica que ahí acaba el documento. La página en PDF se obtiene con el mandato:
~$ pdflatex prueba.tex
Esto generará tres archivos: prueba.aux, prueba.log y prueba.pdf. El único que nos interesea es prueba.pdf, por tanto eliminamos los otros dos. El archivo fuente original prueba.tex también lo podemos conservar, por si acaso. El resultado es este:
Supongo que no será necesario que te diga que el archivo prueba.tex te puede
servir como plantilla para obtener otras fórmulas con este método, pero dicho queda de
todas formas. Tampoco habrá que decirte que en Internet hay mucha información sobre cómo
usar LaTeX. También pudiera ser que no tengas instalado pdflatex, eso se nota
porque cuando intentas usarlo no funciona y significa que tampoco tienes LaTeX, cuyo
nombre de paquete linuxero
es texlive o algo parecido. Harías bien en
buscar en Internet cómo instalar LaTeX en tu Sistema Operativo, pero solo en el caso de
que quieras usarlo.
Aquí te dejo un vídeo del proceso que sigo para obtener las imágenes en mi Debian GNU/Linux, por supuesto. Este método puede servir para unas cuantas fórmulas, pero si vas a escribir una tesis doctoral sobre matemáticas más vale que te quedes con LaTeX.
Se pueden utilizar por lo menos tres marcas para incluir fórmulas matemáticas: equation, inlineequation e informalequation. Las fórmulas incluidas en el ejemplo que sigue:
<para>
Se cuenta que la ley de la gravedad, cuya ecuación es:
<equation xml:id="eq-gravedad">
<title>Gravitación universal</title>
<alt>F = G × ((m1 × m2) / r²)</alt>
<inlinemediaobject>
<imageobject>
<imagedata format="svg" scale="20" fileref="mates/eq-gravedad.svg"/>
</imageobject>
<textobject><phrase> F = G × ((m1 × m2) / r²) </phrase></textobject>
</inlinemediaobject>
</equation>
fue descubierta por Isaac Newton después de observar la caída de una manzana.
</para>
<para>
La fórmula:
<informalequation>
<alt>x = (−b ± √(b² − 4ac)) / 2a</alt>
<inlinemediaobject>
<imageobject>
<imagedata format="svg" scale="32" fileref="mates/eq-cuadratica.svg"/>
</imageobject>
<textobject><phrase> x = (−b ± √(b² − 4ac)) / 2a </phrase></textobject>
</inlinemediaobject>
</informalequation>
resuelve la ecuación de segundo grado ax² + bx + c = 0.
</para>
<para>
Una de las ecuaciones más conocidas es:
<inlineequation>
<alt>e=mc²</alt>
<inlinemediaobject>
<imageobject>
<imagedata format="svg" scale="10" fileref="mates/eq-emc2.svg"/>
</imageobject>
<textobject><phrase> e = mc² </phrase></textobject>
</inlinemediaobject>
</inlineequation>
que indica la equivalencia entre masa y energía en la teoría de la relatividad
de Albert Einstein.
</para>
se verían más o menos así:
En la fórmula de la gravitación universal se han utilizado el atributo xml:id, que nos permite referenciarla desde otros puntos del escrito, y el título. La ecuación cuadrática se presenta con la forma menos elaborada informalequation, y la de Einstein se muestra en la misma línea porque así lo permite su altura. Aunque, por supuesto, el resultado final dependerá de nuestras preferencias, ya que es posible utilizar inlineequation de la misma forma y produciendo los mismos resultados que informalequation.
El formato de imágenes SVG requiere ajustar su dimensión, cosa que hago mediante el atributo scale; entre uno y cien, a mayor número le corresponde mayor tamaño; se podrían usar otros atributos, como widht o depth por ejemplo. No tengo un modo de conseguir que el tamaño de los elementos de todas las fórmulas de un escrito sea exactamente el mismo, lo hago a ojo de buen cubero y, si no me queda bien, lo reajusto y arreando. Ciertamente podría entretenerme en hacer cálculos, como establecer una proporción entre los píxeles ideales de ancho para un determinado alto o algo así. Tal vez algún día lo haga.
Obteniendo los formatos elegidos
De los muchos formatos disponibles a partir de un escrito elaborado utilizando el lenguaje DocBook, hemos escogido los que nos han parecido más adecuados para publicar nuestros escritos:
- EPUB
- Formato general para libro electrónico.
- HTML
- Para lectura como página web.
- Para impresión en papel.
Es posible utilizar el software Calibre para retocar el resultado final del EPUB, así como para generar un nuevo PDF si no nos gusta el aspecto del obtenido con DocBook o para conseguir algún otro formato. Lo único que hay que hacer es abrir con Calibre el formato EPUB, modificar al gusto y volver a grabar en el formato elegido, ya sea PDF, EPUB, MOBI o cualquiera de los muchos disponibles. El HTML no se puede modificar con Calibre, hay que tenerlo preparado en el momento de procesar el escrito original.
Para lo que sigue es necesario hacer uso de la
consola de Linux,
a veces también llamada terminal de texto
o simplemente terminal
. Es normal
que si te falta experiencia puedas torcer el gesto ante semejante perspectiva, pero con
las indicaciones adecuadas y un poco de buena voluntad por tu parte, ya verás como todo
va a salir bien
. Trust me.
Formato EPUB (libro electrónico)
Para conseguir el formato EPUB utilizaremos el programa a2x, el cual forma parte del paquete asciidoc, que es el que tenemos que instalar para tenerlo disponible. Una vez instalado pasamos a obtener el formato EPUB con la siguiente orden:
~$ a2x -f epub ejemplo.xml
El parámetro -f epub indica que el formato deseado es EPUB, el cual será obtenido
a partir nuestro documento DocBook llamado ejemplo.xml
. Para conseguir algo un
poco más elaborado habría que añadirle algunos parámetros más a la instrucción básica que
acabamos de ver. Sería conveniente elegir expresamente que deseamos un libro con el
parámetro -d book. También podríamos añadir nuestra personalización a la
plantilla XSL predeterminada y/o algo de CSS para afinar un poco la presentación. La
plantilla XSL se añade con el parámetro --xsl-file seguido del nombre del
archivo XSL y el estilo CSS con --stylesheet seguido igualmente del nombre del
archivo CSS:
~$ a2x -d book -f epub --xsl-file config/epub.xsl \
-> --stylesheet config/epub.css ejemplo.xml
La barra inclinada inversa \
significa que la instrucción continúa en la línea
siguiente (la consola de Linux es poderosa).
Si, como yo, no estás de acuerdo con que DocBook escriba siempre la palabra Capítulo
(o Sección
o lo que sea) seguida del número, puedes desactivar este comportamiento
modificando (o hackeando) como administrador (root en la jerga) el archivo
docbook.xsl, que en en Arch Linux se encuentra en:
/usr/share/xml/docbook/xsl-stylesheets-1.79.2/epub/docbook.xsl
y en Debian:
/usr/share/xml/docbook/stylesheet/docbook-xsl/epub/docbook.xsl
añadiéndole las 3 líneas siguientes después de las marcas import e include:
<xsl:param name="chapter.autolabel">0</xsl:param> <!-- Sin "Capítulo X" -->
<xsl:param name="appendix.autolabel">0</xsl:param> <!-- Sin "Apéndice X" -->
<xsl:param name="section.autolabel">0</xsl:param> <!-- Sin "Sección X" -->
Por lo que respecta a la localización de la plantilla (sistema Arch) /usr/share/xml/docbook/xsl-stylesheets-1.79.2/epub/docbook.xsl, habremos de buscarla utilizando, por ejemplo, la orden:
~$ find /usr -name docbook.xsl -print
La clave está en descubrir la carpeta que nos interesa, que en este caso sería (sistema Debian) .../docbook/stylesheet/docbook-xsl/epub/docbook.xsl, entre las muchas líneas que seguramente producirá la salida de la orden anterior, e incorporar la línea completa, obviamente, a los parámetros de a2x como hemos visto en el ejemplo.
Aunque para nada es aconsejable andar toqueteando los archivos que el sistema instala
(yo lo he hecho, pero: no lo hagáis en casa
), porque si nos entrara una
actualización, esos archivos serán sobrescritos por los nuevos y perderemos nuestras
modificaciones, sin descartar la posibilidad de cometer un error y estropear el
funcionamiento de los programas que dependan de ellos. Por lo tanto, lo más
recomendable es crear nuestro propio archivo XSL con las modificaciones que
deseemos, y será este archivo el que pasaremos a los parámetros de a2x,
como hemos avanzado en los ejemplos. Lo situaremos dentro de la carpeta config
y lo llamaremos epub.xsl porque nos parece coherente, pero puedes ponerlo donde
te dé la gana y llamarlo loquesea.xsl tranquilamente.
config/epub.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:import href="/usr/share/xml/docbook/stylesheet/docbook-xsl/epub/docbook.xsl">
<xsl:param name="chapter.autolabel">0</xsl:param> <!-- Sin "Capítulo X" -->
<xsl:param name="appendix.autolabel">0</xsl:param> <!-- Sin "Apéndice X" -->
<xsl:param name="section.autolabel">0</xsl:param> <!-- Sin "Sección X" -->
</xsl:stylesheet>
Después del encabezado que todo archivo XML debe llevar (el lenguaje XSL también está construido con XML), añadimos la marca raíz xsl:stylesheet con sus dos atributos tal y como aparece en el ejemplo. Naturalmente, el valor del atributo href del elemento, o marca, xsl:import es la ruta y el nombre del archivo predeterminado XSL, que hemos buscado y hallado en nuestro actual sistema Debian testing. Hay que incluirlo (o importarlo) aquí porque al indicar una hoja de estilo personalizada, se anula la predeterminada y es necesario contar con ella para que todo funcione. Incorporamos las tres líneas para el formato del título de capítulos, apéndices y secciones, y ya podemos tener la tranquilidad de que no provocaremos errores a nivel del sistema, ni tampoco perderemos nuestra personalización cuando se actualice DocBook.
Un documento EPUB es básicamente HTML con algunos otros archivos añadidos, todo ello comprimido en formato ZIP. Si no me crees, renombra cualquier archivo .epub como .zip, descomprímelo y podrás ver de qué está hecho. La hoja de estilo CSS que le suelo incorporar viene a ser más o menos como la que sigue:
config/epub.css
body {
font-size: 14pt; /* Tamaño de letra 14 puntos. */
text-align: left; /* Texto alineado a la izquierda. */
}
a {
text-decoration: none; /* Enlaces sin subrayado por defecto. */
}
a:hover {
text-decoration: underline; /* Enlaces se subrayan al "señalarlos". */
}
p {
text-align: justify; /* Texto justificado. */
}
span.underline {
text-decoration: underline; /* Para texto subrayado */
}
span.strikethrough {
text-decoration: line-through; /* Para texto tachado */
}
Las unidades de medida son: puntos de imprenta (pt) para el tamaño de letra, y el espacio
que ocupa la letra M
(em). Esto está definido así en CSS, solo se puede escoger el
espacio de la letra M
mayúscula o el de la x
minúscula, no cualquier otro.
Aunque también podemos utilizar píxeles, porcentajes, milímetros... Si quieres saber más
puedes consultar algún manual sobre
unidades de medida en CSS
de los muchos que hay en la Web.
Las clases CSS .underline y .strikethrough, dentro del elemento HTML span, se aplicarán cuando en DocBook las incluyamos como valor del atributo role de la marca emphasis:
<emphasis role="underline">esto está subrayado</emphasis>
<emphasis role="strikethrough">esto está tachado</emphasis>
Lo cual veremos así: esto está subrayado, esto está tachado. La
negrita se aplica directamente con el valor de role=bold
, y la cursiva es
el resultado predeterminado de la marca emphasis sin atributos.
Formato HTML (página web)
El formato HTML lo consigo utilizando xmlto de la siguiente manera:
~$ xmlto -m config/html.xsl --skip-validation -o ejemplo_html/ html ejemplo.xml
Tendrás que instalar el programa xmlto en el caso de que tu sistema no lo haya hecho. Con -m config/html.xsl consigo que se apliquen las modificaciones incluidas en el archivo html.xsl (fragmento XSL) que está en la carpeta config. Con --skip-validation omito el paso de validación para evitar los errores que se producirían al intentar validar el documento original contra un esquema que no se proporciona. La validación no será necesaria si cuidamos de que nuestros originales sean documentos XML bien formados y cumplan con DocBook. Si queremos proporcionar una hoja de estilo completa, podemos hacerlo mediante el uso de -x hoja_de_estilo.xsl y omitiendo tanto el parámetro -m como --skip-validation, pero hasta el momento de escribir esto no me ha sido necesario para conseguir un HTML decente. Con -o ejemplo_html/ envío la salida a una carpeta (de ahí la barra final, aunque no es estrictamente necesaria) llamada ejemplo_html. Con html indico el formato en el que quiero la salida, ya que es posible obtener otros formatos como hemos podido ver en el manual enlazado. Por último encontramos el nombre del archivo a ser procesado: el original escrito en DocBook ejemplo.xml.
Pero eso no es todo, todavía falta copiar los archivos necesarios para darle forma, o estilo, a la visualización del libro y aportar las imágenes que hayamos incluido en el original DocBook. Copiamos el archivo config/html.css a la carpeta ejemplo_html con el nombre que le daremos en el archivo XSL (estilo.css), y toda la carpeta imgs sin cambios de nombres:
~$ cp -rf config/html.css ejemplo_html/estilo.css
~$ cp -rf imgs ejemplo_html/
En el argot de las órdenes (mal llamadas comandos según mi opinión) en una consola
de Linux, cp -rf viene a significar: copiar todo, incluido carpetas con
su contenido al completo, y crear las carpetas si es necesario en el destino de la copia
.
A continuación va lo que se quiere copiar, un espacio, y el destino de la copia.
Pero antes de poder copiar cualquier cosa tenemos que disponer de ello, así que
empezaremos por el fragmento de estilo xsl, con el cual vamos a personalizar
nuestro libro en el formato HTML para ser leído en la web en línea
:
config/html.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- La localización del archivo depende del Sistema Operativo. En Debian: --/>
<xsl:import href="/usr/share/xml/docbook/stylesheet/docbook-xsl/html/chunk.xsl"/>
<!-- Incluye una hoja de estilo personalizado CSS en el html final. -->
<xsl:param name="html.stylesheet" select="'estilo.css'"/>
<xsl:param name="chapter.autolabel">0</xsl:param> <!-- Sin "Capítulo X" -->
<xsl:param name="appendix.autolabel">0</xsl:param> <!-- Sin "Apéndice X" -->
<xsl:param name="section.autolabel">0</xsl:param> <!-- Sin "Sección X" -->
<!-- Se elimina la línea superior del pie de página (valor = cero) -->
<xsl:param name="footer.rule">0</xsl:param>
<!-- Sustituye el texto de los enlaces de navegación por unas imágenes.
Sus nombres tienen que ser: 'next', 'prev', 'up' y 'home' (más la
extensión). La extensión de las imágenes será .png y la ruta a su
localización (path) tiene que ser a partir de donde estén los archivos
html, no este archivo. -->
<xsl:param name="navig.graphics" select="'1'"/>
<xsl:param name="navig.graphics.path" select="'imgs/'"/>
<xsl:param name="navig.graphics.extension" select="'.png'"/>
<!-- Genera índices (toc = tables of contents) para el elemto book. -->
<xsl:param name="generate.toc">
book toc,title,figure,table,example,equation
</xsl:param>
<!-- Añade atributos al elemento <html> -->
<xsl:template name="root.attributes">
<xsl:attribute name="lang">es<xsl:attribute/> <!-- Español estándar (España) -->
</xsl:template>
<!-- Ruptura arbitraria de línea (<?linebreak?>-->
<xsl:template match="processing-instruction('linebreak')">
<br/>
</xsl:template>
<!-- Suprime los enlaces de navegación en la cabecera (select="no-cero") -->
<xsl:param name="suppress.header.navigation" select="1"></xsl:param>
</xsl:stylesheet>
Los comentarios, como siempre, intentan explicar el propósito del código XSLT. Aquí
importamos
la hoja de estilo chunk.xsl (traducible como trozo.xsl)
porque es la indicada para conseguir el formato con un archivo HTML por capítulo. Al
añadir un atributo al elemento <html> en la forma que se muestra,
se consigue que en la página web generada aparezca así: <html lang="es">.
Como dijimos anteriormente, estas cosas se pueden encontrar en los manuales de DocBook.
Pondremos como ejemplo el capítulo 12,
personalizaciones HTML,
del ya mencionado manual
DocBook XSL: The Complete Guide
,
el cual volvemos a enlazar para ahorrarte desplazamientos.
A continuación veremos la hoja de estilo CSS, incluida en el archivo anterior con el nombre estilo.css, que se encarga de personalizar el aspecto que tendrá nuestra obra al ser presentada como página web. Reside en la carpeta config y se llama html.css:
config/html.css
/* Para aplicar al elemento <html>. */
html
{
position: absolute;
width: 100vw; /* Ancho total */
height: 100%; /* Alto total */
margin: 0 auto; /* Centrado, sin márgenes. */
font-size: 14pt; /* Tamaño de la letra en puntos. */
background-image: url("imgs/mesa.png"); /* Imagen de fondo. */
}
/* Para aplicar al elemento <body>. */
body
{
position: relative;
max-width: 40em; /* Ancho máximo de la zona del texto. */
height: 95%; /* Alto de la zona del texto. */
margin: 0.5em auto; /* Márgen superior, centrado horizontal. */
padding: 1em 2em 1em 2em; /* Espacio desde los bordes hacia el interior. */
cursor: default; /* La forma del puntero no cambia. */
overflow: hidden; /* Sin barra de desplazamiento. */
}
/* Estilos para los enlaces. El orden de aparición es importante. */
/* Enlace normal, aún no visitado. */
a:link
{
text-decoration: none; /* Texto del enlace sin subrayado. */
color: #0000ff; /* Texto del enlace en color azul. */
}
/* Enlace visitado. */
a:visited
{
text-decoration: none; /* Igual que el no visitado. */
}
/* Enlace al situar el puntero (ratón) encima. */
a:hover
{
text-decoration: underline; /* Texto subrayado. */
color: #0000ff; /* Color azul. */
}
/* Enlace activo (click sin soltar el botón). */
a:active
{
color: #0000ff; /* Mismo color que el enlace normal. */
}
span.underline {
text-decoration: underline; /* Para texto subrayado */
}
span.strikethrough {
text-decoration: line-through; /* Para texto tachado */
}
/* Para el texto. Se aplica a todos los elementos indicados: */
.set,
.book,
.preface,
.chapter,
.bibliography,
.appendix,
.section
{
position: relative;
height: 93.3%;
margin: 0.5em -2em -1em -2em; /* Márgenes externos. */
padding: 0.5em 2em 0.5em 2em; /* Márgenes internos. */
overflow: auto; /* Barras desplazamiento automáticas. */
background-image: url("imgs/papel.png"); /* Imagen de fondo. */
}
/* Para el pie de página */
.navfooter
{
position: relative;
height: 10%; /* Alto. */
margin: 0 -2em 0 -2em; /* Márgenes (arriba dcha. abajo izqda.) */
padding: 0.5em 2em 0.5em 2em; /* Márgenes internos (igual orden). */
background-image: url("../imgs/panel.png"); /* Imagen de fondo. */
}
Como antes, los comentarios pretenden explicar el código, pero siempre es recomendable buscar por cuenta propia las aclaraciones a nuestras interesantes dudas. Es importante tener en cuenta que en CSS el orden en que si dispongan los distintos elementos influye en el resultado final. El estilo se aplica secuencialmente desde la primera línea del archivo hasta la última.
Formato PDF (imprimible en papel)
Para convertir DocBook a PDF empleo xsltproc junto con fop. De nuevo te aviso de que puede ser necesario que tengas que instalar estos programas. En primer lugar ejecuto xsltproc para generar un archivo intermedio con el sufijo .fo, el cual contendrá las configuraciones definidas en la hoja de estilo pdf.xsl.
~$ xsltproc -xinclude -o libro.fo \
-> --stringparam double.sided 1 config/pdf.xsl ejemplo.xml
Esto ha creado un archivo llamado ejemplo.fo para ser impreso a doble cara (--stringparam double.sided 1), con las características definidas en el archivo de configuración pdf.xsl, que se encuentra en la carpeta config, a partir de original DocBook llamado ejemplo.xml. Con la siguiente instrucción se consigue el PDF definitivo:
~$ fop -fo libro.fo -pdf libro.pdf
Para personalizar el PDF utilizo como plantilla de presentación
general la
siguiente hoja de estilo, que es la que hemos incluido como parámetro de la orden
xsltproc.
config/pdf.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:d="http://docbook.org/ns/docbook"
exclude-result-prefixes="d"
version="1.0">
<!-- Importamos la plantilla original. La localización del archivo
depende del Sistema Operativo. En Debian: --/>
<xsl:import href="/usr/share/xml/docbook/stylesheet/docbook-xsl/fo/docbook.xsl"/>
<xsl:param name="chapter.autolabel">0</xsl:param> <!-- Sin "Capítulo X" -->
<xsl:param name="appendix.autolabel">0</xsl:param> <!-- Sin "Apéndice X" -->
<xsl:param name="section.autolabel">0</xsl:param> <!-- Sin "Sección X" -->
<xsl:param name="hyphenate">true</xsl:param> <!-- Cortar palabras -->
<xsl:param name="double.sided">1</xsl:param> <!-- Doble cara -->
<xsl:param name="paper.type" select="'A4'"/>
<xsl:param name="body.font.master" select="'11'"/> <!-- Tamaño de letra -->
<xsl:param name="page.margin.top">4.5cm</xsl:param> <!-- Margen sup -->
<xsl:param name="page.margin.bottom">4.5cm</xsl:param> <!-- Margen inf -->
<xsl:param name="page.margin.inner" select="'4.5cm'"/> <!-- Margen izq -->
<xsl:param name="page.margin.outer" select="'4.5cm'"/> <!-- Margen der -->
<xsl:param name="body.start.indent" select="'0pt'"> <!-- No añade indentación al margen -->
<xsl:param name="header.rule" select="'0'"/> <!-- Sin línea en la cabecera -->
<xsl:param name="footer.rule" select="'0'"/> <!-- Sin línea en el pie -->
<!-- Establece el tamaño de letra para el título y nombre del autor -->
<xsl:attribute-set name="book.titlepage.recto.style">
<xsl:attribute name="font-family">
<xsl:value-of select="$title.font.family"/>
</xsl:attribute>
<xsl:attribute name="font-weight">bold</xsl:attribute>
<xsl:attribute name="font-size">25pt</xsl:attribute> <!-- Tamaño de letra -->
<xsl:attribute name="text-align">center</xsl:attribute>
</xsl:attribute-set>
<!-- Elimina el título de la cabecera de las páginas -->
<xsl:template name="header.content">
<xsl:param name="pageclass" select="''"/>
<xsl:param name="sequence" select="''"/>
<xsl:param name="position" select="''"/>
<xsl:param name="gentext-key" select="''"/>
</xsl:template>
<!-- Separación entre párrafos (sin separación) -->
<xsl:attribute-set name="normal.para.spacing">
<xsl:attribute name="space-before.optimum">0</xsl:attribute>
<xsl:attribute name="space-before.minimum">0</xsl:attribute>
<xsl:attribute name="space-before.maximum">0</xsl:attribute>
</xsl:attribute-set>
<!-- Sangría en la primera línea del párrafo (un cuadratín) -->
<xsl:attribute-set name="normal.para.spacing">
<xsl:attribute name="text-indent">1em</xsl:attribute>
</xsl:attribute-set>
<!-- Números de página en formato arábigo -->
<xsl:template name="page.number.format">
<xsl:param name="element" select="local-name(.)"/>
<xsl:param name="master-reference" select="''"/>
<xsl:choose>
<xsl:when test="$element = 'toc' and self::book">1</xsl:when>
<xsl:when test="$element = 'preface'">1</xsl:when>
<xsl:when test="$element = 'dedication'">1</xsl:when>
<xsl:otherwise>1</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Números de página para impresión a doble cara -->
<xsl:template name="initial.page.number">
<xsl:param name="element" select="local-name(.)"/>
<xsl:param name="master-reference" select="''"/>
<xsl:choose>
<xsl:when test="$double.sided != 0">auto</xsl:when> <!-- Doble cara -->
<xsl:otherwise>blank</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Genera índices, o tablas de contenido (toc = tables of contents).
Solo se activa el elemento book -->
<xsl:param name="generate.toc">
book toc,title,table,example,equation
</xsl:param>
<!-- Modificaciones al elemento <emphasis> de docbook, atributo 'role' -->
<xsl:template match="emphasis">
<xsl:choose>
<xsl:when test="@role='bold'"> <!-- negrita -->
<fo:inline font-weight="bold">
<xsl:call-template name="inline.charseq"/>
</fo:inline>
</xsl:when>
<xsl:when test="@role='underline'"> <!-- subrayado -->
<fo:inline text-decoration="underline">
<xsl:call-template name="inline.charseq"/>
</fo:inline>
</xsl:when>
<xsl:when test="@role='strikethrough'"> <!-- tachado -->
<fo:inline text-decoration="line-through">
<xsl:call-template name="inline.charseq"/>
</fo:inline>
</xsl:when>
<xsl:otherwise> <!-- cursiva (<emphasis> sin atributos) -->
<fo:inline font-style="italic">
<xsl:call-template name="inline.charseq"/>
</fo:inline>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Ruptura arbitraria de línea (<?linebreak?> -->
<xsl:template match="processing-instruction('linebreak')">
<fo:block/>
</xsl:template>
<!-- Salto incondicional de página (<?hard-pagebreak?> -->
<xsl:template match="processing-instruction('hard-pagebreak')">
<fo:block break-after='page'/>
</xsl:template>
</xsl:stylesheet>
El archivo .../fo/docbook.xsl que aparece en la marca xsl:import es la hoja de estilo, o plantilla, predeterminada para el PDF equivalente a la que vimos antes para el EPUB. Se localiza como describimos anteriormente, prestando atención a la carpeta fo en la lista de archivos que aparecen en el terminal.
Cuando es necesario incluir imágenes añado a continuación, pero antes de la etiqueta de cierre </xsl:stylesheet>, lo siguiente:
<!-- *** Para las imágenes en el PDF *** -->
<xsl:template name="process.image">
<!-- Si la imagen es más ancha que la página, se reduce a default.image.width -->
<xsl:variable name="scalefit">
<xsl:choose>
<xsl:when test="$ignore.image.scaling != 0">0</xsl:when>
<xsl:when test="@contentwidth">0</xsl:when>
<xsl:when test="@contentdepth and @contentdepth != '100%'">0</xsl:when>
<xsl:when test="@scale">0</xsl:when>
<xsl:when test="@scalefit">
<xsl:value-of select="@scalefit"/>
</xsl:when>
<xsl:when test="@width or @depth">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="scale">
<xsl:choose>
<xsl:when test="$ignore.image.scaling != 0">0</xsl:when>
<xsl:when test="@contentwidth or @contentdepth">1.0</xsl:when>
<xsl:when test="@scale">
<xsl:value-of select="@scale div 100.0"/> <!-- A mayor valor, menor tamaño de la imagen -->
</xsl:when>
<xsl:otherwise>1.0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="filename">
<xsl:choose>
<xsl:when test="local-name(.) = 'graphic' or local-name(.) = 'inlinegraphic'">
<xsl:call-template name="mediaobject.filename">
<xsl:with-param name="object" select="."/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="mediaobject.filename">
<xsl:with-param name="object" select=".."/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<fo:external-graphic>
<xsl:attribute name="src">
<xsl:call-template name="fo-external-image">
<xsl:with-param name="filename">
<xsl:if test="$img.src.path != '' and not(starts-with($filename, '/')) and not(contains($filename, '://'))">
<xsl:value-of select="$img.src.path"/>
</xsl:if>
<xsl:value-of select="$filename"/>
</xsl:with-param>
</xsl:call-template>
</xsl:attribute>
<xsl:attribute name="content-width">
<xsl:choose>
<xsl:when test="$ignore.image.scaling != 0">auto</xsl:when>
<xsl:when test="contains(@contentwidth,'%')">
<xsl:value-of select="@contentwidth"/>
</xsl:when>
<xsl:when test="@contentwidth">
<xsl:call-template name="length-spec">
<xsl:with-param name="length" select="@contentwidth"/>
<xsl:with-param name="default.units" select="'px'"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="number($scale) != 1.0">
<xsl:value-of select="$scale * 100"/>
<xsl:text>%</xsl:text>
</xsl:when>
<xsl:when test="$scalefit = 1">scale-to-fit</xsl:when>
<xsl:otherwise>scale-down-to-fit</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</fo:external-graphic>
</xsl:template>
Si acaso no fuese de tu agrado el aspecto del PDF conseguido, siempre puedes obtener otro a partir del formato EPUB, ya sea de forma interactiva o utilizando las herramientas previstas para ser usadas en consola que puedes encontrar en esta página de la web de Calibre. Ahí tenemos la información necesaria para utilizar en nuestro terminal de texto un programa que nos permitirá tanto afinar nuestro EPUB, como la conversión a otros formatos, entre ellos PDF. El programa se llama ebook-convert y forma parte de la instalación de Calibre (al menos en GNU/Linux). He de advertirte de que el PDF conseguido con Calibre no sitúa el comienzo de los capítulos en las páginas derechas, como mandan los cánones editoriales, sino allí donde les toque, sea página izquierda o derecha. Probablemente habrá otros matices diferenciadores, pero dejaré que seas tú quien se ocupe de encontrarlos y decidir lo que mejor se adecue a tus muy escogidas preferencias.
Ajustes en las imágenes según el formato
No es de extrañar que una misma imagen se vea de tamaño diferente en HTML que en PDF, o que un tipo de imagen (digamos SVG) se vea en un formato pero no en el otro. Para lidiar con estos inconvenientes disponemos del atributo role en la marca imageobject. Utilizo las imágenes SVG en la web y en el EPUB (recuerda que EPUB es básicamente HTML) con idea de conseguir una web accesible, ya que el formato SVG se puede ampliar lo que haga falta sin problemas. Sin embargo el programa xsltproc actualmente no procesa las imágenes destinadas al papel (PDF) en el formato SVG, así que las duplico al formato PNG. Esto es un capricho mío, puedes utilizar solo el formato PNG si quieres, pero teniendo en cuenta que probablemente tengas que retocar el tamaño de alguna imagen en el PDF. La cosa sería como sigue en nuestro original escrito en DocBook:
<figure xml:id="Imagen prueba"><title>Prueba de imagen</title>
<mediaobject>
<imageobject role="html"> <!-- Especificaciones para HTML y EPUB -->
<imagedata format="svg" align="center" scale="100" fileref="imagenes/prueba.svg"/>
</imageobject>
<imageobject role="fo"> <!-- Especificaciones para PDF -->
<imagedata format="png" align="center" scale="75" fileref="imagenes/prueba.png"/>
</imageobject>
<textobject>
<phrase>Texto para el caso de que la imagen no pueda ser visualizada.</phrase>
</textobject>
<caption>
<para>
Explicación o comentario, visible en el documento, sobre la imagen.
</para>
</caption>
</mediaobject>
</figure>
Simplemente se duplica la marca imageobject, con su correspondiente imagedata
naturalmente, asignándole a una el role=html
y a la otra el role=fo
,
cada una con su especificaciones de formato, alineación, escala y nombre de la imagen,
que para el HTML será prueba.svg y para el PDF prueba.png. Si las imágenes
son de tipos diferentes, como en el ejemplo, deben existir las dos, aunque pueden
aplicarse distintas especificaciones a una misma imagen, como escalas diferentes para
HTML y PDF. Por supuesto que la utilización del atributo role también es válido
en los casos de fórmulas matemáticas incluidas mediante imágenes. Se hace exactamente de
la misma forma.
Para duplicar las imágenes originales en SVG al formato PNG puedes utilizar la misma técnica que se muestra en el vídeo del apartado sobre las matemáticas, o cualquier programa de manipulación de imágenes, como el GIMP en Linux o Photoshop en Windows.
Añadiendo una portada
Podemos incluir una portada en los formatos EPUB y PDF. No le vemos mucho sentido a una portada para HTML, pero allá tú si acaso te diera por insistir en ello.
Para el EPUB la portada se obtiene incluyendo el elemento cover en el encabezado DocBook. Partiendo del ejemplo utilizado en el apartado Escribiendo en DocBook, lo insertaremos a continuación de author, pero lo puedes poner donde quieras siempre que esté dentro de info.
ejemplo.xml
?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book [
<!ENTITY % ent SYSTEM "entidades.xml">
%ent;
]>
<book version="5.0" xml:lang="es"
xmlns="http://docbook.org/ns/docbook"
xmlns:xl="http://www.w3.org/1999/xlink">
<info>
<title>EL INGENIOSO HIDALGO DON QUIJOTE DE LA MANCHA</title>
<author>
<personname>Miguel de Cervantes Saavedra</personname>
</author>
<cover>
<mediaobject>
<imageobject role="html">
<imagedata format="svg" fileref="imgs/portada.svg"/>
</imageobject>
</mediaobject>
</cover>
<pubdate>1605</pubdate>
</info>
&cap1; <!-- El capítulo uno se insertará en este punto -->
&cap2; <!-- El capítulo dos se insertará en este punto -->
</book>
La portada consiste en un archivo de imagen —es lo que te sugiero—, aunque esa imagen
pueda contener letras, palabras o signos que puedan ser considerados texto
.
La portada en PDF la conseguiremos creando un documento nuevo de una sola hoja (dos
páginas), con el mismo tamaño que las páginas del libro, y pegándolo
al libro como
primera y segunda páginas. La primera página de este nuevo archivo para la portada
debería ser la misma imagen que la utilizada para el EPUB y la segunda estará en blanco.
Lo convertiremos a PDF con algún programa de manipulación de imágenes, como el mismo
Inkscape o los ya menciondos GIMP o Photoshop, poniendo cuidado en guardarlo con tamaño
A4, que es el utilizado en los ejemplos, o el que tengan las páginas de tu libro.
Seguidamente, para pegarlo
al libro utilizaremos la navaja suiza
de Linux
para PDF: pdftk,
aunque también está disponible para Windows y Mac. Casi me olvido de decirte que si en tu
sistema no existe pdftk, y quieres usarlo, tienes que instalarlo. El ejemplo de
uso para concatenar dos PDF (primero la portada y después el libro) sería:
~$ pdftk A=portada.pdf B=ejemplo.pdf cat A B output definitivo.pdf
Utilizo la imagen de portada y la página en blanco por separado, para disponer de ella
por si acaso quiero añadirla en algún otro lugar. El archivo Makefile del apartado
dedicado al programa make contiene la forma en que lo hago. En Linux se puede
consultar el manual de casi todos los programas, conocido como páginas man
,
tecleando en el terminal: man nombre_programa. Te puedes desplazar por el
contenido con la barra de espacio y la tecla B
, y cuando quieras salir pulsa la
Q
. Sugerencia:
~$ man pdftk
Consideraciones sobre la tipografía
Es posible elegir un determinado tipo de letra (mal denominado fuente
en mi
opinión, aunque el diccionario de la RAE lo haya incluido) para los formatos a obtener,
si no queremos conformarnos con el utilizado por defecto pero, dependiendo de la
naturaleza de nuestra obra, esto puede resultar un importante inconveniente, ya que si
utilizamos caracteres que no formen parte del conjunto incluido en el tipo de imprenta
escogido no podremos hacerlos visibles. Si usamos, por ejemplo, letras griegas y nuestro
tipo de letra no las tiene implementadas, veremos en su lugar el signo #
o algún
otro en sustitución del carácter inexistente. Es por esto que un servidor ha decidido
no personalizar la tipografía, ya que la utilizada por defecto está muy bien y garantiza
que todos los signos que se me ocurra escribir serán visibles en el escrito final, sea
cual sea el formato elegido. Cierto que el tipo de letra de este sitio web está
personalizado, pero eso es porque HTML permite utilizar cualquier carácter a través de
entidades. Los problemas aparecen en el PDF y el EPUB. Así que, si encuentras una
tipografía que te guste, la cual contiene todos los caracteres que necesitas, y decides
empeñarte en conseguirlo, que los vientos electrónicos te sean favorables, diligente
digituense. Por mi parte me voy a limitar a darte unas escuetas pistas para que,
al menos, tengas una idea de por dónde empezar.
Para personalizar el tipo de letra en los formaos EPUB y HTML deberás prepararlo en una
carpeta e incluirlo en el archivo de estilo CSS. Puedes consultar el código fuente de
esta misma web, mirar el contenido del archivo estilo.css y actuar en consecuencia.
Es posible que encuentres alguna dificultad extra para conseguir que dicha carpeta con
tu fuente
forme parte del paquete .epub, pero un servidor no va a perder
tiempo en averiguar cómo se hace algo que no va a utilizar (aunque probablemente Calibre
tenga algo que decir al respecto). Para el PDF deberás hacerlo a través de un archivo
especial que leerá el programa fop. Como aperitivo, puedes ir picando algo en la
web de Apache FOP Project.
Organizándolo todo
La organización de los archivos depende, lógicamente, de cada cual. Yo los he dispuesto en la forma que aparece en los siguientes recortes de pantalla que muestran la salida del mandato tree, porque así puedo empaquetar más cómodamente los diferentes formatos para su publicación por separado en esta tu web. También está pensada para facilitar la creación de la estructura para cada nuevo libro; basta con copiar la carpeta raíz con un nuevo nombre, eliminar los archivos de la carpeta originales, las imágenes que no estén en imgs/permanentes/, y la carpeta formatos al completo, ya que la crea el propio Makefile si no existe. Una vez hecho esto, se van añadiendo los archivos .xml a la carpeta originales y se modifican apropiadamente config/entidades.xml y montaje.xml. Pero no tienes por qué copiarme aunque tengas mi permiso para hacerlo. Tómalo como una guía o ejemplo y descubre tu propio camino, joven digituense.
El puntito inicial en el recorte de la izquierda indica que estamos dentro
de la
carpeta base, o raíz, del proyecto, sea cual sea su nombre. Los nombres en color azul son
carpetas y el resto archivos normales, tanto de texto como de imagen. El llamado montaje.xml
es el original a procesar, lo llamo así porque solo contiene lo necesario para montar
el libro, cuyo texto se encuentra en la carpeta originales dividido en varios
archivos si fuese necesario (recuerda las entidades). A la derecha tenemos el esquema de
la carpeta que contiene los distintos formatos, a los que he añadido el .txt
(texto llano) como regalo especial. En el siguiente apartado veremos como se consigue.
El programa make y los archivos Makefile
El programa make fue pensado para
compilar
código de programación repartido entre muchos archivos, de manera que no sea necesario
recompilarlos todos cada vez que alguno cambie, sino solamente los que hayan sido
modificados. En realidad puede hacer más cosas, pero esto es lo que se suele explicar
en todas partes, teniendo en cuenta que su utilidad principal es ayudar a construir
programas de ordenador en sistemas Unix/Linux. Para cumplir sus funciones hace uso de
unos archivos especiales que han de llamarse, sí o sí, Makefile escrito tal
cual, con su mayúscula inicial, en singular y sin sufijo o extensión. Un Makefile
tiene la particularidad de que ha de ser ejecutado desde una consola y estando dentro
de la misma carpeta que lo contiene. Es posible llamar
a un Makefile que
esté en una carpeta distinta del que hace la llamada, pero se requieren unas técnicas más
avanzadas que las que aquí vamos a intentar explicar. Para ejecutar un Makefile
(las instrucciones que contiene) solamente hay que situarse en la carpeta en que se
encuentre y utilizar la orden make. Obviamente, para poder utilizar make
tenemos que tenerlo instalado.
Los archivos Makefile tienen unas características que permiten llevar a cabo muchas instrucciones con una simple orden make, y eso es lo que vamos a aprovechar para obtener cómodamente los formatos finales a partir de nuestro escrito en DocBook. Las características a que nos referimos son principalmente tres: objetivos, dependencias y variables. Un objetivo es una etiqueta, un nombre seguido de dos puntos, que se puede utilizar al ejecutar la orden make así: make epub, make pdf, etc. Si utilizamos solamente make, sin especificar ningún objetivo, se ejecutará el primero que se encuentre en el archivo Makefile. Una dependencia es algo que tiene que estar creado o ejecutado para realizar el objetivo al que pertenece. Puede ser incluso otro objetivo. Una variable es un nombre, usualmente corto, que contiene algo que puede ser utilizado en distintas partes del Makefile sin tener que escribirlo completamente cada vez. Otra cosa muy importante a tener en cuenta a la hora de escribir un Makefile, es que toda instrucción a ejecutar tiene que estar precedida por una tabulación al principio de la línea o no funcionará. Repito: hay que pulsar la tecla tabulador al principio de cada línea que contenga una orden, y eso es lo que hay. Y ahora, sin anestesia ni nada, te presento mi Makefile para obtener los formatos de DocBook:
Makefile
SHELL = /bin/bash
NOMBRE = $(shell grep title montaje.xml | head -1 | cut -d'*' -f2)
todos: epub pdf txt
epub:
rm -rf formatos/${NOMBRE}.epub
mkdir -p formatos
a2x -d book -f epub --xsl-file config/epub.xsl --stylesheet config/epub.css montaje.xml
mv montaje.epub formatos/${NOMBRE}.epub
pdf:
rm -rf formatos/${NOMBRE}.pdf
mkdir -p formatos
xsltproc -xinclude -o montaje.fo --stringparam double.sided 1 --stringparam ulink.show 0 config/pdf.xsl montaje.xml
fop -fo montaje.fo -pdf formatos/${NOMBRE}_tmp.pdf
pdftk A=imgs/portada.pdf B=imgs/blanco.pdf cat A B output formatos/portada_tmp.pdf
pdftk A=formatos/portada_tmp.pdf B=formatos/${NOMBRE}_tmp.pdf cat A B output formatos/${NOMBRE}.pdf
rm -rf *.fo formatos/*_tmp.pdf
html:
rm -rf formatos/${NOMBRE}_html
mkdir -p formatos/${NOMBRE}_html/imgs
xmlto -m config/html.xsl --skip-validation -o formatos/${NOMBRE}_html/ html montaje.xml
for archivo in $$(ls formatos/${NOMBRE}_html/*.html); \
do sed -i '1 s/^/<!DOCTYPE html>\n/' $$archivo; \
done
cp -rf config/html.css formatos/${NOMBRE}_html/estilo.css
cp -rf imgs formatos/${NOMBRE}_html/
rm -f formatos/${NOMBRE}_html/*.proc
rm -f formatos/${NOMBRE}_html/imgs/portada.*
rm -f formatos/${NOMBRE}_html/imgs/blanco.*
txt: html
rm -rf formatos/${NOMBRE}.txt
mkdir -p formatos
w3m -dump formatos/${NOMBRE}_html/index.html > formatos/obra.txt
w3m -dump formatos/${NOMBRE}_html/ch*.html >> formatos/obra.txt
w3m -dump formatos/${NOMBRE}_html/ap*.html >> formatos/obra.txt
sed -e '/Anterior/,+2d' formatos/obra.txt > formatos/${NOMBRE}.txt
sed -e '/Siguiente/,+1d' formatos/${NOMBRE}.txt > formatos/obra.txt
sed '/Fecha/d' formatos/obra.txt > formatos/${NOMBRE}.txt
sed -i 's/ / /g' formatos/${NOMBRE}.txt
rm -f formatos/obra.txt
La primera línea le dice a Make que las instrucciones para la
shell
deben ser interpretadas por bash
(en Linux suele haber varios intérpretes de órdenes disponibles), que se encuentra en la
carpeta bin, la cual cuelga
directamente de la raíz del sistema de
archivos /
. La segunda línea es una especie de hack, en el sentido de
truco informático
, para obtener el nombre de la obra desde el archivo montaje.xml
y así no tener que modificar nada en el Makefile de cada nuevo libro. Desde
luego puedes sustituir lo que hay a la derecha del signo igual por el nombre de tu libro
escrito tal cual (mejor entre comillas dobles) y todo seguirá funcionando perfectamente.
Pero vayamos por partes.
Veamos en primer lugar la variable utilizada: NOMBRE. Contiene el nombre del
archivo que constituye el libro. De esta forma solo hay que cambiarlo una única vez al
principio del Makefile de cada libro, y la palabra NOMBRE
será sustituida
por el texto que hayamos escrito a continuación del signo igual en todos los lugares
donde la misma aparezca, pero las reglas de los Makefile obligan a utilizar el
signo $
y las llaves en la forma que vemos en el archivo para conseguir esa
magia
. Suponiendo que la primera línea del archivo sea:
NOMBRE = "MiLibro"
donde nosotros escribimos formatos/${NOMBRE}.epub el programa make escribirá: formatos/MiLibro.epub y hará igual en todos los demás sitios donde aparezca ${NOMBRE}.
En segundo lugar, vemos que el Makefile contiene cinco objetvos: todos:, epub:, pdf:, html: y txt:, pero el primero que aparece (todos:) depende de los tres mencionados en su misma línea. Esto quiere decir que, si escribimos en nuestra consola la orden make así sin más, se ejecutará el objetivo denominado todos por ser el primero que hay en el archivo, y como ese objetivo tiene a los demás asignados como dependencias, hemos conseguido obtener los cuatro formatos a la vez con solo ejecutar la orden make. Pero eso no es todo, ya que con el mandato make epub obtendremos sólamente el formato EPUB, y lo mismo sucede con los demás. Ejecutando make objetivo conseguimos que únicamente se lleven a cabo las instrucciones asignadas a ese objetivo en concreto, que son las que están a continuación, o debajo, de su nombre y comienzan con una tabulación. Como el texto llano se obtiene a partir de los archivos HTML, al objetivo txt le he asignado como dependencia el objetivo html, con lo que me aseguro de que el formato HTML exista cuando txt sea ejecutado. Al estar html como dependencia de otro objetivo, lo dejo sin incluir en todos para que no se ejecute dos veces. Pero si no te interesa para nada el .txt, puedes eliminarlo por completo y/o sustituir en todos la dependencia txt por html, para que se ejecute por defecto al igual que los demás.
El mandato rm -rf es para eliminar de manera recursiva e incondicional las carpetas y archivos del formato correspondiente, haciendo limpieza general antes de crearlo por si acaso ya existiera. También se utiliza de la misma forma para borrar los archivos creados con carácter temporal. Con mkdir se crean las carpetas donde vamos a situar los archivos definitivos de cada formato y todos los necesarios para su correcto funcionamiento, como las imágenes del HTML. Respecto a las instrucciones w3m y sed utilizadas en el formato de texto llano (.txt), solo te voy a decir que el primero es un navegador web para consola (en Linux hay de todo) que utilizo para extraer el texto sin las etiquetas del formato HTML, y que el segundo es un programa muy útil para editar texto automáticamente, por así decirlo. Dejo a tu iniciativa autodidacta la obtención de más conocimientos al respecto. El resto de las órdenes de cada objetivo verás que son las mismas que hemos ido comentando para la obtención de los formatos.
En el objetivo html se incluyen las siguientes líneas aunque, como ya sabrás (o deberías saber), al utilizar la barra inclinada inversa conforman una sola línea de órdenes:
for archivo in $$(ls formatos/${NOMBRE}_html/*.html); \
do sed -i '1 s/^/<!DOCTYPE html>\n/' $$archivo; \
done
Con esto consigo añadir la etiqueta <!DOCTYPE html> al principio de cada uno de los archivos .html, ya que los conversores XSL no la incluyen (al menos los que uso a la fecha de escribir esto). No pasa nada si tú no lo haces, el formato HTML seguirá viendose bien, es que soy un tanto puntilloso; como esto es lo que el navegador espera encontrar al principio de un documento HTML5, lo pongo y ya está, para algo uno aprendió a programar. Este código es el motivo de que el intérprete de órdenes deba ser bash, como explicamos antes, ya que con otra shell podría no funcionar.
Por supuesto que hay otras formas de obtener todos los formatos automáticamente sin
utilizar make. Si has conseguido iniciarte en los misterios del terminal
posiblemente conozcas los llamados
shell scripts,
que bien pueden ser la principal alternativa a los Makefile para estos casos.
Otras opciones posiblemente tengan que ver con algún lenguaje de programación y las
ganas de usarlo para estas cosas, aunque ya se sabe que hay gente para todo
.
Si echas a faltar explicaciones más detalladas sobre XML, XSL, CSS, los Makefile…
piensa que de lo que se trata aquí es de mostrarte cómo lo hago con DocBook. Para
llegar a comprender todos los pormenores tendrías que saber programar además de contar
con nociones de shell scripts, CSS y XSLT. No me parece práctico incluir en
este modesto artículo un tutorial de programación general, otro de CSS y de XSLT básicos
y posiblemente uno más sobre órdenes en la consola de Linux y cómo se utilizan en los
Makefile. Por suesto que si no te conformas con un uso ad hoc
siempre puedes investigar por tu cuenta, que en Internet está casi todo.
Sugerencia final
Si tienes interés en estas tecnologías y aún te quedan dudas, cualquiera de las publicaciones que hay en la biblioteca te puede servir de ejemplo práctico. Descargándote el ZIP que contiene todos los archivos al completo y descomprimiéndolo podrás curiosear a tu antojo y ver con tus propios ojos cómo está construido. El de la pirámide de Keops tiene bastantes cosas: imágenes, cálculos matemáticos, varios capítulos y hasta un apartado con bibliografía. Si osas atreverte, por lo que a mí respecta te deseo que las cuatro musas de las letras y los ciberdioses informáticos te sean favorables.
Que la inspiración te acompañe, joven digituense.
