Skip to content

Commit 7d77290

Browse files
author
Dmitry Radchuk
committed
Add automatic link alternative description parsing
DEVSIX-7996
1 parent ac7912d commit 7d77290

File tree

11 files changed

+94
-12
lines changed

11 files changed

+94
-12
lines changed

src/main/java/com/itextpdf/html2pdf/attach/impl/tags/ABlockTagWorker.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public void processEnd(IElementNode element, ProcessorContext context) {
7171
}
7272
}
7373
((Div) getElementResult()).getAccessibilityProperties().setRole(StandardRoles.LINK);
74-
LinkHelper.applyLinkAnnotation(getElementResult(), url, context);
74+
LinkHelper.applyLinkAnnotation(getElementResult(), url, context, element);
7575
}
7676

7777
if (getElementResult() != null) {

src/main/java/com/itextpdf/html2pdf/attach/impl/tags/ATagWorker.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public void processEnd(IElementNode element, ProcessorContext context) {
100100
}
101101
getAllElements().set(i, simulatedDiv);
102102
}
103-
LinkHelper.applyLinkAnnotation(getAllElements().get(i), url, context);
103+
LinkHelper.applyLinkAnnotation(getAllElements().get(i), url, context, element);
104104
}
105105
}
106106

src/main/java/com/itextpdf/html2pdf/attach/util/LinkHelper.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,18 @@ This file is part of the iText (R) project.
3636
import com.itextpdf.kernel.pdf.annot.PdfAnnotation;
3737
import com.itextpdf.kernel.pdf.annot.PdfLinkAnnotation;
3838
import com.itextpdf.kernel.pdf.tagging.StandardRoles;
39+
import com.itextpdf.kernel.pdf.tagutils.AccessibilityProperties;
3940
import com.itextpdf.layout.tagging.IAccessibleElement;
4041
import com.itextpdf.layout.IPropertyContainer;
4142
import com.itextpdf.layout.element.ILeafElement;
4243
import com.itextpdf.layout.properties.Property;
4344
import com.itextpdf.html2pdf.html.AttributeConstants;
4445
import com.itextpdf.styledxmlparser.node.IElementNode;
4546
import java.util.List;
47+
48+
import com.itextpdf.styledxmlparser.node.INode;
49+
import com.itextpdf.styledxmlparser.node.impl.jsoup.node.JsoupElementNode;
50+
import com.itextpdf.styledxmlparser.node.impl.jsoup.node.JsoupNode;
4651
import org.slf4j.Logger;
4752
import org.slf4j.LoggerFactory;
4853

@@ -80,7 +85,34 @@ public static void applyLinkAnnotation(IPropertyContainer container, String url)
8085
* @param url the destination.
8186
* @param context the processor context.
8287
*/
88+
@Deprecated
8389
public static void applyLinkAnnotation(IPropertyContainer container, String url, ProcessorContext context) {
90+
applyLinkAnnotation(container, url, context, "");
91+
}
92+
93+
private static String retrieveAlternativeDescription(IElementNode element) {
94+
List<INode> children = element.childNodes();
95+
//if there is an img tag under the link then prefer the alt attribute as a link description
96+
if (children.size() == 1
97+
&& children.get(0).childNodes().isEmpty()
98+
&& children.get(0) instanceof JsoupElementNode
99+
&& ((JsoupElementNode)children.get(0)).getAttribute(AttributeConstants.ALT) != null) {
100+
return ((JsoupElementNode)children.get(0)).getAttribute(AttributeConstants.ALT);
101+
}
102+
//return title attribute value in case of regular link
103+
return element.getAttribute(AttributeConstants.TITLE);
104+
}
105+
106+
/**
107+
* Applies a link annotation.
108+
*
109+
* @param container the containing object.
110+
* @param url the destination.
111+
* @param context the processor context.
112+
* @param alternateDescription description for a link.
113+
*/
114+
@Deprecated
115+
public static void applyLinkAnnotation(IPropertyContainer container, String url, ProcessorContext context, String alternateDescription) {
84116
if (container != null) {
85117
PdfLinkAnnotation linkAnnotation;
86118
if (url.startsWith("#")) {
@@ -94,6 +126,9 @@ public static void applyLinkAnnotation(IPropertyContainer container, String url,
94126
} else {
95127
linkAnnotation = (PdfLinkAnnotation) new PdfLinkAnnotation(new Rectangle(0, 0, 0, 0)).setAction(PdfAction.createURI(url)).setFlags(PdfAnnotation.PRINT);
96128
}
129+
if (container instanceof IAccessibleElement && alternateDescription != null) {
130+
((IAccessibleElement) container).getAccessibilityProperties().setAlternateDescription(alternateDescription);
131+
}
97132
linkAnnotation.setBorder(new PdfArray(new float[]{0, 0, 0}));
98133
container.setProperty(Property.LINK_ANNOTATION, linkAnnotation);
99134
if (container instanceof ILeafElement && container instanceof IAccessibleElement) {
@@ -102,6 +137,18 @@ public static void applyLinkAnnotation(IPropertyContainer container, String url,
102137
}
103138
}
104139

140+
/**
141+
* Applies a link annotation.
142+
*
143+
* @param container the containing object.
144+
* @param url the destination.
145+
* @param context the processor context.
146+
* @param element the element node.
147+
*/
148+
public static void applyLinkAnnotation(IPropertyContainer container, String url, ProcessorContext context, IElementNode element) {
149+
LinkHelper.applyLinkAnnotation(container, url, context, retrieveAlternativeDescription(element));
150+
}
151+
105152
/**
106153
* Creates a destination
107154
*

src/test/java/com/itextpdf/html2pdf/HtmlConverterPdfUA2Test.java

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,9 @@ public void simpleLinkTest() throws IOException, InterruptedException, XMPExcept
7676
converterProperties.setFontProvider(fontProvider);
7777
HtmlConverter.convertToPdf(new FileInputStream(sourceHtml), pdfDocument, converterProperties);
7878

79-
/* TODO: DEVSIX-7996 - Links created from html2pdf are not ua-2 compliant
80-
* Two verapdf errors are generated here:
81-
* 1. clause="8.9.4.1", Link annotation neither has a Contents entry nor alternate description.
82-
* 2. clause="8.5.1", Real content that does not possess the semantics of text objects and does not have
79+
/* TODO: DEVSIX-5700 - Links created from html2pdf are not ua-2 compliant
80+
* One verapdf error is generated here:
81+
* 1. clause="8.5.1", Real content that does not possess the semantics of text objects and does not have
8382
* an alternate textual representation is not enclosed within Figure or Formula structure elements.
8483
*/
8584
compareAndCheckCompliance(destinationPdf, cmpPdf, false);
@@ -100,10 +99,33 @@ public void backwardLinkTest() throws IOException, InterruptedException, XMPExce
10099
converterProperties.setFontProvider(fontProvider);
101100
HtmlConverter.convertToPdf(new FileInputStream(sourceHtml), pdfDocument, converterProperties);
102101

103-
/* TODO: DEVSIX-7996 - Links created from html2pdf are not ua-2 compliant
104-
* Two verapdf errors are generated here:
105-
* 1. clause="8.9.4.1", Link annotation neither has a Contents entry nor alternate description.
106-
* 2. clause="8.5.1", Real content that does not possess the semantics of text objects and does not have
102+
/* TODO: DEVSIX-5700 - Links created from html2pdf are not ua-2 compliant
103+
* One verapdf error is generated here:
104+
* 1. clause="8.5.1", Real content that does not possess the semantics of text objects and does not have
105+
* an alternate textual representation is not enclosed within Figure or Formula structure elements.
106+
*/
107+
compareAndCheckCompliance(destinationPdf, cmpPdf, false);
108+
}
109+
110+
@Test
111+
public void imageLinkTest() throws IOException, InterruptedException, XMPException {
112+
String sourceHtml = SOURCE_FOLDER + "imageLink.html";
113+
String cmpPdf = SOURCE_FOLDER + "cmp_imageLink.pdf";
114+
String destinationPdf = DESTINATION_FOLDER + "imageLink.pdf";
115+
116+
PdfDocument pdfDocument = new PdfDocument(new PdfWriter(destinationPdf, new WriterProperties().setPdfVersion(
117+
PdfVersion.PDF_2_0)));
118+
createSimplePdfUA2Document(pdfDocument);
119+
120+
ConverterProperties converterProperties = new ConverterProperties();
121+
FontProvider fontProvider = new DefaultFontProvider(false, true, false);
122+
converterProperties.setFontProvider(fontProvider);
123+
converterProperties.setBaseUri(SOURCE_FOLDER);
124+
HtmlConverter.convertToPdf(new FileInputStream(sourceHtml), pdfDocument, converterProperties);
125+
126+
/* TODO: DEVSIX-5700 - Links created from html2pdf are not ua-2 compliant
127+
* One verapdf error is generated here:
128+
* 1. clause="8.5.1", Real content that does not possess the semantics of text objects and does not have
107129
* an alternate textual representation is not enclosed within Figure or Formula structure elements.
108130
*/
109131
compareAndCheckCompliance(destinationPdf, cmpPdf, false);

src/test/resources/com/itextpdf/html2pdf/HtmlConverterPdfUA2Test/backwardLink.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
<div id="15=15">Target div</div>
99
<div style="height:1000px">Some content</div>
10-
<a href="#15=15">Long link text to bottom div. Long link text to bottom div. Long link text to bottom div.
10+
<a href="#15=15" title="alternative description">Long link text to bottom div. Long link text to bottom div. Long link text to bottom div.
1111
Long link text to bottom div. Long link text to bottom div. Long link text to bottom div.</a>
1212

1313
</body>
1010 Bytes
Loading
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
5+
</head>
6+
<body>
7+
8+
<a href="#15=15" title="alternative description"><img alt="blue96x96" src="blue96x96.png"></a>
9+
<div style="height:1000px">Some content</div>
10+
<div id="15=15">Target div</div>
11+
12+
</body>
13+
</html>

0 commit comments

Comments
 (0)