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/.
10 #include "ooxmlexport.hxx"
13 #include <oox/token/tokens.hxx>
14 #include <rtl/ustring.hxx>
15 #include <sal/log.hxx>
16 #include <oox/mathml/export.hxx>
19 using namespace oox::core
;
21 SmOoxmlExport::SmOoxmlExport(const SmNode
*const pIn
, OoxmlVersion
const v
,
22 drawingml::DocumentType
const documentType
)
23 : SmWordExportBase( pIn
)
25 , m_DocumentType(documentType
)
29 void SmOoxmlExport::ConvertFromStarMath( const ::sax_fastparser::FSHelperPtr
& serializer
, const sal_Int8 nAlign
)
31 if( GetTree() == nullptr )
33 m_pSerializer
= serializer
;
35 //Formula alignment situations:
37 // 1)Inline(as before):
47 // <m:jc m:val="left|right|center">
54 if (nAlign
!= FormulaExportBase::eFormulaAlign::INLINE
)
56 m_pSerializer
->startElementNS(XML_m
, XML_oMathPara
,
57 FSNS(XML_xmlns
, XML_m
), "http://schemas.openxmlformats.org/officeDocument/2006/math");
58 m_pSerializer
->startElementNS(XML_m
, XML_oMathParaPr
);
59 if (nAlign
== FormulaExportBase::eFormulaAlign::CENTER
)
60 m_pSerializer
->singleElementNS(XML_m
, XML_jc
, FSNS(XML_m
, XML_val
), "center");
61 if (nAlign
== FormulaExportBase::eFormulaAlign::GROUPEDCENTER
)
62 m_pSerializer
->singleElementNS(XML_m
, XML_jc
, FSNS(XML_m
, XML_val
), "center");
63 if (nAlign
== FormulaExportBase::eFormulaAlign::LEFT
)
64 m_pSerializer
->singleElementNS(XML_m
, XML_jc
, FSNS(XML_m
, XML_val
), "left");
65 if (nAlign
== FormulaExportBase::eFormulaAlign::RIGHT
)
66 m_pSerializer
->singleElementNS(XML_m
, XML_jc
, FSNS(XML_m
, XML_val
), "right");
67 m_pSerializer
->endElementNS(XML_m
, XML_oMathParaPr
);
68 m_pSerializer
->startElementNS(XML_m
, XML_oMath
);
69 HandleNode(GetTree(), 0);
70 m_pSerializer
->endElementNS(XML_m
, XML_oMath
);
71 m_pSerializer
->endElementNS(XML_m
, XML_oMathPara
);
73 else //else, inline as was before
75 m_pSerializer
->startElementNS(XML_m
, XML_oMath
,
76 FSNS(XML_xmlns
, XML_m
), "http://schemas.openxmlformats.org/officeDocument/2006/math");
77 HandleNode( GetTree(), 0 );
78 m_pSerializer
->endElementNS( XML_m
, XML_oMath
);
82 // NOTE: This is still work in progress and unfinished, but it already covers a good
83 // part of the ooxml math stuff.
85 void SmOoxmlExport::HandleVerticalStack( const SmNode
* pNode
, int nLevel
)
87 m_pSerializer
->startElementNS(XML_m
, XML_eqArr
);
88 int size
= pNode
->GetNumSubNodes();
93 m_pSerializer
->startElementNS(XML_m
, XML_e
);
94 HandleNode( pNode
->GetSubNode( i
), nLevel
+ 1 );
95 m_pSerializer
->endElementNS( XML_m
, XML_e
);
97 m_pSerializer
->endElementNS( XML_m
, XML_eqArr
);
100 void SmOoxmlExport::HandleText( const SmNode
* pNode
, int /*nLevel*/)
102 m_pSerializer
->startElementNS(XML_m
, XML_r
);
104 if( pNode
->GetToken().eType
== TTEXT
) // literal text (in quotes)
106 m_pSerializer
->startElementNS(XML_m
, XML_rPr
);
107 m_pSerializer
->singleElementNS(XML_m
, XML_lit
);
108 m_pSerializer
->singleElementNS(XML_m
, XML_nor
);
109 m_pSerializer
->endElementNS( XML_m
, XML_rPr
);
111 if (drawingml::DOCUMENT_DOCX
== m_DocumentType
&& ECMA_DIALECT
== version
)
112 { // HACK: MSOffice2007 does not import characters properly unless this font is explicitly given
113 m_pSerializer
->startElementNS(XML_w
, XML_rPr
);
114 m_pSerializer
->singleElementNS( XML_w
, XML_rFonts
, FSNS( XML_w
, XML_ascii
), "Cambria Math",
115 FSNS( XML_w
, XML_hAnsi
), "Cambria Math" );
116 m_pSerializer
->endElementNS( XML_w
, XML_rPr
);
118 m_pSerializer
->startElementNS(XML_m
, XML_t
, FSNS(XML_xml
, XML_space
), "preserve");
119 const SmTextNode
* pTemp
= static_cast<const SmTextNode
* >(pNode
);
120 SAL_INFO( "starmath.ooxml", "Text:" << pTemp
->GetText());
121 OUStringBuffer
buf(pTemp
->GetText());
122 for(sal_Int32 i
=0;i
<pTemp
->GetText().getLength();i
++)
125 if ((nPendingAttributes
) &&
126 (i
== ((pTemp
->GetText().getLength()+1)/2)-1))
128 *pS
<< sal_uInt8(0x22); //char, with attributes right
129 //after the character
132 *pS
<< sal_uInt8(CHAR
);
134 sal_uInt8 nFace
= 0x1;
135 if (pNode
->GetFont().GetItalic() == ITALIC_NORMAL
)
137 else if (pNode
->GetFont().GetWeight() == WEIGHT_BOLD
)
139 *pS
<< sal_uInt8(nFace
+128); //typeface
141 buf
[i
] = SmTextNode::ConvertSymbolToUnicode(buf
[i
]);
143 //Mathtype can only have these sort of character
144 //attributes on a single character, starmath can put them
145 //anywhere, when the entity involved is a text run this is
146 //a large effort to place the character attribute on the
147 //central mathtype character so that it does pretty much
148 //what the user probably has in mind. The attributes
149 //filled in here are dummy ones which are replaced in the
150 //ATTRIBUT handler if a suitable location for the
151 //attributes was found here. Unfortunately it is
152 //possible for starmath to place character attributes on
153 //entities which cannot occur in mathtype e.g. a Summation
154 //symbol so these attributes may be lost
155 if ((nPendingAttributes
) &&
156 (i
== ((pTemp
->GetText().getLength()+1)/2)-1))
158 *pS
<< sal_uInt8(EMBEL
);
159 while (nPendingAttributes
)
162 //wedge the attributes in here and clear
164 nPendingAttributes
--;
166 nInsertion
=pS
->Tell();
167 *pS
<< sal_uInt8(END
); //end embel
168 *pS
<< sal_uInt8(END
); //end embel
172 m_pSerializer
->writeEscaped(buf
.makeStringAndClear());
173 m_pSerializer
->endElementNS( XML_m
, XML_t
);
174 m_pSerializer
->endElementNS( XML_m
, XML_r
);
177 void SmOoxmlExport::HandleFractions( const SmNode
* pNode
, int nLevel
, const char* type
)
179 m_pSerializer
->startElementNS(XML_m
, XML_f
);
180 if( type
!= nullptr )
182 m_pSerializer
->startElementNS(XML_m
, XML_fPr
);
183 m_pSerializer
->singleElementNS(XML_m
, XML_type
, FSNS(XML_m
, XML_val
), type
);
184 m_pSerializer
->endElementNS( XML_m
, XML_fPr
);
186 assert( pNode
->GetNumSubNodes() == 3 );
187 m_pSerializer
->startElementNS(XML_m
, XML_num
);
188 HandleNode( pNode
->GetSubNode( 0 ), nLevel
+ 1 );
189 m_pSerializer
->endElementNS( XML_m
, XML_num
);
190 m_pSerializer
->startElementNS(XML_m
, XML_den
);
191 HandleNode( pNode
->GetSubNode( 2 ), nLevel
+ 1 );
192 m_pSerializer
->endElementNS( XML_m
, XML_den
);
193 m_pSerializer
->endElementNS( XML_m
, XML_f
);
196 void SmOoxmlExport::HandleAttribute( const SmAttributNode
* pNode
, int nLevel
)
198 switch( pNode
->Attribute()->GetToken().eType
)
217 m_pSerializer
->startElementNS(XML_m
, XML_acc
);
218 m_pSerializer
->startElementNS(XML_m
, XML_accPr
);
219 OString value
= OUStringToOString(
220 OUString( pNode
->Attribute()->GetToken().cMathChar
), RTL_TEXTENCODING_UTF8
);
221 m_pSerializer
->singleElementNS(XML_m
, XML_chr
, FSNS(XML_m
, XML_val
), value
);
222 m_pSerializer
->endElementNS( XML_m
, XML_accPr
);
223 m_pSerializer
->startElementNS(XML_m
, XML_e
);
224 HandleNode( pNode
->Body(), nLevel
+ 1 );
225 m_pSerializer
->endElementNS( XML_m
, XML_e
);
226 m_pSerializer
->endElementNS( XML_m
, XML_acc
);
231 m_pSerializer
->startElementNS(XML_m
, XML_bar
);
232 m_pSerializer
->startElementNS(XML_m
, XML_barPr
);
233 m_pSerializer
->singleElementNS( XML_m
, XML_pos
, FSNS( XML_m
, XML_val
),
234 ( pNode
->Attribute()->GetToken().eType
== TUNDERLINE
) ? "bot" : "top" );
235 m_pSerializer
->endElementNS( XML_m
, XML_barPr
);
236 m_pSerializer
->startElementNS(XML_m
, XML_e
);
237 HandleNode( pNode
->Body(), nLevel
+ 1 );
238 m_pSerializer
->endElementNS( XML_m
, XML_e
);
239 m_pSerializer
->endElementNS( XML_m
, XML_bar
);
242 m_pSerializer
->startElementNS(XML_m
, XML_borderBox
);
243 m_pSerializer
->startElementNS(XML_m
, XML_borderBoxPr
);
244 m_pSerializer
->singleElementNS(XML_m
, XML_hideTop
, FSNS(XML_m
, XML_val
), "1");
245 m_pSerializer
->singleElementNS(XML_m
, XML_hideBot
, FSNS(XML_m
, XML_val
), "1");
246 m_pSerializer
->singleElementNS(XML_m
, XML_hideLeft
, FSNS(XML_m
, XML_val
), "1");
247 m_pSerializer
->singleElementNS(XML_m
, XML_hideRight
, FSNS(XML_m
, XML_val
), "1");
248 m_pSerializer
->singleElementNS(XML_m
, XML_strikeH
, FSNS(XML_m
, XML_val
), "1");
249 m_pSerializer
->endElementNS( XML_m
, XML_borderBoxPr
);
250 m_pSerializer
->startElementNS(XML_m
, XML_e
);
251 HandleNode( pNode
->Body(), nLevel
+ 1 );
252 m_pSerializer
->endElementNS( XML_m
, XML_e
);
253 m_pSerializer
->endElementNS( XML_m
, XML_borderBox
);
256 HandleAllSubNodes( pNode
, nLevel
);
261 void SmOoxmlExport::HandleRoot( const SmRootNode
* pNode
, int nLevel
)
263 m_pSerializer
->startElementNS(XML_m
, XML_rad
);
264 if( const SmNode
* argument
= pNode
->Argument())
266 m_pSerializer
->startElementNS(XML_m
, XML_deg
);
267 HandleNode( argument
, nLevel
+ 1 );
268 m_pSerializer
->endElementNS( XML_m
, XML_deg
);
272 m_pSerializer
->startElementNS(XML_m
, XML_radPr
);
273 m_pSerializer
->singleElementNS(XML_m
, XML_degHide
, FSNS(XML_m
, XML_val
), "1");
274 m_pSerializer
->endElementNS( XML_m
, XML_radPr
);
275 m_pSerializer
->singleElementNS(XML_m
, XML_deg
); // empty but present
277 m_pSerializer
->startElementNS(XML_m
, XML_e
);
278 HandleNode( pNode
->Body(), nLevel
+ 1 );
279 m_pSerializer
->endElementNS( XML_m
, XML_e
);
280 m_pSerializer
->endElementNS( XML_m
, XML_rad
);
283 static OString
mathSymbolToString( const SmNode
* node
)
285 assert( node
->GetType() == SmNodeType::Math
|| node
->GetType() == SmNodeType::MathIdent
);
286 const SmTextNode
* txtnode
= static_cast< const SmTextNode
* >( node
);
287 assert( txtnode
->GetText().getLength() == 1 );
288 sal_Unicode chr
= SmTextNode::ConvertSymbolToUnicode( txtnode
->GetText()[0] );
289 return OUStringToOString( OUString( chr
), RTL_TEXTENCODING_UTF8
);
292 void SmOoxmlExport::HandleOperator( const SmOperNode
* pNode
, int nLevel
)
294 SAL_INFO( "starmath.ooxml", "Operator: " << int( pNode
->GetToken().eType
));
295 switch( pNode
->GetToken().eType
)
308 const SmSubSupNode
* subsup
= pNode
->GetSubNode( 0 )->GetType() == SmNodeType::SubSup
309 ? static_cast< const SmSubSupNode
* >( pNode
->GetSubNode( 0 )) : nullptr;
310 const SmNode
* operation
= subsup
!= nullptr ? subsup
->GetBody() : pNode
->GetSubNode( 0 );
311 m_pSerializer
->startElementNS(XML_m
, XML_nary
);
312 m_pSerializer
->startElementNS(XML_m
, XML_naryPr
);
313 m_pSerializer
->singleElementNS( XML_m
, XML_chr
,
314 FSNS( XML_m
, XML_val
), mathSymbolToString(operation
) );
315 if( subsup
== nullptr || subsup
->GetSubSup( CSUB
) == nullptr )
316 m_pSerializer
->singleElementNS(XML_m
, XML_subHide
, FSNS(XML_m
, XML_val
), "1");
317 if( subsup
== nullptr || subsup
->GetSubSup( CSUP
) == nullptr )
318 m_pSerializer
->singleElementNS(XML_m
, XML_supHide
, FSNS(XML_m
, XML_val
), "1");
319 m_pSerializer
->endElementNS( XML_m
, XML_naryPr
);
320 if( subsup
== nullptr || subsup
->GetSubSup( CSUB
) == nullptr )
321 m_pSerializer
->singleElementNS(XML_m
, XML_sub
);
324 m_pSerializer
->startElementNS(XML_m
, XML_sub
);
325 HandleNode( subsup
->GetSubSup( CSUB
), nLevel
+ 1 );
326 m_pSerializer
->endElementNS( XML_m
, XML_sub
);
328 if( subsup
== nullptr || subsup
->GetSubSup( CSUP
) == nullptr )
329 m_pSerializer
->singleElementNS(XML_m
, XML_sup
);
332 m_pSerializer
->startElementNS(XML_m
, XML_sup
);
333 HandleNode( subsup
->GetSubSup( CSUP
), nLevel
+ 1 );
334 m_pSerializer
->endElementNS( XML_m
, XML_sup
);
336 m_pSerializer
->startElementNS(XML_m
, XML_e
);
337 HandleNode( pNode
->GetSubNode( 1 ), nLevel
+ 1 ); // body
338 m_pSerializer
->endElementNS( XML_m
, XML_e
);
339 m_pSerializer
->endElementNS( XML_m
, XML_nary
);
343 m_pSerializer
->startElementNS(XML_m
, XML_func
);
344 m_pSerializer
->startElementNS(XML_m
, XML_fName
);
345 m_pSerializer
->startElementNS(XML_m
, XML_limLow
);
346 m_pSerializer
->startElementNS(XML_m
, XML_e
);
347 HandleNode( pNode
->GetSymbol(), nLevel
+ 1 );
348 m_pSerializer
->endElementNS( XML_m
, XML_e
);
349 m_pSerializer
->startElementNS(XML_m
, XML_lim
);
350 if( const SmSubSupNode
* subsup
= pNode
->GetSubNode( 0 )->GetType() == SmNodeType::SubSup
351 ? static_cast< const SmSubSupNode
* >( pNode
->GetSubNode( 0 )) : nullptr )
353 if( subsup
->GetSubSup( CSUB
) != nullptr )
354 HandleNode( subsup
->GetSubSup( CSUB
), nLevel
+ 1 );
356 m_pSerializer
->endElementNS( XML_m
, XML_lim
);
357 m_pSerializer
->endElementNS( XML_m
, XML_limLow
);
358 m_pSerializer
->endElementNS( XML_m
, XML_fName
);
359 m_pSerializer
->startElementNS(XML_m
, XML_e
);
360 HandleNode( pNode
->GetSubNode( 1 ), nLevel
+ 1 ); // body
361 m_pSerializer
->endElementNS( XML_m
, XML_e
);
362 m_pSerializer
->endElementNS( XML_m
, XML_func
);
365 SAL_WARN("starmath.ooxml", "Unhandled operation");
366 HandleAllSubNodes( pNode
, nLevel
);
371 void SmOoxmlExport::HandleSubSupScriptInternal( const SmSubSupNode
* pNode
, int nLevel
, int flags
)
373 // docx supports only a certain combination of sub/super scripts, but LO can have any,
374 // so try to merge it using several tags if necessary
375 if( flags
== 0 ) // none
377 if(( flags
& ( 1 << RSUP
| 1 << RSUB
)) == ( 1 << RSUP
| 1 << RSUB
))
379 m_pSerializer
->startElementNS(XML_m
, XML_sSubSup
);
380 m_pSerializer
->startElementNS(XML_m
, XML_e
);
381 flags
&= ~( 1 << RSUP
| 1 << RSUB
);
383 HandleNode( pNode
->GetBody(), nLevel
+ 1 );
385 HandleSubSupScriptInternal( pNode
, nLevel
, flags
);
386 m_pSerializer
->endElementNS( XML_m
, XML_e
);
387 m_pSerializer
->startElementNS(XML_m
, XML_sub
);
388 HandleNode( pNode
->GetSubSup( RSUB
), nLevel
+ 1 );
389 m_pSerializer
->endElementNS( XML_m
, XML_sub
);
390 m_pSerializer
->startElementNS(XML_m
, XML_sup
);
391 HandleNode( pNode
->GetSubSup( RSUP
), nLevel
+ 1 );
392 m_pSerializer
->endElementNS( XML_m
, XML_sup
);
393 m_pSerializer
->endElementNS( XML_m
, XML_sSubSup
);
395 else if(( flags
& ( 1 << RSUB
)) == 1 << RSUB
)
397 m_pSerializer
->startElementNS(XML_m
, XML_sSub
);
398 m_pSerializer
->startElementNS(XML_m
, XML_e
);
399 flags
&= ~( 1 << RSUB
);
401 HandleNode( pNode
->GetBody(), nLevel
+ 1 );
403 HandleSubSupScriptInternal( pNode
, nLevel
, flags
);
404 m_pSerializer
->endElementNS( XML_m
, XML_e
);
405 m_pSerializer
->startElementNS(XML_m
, XML_sub
);
406 HandleNode( pNode
->GetSubSup( RSUB
), nLevel
+ 1 );
407 m_pSerializer
->endElementNS( XML_m
, XML_sub
);
408 m_pSerializer
->endElementNS( XML_m
, XML_sSub
);
410 else if(( flags
& ( 1 << RSUP
)) == 1 << RSUP
)
412 m_pSerializer
->startElementNS(XML_m
, XML_sSup
);
413 m_pSerializer
->startElementNS(XML_m
, XML_e
);
414 flags
&= ~( 1 << RSUP
);
416 HandleNode( pNode
->GetBody(), nLevel
+ 1 );
418 HandleSubSupScriptInternal( pNode
, nLevel
, flags
);
419 m_pSerializer
->endElementNS( XML_m
, XML_e
);
420 m_pSerializer
->startElementNS(XML_m
, XML_sup
);
421 HandleNode( pNode
->GetSubSup( RSUP
), nLevel
+ 1 );
422 m_pSerializer
->endElementNS( XML_m
, XML_sup
);
423 m_pSerializer
->endElementNS( XML_m
, XML_sSup
);
425 else if(( flags
& ( 1 << LSUP
| 1 << LSUB
)) == ( 1 << LSUP
| 1 << LSUB
))
427 m_pSerializer
->startElementNS(XML_m
, XML_sPre
);
428 m_pSerializer
->startElementNS(XML_m
, XML_sub
);
429 HandleNode( pNode
->GetSubSup( LSUB
), nLevel
+ 1 );
430 m_pSerializer
->endElementNS( XML_m
, XML_sub
);
431 m_pSerializer
->startElementNS(XML_m
, XML_sup
);
432 HandleNode( pNode
->GetSubSup( LSUP
), nLevel
+ 1 );
433 m_pSerializer
->endElementNS( XML_m
, XML_sup
);
434 m_pSerializer
->startElementNS(XML_m
, XML_e
);
435 flags
&= ~( 1 << LSUP
| 1 << LSUB
);
437 HandleNode( pNode
->GetBody(), nLevel
+ 1 );
439 HandleSubSupScriptInternal( pNode
, nLevel
, flags
);
440 m_pSerializer
->endElementNS( XML_m
, XML_e
);
441 m_pSerializer
->endElementNS( XML_m
, XML_sPre
);
443 else if(( flags
& ( 1 << CSUB
)) == ( 1 << CSUB
))
444 { // m:limLow looks like a good element for central superscript
445 m_pSerializer
->startElementNS(XML_m
, XML_limLow
);
446 m_pSerializer
->startElementNS(XML_m
, XML_e
);
447 flags
&= ~( 1 << CSUB
);
449 HandleNode( pNode
->GetBody(), nLevel
+ 1 );
451 HandleSubSupScriptInternal( pNode
, nLevel
, flags
);
452 m_pSerializer
->endElementNS( XML_m
, XML_e
);
453 m_pSerializer
->startElementNS(XML_m
, XML_lim
);
454 HandleNode( pNode
->GetSubSup( CSUB
), nLevel
+ 1 );
455 m_pSerializer
->endElementNS( XML_m
, XML_lim
);
456 m_pSerializer
->endElementNS( XML_m
, XML_limLow
);
458 else if(( flags
& ( 1 << CSUP
)) == ( 1 << CSUP
))
459 { // m:limUpp looks like a good element for central superscript
460 m_pSerializer
->startElementNS(XML_m
, XML_limUpp
);
461 m_pSerializer
->startElementNS(XML_m
, XML_e
);
462 flags
&= ~( 1 << CSUP
);
464 HandleNode( pNode
->GetBody(), nLevel
+ 1 );
466 HandleSubSupScriptInternal( pNode
, nLevel
, flags
);
467 m_pSerializer
->endElementNS( XML_m
, XML_e
);
468 m_pSerializer
->startElementNS(XML_m
, XML_lim
);
469 HandleNode( pNode
->GetSubSup( CSUP
), nLevel
+ 1 );
470 m_pSerializer
->endElementNS( XML_m
, XML_lim
);
471 m_pSerializer
->endElementNS( XML_m
, XML_limUpp
);
475 SAL_WARN("starmath.ooxml", "Unhandled sub/sup combination");
476 // TODO do not do anything, this should be probably an assert()
477 // HandleAllSubNodes( pNode, nLevel );
481 void SmOoxmlExport::HandleMatrix( const SmMatrixNode
* pNode
, int nLevel
)
483 m_pSerializer
->startElementNS(XML_m
, XML_m
);
484 for (size_t row
= 0; row
< pNode
->GetNumRows(); ++row
)
486 m_pSerializer
->startElementNS(XML_m
, XML_mr
);
487 for (size_t col
= 0; col
< pNode
->GetNumCols(); ++col
)
489 m_pSerializer
->startElementNS(XML_m
, XML_e
);
490 if( const SmNode
* node
= pNode
->GetSubNode( row
* pNode
->GetNumCols() + col
))
491 HandleNode( node
, nLevel
+ 1 );
492 m_pSerializer
->endElementNS( XML_m
, XML_e
);
494 m_pSerializer
->endElementNS( XML_m
, XML_mr
);
496 m_pSerializer
->endElementNS( XML_m
, XML_m
);
499 void SmOoxmlExport::HandleBrace( const SmBraceNode
* pNode
, int nLevel
)
501 m_pSerializer
->startElementNS(XML_m
, XML_d
);
502 m_pSerializer
->startElementNS(XML_m
, XML_dPr
);
504 //check if the node has an opening brace
505 if( TNONE
== pNode
->OpeningBrace()->GetToken().eType
)
506 m_pSerializer
->singleElementNS(XML_m
, XML_begChr
, FSNS(XML_m
, XML_val
), "");
508 m_pSerializer
->singleElementNS( XML_m
, XML_begChr
,
509 FSNS( XML_m
, XML_val
), mathSymbolToString( pNode
->OpeningBrace()) );
511 std::vector
< const SmNode
* > subnodes
;
512 if( pNode
->Body()->GetType() == SmNodeType::Bracebody
)
514 const SmBracebodyNode
* body
= static_cast< const SmBracebodyNode
* >( pNode
->Body());
515 bool separatorWritten
= false; // assume all separators are the same
516 for (size_t i
= 0; i
< body
->GetNumSubNodes(); ++i
)
518 const SmNode
* subnode
= body
->GetSubNode( i
);
519 if (subnode
->GetType() == SmNodeType::Math
|| subnode
->GetType() == SmNodeType::MathIdent
)
520 { // do not write, but write what separator it is
521 const SmMathSymbolNode
* math
= static_cast< const SmMathSymbolNode
* >( subnode
);
522 if( !separatorWritten
)
524 m_pSerializer
->singleElementNS( XML_m
, XML_sepChr
,
525 FSNS( XML_m
, XML_val
), mathSymbolToString(math
) );
526 separatorWritten
= true;
530 subnodes
.push_back( subnode
);
534 subnodes
.push_back( pNode
->Body());
536 if( TNONE
== pNode
->ClosingBrace()->GetToken().eType
)
537 m_pSerializer
->singleElementNS(XML_m
, XML_endChr
, FSNS(XML_m
, XML_val
), "");
539 m_pSerializer
->singleElementNS( XML_m
, XML_endChr
,
540 FSNS( XML_m
, XML_val
), mathSymbolToString(pNode
->ClosingBrace()) );
542 m_pSerializer
->endElementNS( XML_m
, XML_dPr
);
543 for(const SmNode
* subnode
: subnodes
)
545 m_pSerializer
->startElementNS(XML_m
, XML_e
);
546 HandleNode( subnode
, nLevel
+ 1 );
547 m_pSerializer
->endElementNS( XML_m
, XML_e
);
549 m_pSerializer
->endElementNS( XML_m
, XML_d
);
552 void SmOoxmlExport::HandleVerticalBrace( const SmVerticalBraceNode
* pNode
, int nLevel
)
554 SAL_INFO( "starmath.ooxml", "Vertical: " << int( pNode
->GetToken().eType
));
555 switch( pNode
->GetToken().eType
)
560 bool top
= ( pNode
->GetToken().eType
== TOVERBRACE
);
561 m_pSerializer
->startElementNS(XML_m
, top
? XML_limUpp
: XML_limLow
);
562 m_pSerializer
->startElementNS(XML_m
, XML_e
);
563 m_pSerializer
->startElementNS(XML_m
, XML_groupChr
);
564 m_pSerializer
->startElementNS(XML_m
, XML_groupChrPr
);
565 m_pSerializer
->singleElementNS( XML_m
, XML_chr
,
566 FSNS( XML_m
, XML_val
), mathSymbolToString(pNode
->Brace()) );
567 // TODO not sure if pos and vertJc are correct
568 m_pSerializer
->singleElementNS( XML_m
, XML_pos
,
569 FSNS( XML_m
, XML_val
), top
? "top" : "bot" );
570 m_pSerializer
->singleElementNS(XML_m
, XML_vertJc
, FSNS(XML_m
, XML_val
),
571 top
? "bot" : "top");
572 m_pSerializer
->endElementNS( XML_m
, XML_groupChrPr
);
573 m_pSerializer
->startElementNS(XML_m
, XML_e
);
574 HandleNode( pNode
->Body(), nLevel
+ 1 );
575 m_pSerializer
->endElementNS( XML_m
, XML_e
);
576 m_pSerializer
->endElementNS( XML_m
, XML_groupChr
);
577 m_pSerializer
->endElementNS( XML_m
, XML_e
);
578 m_pSerializer
->startElementNS(XML_m
, XML_lim
);
579 HandleNode( pNode
->Script(), nLevel
+ 1 );
580 m_pSerializer
->endElementNS( XML_m
, XML_lim
);
581 m_pSerializer
->endElementNS( XML_m
, top
? XML_limUpp
: XML_limLow
);
585 SAL_WARN("starmath.ooxml", "Unhandled vertical brace");
586 HandleAllSubNodes( pNode
, nLevel
);
591 void SmOoxmlExport::HandleBlank()
593 m_pSerializer
->startElementNS(XML_m
, XML_r
);
594 m_pSerializer
->startElementNS(XML_m
, XML_t
, FSNS(XML_xml
, XML_space
), "preserve");
595 m_pSerializer
->write( " " );
596 m_pSerializer
->endElementNS( XML_m
, XML_t
);
597 m_pSerializer
->endElementNS( XML_m
, XML_r
);
600 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */