Odborný článok

PDF do Markdown a DOCX v Delphi s PDFlibPas

PDFlibPas prevedie obsah PDF do dvoch editovateľných formátov bez automatizácie Office. ExportPageMarkdown a ExportDocumentMarkdown vrátia sémantický Markdown s odvodenými nadpismi, číslovanými aj nečíslovanými zoznamami a tabuľkami s pipe oddeľovačmi, zatiaľ čo SaveDOCXToFile a SaveDOCXToStream zapíšu balík WordprocessingML obsahujúci odstavce, nadpisy, natívne číslovanie zoznamov, rozpoznané tabuľky, štýlovanie písma, zalomenia strán a umiestnené PNG obrázky

Oboje beží úplne v Pascale, na serveri, bez nainštalovaného Wordu a bez COM. Práve toto obmedzenie je dôvodom, prečo táto funkcia existuje v PDF knižnici, a nie v desktopovom nástroji

Prečo je „PDF do Wordu“ naozaj ťažké?

Pretože stránka PDF neobsahuje odstavce. Obsahuje operátory na zobrazenie textu, ktoré umiestňujú behy glyfov na súradnice, v poradí, v akom ich producent vygeneroval, bez akejkoľvek povinnosti naznačiť, že dva behy patria do tej istej vety, nieto do tej istej položky zoznamu. Formát bol navrhnutý tak, aby presne opísal vytlačenú stránku, a v tom aj uspeje — tým, že zahodí štruktúru, ktorá stránku vytvorila

Takže každý konvertor musí rekonštruovať to, čo generátor zahodil. Zoskupovanie riadkov vychádza zo zvislých medzier a zarovnania na základnej línii. Hranice odstavcov vychádzajú zo zmien medzier a odsadenia. Nadpis je riadok, ktorého písmo je väčšie alebo hrubšie než telo textu a ktorý sa odlišuje od toho, čo nasleduje. Zoznam je séria odstavcov začínajúcich znakom odrážky alebo vzorom čísla. Tabuľka je mriežka textových blokov, ktorých okraje sa zarovnávajú naprieč riadkami a stĺpcami. Každé z toho je odvodenie, a odvodenie znamená dobrý výsledok na dokumentoch, ktoré dodržiavajú bežné typografické konvencie, a priemerný na tých, ktoré ich nedodržiavajú

Označené PDF sú výnimkou, a to výraznou. Keď dokument nesie strom štruktúry, roly odstavca, nadpisu, zoznamu a tabuľky sú zaznamenané, nie odhadované — a preto sa práca na prístupnosti opísaná v článku štruktúra prístupnosti označeného PDF oplatí aj v kvalite konverzie. Ak máte kontrolu nad producentom, označenie výstupu je vec s najvyšším pákovým efektom, ktorú môžete urobiť pre kohokoľvek, kto ho neskôr bude musieť previesť

Export do Markdown, stránka po stránke

Cesta cez Markdown je tá, po ktorej siahnete vtedy, keď je cieľom textový pipeline: dokumentačný web, vyhľadávací index, korpus na vyhľadávanie pre asistenta. Voľby sú bitová maska: PDF_MARKDOWN_INCLUDE_PAGE_MARKERS, PDF_MARKDOWN_DETECT_HEADINGS, PDF_MARKDOWN_PRESERVE_STYLES, pričom PDF_MARKDOWN_DEFAULT kombinuje všetky tri

var
  Pdf: TPDFlib;
  Md: WideString;
begin
  Pdf := TPDFlib.Create;
  try
    Pdf.LoadFromFile('handbook.pdf', '');

    // Jedna stránka ako reťazec
    Md := Pdf.ExportPageMarkdown(1, PDF_MARKDOWN_DEFAULT);

    // Rozsah strán, streamovaný na disk ako UTF-8 bez BOM
    Pdf.SaveMarkdownToFile('1-40',
      PDF_MARKDOWN_DETECT_HEADINGS or PDF_MARKDOWN_PRESERVE_STYLES,
      'handbook.md');
  finally
    Pdf.Free;
  end;
end;

Značky stránok sa oplatia pri práci s vyhľadávaním. Kúsok textu, ktorý nesie informáciu o tom, z ktorej stránky pochádza, sa dá presne citovať, a čitateľ, ktorý citáciu nasleduje, sa dostane presne tam, kde sa dané tvrdenie naozaj nachádza. Vypnite ich, keď je Markdown určený na čítanie človekom, kde sú hranice strán z pôvodného rozloženia len šumom

Streamované vstupné body sú dôležité pri veľkých dokumentoch. SaveMarkdownToStream a SaveMarkdownToFile zapisujú UTF-8 po jednej stránke a nebufferujú celý výstup naraz, takže 900-stranová príručka sa najprv nestane 900-stranovým reťazcom v pamäti. Aj absencia značky poradia bajtov je zámerná: BOM na Markdown súbore mätie prekvapivo veľa generátorov statických webov aj diff nástrojov

DOCX bez Office na stroji

Zapisovač DOCX vytvára balík úplne sám: položky ZIP zapísané ako surové Deflate s kontrolami CRC, časti WordprocessingML a vzťahy, ktoré ich spájajú. Nič nevolá do Wordu, čo znamená, že konverzia beží na bezhlavom serveri, pod servisným účtom, v kontajneri — všade tam, kde je automatizácia Office buď bez licencie, nestabilná, alebo zakázaná

var
  Pdf: TPDFlib;
  Target: TFileStream;
begin
  Pdf := TPDFlib.Create;
  Target := TFileStream.Create('handbook.docx', fmCreate);
  try
    Pdf.LoadFromFile('handbook.pdf', '');
    Pdf.SaveDOCXToStream('1-40',
      PDF_DOCX_INCLUDE_IMAGES or PDF_DOCX_DETECT_HEADINGS or
      PDF_DOCX_PRESERVE_STYLES or PDF_DOCX_PRESERVE_PAGE_BREAKS,
      Target);
  finally
    Target.Free;
    Pdf.Free;
  end;
end;

Údaje obrázkov sa zapisujú tak, ako sa jednotlivé stránky spracúvajú, a nie sa zbierajú a pripájajú až na konci, takže špičková spotreba pamäte sleduje jednu stránku, a nie celý dokument. Presné poradie strán sa zachováva a vybraná stránka PDF sa po skončení obnoví, čo je dôležité vtedy, keď je export jeden krok v rámci dlhšej úlohy, ktorá mala stránku vybranú z iných dôvodov

Čo vám prináša deterministické balenie?

Reprodukovateľnosť bajt po bajte. Dve konverzie toho istého vstupu s rovnakými voľbami vytvoria rovnaký balík, čo znamená, že môžete výstup hashovať na detekciu zmien, porovnať dva buildy generovaného dokumentu a agresívne cachovať bez obavy, že rovnaký vstup vytvoril iný artefakt

Automatizácia Office toto sľúbiť nemôže. Vkladá časové značky, identifikátory revízií a metadáta závislé od stroja, takže ten istý dokument prevedený dvakrát sa líši spôsobom, ktorý znemožňuje hashovanie. Rovnaká úvaha stojí za deterministickými identifikátormi súborov opísanými v článku deterministické PDF ID pre reprodukovateľné buildy: keď je výstup reprodukovateľný, overovanie sa mení z inšpekcie na porovnávanie

Kde je výstup dobrý, a kde nie je

Buďte k svojim používateľom v tomto bode úprimní, pretože kvalita konverzie závisí viac od vstupu než od konvertora. Označené PDF a čisto vygenerované obchodné dokumenty — faktúry, reporty, zmluvy — sa prevádzajú dobre: nadpisy pristanú ako nadpisy, tabuľky prežijú, zoznamy sa vo Worde správne prečíslujú. Dvojstĺpcové akademické rozloženia sa prevádzajú prijateľne, ak je geometria stĺpcov pravidelná. Tabuľky, ktoré presahujú cez zalomenie strany, sa poskladajú odvodením a niekedy sa rozdelia. Silno dizajnovaný marketingový materiál, kde je text umiestnený kvôli vizuálnemu efektu, a nie v poradí čítania, sa prevádza zle, a žiadne množstvo odvodzovania to nenapraví

Skenované dokumenty sú úplne samostatný prípad. Stránka, ktorá je jeden veľký obrázok, neobsahuje žiadne textové objekty, takže niet čo exportovať, kým neexistuje textová vrstva; cesta cez OCR, ktorá takú vrstvu vytvorí, je predpoklad, nie voliteľná možnosť. Pred spustením veľkej dávky si vzorkujte tucet reprezentatívnych súborov a pozrite sa na výstup, a zvážte, či najprv nevymenovať prvky stránky, ako je opísané v článku vyhľadávanie textu a výpočet prvkov stránky, aby ste videli, čo tie stránky naozaj obsahujú

Pre pipeline asistentov a vyhľadávania je zvyčajne lepším cieľom cesta cez Markdown: nadpisy sa stávajú hranicami blokov, tabuľky ostávajú čitateľné ako pipe tabuľky a značky stránok dávajú každému bloku citovateľné umiestnenie. Pre editáciu človekom je odpoveďou DOCX, pretože to, čo používateľ chce, nie je text samotný, ale schopnosť ho meniť

PDFlibPas je knižnica PDF pre Delphi, C++Builder a Lazarus so zodpovedajúcimi rozhraniami DLL a ActiveX, takže rovnaké exportné volania sú dostupné aj z C#, C++ alebo skriptovacích hostiteľov. Úplná dokumentácia a skúšobná verzia sú na stránke PDFlibPas Delphi PDF library