2 Punkte von GN⁺ 2025-02-11 | 1 Kommentare | Auf WhatsApp teilen
  • PDFSyntax ist eine Python-Bibliothek mit Fokus auf Kapitel 7 „Syntax“ der PDF Specification. Sie dient dazu, die interne Dokumentstruktur von PDF-Dateien bis auf Byte-Ebene zu untersuchen und zu verändern
  • Von Grund auf in reinem Python geschrieben, ist sie eine leichtgewichtige Bibliothek ohne Abhängigkeiten und legt Wert auf Einfachheit und Unveränderlichkeit
  • Die grundlegende Bearbeitungsmethode sind von der PDF-Spezifikation erlaubte nicht-destruktive inkrementelle Updates: Änderungssektionen werden ans Ende der Originaldatei angehängt; ein Zurückrollen oder Zusammenführen zu einer einzelnen Revision ist möglich
  • Das CLI bietet unter anderem overview, disasm, text, fonts und browse; browse gibt den PDF-Quelltext übersichtlich aus und ermöglicht das Erkunden der internen Struktur als statisches HTML mit Hyperlinks
  • Derzeit ist es ein Projekt in Arbeit mit Beta-Qualität; die API kann sich jederzeit ändern. Es steht unter der MIT-Lizenz, nimmt aber noch keine externen Beiträge an

Untersuchung und Umwandlung der internen PDF-Struktur

  • PDFSyntax ist eine Python-Bibliothek zur Untersuchung und Umwandlung der internen Struktur von PDF-Dateien
  • Der Fokus liegt auf Kapitel 7 „Syntax“ der Portable Document Format (PDF) Specification
  • Die Verwaltung der Dokumentstruktur ist bis auf Byte-Ebene implementiert und wird unter anderem für Folgendes genutzt:
    • Zugriff auf Metadaten
    • Drehen von Seiten
    • Lesen und Schreiben von PDFs
    • Zugriff auf und Manipulation von internen Objekten

Designrichtung

  • Interne Funktionen werden als API-Toolkit für Lese- und Schreiboperationen an PDFs bereitgestellt
  • Einige Funktionen stehen auch als CLI zur Nutzung im Terminal oder Browser zur Verfügung
  • Die Bibliothek ist in reinem Python geschrieben und hat keine externen Abhängigkeiten
  • Sie legt Wert auf Einfachheit und Unveränderlichkeit
  • Die Standardmethode zur Bearbeitung sind inkrementelle Updates, bei denen das Original nicht direkt überschrieben wird, sondern Änderungen ans Ende der Originaldatei angehängt werden
    • Revisionen können bei Bedarf zurückgerollt werden
    • Alle Revisionen können auch zu einer einzigen zusammengeführt werden

Installation und CLI-Nutzung

  • Installation über PyPI möglich
pip install pdfsyntax
  • Die grundlegende Nutzungsform des CLI lautet:
pdfsyntax COMMAND FILE
  • Bei Installation aus dem Quellcode kann es in der längeren Form ausgeführt werden:
python3 -m pdfsyntax COMMAND FILE
  • Die wichtigsten Befehle für eine schnelle PDF-Analyse sind:
    • overview: Gibt Textinformationen zu Struktur und Metadaten aus
    • disasm: Gibt einen Dump der Dateistruktur im Terminal aus
    • text: Gibt extrahierten Text aus, der die räumliche Anordnung wie bei einem Scan beibehält
    • fonts: Gibt die Liste der verwendeten Schriftarten aus
    • browse: Gibt den PDF-Quelltext übersichtlich aus und erzeugt statisches HTML mit Hyperlinks, um die interne Struktur zu erkunden

API-Nutzung

  • PDFSyntax besteht größtenteils aus einfachen Funktionen
  • Mit readfile kann ein PDF gelesen werden, und mit metadata lassen sich die Metadaten als Python-dict abrufen
>>> from pdfsyntax import readfile, metadata
>>> doc = readfile("samples/simple_text_string.pdf")
>>> metadata(doc)
  • Das Doc-Objekt ist praktisch die einzige dedizierte Klasse, die den internen Zustand eines Dokuments speichert
    • Aus der Originaldatei gecachte oder memoized Inhalte
    • Änderungen durch Hinzufügen, Bearbeiten und Löschen von Inhalten
    • Änderungsverlauf, der über inkrementelle Updates nachverfolgt wird
  • Dieselbe Funktion metadata kann auch als Methode des Doc-Objekts verwendet werden
>>> doc.metadata()
  • Mit Low-Level-Funktionen wie get_object und update_object kann direkt auf interne Objekte des Dokuments zugegriffen und diese manipuliert werden
  • Außerdem werden High-Level-Funktionen wie rotate angeboten
>>> from pdfsyntax import rotate, writefile
>>> doc180 = rotate(doc, 180)
  • Im Rotationsbeispiel wird das Originalobjekt nicht verändert; stattdessen wird ein neues Objekt erstellt, das die laufende Richtungsänderung enthält
  • Das geänderte PDF kann mit writefile auf die Festplatte geschrieben werden
>>> writefile(doc180, "rotated_doc.pdf")
  • Die Ergebnisdatei hat die Form, dass hinter den Originalinhalten eine neue Sektion angehängt ist; schneidet man diese Sektion ab, lassen sich die Änderungen rückgängig machen

Aktueller Status und Beitragspolitik

  • Das Projekt ist in Arbeit und Software in Beta-Qualität
  • Die API kann sich jederzeit ändern
  • Die Aufgabenliste umfasst unter anderem:
    • Zuschneiden und Zusammenfügen von Seiten
    • Verlustfreie Kompression
    • Mehr Filter
    • Verbesserte Textextraktion
    • Erweiterung der Textextraktion durch Layout-Erkennung
  • PDFSyntax steht unter der MIT-Lizenz
  • Derzeit werden keine externen Beiträge angenommen
    • Es handelt sich um ein persönliches Projekt, und die verfügbare Zeit ist begrenzt
    • Zunächst liegt der Fokus auf neuen Funktionen und dem Refactoring-Roadmap; Beiträge sollen angenommen werden, sobald das Projekt stabilisiert ist

1 Kommentare

 
GN⁺ 2025-02-11
Meinungen auf Hacker News
  • Vor langer Zeit war ich einmal damit betraut, Daten aus verschiedenen PDFs zu extrahieren, und habe ein Tool gebaut, das die Platzierung von Zeichen auf der Seite sowie die Bounding Boxes aller Elemente visualisierte.
    Am Ende scheiterte das Projekt komplett, und einige Leute waren verärgert, weil es nicht die erwarteten Ergebnisse lieferte.
    Heute würde ich zu 100 % darauf setzen, die LLM-Fähigkeiten zur Datenextraktion aus PDFs zu nutzen. Damals gab es diese Option nicht.

    • Daten aus beliebigen PDFs zu parsen, ist fast eine verfluchte Aufgabe. Da PDFs auch Bilder enthalten können, ist es in etwa so, als würde man direkt JPEGs als Ziel nehmen.
      Je nach Erwartung kommt man mit OCR ziemlich weit, aber meiner Erfahrung nach reicht es immer knapp nicht für genau das, was man braucht.
    • LLMs können helfen, die Reihenfolge der aus einer Seite extrahierten Zeichen zu rekonstruieren, aber an die eigentlichen Inhalte zu kommen, bleibt schwierig.
      Ich habe mehrfach Fälle gesehen, in denen Textzeichen als Glyphen einer Custom Font ohne ASCII-ähnliches Mapping vorlagen oder, wie besonders häufig bei CAD-Ausgaben, Buchstabenformen aus Linien gezeichnet wurden.
      Dann gibt es keinen identifizierbaren Text zum Extrahieren, sodass man die Seite letztlich wieder per OCR prüfen muss.
    • In einem früheren Job hatte ich mit etwas Ähnlichem zu tun; regelbasiertes Parsing ist wirklich schwer sauber hinzubekommen und scheitert oft an Edge Cases.
      Wir bauen bei https://runtrellis.com/ eine PDF-Verarbeitungspipeline auf Basis von LLMs und Vision-Language-Modellen von Grund auf und haben selbst bei schwierigen PDFs eine Genauigkeit nahe 100 % gesehen.
      Der Kern ist, regelbasierte Engines zusammen mit Referenzdaten zu verwenden, um die Ergebnisse gegenzuprüfen.
    • Vor langer Zeit habe ich einmal 2D-CAD-Zeichnungen aus PDFs extrahiert und in vollständiges 3D umgewandelt; das hat ziemlich Spaß gemacht.
    • pdfjs erledigt all diese Arbeit und ist ziemlich robust. Ich habe es kürzlich genutzt, um Tabellendaten aus zehn Jahren Bankauszügen zu extrahieren.
  • Ziemlich cool. In meinem früheren Job hätte ich das wohl viel benutzt.
    Ideal wäre es, wenn man wie bei https://lapo.it/asn1js/ eine Datei hineinziehen könnte und die gesamte Verarbeitung lokal passiert.

  • Dank des „Privilegs“, Code zur Datenextraktion aus PDFs betreuen zu dürfen, habe ich eine Weile die kostenlose Version von iText RUPS zum PDF-Debugging verwendet.
    Die Inspektionsfunktionen hier sehen etwas mächtiger aus, also dürfte das sehr nützlich sein. Ich werde es ausprobieren.

  • Ich erinnere mich an ein ähnliches Projekt auf GitHub. Damit konnte man beliebige Binärdaten anhand eines vorgegebenen Schemas visualisieren, und ich meine, es gab ein TCP/IP-Beispiel.

    • Vielleicht https://kaitai.io/?
      Für diese Aufgabe sah es sehr gut aus, aber im letzten Projekt brauchten wir auch Serialisierung, deshalb haben wir es nicht verwendet.
    • HexFiend hat ebenfalls eine Template-Syntax zur Visualisierung von Binärdaten. Sie basiert auf Tcl.
      https://github.com/HexFiend/HexFiend/blob/master/templates/T...
    • Mit „beliebig“ sollte man in diesem Kontext vorsichtig sein.
      Interessanterweise verwende ich PDF als „Hello World“, wenn ich solche Dateiformat-Deskriptoren teste, weil die PDF-Spezifikation so absonderlich ist.
      Wenn eine Beschreibungssprache das Layout von PDF korrekt ausdrücken kann, ist sie definitiv gut entworfen.
      Bisher hatte ich wenig Glück mit allem, was nicht aus dem deklarativen Modus ausbrechen und „als Nächstes diesen Code ausführen“ kann.
  • Das dürfte auch für Forensik und die Suche nach Wasserzeichen praktisch sein.

    • Sieht interessant aus. Ich kenne mich damit nicht gut aus: Wie könnte man das zur Wasserzeichenerkennung verwenden? Könnte man auf dieselbe Weise auch Signaturen erkennen?
  • Sieht gut aus.
    Noch besser wäre es, wenn jedes Byte des PDFs angezeigt würde. endobj und xref scheinen nicht sichtbar zu sein.

    • Stimmt, das werde ich bald beheben.
  • Es wäre wirklich großartig, wenn das als Browser-Bibliothek verfügbar wäre. Man könnte einfach Dateien per Drag-and-drop hineinziehen und sich das Innenleben ansehen. Trotzdem beeindruckend.

    • Meinst du eine Browser-Erweiterung? Ich will nicht unhöflich sein, nur sicherstellen, dass ich dich richtig verstehe.
  • Gut gemacht. Ein sehr nützliches Sicherheits-Preview-Tool. PDFs sind ein Ärgernis.

  • Ich frage mich, ob das UI-Tool für die Visualisierung eine Bibliothek ist.
    Mir gefällt das UI-Format wirklich gut; ich würde es gern auch zum Zerlegen und Debuggen von Video-Bytestreams verwenden.
    Edit: Tatsächlich ist es ziemlich simpel. Guter Einsatz von CSS! https://github.com/desgeeko/pdfsyntax/blob/main/docs/simple_...

    • Genau. Mir ist Einfachheit wichtig, und die Interaktion, die einfaches HTML und CSS bieten, reicht für meinen Anwendungsfall aus :)
  • In einem ähnlichen Zusammenhang: Warum ist PDF eigentlich noch nicht ersetzt worden? Es gibt XPS, DjVu und XHTML (EPUB), aber sie scheinen alle auf unterschiedliche Use Cases zu zielen, etwa verpackte HTML-Dateien.
    Was ich möchte, ist ein einfaches Dokumentformat, das andere Dateien und Metadaten einbetten kann, ohne Adobes Schwerfälligkeit.
    Es sollte Hyperlinks innerhalb der Seite erlauben, Text sollte bei geänderter Schriftgröße nicht überlaufen, und es sollte konsistent druckbar sein.

    • Ich glaube nicht, dass PDF wegen Adobes Schuld oder Schwerfälligkeit ein „unglückliches“ Format für Bearbeitung, Lesen auf Geräten oder das Extrahieren semantischer statt darstellungsbezogener Informationen geworden ist.
      PDF ist kein Datenformat, sondern ein Seitenbeschreibungsformat; alle Entscheidungen ergeben sich aus der Notwendigkeit, dieselbe „Seite“ drucken zu können, selbst bei unterschiedlichen Betriebssystemen, Software, Druckern und exakten Papiergrößen.
      Der Hauptgrund, warum PDF so lange überlebt, ist vermutlich, dass vieles auf dem Dokumentparadigma beruht, also darauf, ein „Dokument“ als „Bündel mehrerer Papierseiten“ zu verstehen.
      Von der Zusammenfassung nach einem Arztbesuch bis zu Fahrzeugzulassungsdokumenten gibt es bereits eine bestimmte visuelle Darstellung, die so gewählt ist, dass sie auf Papier plausibel wirkt und exakt passt.
      HTML, etwa als eigenständig lauffähiges Format mit Bildern und CSS als Data-URLs, oder ePub könnten in den meisten Hinsichten besser sein.
      Aber die Ziele sind so unterschiedlich, dass man von Leuten, die heute PDFs erstellen, bei einem solchen Umstieg wohl Beschwerden hören würde, dass Inhalte je nach Gerät etwas anders aussehen und je nach Einstellungen sogar die Seitenumbrüche variieren.
      In diesem Zusammenhang ist interessant, dass selbst Google Docs standardmäßig im Seitenmodus startet und nicht im „seitenlosen“ Modus, obwohl vermutlich deutlich weniger als die Hälfte der Dokumente gedruckt oder in PDF umgewandelt werden.
      Der „seitenlose“ Modus ist deutlich nützlicher: Er passt sich wie eine normale Webseite an das Fenster an und scrollt endlos über eine zusammenhängende Fläche.
    • Unterschiedliche Use Cases.
      An der Anforderung, dass „Text nicht überläuft“, hängen viele Details.
      In PDF kann jeder Buchstabe, jedes Zeichen und jede Glyphe eines Textes eine exakte x,y-Position auf der Seite haben, manchmal sogar außerhalb der Seite.
      Dadurch kann Inhalt präzise platziert werden, egal was sich darum herum befindet. Die Anwendung, die PDF erzeugt, muss die Elemente korrekt positionieren und Zeilenumbrüche für Buchstaben oder Wörter implementieren.
      XPS kam einer Neuimplementierung von PDF am nächsten, aber Microsoft bekam nicht genug Unterstützung von anderen Akteuren und es verschwand stillschweigend.
    • Ein interessanter Punkt an PDF, den ich bis vor Kurzem nicht kannte: PDF ist eine Teilmenge von PostScript, und das ist in gewissem Maß der Grund für seine Schwere.
      PostScript ist zwar eigenartig, aber eine vollständige Programmiersprache; PDF ist das nicht, also nicht Turing-vollständig.
      PDF unterstützt keinen Kontrollfluss, sodass etwas, das man in PostScript als einfache Schleife ausdrücken könnte, in PDF aufgefaltet und als Reihe einfacher Deklarationen oder Ausdrücke gespeichert werden muss.
      Der Vorteil ist, dass man zum Rendern von PDF keinen vollständigen Programminterpreter braucht.
    • Sobald so ein Gespräch beginnt, taucht die LaTeX-Fraktion auf, und alle, die sinnvoll etwas zum Standard beitragen könnten, bleiben in dieser Diskussion stecken.
    • Ein Grund ist, dass keines der anderen Formate in unveränderter Form für kommerziellen Druck geeignet ist.