From 408dc4e9ba440096bb6460bd904fbcf4d7d60ed2 Mon Sep 17 00:00:00 2001 From: Andrei Augustin <36695484+andreiaugustin@users.noreply.github.com> Date: Sun, 17 Dec 2023 21:11:46 +0200 Subject: [PATCH] Add PDF/UA subset (#1485) * Added PDF/UA subset and its metadata * Added PDF/UA metadata unit tests * Added PDF/UA subset to accessibility docs * Updated change log for PDF/UA subset --- CHANGELOG.md | 4 ++++ docs/accessibility.md | 2 ++ lib/mixins/pdfua.js | 24 ++++++++++++++++++++++++ lib/mixins/subsets.js | 5 +++++ tests/unit/pdfua.spec.js | 37 +++++++++++++++++++++++++++++++++++++ 5 files changed, 72 insertions(+) create mode 100644 lib/mixins/pdfua.js create mode 100644 tests/unit/pdfua.spec.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 79dc840ad..8484fc9a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## pdfkit changelog +### Unreleased + +- Add subset for PDF/UA + ### [v0.14.0] - 2023-11-09 - Add support for PDF/A-1b, PDF/A-1a, PDF/A-2b, PDF/A-2a, PDF/A-3b, PDF/A-3a diff --git a/docs/accessibility.md b/docs/accessibility.md index 098faec92..79de1e413 100644 --- a/docs/accessibility.md +++ b/docs/accessibility.md @@ -14,6 +14,8 @@ Universal Accessibility) document (which is an extension of Tagged PDF): * Pass the option `pdfVersion: '1.5'` (or a higher version) when creating your `PDFDocument` (depending on the features you use, you may only need 1.4; refer to the PDF reference for details). + * Pass the option `subset: 'PDF/UA'` when creating your `PDFDocument` (if you wish the PDF to + be identified as PDF/UA-1). * Pass the option `tagged: true` when creating your `PDFDocument` (technically, this sets the `Marked` property in the `Markings` dictionary to `true` in the PDF). * Provide a `Title` in the `info` option, and pass `displayTitle: true` when creating your diff --git a/lib/mixins/pdfua.js b/lib/mixins/pdfua.js new file mode 100644 index 000000000..89fd9e3ae --- /dev/null +++ b/lib/mixins/pdfua.js @@ -0,0 +1,24 @@ + +export default { + + initPDFUA() { + this.subset = 1; + }, + + endSubset() { + this._addPdfuaMetadata(); + }, + + _addPdfuaMetadata() { + this.appendXML(this._getPdfuaid()); + }, + + _getPdfuaid() { + return ` + + ${this.subset} + + `; + }, + +} \ No newline at end of file diff --git a/lib/mixins/subsets.js b/lib/mixins/subsets.js index b076efa1d..f2875ecf2 100644 --- a/lib/mixins/subsets.js +++ b/lib/mixins/subsets.js @@ -1,4 +1,5 @@ import PDFA from './pdfa'; +import PDFUA from './pdfua'; export default { _importSubset(subset) { @@ -20,6 +21,10 @@ export default { this._importSubset(PDFA); this.initPDFA(options.subset); break; + case 'PDF/UA': + this._importSubset(PDFUA); + this.initPDFUA(); + break; } } } \ No newline at end of file diff --git a/tests/unit/pdfua.spec.js b/tests/unit/pdfua.spec.js new file mode 100644 index 000000000..28e3e4f61 --- /dev/null +++ b/tests/unit/pdfua.spec.js @@ -0,0 +1,37 @@ +import PDFDocument from '../../lib/document'; +import { logData } from './helpers'; + +describe('PDF/UA', () => { + + test('metadata is present', () => { + let options = { + autoFirstPage: false, + pdfVersion: '1.7', + subset: 'PDF/UA', + tagged: true + }; + let doc = new PDFDocument(options); + const data = logData(doc); + doc.end(); + expect(data).toContainChunk([ + `11 0 obj`, + `<<\n/length 841\n/Type /Metadata\n/Subtype /XML\n/Length 843\n>>` + ]); + }); + + test('metadata constains pdfuaid part', () => { + let options = { + autoFirstPage: false, + pdfVersion: '1.7', + subset: 'PDF/UA', + tagged: true + }; + let doc = new PDFDocument(options); + const data = logData(doc); + doc.end(); + let metadata = Buffer.from(data[24]).toString(); + + expect(metadata).toContain('pdfuaid:part>1'); + }); + +}); \ No newline at end of file