Desde html hasta epub
Ejemplos de libros que he generado desde mis páginas html
- AI - IA. Inteligencia artificial aplicada a la programación y la docencia
- Nube privada virtual
- Manual Técnico: servidor DNS
En
https://github.com/aortrei469/epubDesdeHTMLse encuentra el software al que se hace referencia en el artículo
Generar epub desde una relación de ficheros html
HACER COPIA DE SEGURIDAD DE TODO ANTES DE EMPEZAR
Cambiamos el contenido del <head> de todos los ficheros html que formarán parte del epub
Dejamos, como ejemplo:
<head>
<title>XXXXX</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="author" content="XXXXXXXXXXXXXXX" />
<meta name="robots" content="noindex, nofollow" />
<link rel="stylesheet" href="css/manual.css" type="text/css" media="all" />
</head>
Purgar todo aquello que no se pueda encontrar en el epub, por ejemplo en mi caso tengo que Eliminar todos los <a> que engloban a las <img> en las <figure>
Utilidad:
aor@aorsrv:~/proyectos/opencode/epubHtmlToEpub$ ls *.sh
eliminaTagASobreTagImg.sh
Ejemplo:
aor@aorsrv:~/proyectos/opencode/epubHtmlToEpub/libro$ ../eliminaTagASobreTagImg.sh
Procesando: 0_Infraestructura.html
Procesando: 1_srv01.html
Procesando: 2_srv01_maquinas_virtuales.html
Procesando: 3_SRV01_mv_database.html
Procesando: 4_SRV01_mv_grafana_loki.html
Procesando: 5_SRV01_mv_openproject.html
Procesando: 6_srv01_n8n.html
Procesando: 7_wordpress.html
Hecho. Backups creados como *.bak
También tendré problemas con los grafos. Buscamos los <div class="mermaid">
Eliminamos del lo siguiente
<script src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"></script>
<script>
mermaid.initialize({
startOnLoad: true,
theme: 'default',
securityLevel: 'loose',
flowchart: { useMaxWidth: true, htmlLabels: true },
sequence: { useMaxWidth: true }
});
</script>
Así como todos los scripts que estemos usando. Es mejor no usarlos, es sólo
documentación.
Para mermaid generamos también la imagen y según sea para html o epub lo
seleccionaremos mediante estilo
Ejemplo:
.mermaid {
display: none !important;
}
.img-mermaid {
display: block !important;
}
Cambiarle el css para que corte tablas, código etc.
Usamos el css que tenemos preparado para los ebooks. Esto es,
resultadoBaseEpubEnMIsDocumentos.css
...
...
/* ==========================================================================
8. PAGINACIÓN Y CONTROL DE SALTOS (Reglas Kindle)
========================================================================== */
h1, h2, h3 {
page-break-after: avoid;
}
figure, .diagram-container, table, pre {
page-break-inside: avoid;
}
En epub por ejemplo no se pueden usar atributos como align , por lo que lo
trabajamos mediante clases
/*
ya no se puede usar align
*/
.texto-centrado {
text-align: center;
}
.texto-derecha {
text-align: right;
}
Limpiar metadatas
sudo apt install mat2find ./libro/images/ -type f -exec mat2 --inplace {} +- Vemos los errores obtenidos, y los solucionamos
Verificar que no quedan metadatos
sudo apt install libimage-exiftool-perlfind ./libro/images/ -type f \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" \) -exec sh -c 'echo "=== Examinando: $1 ==="; exiftool "$1" | grep -E "Camera|Date|Software|Modify|Create|Artist|Copyright"' _ {} \;- (En una sola imagen: exiftool imagen.jpg.)
Verificamos que no tengamos espacios en blanco en nombres de ficheros
Para saber si hay ficheros que no cumplen ejecutamos:
aor@aorsrv:~/proyectos/opencode/epubDesdeHtml$ cat verificar_epub.sh
#!/bin/bash
# Comprobar si se ha pasado un directorio como argumento
if [ -z "$1" ]; then
echo "Uso: $0 /ruta/al/directorio/del/epub"
exit 1
fi
TARGET_DIR="$1"
# Verificar si el directorio existe
if [ ! -d "$TARGET_DIR" ]; then
echo "Error: El directorio '$TARGET_DIR' no existe."
exit 1
fi
echo "Iniciando verificación de nombres de archivo en: $TARGET_DIR"
echo "--------------------------------------------------------"
ALERTA=0
# Buscar todos los archivos de forma recursiva
while IFS= read -r -d '' archivo; do
# Obtener solo el nombre del archivo (sin la ruta)
nombre=$(basename "$archivo")
# Obtener la ruta relativa desde el directorio objetivo
ruta_relativa="${archivo#$TARGET_DIR/}"
# 1. Exclusión del archivo mimetype en la raíz (es una excepción válida)
if [ "$ruta_relativa" == "mimetype" ]; then
continue
fi
# 2. Verificar caracteres no permitidos (solo permite A-Z, a-z, 0-9, ., _, -)
if [[ ! "$nombre" =~ ^[A-Za-z0-9._-]+$ ]]; then
echo "[ERROR] Caracteres inválidos o espacios en: $ruta_relativa"
ALERTA=1
fi
# 3. Verificar longitud del nombre del archivo (máximo 255 bytes)
if [ ${#nombre} -gt 255 ]; then
echo "[ERROR] Nombre demasiado largo (>255 caracteres): $ruta_relativa"
ALERTA=1
fi
done < <(find "$TARGET_DIR" -type f -print0)
echo "--------------------------------------------------------"
if [ $ALERTA -eq 0 ]; then
echo "¡Éxito! Todos los archivos cumplen con las restricciones de EPUB."
else
echo "Se han encontrado errores. Corrige los nombres antes de compilar el EPUB."
fi
Ejemplo:
aor@aorsrv:~/proyectos/opencode/epubDesdeHtml$ ./verificar_epub.sh libro
Iniciando verificación de nombres de archivo en: libro
--------------------------------------------------------
[ERROR] Caracteres inválidos o espacios en: images/wordpress/Captura de pantalla_2025-11-21_19-06-12.jpg
[ERROR] Caracteres inválidos o espacios en: images/wordpress/Captura de pantalla_2025-11-21_19-05-41.jpg
[ERROR] Caracteres inválidos o espacios en: images/wordpress/Captura de pantalla_2025-11-21_19-02-49.jpg
[ERROR] Caracteres inválidos o espacios en: images/wordpress/Captura de pantalla_2025-11-21_19-04-55.jpg
[ERROR] Caracteres inválidos o espacios en: images/wordpress/Captura de pantalla_2025-11-21_19-04-41.jpg
[ERROR] Caracteres inválidos o espacios en: images/wordpress/Captura de pantalla_2025-11-21_19-03-30.jpg
[ERROR] Caracteres inválidos o espacios en: images/wordpress/Captura de pantalla_2025-11-21_19-04-26.jpg
--------------------------------------------------------
Se han encontrado errores. Corrige los nombres antes de compilar el EPUB.
Generamos el libro
source env/bin/activate
./env/bin/python generar_epub.py
Chequeamos el libro generado
sudo apt install epubcheck
epubcheck libro.epub
Una vez que lo tenemos (hasta entonces: eliminar epub, regenerar, volver a
chequear
Actualizamos los errores encontrados en nuestro ficheros htm originales
Si los hemos conservado. HACER COPIA DE SEGURIDAD ANTES DE EMPEZAR
Vamos a minificar nuestros documentos
sudo apt install -y minify
minify -r --html-keep-conditional-comments --match=".*\.(html|xhtml|css)$" -o libro/ libro_min/
Ejemplo:
(env) aor@aorsrv:~/proyectos/opencode/epubDesdeHtml$ mkdir libro_min
(env) aor@aorsrv:~/proyectos/opencode/epubDesdeHtml$ minify -r --html-keep-conditional-comments --match=".*\.(html|xhtml|css)$" -o libro_min libro
(env) aor@aorsrv:~/proyectos/opencode/epubDesdeHtml$ ls libro
0_Infraestructura.html 2_srv01_maquinas_virtuales.html 4_SRV01_mv_grafana_loki.html 6_srv01_n8n.html css
1_srv01.html 3_SRV01_mv_database.html 5_SRV01_mv_openproject.html 7_wordpress.html images
(env) aor@aorsrv:~/proyectos/opencode/epubDesdeHtml$ ls libro_min/
libro
(env) aor@aorsrv:~/proyectos/opencode/epubDesdeHtml$ ls libro_min/libro/
0_Infraestructura.html 2_srv01_maquinas_virtuales.html 4_SRV01_mv_grafana_loki.html 6_srv01_n8n.html css
1_srv01.html 3_SRV01_mv_database.html 5_SRV01_mv_openproject.html 7_wordpress.html
Verificamos el resultado Y volvemos a generar el libro minimizado
(env) aor@aorsrv:~/proyectos/opencode/epubDesdeHtml$ rm -f libro.epub
(env) aor@aorsrv:~/proyectos/opencode/epubDesdeHtml$ ./env/bin/python generar_epub.py
Páginas HTML: 8
CSS: 1
Imágenes: 42
✓ 0_Infraestructura.html → 0_Infraestructura.xhtml (NUBE PRIVADA INTEGRAL)
✓ 1_srv01.html → 1_srv01.xhtml (Server01)
✓ 2_srv01_maquinas_virtuales.html → 2_srv01_maquinas_virtuales.xhtml (Server01. MVs)
✓ 3_SRV01_mv_database.html → 3_SRV01_mv_database.xhtml (database)
✓ 4_SRV01_mv_grafana_loki.html → 4_SRV01_mv_grafana_loki.xhtml (observability)
✓ 5_SRV01_mv_openproject.html → 5_SRV01_mv_openproject.xhtml (OpenProject)
✓ 6_srv01_n8n.html → 6_srv01_n8n.xhtml (n8n)
✓ 7_wordpress.html → 7_wordpress.xhtml (wordpress)
EPUB generado: libro.epub
ID: xxxxxxxxxxxx
(env) aor@aorsrv:~/proyectos/opencode/epubDesdeHtml$ epubcheck libro.epub
Validación usando la versión de reglas epub 3.2.
No se han detectado errores o advertencias.
Mensajes: 0 errores fatales / 0 errores / 0 advertencias / 0 indicaciones
EPUBCheck completado
Cargamos en Sigil
~/Descargas$ ./Sigil-2.7.6-x86_64.AppImage
Y hacemos:
Herramientas
MUY IMPORTANTE HAY QUE HACER TODOS LOS PASOS
- Editar metadatos
- Añadir portada
- Reformatear HTML
- Comprobar epub F7
Complementos
Edición -> Baka-jpeg
El plugin Baka-Jpeg para Sigil tiene como objetivo comprimir y reducir el
tamaño de las imágenes en tu archivo ePub, tomando decisiones inteligentes.
El plugin procesa formatos como JPG, BMP y PNG, y en el caso de los PNG, los
convierte a JPEG si determina que esto reducirá significativamente el tamaño
del archivo (por ejemplo, en fotografías o imágenes complejas).
Recomendación: tener solo jpg en las páginas html antes de iniciar el
proceso
Tener en cuenta:
- Para textos o dibujos: El plugin es "inteligente" e intenta evitar comprimir archivos PNG que contienen texto nítido, ya que pasarlos a JPEG puede hacer que se vean borrosos.
- Conversión: Sí, puede transformar imágenes PNG a JPG para optimizar el peso total del libro electrónico.
- Recomendación: Como este tipo de plugins modifica los archivos de forma permanente, siempre se aconseja hacer una copia de seguridad o guardar tu archivo ePub antes de ejecutarlo.
El plugin realiza todo el proceso en tres pasos internos:
- Conversión: Transforma el archivo físico de la imagen de .png a .jpeg.
- Actualización del código: Busca todas las etiquetas <img src="..."> en tus archivos HTML y cambia la extensión .png por .jpeg para que sigan apuntando al archivo correcto.
- Actualización del Manifiesto: Modifica el archivo de control del ePub (content.opf) para registrar el nuevo formato de imagen.
Tras usarlo verificar que todo queda correcto, hacer una búsqueda por
ejemplo de todos los .png
Top comments (0)