summaryrefslogtreecommitdiff
path: root/starmath
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@suse.cz>2011-11-18 18:09:43 +0100
committerLuboš Luňák <l.lunak@suse.cz>2011-11-24 18:43:57 +0100
commite9462ed2d978dc3e641227ea9f553eeed4d81a97 (patch)
tree8b77274817348852458ed19be1bd46bb66d0a749 /starmath
parent1d163e4835b4906eb4559851e5ab2470b26332fe (diff)
ooxml mathml import - first very basic implementation
still needs a number of cleanups (and handling more of course)
Diffstat (limited to 'starmath')
-rw-r--r--starmath/Library_sm.mk1
-rw-r--r--starmath/inc/document.hxx5
-rw-r--r--starmath/inc/unomodel.hxx6
-rw-r--r--starmath/source/document.cxx10
-rw-r--r--starmath/source/ooxmlimport.cxx233
-rw-r--r--starmath/source/ooxmlimport.hxx78
-rw-r--r--starmath/source/unomodel.cxx5
7 files changed, 337 insertions, 1 deletions
diff --git a/starmath/Library_sm.mk b/starmath/Library_sm.mk
index 6b9c7babdca4..9c4a6904450e 100644
--- a/starmath/Library_sm.mk
+++ b/starmath/Library_sm.mk
@@ -80,6 +80,7 @@ $(eval $(call gb_Library_add_exception_objects,sm,\
starmath/source/mathtype \
starmath/source/node \
starmath/source/ooxmlexport \
+ starmath/source/ooxmlimport \
starmath/source/parse \
starmath/source/rect \
starmath/source/register \
diff --git a/starmath/inc/document.hxx b/starmath/inc/document.hxx
index 99f0d8b4cc79..c1b48629a454 100644
--- a/starmath/inc/document.hxx
+++ b/starmath/inc/document.hxx
@@ -53,6 +53,10 @@ class SfxMenuBarManager;
class SfxPrinter;
class Printer;
class SmCursor;
+namespace ooxmlformulaimport
+{
+class XmlStream;
+}
#define HINT_DATACHANGED 1004
@@ -175,6 +179,7 @@ class SmDocShell : public SfxObjectShell, public SfxListener
void InvalidateCursor();
bool writeFormulaOoxml( ::sax_fastparser::FSHelperPtr m_pSerializer, oox::core::OoxmlVersion version );
+ bool readFormulaOoxml( ooxmlformulaimport::XmlStream& stream );
public:
TYPEINFO();
diff --git a/starmath/inc/unomodel.hxx b/starmath/inc/unomodel.hxx
index 66479f988ec5..1324c9f8bc88 100644
--- a/starmath/inc/unomodel.hxx
+++ b/starmath/inc/unomodel.hxx
@@ -38,6 +38,7 @@
#include <comphelper/propertysethelper.hxx>
#include <vcl/print.hxx>
#include <oox/export/ooxmlexport.hxx>
+#include <oox/export/starmathimport.hxx>
class SmFormat;
@@ -65,7 +66,8 @@ class SmModel : public SfxBaseModel,
public comphelper::PropertySetHelper,
public com::sun::star::lang::XServiceInfo,
public com::sun::star::view::XRenderable,
- public OoxmlFormulaExportBase
+ public OoxmlFormulaExportBase,
+ public OoxmlFormulaImportBase
{
SmPrintUIOptions* m_pPrintUIOptions;
protected:
@@ -104,6 +106,8 @@ public:
// OoxmlFormulaExportBase
virtual void writeFormulaOoxml( ::sax_fastparser::FSHelperPtr m_pSerializer, oox::core::OoxmlVersion version );
+ // OoxmlFormulaImportBase
+ virtual void readFormulaOoxml( ooxmlformulaimport::XmlStream& stream );
static ::com::sun::star::uno::Sequence< rtl::OUString > getSupportedServiceNames_Static();
static ::rtl::OUString getImplementationName_Static();
diff --git a/starmath/source/document.cxx b/starmath/source/document.cxx
index 7586e64d3089..36df9ae505dc 100644
--- a/starmath/source/document.cxx
+++ b/starmath/source/document.cxx
@@ -96,6 +96,7 @@
#include <view.hxx>
#include "mathtype.hxx"
#include "ooxmlexport.hxx"
+#include "ooxmlimport.hxx"
#include "mathmlimport.hxx"
#include "mathmlexport.hxx"
#include <sfx2/sfxsids.hrc>
@@ -998,6 +999,15 @@ bool SmDocShell::writeFormulaOoxml( ::sax_fastparser::FSHelperPtr m_pSerializer,
return aEquation.ConvertFromStarMath( m_pSerializer );
}
+bool SmDocShell::readFormulaOoxml( ooxmlformulaimport::XmlStream& stream )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::readFormulaOoxml" );
+
+ SmOoxmlImport aEquation( stream );
+ SetText( aEquation.ConvertToStarMath());
+ return true; // TODO just void?
+}
+
sal_Bool SmDocShell::SaveCompleted( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage )
{
RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SaveCompleted" );
diff --git a/starmath/source/ooxmlimport.cxx b/starmath/source/ooxmlimport.cxx
new file mode 100644
index 000000000000..cd7610fd215a
--- /dev/null
+++ b/starmath/source/ooxmlimport.cxx
@@ -0,0 +1,233 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2011 Lubos Lunak <l.lunak@suse.cz> (initial developer)
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+#include "ooxmlimport.hxx"
+
+#include <oox/token/tokens.hxx>
+#include <oox/token/namespaces.hxx>
+
+using namespace oox;
+using namespace ooxmlformulaimport;
+using rtl::OUString;
+
+/*
+The primary internal data structure for the formula is the text representation
+(the SmNode tree is built from it), so read data must be converted into this format.
+*/
+
+#define M_TOKEN( token ) OOX_TOKEN( officeMath, token )
+#define OPENING_TAG( token ) OPENING( token )
+#define CLOSING_TAG( token ) CLOSING( token )
+
+// *sigh*
+#define STR( str ) OUString( RTL_CONSTASCII_USTRINGPARAM( str ))
+
+// TODO create IS_OPENING(), IS_CLOSING() instead of doing 'next == OPENING( next )' ?
+
+SmOoxmlImport::SmOoxmlImport( ooxmlformulaimport::XmlStream& s )
+: stream( s )
+{
+}
+
+OUString SmOoxmlImport::ConvertToStarMath()
+{
+ return handleStream();
+}
+
+// "toplevel" of reading, there will be oMath (if there was oMathPara, that was
+// up to the parent component to handle)
+
+// NOT complete
+OUString SmOoxmlImport::handleStream()
+{
+ checkOpeningTag( M_TOKEN( oMath ));
+ OUString ret;
+ bool out = false;
+ while( !out && !stream.nextIsEnd())
+ {
+ switch( stream.peekNextToken())
+ {
+ case OPENING( M_TOKEN( f )):
+ ret += STR( " " ) + handleF();
+ break;
+ case CLOSING( M_TOKEN( oMath )):
+ out = true;
+ break;
+ default:
+ handleUnexpectedTag();
+ break;
+ }
+ }
+ checkClosingTag( M_TOKEN( oMath ));
+ return ret;
+}
+
+// NOT complete
+OUString SmOoxmlImport::handleF()
+{
+ checkOpeningTag( M_TOKEN( f ));
+ if( stream.peekNextToken() == OPENING_TAG( M_TOKEN( fPr )))
+ {
+ // TODO
+ }
+ checkOpeningTag( M_TOKEN( num ));
+ OUString num = readR();
+ checkClosingTag( M_TOKEN( num ));
+ checkOpeningTag( M_TOKEN( den ));
+ OUString den = readR();
+ checkClosingTag( M_TOKEN( den ));
+ checkClosingTag( M_TOKEN( f ));
+ return STR( "{" ) + num + STR( "} over {" ) + den + STR( "}" );
+}
+
+// NOT complete
+OUString SmOoxmlImport::readR()
+{
+ checkOpeningTag( M_TOKEN( r ));
+
+// checkOpeningTag( OOX_TOKEN( doc, rPr ));
+// checkOpeningTag( OOX_TOKEN( doc, rFonts ));
+// checkClosingTag( OOX_TOKEN( doc, rFonts ));
+// checkClosingTag( OOX_TOKEN( doc, rPr ));
+
+ // TODO can there be more t's ?
+ checkOpeningTag( M_TOKEN( t ));
+ OUString text = stream.getCharacters();
+ if( !stream.getAttributes().getBool( OOX_TOKEN( xml, space ), false ))
+ text = text.trim();
+ checkClosingTag( M_TOKEN( t ));
+ checkClosingTag( M_TOKEN( r ));
+ return text;
+}
+
+void SmOoxmlImport::checkOpeningTag( int token )
+{
+ checkTag( OPENING( token ), "opening" );
+}
+
+void SmOoxmlImport::checkClosingTag( int token )
+{
+ checkTag( CLOSING( token ), "closing" );
+}
+
+void SmOoxmlImport::checkTag( int token, const char* txt )
+{
+ if( stream.peekNextToken() == token )
+ {
+ stream.getNextToken(); // read it
+ return; // ok
+ }
+ if( recoverAndFindTag( token ))
+ {
+ stream.getNextToken(); // read it
+ return; // ok, skipped some tokens
+ }
+ fprintf( stderr, "Expected %s tag %d not found.\n", txt, token );
+}
+
+bool SmOoxmlImport::recoverAndFindTag( int token )
+{
+ int depth = 0;
+ for(;;)
+ {
+ if( depth > 0 ) // we're inside a nested element, skip those
+ {
+ int next = stream.getNextToken();
+ if( next == OPENING( next ))
+ {
+ fprintf( stderr, "Skipping opening tag %d\n", next );
+ ++depth;
+ }
+ else if( next == CLOSING( next ))
+ { // TODO debug output without the OPENING/CLOSING bits set
+ fprintf( stderr, "Skipping closing tag %d\n", next );
+ --depth;
+ }
+ else if( next == XML_TOKEN_INVALID ) // end of stream
+ {
+ fprintf( stderr, "Unexpected end of stream reached.\n" );
+ return false;
+ }
+ else
+ {
+ fprintf( stderr, "Malformed token %d\n", next );
+ abort();
+ }
+ continue;
+ }
+ int next = stream.peekNextToken();
+ if( next == CLOSING( next ))
+ return false; // that would be leaving current element, so not found
+ if( next == token )
+ return true; // ok, found
+ if( next == OPENING( next ))
+ {
+ fprintf( stderr, "Skipping opening tag %d\n", next );
+ stream.getNextToken();
+ ++depth;
+ }
+ else if( next == XML_TOKEN_INVALID )
+ {
+ fprintf( stderr, "Unexpected end of stream reached.\n" );
+ return false;
+ }
+ else
+ abort();
+ }
+}
+
+void SmOoxmlImport::skipElement( int token )
+{
+ int closing = ( token & ~TAG_OPENING ) | TAG_CLOSING; // make it a closing tag
+ assert( stream.peekNextToken() == OPENING( token ));
+ // just find the matching closing tag
+ if( recoverAndFindTag( closing ))
+ {
+ stream.getNextToken(); // read it
+ return;
+ }
+ fprintf( stderr, "Expected end of element %d not found.\n", token );
+}
+
+void SmOoxmlImport::handleUnexpectedTag()
+{
+ int next = stream.peekNextToken();
+ if( next == XML_TOKEN_INVALID )
+ return; // end of stream
+ if( next == CLOSING( next ))
+ {
+ stream.getNextToken(); // just skip it
+ return;
+ }
+ skipElement( stream.peekNextToken());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/ooxmlimport.hxx b/starmath/source/ooxmlimport.hxx
new file mode 100644
index 000000000000..80be1d836b5c
--- /dev/null
+++ b/starmath/source/ooxmlimport.hxx
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2011 Lubos Lunak <l.lunak@suse.cz> (initial developer)
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#ifndef SM_OOXMLIMPORT_HXX
+#define SM_OOXMLIMPORT_HXX
+
+#include <oox/export/starmathimport.hxx>
+
+#include "node.hxx"
+
+/**
+ Class implementing reading of formulas from OOXML. The toplevel element is expected
+ to be oMath (handle oMathPara outside of this code).
+ */
+class SmOoxmlImport
+{
+public:
+ SmOoxmlImport( ooxmlformulaimport::XmlStream& stream );
+ rtl::OUString ConvertToStarMath();
+private:
+ rtl::OUString handleStream();
+ rtl::OUString handleF();
+ rtl::OUString readR();
+ /**
+ Checks that the next token is the given opening tag, if not, writes out a warning
+ and tries to recover (skips tags until found or until the current element would end).
+ */
+ void checkOpeningTag( int token );
+ /**
+ Checks that the next token is the given opening tag, if not, writes out a warning
+ and tries to recover (skips tags until found or until the current element would end).
+ */
+ void checkClosingTag( int token );
+ // helper for the two above
+ void checkTag( int token, const char* txt );
+ /**
+ Tries to find the given token, until either found (returns true) or end of current element.
+ */
+ bool recoverAndFindTag( int token );
+ /**
+ Skips the given element (i.e. reads up to and including the matching closing tag).
+ */
+ void skipElement( int token );
+ /**
+ Handle the current (unexpected) tag.
+ */
+ void handleUnexpectedTag();
+ ooxmlformulaimport::XmlStream& stream;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/unomodel.cxx b/starmath/source/unomodel.cxx
index 2cb17987b2ac..8b7ea8169235 100644
--- a/starmath/source/unomodel.cxx
+++ b/starmath/source/unomodel.cxx
@@ -1137,4 +1137,9 @@ void SmModel::writeFormulaOoxml( ::sax_fastparser::FSHelperPtr m_pSerializer, oo
static_cast< SmDocShell* >( GetObjectShell())->writeFormulaOoxml( m_pSerializer, version );
}
+void SmModel::readFormulaOoxml( ooxmlformulaimport::XmlStream& stream )
+{
+ static_cast< SmDocShell* >( GetObjectShell())->readFormulaOoxml( stream );
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */