[Libreoffice-commits] .: 5 commits - starmath/Library_sm.mk starmath/source sw/qa

Miklos Vajna vmiklos at kemper.freedesktop.org
Fri Jul 27 02:54:59 PDT 2012


 starmath/Library_sm.mk                               |    1 
 starmath/source/document.cxx                         |    2 
 starmath/source/ooxmlexport.cxx                      |  191 +---------------
 starmath/source/ooxmlexport.hxx                      |   36 +--
 starmath/source/rtfexport.cxx                        |  139 -----------
 starmath/source/rtfexport.hxx                        |   33 +-
 starmath/source/wordexportbase.cxx                   |  212 +++++++++++++++++
 starmath/source/wordexportbase.hxx                   |   67 +++++
 sw/qa/extras/rtfexport/data/math-limupp.rtf          |   77 ++++++
 sw/qa/extras/rtfexport/data/math-nary.rtf            |   87 +++++++
 sw/qa/extras/rtfexport/data/math-placeholders.rtf    |   26 ++
 sw/qa/extras/rtfexport/data/math-rad.rtf             |   48 ++++
 sw/qa/extras/rtfexport/data/math-sepchr.rtf          |   39 +++
 sw/qa/extras/rtfexport/data/math-strikeh.rtf         |   26 ++
 sw/qa/extras/rtfexport/data/math-subscripts.rtf      |  224 +++++++++++++++++++
 sw/qa/extras/rtfexport/data/math-vertical-stacks.rtf |  131 +++++++++++
 sw/qa/extras/rtfexport/rtfexport.cxx                 |   79 ++++++
 17 files changed, 1066 insertions(+), 352 deletions(-)

New commits:
commit 2f91b691e523385ff6350ea3524c7f795820612d
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Fri Jul 27 11:09:57 2012 +0200

    factor out common code of SmOoxmlExport and SmRtfExport to SmWordExportBase
    
    Change-Id: I63ce6c57faf8568776d24ba1e8b13bd11b6c5532

diff --git a/starmath/Library_sm.mk b/starmath/Library_sm.mk
index 779895d..e3727c8 100644
--- a/starmath/Library_sm.mk
+++ b/starmath/Library_sm.mk
@@ -90,6 +90,7 @@ $(eval $(call gb_Library_add_exception_objects,sm,\
         starmath/source/utility \
         starmath/source/view \
         starmath/source/visitors \
+        starmath/source/wordexportbase \
 ))
 
 
diff --git a/starmath/source/ooxmlexport.cxx b/starmath/source/ooxmlexport.cxx
index 1eaf6c8..9cf7188 100644
--- a/starmath/source/ooxmlexport.cxx
+++ b/starmath/source/ooxmlexport.cxx
@@ -36,19 +36,19 @@ using namespace oox;
 using namespace oox::core;
 
 SmOoxmlExport::SmOoxmlExport( const SmNode* pIn, OoxmlVersion v )
-: pTree( pIn )
+: SmWordExportBase( pIn )
 , version( v )
 {
 }
 
 bool SmOoxmlExport::ConvertFromStarMath( ::sax_fastparser::FSHelperPtr serializer )
 {
-    if( pTree == NULL )
+    if( m_pTree == NULL )
         return false;
     m_pSerializer = serializer;
     m_pSerializer->startElementNS( XML_m, XML_oMath,
         FSNS( XML_xmlns, XML_m ), "http://schemas.openxmlformats.org/officeDocument/2006/math", FSEND );
-    HandleNode( pTree, 0 );
+    HandleNode( m_pTree, 0 );
     m_pSerializer->endElementNS( XML_m, XML_oMath );
     return true;
 }
@@ -56,124 +56,6 @@ bool SmOoxmlExport::ConvertFromStarMath( ::sax_fastparser::FSHelperPtr serialize
 // NOTE: This is still work in progress and unfinished, but it already covers a good
 // part of the ooxml math stuff.
 
-void SmOoxmlExport::HandleNode( const SmNode* pNode, int nLevel )
-{
-    SAL_INFO( "starmath.ooxml", "Node: " << nLevel << " " << int( pNode->GetType()) << " " << pNode->GetNumSubNodes());
-    switch(pNode->GetType())
-    {
-        case NATTRIBUT:
-            HandleAttribute( static_cast< const SmAttributNode* >( pNode ), nLevel );
-            break;
-        case NTEXT:
-            HandleText(pNode,nLevel);
-            break;
-        case NVERTICAL_BRACE:
-            HandleVerticalBrace( static_cast< const SmVerticalBraceNode* >( pNode ), nLevel );
-            break;
-        case NBRACE:
-            HandleBrace( static_cast< const SmBraceNode* >( pNode ), nLevel );
-            break;
-        case NOPER:
-            HandleOperator( static_cast< const SmOperNode* >( pNode ), nLevel );
-            break;
-        case NUNHOR:
-            HandleUnaryOperation( static_cast< const SmUnHorNode* >( pNode ), nLevel );
-            break;
-        case NBINHOR:
-            HandleBinaryOperation( static_cast< const SmBinHorNode* >( pNode ), nLevel );
-            break;
-        case NBINVER:
-            HandleFractions(pNode,nLevel);
-            break;
-        case NROOT:
-            HandleRoot( static_cast< const SmRootNode* >( pNode ), nLevel );
-            break;
-        case NSPECIAL:
-        {
-            const SmTextNode* pText= static_cast< const SmTextNode* >( pNode );
-            //if the token str and the result text are the same then this
-            //is to be seen as text, else assume its a mathchar
-            if (pText->GetText() == pText->GetToken().aText)
-                HandleText(pText,nLevel);
-            else
-                HandleMath(pText,nLevel);
-            break;
-        }
-        case NMATH:
-            HandleMath(pNode,nLevel);
-            break;
-        case NSUBSUP:
-            HandleSubSupScript( static_cast< const SmSubSupNode* >( pNode ), nLevel );
-            break;
-        case NEXPRESSION:
-            HandleAllSubNodes( pNode, nLevel );
-            break;
-        case NTABLE:
-            //Root Node, PILE equivalent, i.e. vertical stack
-            HandleTable(pNode,nLevel);
-            break;
-        case NMATRIX:
-            HandleMatrix( static_cast< const SmMatrixNode* >( pNode ), nLevel );
-            break;
-        case NLINE:
-            {
-// TODO
-            HandleAllSubNodes( pNode, nLevel );
-            }
-            break;
-#if 0
-        case NALIGN:
-            HandleMAlign(pNode,nLevel);
-            break;
-#endif
-        case NPLACE:
-            // explicitly do nothing, MSOffice treats that as a placeholder if item is missing
-            break;
-        case NBLANK:
-            m_pSerializer->startElementNS( XML_m, XML_r, FSEND );
-            m_pSerializer->startElementNS( XML_m, XML_t, FSNS( XML_xml, XML_space ), "preserve", FSEND );
-            m_pSerializer->write( " " );
-            m_pSerializer->endElementNS( XML_m, XML_t );
-            m_pSerializer->endElementNS( XML_m, XML_r );
-            break;
-        default:
-            HandleAllSubNodes( pNode, nLevel );
-            break;
-    }
-}
-
-//Root Node, PILE equivalent, i.e. vertical stack
-void SmOoxmlExport::HandleTable( const SmNode* pNode, int nLevel )
-{
-    //The root of the starmath is a table, if
-    //we convert this them each iteration of
-    //conversion from starmath to OOXML will
-    //add an extra unnecessary level to the
-    //OOXML output stack which would grow
-    //without bound in a multi step conversion
-    if( nLevel || pNode->GetNumSubNodes() > 1 )
-        HandleVerticalStack( pNode, nLevel );
-    else
-        HandleAllSubNodes( pNode, nLevel );
-}
-
-void SmOoxmlExport::HandleAllSubNodes( const SmNode* pNode, int nLevel )
-{
-    int size = pNode->GetNumSubNodes();
-    for( int i = 0;
-         i < size;
-         ++i )
-    {
-// TODO remove when all types of nodes are handled properly
-        if( pNode->GetSubNode( i ) == NULL )
-        {
-            OSL_FAIL( "Subnode is NULL, parent node not handled properly" );
-            continue;
-        }
-        HandleNode( pNode->GetSubNode( i ), nLevel + 1 );
-    }
-}
-
 void SmOoxmlExport::HandleVerticalStack( const SmNode* pNode, int nLevel )
 {
     m_pSerializer->startElementNS( XML_m, XML_eqArr, FSEND );
@@ -278,34 +160,6 @@ void SmOoxmlExport::HandleFractions( const SmNode* pNode, int nLevel, const char
     m_pSerializer->endElementNS( XML_m, XML_f );
 }
 
-void SmOoxmlExport::HandleUnaryOperation( const SmUnHorNode* pNode, int nLevel )
-{
-    // update HandleMath() when adding new items
-    SAL_INFO( "starmath.ooxml", "Unary: " << int( pNode->GetToken().eType ));
-
-// Avoid MSVC warning C4065: switch statement contains 'default' but no 'case' labels
-//    switch( pNode->GetToken().eType )
-//    {
-//        default:
-            HandleAllSubNodes( pNode, nLevel );
-//            break;
-//    }
-}
-
-void SmOoxmlExport::HandleBinaryOperation( const SmBinHorNode* pNode, int nLevel )
-{
-    SAL_INFO( "starmath.ooxml", "Binary: " << int( pNode->Symbol()->GetToken().eType ));
-    // update HandleMath() when adding new items
-    switch( pNode->Symbol()->GetToken().eType )
-    {
-        case TDIVIDEBY:
-            return HandleFractions( pNode, nLevel, "lin" );
-        default:
-            HandleAllSubNodes( pNode, nLevel );
-            break;
-    }
-}
-
 void SmOoxmlExport::HandleAttribute( const SmAttributNode* pNode, int nLevel )
 {
     switch( pNode->Attribute()->GetToken().eType )
@@ -370,21 +224,6 @@ void SmOoxmlExport::HandleAttribute( const SmAttributNode* pNode, int nLevel )
     }
 }
 
-void SmOoxmlExport::HandleMath( const SmNode* pNode, int nLevel )
-{
-    SAL_INFO( "starmath.ooxml", "Math: " << int( pNode->GetToken().eType ));
-    switch( pNode->GetToken().eType )
-    {
-        case TDIVIDEBY:
-        case TACUTE:
-        // these are handled elsewhere, e.g. when handling BINHOR
-            OSL_ASSERT( false );
-        default:
-            HandleText( pNode, nLevel );
-            break;
-    }
-}
-
 void SmOoxmlExport::HandleRoot( const SmRootNode* pNode, int nLevel )
 {
     m_pSerializer->startElementNS( XML_m, XML_rad, FSEND );
@@ -494,18 +333,6 @@ void SmOoxmlExport::HandleOperator( const SmOperNode* pNode, int nLevel )
     }
 }
 
-void SmOoxmlExport::HandleSubSupScript( const SmSubSupNode* pNode, int nLevel )
-{
-    // set flags to a bitfield of which sub/sup items exists
-    int flags = ( pNode->GetSubSup( CSUB ) != NULL ? ( 1 << CSUB ) : 0 )
-            | ( pNode->GetSubSup( CSUP ) != NULL ? ( 1 << CSUP ) : 0 )
-            | ( pNode->GetSubSup( RSUB ) != NULL ? ( 1 << RSUB ) : 0 )
-            | ( pNode->GetSubSup( RSUP ) != NULL ? ( 1 << RSUP ) : 0 )
-            | ( pNode->GetSubSup( LSUB ) != NULL ? ( 1 << LSUB ) : 0 )
-            | ( pNode->GetSubSup( LSUP ) != NULL ? ( 1 << LSUP ) : 0 );
-    HandleSubSupScriptInternal( pNode, nLevel, flags );
-}
-
 void SmOoxmlExport::HandleSubSupScriptInternal( const SmSubSupNode* pNode, int nLevel, int flags )
 {
 // docx supports only a certain combination of sub/super scripts, but LO can have any,
@@ -714,4 +541,13 @@ void SmOoxmlExport::HandleVerticalBrace( const SmVerticalBraceNode* pNode, int n
     }
 }
 
+void SmOoxmlExport::HandleBlank()
+{
+    m_pSerializer->startElementNS( XML_m, XML_r, FSEND );
+    m_pSerializer->startElementNS( XML_m, XML_t, FSNS( XML_xml, XML_space ), "preserve", FSEND );
+    m_pSerializer->write( " " );
+    m_pSerializer->endElementNS( XML_m, XML_t );
+    m_pSerializer->endElementNS( XML_m, XML_r );
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/ooxmlexport.hxx b/starmath/source/ooxmlexport.hxx
index 6de792e..f46a26b 100644
--- a/starmath/source/ooxmlexport.hxx
+++ b/starmath/source/ooxmlexport.hxx
@@ -29,7 +29,7 @@
 #ifndef SM_OOXMLEXPORT_HXX
 #define SM_OOXMLEXPORT_HXX
 
-#include "node.hxx"
+#include "wordexportbase.hxx"
 
 #include <sax/fshelper.hxx>
 #include <oox/core/filterbase.hxx>
@@ -37,30 +37,23 @@
 /**
  Class implementing writing of formulas to OOXML.
  */
-class SmOoxmlExport
+class SmOoxmlExport : public SmWordExportBase
 {
 public:
     SmOoxmlExport( const SmNode* pIn, oox::core::OoxmlVersion version );
     bool ConvertFromStarMath( ::sax_fastparser::FSHelperPtr m_pSerializer );
 private:
-    void HandleNode( const SmNode* pNode, int nLevel );
-    void HandleAllSubNodes( const SmNode* pNode, int nLevel );
-    void HandleTable( const SmNode* pNode, int nLevel );
-    void HandleVerticalStack( const SmNode* pNode, int nLevel );
-    void HandleText( const SmNode* pNode, int nLevel );
-    void HandleMath( const SmNode* pNode, int nLevel );
-    void HandleFractions( const SmNode* pNode, int nLevel, const char* type = NULL );
-    void HandleUnaryOperation( const SmUnHorNode* pNode, int nLevel );
-    void HandleBinaryOperation( const SmBinHorNode* pNode, int nLevel );
-    void HandleRoot( const SmRootNode* pNode, int nLevel );
-    void HandleAttribute( const SmAttributNode* pNode, int nLevel );
-    void HandleOperator( const SmOperNode* pNode, int nLevel );
-    void HandleSubSupScript( const SmSubSupNode* pNode, int nLevel );
-    void HandleSubSupScriptInternal( const SmSubSupNode* pNode, int nLevel, int flags );
-    void HandleMatrix( const SmMatrixNode* pNode, int nLevel );
-    void HandleBrace( const SmBraceNode* pNode, int nLevel );
-    void HandleVerticalBrace( const SmVerticalBraceNode* pNode, int nLevel );
-    const SmNode* const pTree;
+    virtual void HandleVerticalStack( const SmNode* pNode, int nLevel );
+    virtual void HandleText( const SmNode* pNode, int nLevel );
+    virtual void HandleFractions( const SmNode* pNode, int nLevel, const char* type = NULL );
+    virtual void HandleRoot( const SmRootNode* pNode, int nLevel );
+    virtual void HandleAttribute( const SmAttributNode* pNode, int nLevel );
+    virtual void HandleOperator( const SmOperNode* pNode, int nLevel );
+    virtual void HandleSubSupScriptInternal( const SmSubSupNode* pNode, int nLevel, int flags );
+    virtual void HandleMatrix( const SmMatrixNode* pNode, int nLevel );
+    virtual void HandleBrace( const SmBraceNode* pNode, int nLevel );
+    virtual void HandleVerticalBrace( const SmVerticalBraceNode* pNode, int nLevel );
+    virtual void HandleBlank();
     ::sax_fastparser::FSHelperPtr m_pSerializer;
     oox::core::OoxmlVersion version;
 };
diff --git a/starmath/source/rtfexport.cxx b/starmath/source/rtfexport.cxx
index b8cebd7..5868e51 100644
--- a/starmath/source/rtfexport.cxx
+++ b/starmath/source/rtfexport.cxx
@@ -34,7 +34,7 @@
 #include <filter/msfilter/rtfutil.hxx>
 
 SmRtfExport::SmRtfExport(const SmNode* pIn)
-    : m_pTree(pIn)
+    : SmWordExportBase(pIn)
       , m_pBuffer(0)
 {
 }
@@ -53,90 +53,6 @@ bool SmRtfExport::ConvertFromStarMath(OStringBuffer& rBuffer)
 // NOTE: This is still work in progress and unfinished, but it already covers a good
 // part of the rtf math stuff.
 
-void SmRtfExport::HandleNode(const SmNode* pNode, int nLevel)
-{
-    SAL_INFO("starmath.rtf", "Node: " << nLevel << " " << int(pNode->GetType()) << " " << pNode->GetNumSubNodes());
-
-    switch(pNode->GetType())
-    {
-        case NATTRIBUT:
-            HandleAttribute( static_cast< const SmAttributNode* >( pNode ), nLevel );
-            break;
-        case NTEXT:
-            HandleText(pNode,nLevel);
-            break;
-        case NVERTICAL_BRACE:
-            HandleVerticalBrace(static_cast<const SmVerticalBraceNode*>(pNode), nLevel);
-            break;
-        case NBRACE:
-            HandleBrace( static_cast< const SmBraceNode* >( pNode ), nLevel );
-            break;
-        case NOPER:
-            HandleOperator(static_cast<const SmOperNode*>(pNode), nLevel);
-            break;
-        case NUNHOR:
-            HandleUnaryOperation(static_cast<const SmUnHorNode*>(pNode), nLevel);
-            break;
-        case NBINHOR:
-            HandleBinaryOperation(static_cast<const SmBinHorNode*>(pNode), nLevel);
-            break;
-        case NBINVER:
-            HandleFractions(pNode, nLevel);
-            break;
-        case NROOT:
-            HandleRoot(static_cast<const SmRootNode*>(pNode), nLevel);
-            break;
-        case NMATH:
-            HandleMath(pNode, nLevel);
-            break;
-        case NSUBSUP:
-            HandleSubSupScript(static_cast<const SmSubSupNode*>(pNode), nLevel);
-            break;
-        case NEXPRESSION:
-            HandleAllSubNodes(pNode, nLevel);
-            break;
-        case NTABLE:
-            //Root Node, PILE equivalent, i.e. vertical stack
-            HandleTable(pNode,nLevel);
-            break;
-        case NMATRIX:
-            HandleMatrix(static_cast<const SmMatrixNode*>(pNode), nLevel);
-            break;
-        case NLINE:
-            HandleAllSubNodes(pNode, nLevel);
-            break;
-        case NPLACE:
-            // explicitly do nothing, MSOffice treats that as a placeholder if item is missing
-            break;
-        default:
-            SAL_INFO("starmath.rtf", "TODO: " << OSL_THIS_FUNC << " unhandled node type");
-            break;
-    }
-}
-
-//Root Node, PILE equivalent, i.e. vertical stack
-void SmRtfExport::HandleTable(const SmNode* pNode, int nLevel)
-{
-    if (nLevel || pNode->GetNumSubNodes() > 1)
-        HandleVerticalStack(pNode, nLevel);
-    else
-        HandleAllSubNodes(pNode, nLevel);
-}
-
-void SmRtfExport::HandleAllSubNodes(const SmNode* pNode, int nLevel)
-{
-    int size = pNode->GetNumSubNodes();
-    for (int i = 0; i < size; ++i)
-    {
-        if (!pNode->GetSubNode(i))
-        {
-            OSL_FAIL("Subnode is NULL, parent node not handled properly");
-            continue;
-        }
-        HandleNode(pNode->GetSubNode(i), nLevel + 1);
-    }
-}
-
 void SmRtfExport::HandleVerticalStack(const SmNode* pNode, int nLevel)
 {
     m_pBuffer->append("{\\meqArr ");
@@ -187,25 +103,6 @@ void SmRtfExport::HandleFractions(const SmNode* pNode, int nLevel, const char* t
     m_pBuffer->append("}"); // mf
 }
 
-void SmRtfExport::HandleUnaryOperation(const SmUnHorNode* pNode, int nLevel)
-{
-    HandleAllSubNodes(pNode, nLevel);
-}
-
-void SmRtfExport::HandleBinaryOperation(const SmBinHorNode* pNode, int nLevel)
-{
-    SAL_INFO("starmath.rtf", "Binary: " << int(pNode->Symbol()->GetToken().eType));
-    // update HandleMath() when adding new items
-    switch (pNode->Symbol()->GetToken().eType)
-    {
-        case TDIVIDEBY:
-            return HandleFractions(pNode, nLevel, "lin");
-        default:
-            HandleAllSubNodes(pNode, nLevel);
-            break;
-    }
-}
-
 void SmRtfExport::HandleAttribute(const SmAttributNode* pNode, int nLevel)
 {
     switch (pNode->Attribute()->GetToken().eType)
@@ -272,21 +169,6 @@ void SmRtfExport::HandleAttribute(const SmAttributNode* pNode, int nLevel)
     }
 }
 
-void SmRtfExport::HandleMath(const SmNode* pNode, int nLevel)
-{
-    SAL_INFO("starmath.rtf", "Math: " << int(pNode->GetToken().eType));
-    switch (pNode->GetToken().eType)
-    {
-        case TDIVIDEBY:
-        case TACUTE:
-            // these are handled elsewhere, e.g. when handling BINHOR
-            OSL_ASSERT(false);
-        default:
-            HandleText(pNode, nLevel);
-            break;
-    }
-}
-
 void SmRtfExport::HandleRoot(const SmRootNode* pNode, int nLevel)
 {
     m_pBuffer->append("{\\mrad ");
@@ -397,18 +279,6 @@ void SmRtfExport::HandleOperator(const SmOperNode* pNode, int nLevel)
     }
 }
 
-void SmRtfExport::HandleSubSupScript(const SmSubSupNode* pNode, int nLevel)
-{
-    // set flags to a bitfield of which sub/sup items exists
-    int flags = (pNode->GetSubSup(CSUB) ? (1 << CSUB) : 0)
-            | (pNode->GetSubSup(CSUP) ? (1 << CSUP) : 0)
-            | (pNode->GetSubSup(RSUB) ? (1 << RSUB) : 0)
-            | (pNode->GetSubSup(RSUP) ? (1 << RSUP) : 0)
-            | (pNode->GetSubSup(LSUB) ? (1 << LSUB) : 0)
-            | (pNode->GetSubSup(LSUP) ? (1 << LSUP) : 0);
-    HandleSubSupScriptInternal(pNode, nLevel, flags);
-}
-
 void SmRtfExport::HandleSubSupScriptInternal(const SmSubSupNode* pNode, int nLevel, int flags)
 {
 // rtf supports only a certain combination of sub/super scripts, but LO can have any,
@@ -618,4 +488,11 @@ void SmRtfExport::HandleVerticalBrace(const SmVerticalBraceNode* pNode, int nLev
     }
 }
 
+void SmRtfExport::HandleBlank()
+{
+    m_pBuffer->append("{\\mr ");
+    m_pBuffer->append(" ");
+    m_pBuffer->append("}"); // mr
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/rtfexport.hxx b/starmath/source/rtfexport.hxx
index 9e1f6c3..bf12b64 100644
--- a/starmath/source/rtfexport.hxx
+++ b/starmath/source/rtfexport.hxx
@@ -29,38 +29,31 @@
 #ifndef SM_RTFEXPORT_HXX
 #define SM_RTFEXPORT_HXX
 
-#include "node.hxx"
+#include "wordexportbase.hxx"
 
 #include <rtl/strbuf.hxx>
 
 /**
  Class implementing writing of formulas to RTF.
  */
-class SmRtfExport
+class SmRtfExport : public SmWordExportBase
 {
 public:
     SmRtfExport(const SmNode* pIn);
     bool ConvertFromStarMath(OStringBuffer& rBuffer);
 private:
-    void HandleNode(const SmNode* pNode, int nLevel);
-    void HandleAllSubNodes(const SmNode* pNode, int nLevel);
-    void HandleTable(const SmNode* pNode, int nLevel);
-    void HandleVerticalStack(const SmNode* pNode, int nLevel);
-    void HandleText(const SmNode* pNode, int nLevel);
-    void HandleMath(const SmNode* pNode, int nLevel);
-    void HandleFractions(const SmNode* pNode, int nLevel, const char* type = NULL);
-    void HandleUnaryOperation(const SmUnHorNode* pNode, int nLevel);
-    void HandleBinaryOperation(const SmBinHorNode* pNode, int nLevel);
-    void HandleRoot(const SmRootNode* pNode, int nLevel);
-    void HandleAttribute(const SmAttributNode* pNode, int nLevel);
-    void HandleOperator(const SmOperNode* pNode, int nLevel);
-    void HandleSubSupScript(const SmSubSupNode* pNode, int nLevel);
-    void HandleSubSupScriptInternal(const SmSubSupNode* pNode, int nLevel, int flags);
-    void HandleMatrix(const SmMatrixNode* pNode, int nLevel);
-    void HandleBrace(const SmBraceNode* pNode, int nLevel);
-    void HandleVerticalBrace(const SmVerticalBraceNode* pNode, int nLevel);
+    virtual void HandleVerticalStack(const SmNode* pNode, int nLevel);
+    virtual void HandleText(const SmNode* pNode, int nLevel);
+    virtual void HandleFractions(const SmNode* pNode, int nLevel, const char* type = NULL);
+    virtual void HandleRoot(const SmRootNode* pNode, int nLevel);
+    virtual void HandleAttribute(const SmAttributNode* pNode, int nLevel);
+    virtual void HandleOperator(const SmOperNode* pNode, int nLevel);
+    virtual void HandleSubSupScriptInternal(const SmSubSupNode* pNode, int nLevel, int flags);
+    virtual void HandleMatrix(const SmMatrixNode* pNode, int nLevel);
+    virtual void HandleBrace(const SmBraceNode* pNode, int nLevel);
+    virtual void HandleVerticalBrace(const SmVerticalBraceNode* pNode, int nLevel);
+    virtual void HandleBlank();
 
-    const SmNode* const m_pTree;
     OStringBuffer* m_pBuffer;
 };
 
diff --git a/starmath/source/wordexportbase.cxx b/starmath/source/wordexportbase.cxx
new file mode 100644
index 0000000..9f5e54b
--- /dev/null
+++ b/starmath/source/wordexportbase.cxx
@@ -0,0 +1,212 @@
+/* -*- 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 at 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.
+ */
+
+
+#include "wordexportbase.hxx"
+
+#include <rtl/oustringostreaminserter.hxx>
+
+SmWordExportBase::SmWordExportBase( const SmNode* pIn )
+: m_pTree( pIn )
+{
+}
+
+SmWordExportBase::~SmWordExportBase()
+{
+}
+
+void SmWordExportBase::HandleNode( const SmNode* pNode, int nLevel )
+{
+    SAL_INFO( "starmath.wordbase", "Node: " << nLevel << " " << int( pNode->GetType()) << " " << pNode->GetNumSubNodes());
+    switch(pNode->GetType())
+    {
+        case NATTRIBUT:
+            HandleAttribute( static_cast< const SmAttributNode* >( pNode ), nLevel );
+            break;
+        case NTEXT:
+            HandleText(pNode,nLevel);
+            break;
+        case NVERTICAL_BRACE:
+            HandleVerticalBrace( static_cast< const SmVerticalBraceNode* >( pNode ), nLevel );
+            break;
+        case NBRACE:
+            HandleBrace( static_cast< const SmBraceNode* >( pNode ), nLevel );
+            break;
+        case NOPER:
+            HandleOperator( static_cast< const SmOperNode* >( pNode ), nLevel );
+            break;
+        case NUNHOR:
+            HandleUnaryOperation( static_cast< const SmUnHorNode* >( pNode ), nLevel );
+            break;
+        case NBINHOR:
+            HandleBinaryOperation( static_cast< const SmBinHorNode* >( pNode ), nLevel );
+            break;
+        case NBINVER:
+            HandleFractions(pNode,nLevel);
+            break;
+        case NROOT:
+            HandleRoot( static_cast< const SmRootNode* >( pNode ), nLevel );
+            break;
+        case NSPECIAL:
+        {
+            const SmTextNode* pText= static_cast< const SmTextNode* >( pNode );
+            //if the token str and the result text are the same then this
+            //is to be seen as text, else assume its a mathchar
+            if (pText->GetText() == pText->GetToken().aText)
+                HandleText(pText,nLevel);
+            else
+                HandleMath(pText,nLevel);
+            break;
+        }
+        case NMATH:
+            HandleMath(pNode,nLevel);
+            break;
+        case NSUBSUP:
+            HandleSubSupScript( static_cast< const SmSubSupNode* >( pNode ), nLevel );
+            break;
+        case NEXPRESSION:
+            HandleAllSubNodes( pNode, nLevel );
+            break;
+        case NTABLE:
+            //Root Node, PILE equivalent, i.e. vertical stack
+            HandleTable(pNode,nLevel);
+            break;
+        case NMATRIX:
+            HandleMatrix( static_cast< const SmMatrixNode* >( pNode ), nLevel );
+            break;
+        case NLINE:
+            {
+// TODO
+            HandleAllSubNodes( pNode, nLevel );
+            }
+            break;
+#if 0
+        case NALIGN:
+            HandleMAlign(pNode,nLevel);
+            break;
+#endif
+        case NPLACE:
+            // explicitly do nothing, MSOffice treats that as a placeholder if item is missing
+            break;
+        case NBLANK:
+            HandleBlank();
+            break;
+        default:
+            HandleAllSubNodes( pNode, nLevel );
+            break;
+    }
+}
+
+//Root Node, PILE equivalent, i.e. vertical stack
+void SmWordExportBase::HandleTable( const SmNode* pNode, int nLevel )
+{
+    //The root of the starmath is a table, if
+    //we convert this them each iteration of
+    //conversion from starmath to Word will
+    //add an extra unnecessary level to the
+    //Word output stack which would grow
+    //without bound in a multi step conversion
+    if( nLevel || pNode->GetNumSubNodes() > 1 )
+        HandleVerticalStack( pNode, nLevel );
+    else
+        HandleAllSubNodes( pNode, nLevel );
+}
+
+void SmWordExportBase::HandleAllSubNodes( const SmNode* pNode, int nLevel )
+{
+    int size = pNode->GetNumSubNodes();
+    for( int i = 0;
+         i < size;
+         ++i )
+    {
+// TODO remove when all types of nodes are handled properly
+        if( pNode->GetSubNode( i ) == NULL )
+        {
+            OSL_FAIL( "Subnode is NULL, parent node not handled properly" );
+            continue;
+        }
+        HandleNode( pNode->GetSubNode( i ), nLevel + 1 );
+    }
+}
+
+void SmWordExportBase::HandleUnaryOperation( const SmUnHorNode* pNode, int nLevel )
+{
+    // update HandleMath() when adding new items
+    SAL_INFO( "starmath.wordbase", "Unary: " << int( pNode->GetToken().eType ));
+
+// Avoid MSVC warning C4065: switch statement contains 'default' but no 'case' labels
+//    switch( pNode->GetToken().eType )
+//    {
+//        default:
+            HandleAllSubNodes( pNode, nLevel );
+//            break;
+//    }
+}
+
+void SmWordExportBase::HandleBinaryOperation( const SmBinHorNode* pNode, int nLevel )
+{
+    SAL_INFO( "starmath.wordbase", "Binary: " << int( pNode->Symbol()->GetToken().eType ));
+    // update HandleMath() when adding new items
+    switch( pNode->Symbol()->GetToken().eType )
+    {
+        case TDIVIDEBY:
+            return HandleFractions( pNode, nLevel, "lin" );
+        default:
+            HandleAllSubNodes( pNode, nLevel );
+            break;
+    }
+}
+
+void SmWordExportBase::HandleMath( const SmNode* pNode, int nLevel )
+{
+    SAL_INFO( "starmath.wordbase", "Math: " << int( pNode->GetToken().eType ));
+    switch( pNode->GetToken().eType )
+    {
+        case TDIVIDEBY:
+        case TACUTE:
+        // these are handled elsewhere, e.g. when handling BINHOR
+            OSL_ASSERT( false );
+        default:
+            HandleText( pNode, nLevel );
+            break;
+    }
+}
+
+void SmWordExportBase::HandleSubSupScript( const SmSubSupNode* pNode, int nLevel )
+{
+    // set flags to a bitfield of which sub/sup items exists
+    int flags = ( pNode->GetSubSup( CSUB ) != NULL ? ( 1 << CSUB ) : 0 )
+            | ( pNode->GetSubSup( CSUP ) != NULL ? ( 1 << CSUP ) : 0 )
+            | ( pNode->GetSubSup( RSUB ) != NULL ? ( 1 << RSUB ) : 0 )
+            | ( pNode->GetSubSup( RSUP ) != NULL ? ( 1 << RSUP ) : 0 )
+            | ( pNode->GetSubSup( LSUB ) != NULL ? ( 1 << LSUB ) : 0 )
+            | ( pNode->GetSubSup( LSUP ) != NULL ? ( 1 << LSUP ) : 0 );
+    HandleSubSupScriptInternal( pNode, nLevel, flags );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/wordexportbase.hxx b/starmath/source/wordexportbase.hxx
new file mode 100644
index 0000000..36944b1
--- /dev/null
+++ b/starmath/source/wordexportbase.hxx
@@ -0,0 +1,67 @@
+/* -*- 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 at 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_WORDEXPORTBASE_HXX
+#define SM_WORDEXPORTBASE_HXX
+
+#include "node.hxx"
+
+/**
+ Base class implementing writing of formulas to Word.
+ */
+class SmWordExportBase
+{
+public:
+    SmWordExportBase( const SmNode* pIn );
+    virtual ~SmWordExportBase();
+protected:
+    void HandleNode( const SmNode* pNode, int nLevel );
+    void HandleAllSubNodes( const SmNode* pNode, int nLevel );
+    void HandleTable( const SmNode* pNode, int nLevel );
+    virtual void HandleVerticalStack( const SmNode* pNode, int nLevel ) = 0;
+    virtual void HandleText( const SmNode* pNode, int nLevel ) = 0;
+    void HandleMath( const SmNode* pNode, int nLevel );
+    virtual void HandleFractions( const SmNode* pNode, int nLevel, const char* type = NULL ) = 0;
+    void HandleUnaryOperation( const SmUnHorNode* pNode, int nLevel );
+    void HandleBinaryOperation( const SmBinHorNode* pNode, int nLevel );
+    virtual void HandleRoot( const SmRootNode* pNode, int nLevel ) = 0;
+    virtual void HandleAttribute( const SmAttributNode* pNode, int nLevel ) = 0;
+    virtual void HandleOperator( const SmOperNode* pNode, int nLevel ) = 0;
+    void HandleSubSupScript( const SmSubSupNode* pNode, int nLevel );
+    virtual void HandleSubSupScriptInternal( const SmSubSupNode* pNode, int nLevel, int flags ) = 0;
+    virtual void HandleMatrix( const SmMatrixNode* pNode, int nLevel ) = 0;
+    virtual void HandleBrace( const SmBraceNode* pNode, int nLevel ) = 0;
+    virtual void HandleVerticalBrace( const SmVerticalBraceNode* pNode, int nLevel ) = 0;
+    virtual void HandleBlank() = 0;
+    const SmNode* const m_pTree;
+};
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit ebacc340796a6a99d363bd3f04c72106db7d6f7a
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Fri Jul 27 11:01:50 2012 +0200

    SmOoxmlExport: remove unused ctor param
    
    Change-Id: I2c4f9239207bd8da7f29d2a386e9a432e32e5755

diff --git a/starmath/source/document.cxx b/starmath/source/document.cxx
index 65f2468..5a41f97 100644
--- a/starmath/source/document.cxx
+++ b/starmath/source/document.cxx
@@ -983,7 +983,7 @@ bool SmDocShell::writeFormulaOoxml( ::sax_fastparser::FSHelperPtr m_pSerializer,
         Parse();
     if( pTree && !IsFormulaArranged() )
         ArrangeFormula();
-    SmOoxmlExport aEquation( aText, pTree, version );
+    SmOoxmlExport aEquation( pTree, version );
     return aEquation.ConvertFromStarMath( m_pSerializer );
 }
 
diff --git a/starmath/source/ooxmlexport.cxx b/starmath/source/ooxmlexport.cxx
index d1970dc..1eaf6c8 100644
--- a/starmath/source/ooxmlexport.cxx
+++ b/starmath/source/ooxmlexport.cxx
@@ -35,9 +35,8 @@
 using namespace oox;
 using namespace oox::core;
 
-SmOoxmlExport::SmOoxmlExport( const String &rIn, const SmNode* pIn, OoxmlVersion v )
-: str( rIn )
-, pTree( pIn )
+SmOoxmlExport::SmOoxmlExport( const SmNode* pIn, OoxmlVersion v )
+: pTree( pIn )
 , version( v )
 {
 }
diff --git a/starmath/source/ooxmlexport.hxx b/starmath/source/ooxmlexport.hxx
index 34b13ed..6de792e 100644
--- a/starmath/source/ooxmlexport.hxx
+++ b/starmath/source/ooxmlexport.hxx
@@ -40,7 +40,7 @@
 class SmOoxmlExport
 {
 public:
-    SmOoxmlExport( const String &rIn,const SmNode* pIn, oox::core::OoxmlVersion version );
+    SmOoxmlExport( const SmNode* pIn, oox::core::OoxmlVersion version );
     bool ConvertFromStarMath( ::sax_fastparser::FSHelperPtr m_pSerializer );
 private:
     void HandleNode( const SmNode* pNode, int nLevel );
@@ -60,7 +60,6 @@ private:
     void HandleMatrix( const SmMatrixNode* pNode, int nLevel );
     void HandleBrace( const SmBraceNode* pNode, int nLevel );
     void HandleVerticalBrace( const SmVerticalBraceNode* pNode, int nLevel );
-    String str;
     const SmNode* const pTree;
     ::sax_fastparser::FSHelperPtr m_pSerializer;
     oox::core::OoxmlVersion version;
commit 6486899be3a63d07830c3eb2f4b8a3a6e5c81c9c
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Fri Jul 27 10:31:17 2012 +0200

    test RTF_M{RAD,SEPCHR,SSUB,F}
    
    Change-Id: I73f472fb09f97d94fbc9ef5cf38d9cf3c4beb999

diff --git a/sw/qa/extras/rtfexport/data/math-rad.rtf b/sw/qa/extras/rtfexport/data/math-rad.rtf
new file mode 100644
index 0000000..bcd2563
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/math-rad.rtf
@@ -0,0 +1,48 @@
+{\rtf1
+{\mmath
+{\*\moMathPara 
+{\*\moMath 
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid816065 }
+{\mrad
+{\mradPr
+{\mdegHide on}
+{\mctrlPr\f34 }
+}
+{\mdeg
+{\rtlch\fcs1 \af1 \ltrch\fcs0 
+\f34\insrsid816065 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid816065 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 4}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid816065 }
+}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid816065 }
+{\mrad
+{\mradPr
+{\mctrlPr
+\f34 }
+}
+{\mdeg
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid816065 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 3}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid816065 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid816065 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 x}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid816065 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 +1}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid816065 }
+}
+}
+}
+}
+}
+\par
+}
diff --git a/sw/qa/extras/rtfexport/data/math-sepchr.rtf b/sw/qa/extras/rtfexport/data/math-sepchr.rtf
new file mode 100644
index 0000000..bf49556
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/math-sepchr.rtf
@@ -0,0 +1,39 @@
+{\rtf1
+{\mmath
+{\*\moMathPara 
+{\*\moMath 
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid13126585 }
+{\md
+{\mdPr
+{\mbegChr A}
+{\msepChr B}
+{\mendChr C}
+{\mctrlPr\f34 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 
+\i\f34\insrsid13126585 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 x}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid13126585 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid13126585 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 y}
+}
+{\rtlch\fcs1 \af1 
+\ltrch\fcs0 \f34\insrsid13126585 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid13126585 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 z}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid13126585 }
+}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid13126585 }
+}
+}
+}
+\par
+}
diff --git a/sw/qa/extras/rtfexport/data/math-subscripts.rtf b/sw/qa/extras/rtfexport/data/math-subscripts.rtf
new file mode 100644
index 0000000..dfb8187
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/math-subscripts.rtf
@@ -0,0 +1,224 @@
+{\rtf1
+{\mmath
+{\*\moMathPara 
+{\*\moMath 
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+{\msSup
+{\msSupPr
+{\mctrlPr\f34 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 
+\i\f34\insrsid15485000 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 x}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+}
+{\msup
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid15485000 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 y}
+}
+{\rtlch\fcs1 \af1 
+\ltrch\fcs0 \f34\insrsid15485000 }
+}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid15485000 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 +}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+{\msSup
+{\msSupPr
+{\mctrlPr\f34 }
+}
+{\me
+{\rtlch\fcs1 \af1 
+\ltrch\fcs0 \i\f34\insrsid15485000 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 e}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+}
+{\msup
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid15485000 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 x}
+}
+{
+\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+{\msSup
+{\msSupPr
+{\mctrlPr\f34 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid15485000 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 x}
+}
+{
+\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+}
+{\msup
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid15485000 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 b}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 
+\f34\insrsid15485000 }
+{\msSub
+{\msSubPr
+{\mctrlPr\f34 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid15485000 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 x}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+}
+{\msub
+{\rtlch\fcs1 \af1 \ltrch\fcs0 
+\i\f34\insrsid15485000 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 b}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+{\msSubSup
+{\msSubSupPr
+{\mctrlPr\f34 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 
+\i\f34\insrsid15485000 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 a}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+}
+{\msub
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid15485000 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 c}
+}
+{\rtlch\fcs1 \af1 
+\ltrch\fcs0 \f34\insrsid15485000 }
+}
+{\msup
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid15485000 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 b}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+{\msPre
+{\msPrePr
+{\mctrlPr\f34 }
+}
+{\msub
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid15485000 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 2}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+}
+{\msup
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid15485000 
+\hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 1}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid15485000 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 x}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 
+\f34\insrsid15485000 }
+}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+{\msSubSup
+{\msSubSupPr
+{\mctrlPr\f34 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+{\msPre
+{\msPrePr
+{\mctrlPr\f34 }
+}
+{\msub
+{\rtlch\fcs1 \af1 \ltrch\fcs0 
+\i\f34\insrsid15485000 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 4}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+}
+{\msup
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid15485000 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 5}
+}
+{\rtlch\fcs1 \af1 
+\ltrch\fcs0 \f34\insrsid15485000 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+{\mlimLow
+{\mlimLowPr
+{\mctrlPr\f34 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+{\mlimUpp
+{\mlimUppPr
+{\mctrlPr\f34 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 
+\i\f34\insrsid15485000 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 x}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+}
+{\mlim
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid15485000 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 6}
+}
+{\rtlch\fcs1 \af1 
+\ltrch\fcs0 \f34\insrsid15485000 }
+}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+}
+{\mlim
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid15485000 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 3}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+}
+}
+{
+\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+}
+{\msub
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid15485000 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 2}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 
+\f34\insrsid15485000 }
+}
+{\msup
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid15485000 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 1}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15485000 }
+}
+}
+}
+}
+}
+\par
+}
diff --git a/sw/qa/extras/rtfexport/data/math-vertical-stacks.rtf b/sw/qa/extras/rtfexport/data/math-vertical-stacks.rtf
new file mode 100644
index 0000000..d74db9b
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/math-vertical-stacks.rtf
@@ -0,0 +1,131 @@
+{\rtf1
+{\mmath
+{\*\moMathPara 
+{\*\moMath 
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid936301 }
+{\mf
+{\mfPr
+{\mctrlPr\f34 }
+}
+{\mnum
+{\rtlch\fcs1 \af1 \ltrch\fcs0 
+\i\f34\insrsid936301 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 a}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid936301 }
+}
+{\mden
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid936301 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 b}
+}
+{\rtlch\fcs1 \af1 
+\ltrch\fcs0 \f34\insrsid936301 }
+}
+}
+}
+}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \insrsid6706768 
+\par }
+{\mmath
+{\*\moMathPara 
+{\*\moMath 
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid936301 }
+{\mf
+{\mfPr
+{\mtype lin}
+{\mctrlPr\f34 }
+}
+{\mnum
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid936301 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 a}
+}
+{\rtlch\fcs1 \af1 
+\ltrch\fcs0 \f34\insrsid936301 }
+}
+{\mden
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid936301 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 b}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid936301 }
+}
+}
+}
+}
+}
+{
+\rtlch\fcs1 \af1 \ltrch\fcs0 \insrsid6706768 
+\par }
+{\mmath
+{\*\moMathPara 
+{\*\moMath 
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid936301 }
+{\mf
+{\mfPr
+{\mtype noBar}
+{\mctrlPr\f34 }
+}
+{\mnum
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid936301 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 a}
+}
+{\rtlch\fcs1 \af1 
+\ltrch\fcs0 \f34\insrsid936301 }
+}
+{\mden
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid936301 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 b}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid936301 }
+}
+}
+}
+}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \insrsid6706768 
+\par }
+{\mmath
+{\*\moMathPara 
+{\*\moMath 
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid936301 }
+{\mf
+{\mfPr
+{\mtype noBar}
+{\mctrlPr\f34 }
+}
+{\mnum
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid936301 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 a}
+}
+{\rtlch\fcs1 \af1 
+\ltrch\fcs0 \f34\insrsid936301 }
+}
+{\mden
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid936301 }
+{\mf
+{\mfPr
+{\mtype noBar}
+{\mctrlPr\f34 }
+}
+{\mnum
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid936301 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 b}
+}
+{\rtlch\fcs1 \af1 
+\ltrch\fcs0 \f34\insrsid936301 }
+}
+{\mden
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid936301 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 c}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid936301 }
+}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid936301 }
+}
+}
+}
+}
+}
+\par
+}
diff --git a/sw/qa/extras/rtfexport/rtfexport.cxx b/sw/qa/extras/rtfexport/rtfexport.cxx
index 6d1bceb..7cf93df 100644
--- a/sw/qa/extras/rtfexport/rtfexport.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport.cxx
@@ -63,6 +63,10 @@ public:
     void testMathLimupp();
     void testMathStrikeh();
     void testMathPlaceholders();
+    void testMathRad();
+    void testMathSepchr();
+    void testMathSubscripts();
+    void testMathVerticalstacks();
 
     CPPUNIT_TEST_SUITE(Test);
 #if !defined(MACOSX) && !defined(WNT)
@@ -88,6 +92,10 @@ public:
     CPPUNIT_TEST(testMathLimupp);
     CPPUNIT_TEST(testMathStrikeh);
     CPPUNIT_TEST(testMathPlaceholders);
+    CPPUNIT_TEST(testMathRad);
+    CPPUNIT_TEST(testMathSepchr);
+    CPPUNIT_TEST(testMathSubscripts);
+    CPPUNIT_TEST(testMathVerticalstacks);
 #endif
 #endif
     CPPUNIT_TEST_SUITE_END();
@@ -358,6 +366,37 @@ void Test::testMathPlaceholders()
     CPPUNIT_ASSERT_EQUAL(OUString("sum from <?> to <?> <?>"), aActual);
 }
 
+void Test::testMathRad()
+{
+    roundtrip("math-rad.rtf");
+    OUString aActual = getFormula(getRun(getParagraph(1), 1));
+    CPPUNIT_ASSERT_EQUAL(OUString("sqrt {4} nroot {3} {x + 1}"), aActual);
+}
+
+void Test::testMathSepchr()
+{
+    roundtrip("math-sepchr.rtf");
+    OUString aActual = getFormula(getRun(getParagraph(1), 1));
+    CPPUNIT_ASSERT_EQUAL(OUString("AxByBzC"), aActual);
+}
+
+void Test::testMathSubscripts()
+{
+    roundtrip("math-subscripts.rtf");
+    OUString aActual = getFormula(getRun(getParagraph(1), 1));
+    OUString aExpected("{x} ^ {y} + {e} ^ {x} {x} ^ {b} {x} rsub {b} {a} rsub {c} rsup {b} {x} lsub {2} lsup {1} {{x csup {6} csub {3}} lsub {4} lsup {5}} rsub {2} rsup {1}");
+    CPPUNIT_ASSERT_EQUAL(aExpected, aActual);
+}
+
+void Test::testMathVerticalstacks()
+{
+    roundtrip("math-vertical-stacks.rtf");
+    CPPUNIT_ASSERT_EQUAL(OUString("{a} over {b}"), getFormula(getRun(getParagraph(1), 1)));
+    CPPUNIT_ASSERT_EQUAL(OUString("{a} / {b}"), getFormula(getRun(getParagraph(2), 1)));
+    CPPUNIT_ASSERT_EQUAL(OUString("stack { a # b }"), getFormula(getRun(getParagraph(3), 1)));
+    CPPUNIT_ASSERT_EQUAL(OUString("stack { a # stack { b # c } }"), getFormula(getRun(getParagraph(4), 1)));
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
commit c0bd973c5ef749efbb794c87a9e2920b85533ca5
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Fri Jul 27 10:16:26 2012 +0200

    test rtf import/export of math placeholders
    
    Change-Id: Ie6864f152fae90e993e4ec127079491100029fa2

diff --git a/sw/qa/extras/rtfexport/data/math-placeholders.rtf b/sw/qa/extras/rtfexport/data/math-placeholders.rtf
new file mode 100644
index 0000000..31e995a
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/math-placeholders.rtf
@@ -0,0 +1,26 @@
+{\rtf1
+{\mmath
+{\*\moMathPara 
+{\*\moMath 
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid13982551 }
+{\mnary
+{\mnaryPr
+{\mchr \u8721 ?}
+{\mctrlPr\f34 }
+}
+{\msub
+{\rtlch\fcs1 \af1 
+\ltrch\fcs0 \f34\insrsid13982551 }
+}
+{\msup
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid13982551 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid13982551 }
+}
+}
+}
+}
+}
+\par
+}
diff --git a/sw/qa/extras/rtfexport/rtfexport.cxx b/sw/qa/extras/rtfexport/rtfexport.cxx
index 443b586..6d1bceb 100644
--- a/sw/qa/extras/rtfexport/rtfexport.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport.cxx
@@ -62,6 +62,7 @@ public:
     void testMathNary();
     void testMathLimupp();
     void testMathStrikeh();
+    void testMathPlaceholders();
 
     CPPUNIT_TEST_SUITE(Test);
 #if !defined(MACOSX) && !defined(WNT)
@@ -86,6 +87,7 @@ public:
     CPPUNIT_TEST(testMathNary);
     CPPUNIT_TEST(testMathLimupp);
     CPPUNIT_TEST(testMathStrikeh);
+    CPPUNIT_TEST(testMathPlaceholders);
 #endif
 #endif
     CPPUNIT_TEST_SUITE_END();
@@ -349,6 +351,13 @@ void Test::testMathStrikeh()
     CPPUNIT_ASSERT_EQUAL(OUString("overstrike {abc}"), aActual);
 }
 
+void Test::testMathPlaceholders()
+{
+    roundtrip("math-placeholders.rtf");
+    OUString aActual = getFormula(getRun(getParagraph(1), 1));
+    CPPUNIT_ASSERT_EQUAL(OUString("sum from <?> to <?> <?>"), aActual);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
commit 8182f7d393bc60c693a1c509b3e8edcc87484968
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Fri Jul 27 10:00:30 2012 +0200

    test RTF_M{NARY,LIMUPP,STRIKEH}
    
    Change-Id: I612fbc2064dead58786fbe77597ca677f6703eb7

diff --git a/sw/qa/extras/rtfexport/data/math-limupp.rtf b/sw/qa/extras/rtfexport/data/math-limupp.rtf
new file mode 100644
index 0000000..30ebe1c
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/math-limupp.rtf
@@ -0,0 +1,77 @@
+{\rtf1
+{\mmath
+{\*\moMathPara 
+{\*\moMath 
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid7036055 }
+{\mlimUpp
+{\mlimUppPr
+{\mctrlPr\f34 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 
+\f34\insrsid7036055 }
+{\mgroupChr
+{\mgroupChrPr
+{\mchr \u9182 ?}
+{\mpos top}
+{\mvertJc bot}
+{\mctrlPr\f34 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid7036055 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 abcd}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 
+\f34\insrsid7036055 }
+}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid7036055 }
+}
+{\mlim
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid7036055 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 4}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid7036055 }
+}
+}
+}
+}
+}
+\par
+{\mmath
+{\*\moMathPara 
+{\*\moMath 
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid7036055 }
+{\mlimLow
+{\mlimLowPr
+{\mctrlPr\f34 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid7036055 }
+{\mgroupChr
+{\mgroupChrPr
+{\mctrlPr\f34 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 
+\i\f34\insrsid7036055 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 xyz}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid7036055 }
+}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid7036055 }
+}
+{\mlim
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid7036055 
+\hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 3}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid7036055 }
+}
+}
+}
+}
+}
+\par
+}
diff --git a/sw/qa/extras/rtfexport/data/math-nary.rtf b/sw/qa/extras/rtfexport/data/math-nary.rtf
new file mode 100644
index 0000000..e428e54
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/math-nary.rtf
@@ -0,0 +1,87 @@
+{\rtf1
+{\mmath
+{\*\moMathPara 
+{\*\moMath 
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid8470899 }
+{\mnary
+{\mnaryPr
+{\mchr \u8752 ?}
+{\mctrlPr\f34 }
+}
+{\msub
+{\rtlch\fcs1 \af1 
+\ltrch\fcs0 \i\f34\insrsid8470899 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 1}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid8470899 }
+}
+{\msup
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid8470899 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 2}
+}
+{
+\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid8470899 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid8470899 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 x}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid8470899 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 +1}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid8470899 }
+}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid8470899 }
+{\mnary
+{\mnaryPr
+{\mchr \u8719 ?}
+{\msupHide on}
+{\mctrlPr\f34 }
+}
+{\msub
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid8470899 
+\hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 a}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid8470899 }
+}
+{\msup
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid8470899 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid8470899 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 b}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid8470899 }
+}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid8470899 }
+{\mnary
+{\mnaryPr
+{\mchr \u8721 ?}
+{\msubHide on}
+{\mctrlPr\f34 }
+}
+{\msub
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid8470899 }
+}
+{\msup
+{
+\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid8470899 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 2}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid8470899 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid8470899 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 x}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid8470899 }
+}
+}
+}
+}
+}
+\par
+}
diff --git a/sw/qa/extras/rtfexport/data/math-strikeh.rtf b/sw/qa/extras/rtfexport/data/math-strikeh.rtf
new file mode 100644
index 0000000..b09e1fd
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/math-strikeh.rtf
@@ -0,0 +1,26 @@
+{\rtf1
+{\mmath
+{\*\moMathPara 
+{\*\moMath 
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15277751 }
+{\mborderBox
+{\mborderBoxPr
+{\mhideTop on}
+{\mhideBot on}
+{\mhideLeft on}
+{\mhideRight on}
+{\mstrikeH on}
+{\mctrlPr\f34 }
+}
+{\me
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \i\f34\insrsid15277751 \hich\af34\dbch\af42\loch\f34 
+{\mr\mscr0\msty2 abc}
+}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \f34\insrsid15277751 }
+}
+}
+}
+}
+}
+\par
+}
diff --git a/sw/qa/extras/rtfexport/rtfexport.cxx b/sw/qa/extras/rtfexport/rtfexport.cxx
index 5e119fd..443b586 100644
--- a/sw/qa/extras/rtfexport/rtfexport.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport.cxx
@@ -59,6 +59,9 @@ public:
     void testMathMatrix();
     void testMathBox();
     void testMathMso2007();
+    void testMathNary();
+    void testMathLimupp();
+    void testMathStrikeh();
 
     CPPUNIT_TEST_SUITE(Test);
 #if !defined(MACOSX) && !defined(WNT)
@@ -80,6 +83,9 @@ public:
     CPPUNIT_TEST(testMathMatrix);
     CPPUNIT_TEST(testMathBox);
     CPPUNIT_TEST(testMathMso2007);
+    CPPUNIT_TEST(testMathNary);
+    CPPUNIT_TEST(testMathLimupp);
+    CPPUNIT_TEST(testMathStrikeh);
 #endif
 #endif
     CPPUNIT_TEST_SUITE_END();
@@ -318,6 +324,31 @@ void Test::testMathMso2007()
     CPPUNIT_ASSERT_EQUAL(aExpected, aActual);
 }
 
+void Test::testMathNary()
+{
+    roundtrip("math-nary.rtf");
+    OUString aActual = getFormula(getRun(getParagraph(1), 1));
+    OUString aExpected("lllint from {1} to {2} {x + 1} prod from {a} {b} sum to {2} {x}");
+    CPPUNIT_ASSERT_EQUAL(aExpected, aActual);
+}
+
+void Test::testMathLimupp()
+{
+    roundtrip("math-limupp.rtf");
+    OUString aActual = getFormula(getRun(getParagraph(1), 1));
+    CPPUNIT_ASSERT_EQUAL(OUString("{abcd} overbrace {4}"), aActual);
+
+    aActual = getFormula(getRun(getParagraph(2), 1));
+    CPPUNIT_ASSERT_EQUAL(OUString("{xyz} underbrace {3}"), aActual);
+}
+
+void Test::testMathStrikeh()
+{
+    roundtrip("math-strikeh.rtf");
+    OUString aActual = getFormula(getRun(getParagraph(1), 1));
+    CPPUNIT_ASSERT_EQUAL(OUString("overstrike {abc}"), aActual);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();


More information about the Libreoffice-commits mailing list