Bump version to 5.0-14
[LibreOffice.git] / starmath / source / ooxmlexport.cxx
blob9cccd7431a21616bfd1cd54040b828f3bd8a839f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
11 #include "ooxmlexport.hxx"
13 #include <oox/token/tokens.hxx>
14 #include <rtl/ustring.hxx>
16 using namespace oox;
17 using namespace oox::core;
19 SmOoxmlExport::SmOoxmlExport( const SmNode* pIn, OoxmlVersion v )
20 : SmWordExportBase( pIn )
21 , version( v )
25 bool SmOoxmlExport::ConvertFromStarMath( ::sax_fastparser::FSHelperPtr serializer )
27 if( m_pTree == NULL )
28 return false;
29 m_pSerializer = serializer;
30 m_pSerializer->startElementNS( XML_m, XML_oMath,
31 FSNS( XML_xmlns, XML_m ), "http://schemas.openxmlformats.org/officeDocument/2006/math", FSEND );
32 HandleNode( m_pTree, 0 );
33 m_pSerializer->endElementNS( XML_m, XML_oMath );
34 return true;
37 // NOTE: This is still work in progress and unfinished, but it already covers a good
38 // part of the ooxml math stuff.
40 void SmOoxmlExport::HandleVerticalStack( const SmNode* pNode, int nLevel )
42 m_pSerializer->startElementNS( XML_m, XML_eqArr, FSEND );
43 int size = pNode->GetNumSubNodes();
44 for( int i = 0;
45 i < size;
46 ++i )
48 m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
49 HandleNode( pNode->GetSubNode( i ), nLevel + 1 );
50 m_pSerializer->endElementNS( XML_m, XML_e );
52 m_pSerializer->endElementNS( XML_m, XML_eqArr );
55 void SmOoxmlExport::HandleText( const SmNode* pNode, int /*nLevel*/)
57 m_pSerializer->startElementNS( XML_m, XML_r, FSEND );
59 if( pNode->GetToken().eType == TTEXT ) // literal text (in quotes)
61 m_pSerializer->startElementNS( XML_m, XML_rPr, FSEND );
62 m_pSerializer->singleElementNS( XML_m, XML_lit, FSEND );
63 m_pSerializer->singleElementNS( XML_m, XML_nor, FSEND );
64 m_pSerializer->endElementNS( XML_m, XML_rPr );
66 if( version == ECMA_DIALECT )
67 { // HACK: MSOffice2007 does not import characters properly unless this font is explicitly given
68 m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
69 m_pSerializer->singleElementNS( XML_w, XML_rFonts, FSNS( XML_w, XML_ascii ), "Cambria Math",
70 FSNS( XML_w, XML_hAnsi ), "Cambria Math", FSEND );
71 m_pSerializer->endElementNS( XML_w, XML_rPr );
73 m_pSerializer->startElementNS( XML_m, XML_t, FSNS( XML_xml, XML_space ), "preserve", FSEND );
74 const SmTextNode* pTemp = static_cast<const SmTextNode* >(pNode);
75 SAL_INFO( "starmath.ooxml", "Text:" << OUStringToOString( pTemp->GetText(), RTL_TEXTENCODING_UTF8 ).getStr());
76 for(sal_Int32 i=0;i<pTemp->GetText().getLength();i++)
78 #if 0
79 if ((nPendingAttributes) &&
80 (i == ((pTemp->GetText().getLength()+1)/2)-1))
82 *pS << sal_uInt8(0x22); //char, with attributes right
83 //after the character
85 else
86 *pS << sal_uInt8(CHAR);
88 sal_uInt8 nFace = 0x1;
89 if (pNode->GetFont().GetItalic() == ITALIC_NORMAL)
90 nFace = 0x3;
91 else if (pNode->GetFont().GetWeight() == WEIGHT_BOLD)
92 nFace = 0x7;
93 *pS << sal_uInt8(nFace+128); //typeface
94 #endif
95 sal_uInt16 nChar = pTemp->GetText()[i];
96 m_pSerializer->writeEscaped( OUString( SmTextNode::ConvertSymbolToUnicode(nChar)));
98 #if 0
99 //Mathtype can only have these sort of character
100 //attributes on a single character, starmath can put them
101 //anywhere, when the entity involved is a text run this is
102 //a large effort to place the character attribute on the
103 //central mathtype character so that it does pretty much
104 //what the user probably has in mind. The attributes
105 //filled in here are dummy ones which are replaced in the
106 //ATTRIBUT handler if a suitable location for the
107 //attributes was found here. Unfortunately it is
108 //possible for starmath to place character attributes on
109 //entities which cannot occur in mathtype e.g. a Summation
110 //symbol so these attributes may be lost
111 if ((nPendingAttributes) &&
112 (i == ((pTemp->GetText().getLength()+1)/2)-1))
114 *pS << sal_uInt8(EMBEL);
115 while (nPendingAttributes)
117 *pS << sal_uInt8(2);
118 //wedge the attributes in here and clear
119 //the pending stack
120 nPendingAttributes--;
122 nInsertion=pS->Tell();
123 *pS << sal_uInt8(END); //end embel
124 *pS << sal_uInt8(END); //end embel
126 #endif
128 m_pSerializer->endElementNS( XML_m, XML_t );
129 m_pSerializer->endElementNS( XML_m, XML_r );
132 void SmOoxmlExport::HandleFractions( const SmNode* pNode, int nLevel, const char* type )
134 m_pSerializer->startElementNS( XML_m, XML_f, FSEND );
135 if( type != NULL )
137 m_pSerializer->startElementNS( XML_m, XML_fPr, FSEND );
138 m_pSerializer->singleElementNS( XML_m, XML_type, FSNS( XML_m, XML_val ), type, FSEND );
139 m_pSerializer->endElementNS( XML_m, XML_fPr );
141 OSL_ASSERT( pNode->GetNumSubNodes() == 3 );
142 m_pSerializer->startElementNS( XML_m, XML_num, FSEND );
143 HandleNode( pNode->GetSubNode( 0 ), nLevel + 1 );
144 m_pSerializer->endElementNS( XML_m, XML_num );
145 m_pSerializer->startElementNS( XML_m, XML_den, FSEND );
146 HandleNode( pNode->GetSubNode( 2 ), nLevel + 1 );
147 m_pSerializer->endElementNS( XML_m, XML_den );
148 m_pSerializer->endElementNS( XML_m, XML_f );
151 void SmOoxmlExport::HandleAttribute( const SmAttributNode* pNode, int nLevel )
153 switch( pNode->Attribute()->GetToken().eType )
155 case TCHECK:
156 case TACUTE:
157 case TGRAVE:
158 case TBREVE:
159 case TCIRCLE:
160 case TVEC:
161 case TTILDE:
162 case THAT:
163 case TDOT:
164 case TDDOT:
165 case TDDDOT:
166 case TWIDETILDE:
167 case TWIDEHAT:
168 case TWIDEVEC:
169 case TBAR:
171 m_pSerializer->startElementNS( XML_m, XML_acc, FSEND );
172 m_pSerializer->startElementNS( XML_m, XML_accPr, FSEND );
173 OString value = OUStringToOString(
174 OUString( pNode->Attribute()->GetToken().cMathChar ), RTL_TEXTENCODING_UTF8 );
175 m_pSerializer->singleElementNS( XML_m, XML_chr, FSNS( XML_m, XML_val ), value.getStr(), FSEND );
176 m_pSerializer->endElementNS( XML_m, XML_accPr );
177 m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
178 HandleNode( pNode->Body(), nLevel + 1 );
179 m_pSerializer->endElementNS( XML_m, XML_e );
180 m_pSerializer->endElementNS( XML_m, XML_acc );
181 break;
183 case TOVERLINE:
184 case TUNDERLINE:
185 m_pSerializer->startElementNS( XML_m, XML_bar, FSEND );
186 m_pSerializer->startElementNS( XML_m, XML_barPr, FSEND );
187 m_pSerializer->singleElementNS( XML_m, XML_pos, FSNS( XML_m, XML_val ),
188 ( pNode->Attribute()->GetToken().eType == TUNDERLINE ) ? "bot" : "top", FSEND );
189 m_pSerializer->endElementNS( XML_m, XML_barPr );
190 m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
191 HandleNode( pNode->Body(), nLevel + 1 );
192 m_pSerializer->endElementNS( XML_m, XML_e );
193 m_pSerializer->endElementNS( XML_m, XML_bar );
194 break;
195 case TOVERSTRIKE:
196 m_pSerializer->startElementNS( XML_m, XML_borderBox, FSEND );
197 m_pSerializer->startElementNS( XML_m, XML_borderBoxPr, FSEND );
198 m_pSerializer->singleElementNS( XML_m, XML_hideTop, FSNS( XML_m, XML_val ), "1", FSEND );
199 m_pSerializer->singleElementNS( XML_m, XML_hideBot, FSNS( XML_m, XML_val ), "1", FSEND );
200 m_pSerializer->singleElementNS( XML_m, XML_hideLeft, FSNS( XML_m, XML_val ), "1", FSEND );
201 m_pSerializer->singleElementNS( XML_m, XML_hideRight, FSNS( XML_m, XML_val ), "1", FSEND );
202 m_pSerializer->singleElementNS( XML_m, XML_strikeH, FSNS( XML_m, XML_val ), "1", FSEND );
203 m_pSerializer->endElementNS( XML_m, XML_borderBoxPr );
204 m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
205 HandleNode( pNode->Body(), nLevel + 1 );
206 m_pSerializer->endElementNS( XML_m, XML_e );
207 m_pSerializer->endElementNS( XML_m, XML_borderBox );
208 break;
209 default:
210 HandleAllSubNodes( pNode, nLevel );
211 break;
215 void SmOoxmlExport::HandleRoot( const SmRootNode* pNode, int nLevel )
217 m_pSerializer->startElementNS( XML_m, XML_rad, FSEND );
218 if( const SmNode* argument = pNode->Argument())
220 m_pSerializer->startElementNS( XML_m, XML_deg, FSEND );
221 HandleNode( argument, nLevel + 1 );
222 m_pSerializer->endElementNS( XML_m, XML_deg );
224 else
226 m_pSerializer->startElementNS( XML_m, XML_radPr, FSEND );
227 m_pSerializer->singleElementNS( XML_m, XML_degHide, FSNS( XML_m, XML_val ), "1", FSEND );
228 m_pSerializer->endElementNS( XML_m, XML_radPr );
229 m_pSerializer->singleElementNS( XML_m, XML_deg, FSEND ); // empty but present
231 m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
232 HandleNode( pNode->Body(), nLevel + 1 );
233 m_pSerializer->endElementNS( XML_m, XML_e );
234 m_pSerializer->endElementNS( XML_m, XML_rad );
237 static OString mathSymbolToString( const SmNode* node )
239 assert( node->GetType() == NMATH || node->GetType() == NMATHIDENT );
240 const SmTextNode* txtnode = static_cast< const SmTextNode* >( node );
241 assert( txtnode->GetText().getLength() == 1 );
242 sal_Unicode chr = SmTextNode::ConvertSymbolToUnicode( txtnode->GetText()[0] );
243 return OUStringToOString( OUString( chr ), RTL_TEXTENCODING_UTF8 );
246 void SmOoxmlExport::HandleOperator( const SmOperNode* pNode, int nLevel )
248 SAL_INFO( "starmath.ooxml", "Operator: " << int( pNode->GetToken().eType ));
249 switch( pNode->GetToken().eType )
251 case TINT:
252 case TINTD:
253 case TIINT:
254 case TIIINT:
255 case TLINT:
256 case TLLINT:
257 case TLLLINT:
258 case TPROD:
259 case TCOPROD:
260 case TSUM:
262 const SmSubSupNode* subsup = pNode->GetSubNode( 0 )->GetType() == NSUBSUP
263 ? static_cast< const SmSubSupNode* >( pNode->GetSubNode( 0 )) : NULL;
264 const SmNode* operation = subsup != NULL ? subsup->GetBody() : pNode->GetSubNode( 0 );
265 m_pSerializer->startElementNS( XML_m, XML_nary, FSEND );
266 m_pSerializer->startElementNS( XML_m, XML_naryPr, FSEND );
267 m_pSerializer->singleElementNS( XML_m, XML_chr,
268 FSNS( XML_m, XML_val ), mathSymbolToString( operation ).getStr(), FSEND );
269 if( subsup == NULL || subsup->GetSubSup( CSUB ) == NULL )
270 m_pSerializer->singleElementNS( XML_m, XML_subHide, FSNS( XML_m, XML_val ), "1", FSEND );
271 if( subsup == NULL || subsup->GetSubSup( CSUP ) == NULL )
272 m_pSerializer->singleElementNS( XML_m, XML_supHide, FSNS( XML_m, XML_val ), "1", FSEND );
273 m_pSerializer->endElementNS( XML_m, XML_naryPr );
274 if( subsup == NULL || subsup->GetSubSup( CSUB ) == NULL )
275 m_pSerializer->singleElementNS( XML_m, XML_sub, FSEND );
276 else
278 m_pSerializer->startElementNS( XML_m, XML_sub, FSEND );
279 HandleNode( subsup->GetSubSup( CSUB ), nLevel + 1 );
280 m_pSerializer->endElementNS( XML_m, XML_sub );
282 if( subsup == NULL || subsup->GetSubSup( CSUP ) == NULL )
283 m_pSerializer->singleElementNS( XML_m, XML_sup, FSEND );
284 else
286 m_pSerializer->startElementNS( XML_m, XML_sup, FSEND );
287 HandleNode( subsup->GetSubSup( CSUP ), nLevel + 1 );
288 m_pSerializer->endElementNS( XML_m, XML_sup );
290 m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
291 HandleNode( pNode->GetSubNode( 1 ), nLevel + 1 ); // body
292 m_pSerializer->endElementNS( XML_m, XML_e );
293 m_pSerializer->endElementNS( XML_m, XML_nary );
294 break;
296 case TLIM:
297 m_pSerializer->startElementNS( XML_m, XML_func, FSEND );
298 m_pSerializer->startElementNS( XML_m, XML_fName, FSEND );
299 m_pSerializer->startElementNS( XML_m, XML_limLow, FSEND );
300 m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
301 HandleNode( pNode->GetSymbol(), nLevel + 1 );
302 m_pSerializer->endElementNS( XML_m, XML_e );
303 m_pSerializer->startElementNS( XML_m, XML_lim, FSEND );
304 if( const SmSubSupNode* subsup = pNode->GetSubNode( 0 )->GetType() == NSUBSUP
305 ? static_cast< const SmSubSupNode* >( pNode->GetSubNode( 0 )) : NULL )
307 if( subsup->GetSubSup( CSUB ) != NULL )
308 HandleNode( subsup->GetSubSup( CSUB ), nLevel + 1 );
310 m_pSerializer->endElementNS( XML_m, XML_lim );
311 m_pSerializer->endElementNS( XML_m, XML_limLow );
312 m_pSerializer->endElementNS( XML_m, XML_fName );
313 m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
314 HandleNode( pNode->GetSubNode( 1 ), nLevel + 1 ); // body
315 m_pSerializer->endElementNS( XML_m, XML_e );
316 m_pSerializer->endElementNS( XML_m, XML_func );
317 break;
318 default:
319 SAL_WARN("starmath.ooxml", "Unhandled operation");
320 HandleAllSubNodes( pNode, nLevel );
321 break;
325 void SmOoxmlExport::HandleSubSupScriptInternal( const SmSubSupNode* pNode, int nLevel, int flags )
327 // docx supports only a certain combination of sub/super scripts, but LO can have any,
328 // so try to merge it using several tags if necessary
329 if( flags == 0 ) // none
330 return;
331 if(( flags & ( 1 << RSUP | 1 << RSUB )) == ( 1 << RSUP | 1 << RSUB ))
332 { // m:sSubSup
333 m_pSerializer->startElementNS( XML_m, XML_sSubSup, FSEND );
334 m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
335 flags &= ~( 1 << RSUP | 1 << RSUB );
336 if( flags == 0 )
337 HandleNode( pNode->GetBody(), nLevel + 1 );
338 else
339 HandleSubSupScriptInternal( pNode, nLevel, flags );
340 m_pSerializer->endElementNS( XML_m, XML_e );
341 m_pSerializer->startElementNS( XML_m, XML_sub, FSEND );
342 HandleNode( pNode->GetSubSup( RSUB ), nLevel + 1 );
343 m_pSerializer->endElementNS( XML_m, XML_sub );
344 m_pSerializer->startElementNS( XML_m, XML_sup, FSEND );
345 HandleNode( pNode->GetSubSup( RSUP ), nLevel + 1 );
346 m_pSerializer->endElementNS( XML_m, XML_sup );
347 m_pSerializer->endElementNS( XML_m, XML_sSubSup );
349 else if(( flags & ( 1 << RSUB )) == 1 << RSUB )
350 { // m:sSub
351 m_pSerializer->startElementNS( XML_m, XML_sSub, FSEND );
352 m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
353 flags &= ~( 1 << RSUB );
354 if( flags == 0 )
355 HandleNode( pNode->GetBody(), nLevel + 1 );
356 else
357 HandleSubSupScriptInternal( pNode, nLevel, flags );
358 m_pSerializer->endElementNS( XML_m, XML_e );
359 m_pSerializer->startElementNS( XML_m, XML_sub, FSEND );
360 HandleNode( pNode->GetSubSup( RSUB ), nLevel + 1 );
361 m_pSerializer->endElementNS( XML_m, XML_sub );
362 m_pSerializer->endElementNS( XML_m, XML_sSub );
364 else if(( flags & ( 1 << RSUP )) == 1 << RSUP )
365 { // m:sSup
366 m_pSerializer->startElementNS( XML_m, XML_sSup, FSEND );
367 m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
368 flags &= ~( 1 << RSUP );
369 if( flags == 0 )
370 HandleNode( pNode->GetBody(), nLevel + 1 );
371 else
372 HandleSubSupScriptInternal( pNode, nLevel, flags );
373 m_pSerializer->endElementNS( XML_m, XML_e );
374 m_pSerializer->startElementNS( XML_m, XML_sup, FSEND );
375 HandleNode( pNode->GetSubSup( RSUP ), nLevel + 1 );
376 m_pSerializer->endElementNS( XML_m, XML_sup );
377 m_pSerializer->endElementNS( XML_m, XML_sSup );
379 else if(( flags & ( 1 << LSUP | 1 << LSUB )) == ( 1 << LSUP | 1 << LSUB ))
380 { // m:sPre
381 m_pSerializer->startElementNS( XML_m, XML_sPre, FSEND );
382 m_pSerializer->startElementNS( XML_m, XML_sub, FSEND );
383 HandleNode( pNode->GetSubSup( LSUB ), nLevel + 1 );
384 m_pSerializer->endElementNS( XML_m, XML_sub );
385 m_pSerializer->startElementNS( XML_m, XML_sup, FSEND );
386 HandleNode( pNode->GetSubSup( LSUP ), nLevel + 1 );
387 m_pSerializer->endElementNS( XML_m, XML_sup );
388 m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
389 flags &= ~( 1 << LSUP | 1 << LSUB );
390 if( flags == 0 )
391 HandleNode( pNode->GetBody(), nLevel + 1 );
392 else
393 HandleSubSupScriptInternal( pNode, nLevel, flags );
394 m_pSerializer->endElementNS( XML_m, XML_e );
395 m_pSerializer->endElementNS( XML_m, XML_sPre );
397 else if(( flags & ( 1 << CSUB )) == ( 1 << CSUB ))
398 { // m:limLow looks like a good element for central superscript
399 m_pSerializer->startElementNS( XML_m, XML_limLow, FSEND );
400 m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
401 flags &= ~( 1 << CSUB );
402 if( flags == 0 )
403 HandleNode( pNode->GetBody(), nLevel + 1 );
404 else
405 HandleSubSupScriptInternal( pNode, nLevel, flags );
406 m_pSerializer->endElementNS( XML_m, XML_e );
407 m_pSerializer->startElementNS( XML_m, XML_lim, FSEND );
408 HandleNode( pNode->GetSubSup( CSUB ), nLevel + 1 );
409 m_pSerializer->endElementNS( XML_m, XML_lim );
410 m_pSerializer->endElementNS( XML_m, XML_limLow );
412 else if(( flags & ( 1 << CSUP )) == ( 1 << CSUP ))
413 { // m:limUpp looks like a good element for central superscript
414 m_pSerializer->startElementNS( XML_m, XML_limUpp, FSEND );
415 m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
416 flags &= ~( 1 << CSUP );
417 if( flags == 0 )
418 HandleNode( pNode->GetBody(), nLevel + 1 );
419 else
420 HandleSubSupScriptInternal( pNode, nLevel, flags );
421 m_pSerializer->endElementNS( XML_m, XML_e );
422 m_pSerializer->startElementNS( XML_m, XML_lim, FSEND );
423 HandleNode( pNode->GetSubSup( CSUP ), nLevel + 1 );
424 m_pSerializer->endElementNS( XML_m, XML_lim );
425 m_pSerializer->endElementNS( XML_m, XML_limUpp );
427 else
429 SAL_WARN("starmath.ooxml", "Unhandled sub/sup combination");
430 // TODO do not do anything, this should be probably an assert()
431 // HandleAllSubNodes( pNode, nLevel );
435 void SmOoxmlExport::HandleMatrix( const SmMatrixNode* pNode, int nLevel )
437 m_pSerializer->startElementNS( XML_m, XML_m, FSEND );
438 for( int row = 0; row < pNode->GetNumRows(); ++row )
440 m_pSerializer->startElementNS( XML_m, XML_mr, FSEND );
441 for( int col = 0; col < pNode->GetNumCols(); ++col )
443 m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
444 if( const SmNode* node = pNode->GetSubNode( row * pNode->GetNumCols() + col ))
445 HandleNode( node, nLevel + 1 );
446 m_pSerializer->endElementNS( XML_m, XML_e );
448 m_pSerializer->endElementNS( XML_m, XML_mr );
450 m_pSerializer->endElementNS( XML_m, XML_m );
453 void SmOoxmlExport::HandleBrace( const SmBraceNode* pNode, int nLevel )
455 m_pSerializer->startElementNS( XML_m, XML_d, FSEND );
456 m_pSerializer->startElementNS( XML_m, XML_dPr, FSEND );
458 //check if the node has an opening brace
459 if( TNONE == pNode->GetSubNode(0)->GetToken().eType )
460 m_pSerializer->singleElementNS( XML_m, XML_begChr,
461 FSNS( XML_m, XML_val ), "", FSEND );
462 else
463 m_pSerializer->singleElementNS( XML_m, XML_begChr,
464 FSNS( XML_m, XML_val ), mathSymbolToString( pNode->OpeningBrace()).getStr(), FSEND );
466 std::vector< const SmNode* > subnodes;
467 if( pNode->Body()->GetType() == NBRACEBODY )
469 const SmBracebodyNode* body = static_cast< const SmBracebodyNode* >( pNode->Body());
470 bool separatorWritten = false; // assume all separators are the same
471 for( int i = 0; i < body->GetNumSubNodes(); ++i )
473 const SmNode* subnode = body->GetSubNode( i );
474 if (subnode->GetType() == NMATH || subnode->GetType() == NMATHIDENT)
475 { // do not write, but write what separator it is
476 const SmMathSymbolNode* math = static_cast< const SmMathSymbolNode* >( subnode );
477 if( !separatorWritten )
479 m_pSerializer->singleElementNS( XML_m, XML_sepChr,
480 FSNS( XML_m, XML_val ), mathSymbolToString( math ).getStr(), FSEND );
481 separatorWritten = true;
484 else
485 subnodes.push_back( subnode );
488 else
489 subnodes.push_back( pNode->Body());
491 if( TNONE == pNode->GetSubNode(2)->GetToken().eType )
492 m_pSerializer->singleElementNS( XML_m, XML_endChr,
493 FSNS( XML_m, XML_val ), "", FSEND );
494 else
495 m_pSerializer->singleElementNS( XML_m, XML_endChr,
496 FSNS( XML_m, XML_val ), mathSymbolToString( pNode->ClosingBrace()).getStr(), FSEND );
498 m_pSerializer->endElementNS( XML_m, XML_dPr );
499 for( unsigned int i = 0; i < subnodes.size(); ++i )
501 m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
502 HandleNode( subnodes[ i ], nLevel + 1 );
503 m_pSerializer->endElementNS( XML_m, XML_e );
505 m_pSerializer->endElementNS( XML_m, XML_d );
508 void SmOoxmlExport::HandleVerticalBrace( const SmVerticalBraceNode* pNode, int nLevel )
510 SAL_INFO( "starmath.ooxml", "Vertical: " << int( pNode->GetToken().eType ));
511 switch( pNode->GetToken().eType )
513 case TOVERBRACE:
514 case TUNDERBRACE:
516 bool top = ( pNode->GetToken().eType == TOVERBRACE );
517 m_pSerializer->startElementNS( XML_m, top ? XML_limUpp : XML_limLow, FSEND );
518 m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
519 m_pSerializer->startElementNS( XML_m, XML_groupChr, FSEND );
520 m_pSerializer->startElementNS( XML_m, XML_groupChrPr, FSEND );
521 m_pSerializer->singleElementNS( XML_m, XML_chr,
522 FSNS( XML_m, XML_val ), mathSymbolToString( pNode->Brace()).getStr(), FSEND );
523 // TODO not sure if pos and vertJc are correct
524 m_pSerializer->singleElementNS( XML_m, XML_pos,
525 FSNS( XML_m, XML_val ), top ? "top" : "bot", FSEND );
526 m_pSerializer->singleElementNS( XML_m, XML_vertJc, FSNS( XML_m, XML_val ), top ? "bot" : "top", FSEND );
527 m_pSerializer->endElementNS( XML_m, XML_groupChrPr );
528 m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
529 HandleNode( pNode->Body(), nLevel + 1 );
530 m_pSerializer->endElementNS( XML_m, XML_e );
531 m_pSerializer->endElementNS( XML_m, XML_groupChr );
532 m_pSerializer->endElementNS( XML_m, XML_e );
533 m_pSerializer->startElementNS( XML_m, XML_lim, FSEND );
534 HandleNode( pNode->Script(), nLevel + 1 );
535 m_pSerializer->endElementNS( XML_m, XML_lim );
536 m_pSerializer->endElementNS( XML_m, top ? XML_limUpp : XML_limLow );
537 break;
539 default:
540 SAL_WARN("starmath.ooxml", "Unhandled vertical brace");
541 HandleAllSubNodes( pNode, nLevel );
542 break;
546 void SmOoxmlExport::HandleBlank()
548 m_pSerializer->startElementNS( XML_m, XML_r, FSEND );
549 m_pSerializer->startElementNS( XML_m, XML_t, FSNS( XML_xml, XML_space ), "preserve", FSEND );
550 m_pSerializer->write( " " );
551 m_pSerializer->endElementNS( XML_m, XML_t );
552 m_pSerializer->endElementNS( XML_m, XML_r );
555 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */