Skip to content

Commit

Permalink
Merge pull request #31 from metanorma/update
Browse files Browse the repository at this point in the history
Update for SVG processing
  • Loading branch information
Intelligent2013 authored May 9, 2020
2 parents ad664a1 + 2fbc9a7 commit 4999e3e
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 6 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.metanorma.fop</groupId>
<artifactId>mn2pdf</artifactId>
<version>1.13</version>
<version>1.14</version>
<name>Metanorma XML to PDF converter</name>
<packaging>jar</packaging>
<url>https://www.metanorma.com</url>
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/com/metanorma/fop/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.nio.channels.ReadableByteChannel;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Enumeration;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
Expand Down Expand Up @@ -124,4 +125,15 @@ public static String getAppVersion() {

return version;
}

public static String getDecodedBase64SVGnode(String encodedString) { //throws SAXException, IOException, ParserConfigurationException {
byte[] decodedBytes = Base64.getDecoder().decode(encodedString);
String decodedString = new String(decodedBytes);
return decodedString;
/*if (decodedString.startsWith("<?xml")) {
return decodedString.substring(decodedString.indexOf("?>") + 2);
} else {
return decodedString;
}*/
}
}
114 changes: 109 additions & 5 deletions src/main/java/com/metanorma/fop/mn2pdf.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,25 @@
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.CodeSource;
import java.text.MessageFormat;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.ErrorListener;

Expand All @@ -22,6 +31,7 @@
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
Expand All @@ -42,6 +52,11 @@
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import org.xml.sax.SAXException;

Expand Down Expand Up @@ -120,6 +135,10 @@ public class mn2pdf {

static final int ERROR_EXIT_CODE = -1;

static final String TMPDIR = System.getProperty("java.io.tmpdir");

final Path tmpfilepath = Paths.get(TMPDIR, UUID.randomUUID().toString());

/**
* Converts an XML file to a PDF file using FOP
*
Expand All @@ -130,13 +149,19 @@ public class mn2pdf {
* @throws IOException In case of an I/O problem
* @throws FOPException, SAXException In case of a FOP problem
*/
public void convertmn2pdf(String fontPath, File xml, File xsl, File pdf) throws IOException, FOPException, SAXException, TransformerException, TransformerConfigurationException, TransformerConfigurationException {
public void convertmn2pdf(String fontPath, File xml, File xsl, File pdf) throws IOException, FOPException, SAXException, TransformerException, TransformerConfigurationException, TransformerConfigurationException, ParserConfigurationException {



String imagesxml = getImageFilePath(xml);

try {
//Setup XSLT
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(new StreamSource(xsl));

transformer.setParameter("svg_images", imagesxml);

//Setup input for XSLT transformation
Source src = new StreamSource(xml);

Expand Down Expand Up @@ -174,11 +199,22 @@ public void convertmn2pdf(String fontPath, File xml, File xsl, File pdf) throws
fontcfg.setPDFUAmode("DISABLED");
runFOP(fontcfg, src, pdf, transformer);
}

} catch (Exception e) {
e.printStackTrace(System.err);
System.exit(ERROR_EXIT_CODE);
}
// flush temporary folder
if (!DEBUG) {
//Files.deleteIfExists(tmpfilepath);
try {
Files.walk(tmpfilepath)
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

private void runFOP (fontConfig fontcfg, Source src, File pdf, Transformer transformer) throws IOException, FOPException, SAXException, TransformerException, TransformerConfigurationException, TransformerConfigurationException {
Expand Down Expand Up @@ -237,7 +273,7 @@ public void error(TransformerException exc)
public void fatalError(TransformerException exc)
throws TransformerException {
String excstr=exc.toString();
if (excstr.contains("PDFConformanceException") && excstr.contains("all fonts, even the base 14 fonts, have to be embedded") && !PDFUA_error) {
if (excstr.contains("PDFConformanceException") && excstr.contains("PDF/UA-1") && !PDFUA_error) { // excstr.contains("all fonts, even the base 14 fonts, have to be embedded")
System.err.println(exc.toString());
PDFUA_error = true;
} else {
Expand Down Expand Up @@ -347,4 +383,72 @@ private static String getJaxpImplementationInfo(String componentName, Class comp
componentClass.getName(),
source == null ? "Java Runtime" : source.getLocation());
}

private String getImageFilePath(File xml) {
try {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
InputStream xmlstream = new FileInputStream(xml);
Document sourceXML = dBuilder.parse(xmlstream);
NodeList images = sourceXML.getElementsByTagName("image");

HashMap<String, String> svgmap = new HashMap<>();
for (int i = 0; i < images.getLength(); i++) {
Node image = images.item(i);
Node mimetype = image.getAttributes().getNamedItem("mimetype");
if (mimetype != null && mimetype.getTextContent().equals("image/svg+xml")) {
// decode base64 svg into external tmp file
Node svg_src = image.getAttributes().getNamedItem("src");
Node svg_id = image.getAttributes().getNamedItem("id");
if (svg_src != null && svg_id != null && svg_src.getTextContent().startsWith("data:image")) {
String base64svg = svg_src.getTextContent().substring(svg_src.getTextContent().indexOf("base64,")+7);
String xmlsvg = Util.getDecodedBase64SVGnode(base64svg);
try {
Files.createDirectories(tmpfilepath);
String id = svg_id.getTextContent();
Path svgpath = Paths.get(tmpfilepath.toString(), id + ".svg");
try (BufferedWriter bw = Files.newBufferedWriter(svgpath)) {
bw.write(xmlsvg);
}
svgmap.put(id, svgpath.toFile().toURI().toURL().toString());
} catch (IOException ex) {
System.err.println("Can't save svg file into a temporary directory " + tmpfilepath.toString());
ex.printStackTrace();;
}
}
}
}
if (!svgmap.isEmpty()) {
// crate map file for svg images
DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentFactory.newDocumentBuilder();
Document document = documentBuilder.newDocument();
Element root = document.createElement("images");
document.appendChild(root);
for (Map.Entry<String, String> item : svgmap.entrySet()) {
Element image = document.createElement("image");
root.appendChild(image);
Attr attr_id = document.createAttribute("id");
attr_id.setValue(item.getKey());
image.setAttributeNode(attr_id);
Attr attr_path = document.createAttribute("src");
attr_path.setValue(item.getValue());
image.setAttributeNode(attr_path);
}
// save xml 'images.xml' with svg links to temporary folder
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource domSource = new DOMSource(document);
Path outputPath = Paths.get(tmpfilepath.toString(), "images.xml");
StreamResult streamResult = new StreamResult(outputPath.toFile());
transformer.transform(domSource, streamResult);

return outputPath.toString();
}
} catch (Exception ex) {
System.err.println("Can't save images.xml into temporary folder");
ex.printStackTrace();
}
return "";
}
}

0 comments on commit 4999e3e

Please sign in to comment.