Tekninen artikkeli

PDF-tekstin uuttaminen rakenteen järjestyksessä HotPDF:llä

Jokainen geometrinen tekstiuuttaja arvaa. Se lukee glyfit, jotka sivu piirtää, lajittelee ne perusviivan ja vaakasuoran sijainnin mukaan ja toivoo visuaalisen asettelun vastaavan sitä järjestystä, jossa ihminen lukisi. Yhden palstan raportissa se arvaus on oikein. Kaksipalstaisessa aikakauslehtiartikkelissa, sivupalkin sisältävässä lomakkeessa tai taulukossa, jonka solut emittoitiin palsta kerrallaan, se on väärin tavalla, jota on vaikea huomata ja joka on kallis havaita alavirrassa. HotPDF vastaa tähän funktiolla ExtractLoadedPageStructureText, joka ohittaa geometrian kokonaan: se kulkee dokumentin rakennepuun läpi luontijärjestyksessä, niin kuin ISO 32000-1 §14.8.4 määrittelee, ja kokoaa sitten sivun glyfit niiden marked-content-tunnisteen mukaan. Tagatulle PDF:lle tuo ei ole heuristiikka, se on järjestys, jonka tuottava sovellus ilmoitti

Funktio palauttaa arvon False, kun sivulla ei ole käytettävissä olevaa rakennepuuta, mikä on merkki varata geometriseen uuttajaan epäonnistumisen sijaan. Kaksipolkinen suunnittelu merkitsee enemmän kuin algoritmi: todellinen dokumenttien saanti näkee tagatut viranomaislomakkeet ja skannerin tuotoksen samassa kansiossa, eikä putki, joka käsittelee vain toista niistä, ole putki

Miksi geometrinen uutto saa lukujärjestyksen väärin?

Koska PDF-sisältövirta ei kanna lukujärjestystä lainkaan. Se on piirto-operaattorien jono, ja tuottaja voi vapaasti emitoida ne siinä jonossa, mikä sopii sen omalle asettelukoneelle. Tekstinkäsittelyohjelmat emittoivat yleensä virtajärjestyksessä ja geometrinen lajittelu näyttää hyvältä. Asettelutyökalut, lomakesuunnittelijat ja raporttigeneraattorit eivät useinkaan: sivun alatunniste voidaan emittoida rungon ennen, taulukko voidaan täyttää palstapääjärjestyksessä, ja kaksipalstainen sivu voi lomittaa rivejä molemmista palstoista, koska sommitteli ratkaisi ne yhdessä

Kaksipalstaisen PDF-sivun vertailu, jossa perusviivan mukaan lajitteleva geometrinen uutto lomittaa palstoja vastoin rakenteen järjestyksen MCID-uuttoa HotPDF:ssä
Glyfien lajittelu perusviivan mukaan lomittaa kaksi palstaa merkityksettömäksi, kun taas rakennepuu toistaa järjestyksen, jonka tuottaja ilmoitti

Vikamuoto on hiljainen. Geometrinen uuttaja ei koskaan raportoi virhettä, se vain palauttaa proosaa, jonka lauseet on lomitettu kahdesta palstasta. Mikä tahansa kyseistä tekstiä kuluttava, hakemisto, sähköisen laskun kenttäkartoittaja tai kielimalliin ruokkiva hakuputki, perii vaurion ilman varoitusta. HotPDF toimittaa myös geometriset uuttajat ladatuille dokumenteille, ja ne pysyvät oikeana työkaluna tagaamattomille tiedostoille; rakenteen järjestyksen polun pointti on lopettaa arvaaminen, kun dokumentti jo kantaa vastauksen

Mitä rakennepuu oikeasti tallentaa

Tagattu PDF pitää sisällään toisen, rinnakkaisen kuvauksen sivusta. Luettelo osoittaa kohteeseen /StructTreeRoot, jonka /K-lapset muodostavat rakenne-elementtien puun: /Document, /Sect, /P, /Table, /TR, /TD ja niin edelleen. Tuon puun lehdet ovat marked-content-viittauksia, kokonaislukuja, jotka nimeävät sivun sisältövirran jakson. Sisältöpuolella kyseiset jaksot avataan BDC-operaattorilla, joka kantaa arvon /MCID, ja suljetaan operaattorilla EMC. Jokainen rakenne-elementti kantaa myös /Pg-merkinnän, joka nimeää sivun, johon se kuuluu, ja se tekee sivukohtaisen läpikäynnin mahdolliseksi dokumentissa, jonka rakennepuu ulottuu sadoille sivuille

PDF-rakennepuun anatomia, joka linkittää StructTreeRoot-elementit, kuten Sect, Table, TR ja TD, BDC MCID -jaksoihin HotPDF:n sivun sisältövirrassa
Puun lehdet ovat marked-content-viittauksia, ja jokainen elementti kantaa Pg-merkinnän, joka antaa kulun suodattaa nykyiselle sivulle

HotPDF käy kyseisen puun läpi 128 tason syvyyskatolla ja suodattaa arvon /Pg mukaan niin, että vain nykyinen sivu osallistuu. Läpikäynnin tuloste ei ole tekstiä, se on järjestetty luettelo MCID-arvoista: marked-content-jaksojen luontijärjestys tällä sivulla. Tekstin kokoaminen on sitten kyse siitä, että glyfit toistetaan tuossa järjestyksessä

MCID tallennetaan glyfiuuton aikana, ei etsitä jälkikäteen

Tämä on se toteutuksen yksityiskohta, joka tekee ominaisuudesta halvan. HotPDF tallentaa jo aktiivisen marked-content-tunnisteen jokaiseen uuttamaansa glyfiin, kohteeseen THPDFGlyphRecordin MCID-kenttään, koska sisältövirran tulkki tietää, mikä BDC-vaikutusalue on auki sillä hetkellä, kun se käsittelee jokaisen Tj- tai TJ-operaattorin. Rakenteen järjestyksen uutto ei siksi tarvitse toista läpikäyntiä sisältövirran yllä. Se kerää MCID-jonon rakennepuusta, bucketoi jo uutetut glyfit MCID:n mukaan ja emittoi ne tuossa jonossa

var
  Pdf: THotPDF;
  PageCount, I, Untagged: Integer;
  PageText, AllText: UnicodeString;
  Report: TStrings;   // kutsujan omistama diagnostiikkavastaanotto
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
        // Luontijärjestys suoraan rakennepuusta
        if Untagged > 0 then
          Report.Add(Format('page %d: %d glyphs outside the structure tree',
            [I, Untagged]));
      end
      else
        // Ei käytettävissä olevaa rakennepuuta tällä sivulla: geometrinen varatie
        Pdf.ExtractLoadedPageText(I, PageText);
      AllText := AllText + PageText + #13#10;
    end;
  finally
    Pdf.Free;
  end;
end;

Tagaamattomat glyfit lasketaan, ei koskaan pudoteta hiljaa

Sivu voi olla osittain tagattu. Tuottajat lisäävät koristeellisen viivan, sivunumeron tai myöhäisvaiheen vesileiman minkä tahansa BDC-vaikutusalueen ulkopuolelle, ja ne glyfit eivät kuulu mihinkään MCID:hen. Niiden pudottaminen olisi siisti toteutus ja väärä, koska sama aukko ilmestyy myös silloin, kun tuottaja tagaa rungon mutta unohtaa taulukon, ja menettäisit taulukon huomaamatta

HotPDF liittää vaatimattomat glyfit geometrisenä häntänä rakenteen järjestyksessä olevan tekstin jälkeen ja raportoi niiden lukumäärän UntaggedGlyphCount-tulostusparametrin kautta. Tuo luku on laatusignaali, johon voi reagoida. Kourallinen glyfejä kahdentuhannen sivulla on sivukalusteita ja voidaan ohittaa. Neljäkymmentä prosenttia sivusta rakennepuun ulkopuolella tarkoittaa, että taggaus on koristeellista ja geometrinen uuttaja on rehellisempi vastaus kyseiselle tiedostolle

Päätösvirta HotPDF:n rakennetekstin uutolle geometrisella varatiellä, kun sivulla ei ole käytettävää rakennepuuta tai taggaus on koristeellista
True tarkoittaa rakenteen järjestystä tagaamaton häntä liitettynä, ja False ohjaa sivun geometriseen uuttajaan epäonnistumisen sijaan
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);
    // Luota rakennepuuhun vain, kun se vaatii suurimman osan sivusta
    if (TotalGlyphs = 0) or (Untagged * 4 <= TotalGlyphs) then
    begin
      UsedStructure := True;
      Result := True;
      Exit;
    end;
  end;
  Result := Pdf.ExtractLoadedPageText(PageIndex, AText);
end;

Mikä saa funktion palauttamaan arvon False

Kolme tapausta, ja ne kannattaa erottaa, koska vain yksi niistä on vika dokumentissa. Ensimmäinen on tavallinen tagaamaton PDF: ei /StructTreeRootia, ei mitään kuljettavaa, ja arvo False on yksinkertaisesti totuus. Toinen on skannattu sivu, jonka teksti tulee OCR-kerroksesta, jota ei koskaan tagattu. Kolmas on kiinnostava: sisältö, joka kantaa BDC-operaattoreita arvoilla /MCID, mutta jonka sivulla ei ole /StructParents-merkintää ja jonka rakennepuu ei koskaan viittaa kyseisiin tunnisteisiin. Marked content on olemassa, rakennepuoli ei ole, eikä ole järjestystä palautettavana. HotPDF raportoi arvon False sen keksimisen sijaan

Tuo viimeinen tapaus ilmestyy käsin muokattuihin tiedostoihin ja työkalujen tuotoksiin, jotka emittoivat marked contentia valinnaista sisältöä tai artefaktia varten rakennepuuta rakentamatta. Jos tuotat itse tagattuja PDF:itä, sama epäsymmetria on se, mitä PDF/UA-validointi tarkistaa, ja kirjoittajapuolen vastine käsitellään artikkelissa asettelu-DOM, joka emittoi tagattua, sivutettua tulostetta

Missä rakenteen järjestys maksaa itsensä takaisin

Saavutettavuuden auditointi on ilmeinen: jos sertifioit dokumenttia vasten PDF/UA:ta, näytönlukijan ilmoittama lukujärjestys on täsmälleen rakenteen järjestys, joten sen uuttaminen on tapa tarkistaa se ilman näytönlukijaa. Tiedonkeruu on suurempi kaupallinen tapaus. Tagatut viranomaislomakkeet, säännellyt julkistukset ja sähköisen laskun liitteet kantavat kenttäotsikoita ja arvoja ilmoitetussa järjestyksessä, ja niiden lukeminen tuossa järjestyksessä poistaa kokonaisen luokan kartoitusvirheitä, joita geometrinen uutto luo monipalstaisiin asetteluihin

Uusin kuluttaja on kielimallien haku. Dokumentin pilkkominen upotuksia varten on vain niin hyvä kuin tekstijärjestys, ja palanen, joka lomittaa kaksi palstaa, tuottaa lauseita, joita ei koskaan ollut olemassa. Rakenteen järjestyksen uutto on saatavilla olevista korjauksista halvin, koska tagatuille dokumenteille oikea järjestys on jo tiedostossa, sen lukeminen riittää

HotPDF on natiivi VCL-komponentti Delphille ja C++Builderille, joten sekä rakennepuun läpikäynti että glyfien toisto toimivat prosessinsisäisesti ladattua dokumenttia vastaan ilman ulkoista renderöijää. Täydet API-yksityiskohdat ladatun dokumentin uuttoperheestä ovat HotPDF Delphi PDF -komponentin tuotesivulla