SVG support + merge spans + bugfixes

git-svn-id: svn://svn.code.sf.net/p/writer2latex/code/trunk@170 f0f2a975-2e09-46c8-9428-3b39399b9f3c
This commit is contained in:
henrikjust 2014-09-06 19:19:17 +00:00
parent a336023983
commit a0b76b3729
18 changed files with 212 additions and 130 deletions

View file

@ -2,6 +2,24 @@ Changelog for Writer2LaTeX version 1.2 -> 1.4
---------- version 1.3.2 alpha ---------- ---------- version 1.3.2 alpha ----------
[w2x] Two or more span elements in a row with identical attributes are now merged
[all] Filters: Appended [Writer2LaTeX] or [Writer2xhtml] to all filter UI names to make them more visible
[w2l] Bugfix: Avoid null pointer exception caused by list styles in some cases
[w2x] Bugfix: EPUB export filter works again (was broken in 1.3.1)
[w2x] Bugfix: Text boxes are no longer lost if within a paragraph
[w2x] SVG support in HTML5 is now finished: Vector graphics is converted to SVG (does not work in older versions of LO).
The option use_svg has been renamed to inline_svg. If set to true (default) inline SVG is used, if set to false,
external SVG-files are used.
[all] If an image image cannot be converted to an acceptable format, the optional alternative image will now be tried
[all] Bugfix: Avoid null pointer exception if a table has no defined table width
[w2l] Bugfix (StarMath conversion): Protect the character [ after \\ in gather and matrix environments [w2l] Bugfix (StarMath conversion): Protect the character [ after \\ in gather and matrix environments
[w2l] Bugfix: Protect the character [ after \\ in tables [w2l] Bugfix: Protect the character [ after \\ in tables
@ -29,7 +47,7 @@ Changelog for Writer2LaTeX version 1.2 -> 1.4
the option xslt_path has been removed. Also the vacant spot in the export dialog is now used for the option use_mathjax the option xslt_path has been removed. Also the vacant spot in the export dialog is now used for the option use_mathjax
(only active for XHTML+MathML and HTML5) (only active for XHTML+MathML and HTML5)
[w2l] Added support for TexMaths equations in LaTeX, XHTML+MathML and HTML5 (the last two only if use_mathjax=true) [all] Added support for TexMaths equations in LaTeX, XHTML+MathML and HTML5 (the last two only if use_mathjax=true)
[all] The command line application now gives an explanation if the source file is not in ODF format [all] The command line application now gives an explanation if the source file is not in ODF format

Binary file not shown.

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-2012 by Henrik Just * Copyright: 2002-2014 by Henrik Just
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.4 (2012-04-03) * Version 1.4 (2014-09-05)
*/ */
@ -76,9 +76,8 @@ 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 and SVG
// 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)) &&
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;
} }
@ -133,7 +132,10 @@ public class GraphicConverterImpl1 implements GraphicConverter {
} }
else { else {
byte[] converted = xTarget.getBuffer(); byte[] converted = xTarget.getBuffer();
return converted; if (converted.length>0) { // Older versions of AOO/LO fails to convert to SVG (empty result)
return converted;
}
return null;
} }
} }
catch (com.sun.star.io.IOException e) { catch (com.sun.star.io.IOException e) {

View file

@ -20,7 +20,7 @@
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.4 (2014-09-03) * Version 1.4 (2014-09-06)
* *
*/ */
@ -33,7 +33,7 @@ public class ConverterFactory {
// Version information // Version information
private static final String VERSION = "1.3.2"; private static final String VERSION = "1.3.2";
private static final String DATE = "2014-09-03"; private static final String DATE = "2014-09-06";
/** 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 (2014-09-03) * Version 1.4 (2014-09-05)
* *
*/ */
@ -30,7 +30,6 @@ import java.io.OutputStream;
import java.io.IOException; import java.io.IOException;
import writer2latex.api.OutputFile; import writer2latex.api.OutputFile;
import writer2latex.util.Misc;
/** This class is used to represent a binary graphics document to be included in the converter result. /** This class is used to represent a binary graphics document to be included in the converter result.
@ -40,37 +39,55 @@ import writer2latex.util.Misc;
public class BinaryGraphicsDocument implements OutputFile { public class BinaryGraphicsDocument implements OutputFile {
private String sFileName; private String sFileName;
private String sFileExtension;
private String sMimeType; private String sMimeType;
private boolean bIsLinked = false; private boolean bAcceptedFormat;
private boolean bIsAcceptedFormat = false;
private boolean bRecycled = false;
// Data for an embedded image // Data for an embedded image
private byte[] blob = null; private byte[] blob = null;
private int nOff; private int nOff = 0;
private int nLen; private int nLen = 0;
// Data for a linked image
private String sURL = null;
/**Constructs a new graphics document. /**Constructs a new graphics document.
* This new document does not contain any data. Document data must * Until data is added using the <code>read</code> methods, the document is considered a link to
* be added using the appropriate methods. * the image given by the file name.
* *
* @param sName The name of the <code>GraphicsDocument</code>. * @param sFileName The name or URL of the <code>GraphicsDocument</code>.
* @param sFileExtension the file extension
* @param sMimeType the MIME type of the document * @param sMimeType the MIME type of the document
*/ */
public BinaryGraphicsDocument(String sName, String sFileExtension, String sMimeType) { public BinaryGraphicsDocument(String sFileName, String sMimeType) {
this.sFileExtension = sFileExtension; this.sFileName = sFileName;
this.sMimeType = sMimeType; this.sMimeType = sMimeType;
sFileName = Misc.trimDocumentName(sName, sFileExtension); bAcceptedFormat = false; // or rather "don't know"
} }
/** Construct a new graphics document which is a recycled version of the supplied one.
* This implies that all information is identical, but the recycled version does not contain any data.
* This is for images that are used more than once in the document.
*
* @param bgd the source document
*/
public BinaryGraphicsDocument(BinaryGraphicsDocument bgd) {
this.sFileName = bgd.getFileName();
this.sMimeType = bgd.getMIMEType();
this.bAcceptedFormat = bgd.isAcceptedFormat();
this.bRecycled = true;
}
/** Is this graphics document recycled?
*
* @return true if this is the case
*/
public boolean isRecycled() {
return bRecycled;
}
/** Set image contents to a byte array /** Set image contents to a byte array
* *
* @param data the image data * @param data the image data
* @param bIsAcceptedFormat flag to indicate that the format of the image is acceptable for the converter
*/ */
public void setData(byte[] data, boolean bIsAcceptedFormat) { public void setData(byte[] data, boolean bIsAcceptedFormat) {
setData(data,0,data.length,bIsAcceptedFormat); setData(data,0,data.length,bIsAcceptedFormat);
@ -87,30 +104,7 @@ public class BinaryGraphicsDocument implements OutputFile {
this.blob = data; this.blob = data;
this.nOff = nOff; this.nOff = nOff;
this.nLen = nLen; this.nLen = nLen;
this.bIsAcceptedFormat = bIsAcceptedFormat; this.bAcceptedFormat = bIsAcceptedFormat;
this.bIsLinked = false;
this.sURL = null;
}
/** Set the URL of a linked image
*
* @param sURL the URL
*/
public void setURL(String sURL) {
this.blob = null;
this.nOff = 0;
this.nLen = 0;
this.bIsAcceptedFormat = false; // or rather don't know
this.bIsLinked = true;
this.sURL = sURL;
}
/** Get the URL of a linked image
*
* @return the URL or null if this is an embedded image
*/
public String getURL() {
return sURL;
} }
/** Does this <code>BinaryGraphicsDocument</code> represent a linked image? /** Does this <code>BinaryGraphicsDocument</code> represent a linked image?
@ -118,7 +112,7 @@ public class BinaryGraphicsDocument implements OutputFile {
* @return true if so * @return true if so
*/ */
public boolean isLinked() { public boolean isLinked() {
return bIsLinked; return blob==null && !bRecycled;
} }
/** Is this image in an acceptable format for the converter? /** Is this image in an acceptable format for the converter?
@ -126,9 +120,13 @@ public class BinaryGraphicsDocument implements OutputFile {
* @return true if so (always returns false for linked images) * @return true if so (always returns false for linked images)
*/ */
public boolean isAcceptedFormat() { public boolean isAcceptedFormat() {
return bIsAcceptedFormat; return bAcceptedFormat;
} }
/** Get the data of the image
*
* @return the image data as a byte array - or null if this is a linked image
*/
public byte[] getData() { public byte[] getData() {
return blob; return blob;
} }
@ -148,20 +146,12 @@ public class BinaryGraphicsDocument implements OutputFile {
} }
} }
/** Get the file extension /** Get the document name or URL</p>
*
* @return the file extension
*/
public String getFileExtension() {
return sFileExtension;
}
/** Get the document with file extension.</p>
* *
* @return The document with file extension. * @return The document name or URL
*/ */
public String getFileName() { public String getFileName() {
return sFileName + sFileExtension; return sFileName;
} }
/** Get the MIME type of the document. /** Get the MIME type of the document.

View file

@ -20,7 +20,7 @@
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.4 (2014-09-03) * Version 1.4 (2014-09-05)
* *
*/ */
@ -28,6 +28,7 @@ package writer2latex.base;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import org.w3c.dom.Element; import org.w3c.dom.Element;
@ -69,6 +70,10 @@ public final class ImageConverter {
private String sDefaultFormat = null; private String sDefaultFormat = null;
private String sDefaultVectorFormat = null; private String sDefaultVectorFormat = null;
private HashSet<String> acceptedFormats = new HashSet<String>(); private HashSet<String> acceptedFormats = new HashSet<String>();
// In the package format, the same image file may be used more than once in the document
// Hence we keep information of all documents for potential
private HashMap<String,BinaryGraphicsDocument> recycledImages = new HashMap<String,BinaryGraphicsDocument>();
/** Construct a new <code>ImageConverter</code> referring to a specific document /** Construct a new <code>ImageConverter</code> referring to a specific document
* *
@ -159,17 +164,48 @@ public final class ImageConverter {
* or convert it to an accepted format * or convert it to an accepted format
*/ */
public BinaryGraphicsDocument getImage(Element node) { public BinaryGraphicsDocument getImage(Element node) {
String sName = sSubDirName+sBaseFileName+formatter.format(++nImageCount);
BinaryGraphicsDocument bgd = getImage(node,sName);
if (bgd!=null) {
if (!bgd.isAcceptedFormat()) { // We may have better luck with an alternative image
Element sibling = getAlternativeImage(node);
if (sibling!=null) {
BinaryGraphicsDocument altBgd = getImage(sibling,sName);
if (altBgd!=null && altBgd.isAcceptedFormat()) {
bgd = altBgd;
}
}
}
}
if (bgd==null || bgd.isLinked() || bgd.isRecycled()) {
// The file name was not used
nImageCount--;
}
else if (node.hasAttribute(XMLString.XLINK_HREF)) {
// This is an embedded image we meet for the first time.
// Recycle it on behalf of the original image node.
String sHref = node.getAttribute(XMLString.XLINK_HREF);
recycledImages.put(sHref, new BinaryGraphicsDocument(bgd));
}
return bgd;
}
private BinaryGraphicsDocument getImage(Element node, String sName) {
assert(XMLString.DRAW_IMAGE.equals(node.getTagName())); assert(XMLString.DRAW_IMAGE.equals(node.getTagName()));
// Image data // Image data
String sExt = null;
String sMIME = null; String sMIME = null;
String sExt = null;
byte[] blob = null; byte[] blob = null;
// First try to extract the image using the xlink:href attribute // First try to extract the image using the xlink:href attribute
if (node.hasAttribute(XMLString.XLINK_HREF)) { if (node.hasAttribute(XMLString.XLINK_HREF)) {
String sHref = node.getAttribute(XMLString.XLINK_HREF); String sHref = node.getAttribute(XMLString.XLINK_HREF);
if (sHref.length()>0) { if (sHref.length()>0) {
// We may have seen this image before, return the recycled version
if (recycledImages.containsKey(sHref)) {
return recycledImages.get(sHref);
}
// Image may be embedded in package: // Image may be embedded in package:
String sPath = sHref; String sPath = sHref;
if (sPath.startsWith("#")) { sPath = sPath.substring(1); } if (sPath.startsWith("#")) { sPath = sPath.substring(1); }
@ -192,9 +228,9 @@ public final class ImageConverter {
else { else {
// This is a linked image // This is a linked image
// TODO: Add option to download image from the URL? // TODO: Add option to download image from the URL?
String sFileName = ofr.fixRelativeLink(sHref);
BinaryGraphicsDocument bgd BinaryGraphicsDocument bgd
= new BinaryGraphicsDocument(Misc.getFileName(sHref),Misc.getFileExtension(sHref),null); = new BinaryGraphicsDocument(sFileName,null);
bgd.setURL(ofr.fixRelativeLink(sHref));
return bgd; return bgd;
} }
} }
@ -225,21 +261,22 @@ public final class ImageConverter {
} }
} }
// We have an embedded image. Assign a name (without extension)
String sName = sSubDirName+sBaseFileName+formatter.format(++nImageCount);
// Is this an EPS file embedded in an SVM file? // Is this an EPS file embedded in an SVM file?
// (This case is obsolete, but kept for the sake of old documents)
if (bExtractEPS && MIMETypes.SVM.equals(sMIME)) { if (bExtractEPS && MIMETypes.SVM.equals(sMIME)) {
// Look for postscript: // Look for postscript:
int[] offlen = new int[2]; int[] offlen = new int[2];
if (SVMReader.readSVM(blob,offlen)) { if (SVMReader.readSVM(blob,offlen)) {
String sFileName = sName+MIMETypes.EPS_EXT;
BinaryGraphicsDocument bgd BinaryGraphicsDocument bgd
= new BinaryGraphicsDocument(sName,MIMETypes.EPS_EXT,MIMETypes.EPS); = new BinaryGraphicsDocument(sFileName, MIMETypes.EPS);
bgd.setData(blob,offlen[0],offlen[1],true); bgd.setData(blob,offlen[0],offlen[1],true);
return bgd; return bgd;
} }
} }
// We have an embedded image.
// If we have a converter AND a default format AND this image // If we have a converter AND a default format AND this image
// 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...
@ -264,10 +301,12 @@ public final class ImageConverter {
sExt = MIMETypes.getFileExtension(sMIME); sExt = MIMETypes.getFileExtension(sMIME);
} }
} }
// Create the result // Create the result
if (isAcceptedFormat(sMIME) || bAcceptOtherFormats) { if (isAcceptedFormat(sMIME) || bAcceptOtherFormats) {
BinaryGraphicsDocument bgd = new BinaryGraphicsDocument(sName,sExt,sMIME); String sFileName = sName+sExt;
BinaryGraphicsDocument bgd = new BinaryGraphicsDocument(sFileName,sMIME);
bgd.setData(blob,isAcceptedFormat(sMIME)); bgd.setData(blob,isAcceptedFormat(sMIME));
return bgd; return bgd;
} }
@ -276,4 +315,12 @@ public final class ImageConverter {
} }
} }
private Element getAlternativeImage(Element node) {
Node sibling = node.getNextSibling();
if (sibling!=null && Misc.isElement(sibling, XMLString.DRAW_IMAGE)) {
return (Element) sibling;
}
return null;
}
} }

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: 2001-2010 by Henrik Just * Copyright: 2001-2014 by Henrik Just
* *
* All Rights Reserved. * All Rights Reserved.
* *
* version 1.2 (2010-12-15) * version 1.4 (2014-09-06)
* *
*/ */
@ -41,12 +41,22 @@ public final class EPUBConverter extends Xhtml11Converter {
// Constructor // Constructor
public EPUBConverter() { public EPUBConverter() {
super(); super();
System.out.println("Creating epub converter");
} }
@Override public ConverterResult convert(InputStream is, String sTargetFileName) throws IOException { @Override public ConverterResult convert(InputStream is, String sTargetFileName) throws IOException {
setOPS(true); setOPS(true);
ConverterResult xhtmlResult = super.convert(is, "chapter"); ConverterResult xhtmlResult = super.convert(is, "chapter");
return createPackage(xhtmlResult,sTargetFileName);
}
@Override public ConverterResult convert(org.w3c.dom.Document dom, String sTargetFileName, boolean bDestructive) throws IOException {
setOPS(true);
ConverterResult xhtmlResult = super.convert(dom, "chapter", bDestructive);
return createPackage(xhtmlResult,sTargetFileName);
}
private ConverterResult createPackage(ConverterResult xhtmlResult, String sTargetFileName) {
ConverterResultImpl epubResult = new ConverterResultImpl(); ConverterResultImpl epubResult = new ConverterResultImpl();
epubResult.addDocument(new EPUBWriter(xhtmlResult,sTargetFileName,getXhtmlConfig())); epubResult.addDocument(new EPUBWriter(xhtmlResult,sTargetFileName,getXhtmlConfig()));
epubResult.setMetaData(xhtmlResult.getMetaData()); epubResult.setMetaData(xhtmlResult.getMetaData());

View file

@ -20,7 +20,7 @@
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.4 (2014-09-03) * Version 1.4 (2014-09-05)
* *
*/ */
@ -297,7 +297,7 @@ public class DrawConverter extends ConverterHelper {
BinaryGraphicsDocument bgd = palette.getImageCv().getImage(node); BinaryGraphicsDocument bgd = palette.getImageCv().getImage(node);
if (bgd!=null) { if (bgd!=null) {
if (!bgd.isLinked()) { // embedded image if (!bgd.isLinked()) { // embedded image
palette.addDocument(bgd); if (!bgd.isRecycled()) { palette.addDocument(bgd); }
sFileName = bgd.getFileName(); sFileName = bgd.getFileName();
String sMIME = bgd.getMIMEType(); String sMIME = bgd.getMIMEType();
bCommentOut = !( bCommentOut = !(
@ -311,8 +311,8 @@ public class DrawConverter extends ConverterHelper {
(config.getBackend()==LaTeXConfig.DVIPS && MIMETypes.EPS.equals(sMIME))); (config.getBackend()==LaTeXConfig.DVIPS && MIMETypes.EPS.equals(sMIME)));
} }
else { // linked image else { // linked image
sFileName = bgd.getURL(); sFileName = bgd.getFileName();
String sExt = bgd.getFileExtension().toLowerCase(); String sExt = Misc.getFileExtension(sFileName).toLowerCase();
// Accept only relative filenames and supported filetypes: // Accept only relative filenames and supported filetypes:
bCommentOut = sFileName.indexOf(":")>-1 || !( bCommentOut = sFileName.indexOf(":")>-1 || !(
config.getBackend()==LaTeXConfig.UNSPECIFIED || config.getBackend()==LaTeXConfig.UNSPECIFIED ||

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-2012 by Henrik Just * Copyright: 2002-2014 by Henrik Just
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.2 (2012-03-05) * Version 1.4 (2014-09-06)
* *
*/ */
@ -94,7 +94,7 @@ public class ListStyleConverter extends StyleConverter {
if (config.formatting()==LaTeXConfig.CONVERT_BASIC || if (config.formatting()==LaTeXConfig.CONVERT_BASIC ||
(config.formatting()>=LaTeXConfig.CONVERT_MOST && oc.isInTable())) { (config.formatting()>=LaTeXConfig.CONVERT_MOST && oc.isInTable())) {
if (oc.getListLevel()==1) { if (oc.getListLevel()==1) {
if (!styleNames.containsName(getDisplayName(oc.getListStyleName()))) { if (!listStyleLevelNames.containsKey(oc.getListStyleName())) {
createListStyleLabels(oc.getListStyleName()); createListStyleLabels(oc.getListStyleName());
} }
ba.add("\\liststyle"+styleNames.getExportName(getDisplayName(oc.getListStyleName()))+"\n",""); ba.add("\\liststyle"+styleNames.getExportName(getDisplayName(oc.getListStyleName()))+"\n","");

View file

@ -20,7 +20,7 @@
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.4 (2014-08-13) * Version 1.4 (2014-09-05)
* *
*/ */
@ -69,6 +69,7 @@ public final class MIMETypes extends writer2latex.api.MIMETypes {
public static final String BIBTEX_EXT = ".bib"; public static final String BIBTEX_EXT = ".bib";
public static final String XHTML_EXT = ".html"; public static final String XHTML_EXT = ".html";
public static final String XHTML_MATHML_EXT = ".xhtml"; public static final String XHTML_MATHML_EXT = ".xhtml";
public static final String HTML5_EXT = ".html";
public static final String PNG_EXT = ".png"; public static final String PNG_EXT = ".png";
public static final String JPEG_EXT = ".jpg"; // this is the default in graphicx.sty public static final String JPEG_EXT = ".jpg"; // this is the default in graphicx.sty
public static final String GIF_EXT = ".gif"; public static final String GIF_EXT = ".gif";
@ -90,8 +91,8 @@ public final class MIMETypes extends writer2latex.api.MIMETypes {
} }
private static final boolean isSVG(byte[] blob) { private static final boolean isSVG(byte[] blob) {
// Look for <svg within the first 250 bytes // Look for <svg within the first 500 bytes
int m = Math.min(blob.length, 250); int m = Math.min(blob.length, 500);
int n = SVG_SIG.length; int n = SVG_SIG.length;
for (int j=0; j<m-n; j++) { for (int j=0; j<m-n; j++) {
boolean bFound = true; boolean bFound = true;
@ -141,6 +142,7 @@ public final class MIMETypes extends writer2latex.api.MIMETypes {
if (BIBTEX.equals(sMIME)) { return BIBTEX_EXT; } if (BIBTEX.equals(sMIME)) { return BIBTEX_EXT; }
if (XHTML.equals(sMIME)) { return XHTML_EXT; } if (XHTML.equals(sMIME)) { return XHTML_EXT; }
if (XHTML_MATHML.equals(sMIME)) { return XHTML_MATHML_EXT; } if (XHTML_MATHML.equals(sMIME)) { return XHTML_MATHML_EXT; }
if (HTML5.equals(sMIME)) { return XHTML_EXT; }
return ""; return "";
} }

View file

@ -16,9 +16,9 @@
* 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-2012 by Henrik Just * Copyright: 2002-2014 by Henrik Just
* *
* Version 1.4 (2012-04-12) * Version 1.4 (2014-09-05)
* *
* All Rights Reserved. * All Rights Reserved.
*/ */
@ -134,11 +134,15 @@ public class TableReader {
if (bHasRelWidth) { if (bHasRelWidth) {
sRelColWidth[nCol] = (100.0F*nRelColWidth[nCol]/nColSum)+"%"; sRelColWidth[nCol] = (100.0F*nRelColWidth[nCol]/nColSum)+"%";
} }
else { else if (sTableWidth!=null){
// Calculate the relative column width from the absolute column widths // Calculate the relative column width from the absolute column widths
// This may not add up to exactly 100%, but we will live with that // This may not add up to exactly 100%, but we will live with that
sRelColWidth[nCol] = Misc.divide(sColWidth[nCol], sTableWidth, true); sRelColWidth[nCol] = Misc.divide(sColWidth[nCol], sTableWidth, true);
} }
else {
// The table has not width, distribute the columns evenly
sRelColWidth[nCol] = Double.toString(100.0/nCols)+"%";
}
} }
// Now determine the actual number of rows and columns // Now determine the actual number of rows and columns

View file

@ -20,7 +20,7 @@
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.4 (2014-08-27) * Version 1.4 (2014-09-05)
* *
*/ */
@ -262,7 +262,7 @@ public class Converter extends ConverterBase {
imageConverter.addAcceptedFormat(MIMETypes.JPEG); imageConverter.addAcceptedFormat(MIMETypes.JPEG);
imageConverter.addAcceptedFormat(MIMETypes.GIF); imageConverter.addAcceptedFormat(MIMETypes.GIF);
if (nType==XhtmlDocument.HTML5 && config.useSVG()) { // HTML supports (inline) SVG as well if (nType==XhtmlDocument.HTML5) { // HTML supports SVG as well
imageConverter.setDefaultVectorFormat(MIMETypes.SVG); imageConverter.setDefaultVectorFormat(MIMETypes.SVG);
} }

View file

@ -20,7 +20,7 @@
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.4 (2014-09-03) * Version 1.4 (2014-09-05)
* *
*/ */
@ -128,7 +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(); bUseSVG = config.inlineSVG();
} }
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
@ -477,7 +477,7 @@ public class DrawConverter extends ConverterHelper {
} }
else { // linked image else { // linked image
if (!converter.isOPS()) { // Cannot have linked images in EPUB, ignore the image if (!converter.isOPS()) { // Cannot have linked images in EPUB, ignore the image
sFileName = bgd.getURL(); sFileName = bgd.getFileName();
} }
} }
} }
@ -509,7 +509,7 @@ public class DrawConverter extends ConverterHelper {
} }
else { else {
// In all other cases, create an img element // In all other cases, create an img element
if (bgd!=null) { converter.addDocument(bgd); } if (bgd!=null && !bgd.isLinked() && !bgd.isRecycled()) { converter.addDocument(bgd); }
Element image = converter.createElement("img"); Element image = converter.createElement("img");
String sName = Misc.getAttribute(getFrame(onode),XMLString.DRAW_NAME); String sName = Misc.getAttribute(getFrame(onode),XMLString.DRAW_NAME);
converter.addTarget(image,sName+"|graphic"); converter.addTarget(image,sName+"|graphic");

View file

@ -20,7 +20,7 @@
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.4 (2014-08-27) * Version 1.4 (2014-09-06)
* *
*/ */
@ -77,6 +77,8 @@ final class IndexData {
Element hnode; // a div node where the index should be added Element hnode; // a div node where the index should be added
} }
/** This class handles text content
*/
public class TextConverter extends ConverterHelper { public class TextConverter extends ConverterHelper {
// Data used to handle splitting over several files // Data used to handle splitting over several files
@ -1511,11 +1513,14 @@ public class TextConverter extends ConverterHelper {
while (child!=null) { while (child!=null) {
if (child.getNodeType()==Node.ELEMENT_NODE) { if (child.getNodeType()==Node.ELEMENT_NODE) {
Element elm = (Element) child; Element elm = (Element) child;
String sTag = elm.getTagName();
if (OfficeReader.isDrawElement(elm)) { if (OfficeReader.isDrawElement(elm)) {
elm = getDrawCv().getRealDrawElement(elm); elm = getDrawCv().getRealDrawElement(elm);
String sAnchor = elm.getAttribute(XMLString.TEXT_ANCHOR_TYPE);
if (Misc.isElement(elm, XMLString.DRAW_FRAME)) {
elm = Misc.getFirstChildElement(elm);
}
if (elm!=null) { if (elm!=null) {
String sAnchor = elm.getAttribute(XMLString.TEXT_ANCHOR_TYPE); String sTag = elm.getTagName();
// Convert only floating frames; text-boxes must always float // Convert only floating frames; text-boxes must always float
if (!"as-char".equals(sAnchor)) { if (!"as-char".equals(sAnchor)) {
getDrawCv().handleDrawElement(elm,(Element)hnodeBlock, getDrawCv().handleDrawElement(elm,(Element)hnodeBlock,
@ -2132,10 +2137,23 @@ public class TextConverter extends ConverterHelper {
getTextSc().applyStyle(sStyleName,info); getTextSc().applyStyle(sStyleName,info);
Element newNode = node; Element newNode = node;
if (info.hasAttributes() || !"span".equals(info.sTagName)) { if (info.hasAttributes() || !"span".equals(info.sTagName)) {
// We need to create a new element // We (probably) need to create a new element
newNode = converter.createElement(info.sTagName); newNode = converter.createElement(info.sTagName);
node.appendChild(newNode);
applyStyle(info,newNode); applyStyle(info,newNode);
// But we may want to merge it with the previous element
Node prev = node.getLastChild();
if (prev!=null && Misc.isElement(prev, info.sTagName)) {
// The previous node is of the same type, compare attributes
Element prevNode = (Element) prev;
if (newNode.getAttribute("class").equals(prevNode.getAttribute("class")) &&
newNode.getAttribute("style").equals(prevNode.getAttribute("style")) &&
newNode.getAttribute("xml:lang").equals(prevNode.getAttribute("xml:lang")) &&
newNode.getAttribute("dir").equals(prevNode.getAttribute("dir"))) {
// Attribute style mapped elements are *not* merged, we will live with that
return applyAttributes(prevNode,ofr.getTextStyle(sStyleName));
}
}
node.appendChild(newNode);
} }
return applyAttributes(newNode,ofr.getTextStyle(sStyleName)); return applyAttributes(newNode,ofr.getTextStyle(sStyleName));
} }
@ -2149,5 +2167,3 @@ public class TextConverter extends ConverterHelper {
} }

View file

@ -20,7 +20,7 @@
* *
* All Rights Reserved. * All Rights Reserved.
* *
* Version 1.4 (2014-08-13) * Version 1.4 (2014-09-05)
* *
*/ */
@ -143,7 +143,7 @@ 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 USE_SVG = 43; private static final int INLINE_SVG = 43;
private static final int USE_MATHJAX = 44; private static final int USE_MATHJAX = 44;
private static final int CALC_SPLIT = 45; private static final int CALC_SPLIT = 45;
private static final int DISPLAY_HIDDEN_SHEETS = 46; private static final int DISPLAY_HIDDEN_SHEETS = 46;
@ -274,7 +274,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[INLINE_SVG] = new BooleanOption("inline_svg","true");
options[USE_MATHJAX] = new BooleanOption("use_mathjax","false"); options[USE_MATHJAX] = new BooleanOption("use_mathjax","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");
@ -401,7 +401,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 inlineSVG() { return ((BooleanOption) options[INLINE_SVG]).getValue(); }
public boolean useMathJax() { return ((BooleanOption) options[USE_MATHJAX]).getValue(); } public boolean useMathJax() { return ((BooleanOption) options[USE_MATHJAX]).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(); }

View file

@ -20,7 +20,7 @@
<prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop> <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop>
<prop oor:name="TemplateName"/> <prop oor:name="TemplateName"/>
<prop oor:name="UIName"> <prop oor:name="UIName">
<value>LaTeX 2e</value> <value>LaTeX 2e [Writer2LaTeX]</value>
</prop> </prop>
<prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop> <prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop>
</node> </node>
@ -34,7 +34,7 @@
<prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop> <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop>
<prop oor:name="TemplateName"/> <prop oor:name="TemplateName"/>
<prop oor:name="UIName"> <prop oor:name="UIName">
<value>BibTeX</value> <value>BibTeX [Writer2LaTeX]</value>
</prop> </prop>
<prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop> <prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop>
</node> </node>

View file

@ -12,7 +12,7 @@
<prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop> <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop>
<prop oor:name="TemplateName"/> <prop oor:name="TemplateName"/>
<prop oor:name="UIName"> <prop oor:name="UIName">
<value>HTML 5</value> <value>HTML 5 [Writer2xhtml]</value>
</prop> </prop>
<prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop> <prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop>
</node> </node>
@ -26,7 +26,7 @@
<prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop><!-- sic! --> <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop><!-- sic! -->
<prop oor:name="TemplateName"/> <prop oor:name="TemplateName"/>
<prop oor:name="UIName"> <prop oor:name="UIName">
<value>HTML5</value> <value>HTML5 [Writer2xhtml]</value>
</prop> </prop>
<prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop> <prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop>
</node> </node>
@ -40,7 +40,7 @@
<prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop> <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop>
<prop oor:name="TemplateName"/> <prop oor:name="TemplateName"/>
<prop oor:name="UIName"> <prop oor:name="UIName">
<value>XHTML 1.0 strict</value> <value>XHTML 1.0 strict [Writer2xhtml]</value>
</prop> </prop>
<prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop> <prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop>
</node> </node>
@ -54,7 +54,7 @@
<prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop> <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop>
<prop oor:name="TemplateName"/> <prop oor:name="TemplateName"/>
<prop oor:name="UIName"> <prop oor:name="UIName">
<value>XHTML 1.1</value> <value>XHTML 1.1 [Writer2xhtml]</value>
</prop> </prop>
<prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop> <prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop>
</node> </node>
@ -68,7 +68,7 @@
<prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop><!-- sic! --> <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop><!-- sic! -->
<prop oor:name="TemplateName"/> <prop oor:name="TemplateName"/>
<prop oor:name="UIName"> <prop oor:name="UIName">
<value>XHTML 1.0 strict</value> <value>XHTML 1.0 strict [Writer2xhtml]</value>
</prop> </prop>
<prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop> <prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop>
</node> </node>
@ -82,7 +82,7 @@
<prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop><!-- sic! --> <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop><!-- sic! -->
<prop oor:name="TemplateName"/> <prop oor:name="TemplateName"/>
<prop oor:name="UIName"> <prop oor:name="UIName">
<value>XHTML 1.1</value> <value>XHTML 1.1 [Writer2xhtml]</value>
</prop> </prop>
<prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop> <prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop>
</node> </node>
@ -96,7 +96,7 @@
<prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop> <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop>
<prop oor:name="TemplateName"/> <prop oor:name="TemplateName"/>
<prop oor:name="UIName"> <prop oor:name="UIName">
<value>XHTML 1.1 + MathML 2.0</value> <value>XHTML 1.1 + MathML 2.0 [Writer2xhtml]</value>
</prop> </prop>
<prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop> <prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop>
</node> </node>
@ -110,7 +110,7 @@
<prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop> <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop>
<prop oor:name="TemplateName"/> <prop oor:name="TemplateName"/>
<prop oor:name="UIName"> <prop oor:name="UIName">
<value>EPUB</value> <value>EPUB [Writer2xhtml]</value>
</prop> </prop>
<prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop> <prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop>
</node> </node>

View file

@ -13,7 +13,7 @@ Overview
The source of Writer2LaTeX consists of three major parts: The source of Writer2LaTeX consists of three major parts:
* A general purpose java library for converting OpenDocument files into LaTeX, * A general purpose java library for converting OpenDocument files into LaTeX,
BibTeX, xhtml, xhtml+MathML and EPUB BibTeX, XHTML, XHTML+MathML, HTML5 and EPUB
This is to be found in the packages writer2latex.* and should only be used This is to be found in the packages writer2latex.* and should only be used
through the provided api writer2latex.api.* through the provided api writer2latex.api.*
* A command line utility writer2latex.Application * A command line utility writer2latex.Application
@ -21,20 +21,12 @@ The source of Writer2LaTeX consists of three major parts:
These are to be found in the packages org.openoffice.da.comp.* These are to be found in the packages org.openoffice.da.comp.*
Currently parts of the source for Writer2LaTeX are somewhat messy and Currently parts of the source for Writer2LaTeX are somewhat messy and
undocumented. This situation is improving from time to time :-) undocumented. This situation tends to improve over time :-)
Third-party software Third-party software
-------------------- --------------------
From OpenOffice.org:
Writer2LaTeX includes some classes from the OpenOffice.org project:
writer2latex.xmerge.* contains some classes which are part of the xmerge
project within OOo (some of the classes are slightly modified)
See copyright notices within the source files
From JSON.org: From JSON.org:
The classes org.json.* are copyright (c) 2002 JSON.org and is used subject to the following notice The classes org.json.* are copyright (c) 2002 JSON.org and is used subject to the following notice
@ -71,9 +63,10 @@ To make these files available for the compiler, edit the file build.xml
as follows: as follows:
The lines The lines
<property name="OFFICE_CLASSES" location="/usr/share/java/openoffice" /> <property name="OFFICE_CLASSES" location="/usr/share/java" />
<property name="URE_CLASSES" location="/usr/share/java/openoffice" /> <property name="URE_CLASSES" location="/usr/share/java" />
should be modified to the directories where your OOo installation keeps these files should be modified to the directories where your LO/AOO installation keeps these files
In some cases your need to install the office development kit as well
To build, open a command shell, navigate to the source directory and type To build, open a command shell, navigate to the source directory and type