More math and TexMaths work
git-svn-id: svn://svn.code.sf.net/p/writer2latex/code/trunk@160 f0f2a975-2e09-46c8-9428-3b39399b9f3c
This commit is contained in:
parent
79ae252419
commit
3dff4f20b4
15 changed files with 514 additions and 525 deletions
|
@ -2,7 +2,7 @@ Changelog for Writer2LaTeX version 1.2 -> 1.4
|
||||||
|
|
||||||
---------- version 1.3.1 alpha ----------
|
---------- version 1.3.1 alpha ----------
|
||||||
|
|
||||||
[w2l] Added support for TexMaths equations
|
[w2l] 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
|
||||||
|
|
||||||
|
@ -12,12 +12,9 @@ Changelog for Writer2LaTeX version 1.2 -> 1.4
|
||||||
dimensions), relative (always use relative width) and auto (use the formatting of the source document):
|
dimensions), relative (always use relative width) and auto (use the formatting of the source document):
|
||||||
If set to true, all tables are exported with relative width, even if they have an absolute width in the source document
|
If set to true, all tables are exported with relative width, even if they have an absolute width in the source document
|
||||||
|
|
||||||
[w2x] Display equations are now recognized by the same means as in the LaTeX export: A single equation in a paragraph with no
|
[w2x] New boolean option use_mathjax (default false): If set to true and export format is XHTML+MATHML or HTML5,
|
||||||
text content except whitespace and an optional sequence number in brackets is considered a display equation. In that case
|
documents will load the MathJax JavaScript library for rendering of formulas (otherwise the document will rely
|
||||||
it is exported with display="block"
|
on native MathML support in the browser)
|
||||||
|
|
||||||
[w2x] New boolean option use_mathjax (default false): If set to true and export format is HTML5, documents will load the MathJax
|
|
||||||
JavaScript library for rendering of formulas (otherwise the document will rely on native MathML support in the browser)
|
|
||||||
|
|
||||||
[w2x] New boolean option use_svg (default false): If set to true and export format is HTML5, vector graphics are exported as
|
[w2x] New boolean option use_svg (default false): If set to true and export format is HTML5, vector graphics are exported as
|
||||||
inline SVG, if possible
|
inline SVG, if possible
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
*
|
*
|
||||||
* All Rights Reserved.
|
* All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Version 1.4 (2012-08-05)
|
* Version 1.4 (2012-08-13)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -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 = "2014-08-05";
|
private static final String DATE = "2014-08-13";
|
||||||
|
|
||||||
/** 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/>
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
*
|
*
|
||||||
* All Rights Reserved.
|
* All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Version 1.4 (2014-08-06)
|
* Version 1.4 (2014-08-13)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -32,18 +32,13 @@ import java.io.FileNotFoundException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.w3c.dom.Document;
|
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
|
||||||
|
|
||||||
import writer2latex.api.GraphicConverter;
|
import writer2latex.api.GraphicConverter;
|
||||||
import writer2latex.api.Converter;
|
import writer2latex.api.Converter;
|
||||||
import writer2latex.api.ConverterResult;
|
import writer2latex.api.ConverterResult;
|
||||||
import writer2latex.api.OutputFile;
|
import writer2latex.api.OutputFile;
|
||||||
import writer2latex.office.EmbeddedObject;
|
import writer2latex.office.EmbeddedObject;
|
||||||
import writer2latex.office.EmbeddedXMLObject;
|
|
||||||
import writer2latex.office.ImageLoader;
|
import writer2latex.office.ImageLoader;
|
||||||
import writer2latex.office.MIMETypes;
|
|
||||||
import writer2latex.office.MetaData;
|
import writer2latex.office.MetaData;
|
||||||
import writer2latex.office.OfficeDocument;
|
import writer2latex.office.OfficeDocument;
|
||||||
import writer2latex.office.OfficeReader;
|
import writer2latex.office.OfficeReader;
|
||||||
|
@ -53,6 +48,8 @@ import writer2latex.util.Misc;
|
||||||
/**<p>Abstract base implementation of <code>writer2latex.api.Converter</code></p>
|
/**<p>Abstract base implementation of <code>writer2latex.api.Converter</code></p>
|
||||||
*/
|
*/
|
||||||
public abstract class ConverterBase implements Converter {
|
public abstract class ConverterBase implements Converter {
|
||||||
|
|
||||||
|
public enum TexMathsStyle {inline, display, latex};
|
||||||
|
|
||||||
// Helper
|
// Helper
|
||||||
protected GraphicConverter graphicConverter;
|
protected GraphicConverter graphicConverter;
|
||||||
|
@ -67,10 +64,6 @@ public abstract class ConverterBase implements Converter {
|
||||||
protected String sTargetFileName;
|
protected String sTargetFileName;
|
||||||
protected ConverterResultImpl converterResult;
|
protected ConverterResultImpl converterResult;
|
||||||
|
|
||||||
// Result of latest parsing of a display equation
|
|
||||||
private Element theEquation = null;
|
|
||||||
private Element theSequence = null;
|
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
public ConverterBase() {
|
public ConverterBase() {
|
||||||
graphicConverter = null;
|
graphicConverter = null;
|
||||||
|
@ -151,22 +144,6 @@ public abstract class ConverterBase implements Converter {
|
||||||
return odDoc.getEmbeddedObject(sHref);
|
return odDoc.getEmbeddedObject(sHref);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the equation found by the last invocation of <code>parseDisplayEquation</code>
|
|
||||||
*
|
|
||||||
* @return the equation or null if no equation was found
|
|
||||||
*/
|
|
||||||
public Element getEquation() {
|
|
||||||
return theEquation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get the sequence number found by the last invocation of <code>parseDisplayEquation</code>
|
|
||||||
*
|
|
||||||
* @return the sequence number or null if no sequence number was found
|
|
||||||
*/
|
|
||||||
public Element getSequence() {
|
|
||||||
return theSequence;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get a TexMaths equation from a draw:frame (PNG formula) or draw:g element (SVG)
|
/** Get a TexMaths equation from a draw:frame (PNG formula) or draw:g element (SVG)
|
||||||
* Such an element is a TexMaths equation if it contains an svg:title element with content "TexMaths"
|
* Such an element is a TexMaths equation if it contains an svg:title element with content "TexMaths"
|
||||||
* The actual formula is the content of an svg:desc element
|
* The actual formula is the content of an svg:desc element
|
||||||
|
@ -181,133 +158,28 @@ public abstract class ConverterBase implements Converter {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get a MathML formula from a draw:frame
|
|
||||||
*
|
|
||||||
* @param node the draw:frame
|
|
||||||
* @return the MathML element, or null if this is not a MathML formula
|
|
||||||
*/
|
|
||||||
public Element getMathmlEquation(Element node) {
|
|
||||||
if (node.getTagName().equals(XMLString.DRAW_FRAME)) {
|
|
||||||
node=Misc.getFirstChildElement(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
String sHref = Misc.getAttribute(node,XMLString.XLINK_HREF);
|
public TexMathsStyle getTexMathsStyle(String s) {
|
||||||
|
String[] sContent = s.split("\u00a7");
|
||||||
if (sHref!=null) { // Embedded object in package or linked object
|
if (sContent.length>=3) { // we only need 3 items of 6
|
||||||
if (ofr.isInPackage(sHref)) { // Embedded object in package
|
if ("display".equals(sContent[1])) {
|
||||||
if (sHref.startsWith("#")) { sHref=sHref.substring(1); }
|
return TexMathsStyle.display;
|
||||||
if (sHref.startsWith("./")) { sHref=sHref.substring(2); }
|
}
|
||||||
EmbeddedObject object = getEmbeddedObject(sHref);
|
else if ("latex".equals(sContent[1]) || "text".equals(sContent[1])) { // text is for OOoLaTeX
|
||||||
if (object!=null) {
|
return TexMathsStyle.latex;
|
||||||
if (MIMETypes.MATH.equals(object.getType()) || MIMETypes.ODF.equals(object.getType())) { // Formula!
|
}
|
||||||
try {
|
}
|
||||||
Document formuladoc = ((EmbeddedXMLObject) object).getContentDOM();
|
return TexMathsStyle.inline;
|
||||||
Element formula = Misc.getChildByTagName(formuladoc,XMLString.MATH); // Since OOo 3.2
|
|
||||||
if (formula==null) {
|
|
||||||
formula = Misc.getChildByTagName(formuladoc,XMLString.MATH_MATH);
|
|
||||||
}
|
|
||||||
return formula;
|
|
||||||
}
|
|
||||||
catch (org.xml.sax.SAXException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
catch (java.io.IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else { // flat XML, object is contained in node
|
|
||||||
Element formula = Misc.getChildByTagName(node,XMLString.MATH); // Since OOo 3.2
|
|
||||||
if (formula==null) {
|
|
||||||
formula = Misc.getChildByTagName(node,XMLString.MATH_MATH);
|
|
||||||
}
|
|
||||||
return formula;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Determine whether or not a paragraph contains a display equation.
|
public String getTexMathsEquation(String s) {
|
||||||
* A paragraph is a display equation if it contains a single formula and no text content except whitespace
|
String[] sContent = s.split("\u00a7");
|
||||||
* and an optional sequence number which may be in brackets.
|
if (sContent.length>=3) { // we only need 3 items of 6
|
||||||
* As a side effect, this method keeps a reference to the equation and the sequence number
|
return sContent[2];
|
||||||
*
|
}
|
||||||
* @param node the paragraph
|
else {
|
||||||
* @return true if this is a display equation
|
return "";
|
||||||
*/
|
}
|
||||||
public boolean parseDisplayEquation(Node node) {
|
|
||||||
theEquation = null;
|
|
||||||
theSequence = null;
|
|
||||||
return doParseDisplayEquation(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean doParseDisplayEquation(Node node) {
|
|
||||||
Node child = node.getFirstChild();
|
|
||||||
while (child!=null) {
|
|
||||||
if (Misc.isElement(child)) {
|
|
||||||
Element elm = (Element) child;
|
|
||||||
String sName = elm.getTagName();
|
|
||||||
// First check for MathML or TexMaths equation
|
|
||||||
Element equation = getMathmlEquation(elm);
|
|
||||||
if (equation==null) {
|
|
||||||
equation = getTexMathsEquation(elm);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (equation!=null) {
|
|
||||||
if (theEquation==null) {
|
|
||||||
theEquation = equation;
|
|
||||||
}
|
|
||||||
else { // two or more equations -> not a display
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (XMLString.TEXT_SEQUENCE.equals(sName)) {
|
|
||||||
if (theSequence==null) {
|
|
||||||
theSequence = elm;
|
|
||||||
}
|
|
||||||
else { // two sequence numbers -> not a display
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (XMLString.TEXT_SPAN.equals(sName)) {
|
|
||||||
if (!doParseDisplayEquation(child)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (XMLString.TEXT_S.equals(sName)) {
|
|
||||||
// Spaces are allowed
|
|
||||||
}
|
|
||||||
else if (XMLString.TEXT_TAB.equals(sName)) {
|
|
||||||
// Tab stops are allowed
|
|
||||||
}
|
|
||||||
else if (XMLString.TEXT_TAB_STOP.equals(sName)) { // old
|
|
||||||
// Tab stops are allowed
|
|
||||||
}
|
|
||||||
else if (XMLString.TEXT_SOFT_PAGE_BREAK.equals(sName)) { // since ODF 1.1
|
|
||||||
// Soft page breaks are allowed
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Other elements -> not a display
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Misc.isText(child)) {
|
|
||||||
String s = child.getNodeValue();
|
|
||||||
int nLen = s.length();
|
|
||||||
for (int i=0; i<nLen; i++) {
|
|
||||||
char c = s.charAt(i);
|
|
||||||
if (c!='(' && c!=')' && c!='[' && c!=']' && c!='{' && c!='}' && c!=' ' && c!='\u00A0') {
|
|
||||||
// Characters except brackets and whitespace -> not a display
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
child = child.getNextSibling();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -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-02-26)
|
* Version 1.4 (2014-08-10)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ public final class ConverterPalette extends ConverterBase {
|
||||||
private InlineConverter inlineCv;
|
private InlineConverter inlineCv;
|
||||||
private FieldConverter fieldCv;
|
private FieldConverter fieldCv;
|
||||||
private DrawConverter drawCv;
|
private DrawConverter drawCv;
|
||||||
private MathmlConverter mathmlCv;
|
private MathConverter mathCv;
|
||||||
private Info info;
|
private Info info;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
|
@ -117,7 +117,7 @@ public final class ConverterPalette extends ConverterBase {
|
||||||
public InlineConverter getInlineCv() { return inlineCv; }
|
public InlineConverter getInlineCv() { return inlineCv; }
|
||||||
public FieldConverter getFieldCv() { return fieldCv; }
|
public FieldConverter getFieldCv() { return fieldCv; }
|
||||||
public DrawConverter getDrawCv() { return drawCv; }
|
public DrawConverter getDrawCv() { return drawCv; }
|
||||||
public MathmlConverter getMathmlCv() { return mathmlCv; }
|
public MathConverter getMathCv() { return mathCv; }
|
||||||
public Info getInfo() { return info; }
|
public Info getInfo() { return info; }
|
||||||
|
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ public final class ConverterPalette extends ConverterBase {
|
||||||
inlineCv = new InlineConverter(ofr,config,this);
|
inlineCv = new InlineConverter(ofr,config,this);
|
||||||
fieldCv = new FieldConverter(ofr,config,this);
|
fieldCv = new FieldConverter(ofr,config,this);
|
||||||
drawCv = new DrawConverter(ofr,config,this);
|
drawCv = new DrawConverter(ofr,config,this);
|
||||||
mathmlCv = new MathmlConverter(ofr,config,this);
|
mathCv = new MathConverter(ofr,config,this);
|
||||||
info = new Info(ofr,config,this);
|
info = new Info(ofr,config,this);
|
||||||
|
|
||||||
// Create master document and add this
|
// Create master document and add this
|
||||||
|
@ -223,7 +223,7 @@ public final class ConverterPalette extends ConverterBase {
|
||||||
inlineCv.appendDeclarations(packages,declarations);
|
inlineCv.appendDeclarations(packages,declarations);
|
||||||
fieldCv.appendDeclarations(packages,declarations);
|
fieldCv.appendDeclarations(packages,declarations);
|
||||||
drawCv.appendDeclarations(packages,declarations);
|
drawCv.appendDeclarations(packages,declarations);
|
||||||
mathmlCv.appendDeclarations(packages,declarations);
|
mathCv.appendDeclarations(packages,declarations);
|
||||||
|
|
||||||
// Add custom preamble
|
// Add custom preamble
|
||||||
String sCustomPreamble = config.getCustomPreamble();
|
String sCustomPreamble = config.getCustomPreamble();
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
*
|
*
|
||||||
* All Rights Reserved.
|
* All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Version 1.4 (2014-08-06)
|
* Version 1.4 (2014-08-11)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -31,17 +31,13 @@ import java.util.Stack;
|
||||||
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
//import org.w3c.dom.Node;
|
|
||||||
|
|
||||||
|
|
||||||
import writer2latex.latex.util.BeforeAfter;
|
import writer2latex.latex.util.BeforeAfter;
|
||||||
import writer2latex.latex.util.Context;
|
import writer2latex.latex.util.Context;
|
||||||
//import writer2latex.office.ImageLoader;
|
|
||||||
import writer2latex.office.EmbeddedObject;
|
import writer2latex.office.EmbeddedObject;
|
||||||
import writer2latex.office.EmbeddedXMLObject;
|
import writer2latex.office.EmbeddedXMLObject;
|
||||||
import writer2latex.office.MIMETypes;
|
import writer2latex.office.MIMETypes;
|
||||||
import writer2latex.office.OfficeReader;
|
import writer2latex.office.OfficeReader;
|
||||||
import writer2latex.office.StyleWithProperties;
|
|
||||||
import writer2latex.office.XMLString;
|
import writer2latex.office.XMLString;
|
||||||
import writer2latex.util.CSVList;
|
import writer2latex.util.CSVList;
|
||||||
import writer2latex.util.Misc;
|
import writer2latex.util.Misc;
|
||||||
|
@ -53,9 +49,8 @@ import writer2latex.xmerge.BinaryGraphicsDocument;
|
||||||
public class DrawConverter extends ConverterHelper {
|
public class DrawConverter extends ConverterHelper {
|
||||||
|
|
||||||
private boolean bNeedGraphicx = false;
|
private boolean bNeedGraphicx = false;
|
||||||
private boolean bNeedOOoLaTeXPreamble = false;
|
|
||||||
|
|
||||||
// Keep track of floating frames (images, textboxes...)
|
// Keep track of floating frames (images, text boxes...)
|
||||||
private Stack<LinkedList<Element>> floatingFramesStack = new Stack<LinkedList<Element>>();
|
private Stack<LinkedList<Element>> floatingFramesStack = new Stack<LinkedList<Element>>();
|
||||||
|
|
||||||
private Element getFrame(Element onode) {
|
private Element getFrame(Element onode) {
|
||||||
|
@ -76,17 +71,6 @@ public class DrawConverter extends ConverterHelper {
|
||||||
else if (config.getBackend()==LaTeXConfig.DVIPS) pack.append("[dvips]");
|
else if (config.getBackend()==LaTeXConfig.DVIPS) pack.append("[dvips]");
|
||||||
pack.append("{graphicx}").nl();
|
pack.append("{graphicx}").nl();
|
||||||
}
|
}
|
||||||
if (bNeedOOoLaTeXPreamble) {
|
|
||||||
// The preamble may be stored in the description
|
|
||||||
String sDescription = palette.getMetaData().getDescription();
|
|
||||||
int nStart = sDescription.indexOf("%%% OOoLatex Preamble %%%%%%%%%%%%%%");
|
|
||||||
int nEnd = sDescription.indexOf("%%% End OOoLatex Preamble %%%%%%%%%%%%");
|
|
||||||
if (nStart>-1 && nEnd>nStart) {
|
|
||||||
decl.append("% OOoLaTeX preamble").nl()
|
|
||||||
.append(sDescription.substring(nStart+37,nEnd));
|
|
||||||
}
|
|
||||||
// TODO: Otherwise try the user settings...
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleCaption(Element node, LaTeXDocumentPortion ldp, Context oc) {
|
public void handleCaption(Element node, LaTeXDocumentPortion ldp, Context oc) {
|
||||||
|
@ -129,25 +113,16 @@ public class DrawConverter extends ConverterHelper {
|
||||||
palette.getFieldCv().handleAnchor(node,ldp,oc);
|
palette.getFieldCv().handleAnchor(node,ldp,oc);
|
||||||
}
|
}
|
||||||
else if (sName.equals(XMLString.DRAW_FRAME)) {
|
else if (sName.equals(XMLString.DRAW_FRAME)) {
|
||||||
Element equation = palette.getTexMathsEquation(node);
|
if (!palette.getMathCv().handleTexMathsEquation(node,ldp)) {
|
||||||
if (equation!=null) {
|
|
||||||
palette.getMathmlCv().handleTexMathsEquation(equation,ldp,oc);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// OpenDocument: Get the actual draw element in the frame
|
// OpenDocument: Get the actual draw element in the frame
|
||||||
handleDrawElement(Misc.getFirstChildElement(node),ldp,oc);
|
handleDrawElement(Misc.getFirstChildElement(node),ldp,oc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sName.equals(XMLString.DRAW_G)) {
|
else if (sName.equals(XMLString.DRAW_G)) {
|
||||||
Element equation = palette.getTexMathsEquation(node);
|
if (!palette.getMathCv().handleTexMathsEquation(node,ldp)) {
|
||||||
if (equation!=null) {
|
|
||||||
palette.getMathmlCv().handleTexMathsEquation(equation,ldp,oc);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Shapes are currently not supported
|
// Shapes are currently not supported
|
||||||
ldp.append("[Warning: Draw object ignored]");
|
ldp.append("[Warning: Draw object ignored]");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Other drawing objects are currently not supported
|
// Other drawing objects are currently not supported
|
||||||
|
@ -159,6 +134,7 @@ public class DrawConverter extends ConverterHelper {
|
||||||
// handle draw:object elements (OOo objects such as Chart, Math,...)
|
// handle draw:object elements (OOo objects such as Chart, Math,...)
|
||||||
|
|
||||||
private void handleDrawObject(Element node, LaTeXDocumentPortion ldp, Context oc) {
|
private void handleDrawObject(Element node, LaTeXDocumentPortion ldp, Context oc) {
|
||||||
|
|
||||||
String sHref = Misc.getAttribute(node,XMLString.XLINK_HREF);
|
String sHref = Misc.getAttribute(node,XMLString.XLINK_HREF);
|
||||||
|
|
||||||
if (sHref!=null) { // Embedded object in package or linked object
|
if (sHref!=null) { // Embedded object in package or linked object
|
||||||
|
@ -169,13 +145,13 @@ public class DrawConverter extends ConverterHelper {
|
||||||
if (object!=null) {
|
if (object!=null) {
|
||||||
if (MIMETypes.MATH.equals(object.getType()) || MIMETypes.ODF.equals(object.getType())) { // Formula!
|
if (MIMETypes.MATH.equals(object.getType()) || MIMETypes.ODF.equals(object.getType())) { // Formula!
|
||||||
try {
|
try {
|
||||||
Document settings = ((EmbeddedXMLObject) object).getSettingsDOM();
|
Element settings = ((EmbeddedXMLObject) object).getSettingsDOM().getDocumentElement();
|
||||||
Document formuladoc = ((EmbeddedXMLObject) object).getContentDOM();
|
Document formuladoc = ((EmbeddedXMLObject) object).getContentDOM();
|
||||||
Element formula = Misc.getChildByTagName(formuladoc,XMLString.MATH); // Since OOo3.2
|
Element formula = Misc.getChildByTagName(formuladoc,XMLString.MATH); // Since OOo3.2
|
||||||
if (formula==null) {
|
if (formula==null) {
|
||||||
formula = Misc.getChildByTagName(formuladoc,XMLString.MATH_MATH);
|
formula = Misc.getChildByTagName(formuladoc,XMLString.MATH_MATH);
|
||||||
}
|
}
|
||||||
String sLaTeX = palette.getMathmlCv().convert(settings,formula);
|
String sLaTeX = palette.getMathCv().convert(settings,formula);
|
||||||
if (!" ".equals(sLaTeX)) { // ignore empty formulas
|
if (!" ".equals(sLaTeX)) { // ignore empty formulas
|
||||||
ldp.append(" $")
|
ldp.append(" $")
|
||||||
.append(sLaTeX)
|
.append(sLaTeX)
|
||||||
|
@ -214,7 +190,7 @@ public class DrawConverter extends ConverterHelper {
|
||||||
}
|
}
|
||||||
if (formula!=null) {
|
if (formula!=null) {
|
||||||
ldp.append(" $")
|
ldp.append(" $")
|
||||||
.append(palette.getMathmlCv().convert(null,formula))
|
.append(palette.getMathCv().convert(null,formula))
|
||||||
.append("$");
|
.append("$");
|
||||||
if (Character.isLetterOrDigit(OfficeReader.getNextChar(node))) { ldp.append(" "); }
|
if (Character.isLetterOrDigit(OfficeReader.getNextChar(node))) { ldp.append(" "); }
|
||||||
}
|
}
|
||||||
|
@ -233,7 +209,6 @@ public class DrawConverter extends ConverterHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
@ -288,47 +263,6 @@ public class DrawConverter extends ConverterHelper {
|
||||||
String sName = frame.getAttribute(XMLString.DRAW_NAME);
|
String sName = frame.getAttribute(XMLString.DRAW_NAME);
|
||||||
palette.getFieldCv().addTarget(sName,"|graphic",ldp);
|
palette.getFieldCv().addTarget(sName,"|graphic",ldp);
|
||||||
String sAnchor = frame.getAttribute(XMLString.TEXT_ANCHOR_TYPE);
|
String sAnchor = frame.getAttribute(XMLString.TEXT_ANCHOR_TYPE);
|
||||||
|
|
||||||
// TODO: Recognize Jex equations (needs further testing of Jex)
|
|
||||||
/*Element desc = Misc.getChildByTagName(frame,XMLString.SVG_DESC);
|
|
||||||
if (desc!=null) {
|
|
||||||
String sDesc = Misc.getPCDATA(desc);
|
|
||||||
if (sDesc.startsWith("jex149$tex={") && sDesc.endsWith("}")) {
|
|
||||||
String sTeX = sDesc.substring(12,sDesc.length()-1);
|
|
||||||
if (sTeX.length()>0) {
|
|
||||||
// Succesfully extracted Jex equation!
|
|
||||||
ldp.append("$"+sTeX+"$");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Recognize OOoLaTeX equation
|
|
||||||
// The LaTeX code is embedded in a custom style attribute:
|
|
||||||
StyleWithProperties style = ofr.getFrameStyle(
|
|
||||||
Misc.getAttribute(frame, XMLString.DRAW_STYLE_NAME));
|
|
||||||
if (style!=null) {
|
|
||||||
String sOOoLaTeX = style.getProperty("OOoLatexArgs");
|
|
||||||
// The content of the attribute is <point size><paragraph sign><mode><paragraph sign><TeX code>
|
|
||||||
int n=0;
|
|
||||||
if (sOOoLaTeX!=null) {
|
|
||||||
if ((n=sOOoLaTeX.indexOf("\u00A7display\u00A7"))>-1) {
|
|
||||||
ldp.append("\\[").append(sOOoLaTeX.substring(n+9)).append("\\]");
|
|
||||||
bNeedOOoLaTeXPreamble = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ((n=sOOoLaTeX.indexOf("\u00A7inline\u00A7"))>-1) {
|
|
||||||
ldp.append("$").append(sOOoLaTeX.substring(n+8)).append("$");
|
|
||||||
bNeedOOoLaTeXPreamble = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ((n=sOOoLaTeX.indexOf("\u00A7text\u00A7"))>-1) {
|
|
||||||
ldp.append(sOOoLaTeX.substring(n+6));
|
|
||||||
bNeedOOoLaTeXPreamble = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//if (oc.isInFrame() || "as-char".equals(sAnchor)) {
|
//if (oc.isInFrame() || "as-char".equals(sAnchor)) {
|
||||||
if ("as-char".equals(sAnchor)) {
|
if ("as-char".equals(sAnchor)) {
|
||||||
|
|
392
source/java/writer2latex/latex/MathConverter.java
Normal file
392
source/java/writer2latex/latex/MathConverter.java
Normal file
|
@ -0,0 +1,392 @@
|
||||||
|
/************************************************************************
|
||||||
|
*
|
||||||
|
* MathConverter.java
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License version 2.1, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
* MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* Copyright: 2002-2014 by Henrik Just
|
||||||
|
*
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Version 1.4 (2014-08-13)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package writer2latex.latex;
|
||||||
|
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
|
||||||
|
import writer2latex.base.ConverterBase.TexMathsStyle;
|
||||||
|
import writer2latex.office.EmbeddedObject;
|
||||||
|
import writer2latex.office.EmbeddedXMLObject;
|
||||||
|
import writer2latex.office.MIMETypes;
|
||||||
|
import writer2latex.office.OfficeReader;
|
||||||
|
import writer2latex.office.StyleWithProperties;
|
||||||
|
import writer2latex.office.TableReader;
|
||||||
|
import writer2latex.office.XMLString;
|
||||||
|
import writer2latex.util.Misc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This ConverterHelper converts mathematical content to LaTeX.
|
||||||
|
* It works slightly different than the other helpers: A number of elements may or may not
|
||||||
|
* have content that should be converted to math. Thus the methods offered first examines
|
||||||
|
* the content. If it turns out to be a mathematical formula, it is converted. Otherwise
|
||||||
|
* nothing is done, and the method returns false.
|
||||||
|
* Mathematical content may be MathML (with StarMath annotation), TexMaths or (the now obsolete) OOoLaTeX
|
||||||
|
*/
|
||||||
|
public final class MathConverter extends ConverterHelper {
|
||||||
|
|
||||||
|
private StarMathConverter smc;
|
||||||
|
|
||||||
|
private boolean bContainsFormulas = false;
|
||||||
|
private boolean bAddParAfterDisplay = false;
|
||||||
|
|
||||||
|
private boolean bNeedOOoLaTeXPreamble = false;
|
||||||
|
|
||||||
|
private Element theEquation = null;
|
||||||
|
private Element theSequence = null;
|
||||||
|
|
||||||
|
public MathConverter(OfficeReader ofr,LaTeXConfig config, ConverterPalette palette) {
|
||||||
|
super(ofr,config,palette);
|
||||||
|
smc = new StarMathConverter(palette.getI18n(),config);
|
||||||
|
bAddParAfterDisplay = config.formatting()>=LaTeXConfig.CONVERT_MOST;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void appendDeclarations(LaTeXDocumentPortion pack, LaTeXDocumentPortion decl) {
|
||||||
|
if (bContainsFormulas) {
|
||||||
|
if (config.useOoomath()) {
|
||||||
|
pack.append("\\usepackage{ooomath}").nl();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
smc.appendDeclarations(pack,decl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bNeedOOoLaTeXPreamble) {
|
||||||
|
// The preamble may be stored in the description
|
||||||
|
String sDescription = palette.getMetaData().getDescription();
|
||||||
|
int nStart = sDescription.indexOf("%%% OOoLatex Preamble %%%%%%%%%%%%%%");
|
||||||
|
int nEnd = sDescription.indexOf("%%% End OOoLatex Preamble %%%%%%%%%%%%");
|
||||||
|
if (nStart>-1 && nEnd>nStart) {
|
||||||
|
decl.append("% OOoLaTeX preamble").nl()
|
||||||
|
.append(sDescription.substring(nStart+37,nEnd));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Replace with a method "handleEquation"
|
||||||
|
public String convert(Element settings, Element formula) {
|
||||||
|
// TODO: Use settings to determine display mode/text mode
|
||||||
|
// formula must be a math:math node
|
||||||
|
// First try to find a StarMath annotation
|
||||||
|
Node semantics = Misc.getChildByTagName(formula,XMLString.SEMANTICS); // Since OOo 3.2
|
||||||
|
if (semantics==null) {
|
||||||
|
semantics = Misc.getChildByTagName(formula,XMLString.MATH_SEMANTICS);
|
||||||
|
}
|
||||||
|
if (semantics!=null) {
|
||||||
|
Node annotation = Misc.getChildByTagName(semantics,XMLString.ANNOTATION); // Since OOo 3.2
|
||||||
|
if (annotation==null) {
|
||||||
|
annotation = Misc.getChildByTagName(semantics,XMLString.MATH_ANNOTATION);
|
||||||
|
}
|
||||||
|
if (annotation!=null) {
|
||||||
|
String sStarMath = "";
|
||||||
|
if (annotation.hasChildNodes()) {
|
||||||
|
NodeList anl = annotation.getChildNodes();
|
||||||
|
int nLen = anl.getLength();
|
||||||
|
for (int i=0; i<nLen; i++) {
|
||||||
|
if (anl.item(i).getNodeType() == Node.TEXT_NODE) {
|
||||||
|
sStarMath+=anl.item(i).getNodeValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bContainsFormulas = true;
|
||||||
|
return smc.convert(sStarMath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// No annotation was found. In this case we should convert the mathml,
|
||||||
|
// but currently we ignore the problem.
|
||||||
|
// TODO: Investigate if Vasil I. Yaroshevich's MathML->LaTeX
|
||||||
|
// XSL transformation could be used here. (Potential problem:
|
||||||
|
// OOo uses MathML 1.01, not MathML 2)
|
||||||
|
if (formula.hasChildNodes()) {
|
||||||
|
return "\\text{Warning: No StarMath annotation}";
|
||||||
|
}
|
||||||
|
else { // empty formula
|
||||||
|
return " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Try to convert a draw:frame or draw:g element as an (inline) TexMaths or OOoLaTeX equation
|
||||||
|
*
|
||||||
|
* @param the element containing the equation (draw:frame or draw:g)
|
||||||
|
* @param ldp the LaTeXDocumentPortion to contain the converted equation
|
||||||
|
*
|
||||||
|
* @return true if this elements happen to be a TexMaths equation, otherwise false
|
||||||
|
*/
|
||||||
|
public boolean handleTexMathsEquation(Element node, LaTeXDocumentPortion ldp) {
|
||||||
|
String sLaTeX = null;
|
||||||
|
Element equation = palette.getTexMathsEquation(node);
|
||||||
|
if (equation!=null) {
|
||||||
|
sLaTeX = Misc.getPCDATA(equation);
|
||||||
|
}
|
||||||
|
else { // Try OOoLaTeX
|
||||||
|
// The LaTeX code is embedded in a custom style attribute:
|
||||||
|
StyleWithProperties style = ofr.getFrameStyle(Misc.getAttribute(node, XMLString.DRAW_STYLE_NAME));
|
||||||
|
if (style!=null) {
|
||||||
|
sLaTeX = style.getProperty("OOoLatexArgs");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sLaTeX!=null) {
|
||||||
|
// Format is <point size>X<mode>X<TeX code>X<format>X<resolution>X<transparency>
|
||||||
|
// where X is a paragraph sign
|
||||||
|
switch (palette.getTexMathsStyle(sLaTeX)) {
|
||||||
|
case inline:
|
||||||
|
ldp.append("$").append(palette.getTexMathsEquation(sLaTeX)).append("$");
|
||||||
|
break;
|
||||||
|
case display:
|
||||||
|
ldp.append("$\\displaystyle ").append(palette.getTexMathsEquation(sLaTeX)).append("$");
|
||||||
|
break;
|
||||||
|
case latex:
|
||||||
|
ldp.append(palette.getTexMathsEquation(sLaTeX));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Try to convert a table as a display equation:
|
||||||
|
* A 1 row by 2 columns table in which each cell contains exactly one paragraph,
|
||||||
|
* the left cell contains exactly one formula and the right cell contains exactly
|
||||||
|
* one sequence number is treated as a (numbered) display equation.
|
||||||
|
* This happens to coincide with the AutoText provided with OOo Writer :-)
|
||||||
|
* @param table the table reader
|
||||||
|
* @param ldp the LaTeXDocumentPortion to contain the converted equation
|
||||||
|
* @return true if the conversion was successful, false if the table
|
||||||
|
* did not represent a display equation
|
||||||
|
*/
|
||||||
|
public boolean handleDisplayEquation(TableReader table, LaTeXDocumentPortion ldp) {
|
||||||
|
if (table.getRowCount()==1 && table.getColCount()==2 &&
|
||||||
|
OfficeReader.isSingleParagraph(table.getCell(0, 0)) && OfficeReader.isSingleParagraph(table.getCell(0, 1)) ) {
|
||||||
|
// Table of the desired form
|
||||||
|
if (parseDisplayEquation(Misc.getFirstChildElement(table.getCell(0, 0))) && theEquation!=null && theSequence==null) {
|
||||||
|
// Found equation in first cell
|
||||||
|
Element myEquation = theEquation;
|
||||||
|
if (parseDisplayEquation(Misc.getFirstChildElement(table.getCell(0, 1))) && theEquation==null && theSequence!=null) {
|
||||||
|
// Found sequence in second cell
|
||||||
|
handleDisplayEquation(myEquation, theSequence, ldp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Try to convert a paragraph as a display equation:
|
||||||
|
* A paragraph which contains exactly one formula + at most one sequence
|
||||||
|
* number is treated as a display equation. Other content must be brackets
|
||||||
|
* or whitespace (possibly with formatting).
|
||||||
|
* @param node the paragraph
|
||||||
|
* @param ldp the LaTeXDocumentPortion to contain the converted equation
|
||||||
|
* @return true if the conversion was successful, false if the paragraph
|
||||||
|
* did not contain a display equation
|
||||||
|
*/
|
||||||
|
public boolean handleDisplayEquation(Element node, LaTeXDocumentPortion ldp) {
|
||||||
|
if (parseDisplayEquation(node) && theEquation!=null) {
|
||||||
|
handleDisplayEquation(theEquation, theSequence, ldp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleDisplayEquation(Element equation, Element sequence, LaTeXDocumentPortion ldp) {
|
||||||
|
boolean bTexMaths = equation.getTagName().equals(XMLString.SVG_DESC);
|
||||||
|
TexMathsStyle style = TexMathsStyle.inline;
|
||||||
|
String sLaTeX;
|
||||||
|
if (bTexMaths) {
|
||||||
|
// TeXMaths equation
|
||||||
|
sLaTeX = palette.getTexMathsEquation(Misc.getPCDATA(equation));
|
||||||
|
style = palette.getTexMathsStyle(Misc.getPCDATA(equation));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// MathML equation
|
||||||
|
sLaTeX = convert(null,equation);
|
||||||
|
}
|
||||||
|
if (!" ".equals(sLaTeX)) { // ignore empty formulas
|
||||||
|
if (!bTexMaths || style!=TexMathsStyle.latex) {
|
||||||
|
if (sequence!=null) {
|
||||||
|
// Numbered equation
|
||||||
|
ldp.append("\\begin{equation}");
|
||||||
|
palette.getFieldCv().handleSequenceLabel(sequence,ldp);
|
||||||
|
if (bTexMaths && style==TexMathsStyle.inline) {
|
||||||
|
ldp.append("\\textstyle ");
|
||||||
|
}
|
||||||
|
ldp.nl()
|
||||||
|
.append(sLaTeX).nl()
|
||||||
|
.append("\\end{equation}").nl();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Unnumbered equation
|
||||||
|
ldp.append("\\begin{equation*}");
|
||||||
|
if (bTexMaths && style==TexMathsStyle.inline) {
|
||||||
|
ldp.append("\\textstyle ");
|
||||||
|
}
|
||||||
|
ldp.nl()
|
||||||
|
.append(sLaTeX).nl()
|
||||||
|
.append("\\end{equation*}").nl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ldp.append(sLaTeX).nl();
|
||||||
|
}
|
||||||
|
if (bAddParAfterDisplay) { ldp.nl(); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Determine whether or not a paragraph contains a display equation.
|
||||||
|
* A paragraph is a display equation if it contains a single formula and no text content except whitespace
|
||||||
|
* and an optional sequence number which may be in brackets.
|
||||||
|
* As a side effect, this method keeps a reference to the equation and the sequence number
|
||||||
|
*
|
||||||
|
* @param node the paragraph
|
||||||
|
* @return true if this is a display equation
|
||||||
|
*/
|
||||||
|
public boolean parseDisplayEquation(Node node) {
|
||||||
|
theEquation = null;
|
||||||
|
theSequence = null;
|
||||||
|
return doParseDisplayEquation(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean doParseDisplayEquation(Node node) {
|
||||||
|
Node child = node.getFirstChild();
|
||||||
|
while (child!=null) {
|
||||||
|
if (Misc.isElement(child)) {
|
||||||
|
Element elm = (Element) child;
|
||||||
|
String sName = elm.getTagName();
|
||||||
|
// First check for MathML or TexMaths equation
|
||||||
|
Element equation = getMathmlEquation(elm);
|
||||||
|
if (equation==null) {
|
||||||
|
equation = palette.getTexMathsEquation(elm);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (equation!=null) {
|
||||||
|
if (theEquation==null) {
|
||||||
|
theEquation = equation;
|
||||||
|
}
|
||||||
|
else { // two or more equations -> not a display
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (XMLString.TEXT_SEQUENCE.equals(sName)) {
|
||||||
|
if (theSequence==null) {
|
||||||
|
theSequence = elm;
|
||||||
|
}
|
||||||
|
else { // two sequence numbers -> not a display
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (XMLString.TEXT_SPAN.equals(sName)) {
|
||||||
|
if (!doParseDisplayEquation(child)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (XMLString.TEXT_S.equals(sName)) {
|
||||||
|
// Spaces are allowed
|
||||||
|
}
|
||||||
|
else if (XMLString.TEXT_TAB.equals(sName)) {
|
||||||
|
// Tab stops are allowed
|
||||||
|
}
|
||||||
|
else if (XMLString.TEXT_TAB_STOP.equals(sName)) { // old
|
||||||
|
// Tab stops are allowed
|
||||||
|
}
|
||||||
|
else if (XMLString.TEXT_SOFT_PAGE_BREAK.equals(sName)) { // since ODF 1.1
|
||||||
|
// Soft page breaks are allowed
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Other elements -> not a display
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Misc.isText(child)) {
|
||||||
|
String s = child.getNodeValue();
|
||||||
|
int nLen = s.length();
|
||||||
|
for (int i=0; i<nLen; i++) {
|
||||||
|
char c = s.charAt(i);
|
||||||
|
if (c!='(' && c!=')' && c!='[' && c!=']' && c!='{' && c!='}' && c!=' ' && c!='\u00A0') {
|
||||||
|
// Characters except brackets and whitespace -> not a display
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
child = child.getNextSibling();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get a MathML formula from a draw:frame
|
||||||
|
*
|
||||||
|
* @param node the draw:frame
|
||||||
|
* @return the MathML element, or null if this is not a MathML formula
|
||||||
|
*/
|
||||||
|
public Element getMathmlEquation(Element node) {
|
||||||
|
if (node.getTagName().equals(XMLString.DRAW_FRAME)) {
|
||||||
|
node=Misc.getFirstChildElement(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
String sHref = Misc.getAttribute(node,XMLString.XLINK_HREF);
|
||||||
|
|
||||||
|
if (sHref!=null) { // Embedded object in package or linked object
|
||||||
|
if (ofr.isInPackage(sHref)) { // Embedded object in package
|
||||||
|
if (sHref.startsWith("#")) { sHref=sHref.substring(1); }
|
||||||
|
if (sHref.startsWith("./")) { sHref=sHref.substring(2); }
|
||||||
|
EmbeddedObject object = palette.getEmbeddedObject(sHref);
|
||||||
|
if (object!=null) {
|
||||||
|
if (MIMETypes.MATH.equals(object.getType()) || MIMETypes.ODF.equals(object.getType())) { // Formula!
|
||||||
|
try {
|
||||||
|
Document formuladoc = ((EmbeddedXMLObject) object).getContentDOM();
|
||||||
|
Element formula = Misc.getChildByTagName(formuladoc,XMLString.MATH); // Since OOo 3.2
|
||||||
|
if (formula==null) {
|
||||||
|
formula = Misc.getChildByTagName(formuladoc,XMLString.MATH_MATH);
|
||||||
|
}
|
||||||
|
return formula;
|
||||||
|
}
|
||||||
|
catch (org.xml.sax.SAXException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
catch (java.io.IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // flat XML, object is contained in node
|
||||||
|
Element formula = Misc.getChildByTagName(node,XMLString.MATH); // Since OOo 3.2
|
||||||
|
if (formula==null) {
|
||||||
|
formula = Misc.getChildByTagName(node,XMLString.MATH_MATH);
|
||||||
|
}
|
||||||
|
return formula;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,249 +0,0 @@
|
||||||
/************************************************************************
|
|
||||||
*
|
|
||||||
* MathmlConverter.java
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License version 2.1, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
||||||
* MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
* Copyright: 2002-2014 by Henrik Just
|
|
||||||
*
|
|
||||||
* All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Version 1.4 (2014-08-08)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package writer2latex.latex;
|
|
||||||
|
|
||||||
|
|
||||||
import org.w3c.dom.Element;
|
|
||||||
import org.w3c.dom.Node;
|
|
||||||
import org.w3c.dom.NodeList;
|
|
||||||
|
|
||||||
import writer2latex.latex.util.Context;
|
|
||||||
import writer2latex.office.OfficeReader;
|
|
||||||
import writer2latex.office.TableReader;
|
|
||||||
import writer2latex.office.XMLString;
|
|
||||||
import writer2latex.util.Misc;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class converts MathML nodes to LaTeX.
|
|
||||||
* The class name is slightly misleading:
|
|
||||||
* It only converts the StarMath annotation, if available
|
|
||||||
* and it also converts TexMaths formulas
|
|
||||||
*/
|
|
||||||
public final class MathmlConverter extends ConverterHelper {
|
|
||||||
|
|
||||||
private enum TexMathsStyle {inline, display, latex};
|
|
||||||
|
|
||||||
private StarMathConverter smc;
|
|
||||||
|
|
||||||
private boolean bContainsFormulas = false;
|
|
||||||
private boolean bAddParAfterDisplay = false;
|
|
||||||
|
|
||||||
public MathmlConverter(OfficeReader ofr,LaTeXConfig config, ConverterPalette palette) {
|
|
||||||
super(ofr,config,palette);
|
|
||||||
smc = new StarMathConverter(palette.getI18n(),config);
|
|
||||||
bAddParAfterDisplay = config.formatting()>=LaTeXConfig.CONVERT_MOST;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void appendDeclarations(LaTeXDocumentPortion pack, LaTeXDocumentPortion decl) {
|
|
||||||
if (bContainsFormulas) {
|
|
||||||
if (config.useOoomath()) {
|
|
||||||
pack.append("\\usepackage{ooomath}").nl();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
smc.appendDeclarations(pack,decl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String convert(Node settings, Node formula) {
|
|
||||||
// TODO: Use settings to determine display mode/text mode
|
|
||||||
// formula must be a math:math node
|
|
||||||
// First try to find a StarMath annotation
|
|
||||||
Node semantics = Misc.getChildByTagName(formula,XMLString.SEMANTICS); // Since OOo 3.2
|
|
||||||
if (semantics==null) {
|
|
||||||
semantics = Misc.getChildByTagName(formula,XMLString.MATH_SEMANTICS);
|
|
||||||
}
|
|
||||||
if (semantics!=null) {
|
|
||||||
Node annotation = Misc.getChildByTagName(semantics,XMLString.ANNOTATION); // Since OOo 3.2
|
|
||||||
if (annotation==null) {
|
|
||||||
annotation = Misc.getChildByTagName(semantics,XMLString.MATH_ANNOTATION);
|
|
||||||
}
|
|
||||||
if (annotation!=null) {
|
|
||||||
String sStarMath = "";
|
|
||||||
if (annotation.hasChildNodes()) {
|
|
||||||
NodeList anl = annotation.getChildNodes();
|
|
||||||
int nLen = anl.getLength();
|
|
||||||
for (int i=0; i<nLen; i++) {
|
|
||||||
if (anl.item(i).getNodeType() == Node.TEXT_NODE) {
|
|
||||||
sStarMath+=anl.item(i).getNodeValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bContainsFormulas = true;
|
|
||||||
return smc.convert(sStarMath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// No annotation was found. In this case we should convert the mathml,
|
|
||||||
// but currently we ignore the problem.
|
|
||||||
// TODO: Investigate if Vasil I. Yaroshevich's MathML->LaTeX
|
|
||||||
// XSL transformation could be used here. (Potential problem:
|
|
||||||
// OOo uses MathML 1.01, not MathML 2)
|
|
||||||
if (formula.hasChildNodes()) {
|
|
||||||
return "\\text{Warning: No StarMath annotation}";
|
|
||||||
}
|
|
||||||
else { // empty formula
|
|
||||||
return " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Handle an (inline) TexMaths equation
|
|
||||||
*
|
|
||||||
* @param node the equation (an svg:desc element containing the formula)
|
|
||||||
* @param ldp the LaTeXDocumentPortion to contain the converted equation
|
|
||||||
* @param oc the current context
|
|
||||||
*/
|
|
||||||
public void handleTexMathsEquation(Element node, LaTeXDocumentPortion ldp, Context oc) {
|
|
||||||
// LaTeX code is contained in svg:desc
|
|
||||||
// Format is <point size>X<mode>X<TeX code>X<format>X<resolution>X<transparency>
|
|
||||||
// where X is a paragraph sign
|
|
||||||
switch (getTexMathsStyle(node)) {
|
|
||||||
case inline:
|
|
||||||
ldp.append("$").append(getTexMathsEquation(node)).append("$");
|
|
||||||
break;
|
|
||||||
case display:
|
|
||||||
ldp.append("$\\displaystyle ").append(getTexMathsEquation(node)).append("$");
|
|
||||||
break;
|
|
||||||
case latex:
|
|
||||||
ldp.append(getTexMathsEquation(node));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private TexMathsStyle getTexMathsStyle(Element node) {
|
|
||||||
String[] sContent = Misc.getPCDATA(node).split("\u00a7");
|
|
||||||
if (sContent.length>=3) { // we only need 3 items of 6
|
|
||||||
if ("display".equals(sContent[1])) {
|
|
||||||
return TexMathsStyle.display;
|
|
||||||
}
|
|
||||||
else if ("latex".equals(sContent[1])) {
|
|
||||||
return TexMathsStyle.latex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return TexMathsStyle.inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getTexMathsEquation(Element node) {
|
|
||||||
String[] sContent = Misc.getPCDATA(node).split("\u00a7");
|
|
||||||
if (sContent.length>=3) { // we only need 3 items of 6
|
|
||||||
return sContent[2];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Try to convert a table as a display equation:
|
|
||||||
* A 1 row by 2 columns table in which each cell contains exactly one paragraph,
|
|
||||||
* the left cell contains exactly one formula and the right cell contains exactly
|
|
||||||
* one sequence number is treated as a (numbered) display equation.
|
|
||||||
* This happens to coincide with the AutoText provided with OOo Writer :-)
|
|
||||||
* @param table the table reader
|
|
||||||
* @param ldp the LaTeXDocumentPortion to contain the converted equation
|
|
||||||
* @return true if the conversion was successful, false if the table
|
|
||||||
* did not represent a display equation
|
|
||||||
*/
|
|
||||||
public boolean handleDisplayEquation(TableReader table, LaTeXDocumentPortion ldp) {
|
|
||||||
if (table.getRowCount()==1 && table.getColCount()==2 &&
|
|
||||||
OfficeReader.isSingleParagraph(table.getCell(0, 0)) && OfficeReader.isSingleParagraph(table.getCell(0, 1)) ) {
|
|
||||||
// Table of the desired form
|
|
||||||
if (palette.parseDisplayEquation(Misc.getFirstChildElement(table.getCell(0, 0))) && palette.getEquation()!=null && palette.getSequence()==null) {
|
|
||||||
// Found equation in first cell
|
|
||||||
Element myEquation = palette.getEquation();
|
|
||||||
if (palette.parseDisplayEquation(Misc.getFirstChildElement(table.getCell(0, 1))) && palette.getEquation()==null && palette.getSequence()!=null) {
|
|
||||||
// Found sequence in second cell
|
|
||||||
handleDisplayEquation(myEquation, palette.getSequence(), ldp);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**Try to convert a paragraph as a display equation:
|
|
||||||
* A paragraph which contains exactly one formula + at most one sequence
|
|
||||||
* number is treated as a display equation. Other content must be brackets
|
|
||||||
* or whitespace (possibly with formatting).
|
|
||||||
* @param node the paragraph
|
|
||||||
* @param ldp the LaTeXDocumentPortion to contain the converted equation
|
|
||||||
* @return true if the conversion was successful, false if the paragraph
|
|
||||||
* did not contain a display equation
|
|
||||||
*/
|
|
||||||
public boolean handleDisplayEquation(Element node, LaTeXDocumentPortion ldp) {
|
|
||||||
if (palette.parseDisplayEquation(node) && palette.getEquation()!=null) {
|
|
||||||
handleDisplayEquation(palette.getEquation(), palette.getSequence(), ldp);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleDisplayEquation(Element equation, Element sequence, LaTeXDocumentPortion ldp) {
|
|
||||||
boolean bTexMaths = equation.getTagName().equals(XMLString.SVG_DESC);
|
|
||||||
TexMathsStyle style = TexMathsStyle.inline;
|
|
||||||
String sLaTeX;
|
|
||||||
if (bTexMaths) {
|
|
||||||
// TeXMaths equation
|
|
||||||
sLaTeX = getTexMathsEquation(equation);
|
|
||||||
style = getTexMathsStyle(equation);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// MathML equation
|
|
||||||
sLaTeX = convert(null,equation);
|
|
||||||
}
|
|
||||||
if (!" ".equals(sLaTeX)) { // ignore empty formulas
|
|
||||||
if (!bTexMaths || style!=TexMathsStyle.latex) {
|
|
||||||
if (sequence!=null) {
|
|
||||||
// Numbered equation
|
|
||||||
ldp.append("\\begin{equation}");
|
|
||||||
palette.getFieldCv().handleSequenceLabel(sequence,ldp);
|
|
||||||
if (bTexMaths && style==TexMathsStyle.inline) {
|
|
||||||
ldp.append("\\textstyle ");
|
|
||||||
}
|
|
||||||
ldp.nl()
|
|
||||||
.append(sLaTeX).nl()
|
|
||||||
.append("\\end{equation}").nl();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Unnumbered equation
|
|
||||||
ldp.append("\\begin{equation*}");
|
|
||||||
if (bTexMaths && style==TexMathsStyle.inline) {
|
|
||||||
ldp.append("\\textstyle ");
|
|
||||||
}
|
|
||||||
ldp.nl()
|
|
||||||
.append(sLaTeX).nl()
|
|
||||||
.append("\\end{equation*}").nl();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ldp.append(sLaTeX).nl();
|
|
||||||
}
|
|
||||||
if (bAddParAfterDisplay) { ldp.nl(); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -98,7 +98,7 @@ public class ParConverter extends StyleConverter {
|
||||||
* \end{enumerate}).
|
* \end{enumerate}).
|
||||||
*/
|
*/
|
||||||
public void handleParagraph(Element node, LaTeXDocumentPortion ldp, Context oc, boolean bLastInBlock) {
|
public void handleParagraph(Element node, LaTeXDocumentPortion ldp, Context oc, boolean bLastInBlock) {
|
||||||
if (palette.getMathmlCv().handleDisplayEquation(node,ldp)) { return; }
|
if (palette.getMathCv().handleDisplayEquation(node,ldp)) { return; }
|
||||||
|
|
||||||
// Get the style name for this paragraph
|
// Get the style name for this paragraph
|
||||||
String sStyleName = node.getAttribute(XMLString.TEXT_STYLE_NAME);
|
String sStyleName = node.getAttribute(XMLString.TEXT_STYLE_NAME);
|
||||||
|
|
|
@ -166,7 +166,7 @@ public class TableConverter extends ConverterHelper {
|
||||||
// Read the table
|
// Read the table
|
||||||
table = ofr.getTableReader(node);
|
table = ofr.getTableReader(node);
|
||||||
|
|
||||||
if (palette.getMathmlCv().handleDisplayEquation(table,ldp)) { return; }
|
if (palette.getMathCv().handleDisplayEquation(table,ldp)) { return; }
|
||||||
|
|
||||||
// Get formatter and update flags according to formatter
|
// Get formatter and update flags according to formatter
|
||||||
formatter = new TableFormatter(ofr,config,palette,table,!oc.isInMulticols(),oc.isInTable());
|
formatter = new TableFormatter(ofr,config,palette,table,!oc.isInMulticols(),oc.isInTable());
|
||||||
|
|
|
@ -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-07)
|
* Version 1.4 (2014-08-13)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -351,7 +351,7 @@ public class Converter extends ConverterBase {
|
||||||
|
|
||||||
// Load MathJax
|
// Load MathJax
|
||||||
// TODO: Should we support different configurations of MathJax?
|
// TODO: Should we support different configurations of MathJax?
|
||||||
if (nType==XhtmlDocument.HTML5 && config.useMathJax()) {
|
if ((nType==XhtmlDocument.HTML5 || nType==XhtmlDocument.XHTML_MATHML) && config.useMathJax()) {
|
||||||
for (int i=0; i<=nOutFileIndex; i++) {
|
for (int i=0; i<=nOutFileIndex; i++) {
|
||||||
if (outFiles.get(i).hasMath()) {
|
if (outFiles.get(i).hasMath()) {
|
||||||
XhtmlDocument doc = outFiles.get(i);
|
XhtmlDocument doc = outFiles.get(i);
|
||||||
|
@ -360,7 +360,7 @@ public class Converter extends ConverterBase {
|
||||||
Element script = doc.getContentDOM().createElement("script");
|
Element script = doc.getContentDOM().createElement("script");
|
||||||
head.appendChild(script);
|
head.appendChild(script);
|
||||||
script.setAttribute("type", "text/javascript");
|
script.setAttribute("type", "text/javascript");
|
||||||
script.setAttribute("src", "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=MML_HTMLorMML");
|
script.setAttribute("src", "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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-03-30)
|
* Version 1.4 (2014-08-13)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ public class ConverterHelper {
|
||||||
protected PresentationStyleConverter getPresentationSc() { return converter.getStyleCv().getPresentationSc(); }
|
protected PresentationStyleConverter getPresentationSc() { return converter.getStyleCv().getPresentationSc(); }
|
||||||
|
|
||||||
protected PageStyleConverter getPageSc() { return converter.getStyleCv().getPageSc(); }
|
protected PageStyleConverter getPageSc() { return converter.getStyleCv().getPageSc(); }
|
||||||
|
|
||||||
protected TextConverter getTextCv() { return converter.getTextCv(); }
|
protected TextConverter getTextCv() { return converter.getTextCv(); }
|
||||||
|
|
||||||
protected TableConverter getTableCv() { return converter.getTableCv(); }
|
protected TableConverter getTableCv() { return converter.getTableCv(); }
|
||||||
|
|
|
@ -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-07)
|
* Version 1.4 (2014-08-12)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -331,16 +331,22 @@ public class DrawConverter extends ConverterHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sName.equals(XMLString.DRAW_FRAME)) {
|
else if (sName.equals(XMLString.DRAW_FRAME)) {
|
||||||
// OpenDocument embeds the draw element in a frame element
|
// First check for TexMaths equation
|
||||||
handleDrawElement(Misc.getFirstChildElement(onode),hnodeBlock,hnodeInline,nMode);
|
if (!getMathCv().convertTexMathsEquation(onode, hnodeBlock, hnodeInline, nMode)) {
|
||||||
|
// OpenDocument embeds the draw element in a frame element
|
||||||
|
handleDrawElement(Misc.getFirstChildElement(onode),hnodeBlock,hnodeInline,nMode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (sName.equals(XMLString.DRAW_G)) {
|
else if (sName.equals(XMLString.DRAW_G)) {
|
||||||
handleDrawGroup(onode,hnodeBlock,hnodeInline,nMode);
|
// First check for TexMaths equation
|
||||||
|
if (!getMathCv().convertTexMathsEquation(onode, hnodeBlock, hnodeInline, nMode)) {
|
||||||
|
handleDrawGroup(onode,hnodeBlock,hnodeInline,nMode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (sName.equals(XMLString.DRAW_CONTROL)) {
|
else if (sName.equals(XMLString.DRAW_CONTROL)) {
|
||||||
handleDrawControl(onode,hnodeBlock,hnodeInline,nMode);
|
handleDrawControl(onode,hnodeBlock,hnodeInline,nMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleDrawObject(Element onode, Element hnodeBlock, Element hnodeInline, int nMode) {
|
private void handleDrawObject(Element onode, Element hnodeBlock, Element hnodeInline, int nMode) {
|
||||||
// TODO: Placement if not inline
|
// TODO: Placement if not inline
|
||||||
|
|
|
@ -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-07)
|
* Version 1.4 (2014-08-13)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -72,9 +72,6 @@ public class MathConverter extends ConverterHelper {
|
||||||
*/
|
*/
|
||||||
public void convert(Node image, Element onode, Node hnode) {
|
public void convert(Node image, Element onode, Node hnode) {
|
||||||
if (bSupportMathML) {
|
if (bSupportMathML) {
|
||||||
if (converter.getTextCv().isDisplayEquation()) {
|
|
||||||
onode.setAttribute("display", "block");
|
|
||||||
}
|
|
||||||
convertAsMathML(onode,hnode);
|
convertAsMathML(onode,hnode);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -82,6 +79,57 @@ public class MathConverter extends ConverterHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean convertTexMathsEquation(Element onode, Element hnodeBlock, Element hnodeInline, int nMode) {
|
||||||
|
// If possible, add the object inline. In pure block context, add a div.
|
||||||
|
Element hnode;
|
||||||
|
if (hnodeInline!=null) {
|
||||||
|
hnode = hnodeInline;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Element div = converter.createElement("div");
|
||||||
|
hnodeBlock.appendChild(div);
|
||||||
|
hnode = div;
|
||||||
|
}
|
||||||
|
|
||||||
|
String sLaTeX = null;
|
||||||
|
Element equation = converter.getTexMathsEquation(onode);
|
||||||
|
if (equation!=null) {
|
||||||
|
sLaTeX = Misc.getPCDATA(equation);
|
||||||
|
}
|
||||||
|
else { // Try OOoLaTeX
|
||||||
|
// The LaTeX code is embedded in a custom style attribute:
|
||||||
|
StyleWithProperties style = ofr.getFrameStyle(Misc.getAttribute(onode, XMLString.DRAW_STYLE_NAME));
|
||||||
|
if (style!=null) {
|
||||||
|
sLaTeX = style.getProperty("OOoLatexArgs");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sLaTeX!=null) {
|
||||||
|
// Format is <point size>X<mode>X<TeX code>X<format>X<resolution>X<transparency>
|
||||||
|
// where X is a paragraph sign
|
||||||
|
String sMathJax;
|
||||||
|
if (config.useMathJax() && bSupportMathML) {
|
||||||
|
switch (converter.getTexMathsStyle(sLaTeX)) {
|
||||||
|
case inline:
|
||||||
|
sMathJax = "\\("+converter.getTexMathsEquation(sLaTeX)+"\\)";
|
||||||
|
break;
|
||||||
|
case display:
|
||||||
|
sMathJax = "\\["+converter.getTexMathsEquation(sLaTeX)+"\\]";
|
||||||
|
break;
|
||||||
|
case latex:
|
||||||
|
default: // Arbitrary LaTeX; this is the tricky bit
|
||||||
|
sMathJax = "\\("+converter.getTexMathsEquation(sLaTeX)+"\\)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sMathJax = " "+converter.getTexMathsEquation(sLaTeX)+" ";
|
||||||
|
}
|
||||||
|
hnode.appendChild(converter.createTextNode(sMathJax));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// For plain xhtml: Convert the formula as an image or as plain text
|
// For plain xhtml: Convert the formula as an image or as plain text
|
||||||
private void convertAsImageOrText(Node image, Node onode, Node hnode) {
|
private void convertAsImageOrText(Node image, Node onode, Node hnode) {
|
||||||
NodeList annotationList = ((Element) onode).getElementsByTagName(XMLString.ANNOTATION); // Since OOo 3.2
|
NodeList annotationList = ((Element) onode).getElementsByTagName(XMLString.ANNOTATION); // Since OOo 3.2
|
||||||
|
|
|
@ -16,18 +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-2014 by Henrik Just
|
||||||
*
|
*
|
||||||
* All Rights Reserved.
|
* All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Version 1.2 (2011-02-17)
|
* Version 1.4 (2014-08-13)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package writer2latex.xhtml;
|
package writer2latex.xhtml;
|
||||||
|
|
||||||
//import java.util.Enumeration;
|
|
||||||
//import java.util.Hashtable;
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
|
@ -64,7 +62,7 @@ class StyleConverter extends ConverterHelper {
|
||||||
|
|
||||||
// Helper for page styles
|
// Helper for page styles
|
||||||
private PageStyleConverter pageSc;
|
private PageStyleConverter pageSc;
|
||||||
|
|
||||||
/** <p>Create a new <code>StyleConverter</code></p>
|
/** <p>Create a new <code>StyleConverter</code></p>
|
||||||
*/
|
*/
|
||||||
public StyleConverter(OfficeReader ofr, XhtmlConfig config, Converter converter, int nType) {
|
public StyleConverter(OfficeReader ofr, XhtmlConfig config, Converter converter, int nType) {
|
||||||
|
|
|
@ -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-07)
|
* Version 1.4 (2014-08-13)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -141,9 +141,6 @@ public class TextConverter extends ConverterHelper {
|
||||||
// We put it here and insert it in the first paragraph/heading to come:
|
// We put it here and insert it in the first paragraph/heading to come:
|
||||||
private Node asapNode = null;
|
private Node asapNode = null;
|
||||||
|
|
||||||
// Are we within a display equation?
|
|
||||||
private boolean bDisplayEquation = false;
|
|
||||||
|
|
||||||
// When generating toc, a few things should be done differently
|
// When generating toc, a few things should be done differently
|
||||||
private boolean bInToc = false;
|
private boolean bInToc = false;
|
||||||
|
|
||||||
|
@ -361,10 +358,6 @@ public class TextConverter extends ConverterHelper {
|
||||||
return inline;
|
return inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDisplayEquation() {
|
|
||||||
return bDisplayEquation;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// BLOCK TEXT (returns current html node at end of block)
|
// BLOCK TEXT (returns current html node at end of block)
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -820,9 +813,7 @@ public class TextConverter extends ConverterHelper {
|
||||||
insertListLabel(currentListStyle, nCurrentListLevel, "ItemNumber", null, sCurrentListLabel, par);
|
insertListLabel(currentListStyle, nCurrentListLevel, "ItemNumber", null, sCurrentListLabel, par);
|
||||||
}
|
}
|
||||||
sCurrentListLabel = null;
|
sCurrentListLabel = null;
|
||||||
bDisplayEquation=converter.parseDisplayEquation(onode);
|
|
||||||
traverseInlineText(onode,par);
|
traverseInlineText(onode,par);
|
||||||
bDisplayEquation=false;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// An empty paragraph (this includes paragraphs that only contains
|
// An empty paragraph (this includes paragraphs that only contains
|
||||||
|
|
Loading…
Add table
Reference in a new issue