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"
12 #include <oox/token/tokens.hxx>
13 #include <rtl/ustring.hxx>
14 #include <sal/log.hxx>
15 #include <oox/mathml/imexport.hxx>
18 using namespace oox::core
;
20 SmOoxmlExport::SmOoxmlExport(const SmNode
*const pIn
, OoxmlVersion
const v
,
21 drawingml::DocumentType
const documentType
)
22 : SmWordExportBase( pIn
)
24 , m_DocumentType(documentType
)
28 void SmOoxmlExport::ConvertFromStarMath( const ::sax_fastparser::FSHelperPtr
& serializer
, const sal_Int8 nAlign
)
30 if( GetTree() == nullptr )
32 m_pSerializer
= serializer
;
34 //Formula alignment situations:
36 // 1)Inline(as before):
46 // <m:jc m:val="left|right|center">
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();
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
++)
122 if ((nPendingAttributes
) &&
123 (i
== ((pTemp
->GetText().getLength()+1)/2)-1))
125 *pS
<< sal_uInt8(0x22); //char, with attributes right
126 //after the character
129 *pS
<< sal_uInt8(CHAR
);
131 sal_uInt8 nFace
= 0x1;
132 if (pNode
->GetFont().GetItalic() == ITALIC_NORMAL
)
134 else if (pNode
->GetFont().GetWeight() == WEIGHT_BOLD
)
136 *pS
<< sal_uInt8(nFace
+128); //typeface
138 buf
[i
] = SmTextNode::ConvertSymbolToUnicode(buf
[i
]);
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
)
159 //wedge the attributes in here and clear
161 nPendingAttributes
--;
163 nInsertion
=pS
->Tell();
164 *pS
<< sal_uInt8(END
); //end embel
165 *pS
<< sal_uInt8(END
); //end embel
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
)
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
);
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
);
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
);
252 HandleAllSubNodes( pNode
, nLevel
);
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
);
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
)
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
);
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
);
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
);
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
);
361 SAL_WARN("starmath.ooxml", "Unhandled operation");
362 HandleAllSubNodes( pNode
, nLevel
);
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
373 if(( flags
& ( 1 << RSUP
| 1 << RSUB
)) == ( 1 << RSUP
| 1 << RSUB
))
375 m_pSerializer
->startElementNS(XML_m
, XML_sSubSup
);
376 m_pSerializer
->startElementNS(XML_m
, XML_e
);
377 flags
&= ~( 1 << RSUP
| 1 << RSUB
);
379 HandleNode( pNode
->GetBody(), nLevel
+ 1 );
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
)
393 m_pSerializer
->startElementNS(XML_m
, XML_sSub
);
394 m_pSerializer
->startElementNS(XML_m
, XML_e
);
395 flags
&= ~( 1 << RSUB
);
397 HandleNode( pNode
->GetBody(), nLevel
+ 1 );
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
)
408 m_pSerializer
->startElementNS(XML_m
, XML_sSup
);
409 m_pSerializer
->startElementNS(XML_m
, XML_e
);
410 flags
&= ~( 1 << RSUP
);
412 HandleNode( pNode
->GetBody(), nLevel
+ 1 );
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
))
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
);
433 HandleNode( pNode
->GetBody(), nLevel
+ 1 );
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
);
445 HandleNode( pNode
->GetBody(), nLevel
+ 1 );
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
);
460 HandleNode( pNode
->GetBody(), nLevel
+ 1 );
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
);
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
), "");
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;
526 subnodes
.push_back( subnode
);
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
), "");
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
)
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
);
581 SAL_WARN("starmath.ooxml", "Unhandled vertical brace");
582 HandleAllSubNodes( pNode
, nLevel
);
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: */