Tehnički članak

Automatsko označavanje strukture za pristupačni PDF u Delphiju

PDF Library for Delphi može označavati dokument dok se crta. Uključite SetAutoTagMode i obični pozivi DrawText postaju odlomci, tekst nacrtan neposredno nakon RegisterHeading postaje naslov te razine, tekuća zaglavlja i podnožja postaju artefakti koje čitač preskače, slike postaju figure, a DrawTableRows unosi tablicu, njene redove i ćelije u stablo strukture

Alternativa, a do nedavno jedina opcija, bila je ručno umotati svaki poziv za crtanje u BeginTag i EndTag. To radi, i za dokumente neobične strukture i dalje je pravi alat. Za obično izvješće, fakturu ili izvod znači da pristupačnost izlaza ovisi o tome da nitko nikada ne zaboravi par, u svakoj putanji koda koja išta crta

Što pokrivaju bitovi načina

SetAutoTagMode prima bitovsku masku i vraća način koji je prethodno bio na snazi. AUTOTAG_TEXT (1) označava tekst kao odlomak, ili kao naslov kad je on na redu. AUTOTAG_FURNITURE (2) označava tekuća zaglavlja, podnožja i brojeve stranica kao artefakte. AUTOTAG_FIGURE (4) pretvara nacrtanu sliku u figuru, ili u artefakt kad je proglašena ukrasnom. AUTOTAG_TABLE (8) unosi nacrtane tablice u stablo strukture. AUTOTAG_DEFAULT je 15, što je sve četiri

Uključivanje načina također označava dokument kao označeni, i taj korak manje je kozmetički nego što zvuči. Čitač smatra dokument neoznačenim osim ako katalog ne kaže drukčije (ISO 32000-1 §14.7.1), pa se datoteka koja nosi potpuno stablo strukture bez deklaracije /MarkInfo najavljuje pomoćnoj tehnologiji kao da uopće nema strukturu. Stablo je tu, ali ga ništa ne čita

Dijagram SetAutoTagMode bitnih maski koje preslikavaju obične Delphi naredbe za crtanje u označeno PDF stablo strukture, uz istaknutu Marked zastavicu kao obveznu
Svaki aktivni bit SetAutoTagMode usmjerava obične pozive za crtanje u odgovarajući element stabla strukture
var
  Lib: TPDFlib;
begin
  Lib := TPDFlib.Create;
  try
    Lib.SetOrigin(1);
    Lib.SetAutoTagMode(AUTOTAG_DEFAULT);   // text + furniture + figures + tables
    Lib.AddStandardFont(4);
    Lib.SetTextSize(18);
    Lib.RegisterHeading(1, 'Annual service report');
    Lib.DrawText(72, 96, 'Annual service report');   // becomes H1
    Lib.SetTextSize(11);
    Lib.DrawText(72, 130, 'Every unit installed before 2024 was inspected.');
    Lib.SaveToFile('report.pdf');
  finally
    Lib.Free;
  end;
end;

Otkud naslov zna kojem tekstu pripada?

RegisterHeading imenuje razinu za sljedeći nacrtani tekst i čeka na tekst. Ako se između nacrta slika, slika postaje figura, a naslov ostaje na čekanju za tekst koji slijedi. To ponašanje je namjerno: alternativa, u kojoj slika preuzima razinu naslova, proizvodila je dokumente u kojima je ukrasna crta pod naslovom bila najavljivana kao naslov

Isto pravilo utrošeno na jednu stavku vrijedi za figure. RegisterFigure dostavlja opis koji sljedeća slika nosi, a RegisterDecoration proglašava sljedeću sliku crtom, okvirom ili pozadinom koja ne nosi značenje. Oboje se troši na jednu sliku, tako da kasnija slika nikada ne nasljeđuje opis namijenjen ranijoj, što je način na koji alt tekst završi pridružen pogrešnoj slici u ručno označenom kodu

Opis je važniji od ijednog drugog pojedinog niza znakova u pristupačnom dokumentu. Čitatelj koji ne vidi dobiva opis umjesto slike, i to je sve što dobiva. Grafikon nije opis; Tromjesečni prihod po regijama, s istočnom regijom najvišom u Q3, jest

PDF Library for Delphi dijagram koji prikazuje kako registrirani PDF naslov čeka iza umetnute slike dok se RegisterFigure i RegisterDecoration svaki potroše točno na jednu sliku
RegisterHeading čeka sljedeći tekst neovisno o tome što se u međuvremenu još crta
Lib.RegisterFigure('Exploded view of the gearbox assembly');
Lib.AddImageFromFile('gearbox.png', 0);      // becomes a tagged Figure

Lib.RegisterDecoration;                       // meaningless rule
Lib.AddImageFromFile('divider.png', 0);       // drawn inside a layout artifact

Tablice, zaglavlja i gdje živi odluka o ponavljanju

S uključenim bitom tablice, DrawTableRows unosi tablicu, njene redove i ćelije u stablo strukture, tako da čitač može reći u kojem se stupcu nalazi vrijednost umjesto da pročita cijelu tablicu kao niz nepovezanog teksta. SetTableHeaderRowCount imenuje koliko vodećih redova su zaglavlja; ti se redovi zapisuju kao ćelije zaglavlja koje nose opseg stupca, što je što čitatelju omogućuje da najavi naslov vrijednosti na kojoj se korisnik nalazi

Redovi zaglavlja imenovani na ovaj način ostaju gdje jesu. Njihovo ponavljanje na vrhu svake stranice je odluka rasporeda, i takvom ostaje: DrawTaggedTableRows prima argument RepeatHeaderRows upravo u tu svrhu. Držanje ovih dviju stvari odvojenima izbjegava da stablo strukture dobije drugi primjerak zaglavlja pri svakom prijelomu stranice, što bi automatsko ponavljanje proizvelo

PDF Library for Delphi dijagram ćelija zaglavlja tablice koje nose opseg stupca u stablu strukture dok RepeatHeaderRows ponavljanje pri prijelomu stranice ostavlja isključivo kao odluku o izgledu
Reci zaglavlja postoje u stablu strukture samo jednom, uz opseg stupca dodijeljen svakoj TH ćeliji
var
  TableID: Integer;
begin
  TableID := Lib.CreateTable(40, 3);
  Lib.SetTableHeaderRowCount(TableID, 1);       // redak 1 je traka zaglavlja
  Lib.SetTableCellContent(TableID, 1, 1, 'Part');
  Lib.SetTableCellContent(TableID, 1, 2, 'Torque');
  Lib.SetTableCellContent(TableID, 1, 3, 'Unit');
  // ... ispuni retke s podacima ...
  // Iscrtaj retke 1..40 u traku od 600pt i ponovi jedan redak zaglavlja po stranici
  Lib.DrawTaggedTableRows(TableID, 72, 150, 600, 1, 40, 1);
end;

Miješanje automatskog i ručnog označavanja

Automatsko označavanje se povlači unutar oznake otvorene ručno. Dio dokumenta može opisati vaš kod, a ostatak prepustiti knjižnici, bez da se dvije ugniježđuju jedna u drugu, što je raspored koji većina stvarnih dokumenata želi. Naslovnica i blok potpisa imaju strukturu koju razumijete samo vi; dvjesto stranica temeljnog teksta između nemaju

Dva sigurnosna pravila drže izlaz čistim. Ništa se ne označava unutar artefakta, jer sadržaj označen kao artefakt ne smije nositi nijedan element strukture. A prazan tekst ne otvara nijedan element, pa slučajni DrawText s praznim nizom znakova ne može proizvesti element strukture koji bi čitač najavio kao prazan. Oboje su vrsta defekata koje ručno označeni dokumenti tiho nakupljaju, a validator prijavljuje u masi mjesecima kasnije

Što automatsko označavanje još uvijek ne odlučuje za vas

Redoslijed čitanja izvan redoslijeda crtanja, semantičke uloge koje nisu odlomak, naslov, figura ili tablica te jezične deklaracije. Automatsko označavanje dodjeljuje strukturu redoslijedom kojim se sadržaj crta. Ako vaš kod rasporeda crta bočnu traku prije tijela, taj je redoslijed onaj koji stablo zapisuje. Za dokumente u kojima se vizualni redoslijed i redoslijed čitanja stvarno razlikuju, API za ručno označavanje ostaje pravi alat, a prikaz označenog PDF-a i strukture pristupačnosti detaljno pokriva uloge, opsege i veze zaglavlja

Kad je dokument završen, provjerite umjesto da pretpostavljate: bilješke o PDF/A i PDF/UA preletu pokazuju kako doći do presude o strukturi koju ste proizveli, a prikaz izvoza izvješća vođenog skupom podataka pokriva gdje se ti pozivi uklapaju u mehanizam izvješća koji generira raspored iz podataka

PDF Library for Delphi je izvorna Pascal PDF knjižnica za Delphi, C++Builder i Lazarus bez vanjskog PDF izvršnog okruženja, pa pristupačni izlaz proizvodi isti kod koji crta dokument. Pogledajte stranicu proizvoda PDF Library for Delphi za cijeli popis API-ja i platformi