Skip to content

Commit

Permalink
Merge pull request #282 from metanorma/pdf_a
Browse files Browse the repository at this point in the history
PDF/A-3A validation fix
  • Loading branch information
Intelligent2013 authored Sep 12, 2024
2 parents b6c044a + 6a6e8cf commit 55b8a45
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 29 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ SHELL ?= /bin/bash
endif

#JAR_VERSION := $(shell mvn -q -Dexec.executable="echo" -Dexec.args='$${project.version}' --non-recursive exec:exec -DforceStdout)
JAR_VERSION := 1.99
JAR_VERSION := 2.00
JAR_FILE := mn2pdf-$(JAR_VERSION).jar

all: target/$(JAR_FILE)
Expand Down
10 changes: 5 additions & 5 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ You will need the Java Development Kit (JDK) version 8, Update 241 (8u241) or hi

[source,sh]
----
java -Xss5m -Xmx2048m -jar target/mn2pdf-1.99.jar --xml-file <XML-FileName> --xsl-file <XSLT-FileName> --pdf-file <Output-PDF-FileName> [--syntax-highlight]
java -Xss5m -Xmx2048m -jar target/mn2pdf-2.00.jar --xml-file <XML-FileName> --xsl-file <XSLT-FileName> --pdf-file <Output-PDF-FileName> [--syntax-highlight]
----

e.g.

[source,sh]
----
java -Xss5m -Xmx2048m -jar target/mn2pdf-1.99.jar --xml-file tests/G.191.xml --xsl-file tests/itu.recommendation.xsl --pdf-file tests/G.191.pdf
java -Xss5m -Xmx2048m -jar target/mn2pdf-2.00.jar --xml-file tests/G.191.xml --xsl-file tests/itu.recommendation.xsl --pdf-file tests/G.191.pdf
----

=== PDF encryption features
Expand Down Expand Up @@ -100,7 +100,7 @@ Update version in `pom.xml`, e.g.:
----
<groupId>org.metanorma.fop</groupId>
<artifactId>mn2pdf</artifactId>
<version>1.99</version>
<version>2.00</version>
<name>Metanorma XML to PDF converter</name>
----

Expand All @@ -111,8 +111,8 @@ Tag the same version in Git:

[source,xml]
----
git tag v1.99
git push origin v1.99
git tag v2.00
git push origin v2.00
----

Then the corresponding GitHub release will be automatically created at:
Expand Down
56 changes: 38 additions & 18 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.metanorma.fop</groupId>
<artifactId>mn2pdf</artifactId>
<version>1.99</version>
<version>2.00</version>
<name>Metanorma XML to PDF converter</name>
<packaging>jar</packaging>
<url>https://www.metanorma.org</url>
Expand Down Expand Up @@ -96,25 +96,35 @@
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/services/org.apache.xmlgraphics.image.loader.spi.ImagePreloader</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>org.metanorma.fop.mn2pdf</Main-Class>
<Implementation-Version>${project.version}</Implementation-Version>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/services/org.apache.xmlgraphics.image.loader.spi.ImagePreloader</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>org.metanorma.fop.mn2pdf</Main-Class>
<Implementation-Version>${project.version}</Implementation-Version>
</manifestEntries>
</transformer>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
Expand Down Expand Up @@ -282,5 +292,15 @@
<artifactId>webp-imageio</artifactId>
<version>0.1.6</version>
</dependency>
<dependency>
<groupId>org.verapdf</groupId>
<artifactId>validation-model</artifactId>
<version>1.26.1</version>
</dependency>
<dependency>
<groupId>org.verapdf</groupId>
<artifactId>validation-model-jakarta</artifactId>
<version>1.26.1</version>
</dependency>
</dependencies>
</project>
13 changes: 13 additions & 0 deletions src/main/java/org/metanorma/fop/PDFConformanceChecker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.metanorma.fop;

import static org.metanorma.Constants.PDF_A_MODE;

public class PDFConformanceChecker {

public static boolean hasException(String msg) {
if (msg != null) {
return msg.contains("PDFConformanceException") && (msg.contains("PDF/UA-1") || msg.contains(PDF_A_MODE));
}
return false;
}
}
18 changes: 14 additions & 4 deletions src/main/java/org/metanorma/fop/PDFGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,11 @@ private void convertmn2pdf(fontConfig fontcfg, XSLTconverter xsltConverter, File
logger.info(WARNING_NONPDFUA);
}

// validate PDF by veraPDF
VeraPDFValidator veraPDFValidator = new VeraPDFValidator();
veraPDFValidator.validate(pdf);


fontcfg.printMessages();

} catch (Exception e) {
Expand Down Expand Up @@ -580,6 +585,13 @@ private void runFOP (fontConfig fontcfg, Source src, File pdf) throws IOExceptio
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
// configure foUserAgent
foUserAgent.setProducer("Ribose Metanorma mn2pdf version " + Util.getAppVersion());

if (encryptionParams.isEmpty()) {
foUserAgent.getRendererOptions().put("pdf-a-mode", PDF_A_MODE);
} else {
logger.severe("PDF/A doesn't allow encrypted PDFs. PDF will be generated in non-PDF/A mode.");
}

setEncryptionParams(foUserAgent);

//Adding a simple logging listener that writes to stdout and stderr
Expand Down Expand Up @@ -641,8 +653,7 @@ private void runFOP (fontConfig fontcfg, Source src, File pdf) throws IOExceptio
}

} catch (Exception e) {
String excstr=e.toString();
if (excstr.contains("PDFConformanceException") && excstr.contains("PDF/UA-1") && !PDFUA_error) { // excstr.contains("all fonts, even the base 14 fonts, have to be embedded")
if (PDFConformanceChecker.hasException(e.toString()) && !PDFUA_error) { // excstr.contains("all fonts, even the base 14 fonts, have to be embedded")
//System.err.println(e.toString());
logger.severe(e.toString());
PDFUA_error = true;
Expand Down Expand Up @@ -1053,8 +1064,7 @@ public void error(TransformerException exc)

public void fatalError(TransformerException exc)
throws TransformerException {
String excstr=exc.toString();
if (excstr.contains("PDFConformanceException") && excstr.contains("PDF/UA-1") && !PDFUA_error) { // excstr.contains("all fonts, even the base 14 fonts, have to be embedded")
if (PDFConformanceChecker.hasException(exc.toString()) && !PDFUA_error) { // excstr.contains("all fonts, even the base 14 fonts, have to be embedded")
//System.err.println(exc.toString());
logger.severe(exc.toString());
PDFUA_error = true;
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/org/metanorma/fop/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,13 @@ public static int getStringWidth(String text, String fontName) {
return stringWidth;
}

public static float getStringWidthByFontSize(String text, String fontName, int fontSize) {
float stringWidth = 0.0f;
Font font = new Font(fontName, Font.PLAIN, fontSize);
stringWidth = SVGUtilities.getStringWidth(text, font);
return stringWidth;
}

public static String saveFileToDisk(String filename, String content) {
try {
Files.createDirectories(tmpfilepath);
Expand Down
55 changes: 55 additions & 0 deletions src/main/java/org/metanorma/fop/VeraPDFValidator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package org.metanorma.fop;

import org.metanorma.utils.LoggerHelper;
import org.verapdf.core.EncryptedPdfException;
import org.verapdf.core.ModelParsingException;
import org.verapdf.core.ValidationException;
import org.verapdf.gf.foundry.VeraGreenfieldFoundryProvider;
import org.verapdf.pdfa.Foundries;
import org.verapdf.pdfa.PDFAParser;
import org.verapdf.pdfa.results.ValidationResult;
import org.verapdf.pdfa.PDFAValidator;
import org.verapdf.pdfa.flavours.PDFAFlavour;
import org.verapdf.report.HTMLReport;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.logging.Logger;

import static org.metanorma.Constants.PDF_A_MODE;

public class VeraPDFValidator {

protected static final Logger logger = Logger.getLogger(LoggerHelper.LOGGER_NAME);

// see https://docs.verapdf.org/develop/
public void validate(File filePDF) {
VeraGreenfieldFoundryProvider.initialise();
String sPDFAmode = PDF_A_MODE.substring(PDF_A_MODE.indexOf("-"));
PDFAFlavour flavour = PDFAFlavour.fromString(sPDFAmode);
try (PDFAParser parser = Foundries.defaultInstance().createParser(new FileInputStream(filePDF), flavour)) {
PDFAValidator validator = Foundries.defaultInstance().createValidator(flavour, false);
ValidationResult result = validator.validate(parser);

if (result.isCompliant()) {
// File is a valid PDF/A PDF_A_MODE
return;
} else {
// it isn't
logger.severe("PDF isn't valid " + PDF_A_MODE + ":");
String veraPDFresult = result.toString();
veraPDFresult = veraPDFresult.replaceAll("(TestAssertion )","\n$1")
.replaceAll("\\s(message=)","\n$1")
.replaceAll("\\s(location=)","\n$1");
logger.severe(veraPDFresult);
//HTMLReport.writeHTMLReport()
}
} catch (IOException | ValidationException | ModelParsingException | EncryptedPdfException exception) {
// Exception during validation
logger.severe(exception.toString());
}
return;
}

}
2 changes: 2 additions & 0 deletions src/main/java/org/metanorma/fop/annotations/Annotation.java
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ public void process(File pdf, String xmlReview) throws IOException {

PDAnnotation pdfannot = PDAnnotation.createAnnotation(fdfannot.getCOSObject());

pdfannot.constructAppearances(); // requires for PDF/A

if (map_pdfannots.get(page) == null) {
map_pdfannots.put(page, new ArrayList<PDAnnotation>());
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/xfdf_simple.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
<text>
<xsl:attribute name="color"><xsl:value-of select="$color_annotation"/></xsl:attribute>
<xsl:attribute name="opacity"><xsl:value-of select="$opacity_popup"/></xsl:attribute>
<xsl:attribute name="flags">nozoom,norotate</xsl:attribute>
<xsl:attribute name="flags">print,nozoom,norotate</xsl:attribute>
<xsl:attribute name="date"><xsl:value-of select="$date"/></xsl:attribute>
<xsl:attribute name="page"><xsl:value-of select="$page - 1"/></xsl:attribute>
<xsl:attribute name="rect"><xsl:value-of select="concat($element_from/@x,',',$element_from/@y)"/></xsl:attribute>
Expand Down

0 comments on commit 55b8a45

Please sign in to comment.