Communitygithub.com

Lectura Bilingüe (Bilingual Reading)

Convierte PDFs técnicos en inglés en un HTML multihilado con traducción párrafo a párrafo, imágenes base64 incrustadas y un índice de navegación plegable a la izquierda.

¿Qué es Lectura Bilingüe (Bilingual Reading)?

Esta habilidad transforma un PDF técnico en inglés en un conjunto de archivos HTML bilingües, optimizados para lectura offline. Cada capítulo se convierte en un archivo HTML independiente que contiene el texto original en inglés, su traducción al chino párrafo a párrafo, y las imágenes incrustadas en base64. Un botón flotante 🌐 permite alternar entre los modos 'solo inglés', 'solo chino' y 'bilingüe', manteniendo el estado con localStorage. El proceso se automatiza mediante scripts de Python (PyMuPDF, PIL) y sigue reglas estrictas: no se resumen párrafos, los bloques de código permanecen en inglés, los párrafos chinos tienen un fondo azul claro con una barra lateral de 4px, y se añade una marca de página al final de cada página del original. Ideal para desarrolladores, estudiantes o cualquier persona que desee leer material técnico en inglés con apoyo de traducción.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/jasonadu/my-skills/tree/HEAD/bilingual-reading

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

¿Qué hace Lectura Bilingüe (Bilingual Reading)?

Resumen

Convierte un PDF técnico en inglés en una versión HTML offline con traducción párrafo a párrafo bilingüe: cada capítulo es un HTML autocontenido (UTF-8, imágenes base64 incrustadas, se puede abrir sin conexión), con un índice plegable fijo a la izquierda y un botón flotante 🌐 en la parte inferior derecha que alterna entre los modos «solo inglés», «solo chino» y «bilingüe», recordando el estado entre páginas.

Activación y entrada

  • Entrada: PDF en inglés (ruta local o URL, se descarga primero).
  • Salida: index.html + páginas de prefacio/postfacio + chapter-NN.html (un archivo por capítulo), empaquetado en zip final.
  • Si el PDF tiene marcadores (get_toc()), la estructura de capítulos se basa en los marcadores y se confirma con el usuario; después de que el usuario confirme «no dividir», se produce en lote.

Reglas principales (no violables)

  1. El texto original se traduce párrafo por párrafo completamente, sin resúmenes ni fusiones.
  2. Un capítulo por archivo, sin dividir capítulos; dentro del capítulo, se siguen las páginas originales en orden.
  3. Los bloques de código (<pre><code>) permanecen en inglés sin traducir; el código con llaves no se escribe dentro de f-strings.
  4. Los párrafos en chino tienen fondo azul claro + barra lateral izquierda de 4px, diferenciándose de los párrafos en inglés; los elementos de lista en chino siguen la misma especificación.
  5. Las imágenes se comprimen y luego se incrustan en base64; después de traducir cada página del PDF original, se añade una marca de página (page_mark(pdf_page)) que muestra el número de página original del PDF.
  6. Los nombres de archivo están en minúsculas con guiones (chapter-01.html, front-matter.html).
  7. Las entradas del índice se generan según la jerarquía de marcadores (l2/l3); los enlaces entre capítulos se encadenan, y los del primer y último capítulo aparecen desactivados.

Flujo de trabajo general

① Definir rango de páginas → ② Extraer texto → ③ Extraer imágenes → ④ Comprimir y convertir a base64
→ ⑤ Leer texto original y traducir → ⑥ Escribir build_chN.py → ⑦ Correguir llaves → ⑧ Ejecutar para generar
→ ⑨ Encadenar navegación → Verificar → Entregar

Primero se hace un capítulo de muestra (normalmente ch1) para que el usuario apruebe el estilo; después de la aprobación, se consolida/reutiliza book_theme.py y se produce en lote de forma continua, sin necesidad de confirmaciones intermedias. Las páginas de prefacio/postfacio y index.html se unifican al final.

Pasos detallados

① Definir rango de páginas

Entrada: TOC del libro / número de capítulo. Usar PyMuPDF para leer marcadores:

import fitz
doc = fitz.open("book.pdf")
toc = doc.get_toc()          # [[level, title, page_1based], ...]

Convertir números de página basados en 1 al intervalo basado en 0 de PyMuPDF. Los números de página de los marcadores a menudo tienen desplazamiento respecto a las páginas físicas; se usan los marcadores como referencia; listar la división de capítulos al usuario y confirmar antes de empezar.

② Extraer texto

text = "".join(doc[p].get_text("text", sort=True) for p in range(start0, end0+1))
open("chN_raw.txt", "w", encoding="utf-8").write(text)

sort=True asegura el orden de lectura, sin confundir columnas múltiples. Guardar texto original en chN_raw.txt por capítulo.

③ Extraer imágenes

Usar scripts/extract_assets.py:

python3 extract_assets.py book.pdf <start_page_1based> <end_page_1based> --out assets
  • page.get_images(full=True) deduplicado por xref → extract_image(xref).
  • jpx (JPEG2000), RGBA, modos P se convierten uniformemente a RGB y luego a JPEG (compatible con navegadores).

④ Comprimir y convertir a base64

Se realiza junto con el paso anterior (integrado en el script): abrir con PIL; si el ancho es >800px, escalar proporcionalmente a 800 (LANCZOS); JPEG q≈68 re-guardar; base64 escribir en assets/figN-M.txt. Cada imagen se comprime a 30~80KB.

⑤ Leer texto original y traducir

  • Leer chN_raw.txt por segmentos (500~600 líneas cada vez), traducir párrafo por párrafo, y registrar las correspondencias de leyendas de imágenes (por ejemplo, diagrama de cuervo, convertirlo al texto correspondiente "notas").
  • Saltar traducción de bloques de código; convertir tablas a HTML table; también traducir elementos de lista uno por uno sin fusionar.

⑥ Escribir script de construcción

Al inicio de build_chN.py: from book_theme import P, LI, CODE, INLINE, H, img_b64, page_mark, page; el contenido principal se escribe en el f-string body. Dentro del f-string, P()/LI() deben escribirse como {P(...)} para que se evalúen; los bloques de código se extraen como variables de cadena normales CODE_X = '''...''' y se concatenan con + CODE_X. Para la plantilla completa, ver el docstring al inicio de scripts/book_theme.py.

⑦ Post-procesamiento: corregir llaves

python3 scripts/fix_braces.py build_chN.py

Recorrer líneas: agregar { al inicio de líneas que comienzan con P('/LI('; buscar hacia adelante la primera línea que termina con ) y agregar } al final. No procesar llamadas a img_b64(/page( para evitar agregar } al final de las líneas page().

⑧ Ejecutar para generar

python3 build_chN.py     # El script imprime el nombre del archivo y el tamaño en KB si tiene éxito

⑨ Encadenar navegación

Completar prev/next según el número de capítulo (ch1 prev=front-matter.html, último capítulo next=None); los botones del primero y último capítulo usan disabled como marcador de posición (ya manejado dentro de page()).

Cierre

  • front-matter.html, closing.html (con/sin bibliografía recomendada, acordar con el usuario antes), index.html como entrada principal (enlace a todos los capítulos).
  • Empaquetar con python3 -m zipfile -c bilingual_reading.zip *.html, entregar el zip.

Ramas y manejo de excepciones

Condición de activaciónMétodo de manejo
Imagen es jpx / RGBA / modo Pextract_assets.py convierte uniformemente a RGB con convert() y luego guarda como JPEG
F-string contiene llaves de bloque de código (dict JSON)No escribir dentro del f-string; extraer como CODE_X = '''...''' y concatenar con + CODE_X
{<P( escrito por errorCorregir con sed 's/{<P(/{P(/g'
Agregar } en lote accidentalmente al final de líneas page()fix_braces.py ya lo evita; si ocurre, eliminar manualmente el } extra al final de esa línea
El usuario solicita "ver el resultado antes de continuar"Solo hacer el capítulo de muestra, pausar y esperar retroalimentación
El usuario solicita "no traducir el código"Todos los <pre><code> permanecen en inglés original (por defecto así)
Más elementos de depuraciónVer references/troubleshooting.md

Índice de recursos

  • scripts/book_theme.py — Módulo compartido principal: CSS/JS/esqueleto de página + funciones P, LI, CODE, INLINE, H, img_b64, page_mark, page. Los cambios de estilo solo se hacen aquí.
  • scripts/extract_assets.py — Pasos ③④: extraer imágenes, comprimir, convertir a base64, escribir en assets/.
  • scripts/fix_braces.py — Paso ⑦: agregar llaves de f-string en lote.
  • references/style-guide.md — Detalles de estilo e interacción (colores, diseño, componentes, comparación de aceptación).
  • references/troubleshooting.md — Tabla de resolución de problemas y experiencia reutilizable.

Lista de verificación de aceptación

  • El estilo del capítulo de muestra fue aprobado por el usuario (fondo azul claro para chino, elementos de lista en chino con la misma especificación, marca de página presente)
  • El texto original está traducido párrafo por párrafo, los bloques de código no están traducidos, las imágenes están incrustadas en base64 y se pueden abrir sin conexión
  • Cada capítulo HTML se puede abrir de forma independiente, el índice se puede plegar, los saltos de ancla funcionan correctamente
  • El botón 🌐 alterna entre tres estados, se mantiene entre páginas (localStorage)
  • Los enlaces entre capítulos están correctamente encadenados, los botones del primer y último capítulo están desactivados
  • Todos los archivos en UTF-8, nombres de archivo en minúsculas con guiones, empaquetado en zip para entrega

Skills relacionados