1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 #include "ooxmlexport.hxx"
13 #include <oox/token/tokens.hxx>
14 #include <rtl/ustring.hxx>
17 using namespace oox::core
;
19 SmOoxmlExport::SmOoxmlExport(const SmNode
*const pIn
, OoxmlVersion
const v
,
20 drawingml::DocumentType
const documentType
)
21 : SmWordExportBase( pIn
)
23 , m_DocumentType(documentType
)
27 bool SmOoxmlExport::ConvertFromStarMath( const ::sax_fastparser::FSHelperPtr
& serializer
)
29 if( m_pTree
== nullptr )
31 m_pSerializer
= serializer
;
32 m_pSerializer
->startElementNS( XML_m
, XML_oMath
,
33 FSNS( XML_xmlns
, XML_m
), "http://schemas.openxmlformats.org/officeDocument/2006/math", FSEND
);
34 HandleNode( m_pTree
, 0 );
35 m_pSerializer
->endElementNS( XML_m
, XML_oMath
);
39 // NOTE: This is still work in progress and unfinished, but it already covers a good
40 // part of the ooxml math stuff.
42 void SmOoxmlExport::HandleVerticalStack( const SmNode
* pNode
, int nLevel
)
44 m_pSerializer
->startElementNS( XML_m
, XML_eqArr
, FSEND
);
45 int size
= pNode
->GetNumSubNodes();
50 m_pSerializer
->startElementNS( XML_m
, XML_e
, FSEND
);
51 HandleNode( pNode
->GetSubNode( i
), nLevel
+ 1 );
52 m_pSerializer
->endElementNS( XML_m
, XML_e
);
54 m_pSerializer
->endElementNS( XML_m
, XML_eqArr
);
57 void SmOoxmlExport::HandleText( const SmNode
* pNode
, int /*nLevel*/)
59 m_pSerializer
->startElementNS( XML_m
, XML_r
, FSEND
);
61 if( pNode
->GetToken().eType
== TTEXT
) // literal text (in quotes)
63 m_pSerializer
->startElementNS( XML_m
, XML_rPr
, FSEND
);
64 m_pSerializer
->singleElementNS( XML_m
, XML_lit
, FSEND
);
65 m_pSerializer
->singleElementNS( XML_m
, XML_nor
, FSEND
);
66 m_pSerializer
->endElementNS( XML_m
, XML_rPr
);
68 if (drawingml::DOCUMENT_DOCX
== m_DocumentType
&& ECMA_DIALECT
== version
)
69 { // HACK: MSOffice2007 does not import characters properly unless this font is explicitly given
70 m_pSerializer
->startElementNS( XML_w
, XML_rPr
, FSEND
);
71 m_pSerializer
->singleElementNS( XML_w
, XML_rFonts
, FSNS( XML_w
, XML_ascii
), "Cambria Math",
72 FSNS( XML_w
, XML_hAnsi
), "Cambria Math", FSEND
);
73 m_pSerializer
->endElementNS( XML_w
, XML_rPr
);
75 m_pSerializer
->startElementNS( XML_m
, XML_t
, FSNS( XML_xml
, XML_space
), "preserve", FSEND
);
76 const SmTextNode
* pTemp
= static_cast<const SmTextNode
* >(pNode
);
77 SAL_INFO( "starmath.ooxml", "Text:" << OUStringToOString( pTemp
->GetText(), RTL_TEXTENCODING_UTF8
).getStr());
78 OUStringBuffer
buf(pTemp
->GetText());
79 for(sal_Int32 i
=0;i
<pTemp
->GetText().getLength();i
++)
82 if ((nPendingAttributes
) &&
83 (i
== ((pTemp
->GetText().getLength()+1)/2)-1))
85 *pS
<< sal_uInt8(0x22); //char, with attributes right
89 *pS
<< sal_uInt8(CHAR
);
91 sal_uInt8 nFace
= 0x1;
92 if (pNode
->GetFont().GetItalic() == ITALIC_NORMAL
)
94 else if (pNode
->GetFont().GetWeight() == WEIGHT_BOLD
)
96 *pS
<< sal_uInt8(nFace
+128); //typeface
98 buf
[i
] = SmTextNode::ConvertSymbolToUnicode(buf
[i
]);
100 //Mathtype can only have these sort of character
101 //attributes on a single character, starmath can put them
102 //anywhere, when the entity involved is a text run this is
103 //a large effort to place the character attribute on the
104 //central mathtype character so that it does pretty much
105 //what the user probably has in mind. The attributes
106 //filled in here are dummy ones which are replaced in the
107 //ATTRIBUT handler if a suitable location for the
108 //attributes was found here. Unfortunately it is
109 //possible for starmath to place character attributes on
110 //entities which cannot occur in mathtype e.g. a Summation
111 //symbol so these attributes may be lost
112 if ((nPendingAttributes
) &&
113 (i
== ((pTemp
->GetText().getLength()+1)/2)-1))
115 *pS
<< sal_uInt8(EMBEL
);
116 while (nPendingAttributes
)
119 //wedge the attributes in here and clear
121 nPendingAttributes
--;
123 nInsertion
=pS
->Tell();
124 *pS
<< sal_uInt8(END
); //end embel
125 *pS
<< sal_uInt8(END
); //end embel
129 m_pSerializer
->writeEscaped(buf
.makeStringAndClear());
130 m_pSerializer
->endElementNS( XML_m
, XML_t
);
131 m_pSerializer
->endElementNS( XML_m
, XML_r
);
134 void SmOoxmlExport::HandleFractions( const SmNode
* pNode
, int nLevel
, const char* type
)
136 m_pSerializer
->startElementNS( XML_m
, XML_f
, FSEND
);
137 if( type
!= nullptr )
139 m_pSerializer
->startElementNS( XML_m
, XML_fPr
, FSEND
);
140 m_pSerializer
->singleElementNS( XML_m
, XML_type
, FSNS( XML_m
, XML_val
), type
, FSEND
);
141 m_pSerializer
->endElementNS( XML_m
, XML_fPr
);
143 assert( pNode
->GetNumSubNodes() == 3 );
144 m_pSerializer
->startElementNS( XML_m
, XML_num
, FSEND
);
145 HandleNode( pNode
->GetSubNode( 0 ), nLevel
+ 1 );
146 m_pSerializer
->endElementNS( XML_m
, XML_num
);
147 m_pSerializer
->startElementNS( XML_m
, XML_den
, FSEND
);
148 HandleNode( pNode
->GetSubNode( 2 ), nLevel
+ 1 );
149 m_pSerializer
->endElementNS( XML_m
, XML_den
);
150 m_pSerializer
->endElementNS( XML_m
, XML_f
);
153 void SmOoxmlExport::HandleAttribute( const SmAttributNode
* pNode
, int nLevel
)
155 switch( pNode
->Attribute()->GetToken().eType
)
173 m_pSerializer
->startElementNS( XML_m
, XML_acc
, FSEND
);
174 m_pSerializer
->startElementNS( XML_m
, XML_accPr
, FSEND
);
175 OString value
= OUStringToOString(
176 OUString( pNode
->Attribute()->GetToken().cMathChar
), RTL_TEXTENCODING_UTF8
);
177 m_pSerializer
->singleElementNS( XML_m
, XML_chr
, FSNS( XML_m
, XML_val
), value
.getStr(), FSEND
);
178 m_pSerializer
->endElementNS( XML_m
, XML_accPr
);
179 m_pSerializer
->startElementNS( XML_m
, XML_e
, FSEND
);
180 HandleNode( pNode
->Body(), nLevel
+ 1 );
181 m_pSerializer
->endElementNS( XML_m
, XML_e
);
182 m_pSerializer
->endElementNS( XML_m
, XML_acc
);
187 m_pSerializer
->startElementNS( XML_m
, XML_bar
, FSEND
);
188 m_pSerializer
->startElementNS( XML_m
, XML_barPr
, FSEND
);
189 m_pSerializer
->singleElementNS( XML_m
, XML_pos
, FSNS( XML_m
, XML_val
),
190 ( pNode
->Attribute()->GetToken().eType
== TUNDERLINE
) ? "bot" : "top", FSEND
);
191 m_pSerializer
->endElementNS( XML_m
, XML_barPr
);
192 m_pSerializer
->startElementNS( XML_m
, XML_e
, FSEND
);
193 HandleNode( pNode
->Body(), nLevel
+ 1 );
194 m_pSerializer
->endElementNS( XML_m
, XML_e
);
195 m_pSerializer
->endElementNS( XML_m
, XML_bar
);
198 m_pSerializer
->startElementNS( XML_m
, XML_borderBox
, FSEND
);
199 m_pSerializer
->startElementNS( XML_m
, XML_borderBoxPr
, FSEND
);
200 m_pSerializer
->singleElementNS( XML_m
, XML_hideTop
, FSNS( XML_m
, XML_val
), "1", FSEND
);
201 m_pSerializer
->singleElementNS( XML_m
, XML_hideBot
, FSNS( XML_m
, XML_val
), "1", FSEND
);
202 m_pSerializer
->singleElementNS( XML_m
, XML_hideLeft
, FSNS( XML_m
, XML_val
), "1", FSEND
);
203 m_pSerializer
->singleElementNS( XML_m
, XML_hideRight
, FSNS( XML_m
, XML_val
), "1", FSEND
);
204 m_pSerializer
->singleElementNS( XML_m
, XML_strikeH
, FSNS( XML_m
, XML_val
), "1", FSEND
);
205 m_pSerializer
->endElementNS( XML_m
, XML_borderBoxPr
);
206 m_pSerializer
->startElementNS( XML_m
, XML_e
, FSEND
);
207 HandleNode( pNode
->Body(), nLevel
+ 1 );
208 m_pSerializer
->endElementNS( XML_m
, XML_e
);
209 m_pSerializer
->endElementNS( XML_m
, XML_borderBox
);
212 HandleAllSubNodes( pNode
, nLevel
);
217 void SmOoxmlExport::HandleRoot( const SmRootNode
* pNode
, int nLevel
)
219 m_pSerializer
->startElementNS( XML_m
, XML_rad
, FSEND
);
220 if( const SmNode
* argument
= pNode
->Argument())
222 m_pSerializer
->startElementNS( XML_m
, XML_deg
, FSEND
);
223 HandleNode( argument
, nLevel
+ 1 );
224 m_pSerializer
->endElementNS( XML_m
, XML_deg
);
228 m_pSerializer
->startElementNS( XML_m
, XML_radPr
, FSEND
);
229 m_pSerializer
->singleElementNS( XML_m
, XML_degHide
, FSNS( XML_m
, XML_val
), "1", FSEND
);
230 m_pSerializer
->endElementNS( XML_m
, XML_radPr
);
231 m_pSerializer
->singleElementNS( XML_m
, XML_deg
, FSEND
); // empty but present
233 m_pSerializer
->startElementNS( XML_m
, XML_e
, FSEND
);
234 HandleNode( pNode
->Body(), nLevel
+ 1 );
235 m_pSerializer
->endElementNS( XML_m
, XML_e
);
236 m_pSerializer
->endElementNS( XML_m
, XML_rad
);
239 static OString
mathSymbolToString( const SmNode
* node
)
241 assert( node
->GetType() == NMATH
|| node
->GetType() == NMATHIDENT
);
242 const SmTextNode
* txtnode
= static_cast< const SmTextNode
* >( node
);
243 assert( txtnode
->GetText().getLength() == 1 );
244 sal_Unicode chr
= SmTextNode::ConvertSymbolToUnicode( txtnode
->GetText()[0] );
245 return OUStringToOString( OUString( chr
), RTL_TEXTENCODING_UTF8
);
248 void SmOoxmlExport::HandleOperator( const SmOperNode
* pNode
, int nLevel
)
250 SAL_INFO( "starmath.ooxml", "Operator: " << int( pNode
->GetToken().eType
));
251 switch( pNode
->GetToken().eType
)
264 const SmSubSupNode
* subsup
= pNode
->GetSubNode( 0 )->GetType() == NSUBSUP
265 ? static_cast< const SmSubSupNode
* >( pNode
->GetSubNode( 0 )) : nullptr;
266 const SmNode
* operation
= subsup
!= nullptr ? subsup
->GetBody() : pNode
->GetSubNode( 0 );
267 m_pSerializer
->startElementNS( XML_m
, XML_nary
, FSEND
);
268 m_pSerializer
->startElementNS( XML_m
, XML_naryPr
, FSEND
);
269 m_pSerializer
->singleElementNS( XML_m
, XML_chr
,
270 FSNS( XML_m
, XML_val
), mathSymbolToString( operation
).getStr(), FSEND
);
271 if( subsup
== nullptr || subsup
->GetSubSup( CSUB
) == nullptr )
272 m_pSerializer
->singleElementNS( XML_m
, XML_subHide
, FSNS( XML_m
, XML_val
), "1", FSEND
);
273 if( subsup
== nullptr || subsup
->GetSubSup( CSUP
) == nullptr )
274 m_pSerializer
->singleElementNS( XML_m
, XML_supHide
, FSNS( XML_m
, XML_val
), "1", FSEND
);
275 m_pSerializer
->endElementNS( XML_m
, XML_naryPr
);
276 if( subsup
== nullptr || subsup
->GetSubSup( CSUB
) == nullptr )
277 m_pSerializer
->singleElementNS( XML_m
, XML_sub
, FSEND
);
280 m_pSerializer
->startElementNS( XML_m
, XML_sub
, FSEND
);
281 HandleNode( subsup
->GetSubSup( CSUB
), nLevel
+ 1 );
282 m_pSerializer
->endElementNS( XML_m
, XML_sub
);
284 if( subsup
== nullptr || subsup
->GetSubSup( CSUP
) == nullptr )
285 m_pSerializer
->singleElementNS( XML_m
, XML_sup
, FSEND
);
288 m_pSerializer
->startElementNS( XML_m
, XML_sup
, FSEND
);
289 HandleNode( subsup
->GetSubSup( CSUP
), nLevel
+ 1 );
290 m_pSerializer
->endElementNS( XML_m
, XML_sup
);
292 m_pSerializer
->startElementNS( XML_m
, XML_e
, FSEND
);
293 HandleNode( pNode
->GetSubNode( 1 ), nLevel
+ 1 ); // body
294 m_pSerializer
->endElementNS( XML_m
, XML_e
);
295 m_pSerializer
->endElementNS( XML_m
, XML_nary
);
299 m_pSerializer
->startElementNS( XML_m
, XML_func
, FSEND
);
300 m_pSerializer
->startElementNS( XML_m
, XML_fName
, FSEND
);
301 m_pSerializer
->startElementNS( XML_m
, XML_limLow
, FSEND
);
302 m_pSerializer
->startElementNS( XML_m
, XML_e
, FSEND
);
303 HandleNode( pNode
->GetSymbol(), nLevel
+ 1 );
304 m_pSerializer
->endElementNS( XML_m
, XML_e
);
305 m_pSerializer
->startElementNS( XML_m
, XML_lim
, FSEND
);
306 if( const SmSubSupNode
* subsup
= pNode
->GetSubNode( 0 )->GetType() == NSUBSUP
307 ? static_cast< const SmSubSupNode
* >( pNode
->GetSubNode( 0 )) : nullptr )
309 if( subsup
->GetSubSup( CSUB
) != nullptr )
310 HandleNode( subsup
->GetSubSup( CSUB
), nLevel
+ 1 );
312 m_pSerializer
->endElementNS( XML_m
, XML_lim
);
313 m_pSerializer
->endElementNS( XML_m
, XML_limLow
);
314 m_pSerializer
->endElementNS( XML_m
, XML_fName
);
315 m_pSerializer
->startElementNS( XML_m
, XML_e
, FSEND
);
316 HandleNode( pNode
->GetSubNode( 1 ), nLevel
+ 1 ); // body
317 m_pSerializer
->endElementNS( XML_m
, XML_e
);
318 m_pSerializer
->endElementNS( XML_m
, XML_func
);
321 SAL_WARN("starmath.ooxml", "Unhandled operation");
322 HandleAllSubNodes( pNode
, nLevel
);
327 void SmOoxmlExport::HandleSubSupScriptInternal( const SmSubSupNode
* pNode
, int nLevel
, int flags
)
329 // docx supports only a certain combination of sub/super scripts, but LO can have any,
330 // so try to merge it using several tags if necessary
331 if( flags
== 0 ) // none
333 if(( flags
& ( 1 << RSUP
| 1 << RSUB
)) == ( 1 << RSUP
| 1 << RSUB
))
335 m_pSerializer
->startElementNS( XML_m
, XML_sSubSup
, FSEND
);
336 m_pSerializer
->startElementNS( XML_m
, XML_e
, FSEND
);
337 flags
&= ~( 1 << RSUP
| 1 << RSUB
);
339 HandleNode( pNode
->GetBody(), nLevel
+ 1 );
341 HandleSubSupScriptInternal( pNode
, nLevel
, flags
);
342 m_pSerializer
->endElementNS( XML_m
, XML_e
);
343 m_pSerializer
->startElementNS( XML_m
, XML_sub
, FSEND
);
344 HandleNode( pNode
->GetSubSup( RSUB
), nLevel
+ 1 );
345 m_pSerializer
->endElementNS( XML_m
, XML_sub
);
346 m_pSerializer
->startElementNS( XML_m
, XML_sup
, FSEND
);
347 HandleNode( pNode
->GetSubSup( RSUP
), nLevel
+ 1 );
348 m_pSerializer
->endElementNS( XML_m
, XML_sup
);
349 m_pSerializer
->endElementNS( XML_m
, XML_sSubSup
);
351 else if(( flags
& ( 1 << RSUB
)) == 1 << RSUB
)
353 m_pSerializer
->startElementNS( XML_m
, XML_sSub
, FSEND
);
354 m_pSerializer
->startElementNS( XML_m
, XML_e
, FSEND
);
355 flags
&= ~( 1 << RSUB
);
357 HandleNode( pNode
->GetBody(), nLevel
+ 1 );
359 HandleSubSupScriptInternal( pNode
, nLevel
, flags
);
360 m_pSerializer
->endElementNS( XML_m
, XML_e
);
361 m_pSerializer
->startElementNS( XML_m
, XML_sub
, FSEND
);
362 HandleNode( pNode
->GetSubSup( RSUB
), nLevel
+ 1 );
363 m_pSerializer
->endElementNS( XML_m
, XML_sub
);
364 m_pSerializer
->endElementNS( XML_m
, XML_sSub
);
366 else if(( flags
& ( 1 << RSUP
)) == 1 << RSUP
)
368 m_pSerializer
->startElementNS( XML_m
, XML_sSup
, FSEND
);
369 m_pSerializer
->startElementNS( XML_m
, XML_e
, FSEND
);
370 flags
&= ~( 1 << RSUP
);
372 HandleNode( pNode
->GetBody(), nLevel
+ 1 );
374 HandleSubSupScriptInternal( pNode
, nLevel
, flags
);
375 m_pSerializer
->endElementNS( XML_m
, XML_e
);
376 m_pSerializer
->startElementNS( XML_m
, XML_sup
, FSEND
);
377 HandleNode( pNode
->GetSubSup( RSUP
), nLevel
+ 1 );
378 m_pSerializer
->endElementNS( XML_m
, XML_sup
);
379 m_pSerializer
->endElementNS( XML_m
, XML_sSup
);
381 else if(( flags
& ( 1 << LSUP
| 1 << LSUB
)) == ( 1 << LSUP
| 1 << LSUB
))
383 m_pSerializer
->startElementNS( XML_m
, XML_sPre
, FSEND
);
384 m_pSerializer
->startElementNS( XML_m
, XML_sub
, FSEND
);
385 HandleNode( pNode
->GetSubSup( LSUB
), nLevel
+ 1 );
386 m_pSerializer
->endElementNS( XML_m
, XML_sub
);
387 m_pSerializer
->startElementNS( XML_m
, XML_sup
, FSEND
);
388 HandleNode( pNode
->GetSubSup( LSUP
), nLevel
+ 1 );
389 m_pSerializer
->endElementNS( XML_m
, XML_sup
);
390 m_pSerializer
->startElementNS( XML_m
, XML_e
, FSEND
);
391 flags
&= ~( 1 << LSUP
| 1 << LSUB
);
393 HandleNode( pNode
->GetBody(), nLevel
+ 1 );
395 HandleSubSupScriptInternal( pNode
, nLevel
, flags
);
396 m_pSerializer
->endElementNS( XML_m
, XML_e
);
397 m_pSerializer
->endElementNS( XML_m
, XML_sPre
);
399 else if(( flags
& ( 1 << CSUB
)) == ( 1 << CSUB
))
400 { // m:limLow looks like a good element for central superscript
401 m_pSerializer
->startElementNS( XML_m
, XML_limLow
, FSEND
);
402 m_pSerializer
->startElementNS( XML_m
, XML_e
, FSEND
);
403 flags
&= ~( 1 << CSUB
);
405 HandleNode( pNode
->GetBody(), nLevel
+ 1 );
407 HandleSubSupScriptInternal( pNode
, nLevel
, flags
);
408 m_pSerializer
->endElementNS( XML_m
, XML_e
);
409 m_pSerializer
->startElementNS( XML_m
, XML_lim
, FSEND
);
410 HandleNode( pNode
->GetSubSup( CSUB
), nLevel
+ 1 );
411 m_pSerializer
->endElementNS( XML_m
, XML_lim
);
412 m_pSerializer
->endElementNS( XML_m
, XML_limLow
);
414 else if(( flags
& ( 1 << CSUP
)) == ( 1 << CSUP
))
415 { // m:limUpp looks like a good element for central superscript
416 m_pSerializer
->startElementNS( XML_m
, XML_limUpp
, FSEND
);
417 m_pSerializer
->startElementNS( XML_m
, XML_e
, FSEND
);
418 flags
&= ~( 1 << CSUP
);
420 HandleNode( pNode
->GetBody(), nLevel
+ 1 );
422 HandleSubSupScriptInternal( pNode
, nLevel
, flags
);
423 m_pSerializer
->endElementNS( XML_m
, XML_e
);
424 m_pSerializer
->startElementNS( XML_m
, XML_lim
, FSEND
);
425 HandleNode( pNode
->GetSubSup( CSUP
), nLevel
+ 1 );
426 m_pSerializer
->endElementNS( XML_m
, XML_lim
);
427 m_pSerializer
->endElementNS( XML_m
, XML_limUpp
);
431 SAL_WARN("starmath.ooxml", "Unhandled sub/sup combination");
432 // TODO do not do anything, this should be probably an assert()
433 // HandleAllSubNodes( pNode, nLevel );
437 void SmOoxmlExport::HandleMatrix( const SmMatrixNode
* pNode
, int nLevel
)
439 m_pSerializer
->startElementNS( XML_m
, XML_m
, FSEND
);
440 for( int row
= 0; row
< pNode
->GetNumRows(); ++row
)
442 m_pSerializer
->startElementNS( XML_m
, XML_mr
, FSEND
);
443 for( int col
= 0; col
< pNode
->GetNumCols(); ++col
)
445 m_pSerializer
->startElementNS( XML_m
, XML_e
, FSEND
);
446 if( const SmNode
* node
= pNode
->GetSubNode( row
* pNode
->GetNumCols() + col
))
447 HandleNode( node
, nLevel
+ 1 );
448 m_pSerializer
->endElementNS( XML_m
, XML_e
);
450 m_pSerializer
->endElementNS( XML_m
, XML_mr
);
452 m_pSerializer
->endElementNS( XML_m
, XML_m
);
455 void SmOoxmlExport::HandleBrace( const SmBraceNode
* pNode
, int nLevel
)
457 m_pSerializer
->startElementNS( XML_m
, XML_d
, FSEND
);
458 m_pSerializer
->startElementNS( XML_m
, XML_dPr
, FSEND
);
460 //check if the node has an opening brace
461 if( TNONE
== pNode
->OpeningBrace()->GetToken().eType
)
462 m_pSerializer
->singleElementNS( XML_m
, XML_begChr
,
463 FSNS( XML_m
, XML_val
), "", FSEND
);
465 m_pSerializer
->singleElementNS( XML_m
, XML_begChr
,
466 FSNS( XML_m
, XML_val
), mathSymbolToString( pNode
->OpeningBrace()).getStr(), FSEND
);
468 std::vector
< const SmNode
* > subnodes
;
469 if( pNode
->Body()->GetType() == NBRACEBODY
)
471 const SmBracebodyNode
* body
= static_cast< const SmBracebodyNode
* >( pNode
->Body());
472 bool separatorWritten
= false; // assume all separators are the same
473 for( int i
= 0; i
< body
->GetNumSubNodes(); ++i
)
475 const SmNode
* subnode
= body
->GetSubNode( i
);
476 if (subnode
->GetType() == NMATH
|| subnode
->GetType() == NMATHIDENT
)
477 { // do not write, but write what separator it is
478 const SmMathSymbolNode
* math
= static_cast< const SmMathSymbolNode
* >( subnode
);
479 if( !separatorWritten
)
481 m_pSerializer
->singleElementNS( XML_m
, XML_sepChr
,
482 FSNS( XML_m
, XML_val
), mathSymbolToString( math
).getStr(), FSEND
);
483 separatorWritten
= true;
487 subnodes
.push_back( subnode
);
491 subnodes
.push_back( pNode
->Body());
493 if( TNONE
== pNode
->ClosingBrace()->GetToken().eType
)
494 m_pSerializer
->singleElementNS( XML_m
, XML_endChr
,
495 FSNS( XML_m
, XML_val
), "", FSEND
);
497 m_pSerializer
->singleElementNS( XML_m
, XML_endChr
,
498 FSNS( XML_m
, XML_val
), mathSymbolToString( pNode
->ClosingBrace()).getStr(), FSEND
);
500 m_pSerializer
->endElementNS( XML_m
, XML_dPr
);
501 for(const SmNode
* subnode
: subnodes
)
503 m_pSerializer
->startElementNS( XML_m
, XML_e
, FSEND
);
504 HandleNode( subnode
, nLevel
+ 1 );
505 m_pSerializer
->endElementNS( XML_m
, XML_e
);
507 m_pSerializer
->endElementNS( XML_m
, XML_d
);
510 void SmOoxmlExport::HandleVerticalBrace( const SmVerticalBraceNode
* pNode
, int nLevel
)
512 SAL_INFO( "starmath.ooxml", "Vertical: " << int( pNode
->GetToken().eType
));
513 switch( pNode
->GetToken().eType
)
518 bool top
= ( pNode
->GetToken().eType
== TOVERBRACE
);
519 m_pSerializer
->startElementNS( XML_m
, top
? XML_limUpp
: XML_limLow
, FSEND
);
520 m_pSerializer
->startElementNS( XML_m
, XML_e
, FSEND
);
521 m_pSerializer
->startElementNS( XML_m
, XML_groupChr
, FSEND
);
522 m_pSerializer
->startElementNS( XML_m
, XML_groupChrPr
, FSEND
);
523 m_pSerializer
->singleElementNS( XML_m
, XML_chr
,
524 FSNS( XML_m
, XML_val
), mathSymbolToString( pNode
->Brace()).getStr(), FSEND
);
525 // TODO not sure if pos and vertJc are correct
526 m_pSerializer
->singleElementNS( XML_m
, XML_pos
,
527 FSNS( XML_m
, XML_val
), top
? "top" : "bot", FSEND
);
528 m_pSerializer
->singleElementNS( XML_m
, XML_vertJc
, FSNS( XML_m
, XML_val
), top
? "bot" : "top", FSEND
);
529 m_pSerializer
->endElementNS( XML_m
, XML_groupChrPr
);
530 m_pSerializer
->startElementNS( XML_m
, XML_e
, FSEND
);
531 HandleNode( pNode
->Body(), nLevel
+ 1 );
532 m_pSerializer
->endElementNS( XML_m
, XML_e
);
533 m_pSerializer
->endElementNS( XML_m
, XML_groupChr
);
534 m_pSerializer
->endElementNS( XML_m
, XML_e
);
535 m_pSerializer
->startElementNS( XML_m
, XML_lim
, FSEND
);
536 HandleNode( pNode
->Script(), nLevel
+ 1 );
537 m_pSerializer
->endElementNS( XML_m
, XML_lim
);
538 m_pSerializer
->endElementNS( XML_m
, top
? XML_limUpp
: XML_limLow
);
542 SAL_WARN("starmath.ooxml", "Unhandled vertical brace");
543 HandleAllSubNodes( pNode
, nLevel
);
548 void SmOoxmlExport::HandleBlank()
550 m_pSerializer
->startElementNS( XML_m
, XML_r
, FSEND
);
551 m_pSerializer
->startElementNS( XML_m
, XML_t
, FSNS( XML_xml
, XML_space
), "preserve", FSEND
);
552 m_pSerializer
->write( " " );
553 m_pSerializer
->endElementNS( XML_m
, XML_t
);
554 m_pSerializer
->endElementNS( XML_m
, XML_r
);
557 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */