Estructura de capítulos EPUB desde marcadores PDF
Un EPUB útil necesita un orden de lectura claro, pero un PDF suele expresarlo únicamente mediante su esquema de marcadores.
Ejecutar — gratis
Esta capacidad recibe una lista extraída de marcadores PDF y convierte cada marcador de primer nivel en una entrada de capítulo EPUB. Conserva el orden y los títulos, asigna nombres XHTML estables y mantiene las páginas de destino cuando están disponibles. Los marcadores anidados permanecen como información de sección y no se convierten por error en capítulos independientes. Si el origen carece de marcadores de primer nivel, la solicitud falla claramente en vez de inventar una estructura inexistente.
Prepare el esquema de marcadores
Comience con el esquema de marcadores obtenido mediante un analizador o una herramienta de inspección de PDF, no con encabezados visuales copiados del contenido de las páginas. Envíe los registros en su orden de lectura original. Cada registro necesita un título y un nivel numérico, donde el nivel 1 identifica un marcador de primer nivel; la página de destino, numerada desde 1, es opcional. Un registro de nivel 2 o superior puede describir una subsección, un apéndice, una figura u otro destino anidado. Esos registros se validan porque los datos de esquema incorrectos no deben pasar inadvertidos, pero no se promueven a capítulos EPUB. Se eliminan los espacios de los extremos de los títulos, mientras se conservan su ortografía, puntuación, mayúsculas y espacios internos. Las páginas, si se incluyen, deben ser enteros positivos. Esta representación explícita evita deducciones basadas en sangrías o tipografía y garantiza resultados repetibles entre sistemas. Además, permite separar la extracción del PDF de la planificación editorial.
Interprete la lista de capítulos generada
La salida contiene el número de capítulos y un arreglo ordenado de capítulos. Cada capítulo recibe un índice desde 1, el título normalizado de su marcador de primer nivel y un nombre estable como chapter-001.xhtml. Los nombres se basan en la posición, no en el título, de modo que la puntuación, los títulos duplicados, los textos no latinos o futuras reglas de slug no provocan colisiones. Cuando un marcador superior incluye una página de destino, el capítulo incorpora source_page; si no se proporcionó una página, ese campo opcional se omite en lugar de establecerse como null. La capacidad no extrae texto, divide el PDF, escribe XHTML ni crea el documento de navegación EPUB. Su función es producir una estructura intermedia limpia que otro código pueda usar para nombrar archivos, asignar contenido extraído, crear entradas del lomo y construir enlaces de navegación. Como los marcadores anidados nunca se convierten en capítulos, el total siempre coincide con los registros de nivel 1.
Gestione esquemas ausentes o imperfectos
Un PDF puede mostrar sus páginas correctamente y, aun así, no contener marcadores utilizables. En ese caso no existe una señal fiable de capítulos de primer nivel, por lo que la capacidad devuelve un error de entrada no válida en lugar de inferir capítulos mediante números de página, tamaños de fuente o patrones textuales. Esta conducta es importante para la conversión automática: una lista inventada puede parecer razonable, pero vincular contenido al título incorrecto o eliminar una jerarquía intencionada. Si existe un esquema pero todos sus marcadores están por debajo del nivel 1, se devuelve el mismo error porque no puede establecerse ningún límite de capítulo superior. Corrija la extracción anterior o añada un esquema deliberado antes de reintentar. Otros registros incorrectos fallan con mensajes específicos para su ubicación, incluidos títulos vacíos, niveles no válidos y páginas no positivas. La implementación recorre una sola vez un máximo de 10,000 registros, no usa red y no depende del tiempo. Una entrada idéntica produce los mismos índices y nombres por $0.002 por solicitud.
Qué puede hacer con ella
Planificar una conversión a EPUB
Convierta un esquema PDF extraído en el manifiesto de capítulos que una canalización pueda completar con contenido XHTML.
Auditar la navegación documental
Compare el número y orden de los capítulos EPUB previstos con los marcadores superiores del PDF antes de publicar.
Crear nombres de capítulo estables
Asigne nombres XHTML posicionales sin colisiones aunque los títulos se repitan o contengan puntuación y caracteres no latinos.
Preguntas frecuentes
¿Cuánto cuesta?
El precio de la API es $0.002 por solicitud, y la misma transformación determinista puede ejecutarse en el navegador.
¿Esta capacidad lee el propio archivo PDF?
No. Recibe el esquema de marcadores ya extraído de un PDF y lo convierte en una lista de capítulos.
¿Qué se considera un capítulo?
Cada marcador cuyo nivel sea exactamente 1 se convierte en un capítulo, siguiendo el orden de entrada.
¿Qué ocurre con los marcadores anidados?
Se validan, pero no se emiten como capítulos. Después pueden gestionarse como secciones dentro de su capítulo superior.
¿Qué sucede si el PDF no tiene marcadores de primer nivel?
La solicitud devuelve un error de entrada no válida porque la capacidad no inventa límites de capítulos.
¿Son obligatorias las páginas de destino?
No. Cuando existe una página, se convierte en source_page; de lo contrario, ese campo opcional se omite.
Para desarrolladores — acceso por API
Todo lo de esta página está disponible por programación. Esta sección es para equipos que quieren integrarlo en sus sistemas; el resto puede usar la herramienta de arriba sin más.
Endpoint de API
¿Prefiere automatizarlo? Un POST autenticado crea la tarea; el resultado llega por webhook o enlace firmado. La misma capacidad también se ejecuta aquí en la web, por email y desde Telegram — y pronto también desde nuestra app.
Llámela desde su stack
curl -X POST https://api.kit.forhosting.com/pdf/to-epub-structure \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"outline":[{"title":"Introduction","level":1,"page":1},{"title":"Background","level":2,"page":3},{"title":"Methods","level":1,"page":12}]}'const res = await fetch("https://api.kit.forhosting.com/pdf/to-epub-structure", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"outline": [
{
"title": "Introduction",
"level": 1,
"page": 1
},
{
"title": "Background",
"level": 2,
"page": 3
},
{
"title": "Methods",
"level": 1,
"page": 12
}
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/pdf/to-epub-structure",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"outline": [
{
"title": "Introduction",
"level": 1,
"page": 1
},
{
"title": "Background",
"level": 2,
"page": 3
},
{
"title": "Methods",
"level": 1,
"page": 12
}
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/pdf/to-epub-structure", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"outline":[{"title":"Introduction","level":1,"page":1},{"title":"Background","level":2,"page":3},{"title":"Methods","level":1,"page":12}]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"outline":[{"title":"Introduction","level":1,"page":1},{"title":"Background","level":2,"page":3},{"title":"Methods","level":1,"page":12}]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/pdf/to-epub-structure", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Ejemplo de solicitud
{
"outline": [
{
"title": "Introduction",
"level": 1,
"page": 1
},
{
"title": "Background",
"level": 2,
"page": 3
},
{
"title": "Methods",
"level": 1,
"page": 12
}
]
}Ejemplo de respuesta
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "pdf.to_epub_structure",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}La API es asíncrona: la llamada devuelve un task_id al instante y el resultado llega por webhook. El polling está limitado a 1 req/s por tarea.
Precio
Precio publicado — sin tokens ni créditos inventados. Una tarea fallida no se cobra.
Límites
max_mb | 25 |
max_pages | 200 |
Errores
| HTTP | Código | Significado |
|---|---|---|
401 | unauthorized | API key ausente o inválida. |
402 | insufficient_balance | El saldo no cubre el precio de la tarea. |
404 | unknown_type | El tipo de tarea no existe. |
429 | rate_limited | Demasiadas peticiones. Use el webhook en vez de sondear. |