Bindery und Dokumente ohne Gluecode

Bindery verwandelt Office-Formate in eine einzige Rust-Engine mit Erkennung, normalisierten APIs, DocQL und weniger kleinen Format-Königreichen, die zu...

Bindery und Dokumente ohne Gluecode

The file was not the problem

The first mistake is thinking the document is the file. It arrives as a file, yes. It has a name, usually with an extension that looks reassuring. The procurement spreadsheet says .xlsx, the report says .docx, the archive dump says .pdf, and everyone pretends the world has become simple because the last four characters look familiar. Lovely. Then the extension lies, the workbook has hidden sheets, the slide deck contains embedded objects, the PDF is mostly text but not quite, and the old Word file still smells faintly of 2003.

Most teams do not build a document pipeline. They build a small museum of format exceptions. One library for Word, another for Excel, something else for PDFs, a heroic shell script for the archive folder, a Python package that was last updated when everyone still thought QR codes were exciting, and a few regular expressions that should be taken outside and given a quiet retirement. Six months later the glue layer is larger than the product. This is not a rare failure mode. This is the normal shape of document work when every format gets its own kingdom.

Bindery exists because the document layer should not become the main project. At the implementation level it isa Rust crate named dweve-bindery. The public page describes one crate with 17 formats, DocQL, Python bindings, and a common engine. The important part is that high-level APIs like Document, Presentation, and Workbook sit over format-specific modules for OLE2, OOXML, ODF, iWork, RTF, PDF, Markdown, EPUB, LaTeX, images, formulas, and DocQL. That list is not there to impress anyone. It is there because real corpora are rude.

The useful claim is simple: open the document through one engine, normalize what can be normalized, and keep the format-specific pain below a shared surface. That does not make every format identical. It makes the differences explicit enough that a pipeline can survive them.

Bindery starts by distrusting the extension. Detection, parsing, normalization, querying, and writing are separate jobs, which is exactly why the glue does not have to leak everywhere.

Detection is not a decoration

Format detection sounds like a small utility until it fails. Then it becomes the whole incident. Extensions are metadata supplied by the person, tool, mail gateway, export job, migration script, or tired intern that last touched the file. Sometimes they are right. Sometimes they are a polite suggestion. A serious document engine should inspect magic bytes, container structure, package parts, streams, and internal cues before deciding which reader owns the file.

Bindery treats that as the front door. The README and page both describe automatic format detection. The library documentation shows Document::open and Presentation::open as the normal path, not a choose-your-parser ceremony. That matters because users do not want a training course in document archaeology before they can extract a table. They want the engine to pick the path and then give them a stable API.

There is a dry little lesson here. The less glamour a component has, the more damage it can do when people wave it away. Detection is notglamorous. Neither is encoding conversion, ZIP handling, OLE directory walking, relationship resolution, Snappy decompression, or XML namespace handling. Fine. The boring work is exactly where production pipelines either become reliable or begin collecting lucky charms.

One model does not mean one lie

Eine einheitliche API kann gefährlich werden, wenn sie so tut, als wären Unterschiede verschwunden. Bindery sollte nicht behaupten, dass ein PDF, eine Tabellenkalkulation, ein iWork-Archiv und ein OOXML-Paket dasselbe Tier in verschiedenen Verkleidungen sind. Das sind sie nicht. Die sinnvolle Architektur besteht nicht darin, Wahrheit zu Brei zu verflachen. Sie besteht darin, gemeinsame Operationen dort anzubieten, wo sie gemeinsam sind, und Fähigkeitsgrenzen dort sichtbar zu halten, wo sie es nicht sind.

Das Quell-Layout zeigt diese Trennung. Es gibt eine einheitliche Word-Dokument-API, eine einheitliche Präsentations-API, Tabellenkalkulations-Traits, Formelauswertung hinter Features, DocQL-Konnektoren und Module auf niedrigerer Ebene für die Formate selbst. Die öffentliche Format-Matrix besagt, dass OOXML und ODF erstklassige Oberflächen für Lesen, Schreiben und Abfragen sind. PDF und RTF sind leseintensiv und beim Schreiben vorsichtiger. EPUB, LaTeX und Markdown sind Ausgabeformate. Legacy Office und iWork haben ihre eigene interne Mechanik. Das ist die richtige Haltung. Eine Engine, ja. Eine Fantasie, nein.

Diese Unterscheidung ist bei Audits und Datenprodukten wichtig. Wenn ein Compliance-Workflow Klauseln aus Verträgen extrahiert, muss er wissen, ob ein Wert aus einem Absatz, einer Tabellenzelle, einer Foliennotiz, einer Formel oder einem PDF-Textlauf stammt. Wenn ein Aufnahme-Job die Abrufung speist, muss er wissen, ob Bilder, Kommentare, Metadaten und Beziehungen erhalten, ignoriert oder als nicht unterstützt markiert wurden. Die Antwort darf nicht in einer parserspezifischen Fußnote vergraben sein, denn diese Fußnote taucht nicht auf, wenn jemand fragt, warum sich das Ergebnis geändert hat.

Eine gemeinsame Engine braucht dennoch eine Fähigkeitsmatrix. Das ehrliche Versprechen ist nicht, dass sich jedes Format gleich verhält. Es ist, dass jedes Versprechen benannt und testbar ist.

Dokumente sind strukturierte Daten, die vergessen haben, es zuzugeben

Das Schlimmste, was eine Dokument-Pipeline tun kann, ist, zu früh alles auf Text zu reduzieren. Text ist nützlich. Text ist nicht das ganze Dokument. Eine Tabellenkalkulation hat Formeln, Referenzen, Blätter, Zeilen, Zellen, Zahlenformate, Kommentare und Arbeitsmappenstruktur. Eine Präsentation hat Folien, Formen, Bilder, Notizen, Reihenfolge und manchmal eine Unternehmensvorlage, die drei Fusionen und ein Rebranding durch pure Boshaftigkeit überlebt hat. Ein Word-Dokument hat Absätze, Läufe, Tabellen, Kopf- und Fußzeilen, Stile, Beziehungen und eingebettete Objekte. Ein PDF hat Ströme und Layout-Entscheidungen, die möglicherweise nicht der Lesereihenfolge entsprechen. All das in einen einzigen flachen String zu verwandeln, ist schnell, beruhigend und oft falsch.

Die High-Level-APIs von Bindery sind nützlich, weil sie die Dokumentstruktur lange genug am Leben halten, um bessere Fragen zu stellen. Die Dokument-API stellt Absätze, Läufe, Tabellen, Zeilen und Zellen bereit. Das Tabellenkalkulationsmodul stellt Arbeitsmappen- und Arbeitsblatt-Traits bereit. Die Formel-Engine deckt eine große Excel-kompatible Funktionsoberfläche ab. DocQL fügt eine SQL-ähnliche Abfragesprache über das Dokumentmodell hinzu, mit Lexer, Parser, Validator, Planer, Ausführer, Konnektoren, Werten und Funktionen im Quellbaum. Das ist mehr als ein Komfort-Wrapper. Es ist eine Möglichkeit, aufzuhören, dieselbe Extraktionslogik für jedes Format neu zu schreiben.

Stellen Sie sich vor, Sie stellen einem Korpus eine Frage: Welche Zellen referenzieren diese Annahme, welche Tabellen enthalten eine Risikokategorie, welche Folien erwähnen eine Richtlinie, welche Dokumente haben eine benutzerdefinierte Eigenschaft und welche Formeln hängen von einer bestimmten Eingabe ab. Im Reich der Einzelformate werden daraus vier Skripte und eine Tabelle voller Entschuldigungen. In einem gemeinsamen Modell wird daraus eine Abfrageoberfläche. Immer noch Arbeit, natürlich. Software beschenkt einen selten mit einem Feiertag. Aber es ist die richtige Arbeit.

DocQL ist der Unterschied zwischen dem Abschaben von Text und dem Stellen von Fragen an Dokumente. Referenzen, Formeln, Tabellen, Formen und Metadaten gehören weiterhin zur Aufgabe.

Warum Rust ein sinnvoller Ort für dieses Durcheinander ist

Dokumentformate sind eine wunderbare Kombination aus binären Strukturen, komprimierten Paketen, XML, veralteten Kodierungen, Bilddaten, Datumssystemen, Formelsemantik und Sicherheitsbedenken. Mit anderen Worten: die Art von Arbeit, bei der vage Speicherverwaltung ein Lebensstil mit Rechnungen ist. Rust ist eine sinnvolle Basis, weil Bindery sorgfältig parsen, Puffer verwalten, Fehler laut behandeln und APIs bereitstellen muss, die den Rest des Stapels nicht raten lassen, was schiefgelaufen ist.

Die Crate-Features erzählen dieselbe Geschichte. Die Standard-Features umfassen OLE, OOXML, OOXML-Verschlüsselung und die Eval-Engine. Die volle Unterstützung aktiviert iWork, ODF, RTF, Formeln, Bildkonvertierung, Schriften und mehr. DocQL ist ein Feature mit eigener Binärdatei. Optionale Abhängigkeiten entsprechen den Formaten und Oberflächen, die sie unterstützen: ZIP-Verarbeitung, schnelles XML-Parsen, Kodierungskonvertierung, Snappy, protobuf, Bilddekodierung, Statistik und komplexe Zahlen für die Formelarbeit und so weiter. Das ist kein einziger Riesenklumpen, der so tut, als gehöre jede Abhängigkeit überall hin. Feature-Flags halten die Form der Dokument-Engine sichtbar.

Das ist für die Einbettung wichtig. Ein Wissenssystem möchte vielleicht die volle Office- und Abfrageoberfläche. Ein kleiner Dienst möchte vielleicht nur OOXML und Textextraktion. Ein Python-Workflow möchte vielleicht Bindungen über dieselbe Engine. Ein Befehlszeilen-Inspektionspfad kann für einmalige Abfragen und Tests nützlich sein. Die Seite spricht über Rust, PyO3 und eine CLI-Oberfläche; der Quellcode zeigt eine DocQL-Binärdatei und ein PyO3-Paket. Die wichtige Designentscheidung ist, dass diese Einstiegspunkte auf einer Engine sitzen. Sonst wird jede Integration zu ihrer eigenen leicht anderen Wahrheit, und dann tragen die Fehlerberichte verschiedene Hüte.

Die Einstiegspunkte können sich unterscheiden, ohne die Wahrheit zu verzweigen. Rust-APIs, Python-Bindungen, DocQL und der breitere Dweve-Stack sollten dieselbe Engine verwenden.

Die Wartungsgeschichte ist die Produktgeschichte

Bindery lässt sich leicht als Parser beschreiben, aber die Wartungsgeschichte ist die eigentliche Produktgeschichte. Jede neue Formatbibliothek, die zu einer Pipeline hinzugefügt wird, hat ihren eigenen Veröffentlichungsrhythmus, ihr eigenes Fehlervokabular, ihre eigenen Fehlertypen, Eigenheiten, Abhängigkeitsrisiken, Test-Fixtures und Fehlermodi. In kleinem Maßstab sieht das beherrschbar aus. Im Korpusmaßstab wird es zu einem operativen Aktenschrank, der beißt.

Eine gemeinsame Engine entfernt die Formatkomplexität nicht. Das wäre verdächtig. Sie verschiebt die Komplexität an einen Ort, an dem Tests, Fähigkeitskennzeichnungen, Features und APIs gemeinsam verwaltet werden können. Die README enthält End-to-End-Tests für Dokument-, Präsentations-, Tabellenkalkulations-, iWork- und andere Formate. Der Quellbaum enthält Module, die Formatgrenzen offensichtlich machen. Diese Struktur ermöglicht es einem Team, die Parser-Ebene zu verbessern, ohne dass jedes Produktteam neu lernen muss, was der Unterschied zwischen einem Beziehungsteil und einem zusammengesetzten Dateistrom ist.

Das ist der Grund, warum Bindery zum Rest des Dweve-Stacks passt. Reed kümmert sich um das Parsing mit Belegen. BitWeave kümmert sich um deterministischen Abruf. Fabric und Spindle kümmern sich um gesteuertes Wissen und den operativen Einsatz. Bindery sitzt vor diesen Ebenen. Es verwandelt Bürodokumente in strukturiertes Material, über das der Rest des Stacks nachdenken kann. Wenn die Eingabeebene aus Kleber und Hoffnung besteht, erbt das nachgelagerte System Kleber und Hoffnung. Sehr effizient, wenn Ihr strategisches Ziel zukünftiges Leiden ist.

Was Sie vor der Einführung fragen sollten

Die erste Frage ist nicht, ob Bindery Ihre Lieblingserweiterung unterstützt. Das ist eine Checklistenfrage, und Checklisten sind gut, aber sie reichen nicht aus. Die bessere Frage ist, welche Dokumentzusagen Sie benötigen. Brauchen Sie Nur-Lese-Extraktion, Schreibunterstützung, Round-Trip-Erhaltung, Formelauswertung, Abfragen über Formate hinweg, Metadaten, eingebettete Bilder, verschlüsseltes OOXML, Legacy-Office, iWork, ODF oder Ausgabe nach EPUB, LaTeX und Markdown? Das sind unterschiedliche Aufgaben. So zu tun, als wären sie eine Aufgabe, ist der Weg, auf dem Roadmaps zu Brei werden.

Die zweite Frage ist, wie Fehler sichtbar gemacht werden. Wenn ein Parser eine Struktur nicht erhalten kann, sagt er das dann? Wenn ein Writer nur nach bestem Bemühen arbeitet, ist das dann sichtbar? Wenn eine Formel nicht ausgewertet werden kann, kann der Aufrufer dann entscheiden, ob er blockieren, warnen oder fortfahren soll? Eine Dokument-Engine ist nicht zuverlässig, weil sie nie Nein sagt. Sie ist zuverlässig, weil ihr Nein typisiert, spezifisch und nah am Problem ist.

Die dritte Frage ist, wie Sie Ihr eigenes Korpus testen. Öffentliche Beispiele sind nützlich, aber Ihr Archiv ist wahrscheinlich seltsamer als der Beispielordner. Es enthält defekte Exporte, uralte Vorlagen, seltsame Zahlenformate, versteckte Tabellenblätter, kopierte und eingefügte Tabellen, fehlerhafte PDFs und Dateien mit dem Namen final_final_really_final. Bindery bietet eine gemeinsame Engine und testbare Oberflächen. Sie brauchen trotzdem Korpus-Tests. Leider werden die Dokumente nicht von allein erwachsen.

Die Lektion

Die Lektion von Bindery ist, dass Dokumentverarbeitung nicht Textextraktion mit zusätzlichen Schritten ist. Es ist Formerkenung, strukturelles Parsing, Fähigkeitsgrenzen, Abfrageoberflächen, Schreibpfade und Wartungsdisziplin. Der Benutzer sieht eine Datei. Das System sieht einen Container, Streams, Beziehungen, Datensätze, Stile, Formeln, Metadaten, Kodierungen und Ausgabezusagen. Eine gute Engine hält diese Komplexität unterhalb der Produktoberfläche, ohne so zu tun, als gäbe es sie nicht.

Bindery Aufgabe ist es, die Dokumentebene im guten Sinne langweilig zu machen. Eine Rust-Engine. Hochwertige APIs für Dokumente, Präsentationen und Tabellenkalkulationen. Formatmodule für die unordentlichen Teile. DocQL für gemeinsame Fragen. Python- und Stack-Integration, wo nützlich. Fähigkeitskennzeichnungen statt Format-Mythologie.

Die Datei war nie das Problem. Der Kleber war es. Bindery ist der Versuch, keine Miete mehr für diese Klebeschicht zu zahlen.