Experimental support for embedded SVG in HTML5

git-svn-id: svn://svn.code.sf.net/p/writer2latex/code/trunk@146 f0f2a975-2e09-46c8-9428-3b39399b9f3c
This commit is contained in:
henrikjust 2012-04-03 07:50:53 +00:00
parent d1ef4d8f8c
commit 71bff7e653
13 changed files with 187 additions and 115 deletions

View file

@ -2,6 +2,8 @@ Changelog for Writer2LaTeX version 1.2 -> 1.4
---------- version 1.3.1 alpha ---------- ---------- version 1.3.1 alpha ----------
[w2x] New boolean option use_svg (default false): If export format is HTML5 vector graphics are exported as inline SVG, if possible
[w2x] Added support for HTML5 as export type (the ConverterFactory understands the pseudo-MIME type text/html5). [w2x] Added support for HTML5 as export type (the ConverterFactory understands the pseudo-MIME type text/html5).
The converter creates polyglot HTML5 documents, i.e. documents will be conforming to HTML5 as well as XML standards. The converter creates polyglot HTML5 documents, i.e. documents will be conforming to HTML5 as well as XML standards.

View file

@ -16,11 +16,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA * MA 02111-1307 USA
* *
* Copyright: 2002-2011 by Henrik Just * Copyright: 2002-2012 by Henrik Just
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.2 (2011-07-22) * Version 1.4 (2012-04-03)
*/ */
@ -76,8 +76,9 @@ public class GraphicConverterImpl1 implements GraphicConverter {
// We don't support cropping and resizing // We don't support cropping and resizing
if (bCrop || bResize) { return false; } if (bCrop || bResize) { return false; }
// We can convert vector formats to eps: // We can convert vector formats to EPS.
if (MIMETypes.EPS.equals(sTargetMime) && // The IDL reference claims we can convert to SVG too, but for some reason this always returns an empty array?
if ((MIMETypes.EPS.equals(sTargetMime)) && // || MIMETypes.SVG.equals(sTargetMime)) &&
(MIMETypes.EMF.equals(sSourceMime) || MIMETypes.WMF.equals(sSourceMime) || MIMETypes.SVM.equals(sSourceMime))) { (MIMETypes.EMF.equals(sSourceMime) || MIMETypes.WMF.equals(sSourceMime) || MIMETypes.SVM.equals(sSourceMime))) {
return true; return true;
} }
@ -96,7 +97,6 @@ public class GraphicConverterImpl1 implements GraphicConverter {
} }
public byte[] convert(byte[] source, String sSourceMime, String sTargetMime) { public byte[] convert(byte[] source, String sSourceMime, String sTargetMime) {
// It seems that the GraphicProvider can only create proper eps if // It seems that the GraphicProvider can only create proper eps if
// the source is a vector format, hence // the source is a vector format, hence
if (MIMETypes.EPS.equals(sTargetMime)) { if (MIMETypes.EPS.equals(sTargetMime)) {
@ -125,15 +125,15 @@ public class GraphicConverterImpl1 implements GraphicConverter {
targetProps[1].Value = xTarget; targetProps[1].Value = xTarget;
xGraphicProvider.storeGraphic(result,targetProps); xGraphicProvider.storeGraphic(result,targetProps);
// Close the output and return the result // Close the output and return the result
xTarget.closeOutput();
xTarget.flush(); xTarget.flush();
xTarget.closeOutput();
if (MIMETypes.EPS.equals(sTargetMime)) { if (MIMETypes.EPS.equals(sTargetMime)) {
return epsCleaner.cleanEps(xTarget.getBuffer()); return epsCleaner.cleanEps(xTarget.getBuffer());
} }
else { else {
return xTarget.getBuffer(); byte[] converted = xTarget.getBuffer();
return converted;
} }
} }
catch (com.sun.star.io.IOException e) { catch (com.sun.star.io.IOException e) {

View file

@ -16,11 +16,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA * MA 02111-1307 USA
* *
* Copyright: 2002-2009 by Henrik Just * Copyright: 2002-2012 by Henrik Just
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.2 (2009-03-26) * Version 1.4 (2012-04-03)
* *
*/ */
@ -67,7 +67,7 @@ public class GraphicConverterImpl2 implements GraphicConverter {
importFilter = new Hashtable<String,String>(); importFilter = new Hashtable<String,String>();
importFilter.put(MIMETypes.BMP, "BMP - MS Windows"); importFilter.put(MIMETypes.BMP, "BMP - MS Windows");
//importFilter.put(MIMETypes.EMF, "EMF - MS Windows Metafile"); importFilter.put(MIMETypes.EMF, "EMF - MS Windows Metafile");
importFilter.put(MIMETypes.EPS, "EPS - Encapsulated PostScript"); importFilter.put(MIMETypes.EPS, "EPS - Encapsulated PostScript");
importFilter.put(MIMETypes.GIF, "GIF - Graphics Interchange Format"); importFilter.put(MIMETypes.GIF, "GIF - Graphics Interchange Format");
importFilter.put(MIMETypes.JPEG, "JPG - JPEG"); importFilter.put(MIMETypes.JPEG, "JPG - JPEG");
@ -78,12 +78,12 @@ public class GraphicConverterImpl2 implements GraphicConverter {
exportFilter = new Hashtable<String,String>(); exportFilter = new Hashtable<String,String>();
exportFilter.put(MIMETypes.BMP,"draw_bmp_Export"); exportFilter.put(MIMETypes.BMP,"draw_bmp_Export");
//exportFilter.put(MIMETypes.EMF,"draw_emf_Export"); exportFilter.put(MIMETypes.EMF,"draw_emf_Export");
exportFilter.put(MIMETypes.EPS,"draw_eps_Export"); exportFilter.put(MIMETypes.EPS,"draw_eps_Export");
exportFilter.put(MIMETypes.GIF,"draw_gif_Export"); exportFilter.put(MIMETypes.GIF,"draw_gif_Export");
exportFilter.put(MIMETypes.JPEG,"draw_jpg_Export"); exportFilter.put(MIMETypes.JPEG,"draw_jpg_Export");
exportFilter.put(MIMETypes.PNG,"draw_png_Export"); exportFilter.put(MIMETypes.PNG,"draw_png_Export");
//exportFilter.put(MIMETypes.SVG,"draw_svg_Export"); exportFilter.put(MIMETypes.SVG,"draw_svg_Export");
exportFilter.put(MIMETypes.SVM,"draw_svm_Export"); exportFilter.put(MIMETypes.SVM,"draw_svm_Export");
exportFilter.put(MIMETypes.TIFF,"draw_tif_Export"); exportFilter.put(MIMETypes.TIFF,"draw_tif_Export");
exportFilter.put(MIMETypes.WMF,"draw_wmf_Export"); exportFilter.put(MIMETypes.WMF,"draw_wmf_Export");
@ -96,22 +96,23 @@ public class GraphicConverterImpl2 implements GraphicConverter {
// We don't support cropping and resizing // We don't support cropping and resizing
if (bCrop || bResize) { return false; } if (bCrop || bResize) { return false; }
// We currently support conversion of bitmaps and svm into pdf and eps // We currently support conversion of bitmaps and SVM into PDF, EPS and SVG
// Trying wmf causes an IllegalArgumentException "URL seems to be an unsupported one" // TODO: SVG does not seem to work in all versions of OOo/LO?
// Trying WMF/EMF causes an IllegalArgumentException "URL seems to be an unsupported one"
// Seems to be an OOo bug; workaround: Use temporary files..?? // Seems to be an OOo bug; workaround: Use temporary files..??
boolean bSupportsSource = MIMETypes.SVM.equals(sSourceMime) || boolean bSupportsSource = MIMETypes.SVM.equals(sSourceMime) ||
MIMETypes.PNG.equals(sSourceMime) || MIMETypes.JPEG.equals(sSourceMime) || MIMETypes.PNG.equals(sSourceMime) || MIMETypes.JPEG.equals(sSourceMime) ||
MIMETypes.GIF.equals(sSourceMime) || MIMETypes.TIFF.equals(sSourceMime) || MIMETypes.GIF.equals(sSourceMime) || MIMETypes.TIFF.equals(sSourceMime) ||
MIMETypes.BMP.equals(sSourceMime); MIMETypes.BMP.equals(sSourceMime);
// || MIMETypes.WMF.equals(sSourceMime) //|| MIMETypes.WMF.equals(sSourceMime) || MIMETypes.EMF.equals(sSourceMime);
boolean bSupportsTarget = MIMETypes.PDF.equals(sTargetMime) || MIMETypes.EPS.equals(sTargetMime); boolean bSupportsTarget = MIMETypes.PDF.equals(sTargetMime) || MIMETypes.EPS.equals(sTargetMime) ||
MIMETypes.SVG.equals(sTargetMime);
return bSupportsSource && bSupportsTarget; return bSupportsSource && bSupportsTarget;
} }
public byte[] convert(byte[] source, String sSourceMime, String sTargetMime) { public byte[] convert(byte[] source, String sSourceMime, String sTargetMime) {
// Open a hidden sdraw document // Open a hidden sdraw document
XMultiComponentFactory xMCF = xComponentContext.getServiceManager(); XMultiComponentFactory xMCF = xComponentContext.getServiceManager();
try { try {
// Load the graphic into a new draw document as xDocument // Load the graphic into a new draw document as xDocument
// using a named filter // using a named filter
@ -168,7 +169,7 @@ public class GraphicConverterImpl2 implements GraphicConverter {
refreshDocument(xDocument); refreshDocument(xDocument);
XOutputStreamToByteArrayAdapter outputStream = new XOutputStreamToByteArrayAdapter(); XOutputStreamToByteArrayAdapter outputStream = new XOutputStreamToByteArrayAdapter();
PropertyValue[] exportProps = new PropertyValue[3]; PropertyValue[] exportProps = new PropertyValue[3];
exportProps[0] = new PropertyValue(); exportProps[0] = new PropertyValue();
exportProps[0].Name = "FilterName"; exportProps[0].Name = "FilterName";
@ -186,6 +187,7 @@ public class GraphicConverterImpl2 implements GraphicConverter {
outputStream.closeOutput(); outputStream.closeOutput();
byte[] result = outputStream.getBuffer(); byte[] result = outputStream.getBuffer();
xDocument.dispose(); xDocument.dispose();
if (MIMETypes.EPS.equals(sTargetMime)) { if (MIMETypes.EPS.equals(sTargetMime)) {
@ -213,9 +215,8 @@ public class GraphicConverterImpl2 implements GraphicConverter {
// Conversion failed, for whatever reason // Conversion failed, for whatever reason
return null; return null;
}
}
protected void refreshDocument(XComponent document) { protected void refreshDocument(XComponent document) {
XRefreshable refreshable = (XRefreshable) UnoRuntime.queryInterface(XRefreshable.class, document); XRefreshable refreshable = (XRefreshable) UnoRuntime.queryInterface(XRefreshable.class, document);
if (refreshable != null) { if (refreshable != null) {

View file

@ -20,7 +20,7 @@
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.4 (2012-03-28) * Version 1.4 (2012-04-03)
* *
*/ */
@ -33,7 +33,7 @@ public class ConverterFactory {
// Version information // Version information
private static final String VERSION = "1.3.1"; private static final String VERSION = "1.3.1";
private static final String DATE = "2012-03-28"; private static final String DATE = "2012-04-03";
/** Return the Writer2LaTeX version in the form /** Return the Writer2LaTeX version in the form
* (major version).(minor version).(patch level)<br/> * (major version).(minor version).(patch level)<br/>

View file

@ -20,7 +20,7 @@
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.4 (2012-03-27) * Version 1.4 (2012-04-01)
* *
*/ */
@ -40,6 +40,7 @@ public class MIMETypes {
public static final String EMF="image/x-emf"; public static final String EMF="image/x-emf";
public static final String WMF="image/x-wmf"; public static final String WMF="image/x-wmf";
public static final String EPS="image/x-eps"; public static final String EPS="image/x-eps";
public static final String SVG="image/svg+xml";
// MIME type for SVM has changed // MIME type for SVM has changed
//public static final String SVM="image/x-svm"; //public static final String SVM="image/x-svm";
public static final String SVM="application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\""; public static final String SVM="application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"";

View file

@ -16,19 +16,16 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA * MA 02111-1307 USA
* *
* Copyright: 2002-2011 by Henrik Just * Copyright: 2002-2012 by Henrik Just
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.2 (2011-07-22) * Version 1.4 (2012-04-03)
* *
*/ */
package writer2latex.office; package writer2latex.office;
//import java.io.ByteArrayInputStream;
//import java.io.ByteArrayOutputStream;
//import java.io.IOException;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.util.HashSet; import java.util.HashSet;
@ -41,8 +38,6 @@ import writer2latex.util.Base64;
import writer2latex.util.Misc; import writer2latex.util.Misc;
import writer2latex.xmerge.BinaryGraphicsDocument; import writer2latex.xmerge.BinaryGraphicsDocument;
//import writer2latex.util.*;
/** /**
* <p>This class extracts images from an OOo file. * <p>This class extracts images from an OOo file.
* The images are returned as BinaryGraphicsDocument.</p> * The images are returned as BinaryGraphicsDocument.</p>
@ -169,24 +164,24 @@ public final class ImageLoader {
// is not in an accepted format AND the converter knows how to // is not in an accepted format AND the converter knows how to
// convert it - try to convert... // convert it - try to convert...
if (gcv!=null && !isAcceptedFormat(sMIME) && sDefaultFormat!=null) { if (gcv!=null && !isAcceptedFormat(sMIME) && sDefaultFormat!=null) {
byte[] newBlob = null;
String sTargetMIME = null; String sTargetMIME = null;
if (MIMETypes.isVectorFormat(sMIME) && sDefaultVectorFormat!=null && if (MIMETypes.isVectorFormat(sMIME) && sDefaultVectorFormat!=null &&
gcv.supportsConversion(sMIME,sDefaultVectorFormat,false,false)) { gcv.supportsConversion(sMIME,sDefaultVectorFormat,false,false)) {
sTargetMIME = sDefaultVectorFormat; // Try vector format first
newBlob = gcv.convert(blob, sMIME, sTargetMIME=sDefaultVectorFormat);
} }
else if (gcv.supportsConversion(sMIME,sDefaultFormat,false,false)) { else if (gcv.supportsConversion(sMIME,sDefaultFormat,false,false)) {
sTargetMIME = sDefaultFormat; // Then try bitmap format
newBlob = gcv.convert(blob,sMIME,sTargetMIME=sDefaultFormat);
} }
if (sTargetMIME!=null) { if (newBlob!=null) {
byte[] newBlob = gcv.convert(blob,sMIME,sTargetMIME); // Conversion successful - create new data
if (newBlob!=null) { blob = newBlob;
// Conversion succesful - create new data sMIME = sTargetMIME;
blob = newBlob; sExt = MIMETypes.getFileExtension(sMIME);
sMIME = sTargetMIME;
sExt = MIMETypes.getFileExtension(sMIME);
}
} }
} }

View file

@ -16,11 +16,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA * MA 02111-1307 USA
* *
* Copyright: 2002-2011 by Henrik Just * Copyright: 2002-2012 by Henrik Just
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.2 (2011-08-05) * Version 1.4 (2012-04-01)
* *
*/ */
@ -61,6 +61,7 @@ public final class MIMETypes extends writer2latex.api.MIMETypes {
public static final byte[] EPS_SIG = { 0x25, 0x21 }; // %! public static final byte[] EPS_SIG = { 0x25, 0x21 }; // %!
public static final byte[] SVM_SIG = { 0x56, 0x43, 0x4c, 0x4d, 0x54, 0x46 }; // VCLMTF public static final byte[] SVM_SIG = { 0x56, 0x43, 0x4c, 0x4d, 0x54, 0x46 }; // VCLMTF
public static final byte[] ZIP_SIG = { 0x50, 0x4b, 0x03, 0x04 }; // PK.. public static final byte[] ZIP_SIG = { 0x50, 0x4b, 0x03, 0x04 }; // PK..
public static final byte[] SVG_SIG = { 0x3c, 0x73, 0x76, 0x67 }; // Not so magic: <svg
// Preferred file extensions for some files // Preferred file extensions for some files
@ -77,6 +78,7 @@ public final class MIMETypes extends writer2latex.api.MIMETypes {
public static final String EMF_EXT = ".emf"; public static final String EMF_EXT = ".emf";
public static final String WMF_EXT = ".wmf"; public static final String WMF_EXT = ".wmf";
public static final String EPS_EXT = ".eps"; public static final String EPS_EXT = ".eps";
public static final String SVG_EXT = ".svg";
public static final String SVM_EXT = ".svm"; public static final String SVM_EXT = ".svm";
public static final String PDF_EXT = ".pdf"; public static final String PDF_EXT = ".pdf";
@ -87,6 +89,24 @@ public final class MIMETypes extends writer2latex.api.MIMETypes {
} }
return true; return true;
} }
private static final boolean isSVG(byte[] blob) {
// Look for <svg within the first 250 bytes
int m = Math.max(blob.length, 250);
int n = SVG_SIG.length;
for (int j=0; j<m; j++) {
boolean bFound = true;
for (int i=0; i<n; i++) {
if (blob[j+i]!=SVG_SIG[i]) {
bFound = false;
break;
}
}
if (bFound) return true;
}
return false;
}
public static final String getMagicMIMEType(byte[] blob) { public static final String getMagicMIMEType(byte[] blob) {
if (isType(blob,PNG_SIG)) { return PNG; } if (isType(blob,PNG_SIG)) { return PNG; }
@ -102,6 +122,7 @@ public final class MIMETypes extends writer2latex.api.MIMETypes {
if (isType(blob,EPS_SIG)) { return EPS; } if (isType(blob,EPS_SIG)) { return EPS; }
if (isType(blob,SVM_SIG)) { return SVM; } if (isType(blob,SVM_SIG)) { return SVM; }
if (isType(blob,ZIP_SIG)) { return ZIP; } if (isType(blob,ZIP_SIG)) { return ZIP; }
if (isSVG(blob)) { return SVG; }
return ""; return "";
} }
@ -114,6 +135,7 @@ public final class MIMETypes extends writer2latex.api.MIMETypes {
if (EMF.equals(sMIME)) { return EMF_EXT; } if (EMF.equals(sMIME)) { return EMF_EXT; }
if (WMF.equals(sMIME)) { return WMF_EXT; } if (WMF.equals(sMIME)) { return WMF_EXT; }
if (EPS.equals(sMIME)) { return EPS_EXT; } if (EPS.equals(sMIME)) { return EPS_EXT; }
if (SVG.equals(sMIME)) { return SVG_EXT; }
if (SVM.equals(sMIME)) { return SVM_EXT; } if (SVM.equals(sMIME)) { return SVM_EXT; }
if (PDF.equals(sMIME)) { return PDF_EXT; } if (PDF.equals(sMIME)) { return PDF_EXT; }
if (LATEX.equals(sMIME)) { return LATEX_EXT; } if (LATEX.equals(sMIME)) { return LATEX_EXT; }
@ -125,7 +147,7 @@ public final class MIMETypes extends writer2latex.api.MIMETypes {
} }
public static boolean isVectorFormat(String sMIME) { public static boolean isVectorFormat(String sMIME) {
return EMF.equals(sMIME) || WMF.equals(sMIME) || EPS.equals(sMIME) || SVM.equals(sMIME) || PDF.equals(sMIME); return EMF.equals(sMIME) || WMF.equals(sMIME) || EPS.equals(sMIME) || SVG.equals(sMIME) || SVM.equals(sMIME) || PDF.equals(sMIME);
} }

View file

@ -20,7 +20,7 @@
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.4 (2012-03-27) * Version 1.4 (2012-04-01)
* *
*/ */
@ -43,7 +43,7 @@ import org.w3c.dom.Document;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import writer2latex.util.SimpleSAXHandler; import writer2latex.util.SimpleXMLParser;
import writer2latex.util.SimpleZipReader; import writer2latex.util.SimpleZipReader;
/** /**
@ -225,6 +225,7 @@ public class OfficeDocument {
* @param is Office document <code>InputStream</code>. * @param is Office document <code>InputStream</code>.
* *
* @throws IOException If any I/O error occurs. * @throws IOException If any I/O error occurs.
* @throws SAXException
*/ */
public void read(InputStream is) throws IOException { public void read(InputStream is) throws IOException {
// We need to read 4 bytes ahead to detect flat or zip format // We need to read 4 bytes ahead to detect flat or zip format
@ -295,21 +296,11 @@ public class OfficeDocument {
private void readFlat(InputStream is) throws IOException { private void readFlat(InputStream is) throws IOException {
SAXParserFactory factory=SAXParserFactory.newInstance();
SimpleSAXHandler handler = new SimpleSAXHandler();
try { try {
SAXParser saxParser = factory.newSAXParser(); contentDoc = SimpleXMLParser.parse(is);
saxParser.parse(is,handler); } catch (SAXException e) {
throw new IOException(e);
} }
catch (SAXException e){
System.err.println("Oops - Error parsing document");
e.printStackTrace();
}
catch (ParserConfigurationException e) {
System.err.println("Oops - failed to get XML parser!?");
e.printStackTrace();
}
contentDoc = handler.getDOM();
styleDoc = null; styleDoc = null;
settingsDoc = null; settingsDoc = null;
metaDoc = null; metaDoc = null;
@ -332,7 +323,7 @@ public class OfficeDocument {
*/ */
static Document parse(byte bytes[]) throws SAXException, IOException { static Document parse(byte bytes[]) throws SAXException, IOException {
SAXParserFactory factory=SAXParserFactory.newInstance(); SAXParserFactory factory=SAXParserFactory.newInstance();
SimpleSAXHandler handler = new SimpleSAXHandler(); SimpleXMLParser handler = new SimpleXMLParser();
try { try {
SAXParser saxParser = factory.newSAXParser(); SAXParser saxParser = factory.newSAXParser();
saxParser.parse(new ByteArrayInputStream(bytes),handler); saxParser.parse(new ByteArrayInputStream(bytes),handler);

View file

@ -20,28 +20,58 @@
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.4 (2012-03-23) * Version 1.4 (2012-04-01)
* *
*/ */
package writer2latex.util; package writer2latex.util;
import java.io.IOException;
import java.io.InputStream;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.w3c.dom.Document;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.DefaultHandler;
/** A simple SAX handler which transforms the SAX events into a DOM tree /** A simple SAX based XML parser which transforms the SAX events into a DOM tree
* (supporting element and text nodes only) * (supporting element and text nodes only)
*/ */
public class SimpleSAXHandler extends DefaultHandler { public class SimpleXMLParser extends DefaultHandler {
/** Static method to parse an XML input stream into a DOM tree
*
* @param is the input stream to parse
* @return a DOM tree of the document
* @throws IOException if an error occurs reading the input stream
* @throws SAXException if an error occurs parsing the stream
*/
public static Document parse(InputStream is) throws IOException, SAXException {
SAXParserFactory factory=SAXParserFactory.newInstance();
SimpleXMLParser handler = new SimpleXMLParser();
try {
SAXParser saxParser = factory.newSAXParser();
saxParser.parse(is,handler);
return handler.getDOM();
}
catch (ParserConfigurationException e) {
System.err.println("Oops - failed to get XML parser!?");
e.printStackTrace();
}
return null;
}
private SimpleDOMBuilder builder = new SimpleDOMBuilder(); private SimpleDOMBuilder builder = new SimpleDOMBuilder();
public org.w3c.dom.Document getDOM() { public org.w3c.dom.Document getDOM() {
return builder.getDOM(); return builder.getDOM();
} }
@Override public void startElement(String nameSpace, String localName, String qName, Attributes attributes){ @Override public void startElement(String nameSpace, String localName, String qName, Attributes attributes){
builder.startElement(qName); builder.startElement(qName);
int nLen = attributes.getLength(); int nLen = attributes.getLength();

View file

@ -20,12 +20,10 @@
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.4 (2012-03-30) * Version 1.4 (2012-04-03)
* *
*/ */
// TODO: When polyglot markup uses either a textarea or pre element, the text within the element does not begin with a newline.
package writer2latex.xhtml; package writer2latex.xhtml;
import java.io.File; import java.io.File;
@ -51,11 +49,8 @@ import writer2latex.api.Config;
import writer2latex.api.ContentEntry; import writer2latex.api.ContentEntry;
import writer2latex.api.ConverterFactory; import writer2latex.api.ConverterFactory;
import writer2latex.api.OutputFile; import writer2latex.api.OutputFile;
//import writer2latex.api.ConverterResult;
import writer2latex.base.ContentEntryImpl; import writer2latex.base.ContentEntryImpl;
import writer2latex.base.ConverterBase; import writer2latex.base.ConverterBase;
//import writer2latex.latex.LaTeXDocumentPortion;
//import writer2latex.latex.util.Context;
import writer2latex.office.MIMETypes; import writer2latex.office.MIMETypes;
import writer2latex.office.OfficeReader; import writer2latex.office.OfficeReader;
import writer2latex.office.StyleWithProperties; import writer2latex.office.StyleWithProperties;
@ -266,6 +261,10 @@ public class Converter extends ConverterBase {
imageLoader.setDefaultFormat(MIMETypes.PNG); imageLoader.setDefaultFormat(MIMETypes.PNG);
imageLoader.addAcceptedFormat(MIMETypes.JPEG); imageLoader.addAcceptedFormat(MIMETypes.JPEG);
imageLoader.addAcceptedFormat(MIMETypes.GIF); imageLoader.addAcceptedFormat(MIMETypes.GIF);
if (nType==XhtmlDocument.HTML5 && config.useSVG()) { // HTML supports (inline) SVG as well
imageLoader.setDefaultVectorFormat(MIMETypes.SVG);
}
styleCv = new StyleConverter(ofr,config,this,nType); styleCv = new StyleConverter(ofr,config,this,nType);
textCv = new TextConverter(ofr,config,this); textCv = new TextConverter(ofr,config,this);

View file

@ -16,11 +16,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA * MA 02111-1307 USA
* *
* Copyright: 2002-2011 by Henrik Just * Copyright: 2002-2012 by Henrik Just
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.2 (2011-07-20) * Version 1.4 (2012-04-03)
* *
*/ */
@ -44,10 +44,12 @@ package writer2latex.xhtml;
import java.util.Iterator; import java.util.Iterator;
import java.util.Vector; import java.util.Vector;
import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.w3c.dom.Document;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import org.w3c.dom.Element; import org.w3c.dom.Element;
@ -56,6 +58,7 @@ import org.w3c.dom.Element;
import writer2latex.util.Misc; import writer2latex.util.Misc;
import writer2latex.util.CSVList; import writer2latex.util.CSVList;
import writer2latex.util.SimpleXMLParser;
import writer2latex.xmerge.BinaryGraphicsDocument; import writer2latex.xmerge.BinaryGraphicsDocument;
import writer2latex.office.EmbeddedObject; import writer2latex.office.EmbeddedObject;
import writer2latex.office.EmbeddedXMLObject; import writer2latex.office.EmbeddedXMLObject;
@ -98,6 +101,7 @@ public class DrawConverter extends ConverterHelper {
private int nImageSize; private int nImageSize;
private String sImageSplit; private String sImageSplit;
private boolean bCoverImage; private boolean bCoverImage;
private boolean bUseSVG;
// Frames in spreadsheet documents are collected here // Frames in spreadsheet documents are collected here
private Vector<Element> frames = new Vector<Element>(); private Vector<Element> frames = new Vector<Element>();
@ -124,6 +128,7 @@ public class DrawConverter extends ConverterHelper {
nImageSize = config.imageSize(); nImageSize = config.imageSize();
sImageSplit = config.imageSplit(); sImageSplit = config.imageSplit();
bCoverImage = config.coverImage(); bCoverImage = config.coverImage();
bUseSVG = config.useSVG();
} }
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
@ -451,6 +456,7 @@ public class DrawConverter extends ConverterHelper {
} }
// Get the image from the ImageLoader // Get the image from the ImageLoader
BinaryGraphicsDocument bgd = null;
String sFileName = null; String sFileName = null;
String sHref = Misc.getAttribute(onode,XMLString.XLINK_HREF); String sHref = Misc.getAttribute(onode,XMLString.XLINK_HREF);
if (sHref!=null && sHref.length()>0 && !ofr.isInPackage(sHref)) { if (sHref!=null && sHref.length()>0 && !ofr.isInPackage(sHref)) {
@ -466,11 +472,10 @@ public class DrawConverter extends ConverterHelper {
} }
} }
else { // embedded or base64 encoded image else { // embedded or base64 encoded image
BinaryGraphicsDocument bgd = converter.getImageLoader().getImage(onode); bgd = converter.getImageLoader().getImage(onode);
if (bgd!=null) { if (bgd!=null) {
converter.addDocument(bgd);
sFileName = bgd.getFileName(); sFileName = bgd.getFileName();
// If this is the cover image, add it to the converter result // If this is the cover image, add it to the converter result
if (bCoverImage && onode==ofr.getFirstImage()) { if (bCoverImage && onode==ofr.getFirstImage()) {
converter.setCoverImageFile(bgd,null); converter.setCoverImageFile(bgd,null);
} }
@ -480,30 +485,49 @@ public class DrawConverter extends ConverterHelper {
if (sFileName==null) { return; } // TODO: Add warning? if (sFileName==null) { return; } // TODO: Add warning?
// Create the image (sFileName contains the file name) // Create the image (sFileName contains the file name)
Element image = converter.createElement("img"); Element imageElement = null;
String sName = Misc.getAttribute(getFrame(onode),XMLString.DRAW_NAME); if (converter.nType==XhtmlDocument.HTML5 && bUseSVG && bgd!=null && MIMETypes.SVG.equals(bgd.getMIMEType())) {
converter.addTarget(image,sName+"|graphic"); // In HTML5 we may embed SVG images directly in the document
image.setAttribute("src",sFileName); byte[] blob = bgd.getData();
try {
// Add alternative text, using either alt.text, name or file name Document dom = SimpleXMLParser.parse(new ByteArrayInputStream(blob));
Element desc = Misc.getChildByTagName(frame,XMLString.SVG_DESC); Element elm = hnodeInline!=null ? hnodeInline : hnodeBlock;
if (desc==null) { imageElement = (Element) elm.getOwnerDocument().importNode(dom.getDocumentElement(), true);
desc = Misc.getChildByTagName(frame,XMLString.SVG_TITLE); } catch (IOException e) {
// Will not happen with a byte array
} catch (SAXException e) {
e.printStackTrace();
}
} }
String sAltText = desc!=null ? Misc.getPCDATA(desc) : (sName!=null ? sName : sFileName); else {
image.setAttribute("alt",sAltText); // In all other cases, create an img element
if (bgd!=null) { converter.addDocument(bgd); }
Element image = converter.createElement("img");
String sName = Misc.getAttribute(getFrame(onode),XMLString.DRAW_NAME);
converter.addTarget(image,sName+"|graphic");
image.setAttribute("src",sFileName);
// Add alternative text, using either alt.text, name or file name
Element desc = Misc.getChildByTagName(frame,XMLString.SVG_DESC);
if (desc==null) {
desc = Misc.getChildByTagName(frame,XMLString.SVG_TITLE);
}
String sAltText = desc!=null ? Misc.getPCDATA(desc) : (sName!=null ? sName : sFileName);
image.setAttribute("alt",sAltText);
imageElement = image;
}
// Now style it
StyleInfo info = new StyleInfo();
String sStyleName = Misc.getAttribute(frame, XMLString.DRAW_STYLE_NAME);
if (nMode!=FULL_SCREEN) { getFrameSc().applyStyle(sStyleName,info); }
applyImageSize(frame,info.props,nMode,false);
// Now style it // Apply placement
StyleInfo info = new StyleInfo(); applyPlacement(frame, hnodeBlock, hnodeInline, nMode, imageElement, info);
String sStyleName = Misc.getAttribute(frame, XMLString.DRAW_STYLE_NAME);
if (nMode!=FULL_SCREEN) { getFrameSc().applyStyle(sStyleName,info); }
applyImageSize(frame,info.props,nMode,false);
// Apply placement applyStyle(info,imageElement);
applyPlacement(frame, hnodeBlock, hnodeInline, nMode, image, info); addLink(onode,imageElement);
applyStyle(info,image);
addLink(onode,image);
} }
private void handleDrawTextBox(Element onode, Element hnodeBlock, Element hnodeInline, int nMode) { private void handleDrawTextBox(Element onode, Element hnodeBlock, Element hnodeInline, int nMode) {

View file

@ -16,11 +16,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA * MA 02111-1307 USA
* *
* Copyright: 2002-2011 by Henrik Just * Copyright: 2002-2012 by Henrik Just
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.2 (2011-06-16) * Version 1.4 (2012-04-03)
* *
*/ */
@ -41,7 +41,7 @@ import writer2latex.util.Misc;
public class XhtmlConfig extends writer2latex.base.ConfigBase { public class XhtmlConfig extends writer2latex.base.ConfigBase {
// Implement configuration methods // Implement configuration methods
protected int getOptionCount() { return 56; } protected int getOptionCount() { return 57; }
protected String getDefaultConfigPath() { return "/writer2latex/xhtml/config/"; } protected String getDefaultConfigPath() { return "/writer2latex/xhtml/config/"; }
// Override setOption: To be backwards compatible, we must accept options // Override setOption: To be backwards compatible, we must accept options
@ -137,19 +137,20 @@ public class XhtmlConfig extends writer2latex.base.ConfigBase {
private static final int SPLIT_AFTER = 40; private static final int SPLIT_AFTER = 40;
private static final int IMAGE_SPLIT = 41; private static final int IMAGE_SPLIT = 41;
private static final int COVER_IMAGE = 42; private static final int COVER_IMAGE = 42;
private static final int CALC_SPLIT = 43; private static final int USE_SVG = 43;
private static final int DISPLAY_HIDDEN_SHEETS = 44; private static final int CALC_SPLIT = 44;
private static final int DISPLAY_HIDDEN_ROWS_COLS = 45; private static final int DISPLAY_HIDDEN_SHEETS = 45;
private static final int DISPLAY_FILTERED_ROWS_COLS = 46; private static final int DISPLAY_HIDDEN_ROWS_COLS = 46;
private static final int APPLY_PRINT_RANGES = 47; private static final int DISPLAY_FILTERED_ROWS_COLS = 47;
private static final int USE_TITLE_AS_HEADING = 48; private static final int APPLY_PRINT_RANGES = 48;
private static final int USE_SHEET_NAMES_AS_HEADINGS = 49; private static final int USE_TITLE_AS_HEADING = 49;
private static final int XSLT_PATH = 50; private static final int USE_SHEET_NAMES_AS_HEADINGS = 50;
private static final int SAVE_IMAGES_IN_SUBDIR = 51; private static final int XSLT_PATH = 51;
private static final int UPLINK = 52; private static final int SAVE_IMAGES_IN_SUBDIR = 52;
private static final int DIRECTORY_ICON = 53; private static final int UPLINK = 53;
private static final int DOCUMENT_ICON = 54; private static final int DIRECTORY_ICON = 54;
private static final int ZEN_HACK = 55; // temporary hack for ePub Zen Garden styles private static final int DOCUMENT_ICON = 55;
private static final int ZEN_HACK = 56; // temporary hack for ePub Zen Garden styles
protected ComplexOption xheading = addComplexOption("heading-map"); protected ComplexOption xheading = addComplexOption("heading-map");
protected ComplexOption xpar = addComplexOption("paragraph-map"); protected ComplexOption xpar = addComplexOption("paragraph-map");
@ -260,6 +261,7 @@ public class XhtmlConfig extends writer2latex.base.ConfigBase {
}; };
options[IMAGE_SPLIT] = new Option("image_split","none"); options[IMAGE_SPLIT] = new Option("image_split","none");
options[COVER_IMAGE] = new BooleanOption("cover_image","false"); options[COVER_IMAGE] = new BooleanOption("cover_image","false");
options[USE_SVG] = new BooleanOption("use_svg","false");
options[CALC_SPLIT] = new BooleanOption("calc_split","false"); options[CALC_SPLIT] = new BooleanOption("calc_split","false");
options[DISPLAY_HIDDEN_SHEETS] = new BooleanOption("display_hidden_sheets", "false"); options[DISPLAY_HIDDEN_SHEETS] = new BooleanOption("display_hidden_sheets", "false");
options[DISPLAY_HIDDEN_ROWS_COLS] = new BooleanOption("display_hidden_rows_cols","false"); options[DISPLAY_HIDDEN_ROWS_COLS] = new BooleanOption("display_hidden_rows_cols","false");
@ -386,6 +388,7 @@ public class XhtmlConfig extends writer2latex.base.ConfigBase {
public int splitAfter() { return ((IntegerOption) options[SPLIT_AFTER]).getValue(); } public int splitAfter() { return ((IntegerOption) options[SPLIT_AFTER]).getValue(); }
public String imageSplit() { return options[IMAGE_SPLIT].getString(); } public String imageSplit() { return options[IMAGE_SPLIT].getString(); }
public boolean coverImage() { return ((BooleanOption) options[COVER_IMAGE]).getValue(); } public boolean coverImage() { return ((BooleanOption) options[COVER_IMAGE]).getValue(); }
public boolean useSVG() { return ((BooleanOption) options[USE_SVG]).getValue(); }
public boolean xhtmlCalcSplit() { return ((BooleanOption) options[CALC_SPLIT]).getValue(); } public boolean xhtmlCalcSplit() { return ((BooleanOption) options[CALC_SPLIT]).getValue(); }
public boolean xhtmlDisplayHiddenSheets() { return ((BooleanOption) options[DISPLAY_HIDDEN_SHEETS]).getValue(); } public boolean xhtmlDisplayHiddenSheets() { return ((BooleanOption) options[DISPLAY_HIDDEN_SHEETS]).getValue(); }
public boolean displayHiddenRowsCols() { return ((BooleanOption) options[DISPLAY_HIDDEN_ROWS_COLS]).getValue(); } public boolean displayHiddenRowsCols() { return ((BooleanOption) options[DISPLAY_HIDDEN_ROWS_COLS]).getValue(); }

View file

@ -16,11 +16,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA * MA 02111-1307 USA
* *
* Copyright: 2002-2010 by Henrik Just * Copyright: 2002-2012 by Henrik Just
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.2 (2010-03-28) * Version 1.4 (2012-04-01)
* *
*/ */
@ -128,6 +128,10 @@ public class BinaryGraphicsDocument implements Document {
return new String(docName + getFileExtension()); return new String(docName + getFileExtension());
} }
public byte[] getData() {
return data;
}
/** /**
* <p>Writes out the <code>Document</code> content to the specified * <p>Writes out the <code>Document</code> content to the specified