Tehnički članak

Izdvajanje teksta PDF-a po redosledu strukture u Delphi-ju

Svaki geometrijski ekstraktor teksta pogađa. Čita glifove koje stranica crta, sortira ih po osnovnoj liniji i horizontalnom položaju, i nada se da vizuelni raspored odgovara redosledu koji bi čovek čitao. Na izveštaju sa jednom kolonom taj pogodak je ispravan. Na članku časopisa sa dve kolone, obrascu sa bočnom trakom, ili tabeli čije su ćelije emitovane kolona po kolona, pogrešan je na načine koje je teško primetiti i skupe otkriti nizvodno. HotPDF odgovara na ovo sa ExtractLoadedPageStructureText, koji ignoriše geometriju potpuno: obilazi stablo strukture dokumenta u redosledu pisanja kako ga definiše ISO 32000-1 §14.8.4, pa ponovo sastavlja glifove stranice po njihovom identifikatoru označenog sadržaja. Za tagirani PDF to nije heuristika, to je redosled koji je aplikacija proizvođač izjavila

Funkcija vraća False kada stranica nema upotrebljivo stablo strukture, što je signal da se rezervni put prebaci na geometrijski ekstraktor, a ne da se otkazuje. Taj dizajn sa dva puta važniji je od algoritma: stvaran unos dokumenata vidi tagirane vladine obrasce i izlaz skenera u istoj fascikli, i pipeline koji rukuje samo jednim od njih nije pipeline

Zašto geometrijsko izdvajanje pogrešava redosled čitanja?

Zato što tok sadržaja PDF-a ne nosi nikakav redosled čitanja. To je sekvenca crtačkih operatora, i proizvođač je slobodan da ih emituje u kojoj god sekvenci odgovara njegovom sopstvenom motoru rasporeda. Procesori teksta obično emituju u redosledu toka i geometrijsko sortiranje deluje dobro. Alati rasporeda, dizajneri obrazaca i generatori izveštaja često ne: podnožje stranice može biti emitovano pre tela, tabela može biti punjena kolona-po-kolona, i stranica sa dve kolone može ispreplitati linije iz obe kolone jer ih je kompozitor razrešio zajedno

Poređenje PDF stranice sa dve kolone prikazuje geometrijsko izdvajanje sortirano po osnovnoj liniji koje spaja kolone naspram izdvajanja MCID po redosledu strukture u HotPDF-u
Sortiranje glifova po osnovnoj liniji isprepliće dve kolone u besmisao, dok stablo strukture ponavlja redosled koji je proizvođač izjavio

Režim otkazivanja je tih. Geometrijski ekstraktor nikad ne izveštava grešku, samo predaje nazad prozu čije su rečenice spojene iz dve kolone. Bilo šta što troši taj tekst, indeks pretrage, maper polja e-fakture, pipeline pretrage koji hrani jezički model, nasleđuje štetu bez upozorenja. HotPDF takođe isporučuje geometrijske ekstraktore za učitane dokumente, i oni ostaju pravi alat za netagirane datoteke; poenta puta redosleda strukture je prestati pogađati kada dokument već nosi odgovor

Šta stablo strukture zapravo čuva

Tagirani PDF drži drugi, paralelni opis stranice. Katalog ukazuje na /StructTreeRoot, čija /K deca formiraju stablo elemenata strukture: /Document, /Sect, /P, /Table, /TR, /TD, i tako dalje. Listovi tog stabla su reference označenog sadržaja, celi brojevi koji imenuju deo toka sadržaja stranice. Na strani sadržaja, ti delovi otvaraju se operatorom BDC koji nosi /MCID i zatvaraju sa EMC. Svaki element strukture takođe nosi unos /Pg koji imenuje stranicu kojoj pripada, što je ono što čini mogućim obilazak po stranici u dokumentu čije se stablo strukture prostire na stotine stranica

Anatomija stabla strukture PDF-a koja povezuje elemente StructTreeRoot poput Sect, Table, TR i TD sa BDC MCID delovima u toku sadržaja stranice HotPDF
Listovi stabla su reference označenog sadržaja, i svaki element nosi Pg unos koji dopušta obilasku filtriranje na tekuću stranicu

HotPDF obilazi to stablo sa dubinskom granicom od 128 nivoa i filtrira na /Pg pa samo tekuća stranica doprinosi. Izlaz obilaska nije tekst, to je uređen popis MCID vrednosti: redosled pisanja delova označenog sadržaja na ovoj stranici. Ponovno sastavljanje teksta je zatim pitanje ponavljanja glifova u tom redosledu

MCID se beleži tokom izdvajanja glifova, ne traži posle

Ovo je detalj implementacije koji čini funkciju jeftinom. HotPDF već beleži aktivni identifikator označenog sadržaja na svakom glifu koji izdvaja, u polju MCID od THPDFGlyphRecord, jer interpretator toka sadržaja zna koji BDC obuhvat je otvoren u trenutku kada obrađuje svaki operator Tj ili TJ. Izdvajanje po redosledu strukture dakle ne treba drugi prolaz preko toka sadržaja. Ono sakuplja MCID sekvencu iz stabla strukture, pa razvrstava već izdvojene glifove po MCID-u i emituje ih u toj sekvenci

var
  Pdf: THotPDF;
  PageCount, I, Untagged: Integer;
  PageText, AllText: UnicodeString;
  Report: TStrings;   // odlagalište dijagnostike u vlasništvu pozivaoca
begin
  Pdf := THotPDF.Create(nil);
  try
    PageCount := Pdf.LoadFromFile('accessible-form.pdf');
    AllText := '';
    for I := 0 to PageCount - 1 do
    begin
      if Pdf.ExtractLoadedPageStructureText(I, PageText, Untagged) then
      begin
        // Redosled pisanja pravo iz stabla strukture
        if Untagged > 0 then
          Report.Add(Format('page %d: %d glyphs outside the structure tree',
            [I, Untagged]));
      end
      else
        // Nema upotrebljivog stabla strukture na ovoj stranici: geometrijska rezerva
        Pdf.ExtractLoadedPageText(I, PageText);
      AllText := AllText + PageText + #13#10;
    end;
  finally
    Pdf.Free;
  end;
end;

Netagirani glifovi se broje, nikad tiho ne bacaju

Stranica može biti delimično tagirana. Proizvođači dodaju dekorativnu liniju, broj stranice, ili vodeni žig kasne faze van svakog BDC obuhvata, i ti glifovi ne pripadaju nijednom MCID-u. Njihovo bacanje bila bi uredna implementacija i pogrešna, jer se isti jaz pojavljuje i kada proizvođač tagira telo ali zaboravi tabelu, i izgubili biste tabelu ne primetivši

HotPDF dodaje neprisvojene glifove kao geometrijski rep posle teksta poređanog po strukturi i izveštava njihov broj kroz izlazni parametar UntaggedGlyphCount. Taj broj je signal kvaliteta na koji možete delovati. Šaka glifova na stranici od dve hiljade je nameštaj stranice i može se ignorisati. Četrdeset procenata stranice van stabla strukture znači da je tagiranje dekorativno i da je geometrijski ekstraktor pošteniji odgovor za tu datoteku

Tok odluke za izdvajanje teksta strukture HotPDF sa geometrijskom rezervom kada stranica nema upotrebljivo stablo strukture ili dekorativno tagiranje
True znači redosled strukture sa dodatim netagiranim repom, a False usmerava stranicu geometrijskom ekstraktoru umesto da otkazuje
function ExtractPageBestEffort(Pdf: THotPDF; PageIndex: Integer;
  out AText: UnicodeString; out UsedStructure: Boolean): Boolean;
var
  Untagged, TotalGlyphs: Integer;
  Glyphs: THPDFGlyphArray;
begin
  UsedStructure := False;
  if Pdf.ExtractLoadedPageStructureText(PageIndex, AText, Untagged) then
  begin
    TotalGlyphs := 0;
    if Pdf.ExtractLoadedPageGlyphs(PageIndex, Glyphs) then
      TotalGlyphs := Length(Glyphs);
    // Verujte stablu strukture samo kada polaže pravo na većinu stranice
    if (TotalGlyphs = 0) or (Untagged * 4 <= TotalGlyphs) then
    begin
      UsedStructure := True;
      Result := True;
      Exit;
    end;
  end;
  Result := Pdf.ExtractLoadedPageText(PageIndex, AText);
end;

Šta čini da funkcija vrati False

Tri slučaja, i vredi ih razlikovati jer je samo jedan od njih defekt u dokumentu. Prvi je običan netagirani PDF: nema /StructTreeRoot, nema šta obići, i False je jednostavno istina. Drugi je skenirana stranica čiji tekst dolazi iz OCR sloja koji nikad nije tagiran. Treći je zanimljivi: sadržaj koji nosi BDC operatore sa /MCID vrednostima ali čija stranica nema unos /StructParents i čije se stablo strukture nikad ne referencira te identifikatore. Označeni sadržaj postoji, strana strukture ne, i nema redosleda za oporavak. HotPDF izveštava False umesto da ga izmisli

Poslednji slučaj pojavljuje se u ručno uređivanim datotekama i u izlazu alata koji emituju označeni sadržaj radi opcionog-sadržaja ili artefakta bez izgradnje stabla strukture. Ako sami proizvodite tagirane PDF-ove, ista asimetrija je ono što PDF/UA validacija proverava, a pisana strana pokrivena je u layout DOM-u koji emituje tagirani, paginiran izlaz

Gde se redosled strukture isplati sam po sebi

Revizija pristupačnosti očigledna je: ako sertifikujete dokument prema PDF/UA, redosled čitanja koji će čitač ekrana objaviti je tačno redosled strukture, pa ga izdvojiti je način da ga pregledate bez čitača ekrana. Prikupljanje podataka veći je komercijalni slučaj. Tagirani vladini obrasci, regulisana objavljivanja i prilozi e-faktura nose oznake polja i vrednosti u izjavljenom redosledu, i njihovo čitanje u tom redosledu uklanja celu klasu grešaka mapiranja koje geometrijsko izdvajanje stvara na višekolonskim rasporedima

Najnoviji potrošač je pretraga za jezičke modele. Sekcionisanje dokumenta za embedding dobro je koliko i redosled teksta, i odeljak koji spaja dve kolone proizvodi rečenice koje nikad nisu postojale. Izdvajanje po redosledu strukture najjeftinija je dostupna popravka za to, jer je za tagirane dokumente ispravan redosled već u datoteci i samo treba biti pročitan

HotPDF je nativna VCL komponenta za Delphi i C++Builder, pa i obilazak stabla strukture i ponavljanje glifova oba rade u procesu nad učitanim dokumentom bez spoljnog renderera uključenog. Potpuni API detalji za familiju izdvajanja učitanih dokumenata nalaze se na stranici proizvoda HotPDF Delphi PDF component