PDFlibPas gali žymėti dokumentą jam braižant. Įjunkite SetAutoTagMode, ir paprasti DrawText kvietimai tampa paragrafais, tekstas, braižomas iškart po RegisterHeading, tampa to lygio antrašte, tekusios antraštės ir poraštės tampa artefaktais, kuriuos skaitytuvas praleidžia, paveikslai tampa figūromis, o DrawTableRows perneša lentelę, jos eilutes ir langelius į struktūros medį
Alternatyva — ir iki neseniai vienintelis pasirinkimas — buvo rankiniu būdu suvynioti kiekvieną braižymo kvietimą į BeginTag ir EndTag. Tai veikia, ir dokumentams su neįprasta struktūra tai vis dar teisingas įrankis. Paprastai ataskaitai, sąskaitai faktūrai ar išrašui tai reiškia, kad išvesties prieinamumas priklauso nuo to, ar niekas niekada nepamirš vienos poros, visuose kodo keliuose, kur braižoma bet kas
Ką apima režimo bitai
SetAutoTagMode priima bitų kaukę ir grąžina anksčiau galiojusį režimą. AUTOTAG_TEXT (1) žymi tekstą kaip paragrafą arba, kai jo laukas, kaip antraštę. AUTOTAG_FURNITURE (2) pažymi tekusias antraštes, poraštes ir puslapių numerius kaip artefaktus. AUTOTAG_FIGURE (4) paveikia nubraižytą paveikslą į figūrą arba, jei jis paskelbtas dekoratyviniu, į artefaktą. AUTOTAG_TABLE (8) perneša nubraižytas lenteles į struktūros medį. AUTOTAG_DEFAULT yra 15, tai yra visi keturi
Režimo įjungimas taip pat pažymi dokumentą kaip pažymėtą, ir šis žingsnis nėra toks kosmetinis, kaip skamba. Skaitytuvas laiko dokumentą nepažymėtu, nebent katalogas sako kitaip (ISO 32000-1 §14.7.1), todėl failas, nešantis baigtą struktūros medį be /MarkInfo deklaracijos, yra pranešamas pagalbinės technologijos kaip visai neturintis struktūros. Medis yra ten; niekas jo neskaito
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;
Iš kur antraštė žino, kuriam tekstui ji priklauso?
RegisterHeading nurodo lygį kitam brėžiamam tekstui ir laukia teksto. Jei tarp jų nubraižomas paveikslas, paveikslas tampa figūra, o antraštė lieka laukianti teksto, kuris eina po jos. Ši elgsena sąmoninga: alternatyva, kur paveikslas pasiima antraštės lygį, gamino dokumentus, kuriuose dekoratyvinė linija po pavadinimu buvo pranešama kaip pats pavadinimas
Ta pati „suvartota vienam elementui“ taisyklė valdo figūras. RegisterFigure pateikia aprašą, kurį neša kitas paveikslas, o RegisterDecoration paskelbia kitą paveikslą linija, rėmeliu ar fonu, neturinčiu prasmės. Abu sunaudoja vienas paveikslas, todėl vėlesnis paveikslas niekada nepaveldi aprašo, skirto ankstesniam — būtent taip rankiniu būdu žymimame kode alt tekstas atsiduria prie netinkamo paveikslo
Aprašas svarbesnis nei bet kuri kita eilutė prieinamame dokumente. Nematantis skaitytojas gauna aprašą paveikslo vietoje, ir tai yra viskas, ką jis gauna. „Diagrama“ nėra aprašas; „Pajamos pagal regioną ketvirčiais, kur rytinis regionas didžiausias 3 ketvirtį“ yra aprašas
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
Lentelės, antraščių eilutės ir kur gyvena kartojimo sprendimas
Įjungus lentelės bitą, DrawTableRows perneša lentelę, jos eilutes ir langelius į struktūros medį, kad skaitytuvas galėtų pasakyti, kuriame stulpelyje yra reikšmė, užuot skaitęs visą lentelę kaip nesusišijusio teksto eilutę. SetTableHeaderRowCount nurodo, kiek pirminių eilučių yra antraštės; tos eilutės rašomos kaip antraštės langeliai, nešantys stulpelio aprėptį, ir būtent tai leidžia skaitytuvui pranešti antraštę tos reikšmės, prie kurios yra vartotojas
Taip pavadintos antraštės eilutės lieka ten, kur yra. Jų kartojimas kiekvieno puslapio viršuje yra išdėstymo sprendimas, ir toks jis ir lieka: DrawTaggedTableRows priima RepeatHeaderRows argumentą būtent tam tikslui. Laikant du dalykus atskirai, išvengiama, kad struktūros medis įgytų antrą antraštės kopiją kiekvienam puslapio lūžiui, ką ir pagamintų automatinis kartojimas
var
TableID: Integer;
begin
TableID := Lib.CreateTable(40, 3);
Lib.SetTableHeaderRowCount(TableID, 1); // row 1 is the header band
Lib.SetTableCellContent(TableID, 1, 1, 'Part');
Lib.SetTableCellContent(TableID, 1, 2, 'Torque');
Lib.SetTableCellContent(TableID, 1, 3, 'Unit');
// ... fill the data rows ...
// Draw rows 1..40 into a 600pt band, repeating one header row per page
Lib.DrawTaggedTableRows(TableID, 72, 150, 600, 1, 40, 1);
end;
Automatinio ir rankinio žymėjimo derinimas
Automatinis žymėjimas pasitraukia iš kelies ranka atvertos žymės viduje. Dalis dokumento gali būti aprašyta jūsų kodo, o likusi dalis palikta bibliotekai, be to, kad vienas su kitu susiliptų — ir būtent tokios sandaros nori dauguma realių dokumentų. Viršelio puslapis ir parašo blokas turi struktūrą, kurią suprantate tik jūs; du šimtai puslapių pagrindinio teksto tarp jų — ne
Dvi saugumo taisyklės palaiko išvestį švarią. Artefakto viduje niekas nežymima, nes turinys, pažymėtas kaip artefaktas, neturi nešti jokio struktūros elemento. Ir tuščias tekstas neatveria jokio elemento, todėl paklydęs DrawText su tuščia eilute negali pagaminti struktūros elemento, kurį skaitytuvas praneštų kaip tuščią. Abu yra tokio pobūdžio defektai, kuriuos rankiniu būdu žymimi dokumentai tyliai kaupia, ir kurių validatorius praneša gausiai po kelių mėnesių
Ko automatinis žymėjimas vis dar jums nepriima
Skaitymo tvarka, viršijanti braižymo tvarką, semantiniai vaidmenys, kurie nėra paragrafas, antraštė, figūra ar lentelė, ir kalbos deklaracijos. Automatinis žymėjimas priskiria struktūrą tvarka, kuria braižomas turinys — jei jūsų išdėstymo kodas braižo šoninę juostą prieš pagrindinį tekstą, tokia tvarka medis ir įrašo. Dokumentams, kuriuose vizualinė tvarka ir skaitymo tvarka iš tikrųjų skiriasi, rankinio žymėjimo API lieka teisingu įrankiu, o pažymėto PDF ir prieinamumo struktūros aprašymas detaliai padengia vaidmenis, aprėptis ir antraštės saitus
Kai dokumentas baigtas, patikrinkite, o nepriimkite kaip savaime suprantamo: PDF/A ir PDF/UA skrydžio prieš tai pastabos parodo, kaip gauti verdiktą apie struktūrą, kurią pagaminote, o duomenų rinkiniu grįsto ataskaitų eksporto aprašymas padengia, kur šie kvietimai tinka ataskaitų variklyje, kuris generuoja savo išdėstymą iš duomenų
PDFlibPas yra natyvi Pascal PDF biblioteka, skirta Delphi, C++Builder ir Lazarus, be išorinės PDF vykdymo aplinkos, todėl prieinamą išvestį gamina tas pats kodas, kuris braižo dokumentą — žr. PDFlibPas produkto puslapį pilnam API ir platformų sąrašui