Maquetación automática con Vivliostyle
10 de jul. de 2024 - #Informática
En el pasado he mencionado que me gusta crear mis propias aventuras para juegos de rol, pero suelo tener un problema cuando intento darles un buen formato: maquetar, sobre todo cuando el estado es muy preliminar, me da mucha pereza, pero tiene sus ventajas, porque además de obligarte a releer, te da visión de conjunto al verlo como página. De un simple vistazo percibes si el orden de las secciones es más o menos óptimo dentro de la estructura.
El proceso puede resultar largo, y aún más en caso de que busques generar un fichero PDF indexado y accesible, además de un fichero epub
. Curioseé si habia algun proyecto en esa línea, porque obviamente no puedo ser la única persona que se ha preocupado por este tema, y dí con Vivliostyle. Se trata de un proyecto escrito en NodeJS, que además cuenta con un repositorio de temas entre los que había uno de epub genérico, y otro creado específicamente para módulos de Dungeons and Dragons. Si me lo ponen así, merece la pena hacer una prueba, a ver cuánto trabajo se podía resolver programáticamente con este invento.
Os comparto mi experiencia, porque la respuesta que he obtenido ha sido “resuelve bastante”. Señalo también que esto es para “soluciones rápidas caseras”: no subestiméis el trabajo de un maquetador profesional, porque un automatismo carece de ojo para la estética.
Creando un proyecto base
Para esta parte no hace falta tener grandes conocimientos de programación: vamos a emplear las herramientas tal como vienen, siendo una mera “receta de cocina”.
Si no te has instalado NodeJS, evidentemente ese es el primer paso.
Crea la estructura de proyecto desde el terminal y ve contestando a las preguntas que va haciendo: el sistema trae algunos temas por defecto que no están nada mal para tu primer intento.
1
npx create-book mi-modulo
Edita los ficheros markdown dentro del proyecto. La base es
manuscript.md
, pero puedes crear el número de ficheros que necesites de acuerdo a tus necesidades. Por ejemplo, a mi me gusta crear un fichero por capítulo, para no saturarme con un documento eterno.Edita el fichero
vivliostyle.config.js
. A continuación señalo los puntos mas relevantes:- entry: la lista de ficheros de manuscrito. A mi me gusta juntarlos en una misma carpeta cuando son varios:
1
2
3
4entry: [
'./manuscript/Capitulo-1.md',
'./manuscript/Capitulo-2.md',
],- output: los ficheros de salida, habitualmente
.pdf
y una página web en HTML llamada webpub. Ojo aquí, que siendo astuto con el formateado de la plantilla desde aquí se puede generar la base de un fichero.epub
. Solo hay que comprimirlo con Calibre después.
1
2
3
4
5
6
7output: [
'./book.pdf',
{
path: './book',
format: 'webpub'
},
],- toc, toctitle y cover: se refieren respectivamente a la autogeneración de la “tabla de contenidos” (Table Of Content) o índice, y la aposibilidad de añadir una imagen como portada del documento.
1
2
3toc: true,
tocTitle: 'Tabla de contenido',
cover: './img/cover.png',Construir mediante el comando de terminal, situándonos dentro el directorio en el que se encuentra el fichero
package.json
:1
npm run build
Crear tu propio estilo visual
Aquí ya es imprescindible tener tiempo y ganas de codificar en HTML y CSS.
Debes crear un fichero
style.css
con la hoja de estilos.Referénciala desde
vivliostyle.config.js
:1
theme: 'mi-propio-tema.css',
Evitar la dependencia de conexiones externas para fuentes tipográficas
Existe la posibilidad bastante real de que cuando habras el fichero en algún dispositivo no tengas conexión a Internet. Por lo tanto, si las fuentes tipográficas sólo están referenciadas, podría perderse el factor estético y descolocarse la maquetación. En consecuencia, es una buena idea guardar las fuentes comprimidas de tu propio fichero CSS.
Buscamos el fichero local de la fuente que deseamos incluir. Podemos hacer el ejercicio con una muy socorrida de Google Fonts, como es la que imitar el rotulador permanente. Vamos a “get font” y vamos a guardarnos todo el código desde “get embed code” mediante web-link.
- Nos interesa la parte del código que marca
<link href="https://fonts.googleapis.com/css2?family=Permanent+Marker&display=swap" rel="stylesheet">
. Copiamos y pegamos el código que hay allí directamente en el ficherocss
para tenerlo enlazado:
1
2
3
4
5
6
7
8
9/* latin */
@font-face {
font-family: 'Permanent Marker';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/permanentmarker/v16/Fh4uPib9Iyv2ucM6pGQMWimMp004La2Cfw.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}- Nos interesa la parte del código que marca
Copiamos la url o dirección web del campo
src
, y lo pegamos en un navegador para bajarnos un fichero de nombre ininteligible, que contendrá el código de la fuente de la tipografía.Pasamos ese fichero por un sistema de codificación en base 64, seleccionando la opción de salida (output)
"Data URI"
. Una vez se haya pulsado “encode”, veremos en el recuador una larga ristra de caracteres. Nos preparamos para copiar ese “chorizo”.Reemplazamos la línea src de la siguiente manera, sustituyendo el campo “MI-CHORIZO-COFIFICADO” por el “chorizo” resultante del paso 3:
1
2src: url(data:@file/octet-stream;base64,
MI-CHORIZO-COFIFICADO) format('woff2');Ya lo tenemos listo para utilizarlo. Como un primer ejemplo, podemos definir el estilo de título:
1
2
3
4
5
6body h1 {
margin-bottom: 0.2em;
font-family: 'Permanent Marker', sans-serif;
font-size: normal;
font-weight: normal;
}
No quiero sorpresas a la hora de imprimir
El campo
@page
maneja esa información. Por ejemplo, para un A4 en vertical tenemos los siguientes valores (señalo quebackground color
lo he “comentado” para ahorrar tinta, pero cada uno tiene sus gustos y necesidades):1
2
3
4
5
6
7
8@page {
size: A4 portrait;
margin-top: calc(1.3cm * 297mm / 297mm);
margin-bottom: calc(1.5cm * 297mm / 297mm);
margin-left: calc(1.3cm * 210mm / 210mm);
margin-right: calc(1.3cm * 210mm / 210mm);
/*background-color: #EEE5CE;*/
}Si queremos aseguraros al 100% de que no se pierda nada cuando se pasa de web a PDF, hay un par de campos dentro de
@media print
para reafirmar que la configuración de impresión desde el navegador web es la correcta:-webkit-print-color-adjust
y-moz-print-color-adjust
. Los colores del ejemplo son los cásicos blanco y negro.1
2
3
4
5
6
7
8
9@media print {
body {
margin: 0;
color: #000;
background-color: #fff;
-webkit-print-color-adjust: exact;
-moz-print-color-adjust: exact;
}
}