EPUB-Kapitelstruktur aus PDF-Lesezeichen
Ein brauchbares EPUB benötigt eine klare Lesereihenfolge, doch ein PDF bildet diese häufig nur in seiner Lesezeichenstruktur ab.
Im Browser ausführen – kostenlos
Diese Funktion übernimmt eine extrahierte PDF-Lesezeichenliste und macht aus jedem Lesezeichen der obersten Ebene einen EPUB-Kapiteldatensatz. Reihenfolge und Titel bleiben erhalten, stabile XHTML-Dateinamen werden vergeben und vorhandene Zielseiten übernommen. Verschachtelte Lesezeichen bleiben Abschnittsinformationen und werden nicht versehentlich zu eigenständigen Kapiteln. Enthält die Quelle keine Lesezeichen der obersten Ebene, wird die Anfrage eindeutig abgelehnt, anstatt eine im Dokument nicht vorhandene Struktur zu erfinden.
Bereiten Sie die Lesezeichenstruktur vor
Verwenden Sie die von einem PDF-Parser oder Prüfwerkzeug ausgegebene Lesezeichenstruktur und nicht optisch hervorgehobene Überschriften aus dem Seiteninhalt. Übermitteln Sie die Datensätze in der ursprünglichen Lesereihenfolge. Jeder benötigt einen Titel und eine numerische Ebene; Ebene 1 bezeichnet ein oberstes Lesezeichen. Eine ab 1 gezählte Zielseite ist optional. Datensätze ab Ebene 2 können Unterabschnitte, Anhänge, Abbildungen oder andere verschachtelte Ziele beschreiben. Sie werden geprüft, damit fehlerhafte Strukturdaten nicht unbemerkt bleiben, aber nicht zu EPUB-Kapiteln hochgestuft. Äußere Leerzeichen in Titeln werden entfernt, während Schreibweise, Zeichensetzung, Großschreibung und innere Abstände erhalten bleiben. Seitenwerte müssen positive ganze Zahlen sein. Diese explizite Darstellung vermeidet Vermutungen anhand von Einrückung oder Typografie, liefert systemübergreifend wiederholbare Ergebnisse und trennt die PDF-Extraktion sauber von der Publikationsplanung.
Verstehen Sie die erzeugte Kapitelliste
Die Ausgabe enthält die Kapitelanzahl und ein geordnetes Kapitelarray. Jedes Kapitel erhält einen ab 1 gezählten Index, den bereinigten Titel des zugehörigen obersten Lesezeichens und einen stabilen Namen wie chapter-001.xhtml. Dateinamen richten sich nach der Position und nicht nach dem Titel. Satzzeichen, doppelte Titel, nichtlateinischer Text oder spätere Slug-Regeln verursachen daher keine Kollisionen. Hat ein oberstes Lesezeichen eine Zielseite, enthält das Kapitel außerdem source_page; andernfalls wird dieses optionale Feld weggelassen und nicht auf null gesetzt. Die Funktion extrahiert keinen Text, teilt kein PDF, schreibt kein XHTML und baut kein EPUB-Navigationsdokument. Sie erstellt eine saubere Zwischenstruktur, mit der nachgelagerter Code Dateien benennen, extrahierte Inhalte zuordnen, Spine-Einträge erzeugen und Navigationslinks aufbauen kann. Die Anzahl entspricht stets den Datensätzen der Ebene 1.
Behandeln Sie fehlende oder mangelhafte Strukturen
Ein PDF kann seine Seiten einwandfrei anzeigen und dennoch keine brauchbaren Lesezeichen besitzen. Ohne verlässliches Signal für oberste Kapitel liefert die Funktion einen Fehler wegen ungültiger Eingabe, statt Kapitel aus Seitenzahlen, Schriftgrößen oder Textmustern abzuleiten. Eine erfundene Liste kann plausibel wirken, Inhalte aber dem falschen Titel zuordnen oder eine beabsichtigte Hierarchie einebnen. Liegen ausschließlich Lesezeichen unterhalb der Ebene 1 vor, entsteht derselbe Fehler. Korrigieren Sie dann die vorgelagerte Extraktion oder ergänzen Sie bewusst eine Struktur. Andere fehlerhafte Datensätze führen zu positionsbezogenen Meldungen über leere Titel, ungültige Ebenen oder nichtpositive Seiten. Die Implementierung durchläuft höchstens 10,000 Datensätze einmalig, verwendet kein Netzwerk und hängt nicht von der Zeit ab. Identische Eingaben erzeugen daher identische Indizes und Namen für $0.002 pro Anfrage.
Anwendungsfälle
Eine EPUB-Konvertierung planen
Überführen Sie eine extrahierte PDF-Struktur in ein Kapitelmanifest, das eine Pipeline mit XHTML-Inhalten füllen kann.
Dokumentnavigation prüfen
Vergleichen Sie Anzahl und Reihenfolge geplanter EPUB-Kapitel vor der Veröffentlichung mit den obersten PDF-Lesezeichen.
Stabile Kapitelnamen erzeugen
Vergeben Sie kollisionsfreie positionale XHTML-Namen auch bei doppelten, interpunktierten oder nichtlateinischen Titeln.
Häufige Fragen
Was kostet die Nutzung?
Der API-Preis beträgt $0.002 pro Anfrage; dieselbe deterministische Umwandlung kann im Browser laufen.
Liest diese Funktion die PDF-Datei selbst?
Nein. Sie übernimmt eine bereits extrahierte Lesezeichenstruktur und wandelt sie in eine Kapitelliste um.
Was gilt als Kapitel?
Jedes Lesezeichen mit der Ebene 1 wird in der Reihenfolge der Eingabe zu einem Kapitel.
Was geschieht mit verschachtelten Lesezeichen?
Sie werden geprüft, aber nicht als Kapitel ausgegeben und können später als Abschnitte behandelt werden.
Was passiert ohne oberste Lesezeichen?
Die Anfrage liefert einen Fehler wegen ungültiger Eingabe, da keine Kapitelgrenzen erfunden werden.
Sind Zielseiten erforderlich?
Nein. Eine vorhandene Seite wird zu source_page; andernfalls bleibt das optionale Feld weg.
Für Entwickler — API-Zugang
Alles auf dieser Seite ist auch per API verfügbar. Dieser Abschnitt richtet sich an Teams, die es in ihre eigenen Systeme einbinden möchten; alle anderen nutzen einfach das Tool oben.
Endpunkt
Authentifizierung per Bearer-Token. Ein einziger POST stellt die Aufgabe in die Warteschlange; das Ergebnis erhalten Sie per Webhook oder über einen signierten Link.
Aufruf aus Ihrem 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)Beispiel-Anfrage
{
"outline": [
{
"title": "Introduction",
"level": 1,
"page": 1
},
{
"title": "Background",
"level": 2,
"page": 3
},
{
"title": "Methods",
"level": 1,
"page": 12
}
]
}Beispiel-Antwort
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "pdf.to_epub_structure",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}Die API arbeitet asynchron: Sie erhalten sofort eine task_id. Polling ist mit 1 Anfrage pro Sekunde erlaubt.
Preis
Der Preis steht auf der Seite – keine Tokens, keine Credits. Fehlgeschlagene Aufgaben werden nicht berechnet.
Limits
max_mb | 25 |
max_pages | 200 |
Fehler
| HTTP | Code | Bedeutung |
|---|---|---|
401 | unauthorized | Der API-Schlüssel fehlt oder ist ungültig – prüfen Sie den Authorization-Header (Bearer). |
402 | insufficient_balance | Ihr Guthaben reicht für diese Aufgabe nicht aus – Aufladungen verfallen nicht. |
404 | unknown_type | Unbekannter Aufgabentyp – prüfen Sie das Feld „type“ gegen den Katalog. |
429 | rate_limited | Zu viele Anfragen – warten Sie kurz; Polling ist mit 1 Anfrage pro Sekunde erlaubt. |