Fully support accessibility features from PDF reference.

This commit is contained in:
Ben Schmidt 2020-09-28 22:36:26 +10:00 committed by Luiz Américo
parent c177874e82
commit 272444e397
4 changed files with 54 additions and 3 deletions

View File

@ -15,9 +15,11 @@ This checklist covers everything that is required to create a conformant Tagged
details).
* Pass the option `tagged: true` when creating your `PDFDocument` (technically, this sets the
`Marked` property in the `Markings` dictionary to `true` in the PDF).
* Specify natural language in the document options and/or logical structure and/or
non-structure marked `Span` content.
* Add logical structure with all significant content included.
* Include accessibility information (such as alternative text, actual text, etc.) in the
logical structure.
logical structure and/or non-structure marked `Span` content.
* Include all spaces which separate words/sentences/etc. in your marked structure content,
even at the ends of lines, paragraphs, etc.. I.e. don't do `doc.text("Hello, world!")` but
instead do `doc.text("Hello, world! ")`.
@ -53,6 +55,17 @@ When marking content, you can provide options (take care to use correct capitali
coordinates
* `attached` - used for `Pagination` artifact content, array of one or more strings:
`Top`, `Bottom`, `Left`, `Right`
* `lang` - used for `Span` content: human language code (e.g. `en-AU`) which overrides default
document language, and any enclosing structure element language
* `alt` - used for `Span` content: alternative text for an image or other visual content
* `expanded` - used for `Span` content: the expanded form of an abbreviation or acronym
* `actual` - used for `Span` content: the actual text the content represents (e.g. if it is
rendered as vector graphics)
It is advisable not to use `Span` content for specifying alternative text, expanded form, or
actual text, especially if there is a possibility of the content automatically wrapping, which
would result in the text appearing twice. Set these options on an associated structure element
instead.
## Logical Structure

View File

@ -74,6 +74,10 @@ class PDFDocument extends stream.Readable {
Names
});
if (this.options.lang) {
this._root.data.Lang = new String(this.options.lang);
}
// The current page
this.page = null;

View File

@ -57,6 +57,20 @@ export default {
dictionary.Attached = options.attached;
}
}
if (tag === 'Span') {
if (options.lang) {
dictionary.Lang = new String(options.lang);
}
if (options.alt) {
dictionary.Alt = new String(options.alt);
}
if (options.expanded) {
dictionary.E = new String(options.expanded);
}
if (options.actual) {
dictionary.ActualText = new String(options.actual);
}
}
this.addContent(`/${tag} ${PDFObject.convert(dictionary)} BDC`);
return this;

View File

@ -91,6 +91,13 @@ EMC
/Attached [/Top]
>> BDC
EMC
/Span <<
/Lang (en-AU)
/Alt (Hi, earth! )
/E (Greetings, terrestrial sphere! )
/ActualText (Hello, world! )
>> BDC
EMC
`,
'binary'
);
@ -101,6 +108,13 @@ EMC
attached: [ "Top" ]
});
document.endMarkedContent();
document.markContent("Span", {
lang: "en-AU",
alt: "Hi, earth! ",
actual: "Hello, world! ",
expanded: "Greetings, terrestrial sphere! "
});
document.endMarkedContent();
document.end();
expect(docData).toContainChunk([
@ -447,18 +461,24 @@ EMC
]);
});
test('identified as tagged', () => {
test('identified as accessible', () => {
document = new PDFDocument({
info: { CreationDate: new Date(Date.UTC(2018, 1, 1)) },
compress: false,
pdfVersion: '1.5',
tagged: true
tagged: true,
lang: 'en-AU'
});
const docData = logData(document);
document.end();
expect(docData).toContainChunk([
`3 0 obj`,
/\/Lang \(en-AU\)/,
`endobj`
]);
expect(docData).toContainChunk([
`3 0 obj`,
/\/Markings 5 0 R/,