Liste marcadores PDF con páginas y niveles
Convierta el árbol de esquema de un PDF en una lista de marcadores limpia y ordenada, fácil de revisar, probar, exportar o incorporar a otro flujo de trabajo.
Ejecutar — gratis
Corre en su navegador. Gratis y sin límite: sus datos no salen de esta página.
Cada elemento incluye el título, su nivel de anidamiento basado en uno y la página de destino, también basada en uno. El recorrido conserva el orden del esquema y coloca cada elemento hijo justo después de su padre. Los esquemas vacíos se rechazan expresamente, por lo que una tabla de contenido ausente no puede confundirse con un resultado correcto sin datos.
Convierta un esquema anidado en filas prácticas
Los marcadores PDF suelen representarse como un árbol de esquema. Los capítulos ocupan el primer nivel, las secciones aparecen debajo y los encabezados más profundos pueden continuar varios niveles. Esa estructura resulta útil en un visor, pero es incómoda para auditar la navegación, crear un informe, comparar ediciones o enviar datos a una hoja de cálculo. Esta capacidad recorre el árbol en preorden: emite primero el padre, después todos sus descendientes en su orden original y, por último, pasa al siguiente hermano. Cada fila contiene la información necesaria para inventariar un marcador: título, nivel y página de destino. Los niveles empiezan en uno, al igual que las páginas. La lista mantiene el orden de lectura visible sin conservar el anidamiento recursivo. La capacidad no abre ni modifica el PDF; recibe el árbol ya obtenido por un analizador o por un paso anterior de procesamiento.
Comprenda la validación y el orden determinista
Cada marcador debe ser un objeto con un título no vacío y una página que sea un entero positivo. El campo opcional de elementos hijos debe ser un arreglo de marcadores. Se elimina el espacio sobrante al principio y al final del título, pero el contenido interior se conserva. El algoritmo nunca ordena alfabéticamente ni por página, porque hacerlo podría destruir la intención del autor. Sigue la secuencia entregada y calcula el nivel a partir de la profundidad. Una misma entrada siempre produce la misma salida, sin red, marcas de tiempo, identificadores aleatorios ni diferencias ambientales. Un esquema superior vacío genera un error de entrada no válida. Así, un proceso automático puede detenerse si el documento carece de marcadores, en lugar de publicar un índice vacío que parezca correcto. También se rechazan hijos mal formados, títulos ausentes, páginas no válidas, profundidad excesiva, ciclos y árboles desmesurados.
Use la lista en flujos documentales
Una lista plana de marcadores sirve como frontera clara entre el análisis del PDF y la lógica posterior. Puede mostrarla como tabla de contenido, comprobar que estén todos los capítulos esperados, comparar títulos y destinos entre versiones o asociar páginas con secciones para extraer contenido. La respuesta aporta el total y los registros ordenados, por lo que un sistema sencillo puede validar la cantidad antes de procesar cada elemento. El nivel permite reconstruir la sangría o incluso volver a formar un árbol, mientras que la página facilita la navegación y el cálculo de intervalos. Tenga presente que la capacidad informa sobre el esquema recibido: no comprueba que las páginas existan en un PDF concreto, no deduce encabezados del texto ni repara destinos rotos. Valide los límites con el número de páginas cuando el analizador de origen lo proporcione. Puede ejecutarla en el navegador y automatizarla por $0.002 mediante API; ambos canales usan la misma implementación.
Qué puede hacer con ella
Audite la navegación documental
Revise cada marcador en su orden visible y detecte capítulos ausentes, niveles inesperados o destinos incorrectos antes de publicar.
Cree una tabla de contenido
Transforme la salida del analizador en filas que puedan sangrarse por nivel y enlazarse con sus páginas de destino.
Compare ediciones de un PDF
Genere inventarios estables de dos versiones y compare títulos, jerarquía, orden y páginas de destino.
Preguntas frecuentes
¿Esta capacidad lee directamente el archivo PDF?
No. Recibe un árbol de esquema generado por un analizador PDF y lo convierte en registros de marcadores.
¿Qué orden utiliza el resultado?
Utiliza un recorrido en preorden: cada padre aparece antes que sus hijos y los hermanos conservan el orden documental recibido.
¿Cómo se numeran los niveles?
Los marcadores superiores tienen nivel 1, sus hijos nivel 2 y cada grado adicional aumenta el nivel en uno.
¿Qué sucede si el esquema está vacío?
La solicitud falla con un error de entrada no válida para no confundir la ausencia de marcadores con un informe vacío correcto.
¿Comprueba si existen las páginas de destino?
Exige que cada destino sea un entero positivo, pero no puede compararlo con el total de páginas sin una validación separada.
¿Cuánto cuesta una solicitud por API?
Cada solicitud por API cuesta $0.002. También puede ejecutar gratis la misma lógica determinista en el navegador.
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/bookmarks-list \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"outline":[{"title":"Introduction","page":1,"children":[{"title":"Background","page":3}]},{"title":"Methods","page":8}]}'const res = await fetch("https://api.kit.forhosting.com/pdf/bookmarks-list", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"outline": [
{
"title": "Introduction",
"page": 1,
"children": [
{
"title": "Background",
"page": 3
}
]
},
{
"title": "Methods",
"page": 8
}
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/pdf/bookmarks-list",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"outline": [
{
"title": "Introduction",
"page": 1,
"children": [
{
"title": "Background",
"page": 3
}
]
},
{
"title": "Methods",
"page": 8
}
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/pdf/bookmarks-list", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"outline":[{"title":"Introduction","page":1,"children":[{"title":"Background","page":3}]},{"title":"Methods","page":8}]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"outline":[{"title":"Introduction","page":1,"children":[{"title":"Background","page":3}]},{"title":"Methods","page":8}]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/pdf/bookmarks-list", 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",
"page": 1,
"children": [
{
"title": "Background",
"page": 3
}
]
},
{
"title": "Methods",
"page": 8
}
]
}Ejemplo de respuesta
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "pdf.bookmarks_list",
"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. |