Биндъри и документи без свързващ код

Bindery превръща офис форматите в един Rust двигател с разпознаване, нормализирани API-та, DocQL и по-малко малки форматни „царства“ за поддръжка.

Биндъри и документи без свързващ код

Файлът не беше проблемът

Първата грешка е да мислиш, че документът е файлът. Той пристига като файл, да. Има име, обикновено с разширение, което изглежда успокояващо. Електронната таблица за доставки казва .xlsx, докладът казва .docx, архивният дамп казва .pdf и всички се преструват, че светът е станал прост, защото последните четири знака изглеждат познати. Прекрасно. После разширението лъже, работната книга има скрити листове, слайд декът съдържа вградени обекти, PDF файлът е предимно текст, но не съвсем, а старият Word файл все още леко мирише на 2003.

Повечето екипи не изграждат тръбопровод за документи. Те изграждат малък музей на форматни изключения. Една библиотека за Word, друга за Excel, нещо друго за PDF файлове, героичен шел скрипт за архивната папка, Python пакет, който е актуализиран за последно, когато всички все още смятаха QR кодовете за вълнуващи, и няколко регулярни израза, които трябва да бъдат изведени навън и тихо пенсионирани. Шест месеца по-късно лепилният слой е по-голям от продукта. Това не е рядък режим на отказ. Това е нормалната форма на работата с документи, когато всеки формат получава собствено кралство.

Bindery съществува, защото слоят за документи не трябва да се превръща в основния проект. На ниво имплементация това е Rust crate, наречен dweve-bindery. Публичната страница описва един crate с 17 формата, DocQL, Python обвързвания и общ двигател. Важната част е, че API на високо ниво като Document, Presentation и Workbook стоят над модули, специфични за формат, за OLE2, OOXML, ODF, iWork, RTF, PDF, Markdown, EPUB, LaTeX, изображения, формули и DocQL. Този списък не е там, за да впечатли някого. Той е там, защото реалните корпуси са груби.

Полезното твърдение е просто: отвори документа през един двигател, нормализирай каквото може да се нормализира и дръж болката, специфична за формата, под споделена повърхност. Това не прави всеки формат идентичен. То прави разликите достатъчно изрични, че тръбопроводът да може да ги преживее.

Bindery започва, като не вярва на разширението. Откриването, анализирането, нормализирането, запитването и записването са отделни задачи, което е точно причината лепилото да не трябва да изтича навсякъде.

Откриването не е декорация

Откриването на формат звучи като малка помощна програма, докато не се провали. Тогава то се превръща в целия инцидент. Разширенията са метаданни, предоставени от човека, инструмента, пощенския шлюз, експортната задача, миграционния скрипт или уморения стажант, който последно е докоснал файла. Понякога те са верни. Понякога са учтиво предложение. Сериозен документен двигател трябва да инспектира магически байтове, структура на контейнера, части на пакета, потоци и вътрешни сигнали, преди да реши кой четец притежава файла.

Bindery третира това като входна врата. README и страницата описват автоматично откриване на формат. Документацията на библиотеката показва Document::open и Presentation::open като нормалния път, а не церемония по избор на парсер. Това има значение, защото потребителите не искат курс за обучение по документна археология, преди да извлекат таблица. Те искат двигателят да избере пътя и после да им даде стабилен API.

Тук има сух малък урок. Колкото по-малко блясък има даден компонент, толкова повече щети може да причини, когато хората го отмахнат. Откриването не е бляскаво. Нито е преобразуването на кодировки, обработката на ZIP, обхождането на OLE директории, разрешаването на връзки, декомпресията на Snappy или обработката на XML именни пространства. Добре. Скучната работа е точно там, където производствените тръбопроводи или стават надеждни, или започват да събират късмети.

Един модел не означава една лъжа

Единният API може да стане опасен, когато се преструва, че разликите са изчезнали. Bindery не трябва да твърди, че PDF, електронна таблица, iWork архив и OOXML пакет са едно и също животно с различни шапки. Не са. Полезната архитектура не е да се сплеска истината в каша. Тя е да се изложат общите операции там, където са общи, и да се запазят видими границите на възможностите там, където не са.

Оформлението на изходния код показва това разделение. Има единен API за Word документи, единен API за презентации, характеристики за електронни таблици, оценка на формули зад функции, DocQL конектори и модули на по-ниско ниво за самите формати. Публичната матрица на форматите казва, че OOXML и ODF са повърхности от първа класа за четене, писане и заявки. PDF и RTF са насочени към четене и са по-внимателни при писане. EPUB, LaTeX и Markdown са изходни формати. Legacy Office и iWork имат собствена вътрешна механика. Това е правилната позиция. Един двигател, да. Една фантазия, не.

Това разграничение има значение при одити и продуктови данни. Ако работен процес за съответствие извлича клаузи от договори, той трябва да знае дали дадена стойност идва от абзац, клетка в таблица, бележка в слайд, формула или текстови ред в PDF. Ако задача за внасяне захранва извличане, тя трябва да знае дали изображения, коментари, метаданни и връзки са запазени, игнорирани или отбелязани като неподдържани. Отговорът не може да бъде заровен в бележка под линия, специфична за даден анализатор, защото тази бележка няма да се появи, когато някой попита защо резултатът се е променил.

Споделеният двигател все пак се нуждае от матрица на възможностите. Честното обещание не е, че всеки формат се държи по един и същи начин. То е, че всяко обещание е именувано и тестваемо.

Документите са структурирани данни, които са забравили да си го признаят

Най-лошото нещо, което един тръбопровод за документи може да направи, е да сведе всичко до текст твърде рано. Текстът е полезен. Текстът не е целият документ. Електронната таблица има формули, препратки, листове, редове, клетки, числови формати, коментари и структура на работната книга. Презентацията има слайдове, фигури, изображения, бележки, подредба и понякога корпоративен шаблон, който е оцелял след три сливания и едно ребрандиране чисто от злоба. Word документът има абзаци, сегменти, таблици, заглавни части, долни колонтитули, стилове, връзки и вградени обекти. PDF има потоци и решения за оформление, които може да съответстват или да не съответстват на реда на четене. Превръщането на всичко това в един плосък низ е бързо, успокояващо и често грешно.

API-тата на високо ниво на Bindery са полезни, защото запазват формата на документа жив достатъчно дълго, за да се задават по-добри въпроси. API-то за документи излага абзаци, сегменти, таблици, редове и клетки. Модулът за електронни таблици излага характеристики на работната книга и работния лист. Двигателят за формули покрива голяма повърхност от функции, съвместими с Excel. DocQL добавя език за заявки, подобен на SQL, върху модела на документа, с лексер, анализатор, валидатор, планировчик, изпълнител, конектори, стойности и функции в дървото на изходния код. Това е повече от удобна обвивка. Това е начин да спрем да пренаписваме една и съща логика за извличане за всеки формат.

Представете си един въпрос към корпуса: кои клетки препращат към това предположение, кои таблици съдържат категория на риск, кои слайдове споменават политика, кои документи имат персонализирано свойство и кои формули зависят от даден вход. В царството на отделните формати това се превръща в четири скрипта и една електронна таблица с извинения. В споделен модел това се превръща в повърхност за заявки. Пак си е работа, разбира се. Софтуерът рядко ти подарява почивка. Но това е правилната работа.

DocQL е разликата между изстъргване на текст и задаване на въпроси с форма на документ. Рефери, формули, таблици, фигури и метаданни остават част от задачата.

Защо Rust е разумно място за тази каша

Форматите на документи са чудесна комбинация от двоични структури, компресирани пакети, XML, наследени кодировки, изображения, системи за дати, семантика на формули и опасения за сигурността. С други думи, работа, при която неясното управление на паметта е начин на живот с приложени фактури. Rust е разумна основа, защото Bindery трябва да извършва внимателно разбор, да управлява буфери, да обработва грешки шумно и да излага API, които не карат останалата част от стека да гадае какво се е объркало.

Функциите на crate разказват същата история. Стандартните функции включват OLE, OOXML, криптиране на OOXML и eval двигателя. Пълната поддръжка включва iWork, ODF, RTF, формули, конвертиране на изображения, шрифтове и други. DocQL е функция със собствен двоичен файл. Независимите зависимости съответстват на форматите и повърхностите, които поддържат: обработка на ZIP, бързо XML разбор, конвертиране на кодировки, Snappy, protobuf, декодиране на изображения, статистика и комплексни числа за работа с формули и така нататък. Това не е един гигантски блок, който се преструва, че всяка зависимост принадлежи навсякъде. Флаговете за функции поддържат формата на документационния двигател видима.

Това има значение за вграждането. Система за знания може да иска пълната повърхност за офиси и заявки. Малка услуга може да иска само OOXML и извличане на текст. Python работен процес може да иска обвързвания върху същия двигател. Път за инспекция от командния ред може да е полезен за еднократни заявки и тестове. Страницата говори за Rust, PyO3 и CLI повърхност; изходният код показва DocQL двоичен файл и PyO3 пакет. Важният дизайнерски избор е, че тези входни точки стоят върху един двигател. В противен случай всяка интеграция се превръща в своя собствена малко по-различна истина и тогава докладите за грешки започват да носят различни шапки.

Входните точки могат да се различават, без да се разклонява истината. Rust API, Python обвързвания, DocQL и по-широкият Dweve стек трябва да използват същия двигател.

Историята на поддръжката е историята на продукта

Bindery е лесно да се опише като парсер, но историята на поддръжката е истинската история на продукта. Всяка нова библиотека за формати, добавена към тръбопровод, има свой собствен ритъм на издаване, речник за грешки, типове грешки, особености, риск от зависимости, тестови примери и режими на отказ. В малък мащаб това изглежда управляемо. В мащаб на корпус се превръща в оперативен архив, който хапе.

Споделеният двигател не премахва сложността на форматите. Това би било подозрително. Той премества сложността на място, където тестове, етикети за възможности, функции и API могат да се управляват заедно. README има тестове от край до край за документи, презентации, електронни таблици, iWork и други формати. Дървото на изходния код има модули, които правят границите на форматите очевидни. Тази структура позволява на екип да подобрява слоя за разбор, без да пита всеки продуктов екип да преоткрива разликата между част за връзка и поток от съставен файл.

Ето защо Bindery си пасва с останалата част от стека Dweve. Reed се грижи за анализирането с разписки. BitWeave се грижи за детерминираното извличане. Fabric и Spindle се грижат за управляваното знание и оперативната употреба. Bindery стои пред тези слоеве. Той превръща офис документите в структуриран материал, върху който останалата част от стека може да разсъждава. Ако входният слой е лепило и надежда, долната система наследява лепило и надежда. Много ефективно, ако стратегическата ви цел е бъдещо страдание.

Какво да попитате, преди да го приемете

Първият въпрос не е дали Bindery поддържа любимото ви разширение. Това е въпрос от списък, а списъците са полезни, но не са достатъчни. По-добрият въпрос е от кои обещания за документи имате нужда. Имате ли нужда от извличане само за четене, поддръжка на запис, запазване при завъртане, изчисляване на формули, заявки през формати, метаданни, вградени изображения, криптиран OOXML, наследен Office, iWork, ODF или извеждане към EPUB, LaTeX и Markdown? Това са различни задачи. Да се преструвате, че са една задача, е начинът, по който пътните карти се превръщат в каша.

Вторият въпрос е как се показва неуспехът. Ако анализатор не може да запази структура, казва ли го? Ако създател е с най-добри усилия, вижда ли се? Ако формула не може да бъде изчислена, може ли извикващият да реши дали да блокира, да предупреди или да продължи? Един двигател за документи не е надежден, защото никога не казва „не“. Той е надежден, защото неговото „не“ е типизирано, конкретно и близо до проблема.

Третият въпрос е как тествате собствения си архив. Публичните примери са полезни, но вашият архив вероятно е по-странен от папката с примери. Той има счупени експорти, древни шаблони, странни числови формати, скрити листове, копирани и поставени таблици, повредени PDF файлове и файлове, наречени final_final_really_final. Bindery дава споделен двигател и тестваеми повърхности. Все пак имате нужда от тестове за архива. За съжаление, документите няма да пораснат сами.

Урокът

Урокът на Bindery е, че обработката на документи не е извличане на текст с допълнителни стъпки. Тя е откриване на формат, структурен анализ, граници на възможностите, повърхности за заявки, пътища за запис и дисциплина за поддръжка. Потребителят вижда файл. Системата вижда контейнер, потоци, връзки, записи, стилове, формули, метаданни, кодирания и обещания за извеждане. Добрият двигател държи тази сложност под повърхността на продукта, без да се преструва, че не съществува.

Работата на Bindery е да направи слоя за документи скучен в добрия смисъл. Един двигател на Rust. API на високо ниво за документи, презентации и електронни таблици. Модули за формати за обърканите части. DocQL за споделени въпроси. Интеграция с Python и стека, където е полезна. Етикети за възможности вместо митология за формати.

Файлът никога не е бил проблемът. Лепилото беше. Bindery е опитът да спрете да плащате наем за този слой лепило.