LibreOffice Module starmath (master) 1
ooxmlexport.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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 */
9
10#include "ooxmlexport.hxx"
11
12#include <oox/token/tokens.hxx>
13#include <rtl/ustring.hxx>
14#include <sal/log.hxx>
16
17using namespace oox;
18using namespace oox::core;
19
21 drawingml::DocumentType const documentType)
22: SmWordExportBase( pIn )
23, version( v )
24, m_DocumentType(documentType)
25{
26}
27
28void SmOoxmlExport::ConvertFromStarMath( const ::sax_fastparser::FSHelperPtr& serializer, const sal_Int8 nAlign )
29{
30 if( GetTree() == nullptr )
31 return;
32 m_pSerializer = serializer;
33
34 //Formula alignment situations:
35 //
36 // 1)Inline(as before):
37 //
38 // <m:oMath>
39 // <m:r> ... </m:r>
40 // </m:oMath>
41 //
42 // 2)Aligned:
43 //
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>
52
53 if (nAlign != FormulaImExportBase::eFormulaAlign::INLINE)
54 {
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);
69 }
70 else //else, inline as was before
71 {
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 );
76 }
77}
78
79// NOTE: This is still work in progress and unfinished, but it already covers a good
80// part of the ooxml math stuff.
81
82void SmOoxmlExport::HandleVerticalStack( const SmNode* pNode, int nLevel )
83{
84 m_pSerializer->startElementNS(XML_m, XML_eqArr);
85 int size = pNode->GetNumSubNodes();
86 for( int i = 0;
87 i < size;
88 ++i )
89 {
90 m_pSerializer->startElementNS(XML_m, XML_e);
91 HandleNode( pNode->GetSubNode( i ), nLevel + 1 );
92 m_pSerializer->endElementNS( XML_m, XML_e );
93 }
94 m_pSerializer->endElementNS( XML_m, XML_eqArr );
95}
96
97void SmOoxmlExport::HandleText( const SmNode* pNode, int /*nLevel*/)
98{
99 m_pSerializer->startElementNS(XML_m, XML_r);
100
101 if( pNode->GetToken().eType == TTEXT ) // literal text (in quotes)
102 {
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 );
107 }
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 );
114 }
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++)
120 {
121#if 0
122 if ((nPendingAttributes) &&
123 (i == ((pTemp->GetText().getLength()+1)/2)-1))
124 {
125 *pS << sal_uInt8(0x22); //char, with attributes right
126 //after the character
127 }
128 else
129 *pS << sal_uInt8(CHAR);
130
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
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))
154 {
155 *pS << sal_uInt8(EMBEL);
156 while (nPendingAttributes)
157 {
158 *pS << sal_uInt8(2);
159 //wedge the attributes in here and clear
160 //the pending stack
161 nPendingAttributes--;
162 }
163 nInsertion=pS->Tell();
164 *pS << sal_uInt8(END); //end embel
165 *pS << sal_uInt8(END); //end embel
166 }
167#endif
168 }
169 m_pSerializer->writeEscaped(buf);
170 m_pSerializer->endElementNS( XML_m, XML_t );
171 m_pSerializer->endElementNS( XML_m, XML_r );
172}
173
174void SmOoxmlExport::HandleFractions( const SmNode* pNode, int nLevel, const char* type )
175{
176 m_pSerializer->startElementNS(XML_m, XML_f);
177 if( type != nullptr )
178 {
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 );
182 }
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 );
191}
192
193void SmOoxmlExport::HandleAttribute( const SmAttributeNode* pNode, int nLevel )
194{
195 switch( pNode->Attribute()->GetToken().eType )
196 {
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:
213 {
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;
224 }
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;
254 }
255}
256
257void SmOoxmlExport::HandleRoot( const SmRootNode* pNode, int nLevel )
258{
259 m_pSerializer->startElementNS(XML_m, XML_rad);
260 if( const SmNode* argument = pNode->Argument())
261 {
262 m_pSerializer->startElementNS(XML_m, XML_deg);
263 HandleNode( argument, nLevel + 1 );
264 m_pSerializer->endElementNS( XML_m, XML_deg );
265 }
266 else
267 {
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
272 }
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 );
277}
278
279static OString mathSymbolToString( const SmNode* node )
280{
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 );
285 return OUStringToOString( OUStringChar( chr ), RTL_TEXTENCODING_UTF8 );
286}
287
288void SmOoxmlExport::HandleOperator( const SmOperNode* pNode, int nLevel )
289{
290 SAL_INFO( "starmath.ooxml", "Operator: " << int( pNode->GetToken().eType ));
291 switch( pNode->GetToken().eType )
292 {
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:
303 {
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
319 {
320 m_pSerializer->startElementNS(XML_m, XML_sub);
321 HandleNode( subsup->GetSubSup( CSUB ), nLevel + 1 );
322 m_pSerializer->endElementNS( XML_m, XML_sub );
323 }
324 if( subsup == nullptr || subsup->GetSubSup( CSUP ) == nullptr )
325 m_pSerializer->singleElementNS(XML_m, XML_sup);
326 else
327 {
328 m_pSerializer->startElementNS(XML_m, XML_sup);
329 HandleNode( subsup->GetSubSup( CSUP ), nLevel + 1 );
330 m_pSerializer->endElementNS( XML_m, XML_sup );
331 }
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;
337 }
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 )
348 {
349 if( subsup->GetSubSup( CSUB ) != nullptr )
350 HandleNode( subsup->GetSubSup( CSUB ), nLevel + 1 );
351 }
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;
364 }
365}
366
367void SmOoxmlExport::HandleSubSupScriptInternal( const SmSubSupNode* pNode, int nLevel, int flags )
368{
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 );
390 }
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 );
405 }
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 );
420 }
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 );
438 }
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 );
453 }
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 );
468 }
469 else
470 {
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 );
474 }
475}
476
477void SmOoxmlExport::HandleMatrix( const SmMatrixNode* pNode, int nLevel )
478{
479 m_pSerializer->startElementNS(XML_m, XML_m);
480 for (size_t row = 0; row < pNode->GetNumRows(); ++row)
481 {
482 m_pSerializer->startElementNS(XML_m, XML_mr);
483 for (size_t col = 0; col < pNode->GetNumCols(); ++col)
484 {
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 );
489 }
490 m_pSerializer->endElementNS( XML_m, XML_mr );
491 }
492 m_pSerializer->endElementNS( XML_m, XML_m );
493}
494
495void SmOoxmlExport::HandleBrace( const SmBraceNode* pNode, int nLevel )
496{
497 m_pSerializer->startElementNS(XML_m, XML_d);
498 m_pSerializer->startElementNS(XML_m, XML_dPr);
499
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()) );
506
507 std::vector< const SmNode* > subnodes;
508 if( pNode->Body()->GetType() == SmNodeType::Bracebody )
509 {
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)
513 {
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 )
519 {
520 m_pSerializer->singleElementNS( XML_m, XML_sepChr,
521 FSNS( XML_m, XML_val ), mathSymbolToString(math) );
522 separatorWritten = true;
523 }
524 }
525 else
526 subnodes.push_back( subnode );
527 }
528 }
529 else
530 subnodes.push_back( pNode->Body());
531
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()) );
537
538 m_pSerializer->endElementNS( XML_m, XML_dPr );
539 for(const SmNode* subnode : subnodes)
540 {
541 m_pSerializer->startElementNS(XML_m, XML_e);
542 HandleNode( subnode, nLevel + 1 );
543 m_pSerializer->endElementNS( XML_m, XML_e );
544 }
545 m_pSerializer->endElementNS( XML_m, XML_d );
546}
547
549{
550 SAL_INFO( "starmath.ooxml", "Vertical: " << int( pNode->GetToken().eType ));
551 switch( pNode->GetToken().eType )
552 {
553 case TOVERBRACE:
554 case TUNDERBRACE:
555 {
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;
579 }
580 default:
581 SAL_WARN("starmath.ooxml", "Unhandled vertical brace");
582 HandleAllSubNodes( pNode, nLevel );
583 break;
584 }
585}
586
588{
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 );
594}
595
596/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
::boost::spirit::classic::rule< ScannerT > argument
Attribute node.
Definition: node.hxx:1890
const SmNode * Body() const
Gets the body data ( the nodes affected by the attribute ).
Definition: node.hxx:1922
const SmNode * Attribute() const
Gets the attribute data.
Definition: node.hxx:1915
Node for brace construction.
Definition: node.hxx:1646
const SmMathSymbolNode * OpeningBrace() const
Returns the node containing the data of the opening brace.
Definition: node.hxx:1655
const SmNode * Body() const
Returns the node containing the data of what is between braces.
Definition: node.hxx:1667
const SmMathSymbolNode * ClosingBrace() const
Returns the node containing the data of the closing brace.
Definition: node.hxx:1674
Body of an SmBraceNode.
Definition: node.hxx:1710
Math symbol node.
Definition: node.hxx:955
Matrix node.
Definition: node.hxx:2000
sal_uInt16 GetNumRows() const
Gets the number of rows of the matrix.
Definition: node.hxx:2014
sal_uInt16 GetNumCols() const
Gets the number of columns of the matrix.
Definition: node.hxx:2020
Definition: node.hxx:125
virtual size_t GetNumSubNodes() const =0
Gets the number of subnodes.
const SmToken & GetToken() const
Gets the token.
Definition: node.hxx:387
virtual SmNode * GetSubNode(size_t nIndex)=0
Gets the subnode of index nIndex.
SmNodeType GetType() const
Gets the node type.
Definition: node.hxx:379
const SmFace & GetFont() const
Gets the font.
Definition: node.hxx:227
void HandleAttribute(const SmAttributeNode *pNode, int nLevel) override
SmOoxmlExport(const SmNode *pIn, oox::core::OoxmlVersion version, oox::drawingml::DocumentType documentType)
Definition: ooxmlexport.cxx:20
oox::drawingml::DocumentType const m_DocumentType
needed to determine markup for nested run properties
Definition: ooxmlexport.hxx:43
void HandleFractions(const SmNode *pNode, int nLevel, const char *type) override
void HandleVerticalStack(const SmNode *pNode, int nLevel) override
Definition: ooxmlexport.cxx:82
void HandleSubSupScriptInternal(const SmSubSupNode *pNode, int nLevel, int flags) override
::sax_fastparser::FSHelperPtr m_pSerializer
Definition: ooxmlexport.hxx:40
void HandleOperator(const SmOperNode *pNode, int nLevel) override
void HandleBrace(const SmBraceNode *pNode, int nLevel) override
void HandleRoot(const SmRootNode *pNode, int nLevel) override
void HandleVerticalBrace(const SmVerticalBraceNode *pNode, int nLevel) override
void HandleText(const SmNode *pNode, int nLevel) override
Definition: ooxmlexport.cxx:97
void ConvertFromStarMath(const ::sax_fastparser::FSHelperPtr &m_pSerializer, const sal_Int8)
Definition: ooxmlexport.cxx:28
void HandleMatrix(const SmMatrixNode *pNode, int nLevel) override
oox::core::OoxmlVersion version
Definition: ooxmlexport.hxx:41
void HandleBlank() override
Operation Node.
Definition: node.hxx:1811
const SmNode * GetSymbol() const
Returns the node with the operator data.
Definition: node.hxx:1820
Root node.
Definition: node.hxx:1307
const SmNode * Body() const
Returns the node containing the data inside the root.
Definition: node.hxx:1350
const SmNode * Argument() const
Returns the node containing the data of the order of the root.
Definition: node.hxx:1332
virtual size_t GetNumSubNodes() const override
Gets the number of subnodes.
Definition: node.cxx:430
virtual SmNode * GetSubNode(size_t nIndex) override
Gets the subnode of index nIndex.
Definition: node.cxx:435
Super- and subscript node.
Definition: node.hxx:1559
const SmNode * GetBody() const
Returns the node with the data of what has to be superindex or subindex.
Definition: node.hxx:1571
const SmNode * GetSubSup(SmSubSup eSubSup) const
Gets the node with the data of what has to be superindex or subindex.
Definition: node.hxx:1595
Text node.
Definition: node.hxx:747
static sal_Unicode ConvertSymbolToUnicode(sal_Unicode nIn)
Converts the character from StarMath's private area symbols to a matching Unicode character,...
Definition: node.cxx:1899
const OUString & GetText() const
Gets the node text.
Definition: node.hxx:782
Node for vertical brace construction.
Definition: node.hxx:1750
const SmMathSymbolNode * Brace() const
Returns the node containing the data of the brace.
Definition: node.hxx:1767
const SmNode * Script() const
Returns the node containing the data of what is in the brace.
Definition: node.hxx:1780
const SmNode * Body() const
Returns the node containing the data of what the brace is pointing for.
Definition: node.hxx:1760
Base class implementing writing of formulas to Word.
void HandleAllSubNodes(const SmNode *pNode, int nLevel)
const SmNode * GetTree() const
void HandleNode(const SmNode *pNode, int nLevel)
FontItalic GetItalic()
FontWeight GetWeight()
Any value
const char * pS
OString top
float v
ITALIC_NORMAL
WEIGHT_BOLD
constexpr sal_Int32 FSNS(sal_Int32 namespc, sal_Int32 element)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
RttiCompleteObjectLocator col
double getLength(const B2DPolygon &rCandidate)
size
int i
OoxmlVersion
ECMA_376_1ST_EDITION
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
END
XML_type
@ LSUB
Definition: node.hxx:1536
@ CSUB
Definition: node.hxx:1536
@ RSUP
Definition: node.hxx:1536
@ RSUB
Definition: node.hxx:1536
@ LSUP
Definition: node.hxx:1536
@ CSUP
Definition: node.hxx:1536
static OString mathSymbolToString(const SmNode *node)
SmTokenType eType
Definition: token.hxx:213
OUString cMathChar
Definition: token.hxx:214
@ TDDDOT
Definition: token.hxx:137
@ TWIDEHAT
Definition: token.hxx:121
@ TCHECK
Definition: token.hxx:123
@ TBREVE
Definition: token.hxx:120
@ TWIDEHARPOON
Definition: token.hxx:121
@ TGRAVE
Definition: token.hxx:120
@ TDOT
Definition: token.hxx:137
@ TBAR
Definition: token.hxx:118
@ TUNDERLINE
Definition: token.hxx:118
@ TACUTE
Definition: token.hxx:120
@ TIINT
Definition: token.hxx:135
@ TWIDEVEC
Definition: token.hxx:121
@ TNONE
Definition: token.hxx:74
@ TTILDE
Definition: token.hxx:122
@ THAT
Definition: token.hxx:120
@ TVEC
Definition: token.hxx:122
@ TDDOT
Definition: token.hxx:137
@ TUNDERBRACE
Definition: token.hxx:126
@ TPROD
Definition: token.hxx:83
@ TLIM
Definition: token.hxx:86
@ TOVERLINE
Definition: token.hxx:118
@ TLLLINT
Definition: token.hxx:136
@ TLINT
Definition: token.hxx:136
@ TIIINT
Definition: token.hxx:135
@ TINT
Definition: token.hxx:135
@ TLLINT
Definition: token.hxx:136
@ TWIDETILDE
Definition: token.hxx:121
@ TTEXT
Definition: token.hxx:124
@ TINTD
Definition: token.hxx:135
@ TOVERBRACE
Definition: token.hxx:126
@ TCIRCLE
Definition: token.hxx:122
@ TCOPROD
Definition: token.hxx:83
@ TSUM
Definition: token.hxx:83
@ TOVERSTRIKE
Definition: token.hxx:118
unsigned char sal_uInt8
sal_uInt16 sal_Unicode
signed char sal_Int8
ResultType type