[Libreoffice-commits] .: 10 commits - starmath/inc starmath/source

Lubos Lunak llunak at kemper.freedesktop.org
Tue Aug 30 07:56:50 PDT 2011


 starmath/inc/node.hxx     |   90 +++++++++++++++++++++---
 starmath/inc/parse.hxx    |   92 ++++++++++++------------
 starmath/source/ooxml.cxx |  170 +++++++++++++++++++++++++++++++++++++++++-----
 starmath/source/ooxml.hxx |    8 +-
 4 files changed, 284 insertions(+), 76 deletions(-)

New commits:
commit 3d2b643c3c9c3185bc1b7efaef466ec681a9608c
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Tue Aug 30 16:54:36 2011 +0200

    implement math vertical brace export to .docx

diff --git a/starmath/inc/node.hxx b/starmath/inc/node.hxx
index 8b11ce5..e390463 100644
--- a/starmath/inc/node.hxx
+++ b/starmath/inc/node.hxx
@@ -1064,6 +1064,13 @@ class SmVerticalBraceNode : public SmStructureNode
 public:
     inline SmVerticalBraceNode(const SmToken &rNodeToken);
 
+    SmNode* Body();
+    const SmNode* Body() const;
+    SmMathSymbolNode* Brace();
+    const SmMathSymbolNode* Brace() const;
+    SmNode* Script();
+    const SmNode* Script() const;
+
     virtual void    Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
     void Accept(SmVisitor* pVisitor);
 };
@@ -1372,6 +1379,34 @@ inline const SmMathSymbolNode* SmBraceNode::ClosingBrace() const
     return const_cast< SmBraceNode* >( this )->ClosingBrace();
 }
 
+inline SmNode* SmVerticalBraceNode::Body()
+{
+    OSL_ASSERT( GetNumSubNodes() > 0 );
+    return GetSubNode( 0 );
+}
+inline const SmNode* SmVerticalBraceNode::Body() const
+{
+    return const_cast< SmVerticalBraceNode* >( this )->Body();
+}
+inline SmMathSymbolNode* SmVerticalBraceNode::Brace()
+{
+    OSL_ASSERT( GetNumSubNodes() > 1 && GetSubNode( 1 )->GetType() == NMATH );
+    return static_cast< SmMathSymbolNode* >( GetSubNode( 1 ));
+}
+inline const SmMathSymbolNode* SmVerticalBraceNode::Brace() const
+{
+    return const_cast< SmVerticalBraceNode* >( this )->Brace();
+}
+inline SmNode* SmVerticalBraceNode::Script()
+{
+    OSL_ASSERT( GetNumSubNodes() > 2 );
+    return GetSubNode( 2 );
+}
+inline const SmNode* SmVerticalBraceNode::Script() const
+{
+    return const_cast< SmVerticalBraceNode* >( this )->Script();
+}
+
 #endif
 
 
diff --git a/starmath/source/ooxml.cxx b/starmath/source/ooxml.cxx
index 992285c..e72d558 100644
--- a/starmath/source/ooxml.cxx
+++ b/starmath/source/ooxml.cxx
@@ -104,11 +104,9 @@ void SmOoxml::HandleNode( const SmNode* pNode, int nLevel )
         case NTEXT:
             HandleText(pNode,nLevel);
             break;
-#if 0
         case NVERTICAL_BRACE:
-            HandleVerticalBrace(pNode,nLevel);
+            HandleVerticalBrace( static_cast< const SmVerticalBraceNode* >( pNode ), nLevel );
             break;
-#endif
         case NBRACE:
             HandleBrace( static_cast< const SmBraceNode* >( pNode ), nLevel );
             break;
@@ -598,4 +596,42 @@ void SmOoxml::HandleBrace( const SmBraceNode* pNode, int nLevel )
     m_pSerializer->endElementNS( XML_m, XML_d );
 }
 
+void SmOoxml::HandleVerticalBrace( const SmVerticalBraceNode* pNode, int nLevel )
+{
+    fprintf( stderr, "VERT %d\n", pNode->GetToken().eType );
+    switch( pNode->GetToken().eType )
+    {
+        case TOVERBRACE:
+        case TUNDERBRACE:
+        {
+            bool top = ( pNode->GetToken().eType == TOVERBRACE );
+            m_pSerializer->startElementNS( XML_m, top ? XML_limUpp : XML_limLow, FSEND );
+            m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
+            m_pSerializer->startElementNS( XML_m, XML_groupChr, FSEND );
+            m_pSerializer->startElementNS( XML_m, XML_groupChrPr, FSEND );
+            m_pSerializer->singleElementNS( XML_m, XML_chr,
+                FSNS( XML_m, XML_val ), mathSymbolToString( pNode->Brace()).getStr(), FSEND );
+            // TODO not sure if pos and vertJc are correct
+            m_pSerializer->singleElementNS( XML_m, XML_pos,
+                FSNS( XML_m, XML_val ), top ? "top" : "bot", FSEND );
+            m_pSerializer->singleElementNS( XML_m, XML_vertJc, FSNS( XML_m, XML_val ), top ? "bot" : "top", FSEND );
+            m_pSerializer->endElementNS( XML_m, XML_groupChrPr );
+            m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
+            HandleNode( pNode->Body(), nLevel + 1 );
+            m_pSerializer->endElementNS( XML_m, XML_e );
+            m_pSerializer->endElementNS( XML_m, XML_groupChr );
+            m_pSerializer->endElementNS( XML_m, XML_e );
+            m_pSerializer->startElementNS( XML_m, XML_lim, FSEND );
+            HandleNode( pNode->Script(), nLevel + 1 );
+            m_pSerializer->endElementNS( XML_m, XML_lim );
+            m_pSerializer->endElementNS( XML_m, top ? XML_limUpp : XML_limLow );
+            break;
+        }
+        default:
+            OSL_FAIL( "Unhandled vertical brace" );
+            HandleAllSubNodes( pNode, nLevel );
+            break;
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/ooxml.hxx b/starmath/source/ooxml.hxx
index a88d717..1bab59b 100644
--- a/starmath/source/ooxml.hxx
+++ b/starmath/source/ooxml.hxx
@@ -59,6 +59,7 @@ private:
     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 );
     String str;
     const SmNode* const pTree;
     ::sax_fastparser::FSHelperPtr m_pSerializer;
commit 5425c4a08e6428c50d22bdc54a852b8a49fbc620
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Tue Aug 30 16:43:09 2011 +0200

    I'm too lazy to count, add comments

diff --git a/starmath/inc/node.hxx b/starmath/inc/node.hxx
index 38d46d4..8b11ce5 100644
--- a/starmath/inc/node.hxx
+++ b/starmath/inc/node.hxx
@@ -77,12 +77,12 @@ enum SmScaleMode    { SCALE_NONE, SCALE_WIDTH, SCALE_HEIGHT };
 
 enum SmNodeType
 {
-    NTABLE,         NBRACE,         NBRACEBODY,     NOPER,          NALIGN,
-    NATTRIBUT,      NFONT,          NUNHOR,         NBINHOR,        NBINVER,
-    NBINDIAGONAL,   NSUBSUP,        NMATRIX,        NPLACE,         NTEXT,
-    NSPECIAL,       NGLYPH_SPECIAL, NMATH,          NBLANK,         NERROR,
-    NLINE,          NEXPRESSION,    NPOLYLINE,      NROOT,          NROOTSYMBOL,
-    NRECTANGLE,     NVERTICAL_BRACE
+/* 0*/ NTABLE,         NBRACE,         NBRACEBODY,     NOPER,          NALIGN,
+/* 5*/ NATTRIBUT,      NFONT,          NUNHOR,         NBINHOR,        NBINVER,
+/*10*/ NBINDIAGONAL,   NSUBSUP,        NMATRIX,        NPLACE,         NTEXT,
+/*15*/ NSPECIAL,       NGLYPH_SPECIAL, NMATH,          NBLANK,         NERROR,
+/*20*/ NLINE,          NEXPRESSION,    NPOLYLINE,      NROOT,          NROOTSYMBOL,
+/*25*/ NRECTANGLE,     NVERTICAL_BRACE
 };
 
 
diff --git a/starmath/inc/parse.hxx b/starmath/inc/parse.hxx
index 43c0992..3ad04d1 100644
--- a/starmath/inc/parse.hxx
+++ b/starmath/inc/parse.hxx
@@ -69,52 +69,52 @@ class SmDocShell;
 
 enum SmTokenType
 {
-    TEND,           TLGROUP,        TRGROUP,        TLPARENT,       TRPARENT,
-    TLBRACKET,      TRBRACKET,      TPLUS,          TMINUS,         TMULTIPLY,
-    TDIVIDEBY,      TASSIGN,        TPOUND,         TSPECIAL,       TSLASH,
-    TBACKSLASH,     TBLANK,         TSBLANK,        TRSUB,          TRSUP,
-    TCSUB,          TCSUP,          TLSUB,          TLSUP,          TGT,
-    TLT,            TAND,           TOR,            TINTERSECT,     TUNION,
-    TNEWLINE,       TBINOM,         TFROM,          TTO,            TINT,
-    TSUM,           TOPER,          TABS,           TSQRT,          TFACT,
-    TNROOT,         TOVER,          TTIMES,         TGE,            TLE,
-    TGG,            TLL,            TDOTSAXIS,      TDOTSLOW,       TDOTSVERT,
-    TDOTSDIAG,      TDOTSUP,        TDOTSDOWN,      TACUTE,         TBAR,
-    TBREVE,         TCHECK,         TCIRCLE,        TDOT,           TDDOT,
-    TDDDOT,         TGRAVE,         THAT,           TTILDE,         TVEC,
-    TUNDERLINE,     TOVERLINE,      TOVERSTRIKE,    TITALIC,        TNITALIC,
-    TBOLD,          TNBOLD,         TPHANTOM,       TFONT,          TSIZE,
-    TCOLOR,         TALIGNL,        TALIGNC,        TALIGNR,        TLEFT,
-    TRIGHT,         TLANGLE,        TLBRACE,        TLLINE,         TLDLINE,
-    TLCEIL,         TLFLOOR,        TNONE,          TMLINE,         TRANGLE,
-    TRBRACE,        TRLINE,         TRDLINE,        TRCEIL,         TRFLOOR,
-    TSIN,           TCOS,           TTAN,           TCOT,           TFUNC,
-    TSTACK,         TMATRIX,        TMATFORM,       TDPOUND,        TPLACE,
-    TTEXT,          TNUMBER,        TCHARACTER,     TIDENT,         TNEQ,
-    TEQUIV,         TDEF,           TPROP,          TSIM,           TSIMEQ,
-    TAPPROX,        TPARALLEL,      TORTHO,         TIN,            TNOTIN,
-    TSUBSET,        TSUBSETEQ,      TSUPSET,        TSUPSETEQ,      TPLUSMINUS,
-    TMINUSPLUS,     TOPLUS,         TOMINUS,        TDIV,           TOTIMES,
-    TODIVIDE,       TTRANSL,        TTRANSR,        TIINT,          TIIINT,
-    TLINT,          TLLINT,         TLLLINT,        TPROD,          TCOPROD,
-    TFORALL,        TEXISTS,        TLIM,           TNABLA,         TTOWARD,
-    TSINH,          TCOSH,          TTANH,          TCOTH,          TASIN,
-    TACOS,          TATAN,          TLN,            TLOG,           TUOPER,
-    TBOPER,         TBLACK,         TWHITE,         TRED,           TGREEN,
-    TBLUE,          TCYAN,          TMAGENTA,       TYELLOW,        TFIXED,
-    TSANS,          TSERIF,         TPOINT,         TASINH,         TACOSH,
-    TATANH,         TACOTH,         TACOT,          TEXP,           TCDOT,
-    TODOT,          TLESLANT,       TGESLANT,       TNSUBSET,       TNSUPSET,
-    TNSUBSETEQ,     TNSUPSETEQ,     TPARTIAL,       TNEG,           TNI,
-    TBACKEPSILON,   TALEPH,         TIM,            TRE,            TWP,
-    TEMPTYSET,      TINFINITY,      TESCAPE,        TLIMSUP,        TLIMINF,
-    TNDIVIDES,      TDRARROW,       TDLARROW,       TDLRARROW,      TUNDERBRACE,
-    TOVERBRACE,     TCIRC,          TTOP,           THBAR,          TLAMBDABAR,
-    TLEFTARROW,     TRIGHTARROW,    TUPARROW,       TDOWNARROW,     TDIVIDES,
-    TNDIBVIDES,     TSETN,          TSETZ,          TSETQ,          TSETR,
-    TSETC,          TWIDEVEC,       TWIDETILDE,     TWIDEHAT,       TWIDESLASH,
-    TWIDEBACKSLASH, TLDBRACKET,     TRDBRACKET,     TNOSPACE,
-    TUNKNOWN,       TDEBUG
+/*  0*/ TEND,           TLGROUP,        TRGROUP,        TLPARENT,       TRPARENT,
+/*  5*/ TLBRACKET,      TRBRACKET,      TPLUS,          TMINUS,         TMULTIPLY,
+/* 10*/ TDIVIDEBY,      TASSIGN,        TPOUND,         TSPECIAL,       TSLASH,
+/* 15*/ TBACKSLASH,     TBLANK,         TSBLANK,        TRSUB,          TRSUP,
+/* 20*/ TCSUB,          TCSUP,          TLSUB,          TLSUP,          TGT,
+/* 25*/ TLT,            TAND,           TOR,            TINTERSECT,     TUNION,
+/* 30*/ TNEWLINE,       TBINOM,         TFROM,          TTO,            TINT,
+/* 35*/ TSUM,           TOPER,          TABS,           TSQRT,          TFACT,
+/* 40*/ TNROOT,         TOVER,          TTIMES,         TGE,            TLE,
+/* 45*/ TGG,            TLL,            TDOTSAXIS,      TDOTSLOW,       TDOTSVERT,
+/* 50*/ TDOTSDIAG,      TDOTSUP,        TDOTSDOWN,      TACUTE,         TBAR,
+/* 55*/ TBREVE,         TCHECK,         TCIRCLE,        TDOT,           TDDOT,
+/* 60*/ TDDDOT,         TGRAVE,         THAT,           TTILDE,         TVEC,
+/* 65*/ TUNDERLINE,     TOVERLINE,      TOVERSTRIKE,    TITALIC,        TNITALIC,
+/* 70*/ TBOLD,          TNBOLD,         TPHANTOM,       TFONT,          TSIZE,
+/* 75*/ TCOLOR,         TALIGNL,        TALIGNC,        TALIGNR,        TLEFT,
+/* 80*/ TRIGHT,         TLANGLE,        TLBRACE,        TLLINE,         TLDLINE,
+/* 85*/ TLCEIL,         TLFLOOR,        TNONE,          TMLINE,         TRANGLE,
+/* 90*/ TRBRACE,        TRLINE,         TRDLINE,        TRCEIL,         TRFLOOR,
+/* 95*/ TSIN,           TCOS,           TTAN,           TCOT,           TFUNC,
+/*100*/ TSTACK,         TMATRIX,        TMATFORM,       TDPOUND,        TPLACE,
+/*105*/ TTEXT,          TNUMBER,        TCHARACTER,     TIDENT,         TNEQ,
+/*110*/ TEQUIV,         TDEF,           TPROP,          TSIM,           TSIMEQ,
+/*115*/ TAPPROX,        TPARALLEL,      TORTHO,         TIN,            TNOTIN,
+/*120*/ TSUBSET,        TSUBSETEQ,      TSUPSET,        TSUPSETEQ,      TPLUSMINUS,
+/*125*/ TMINUSPLUS,     TOPLUS,         TOMINUS,        TDIV,           TOTIMES,
+/*130*/ TODIVIDE,       TTRANSL,        TTRANSR,        TIINT,          TIIINT,
+/*135*/ TLINT,          TLLINT,         TLLLINT,        TPROD,          TCOPROD,
+/*140*/ TFORALL,        TEXISTS,        TLIM,           TNABLA,         TTOWARD,
+/*145*/ TSINH,          TCOSH,          TTANH,          TCOTH,          TASIN,
+/*150*/ TACOS,          TATAN,          TLN,            TLOG,           TUOPER,
+/*155*/ TBOPER,         TBLACK,         TWHITE,         TRED,           TGREEN,
+/*160*/ TBLUE,          TCYAN,          TMAGENTA,       TYELLOW,        TFIXED,
+/*165*/ TSANS,          TSERIF,         TPOINT,         TASINH,         TACOSH,
+/*170*/ TATANH,         TACOTH,         TACOT,          TEXP,           TCDOT,
+/*175*/ TODOT,          TLESLANT,       TGESLANT,       TNSUBSET,       TNSUPSET,
+/*180*/ TNSUBSETEQ,     TNSUPSETEQ,     TPARTIAL,       TNEG,           TNI,
+/*185*/ TBACKEPSILON,   TALEPH,         TIM,            TRE,            TWP,
+/*190*/ TEMPTYSET,      TINFINITY,      TESCAPE,        TLIMSUP,        TLIMINF,
+/*195*/ TNDIVIDES,      TDRARROW,       TDLARROW,       TDLRARROW,      TUNDERBRACE,
+/*200*/ TOVERBRACE,     TCIRC,          TTOP,           THBAR,          TLAMBDABAR,
+/*205*/ TLEFTARROW,     TRIGHTARROW,    TUPARROW,       TDOWNARROW,     TDIVIDES,
+/*210*/ TNDIBVIDES,     TSETN,          TSETZ,          TSETQ,          TSETR,
+/*215*/ TSETC,          TWIDEVEC,       TWIDETILDE,     TWIDEHAT,       TWIDESLASH,
+/*220*/ TWIDEBACKSLASH, TLDBRACKET,     TRDBRACKET,     TNOSPACE,
+/*225*/ TUNKNOWN,       TDEBUG
 };
 
 
commit 198b1c528c6a55adbb84c4e97def4b0b6bccd5a7
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Tue Aug 30 15:28:59 2011 +0200

    helper to simplify horrible string conversions

diff --git a/starmath/source/ooxml.cxx b/starmath/source/ooxml.cxx
index c5acb47..992285c 100644
--- a/starmath/source/ooxml.cxx
+++ b/starmath/source/ooxml.cxx
@@ -421,18 +421,23 @@ void SmOoxml::HandleRoot( const SmRootNode* pNode, int nLevel )
     m_pSerializer->endElementNS( XML_m, XML_rad );
 }
 
+static rtl::OString mathSymbolToString( const SmNode* node )
+{
+    OSL_ASSERT( node->GetType() == NMATH && static_cast< const SmTextNode* >( node )->GetText().Len() == 1 );
+    sal_Unicode chr = Convert( static_cast< const SmTextNode* >( node )->GetText().GetChar( 0 ));
+    return rtl::OUStringToOString( rtl::OUString( chr ), RTL_TEXTENCODING_UTF8 );
+}
+
 void SmOoxml::HandleOperator( const SmOperNode* pNode, int nLevel )
 {
     fprintf( stderr, "OPER %d\n", pNode->GetToken().eType );
     const SmSubSupNode* subsup = pNode->GetSubNode( 0 )->GetType() == NSUBSUP
         ? static_cast< const SmSubSupNode* >( pNode->GetSubNode( 0 )) : NULL;
     const SmNode* operation = subsup != NULL ? subsup->GetBody() : pNode->GetSubNode( 0 );
-    OSL_ASSERT( operation->GetType() == NMATH && static_cast< const SmTextNode* >( operation )->GetText().Len() == 1 );
-    sal_Unicode chr = Convert( static_cast< const SmTextNode* >( operation )->GetText().GetChar( 0 ));
     m_pSerializer->startElementNS( XML_m, XML_nary, FSEND );
     m_pSerializer->startElementNS( XML_m, XML_naryPr, FSEND );
-    rtl::OString chrValue = rtl::OUStringToOString( rtl::OUString( chr ), RTL_TEXTENCODING_UTF8 );
-    m_pSerializer->singleElementNS( XML_m, XML_char, FSNS( XML_m, XML_val ), chrValue.getStr(), FSEND );
+    m_pSerializer->singleElementNS( XML_m, XML_char,
+        FSNS( XML_m, XML_val ), mathSymbolToString( operation ).getStr(), FSEND );
     if( subsup == NULL || subsup->GetSubSup( CSUB ) == NULL )
         m_pSerializer->singleElementNS( XML_m, XML_subHide, FSNS( XML_m, XML_val ), "1", FSEND );
     if( subsup == NULL || subsup->GetSubSup( CSUP ) == NULL )
@@ -555,12 +560,8 @@ void SmOoxml::HandleBrace( const SmBraceNode* pNode, int nLevel )
 {
     m_pSerializer->startElementNS( XML_m, XML_d, FSEND );
     m_pSerializer->startElementNS( XML_m, XML_dPr, FSEND );
-    const SmMathSymbolNode* opening = pNode->OpeningBrace();
-    OSL_ASSERT( static_cast< const SmTextNode* >( opening )->GetText().Len() == 1 );
-    sal_Unicode chr = Convert( static_cast< const SmTextNode* >( opening )->GetText().GetChar( 0 ));
-    rtl::OString chrValue = rtl::OUStringToOString( rtl::OUString( chr ), RTL_TEXTENCODING_UTF8 );
-    m_pSerializer->singleElementNS( XML_m, XML_begChr, FSNS( XML_m, XML_val ), chrValue.getStr(), FSEND );
-
+    m_pSerializer->singleElementNS( XML_m, XML_begChr,
+        FSNS( XML_m, XML_val ), mathSymbolToString( pNode->OpeningBrace()).getStr(), FSEND );
     std::vector< const SmNode* > subnodes;
     if( pNode->Body()->GetType() == NBRACEBODY )
     {
@@ -574,10 +575,8 @@ void SmOoxml::HandleBrace( const SmBraceNode* pNode, int nLevel )
                 const SmMathSymbolNode* math = static_cast< const SmMathSymbolNode* >( subnode );
                 if( !separatorWritten )
                 {
-                    OSL_ASSERT( static_cast< const SmTextNode* >( math )->GetText().Len() == 1 );
-                    sal_Unicode chr3 = Convert( static_cast< const SmTextNode* >( math )->GetText().GetChar( 0 ));
-                    rtl::OString chrValue3 = rtl::OUStringToOString( rtl::OUString( chr3 ), RTL_TEXTENCODING_UTF8 );
-                    m_pSerializer->singleElementNS( XML_m, XML_sepChr, FSNS( XML_m, XML_val ), chrValue3.getStr(), FSEND );
+                    m_pSerializer->singleElementNS( XML_m, XML_sepChr,
+                        FSNS( XML_m, XML_val ), mathSymbolToString( math ).getStr(), FSEND );
                     separatorWritten = true;
                 }
             }
@@ -587,11 +586,8 @@ void SmOoxml::HandleBrace( const SmBraceNode* pNode, int nLevel )
     }
     else
         subnodes.push_back( pNode->Body());
-    const SmMathSymbolNode* closing = pNode->ClosingBrace();
-    OSL_ASSERT( static_cast< const SmTextNode* >( closing )->GetText().Len() == 1 );
-    sal_Unicode chr2 = Convert( static_cast< const SmTextNode* >( closing )->GetText().GetChar( 0 ));
-    rtl::OString chrValue2 = rtl::OUStringToOString( rtl::OUString( chr2 ), RTL_TEXTENCODING_UTF8 );
-    m_pSerializer->singleElementNS( XML_m, XML_endChr, FSNS( XML_m, XML_val ), chrValue2.getStr(), FSEND );
+    m_pSerializer->singleElementNS( XML_m, XML_endChr,
+        FSNS( XML_m, XML_val ), mathSymbolToString( pNode->ClosingBrace()).getStr(), FSEND );
     m_pSerializer->endElementNS( XML_m, XML_dPr );
     for( unsigned int i = 0; i < subnodes.size(); ++i )
     {
commit 41fae7dc55878a49571888aff3c29a36bddb834d
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Tue Aug 30 15:24:25 2011 +0200

    implement math braces export for .docx

diff --git a/starmath/inc/node.hxx b/starmath/inc/node.hxx
index 1b3dbd9..38d46d4 100644
--- a/starmath/inc/node.hxx
+++ b/starmath/inc/node.hxx
@@ -1001,6 +1001,13 @@ public:
         SetNumSubNodes(3);
     }
 
+    SmMathSymbolNode* OpeningBrace();
+    const SmMathSymbolNode* OpeningBrace() const;
+    SmNode* Body();
+    const SmNode* Body() const;
+    SmMathSymbolNode* ClosingBrace();
+    const SmMathSymbolNode* ClosingBrace() const;
+
     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
     void CreateTextFromNode(String &rText);
     void Accept(SmVisitor* pVisitor);
@@ -1337,6 +1344,34 @@ inline const SmNode* SmAttributNode::Body() const
     return const_cast< SmAttributNode* >( this )->Body();
 }
 
+inline SmMathSymbolNode* SmBraceNode::OpeningBrace()
+{
+    OSL_ASSERT( GetNumSubNodes() > 0 && GetSubNode( 0 )->GetType() == NMATH );
+    return static_cast< SmMathSymbolNode* >( GetSubNode( 0 ));
+}
+inline const SmMathSymbolNode* SmBraceNode::OpeningBrace() const
+{
+    return const_cast< SmBraceNode* >( this )->OpeningBrace();
+}
+inline SmNode* SmBraceNode::Body()
+{
+    OSL_ASSERT( GetNumSubNodes() > 1 );
+    return GetSubNode( 1 );
+}
+inline const SmNode* SmBraceNode::Body() const
+{
+    return const_cast< SmBraceNode* >( this )->Body();
+}
+inline SmMathSymbolNode* SmBraceNode::ClosingBrace()
+{
+    OSL_ASSERT( GetNumSubNodes() > 2 && GetSubNode( 2 )->GetType() == NMATH );
+    return static_cast< SmMathSymbolNode* >( GetSubNode( 2 ));
+}
+inline const SmMathSymbolNode* SmBraceNode::ClosingBrace() const
+{
+    return const_cast< SmBraceNode* >( this )->ClosingBrace();
+}
+
 #endif
 
 
diff --git a/starmath/source/ooxml.cxx b/starmath/source/ooxml.cxx
index 9febf65..c5acb47 100644
--- a/starmath/source/ooxml.cxx
+++ b/starmath/source/ooxml.cxx
@@ -108,10 +108,10 @@ void SmOoxml::HandleNode( const SmNode* pNode, int nLevel )
         case NVERTICAL_BRACE:
             HandleVerticalBrace(pNode,nLevel);
             break;
+#endif
         case NBRACE:
-            HandleBrace(pNode,nLevel);
+            HandleBrace( static_cast< const SmBraceNode* >( pNode ), nLevel );
             break;
-#endif
         case NOPER:
             HandleOperator( static_cast< const SmOperNode* >( pNode ), nLevel );
             break;
@@ -551,4 +551,55 @@ void SmOoxml::HandleMatrix( const SmMatrixNode* pNode, int nLevel )
     m_pSerializer->endElementNS( XML_m, XML_m );
 }
 
+void SmOoxml::HandleBrace( const SmBraceNode* pNode, int nLevel )
+{
+    m_pSerializer->startElementNS( XML_m, XML_d, FSEND );
+    m_pSerializer->startElementNS( XML_m, XML_dPr, FSEND );
+    const SmMathSymbolNode* opening = pNode->OpeningBrace();
+    OSL_ASSERT( static_cast< const SmTextNode* >( opening )->GetText().Len() == 1 );
+    sal_Unicode chr = Convert( static_cast< const SmTextNode* >( opening )->GetText().GetChar( 0 ));
+    rtl::OString chrValue = rtl::OUStringToOString( rtl::OUString( chr ), RTL_TEXTENCODING_UTF8 );
+    m_pSerializer->singleElementNS( XML_m, XML_begChr, FSNS( XML_m, XML_val ), chrValue.getStr(), FSEND );
+
+    std::vector< const SmNode* > subnodes;
+    if( pNode->Body()->GetType() == NBRACEBODY )
+    {
+        const SmBracebodyNode* body = static_cast< const SmBracebodyNode* >( pNode->Body());
+        bool separatorWritten = false; // assume all separators are the same
+        for( int i = 0; i < body->GetNumSubNodes(); ++i )
+        {
+            const SmNode* subnode = body->GetSubNode( i );
+            if( subnode->GetType() == NMATH )
+            { // do not write, but write what separator it is
+                const SmMathSymbolNode* math = static_cast< const SmMathSymbolNode* >( subnode );
+                if( !separatorWritten )
+                {
+                    OSL_ASSERT( static_cast< const SmTextNode* >( math )->GetText().Len() == 1 );
+                    sal_Unicode chr3 = Convert( static_cast< const SmTextNode* >( math )->GetText().GetChar( 0 ));
+                    rtl::OString chrValue3 = rtl::OUStringToOString( rtl::OUString( chr3 ), RTL_TEXTENCODING_UTF8 );
+                    m_pSerializer->singleElementNS( XML_m, XML_sepChr, FSNS( XML_m, XML_val ), chrValue3.getStr(), FSEND );
+                    separatorWritten = true;
+                }
+            }
+            else
+                subnodes.push_back( subnode );
+        }
+    }
+    else
+        subnodes.push_back( pNode->Body());
+    const SmMathSymbolNode* closing = pNode->ClosingBrace();
+    OSL_ASSERT( static_cast< const SmTextNode* >( closing )->GetText().Len() == 1 );
+    sal_Unicode chr2 = Convert( static_cast< const SmTextNode* >( closing )->GetText().GetChar( 0 ));
+    rtl::OString chrValue2 = rtl::OUStringToOString( rtl::OUString( chr2 ), RTL_TEXTENCODING_UTF8 );
+    m_pSerializer->singleElementNS( XML_m, XML_endChr, FSNS( XML_m, XML_val ), chrValue2.getStr(), FSEND );
+    m_pSerializer->endElementNS( XML_m, XML_dPr );
+    for( unsigned int i = 0; i < subnodes.size(); ++i )
+    {
+        m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
+        HandleNode( subnodes[ i ], nLevel + 1 );
+        m_pSerializer->endElementNS( XML_m, XML_e );
+    }
+    m_pSerializer->endElementNS( XML_m, XML_d );
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/ooxml.hxx b/starmath/source/ooxml.hxx
index 2b651ed..a88d717 100644
--- a/starmath/source/ooxml.hxx
+++ b/starmath/source/ooxml.hxx
@@ -58,6 +58,7 @@ private:
     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 );
     String str;
     const SmNode* const pTree;
     ::sax_fastparser::FSHelperPtr m_pSerializer;
commit bf33a26a1a29f33532289f55a9c87930f534ae4e
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Tue Aug 30 14:34:33 2011 +0200

    improve comment about SmBrace (body can be expression for abs{x})

diff --git a/starmath/inc/node.hxx b/starmath/inc/node.hxx
index 9fc44d2..1b3dbd9 100644
--- a/starmath/inc/node.hxx
+++ b/starmath/inc/node.hxx
@@ -990,9 +990,7 @@ public:
  * 2: Closing brace<BR>
  * None of the children can be NULL.
  *
- * Note that child 1 (Body) is usually SmBracebodyNode, I don't know if it can
- * be an SmExpressionNode, haven't seen the case. But didn't quite read parser.cxx
- * enought to exclude this possibility.
+ * Note that child 1 (Body) is usually SmBracebodyNode, but it can also be e.g. SmExpressionNode.
  */
 class SmBraceNode : public SmStructureNode
 {
commit a32fe391c25bd0f4db7727eb9085e4b0df70682c
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Tue Aug 30 12:16:14 2011 +0200

    implement NBLANK export to .docx

diff --git a/starmath/source/ooxml.cxx b/starmath/source/ooxml.cxx
index 38eac20..9febf65 100644
--- a/starmath/source/ooxml.cxx
+++ b/starmath/source/ooxml.cxx
@@ -166,18 +166,17 @@ void SmOoxml::HandleNode( const SmNode* pNode, int nLevel )
         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:
-            *pS << sal_uInt8(CHAR);
-            *pS << sal_uInt8(0x98);
-            if (pNode->GetToken().eType == TSBLANK)
-                *pS << sal_uInt16(0xEB04);
-            else
-                *pS << sal_uInt16(0xEB05);
+            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;
-#endif
         default:
             HandleAllSubNodes( pNode, nLevel );
             break;
@@ -252,7 +251,7 @@ void SmOoxml::HandleText( const SmNode* pNode, int /*nLevel*/)
             FSNS( XML_w, XML_hAnsi ), "Cambria Math", FSEND );
         m_pSerializer->endElementNS( XML_w, XML_rPr );
     }
-    m_pSerializer->startElementNS( XML_m, XML_t, FSEND );
+    m_pSerializer->startElementNS( XML_m, XML_t, FSNS( XML_xml, XML_space ), "preserve", FSEND );
     SmTextNode* pTemp=(SmTextNode* )pNode;
 //    fprintf(stderr, "T %s\n", rtl::OUStringToOString( pTemp->GetText(), RTL_TEXTENCODING_UTF8 ).getStr());
     for(xub_StrLen i=0;i<pTemp->GetText().Len();i++)
commit d1359c4d6ee6562137a5fbd5c95032a9a812314c
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Tue Aug 30 12:08:39 2011 +0200

    implement .docx matrix export

diff --git a/starmath/source/ooxml.cxx b/starmath/source/ooxml.cxx
index aec33e9..38eac20 100644
--- a/starmath/source/ooxml.cxx
+++ b/starmath/source/ooxml.cxx
@@ -153,11 +153,9 @@ void SmOoxml::HandleNode( const SmNode* pNode, int nLevel )
             //Root Node, PILE equivalent, i.e. vertical stack
             HandleTable(pNode,nLevel);
             break;
-#if 0
         case NMATRIX:
-            HandleSmMatrix( static_cast< const SmMatrixNode* >( pNode ), nLevel );
+            HandleMatrix( static_cast< const SmMatrixNode* >( pNode ), nLevel );
             break;
-#endif
         case NLINE:
             {
 // TODO
@@ -532,7 +530,26 @@ void SmOoxml::HandleSubSupScriptInternal( const SmSubSupNode* pNode, int nLevel,
     else
     {
         OSL_FAIL( "Unhandled sub/sup combination" );
+        HandleAllSubNodes( pNode, nLevel );
+    }
+}
+
+void SmOoxml::HandleMatrix( const SmMatrixNode* pNode, int nLevel )
+{
+    m_pSerializer->startElementNS( XML_m, XML_m, FSEND );
+    for( int row = 0; row < pNode->GetNumRows(); ++row )
+    {
+        m_pSerializer->startElementNS( XML_m, XML_mr, FSEND );
+        for( int col = 0; col < pNode->GetNumCols(); ++col )
+        {
+            m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
+            if( const SmNode* node = pNode->GetSubNode( row * pNode->GetNumCols() + col ))
+                HandleNode( node, nLevel + 1 );
+            m_pSerializer->endElementNS( XML_m, XML_e );
+        }
+        m_pSerializer->endElementNS( XML_m, XML_mr );
     }
+    m_pSerializer->endElementNS( XML_m, XML_m );
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/ooxml.hxx b/starmath/source/ooxml.hxx
index dbebd37..2b651ed 100644
--- a/starmath/source/ooxml.hxx
+++ b/starmath/source/ooxml.hxx
@@ -57,6 +57,7 @@ private:
     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 );
     String str;
     const SmNode* const pTree;
     ::sax_fastparser::FSHelperPtr m_pSerializer;
commit 61b1fb0f42f51235bb0b92da30c0d4e2d6297960
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Mon Aug 29 19:28:08 2011 +0200

    more generic m:nary implementation

diff --git a/starmath/source/ooxml.cxx b/starmath/source/ooxml.cxx
index 00df7f7..aec33e9 100644
--- a/starmath/source/ooxml.cxx
+++ b/starmath/source/ooxml.cxx
@@ -427,43 +427,15 @@ void SmOoxml::HandleRoot( const SmRootNode* pNode, int nLevel )
 void SmOoxml::HandleOperator( const SmOperNode* pNode, int nLevel )
 {
     fprintf( stderr, "OPER %d\n", pNode->GetToken().eType );
-    switch( pNode->GetToken().eType )
-    {
-        case TINT:
-            HandleOperatorNary( pNode, nLevel, sal_Unicode( 0x222b ));
-            break;
-        case TIINT:
-            HandleOperatorNary( pNode, nLevel, sal_Unicode( 0x222c ));
-            break;
-        case TIIINT:
-            HandleOperatorNary( pNode, nLevel, sal_Unicode( 0x222d ));
-            break;
-        case TLINT:
-            HandleOperatorNary( pNode, nLevel, sal_Unicode( 0x222e ));
-            break;
-        case TLLINT:
-            HandleOperatorNary( pNode, nLevel, sal_Unicode( 0x222f ));
-            break;
-        case TLLLINT:
-            HandleOperatorNary( pNode, nLevel, sal_Unicode( 0x2230 ));
-            break;
-        default:
-            OSL_FAIL( "Operator not handled explicitly" );
-            HandleAllSubNodes( pNode, nLevel );
-            break;
-    }
-}
-
-void SmOoxml::HandleOperatorNary( const SmOperNode* pNode, int nLevel, sal_Unicode chr )
-{
+    const SmSubSupNode* subsup = pNode->GetSubNode( 0 )->GetType() == NSUBSUP
+        ? static_cast< const SmSubSupNode* >( pNode->GetSubNode( 0 )) : NULL;
+    const SmNode* operation = subsup != NULL ? subsup->GetBody() : pNode->GetSubNode( 0 );
+    OSL_ASSERT( operation->GetType() == NMATH && static_cast< const SmTextNode* >( operation )->GetText().Len() == 1 );
+    sal_Unicode chr = Convert( static_cast< const SmTextNode* >( operation )->GetText().GetChar( 0 ));
     m_pSerializer->startElementNS( XML_m, XML_nary, FSEND );
     m_pSerializer->startElementNS( XML_m, XML_naryPr, FSEND );
     rtl::OString chrValue = rtl::OUStringToOString( rtl::OUString( chr ), RTL_TEXTENCODING_UTF8 );
     m_pSerializer->singleElementNS( XML_m, XML_char, FSNS( XML_m, XML_val ), chrValue.getStr(), FSEND );
-    const SmSubSupNode* subsup = pNode->GetSubNode( 0 )->GetType() == NSUBSUP
-        ? static_cast< const SmSubSupNode* >( pNode->GetSubNode( 0 )) : NULL;
-// GetSubNode( 0 ) is otherwise generally ignored, as it should be just SmMathSymbolNode for the operation,
-// and we have 'chr' already
     if( subsup == NULL || subsup->GetSubSup( CSUB ) == NULL )
         m_pSerializer->singleElementNS( XML_m, XML_subHide, FSNS( XML_m, XML_val ), "1", FSEND );
     if( subsup == NULL || subsup->GetSubSup( CSUP ) == NULL )
diff --git a/starmath/source/ooxml.hxx b/starmath/source/ooxml.hxx
index 12c3a3e..dbebd37 100644
--- a/starmath/source/ooxml.hxx
+++ b/starmath/source/ooxml.hxx
@@ -55,7 +55,6 @@ private:
     void HandleRoot( const SmRootNode* pNode, int nLevel );
     void HandleAttribute( const SmAttributNode* pNode, int nLevel );
     void HandleOperator( const SmOperNode* pNode, int nLevel );
-    void HandleOperatorNary( const SmOperNode* pNode, int nLevel, sal_Unicode chr );
     void HandleSubSupScript( const SmSubSupNode* pNode, int nLevel );
     void HandleSubSupScriptInternal( const SmSubSupNode* pNode, int nLevel, int flags );
     String str;
commit 3c923d989fffb77a88d0e754c9a7fe7e0901c67f
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Mon Aug 29 18:20:11 2011 +0200

    implement math .docx support for integrals and limits

diff --git a/starmath/source/ooxml.cxx b/starmath/source/ooxml.cxx
index aea6e09..00df7f7 100644
--- a/starmath/source/ooxml.cxx
+++ b/starmath/source/ooxml.cxx
@@ -111,10 +111,10 @@ void SmOoxml::HandleNode( const SmNode* pNode, int nLevel )
         case NBRACE:
             HandleBrace(pNode,nLevel);
             break;
+#endif
         case NOPER:
-            HandleOperator(pNode,nLevel);
+            HandleOperator( static_cast< const SmOperNode* >( pNode ), nLevel );
             break;
-#endif
         case NUNHOR:
             HandleUnaryOperation( static_cast< const SmUnHorNode* >( pNode ), nLevel );
             break;
@@ -424,6 +424,73 @@ void SmOoxml::HandleRoot( const SmRootNode* pNode, int nLevel )
     m_pSerializer->endElementNS( XML_m, XML_rad );
 }
 
+void SmOoxml::HandleOperator( const SmOperNode* pNode, int nLevel )
+{
+    fprintf( stderr, "OPER %d\n", pNode->GetToken().eType );
+    switch( pNode->GetToken().eType )
+    {
+        case TINT:
+            HandleOperatorNary( pNode, nLevel, sal_Unicode( 0x222b ));
+            break;
+        case TIINT:
+            HandleOperatorNary( pNode, nLevel, sal_Unicode( 0x222c ));
+            break;
+        case TIIINT:
+            HandleOperatorNary( pNode, nLevel, sal_Unicode( 0x222d ));
+            break;
+        case TLINT:
+            HandleOperatorNary( pNode, nLevel, sal_Unicode( 0x222e ));
+            break;
+        case TLLINT:
+            HandleOperatorNary( pNode, nLevel, sal_Unicode( 0x222f ));
+            break;
+        case TLLLINT:
+            HandleOperatorNary( pNode, nLevel, sal_Unicode( 0x2230 ));
+            break;
+        default:
+            OSL_FAIL( "Operator not handled explicitly" );
+            HandleAllSubNodes( pNode, nLevel );
+            break;
+    }
+}
+
+void SmOoxml::HandleOperatorNary( const SmOperNode* pNode, int nLevel, sal_Unicode chr )
+{
+    m_pSerializer->startElementNS( XML_m, XML_nary, FSEND );
+    m_pSerializer->startElementNS( XML_m, XML_naryPr, FSEND );
+    rtl::OString chrValue = rtl::OUStringToOString( rtl::OUString( chr ), RTL_TEXTENCODING_UTF8 );
+    m_pSerializer->singleElementNS( XML_m, XML_char, FSNS( XML_m, XML_val ), chrValue.getStr(), FSEND );
+    const SmSubSupNode* subsup = pNode->GetSubNode( 0 )->GetType() == NSUBSUP
+        ? static_cast< const SmSubSupNode* >( pNode->GetSubNode( 0 )) : NULL;
+// GetSubNode( 0 ) is otherwise generally ignored, as it should be just SmMathSymbolNode for the operation,
+// and we have 'chr' already
+    if( subsup == NULL || subsup->GetSubSup( CSUB ) == NULL )
+        m_pSerializer->singleElementNS( XML_m, XML_subHide, FSNS( XML_m, XML_val ), "1", FSEND );
+    if( subsup == NULL || subsup->GetSubSup( CSUP ) == NULL )
+        m_pSerializer->singleElementNS( XML_m, XML_supHide, FSNS( XML_m, XML_val ), "1", FSEND );
+    m_pSerializer->endElementNS( XML_m, XML_naryPr );
+    if( subsup == NULL || subsup->GetSubSup( CSUB ) == NULL )
+        m_pSerializer->singleElementNS( XML_m, XML_sub, FSEND );
+    else
+    {
+        m_pSerializer->startElementNS( XML_m, XML_sub, FSEND );
+        HandleNode( subsup->GetSubSup( CSUB ), nLevel + 1 );
+        m_pSerializer->endElementNS( XML_m, XML_sub );
+    }
+    if( subsup == NULL || subsup->GetSubSup( CSUP ) == NULL )
+        m_pSerializer->singleElementNS( XML_m, XML_sup, FSEND );
+    else
+    {
+        m_pSerializer->startElementNS( XML_m, XML_sup, FSEND );
+        HandleNode( subsup->GetSubSup( CSUP ), nLevel + 1 );
+        m_pSerializer->endElementNS( XML_m, XML_sup );
+    }
+    m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
+    HandleNode( pNode->GetSubNode( 1 ), nLevel + 1 ); // body
+    m_pSerializer->endElementNS( XML_m, XML_e );
+    m_pSerializer->endElementNS( XML_m, XML_nary );
+}
+
 void SmOoxml::HandleSubSupScript( const SmSubSupNode* pNode, int nLevel )
 {
     // set flags to a bitfield of which sub/sup items exists
diff --git a/starmath/source/ooxml.hxx b/starmath/source/ooxml.hxx
index 7246a8c..12c3a3e 100644
--- a/starmath/source/ooxml.hxx
+++ b/starmath/source/ooxml.hxx
@@ -52,8 +52,10 @@ private:
     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 HandleRoot( const SmRootNode* pNode, int nLevel );
+    void HandleAttribute( const SmAttributNode* pNode, int nLevel );
+    void HandleOperator( const SmOperNode* pNode, int nLevel );
+    void HandleOperatorNary( const SmOperNode* pNode, int nLevel, sal_Unicode chr );
     void HandleSubSupScript( const SmSubSupNode* pNode, int nLevel );
     void HandleSubSupScriptInternal( const SmSubSupNode* pNode, int nLevel, int flags );
     String str;
commit f7d71e379edf2c29d53182458342d7a5ce1446d6
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Mon Aug 29 18:17:53 2011 +0200

    fix comment about children of SmOperNode

diff --git a/starmath/inc/node.hxx b/starmath/inc/node.hxx
index 38793e7..9fc44d2 100644
--- a/starmath/inc/node.hxx
+++ b/starmath/inc/node.hxx
@@ -1079,12 +1079,10 @@ inline SmVerticalBraceNode::SmVerticalBraceNode(const SmToken &rNodeToken) :
  * Used for commands like SUM, INT and similar.
  *
  * Children:<BR>
- * 0: Operation (instance of SmMathSymbolNode)<BR>
+ * 0: Operation (instance of SmMathSymbolNode or SmSubSupNode)<BR>
  * 1: Body<BR>
  * None of the children may be NULL.
  *
- * If there are boundaries on the operation the body will an instance of
- * SmSubSupNode.
  */
 class SmOperNode : public SmStructureNode
 {


More information about the Libreoffice-commits mailing list