tdf#130857 qt weld: Support mail merge "Server Auth" dialog
[LibreOffice.git] / starmath / source / ooxmlexport.cxx
blob2956dd9a8142d2e14c3e5e6817260552773de176
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 */
10 #include "ooxmlexport.hxx"
12 #include <oox/token/tokens.hxx>
13 #include <rtl/ustring.hxx>
14 #include <sal/log.hxx>
15 #include <oox/mathml/imexport.hxx>
17 using namespace oox;
18 using namespace oox::core;
20 SmOoxmlExport::SmOoxmlExport(const SmNode *const pIn, OoxmlVersion const v,
21 drawingml::DocumentType const documentType)
22 : SmWordExportBase( pIn )
23 , version( v )
24 , m_DocumentType(documentType)
28 void SmOoxmlExport::ConvertFromStarMath( const ::sax_fastparser::FSHelperPtr& serializer, const sal_Int8 nAlign )
30 if( GetTree() == nullptr )
31 return;
32 m_pSerializer = serializer;
34 //Formula alignment situations:
36 // 1)Inline(as before):
38 // <m:oMath>
39 // <m:r> ... </m:r>
40 // </m:oMath>
42 // 2)Aligned:
44 // <m:oMathPara>
45 // <m:oMathParaPr>
46 // <m:jc m:val="left|right|center">
47 // </m:oMathParaPr>
48 // <m:oMath>
49 // <m:r> ... </m:r>
50 // </m:oMath>
51 // </m:oMathPara>
53 if (nAlign != FormulaImExportBase::eFormulaAlign::INLINE)
55 m_pSerializer->startElementNS(XML_m, XML_oMathPara,
56 FSNS(XML_xmlns, XML_m), "http://schemas.openxmlformats.org/officeDocument/2006/math");
57 m_pSerializer->startElementNS(XML_m, XML_oMathParaPr);
58 if (nAlign == FormulaImExportBase::eFormulaAlign::CENTER)
59 m_pSerializer->singleElementNS(XML_m, XML_jc, FSNS(XML_m, XML_val), "center");
60 if (nAlign == FormulaImExportBase::eFormulaAlign::LEFT)
61 m_pSerializer->singleElementNS(XML_m, XML_jc, FSNS(XML_m, XML_val), "left");
62 if (nAlign == FormulaImExportBase::eFormulaAlign::RIGHT)
63 m_pSerializer->singleElementNS(XML_m, XML_jc, FSNS(XML_m, XML_val), "right");
64 m_pSerializer->endElementNS(XML_m, XML_oMathParaPr);
65 m_pSerializer->startElementNS(XML_m, XML_oMath);
66 HandleNode(GetTree(), 0);
67 m_pSerializer->endElementNS(XML_m, XML_oMath);
68 m_pSerializer->endElementNS(XML_m, XML_oMathPara);
70 else //else, inline as was before
72 m_pSerializer->startElementNS(XML_m, XML_oMath,
73 FSNS(XML_xmlns, XML_m), "http://schemas.openxmlformats.org/officeDocument/2006/math");
74 HandleNode( GetTree(), 0 );
75 m_pSerializer->endElementNS( XML_m, XML_oMath );
79 // NOTE: This is still work in progress and unfinished, but it already covers a good
80 // part of the ooxml math stuff.
82 void SmOoxmlExport::HandleVerticalStack( const SmNode* pNode, int nLevel )
84 m_pSerializer->startElementNS(XML_m, XML_eqArr);
85 int size = pNode->GetNumSubNodes();
86 for( int i = 0;
87 i < size;
88 ++i )
90 m_pSerializer->startElementNS(XML_m, XML_e);
91 HandleNode( pNode->GetSubNode( i ), nLevel + 1 );
92 m_pSerializer->endElementNS( XML_m, XML_e );
94 m_pSerializer->endElementNS( XML_m, XML_eqArr );
97 void SmOoxmlExport::HandleText( const SmNode* pNode, int /*nLevel*/)
99 m_pSerializer->startElementNS(XML_m, XML_r);
101 if( pNode->GetToken().eType == TTEXT ) // literal text (in quotes)
103 m_pSerializer->startElementNS(XML_m, XML_rPr);
104 m_pSerializer->singleElementNS(XML_m, XML_lit);
105 m_pSerializer->singleElementNS(XML_m, XML_nor);
106 m_pSerializer->endElementNS( XML_m, XML_rPr );
108 if (drawingml::DOCUMENT_DOCX == m_DocumentType && ECMA_376_1ST_EDITION == version)
109 { // HACK: MSOffice2007 does not import characters properly unless this font is explicitly given
110 m_pSerializer->startElementNS(XML_w, XML_rPr);
111 m_pSerializer->singleElementNS( XML_w, XML_rFonts, FSNS( XML_w, XML_ascii ), "Cambria Math",
112 FSNS( XML_w, XML_hAnsi ), "Cambria Math" );
113 m_pSerializer->endElementNS( XML_w, XML_rPr );
115 m_pSerializer->startElementNS(XML_m, XML_t, FSNS(XML_xml, XML_space), "preserve");
116 const SmTextNode* pTemp = static_cast<const SmTextNode* >(pNode);
117 SAL_INFO( "starmath.ooxml", "Text:" << pTemp->GetText());
118 OUStringBuffer buf(pTemp->GetText());
119 for(sal_Int32 i=0;i<pTemp->GetText().getLength();i++)
121 #if 0
122 if ((nPendingAttributes) &&
123 (i == ((pTemp->GetText().getLength()+1)/2)-1))
125 *pS << sal_uInt8(0x22); //char, with attributes right
126 //after the character
128 else
129 *pS << sal_uInt8(CHAR);
131 sal_uInt8 nFace = 0x1;
132 if (pNode->GetFont().GetItalic() == ITALIC_NORMAL)
133 nFace = 0x3;
134 else if (pNode->GetFont().GetWeight() == WEIGHT_BOLD)
135 nFace = 0x7;
136 *pS << sal_uInt8(nFace+128); //typeface
137 #endif
138 buf[i] = SmTextNode::ConvertSymbolToUnicode(buf[i]);
139 #if 0
140 //Mathtype can only have these sort of character
141 //attributes on a single character, starmath can put them
142 //anywhere, when the entity involved is a text run this is
143 //a large effort to place the character attribute on the
144 //central mathtype character so that it does pretty much
145 //what the user probably has in mind. The attributes
146 //filled in here are dummy ones which are replaced in the
147 //ATTRIBUTE handler if a suitable location for the
148 //attributes was found here. Unfortunately it is
149 //possible for starmath to place character attributes on
150 //entities which cannot occur in mathtype e.g. a Summation
151 //symbol so these attributes may be lost
152 if ((nPendingAttributes) &&
153 (i == ((pTemp->GetText().getLength()+1)/2)-1))
155 *pS << sal_uInt8(EMBEL);
156 while (nPendingAttributes)
158 *pS << sal_uInt8(2);
159 //wedge the attributes in here and clear
160 //the pending stack
161 nPendingAttributes--;
163 nInsertion=pS->Tell();
164 *pS << sal_uInt8(END); //end embel
165 *pS << sal_uInt8(END); //end embel
167 #endif
169 m_pSerializer->writeEscaped(buf);
170 m_pSerializer->endElementNS( XML_m, XML_t );
171 m_pSerializer->endElementNS( XML_m, XML_r );
174 void SmOoxmlExport::HandleFractions( const SmNode* pNode, int nLevel, const char* type )
176 m_pSerializer->startElementNS(XML_m, XML_f);
177 if( type != nullptr )
179 m_pSerializer->startElementNS(XML_m, XML_fPr);
180 m_pSerializer->singleElementNS(XML_m, XML_type, FSNS(XML_m, XML_val), type);
181 m_pSerializer->endElementNS( XML_m, XML_fPr );
183 assert( pNode->GetNumSubNodes() == 3 );
184 m_pSerializer->startElementNS(XML_m, XML_num);
185 HandleNode( pNode->GetSubNode( 0 ), nLevel + 1 );
186 m_pSerializer->endElementNS( XML_m, XML_num );
187 m_pSerializer->startElementNS(XML_m, XML_den);
188 HandleNode( pNode->GetSubNode( 2 ), nLevel + 1 );
189 m_pSerializer->endElementNS( XML_m, XML_den );
190 m_pSerializer->endElementNS( XML_m, XML_f );
193 void SmOoxmlExport::HandleAttribute( const SmAttributeNode* pNode, int nLevel )
195 switch( pNode->Attribute()->GetToken().eType )
197 case TCHECK:
198 case TACUTE:
199 case TGRAVE:
200 case TBREVE:
201 case TCIRCLE:
202 case TVEC:
203 case TTILDE:
204 case THAT:
205 case TDOT:
206 case TDDOT:
207 case TDDDOT:
208 case TWIDETILDE:
209 case TWIDEHAT:
210 case TWIDEHARPOON:
211 case TWIDEVEC:
212 case TBAR:
214 m_pSerializer->startElementNS(XML_m, XML_acc);
215 m_pSerializer->startElementNS(XML_m, XML_accPr);
216 OString value = OUStringToOString(pNode->Attribute()->GetToken().cMathChar, RTL_TEXTENCODING_UTF8 );
217 m_pSerializer->singleElementNS(XML_m, XML_chr, FSNS(XML_m, XML_val), value);
218 m_pSerializer->endElementNS( XML_m, XML_accPr );
219 m_pSerializer->startElementNS(XML_m, XML_e);
220 HandleNode( pNode->Body(), nLevel + 1 );
221 m_pSerializer->endElementNS( XML_m, XML_e );
222 m_pSerializer->endElementNS( XML_m, XML_acc );
223 break;
225 case TOVERLINE:
226 case TUNDERLINE:
227 m_pSerializer->startElementNS(XML_m, XML_bar);
228 m_pSerializer->startElementNS(XML_m, XML_barPr);
229 m_pSerializer->singleElementNS( XML_m, XML_pos, FSNS( XML_m, XML_val ),
230 ( pNode->Attribute()->GetToken().eType == TUNDERLINE ) ? "bot" : "top" );
231 m_pSerializer->endElementNS( XML_m, XML_barPr );
232 m_pSerializer->startElementNS(XML_m, XML_e);
233 HandleNode( pNode->Body(), nLevel + 1 );
234 m_pSerializer->endElementNS( XML_m, XML_e );
235 m_pSerializer->endElementNS( XML_m, XML_bar );
236 break;
237 case TOVERSTRIKE:
238 m_pSerializer->startElementNS(XML_m, XML_borderBox);
239 m_pSerializer->startElementNS(XML_m, XML_borderBoxPr);
240 m_pSerializer->singleElementNS(XML_m, XML_hideTop, FSNS(XML_m, XML_val), "1");
241 m_pSerializer->singleElementNS(XML_m, XML_hideBot, FSNS(XML_m, XML_val), "1");
242 m_pSerializer->singleElementNS(XML_m, XML_hideLeft, FSNS(XML_m, XML_val), "1");
243 m_pSerializer->singleElementNS(XML_m, XML_hideRight, FSNS(XML_m, XML_val), "1");
244 m_pSerializer->singleElementNS(XML_m, XML_strikeH, FSNS(XML_m, XML_val), "1");
245 m_pSerializer->endElementNS( XML_m, XML_borderBoxPr );
246 m_pSerializer->startElementNS(XML_m, XML_e);
247 HandleNode( pNode->Body(), nLevel + 1 );
248 m_pSerializer->endElementNS( XML_m, XML_e );
249 m_pSerializer->endElementNS( XML_m, XML_borderBox );
250 break;
251 default:
252 HandleAllSubNodes( pNode, nLevel );
253 break;
257 void SmOoxmlExport::HandleRoot( const SmRootNode* pNode, int nLevel )
259 m_pSerializer->startElementNS(XML_m, XML_rad);
260 if( const SmNode* argument = pNode->Argument())
262 m_pSerializer->startElementNS(XML_m, XML_deg);
263 HandleNode( argument, nLevel + 1 );
264 m_pSerializer->endElementNS( XML_m, XML_deg );
266 else
268 m_pSerializer->startElementNS(XML_m, XML_radPr);
269 m_pSerializer->singleElementNS(XML_m, XML_degHide, FSNS(XML_m, XML_val), "1");
270 m_pSerializer->endElementNS( XML_m, XML_radPr );
271 m_pSerializer->singleElementNS(XML_m, XML_deg); // empty but present
273 m_pSerializer->startElementNS(XML_m, XML_e);
274 HandleNode( pNode->Body(), nLevel + 1 );
275 m_pSerializer->endElementNS( XML_m, XML_e );
276 m_pSerializer->endElementNS( XML_m, XML_rad );
279 static OString mathSymbolToString( const SmNode* node )
281 assert( node->GetType() == SmNodeType::Math || node->GetType() == SmNodeType::MathIdent );
282 const SmTextNode* txtnode = static_cast< const SmTextNode* >( node );
283 assert( txtnode->GetText().getLength() == 1 );
284 sal_Unicode chr = SmTextNode::ConvertSymbolToUnicode( txtnode->GetText()[0] );
285 return OUStringToOString( OUStringChar( chr ), RTL_TEXTENCODING_UTF8 );
288 void SmOoxmlExport::HandleOperator( const SmOperNode* pNode, int nLevel )
290 SAL_INFO( "starmath.ooxml", "Operator: " << int( pNode->GetToken().eType ));
291 switch( pNode->GetToken().eType )
293 case TINT:
294 case TINTD:
295 case TIINT:
296 case TIIINT:
297 case TLINT:
298 case TLLINT:
299 case TLLLINT:
300 case TPROD:
301 case TCOPROD:
302 case TSUM:
304 const SmSubSupNode* subsup = pNode->GetSubNode( 0 )->GetType() == SmNodeType::SubSup
305 ? static_cast< const SmSubSupNode* >( pNode->GetSubNode( 0 )) : nullptr;
306 const SmNode* operation = subsup != nullptr ? subsup->GetBody() : pNode->GetSubNode( 0 );
307 m_pSerializer->startElementNS(XML_m, XML_nary);
308 m_pSerializer->startElementNS(XML_m, XML_naryPr);
309 m_pSerializer->singleElementNS( XML_m, XML_chr,
310 FSNS( XML_m, XML_val ), mathSymbolToString(operation) );
311 if( subsup == nullptr || subsup->GetSubSup( CSUB ) == nullptr )
312 m_pSerializer->singleElementNS(XML_m, XML_subHide, FSNS(XML_m, XML_val), "1");
313 if( subsup == nullptr || subsup->GetSubSup( CSUP ) == nullptr )
314 m_pSerializer->singleElementNS(XML_m, XML_supHide, FSNS(XML_m, XML_val), "1");
315 m_pSerializer->endElementNS( XML_m, XML_naryPr );
316 if( subsup == nullptr || subsup->GetSubSup( CSUB ) == nullptr )
317 m_pSerializer->singleElementNS(XML_m, XML_sub);
318 else
320 m_pSerializer->startElementNS(XML_m, XML_sub);
321 HandleNode( subsup->GetSubSup( CSUB ), nLevel + 1 );
322 m_pSerializer->endElementNS( XML_m, XML_sub );
324 if( subsup == nullptr || subsup->GetSubSup( CSUP ) == nullptr )
325 m_pSerializer->singleElementNS(XML_m, XML_sup);
326 else
328 m_pSerializer->startElementNS(XML_m, XML_sup);
329 HandleNode( subsup->GetSubSup( CSUP ), nLevel + 1 );
330 m_pSerializer->endElementNS( XML_m, XML_sup );
332 m_pSerializer->startElementNS(XML_m, XML_e);
333 HandleNode( pNode->GetSubNode( 1 ), nLevel + 1 ); // body
334 m_pSerializer->endElementNS( XML_m, XML_e );
335 m_pSerializer->endElementNS( XML_m, XML_nary );
336 break;
338 case TLIM:
339 m_pSerializer->startElementNS(XML_m, XML_func);
340 m_pSerializer->startElementNS(XML_m, XML_fName);
341 m_pSerializer->startElementNS(XML_m, XML_limLow);
342 m_pSerializer->startElementNS(XML_m, XML_e);
343 HandleNode( pNode->GetSymbol(), nLevel + 1 );
344 m_pSerializer->endElementNS( XML_m, XML_e );
345 m_pSerializer->startElementNS(XML_m, XML_lim);
346 if( const SmSubSupNode* subsup = pNode->GetSubNode( 0 )->GetType() == SmNodeType::SubSup
347 ? static_cast< const SmSubSupNode* >( pNode->GetSubNode( 0 )) : nullptr )
349 if( subsup->GetSubSup( CSUB ) != nullptr )
350 HandleNode( subsup->GetSubSup( CSUB ), nLevel + 1 );
352 m_pSerializer->endElementNS( XML_m, XML_lim );
353 m_pSerializer->endElementNS( XML_m, XML_limLow );
354 m_pSerializer->endElementNS( XML_m, XML_fName );
355 m_pSerializer->startElementNS(XML_m, XML_e);
356 HandleNode( pNode->GetSubNode( 1 ), nLevel + 1 ); // body
357 m_pSerializer->endElementNS( XML_m, XML_e );
358 m_pSerializer->endElementNS( XML_m, XML_func );
359 break;
360 default:
361 SAL_WARN("starmath.ooxml", "Unhandled operation");
362 HandleAllSubNodes( pNode, nLevel );
363 break;
367 void SmOoxmlExport::HandleSubSupScriptInternal( const SmSubSupNode* pNode, int nLevel, int flags )
369 // docx supports only a certain combination of sub/super scripts, but LO can have any,
370 // so try to merge it using several tags if necessary
371 if( flags == 0 ) // none
372 return;
373 if(( flags & ( 1 << RSUP | 1 << RSUB )) == ( 1 << RSUP | 1 << RSUB ))
374 { // m:sSubSup
375 m_pSerializer->startElementNS(XML_m, XML_sSubSup);
376 m_pSerializer->startElementNS(XML_m, XML_e);
377 flags &= ~( 1 << RSUP | 1 << RSUB );
378 if( flags == 0 )
379 HandleNode( pNode->GetBody(), nLevel + 1 );
380 else
381 HandleSubSupScriptInternal( pNode, nLevel, flags );
382 m_pSerializer->endElementNS( XML_m, XML_e );
383 m_pSerializer->startElementNS(XML_m, XML_sub);
384 HandleNode( pNode->GetSubSup( RSUB ), nLevel + 1 );
385 m_pSerializer->endElementNS( XML_m, XML_sub );
386 m_pSerializer->startElementNS(XML_m, XML_sup);
387 HandleNode( pNode->GetSubSup( RSUP ), nLevel + 1 );
388 m_pSerializer->endElementNS( XML_m, XML_sup );
389 m_pSerializer->endElementNS( XML_m, XML_sSubSup );
391 else if(( flags & ( 1 << RSUB )) == 1 << RSUB )
392 { // m:sSub
393 m_pSerializer->startElementNS(XML_m, XML_sSub);
394 m_pSerializer->startElementNS(XML_m, XML_e);
395 flags &= ~( 1 << RSUB );
396 if( flags == 0 )
397 HandleNode( pNode->GetBody(), nLevel + 1 );
398 else
399 HandleSubSupScriptInternal( pNode, nLevel, flags );
400 m_pSerializer->endElementNS( XML_m, XML_e );
401 m_pSerializer->startElementNS(XML_m, XML_sub);
402 HandleNode( pNode->GetSubSup( RSUB ), nLevel + 1 );
403 m_pSerializer->endElementNS( XML_m, XML_sub );
404 m_pSerializer->endElementNS( XML_m, XML_sSub );
406 else if(( flags & ( 1 << RSUP )) == 1 << RSUP )
407 { // m:sSup
408 m_pSerializer->startElementNS(XML_m, XML_sSup);
409 m_pSerializer->startElementNS(XML_m, XML_e);
410 flags &= ~( 1 << RSUP );
411 if( flags == 0 )
412 HandleNode( pNode->GetBody(), nLevel + 1 );
413 else
414 HandleSubSupScriptInternal( pNode, nLevel, flags );
415 m_pSerializer->endElementNS( XML_m, XML_e );
416 m_pSerializer->startElementNS(XML_m, XML_sup);
417 HandleNode( pNode->GetSubSup( RSUP ), nLevel + 1 );
418 m_pSerializer->endElementNS( XML_m, XML_sup );
419 m_pSerializer->endElementNS( XML_m, XML_sSup );
421 else if(( flags & ( 1 << LSUP | 1 << LSUB )) == ( 1 << LSUP | 1 << LSUB ))
422 { // m:sPre
423 m_pSerializer->startElementNS(XML_m, XML_sPre);
424 m_pSerializer->startElementNS(XML_m, XML_sub);
425 HandleNode( pNode->GetSubSup( LSUB ), nLevel + 1 );
426 m_pSerializer->endElementNS( XML_m, XML_sub );
427 m_pSerializer->startElementNS(XML_m, XML_sup);
428 HandleNode( pNode->GetSubSup( LSUP ), nLevel + 1 );
429 m_pSerializer->endElementNS( XML_m, XML_sup );
430 m_pSerializer->startElementNS(XML_m, XML_e);
431 flags &= ~( 1 << LSUP | 1 << LSUB );
432 if( flags == 0 )
433 HandleNode( pNode->GetBody(), nLevel + 1 );
434 else
435 HandleSubSupScriptInternal( pNode, nLevel, flags );
436 m_pSerializer->endElementNS( XML_m, XML_e );
437 m_pSerializer->endElementNS( XML_m, XML_sPre );
439 else if(( flags & ( 1 << CSUB )) == ( 1 << CSUB ))
440 { // m:limLow looks like a good element for central superscript
441 m_pSerializer->startElementNS(XML_m, XML_limLow);
442 m_pSerializer->startElementNS(XML_m, XML_e);
443 flags &= ~( 1 << CSUB );
444 if( flags == 0 )
445 HandleNode( pNode->GetBody(), nLevel + 1 );
446 else
447 HandleSubSupScriptInternal( pNode, nLevel, flags );
448 m_pSerializer->endElementNS( XML_m, XML_e );
449 m_pSerializer->startElementNS(XML_m, XML_lim);
450 HandleNode( pNode->GetSubSup( CSUB ), nLevel + 1 );
451 m_pSerializer->endElementNS( XML_m, XML_lim );
452 m_pSerializer->endElementNS( XML_m, XML_limLow );
454 else if(( flags & ( 1 << CSUP )) == ( 1 << CSUP ))
455 { // m:limUpp looks like a good element for central superscript
456 m_pSerializer->startElementNS(XML_m, XML_limUpp);
457 m_pSerializer->startElementNS(XML_m, XML_e);
458 flags &= ~( 1 << CSUP );
459 if( flags == 0 )
460 HandleNode( pNode->GetBody(), nLevel + 1 );
461 else
462 HandleSubSupScriptInternal( pNode, nLevel, flags );
463 m_pSerializer->endElementNS( XML_m, XML_e );
464 m_pSerializer->startElementNS(XML_m, XML_lim);
465 HandleNode( pNode->GetSubSup( CSUP ), nLevel + 1 );
466 m_pSerializer->endElementNS( XML_m, XML_lim );
467 m_pSerializer->endElementNS( XML_m, XML_limUpp );
469 else
471 SAL_WARN("starmath.ooxml", "Unhandled sub/sup combination");
472 // TODO do not do anything, this should be probably an assert()
473 // HandleAllSubNodes( pNode, nLevel );
477 void SmOoxmlExport::HandleMatrix( const SmMatrixNode* pNode, int nLevel )
479 m_pSerializer->startElementNS(XML_m, XML_m);
480 for (size_t row = 0; row < pNode->GetNumRows(); ++row)
482 m_pSerializer->startElementNS(XML_m, XML_mr);
483 for (size_t col = 0; col < pNode->GetNumCols(); ++col)
485 m_pSerializer->startElementNS(XML_m, XML_e);
486 if( const SmNode* node = pNode->GetSubNode( row * pNode->GetNumCols() + col ))
487 HandleNode( node, nLevel + 1 );
488 m_pSerializer->endElementNS( XML_m, XML_e );
490 m_pSerializer->endElementNS( XML_m, XML_mr );
492 m_pSerializer->endElementNS( XML_m, XML_m );
495 void SmOoxmlExport::HandleBrace( const SmBraceNode* pNode, int nLevel )
497 m_pSerializer->startElementNS(XML_m, XML_d);
498 m_pSerializer->startElementNS(XML_m, XML_dPr);
500 //check if the node has an opening brace
501 if( TNONE == pNode->OpeningBrace()->GetToken().eType )
502 m_pSerializer->singleElementNS(XML_m, XML_begChr, FSNS(XML_m, XML_val), "");
503 else
504 m_pSerializer->singleElementNS( XML_m, XML_begChr,
505 FSNS( XML_m, XML_val ), mathSymbolToString( pNode->OpeningBrace()) );
507 std::vector< const SmNode* > subnodes;
508 if( pNode->Body()->GetType() == SmNodeType::Bracebody )
510 const SmBracebodyNode* body = static_cast< const SmBracebodyNode* >( pNode->Body());
511 bool separatorWritten = false; // assume all separators are the same
512 for (size_t i = 0; i < body->GetNumSubNodes(); ++i)
514 const SmNode* subnode = body->GetSubNode( i );
515 if (subnode->GetType() == SmNodeType::Math || subnode->GetType() == SmNodeType::MathIdent)
516 { // do not write, but write what separator it is
517 const SmMathSymbolNode* math = static_cast< const SmMathSymbolNode* >( subnode );
518 if( !separatorWritten )
520 m_pSerializer->singleElementNS( XML_m, XML_sepChr,
521 FSNS( XML_m, XML_val ), mathSymbolToString(math) );
522 separatorWritten = true;
525 else
526 subnodes.push_back( subnode );
529 else
530 subnodes.push_back( pNode->Body());
532 if( TNONE == pNode->ClosingBrace()->GetToken().eType )
533 m_pSerializer->singleElementNS(XML_m, XML_endChr, FSNS(XML_m, XML_val), "");
534 else
535 m_pSerializer->singleElementNS( XML_m, XML_endChr,
536 FSNS( XML_m, XML_val ), mathSymbolToString(pNode->ClosingBrace()) );
538 m_pSerializer->endElementNS( XML_m, XML_dPr );
539 for(const SmNode* subnode : subnodes)
541 m_pSerializer->startElementNS(XML_m, XML_e);
542 HandleNode( subnode, nLevel + 1 );
543 m_pSerializer->endElementNS( XML_m, XML_e );
545 m_pSerializer->endElementNS( XML_m, XML_d );
548 void SmOoxmlExport::HandleVerticalBrace( const SmVerticalBraceNode* pNode, int nLevel )
550 SAL_INFO( "starmath.ooxml", "Vertical: " << int( pNode->GetToken().eType ));
551 switch( pNode->GetToken().eType )
553 case TOVERBRACE:
554 case TUNDERBRACE:
556 bool top = ( pNode->GetToken().eType == TOVERBRACE );
557 m_pSerializer->startElementNS(XML_m, top ? XML_limUpp : XML_limLow);
558 m_pSerializer->startElementNS(XML_m, XML_e);
559 m_pSerializer->startElementNS(XML_m, XML_groupChr);
560 m_pSerializer->startElementNS(XML_m, XML_groupChrPr);
561 m_pSerializer->singleElementNS( XML_m, XML_chr,
562 FSNS( XML_m, XML_val ), mathSymbolToString(pNode->Brace()) );
563 // TODO not sure if pos and vertJc are correct
564 m_pSerializer->singleElementNS( XML_m, XML_pos,
565 FSNS( XML_m, XML_val ), top ? "top" : "bot" );
566 m_pSerializer->singleElementNS(XML_m, XML_vertJc, FSNS(XML_m, XML_val),
567 top ? "bot" : "top");
568 m_pSerializer->endElementNS( XML_m, XML_groupChrPr );
569 m_pSerializer->startElementNS(XML_m, XML_e);
570 HandleNode( pNode->Body(), nLevel + 1 );
571 m_pSerializer->endElementNS( XML_m, XML_e );
572 m_pSerializer->endElementNS( XML_m, XML_groupChr );
573 m_pSerializer->endElementNS( XML_m, XML_e );
574 m_pSerializer->startElementNS(XML_m, XML_lim);
575 HandleNode( pNode->Script(), nLevel + 1 );
576 m_pSerializer->endElementNS( XML_m, XML_lim );
577 m_pSerializer->endElementNS( XML_m, top ? XML_limUpp : XML_limLow );
578 break;
580 default:
581 SAL_WARN("starmath.ooxml", "Unhandled vertical brace");
582 HandleAllSubNodes( pNode, nLevel );
583 break;
587 void SmOoxmlExport::HandleBlank()
589 m_pSerializer->startElementNS(XML_m, XML_r);
590 m_pSerializer->startElementNS(XML_m, XML_t, FSNS(XML_xml, XML_space), "preserve");
591 m_pSerializer->write( " " );
592 m_pSerializer->endElementNS( XML_m, XML_t );
593 m_pSerializer->endElementNS( XML_m, XML_r );
596 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */