Svaki geometrijski izdvajač teksta nagađa. Čita glifove koje stranica crta, sortira ih po osnovnoj liniji i vodoravnom položaju, i nada se da vizualni raspored odgovara redoslijedu kojim bi čovjek čitao. Na izvješću u jednom stupcu to je pogađanje ispravno. Na članku iz časopisa u dva stupca, obrascu s bočnom trakom ili tablici čije su ćelije emitirane po stupcima, pogrešno je na načine koje je teško primijetiti i skupo otkriti nizvodno. HotPDF na to odgovara s ExtractLoadedPageStructureText, koji geometriju potpuno ignorira: prelazi stablo strukture dokumenta u redoslijedu pisanja kako ga definira ISO 32000-1 §14.8.4, a zatim ponovno sastavlja glifove stranice prema njihovom identifikatoru označenog sadržaja. Za označeni PDF to nije heuristika, to je redoslijed koji je proizvodna aplikacija proglasila
Funkcija vraća False kada stranica nema upotrebljivo stablo strukture, što je signal za povratak na geometrijski izdvajač umjesto za pad. Taj dvoputni dizajn važniji je od algoritma: stvarni unos dokumenata vidi označene vladine obrasce i izlaz skenera u istoj mapi, a cjevovod koji rukuje samo jednim od njih nije cjevovod
Zašto geometrijsko izdvajanje pogađa redoslijed čitanja?
Zato što tok sadržaja PDF-a uopće ne nosi redoslijed čitanja. To je niz crtajućih operatora, a proizvođač je slobodan emitirati ih u bilo kojem nizu koji odgovara njegovom vlastitom motoru rasporeda. Procesori teksta obično emitiraju u redoslijedu toka i geometrijsko sortiranje izgleda dobro. Alati rasporeda, dizajneri obrazaca i generatori izvješća često ne: podnožje stranice može se emitirati prije tijela, tablica se može puniti po stupcima, a stranica s dva stupca može isprepliti retke iz oba stupca jer ih je sastavljač razriješio zajedno
Način kvara je tih. Geometrijski izdvajač nikad ne javlja pogrešku, samo vraća prozu čije su rečenice spojene iz dva stupca. Sve što taj tekst troši, indeks pretraživanja, maper polja e-računa, cjevovod dohvata koji hrani jezični model, nasljeđuje štetu bez upozorenja. HotPDF također isporučuje geometrijske izdvajače za učitane dokumente, i oni ostaju ispravan alat za neoznačene datoteke; poanta puta u redu strukture jest prestati nagađati kada dokument već nosi odgovor
Što stablo strukture stvarno sprema
Označeni PDF drži drugi, paralelni opis stranice. Katalog upućuje na /StructTreeRoot, čija djeca /K čine stablo strukturnih elemenata: /Document, /Sect, /P, /Table, /TR, /TD i tako dalje. Listovi tog stabla reference su označenog sadržaja, cijeli brojevi koji imenuju raspon toka sadržaja stranice. Na strani sadržaja ti se rasponi otvaraju operatorom BDC koji nosi /MCID i zatvaraju s EMC. Svaki strukturni element također nosi unos /Pg koji imenuje stranicu kojoj pripada, što omogućuje obilazak po stranici u dokumentu čije se stablo strukture proteže na stotine stranica
HotPDF prelazi to stablo s dubinskom granicom od 128 razina i filtrira na /Pg tako da samo trenutna stranica pridonosi. Izlaz obilaska nije tekst, nego uređeni popis MCID vrijednosti: redoslijed pisanja raspona označenog sadržaja na ovoj stranici. Ponovno sastavljanje teksta zatim je pitanje ponavljanja glifova u tom redoslijedu
MCID se zabilježi tijekom izdvajanja glifova, ne traži poslije
Ovo je detalj implementacije koji značajku čini jeftinom. HotPDF već zabilježava aktivni identifikator označenog sadržaja na svakom glifu koji izdvaja, u polju MCID zapisa THPDFGlyphRecord, jer interpreter toka sadržaja zna koji je opseg BDC otvoren u trenutku kada obrađuje svaki operator Tj ili TJ. Izdvajanje u redu strukture dakle ne treba drugi prolaz nad tokom sadržaja. Prikuplja MCID niz iz stabla strukture, zatim razvrstava već izdvojene glifove po MCID i emitira ih u tom nizu
var
Pdf: THotPDF;
PageCount, I, Untagged: Integer;
PageText, AllText: UnicodeString;
Report: TStrings; // odredište dijagnostike u vlasništvu pozivatelja
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
// Redoslijed pisanja ravno 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: geometrijski povratak
Pdf.ExtractLoadedPageText(I, PageText);
AllText := AllText + PageText + #13#10;
end;
finally
Pdf.Free;
end;
end;
Neoznačeni glifovi broje se, nikad se tiho ne odbacuju
Stranica može biti djelomično označena. Proizvođači dodaju ukrasno pravilo, broj stranice ili vodeni žig iz kasne faze izvan svakog opsega BDC, i ti glifovi ne pripadaju nijednom MCID-u. Odbaciti ih bila bi uredna implementacija i pogrešna, jer se isti jaz pojavljuje i kada proizvođač označi tijelo ali zaboravi tablicu, i izgubili biste tablicu a da niste primijetili
HotPDF dodaje nepriznate glifove kao geometrijski rep nakon teksta u redu strukture i javlja njihov broj kroz izlazni parametar UntaggedGlyphCount. Taj broj signal je kvalitete na kojeg možete djelovati. Šaka glifova na stranici od dvije tisuće namještaj je stranice i može se ignorirati. Četrdeset posto stranice izvan stabla strukture znači da je označavanje ukrasno i da je geometrijski izdvajač pošteniji odgovor za tu datoteku
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);
// Vjerujte stablu strukture samo kada tvrdi 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;
Što tjera funkciju da vrati False
Tri slučaja, i vrijedi ih razlikovati jer je samo jedan od njih defekt u dokumentu. Prvi je obični neoznačeni PDF: nema /StructTreeRoot, nema čime hodati, i False je jednostavno istina. Drugi je skenirana stranica čiji tekst dolazi iz OCR sloja koji nikad nije označen. Treći je zanimljiv: sadržaj koji nosi operatore BDC s vrijednostima /MCID ali čija stranica nema unos /StructParents i čije se stablo strukture nikad ne referencira na te identifikatore. Označeni sadržaj postoji, strana strukture ne postoji, i nema redoslijeda za oporaviti. HotPDF javlja False umjesto da ga izmisli
Taj posljednji slučaj pojavljuje se u ručno uređenim datotekama i u izlazu alata koji emitiraju označeni sadržaj za svrhe neobaveznog sadržaja ili artefakata bez gradnje stabla strukture. Ako sami proizvodite označene PDF-ove, ista asimetrija ono je što provjera PDF/UA valjanosti ispituje, a pisarski pandan pokriven je u DOM-u rasporeda koji emitira označeni, podijeljeni na stranice izlaz
Gdje se red strukture isplati
Revizija pristupačnosti očita je: ako certificirate dokument u odnosu na PDF/UA, redoslijed čitanja koji će čitač zaslona najaviti točno je red strukture, pa ga izdvojiti znači pregledati ga bez čitača zaslona. Prikupljanje podataka veći je komercijalni slučaj. Označeni vladini obrasci, regulirana očitovanja i privici e-računa nose natpise polja i vrijednosti u proglašenom redoslijedu, i čitanje u tom redoslijedu uklanja cijelu klasu grešaka preslikavanja koje geometrijsko izdvajanje stvara na rasporedima s više stupaca
Najnoviji potrošač jest dohvat za jezične modele. Komadanje dokumenta za ugrađivanje samo je onoliko dobro koliko je dobar redoslijed teksta, i komad koji spoji dva stupca proizvodi rečenice koje nikad nisu postojale. Izdvajanje u redu strukture najjeftinije je dostupno rješenje za to, jer za označene dokumente ispravan redoslijed već je u datoteci i samo ga treba pročitati
HotPDF je izvorna VCL komponenta za Delphi i C++Builder, pa obilazak stabla strukture i ponavljanje glifova oba rade unutar procesa nad učitanim dokumentom bez uključenog vanjskog prikazivača. Potpune API pojedinosti za obitelj izdvajanja učitanih dokumenata su na stranici proizvoda HotPDF Delphi PDF component