Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * Version: MPL 1.1 / GPLv3+ / LGPLv3+
4 : : *
5 : : * The contents of this file are subject to the Mozilla Public License Version
6 : : * 1.1 (the "License"); you may not use this file except in compliance with
7 : : * the License or as specified alternatively below. You may obtain a copy of
8 : : * the License at http://www.mozilla.org/MPL/
9 : : *
10 : : * Software distributed under the License is distributed on an "AS IS" basis,
11 : : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : : * for the specific language governing rights and limitations under the
13 : : * License.
14 : : *
15 : : * Major Contributor(s):
16 : : * Copyright (C) 2011 Lubos Lunak <l.lunak@suse.cz> (initial developer)
17 : : *
18 : : * All Rights Reserved.
19 : : *
20 : : * For minor contributions see the git repository.
21 : : *
22 : : * Alternatively, the contents of this file may be used under the terms of
23 : : * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
24 : : * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
25 : : * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
26 : : * instead of those above.
27 : : */
28 : :
29 : :
30 : : #include "ooxmlexport.hxx"
31 : :
32 : : #include <oox/token/tokens.hxx>
33 : : #include <rtl/oustringostreaminserter.hxx>
34 : :
35 : : using namespace oox;
36 : : using namespace oox::core;
37 : :
38 : 126 : SmOoxmlExport::SmOoxmlExport( const SmNode* pIn, OoxmlVersion v )
39 : : : SmWordExportBase( pIn )
40 [ + - ]: 126 : , version( v )
41 : : {
42 : 126 : }
43 : :
44 : 126 : bool SmOoxmlExport::ConvertFromStarMath( ::sax_fastparser::FSHelperPtr serializer )
45 : : {
46 [ - + ]: 126 : if( m_pTree == NULL )
47 : 0 : return false;
48 : 126 : m_pSerializer = serializer;
49 : : m_pSerializer->startElementNS( XML_m, XML_oMath,
50 : 126 : FSNS( XML_xmlns, XML_m ), "http://schemas.openxmlformats.org/officeDocument/2006/math", FSEND );
51 : 126 : HandleNode( m_pTree, 0 );
52 : 126 : m_pSerializer->endElementNS( XML_m, XML_oMath );
53 : 126 : return true;
54 : : }
55 : :
56 : : // NOTE: This is still work in progress and unfinished, but it already covers a good
57 : : // part of the ooxml math stuff.
58 : :
59 : 12 : void SmOoxmlExport::HandleVerticalStack( const SmNode* pNode, int nLevel )
60 : : {
61 : 12 : m_pSerializer->startElementNS( XML_m, XML_eqArr, FSEND );
62 : 12 : int size = pNode->GetNumSubNodes();
63 [ + + ]: 36 : for( int i = 0;
64 : : i < size;
65 : : ++i )
66 : : {
67 : 24 : m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
68 : 24 : HandleNode( pNode->GetSubNode( i ), nLevel + 1 );
69 : 24 : m_pSerializer->endElementNS( XML_m, XML_e );
70 : : }
71 : 12 : m_pSerializer->endElementNS( XML_m, XML_eqArr );
72 : 12 : }
73 : :
74 : 726 : void SmOoxmlExport::HandleText( const SmNode* pNode, int /*nLevel*/)
75 : : {
76 : 726 : m_pSerializer->startElementNS( XML_m, XML_r, FSEND );
77 : :
78 [ - + ]: 726 : if( version == ECMA_DIALECT )
79 : : { // HACK: MSOffice2007 does not import characters properly unless this font is explicitly given
80 : 0 : m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
81 : : m_pSerializer->singleElementNS( XML_w, XML_rFonts, FSNS( XML_w, XML_ascii ), "Cambria Math",
82 : 0 : FSNS( XML_w, XML_hAnsi ), "Cambria Math", FSEND );
83 : 0 : m_pSerializer->endElementNS( XML_w, XML_rPr );
84 : : }
85 : 726 : m_pSerializer->startElementNS( XML_m, XML_t, FSNS( XML_xml, XML_space ), "preserve", FSEND );
86 : 726 : SmTextNode* pTemp=(SmTextNode* )pNode;
87 : : SAL_INFO( "starmath.ooxml", "Text:" << OUStringToOString( pTemp->GetText(), RTL_TEXTENCODING_UTF8 ).getStr());
88 [ + + ]: 1557 : for(xub_StrLen i=0;i<pTemp->GetText().Len();i++)
89 : : {
90 : : #if 0
91 : : if ((nPendingAttributes) &&
92 : : (i == ((pTemp->GetText().Len()+1)/2)-1))
93 : : {
94 : : *pS << sal_uInt8(0x22); //char, with attributes right
95 : : //after the character
96 : : }
97 : : else
98 : : *pS << sal_uInt8(CHAR);
99 : :
100 : : sal_uInt8 nFace = 0x1;
101 : : if (pNode->GetFont().GetItalic() == ITALIC_NORMAL)
102 : : nFace = 0x3;
103 : : else if (pNode->GetFont().GetWeight() == WEIGHT_BOLD)
104 : : nFace = 0x7;
105 : : *pS << sal_uInt8(nFace+128); //typeface
106 : : #endif
107 : 831 : sal_uInt16 nChar = pTemp->GetText().GetChar(i);
108 [ + - ]: 831 : m_pSerializer->writeEscaped( OUString( SmTextNode::ConvertSymbolToUnicode(nChar)));
109 : :
110 : : #if 0
111 : : //Mathtype can only have these sort of character
112 : : //attributes on a single character, starmath can put them
113 : : //anywhere, when the entity involved is a text run this is
114 : : //a large effort to place the character attribute on the
115 : : //central mathtype character so that it does pretty much
116 : : //what the user probably has in mind. The attributes
117 : : //filled in here are dummy ones which are replaced in the
118 : : //ATTRIBUT handler if a suitable location for the
119 : : //attributes was found here. Unfortunately it is
120 : : //possible for starmath to place character attributes on
121 : : //entities which cannot occur in mathtype e.g. a Summation
122 : : //symbol so these attributes may be lost
123 : : if ((nPendingAttributes) &&
124 : : (i == ((pTemp->GetText().Len()+1)/2)-1))
125 : : {
126 : : *pS << sal_uInt8(EMBEL);
127 : : while (nPendingAttributes)
128 : : {
129 : : *pS << sal_uInt8(2);
130 : : //wedge the attributes in here and clear
131 : : //the pending stack
132 : : nPendingAttributes--;
133 : : }
134 : : nInsertion=pS->Tell();
135 : : *pS << sal_uInt8(END); //end embel
136 : : *pS << sal_uInt8(END); //end embel
137 : : }
138 : : #endif
139 : : }
140 : 726 : m_pSerializer->endElementNS( XML_m, XML_t );
141 : 726 : m_pSerializer->endElementNS( XML_m, XML_r );
142 : 726 : }
143 : :
144 : 45 : void SmOoxmlExport::HandleFractions( const SmNode* pNode, int nLevel, const char* type )
145 : : {
146 : 45 : m_pSerializer->startElementNS( XML_m, XML_f, FSEND );
147 [ + + ]: 45 : if( type != NULL )
148 : : {
149 : 3 : m_pSerializer->startElementNS( XML_m, XML_fPr, FSEND );
150 : 3 : m_pSerializer->singleElementNS( XML_m, XML_type, FSNS( XML_m, XML_val ), type, FSEND );
151 : 3 : m_pSerializer->endElementNS( XML_m, XML_fPr );
152 : : }
153 : : OSL_ASSERT( pNode->GetNumSubNodes() == 3 );
154 : 45 : m_pSerializer->startElementNS( XML_m, XML_num, FSEND );
155 : 45 : HandleNode( pNode->GetSubNode( 0 ), nLevel + 1 );
156 : 45 : m_pSerializer->endElementNS( XML_m, XML_num );
157 : 45 : m_pSerializer->startElementNS( XML_m, XML_den, FSEND );
158 : 45 : HandleNode( pNode->GetSubNode( 2 ), nLevel + 1 );
159 : 45 : m_pSerializer->endElementNS( XML_m, XML_den );
160 : 45 : m_pSerializer->endElementNS( XML_m, XML_f );
161 : 45 : }
162 : :
163 : 42 : void SmOoxmlExport::HandleAttribute( const SmAttributNode* pNode, int nLevel )
164 : : {
165 [ + + + - ]: 42 : switch( pNode->Attribute()->GetToken().eType )
166 : : {
167 : : case TCHECK:
168 : : case TACUTE:
169 : : case TGRAVE:
170 : : case TBREVE:
171 : : case TCIRCLE:
172 : : case TVEC:
173 : : case TTILDE:
174 : : case THAT:
175 : : case TDOT:
176 : : case TDDOT:
177 : : case TDDDOT:
178 : : case TWIDETILDE:
179 : : case TWIDEHAT:
180 : : case TWIDEVEC:
181 : : case TBAR:
182 : : {
183 [ + - ]: 36 : m_pSerializer->startElementNS( XML_m, XML_acc, FSEND );
184 [ + - ]: 36 : m_pSerializer->startElementNS( XML_m, XML_accPr, FSEND );
185 : : OString value = OUStringToOString(
186 [ + - ][ + - ]: 36 : OUString( pNode->Attribute()->GetToken().cMathChar ), RTL_TEXTENCODING_UTF8 );
187 [ + - ]: 36 : m_pSerializer->singleElementNS( XML_m, XML_chr, FSNS( XML_m, XML_val ), value.getStr(), FSEND );
188 [ + - ]: 36 : m_pSerializer->endElementNS( XML_m, XML_accPr );
189 [ + - ]: 36 : m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
190 [ + - ][ + - ]: 36 : HandleNode( pNode->Body(), nLevel + 1 );
191 [ + - ]: 36 : m_pSerializer->endElementNS( XML_m, XML_e );
192 [ + - ]: 36 : m_pSerializer->endElementNS( XML_m, XML_acc );
193 : 36 : break;
194 : : }
195 : : case TOVERLINE:
196 : : case TUNDERLINE:
197 : 3 : m_pSerializer->startElementNS( XML_m, XML_bar, FSEND );
198 : 3 : m_pSerializer->startElementNS( XML_m, XML_barPr, FSEND );
199 : : m_pSerializer->singleElementNS( XML_m, XML_pos, FSNS( XML_m, XML_val ),
200 [ + - ]: 3 : ( pNode->Attribute()->GetToken().eType == TUNDERLINE ) ? "bot" : "top", FSEND );
201 : 3 : m_pSerializer->endElementNS( XML_m, XML_barPr );
202 : 3 : m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
203 : 3 : HandleNode( pNode->Body(), nLevel + 1 );
204 : 3 : m_pSerializer->endElementNS( XML_m, XML_e );
205 : 3 : m_pSerializer->endElementNS( XML_m, XML_bar );
206 : 3 : break;
207 : : case TOVERSTRIKE:
208 : 3 : m_pSerializer->startElementNS( XML_m, XML_borderBox, FSEND );
209 : 3 : m_pSerializer->startElementNS( XML_m, XML_borderBoxPr, FSEND );
210 : 3 : m_pSerializer->singleElementNS( XML_m, XML_hideTop, FSNS( XML_m, XML_val ), "1", FSEND );
211 : 3 : m_pSerializer->singleElementNS( XML_m, XML_hideBot, FSNS( XML_m, XML_val ), "1", FSEND );
212 : 3 : m_pSerializer->singleElementNS( XML_m, XML_hideLeft, FSNS( XML_m, XML_val ), "1", FSEND );
213 : 3 : m_pSerializer->singleElementNS( XML_m, XML_hideRight, FSNS( XML_m, XML_val ), "1", FSEND );
214 : 3 : m_pSerializer->singleElementNS( XML_m, XML_strikeH, FSNS( XML_m, XML_val ), "1", FSEND );
215 : 3 : m_pSerializer->endElementNS( XML_m, XML_borderBoxPr );
216 : 3 : m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
217 : 3 : HandleNode( pNode->Body(), nLevel + 1 );
218 : 3 : m_pSerializer->endElementNS( XML_m, XML_e );
219 : 3 : m_pSerializer->endElementNS( XML_m, XML_borderBox );
220 : 3 : break;
221 : : default:
222 : 0 : HandleAllSubNodes( pNode, nLevel );
223 : 0 : break;
224 : : }
225 : 42 : }
226 : :
227 : 9 : void SmOoxmlExport::HandleRoot( const SmRootNode* pNode, int nLevel )
228 : : {
229 : 9 : m_pSerializer->startElementNS( XML_m, XML_rad, FSEND );
230 [ + + ]: 9 : if( const SmNode* argument = pNode->Argument())
231 : : {
232 : 3 : m_pSerializer->startElementNS( XML_m, XML_deg, FSEND );
233 : 3 : HandleNode( argument, nLevel + 1 );
234 : 3 : m_pSerializer->endElementNS( XML_m, XML_deg );
235 : : }
236 : : else
237 : : {
238 : 6 : m_pSerializer->startElementNS( XML_m, XML_radPr, FSEND );
239 : 6 : m_pSerializer->singleElementNS( XML_m, XML_degHide, FSNS( XML_m, XML_val ), "1", FSEND );
240 : 6 : m_pSerializer->endElementNS( XML_m, XML_radPr );
241 : 6 : m_pSerializer->singleElementNS( XML_m, XML_deg, FSEND ); // empty but present
242 : : }
243 : 9 : m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
244 : 9 : HandleNode( pNode->Body(), nLevel + 1 );
245 : 9 : m_pSerializer->endElementNS( XML_m, XML_e );
246 : 9 : m_pSerializer->endElementNS( XML_m, XML_rad );
247 : 9 : }
248 : :
249 : 162 : static OString mathSymbolToString( const SmNode* node )
250 : : {
251 : : assert( node->GetType() == NMATH );
252 : 162 : const SmTextNode* txtnode = static_cast< const SmTextNode* >( node );
253 : : assert( txtnode->GetText().Len() == 1 );
254 : 162 : sal_Unicode chr = SmTextNode::ConvertSymbolToUnicode( txtnode->GetText().GetChar( 0 ));
255 [ + - ]: 162 : return OUStringToOString( OUString( chr ), RTL_TEXTENCODING_UTF8 );
256 : : }
257 : :
258 : 21 : void SmOoxmlExport::HandleOperator( const SmOperNode* pNode, int nLevel )
259 : : {
260 : : SAL_INFO( "starmath.ooxml", "Operator: " << int( pNode->GetToken().eType ));
261 [ + + - ]: 21 : switch( pNode->GetToken().eType )
262 : : {
263 : : case TINT:
264 : : case TIINT:
265 : : case TIIINT:
266 : : case TLINT:
267 : : case TLLINT:
268 : : case TLLLINT:
269 : : case TPROD:
270 : : case TCOPROD:
271 : : case TSUM:
272 : : {
273 : 18 : const SmSubSupNode* subsup = pNode->GetSubNode( 0 )->GetType() == NSUBSUP
274 [ + - ]: 18 : ? static_cast< const SmSubSupNode* >( pNode->GetSubNode( 0 )) : NULL;
275 [ + - ]: 18 : const SmNode* operation = subsup != NULL ? subsup->GetBody() : pNode->GetSubNode( 0 );
276 : 18 : m_pSerializer->startElementNS( XML_m, XML_nary, FSEND );
277 : 18 : m_pSerializer->startElementNS( XML_m, XML_naryPr, FSEND );
278 : : m_pSerializer->singleElementNS( XML_m, XML_chr,
279 [ + - ]: 18 : FSNS( XML_m, XML_val ), mathSymbolToString( operation ).getStr(), FSEND );
280 [ + + ][ + + ]: 18 : if( subsup == NULL || subsup->GetSubSup( CSUB ) == NULL )
[ + - ]
281 : 3 : m_pSerializer->singleElementNS( XML_m, XML_subHide, FSNS( XML_m, XML_val ), "1", FSEND );
282 [ + - ][ + + ]: 18 : if( subsup == NULL || subsup->GetSubSup( CSUP ) == NULL )
[ + + ]
283 : 3 : m_pSerializer->singleElementNS( XML_m, XML_supHide, FSNS( XML_m, XML_val ), "1", FSEND );
284 : 18 : m_pSerializer->endElementNS( XML_m, XML_naryPr );
285 [ + + ][ + + ]: 18 : if( subsup == NULL || subsup->GetSubSup( CSUB ) == NULL )
[ + - ]
286 : 3 : m_pSerializer->singleElementNS( XML_m, XML_sub, FSEND );
287 : : else
288 : : {
289 : 15 : m_pSerializer->startElementNS( XML_m, XML_sub, FSEND );
290 : 15 : HandleNode( subsup->GetSubSup( CSUB ), nLevel + 1 );
291 : 15 : m_pSerializer->endElementNS( XML_m, XML_sub );
292 : : }
293 [ + - ][ + + ]: 18 : if( subsup == NULL || subsup->GetSubSup( CSUP ) == NULL )
[ + + ]
294 : 3 : m_pSerializer->singleElementNS( XML_m, XML_sup, FSEND );
295 : : else
296 : : {
297 : 15 : m_pSerializer->startElementNS( XML_m, XML_sup, FSEND );
298 : 15 : HandleNode( subsup->GetSubSup( CSUP ), nLevel + 1 );
299 : 15 : m_pSerializer->endElementNS( XML_m, XML_sup );
300 : : }
301 : 18 : m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
302 : 18 : HandleNode( pNode->GetSubNode( 1 ), nLevel + 1 ); // body
303 : 18 : m_pSerializer->endElementNS( XML_m, XML_e );
304 : 18 : m_pSerializer->endElementNS( XML_m, XML_nary );
305 : 18 : break;
306 : : }
307 : : case TLIM:
308 : 3 : m_pSerializer->startElementNS( XML_m, XML_func, FSEND );
309 : 3 : m_pSerializer->startElementNS( XML_m, XML_fName, FSEND );
310 : 3 : m_pSerializer->startElementNS( XML_m, XML_limLow, FSEND );
311 : 3 : m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
312 : 3 : HandleNode( pNode->GetSymbol(), nLevel + 1 );
313 : 3 : m_pSerializer->endElementNS( XML_m, XML_e );
314 : 3 : m_pSerializer->startElementNS( XML_m, XML_lim, FSEND );
315 [ + - ]: 6 : if( const SmSubSupNode* subsup = pNode->GetSubNode( 0 )->GetType() == NSUBSUP
316 [ + - ]: 3 : ? static_cast< const SmSubSupNode* >( pNode->GetSubNode( 0 )) : NULL )
317 : : {
318 [ + - ]: 3 : if( subsup->GetSubSup( CSUB ) != NULL )
319 : 3 : HandleNode( subsup->GetSubSup( CSUB ), nLevel + 1 );
320 : : }
321 : 3 : m_pSerializer->endElementNS( XML_m, XML_lim );
322 : 3 : m_pSerializer->endElementNS( XML_m, XML_limLow );
323 : 3 : m_pSerializer->endElementNS( XML_m, XML_fName );
324 : 3 : m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
325 : 3 : HandleNode( pNode->GetSubNode( 1 ), nLevel + 1 ); // body
326 : 3 : m_pSerializer->endElementNS( XML_m, XML_e );
327 : 3 : m_pSerializer->endElementNS( XML_m, XML_func );
328 : 3 : break;
329 : : default:
330 : : OSL_FAIL( "Unhandled operation" );
331 : 0 : HandleAllSubNodes( pNode, nLevel );
332 : 0 : break;
333 : : }
334 : 21 : }
335 : :
336 : 78 : void SmOoxmlExport::HandleSubSupScriptInternal( const SmSubSupNode* pNode, int nLevel, int flags )
337 : : {
338 : : // docx supports only a certain combination of sub/super scripts, but LO can have any,
339 : : // so try to merge it using several tags if necessary
340 [ - + ]: 78 : if( flags == 0 ) // none
341 : 78 : return;
342 [ + + ]: 78 : if(( flags & ( 1 << RSUP | 1 << RSUB )) == ( 1 << RSUP | 1 << RSUB ))
343 : : { // m:sSubSup
344 : 6 : m_pSerializer->startElementNS( XML_m, XML_sSubSup, FSEND );
345 : 6 : m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
346 : 6 : flags &= ~( 1 << RSUP | 1 << RSUB );
347 [ + - ]: 6 : if( flags == 0 )
348 : 6 : HandleNode( pNode->GetBody(), nLevel + 1 );
349 : : else
350 : 0 : HandleSubSupScriptInternal( pNode, nLevel, flags );
351 : 6 : m_pSerializer->endElementNS( XML_m, XML_e );
352 : 6 : m_pSerializer->startElementNS( XML_m, XML_sub, FSEND );
353 : 6 : HandleNode( pNode->GetSubSup( RSUB ), nLevel + 1 );
354 : 6 : m_pSerializer->endElementNS( XML_m, XML_sub );
355 : 6 : m_pSerializer->startElementNS( XML_m, XML_sup, FSEND );
356 : 6 : HandleNode( pNode->GetSubSup( RSUP ), nLevel + 1 );
357 : 6 : m_pSerializer->endElementNS( XML_m, XML_sup );
358 : 6 : m_pSerializer->endElementNS( XML_m, XML_sSubSup );
359 : : }
360 [ + + ]: 72 : else if(( flags & ( 1 << RSUB )) == 1 << RSUB )
361 : : { // m:sSub
362 : 12 : m_pSerializer->startElementNS( XML_m, XML_sSub, FSEND );
363 : 12 : m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
364 : 12 : flags &= ~( 1 << RSUB );
365 [ + - ]: 12 : if( flags == 0 )
366 : 12 : HandleNode( pNode->GetBody(), nLevel + 1 );
367 : : else
368 : 0 : HandleSubSupScriptInternal( pNode, nLevel, flags );
369 : 12 : m_pSerializer->endElementNS( XML_m, XML_e );
370 : 12 : m_pSerializer->startElementNS( XML_m, XML_sub, FSEND );
371 : 12 : HandleNode( pNode->GetSubSup( RSUB ), nLevel + 1 );
372 : 12 : m_pSerializer->endElementNS( XML_m, XML_sub );
373 : 12 : m_pSerializer->endElementNS( XML_m, XML_sSub );
374 : : }
375 [ + + ]: 60 : else if(( flags & ( 1 << RSUP )) == 1 << RSUP )
376 : : { // m:sSup
377 : 48 : m_pSerializer->startElementNS( XML_m, XML_sSup, FSEND );
378 : 48 : m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
379 : 48 : flags &= ~( 1 << RSUP );
380 [ + - ]: 48 : if( flags == 0 )
381 : 48 : HandleNode( pNode->GetBody(), nLevel + 1 );
382 : : else
383 : 0 : HandleSubSupScriptInternal( pNode, nLevel, flags );
384 : 48 : m_pSerializer->endElementNS( XML_m, XML_e );
385 : 48 : m_pSerializer->startElementNS( XML_m, XML_sup, FSEND );
386 : 48 : HandleNode( pNode->GetSubSup( RSUP ), nLevel + 1 );
387 : 48 : m_pSerializer->endElementNS( XML_m, XML_sup );
388 : 48 : m_pSerializer->endElementNS( XML_m, XML_sSup );
389 : : }
390 [ + + ]: 12 : else if(( flags & ( 1 << LSUP | 1 << LSUB )) == ( 1 << LSUP | 1 << LSUB ))
391 : : { // m:sPre
392 : 6 : m_pSerializer->startElementNS( XML_m, XML_sPre, FSEND );
393 : 6 : m_pSerializer->startElementNS( XML_m, XML_sub, FSEND );
394 : 6 : HandleNode( pNode->GetSubSup( LSUB ), nLevel + 1 );
395 : 6 : m_pSerializer->endElementNS( XML_m, XML_sub );
396 : 6 : m_pSerializer->startElementNS( XML_m, XML_sup, FSEND );
397 : 6 : HandleNode( pNode->GetSubSup( LSUP ), nLevel + 1 );
398 : 6 : m_pSerializer->endElementNS( XML_m, XML_sup );
399 : 6 : m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
400 : 6 : flags &= ~( 1 << LSUP | 1 << LSUB );
401 [ + - ]: 6 : if( flags == 0 )
402 : 6 : HandleNode( pNode->GetBody(), nLevel + 1 );
403 : : else
404 : 0 : HandleSubSupScriptInternal( pNode, nLevel, flags );
405 : 6 : m_pSerializer->endElementNS( XML_m, XML_e );
406 : 6 : m_pSerializer->endElementNS( XML_m, XML_sPre );
407 : : }
408 [ + + ]: 6 : else if(( flags & ( 1 << CSUB )) == ( 1 << CSUB ))
409 : : { // m:limLow looks like a good element for central superscript
410 : 3 : m_pSerializer->startElementNS( XML_m, XML_limLow, FSEND );
411 : 3 : m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
412 : 3 : flags &= ~( 1 << CSUB );
413 [ - + ]: 3 : if( flags == 0 )
414 : 0 : HandleNode( pNode->GetBody(), nLevel + 1 );
415 : : else
416 : 3 : HandleSubSupScriptInternal( pNode, nLevel, flags );
417 : 3 : m_pSerializer->endElementNS( XML_m, XML_e );
418 : 3 : m_pSerializer->startElementNS( XML_m, XML_lim, FSEND );
419 : 3 : HandleNode( pNode->GetSubSup( CSUB ), nLevel + 1 );
420 : 3 : m_pSerializer->endElementNS( XML_m, XML_lim );
421 : 3 : m_pSerializer->endElementNS( XML_m, XML_limLow );
422 : : }
423 [ + - ]: 3 : else if(( flags & ( 1 << CSUP )) == ( 1 << CSUP ))
424 : : { // m:limUpp looks like a good element for central superscript
425 : 3 : m_pSerializer->startElementNS( XML_m, XML_limUpp, FSEND );
426 : 3 : m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
427 : 3 : flags &= ~( 1 << CSUP );
428 [ + - ]: 3 : if( flags == 0 )
429 : 3 : HandleNode( pNode->GetBody(), nLevel + 1 );
430 : : else
431 : 0 : HandleSubSupScriptInternal( pNode, nLevel, flags );
432 : 3 : m_pSerializer->endElementNS( XML_m, XML_e );
433 : 3 : m_pSerializer->startElementNS( XML_m, XML_lim, FSEND );
434 : 3 : HandleNode( pNode->GetSubSup( CSUP ), nLevel + 1 );
435 : 3 : m_pSerializer->endElementNS( XML_m, XML_lim );
436 : 3 : m_pSerializer->endElementNS( XML_m, XML_limUpp );
437 : : }
438 : : else
439 : : {
440 : : OSL_FAIL( "Unhandled sub/sup combination" );
441 : : // TODO do not do anything, this should be probably an assert()
442 : : // HandleAllSubNodes( pNode, nLevel );
443 : : }
444 : : }
445 : :
446 : 3 : void SmOoxmlExport::HandleMatrix( const SmMatrixNode* pNode, int nLevel )
447 : : {
448 : 3 : m_pSerializer->startElementNS( XML_m, XML_m, FSEND );
449 [ + + ]: 9 : for( int row = 0; row < pNode->GetNumRows(); ++row )
450 : : {
451 : 6 : m_pSerializer->startElementNS( XML_m, XML_mr, FSEND );
452 [ + + ]: 18 : for( int col = 0; col < pNode->GetNumCols(); ++col )
453 : : {
454 : 12 : m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
455 [ + - ]: 12 : if( const SmNode* node = pNode->GetSubNode( row * pNode->GetNumCols() + col ))
456 : 12 : HandleNode( node, nLevel + 1 );
457 : 12 : m_pSerializer->endElementNS( XML_m, XML_e );
458 : : }
459 : 6 : m_pSerializer->endElementNS( XML_m, XML_mr );
460 : : }
461 : 3 : m_pSerializer->endElementNS( XML_m, XML_m );
462 : 3 : }
463 : :
464 : 66 : void SmOoxmlExport::HandleBrace( const SmBraceNode* pNode, int nLevel )
465 : : {
466 [ + - ]: 66 : m_pSerializer->startElementNS( XML_m, XML_d, FSEND );
467 [ + - ]: 66 : m_pSerializer->startElementNS( XML_m, XML_dPr, FSEND );
468 : : m_pSerializer->singleElementNS( XML_m, XML_begChr,
469 [ + - ][ + - ]: 66 : FSNS( XML_m, XML_val ), mathSymbolToString( pNode->OpeningBrace()).getStr(), FSEND );
[ + - ]
470 [ + - ]: 66 : std::vector< const SmNode* > subnodes;
471 [ + - ][ + - ]: 66 : if( pNode->Body()->GetType() == NBRACEBODY )
472 : : {
473 [ + - ]: 66 : const SmBracebodyNode* body = static_cast< const SmBracebodyNode* >( pNode->Body());
474 : 66 : bool separatorWritten = false; // assume all separators are the same
475 [ + - ][ + + ]: 144 : for( int i = 0; i < body->GetNumSubNodes(); ++i )
476 : : {
477 [ + - ]: 78 : const SmNode* subnode = body->GetSubNode( i );
478 [ + + ]: 78 : if( subnode->GetType() == NMATH )
479 : : { // do not write, but write what separator it is
480 : 9 : const SmMathSymbolNode* math = static_cast< const SmMathSymbolNode* >( subnode );
481 [ + + ]: 9 : if( !separatorWritten )
482 : : {
483 : : m_pSerializer->singleElementNS( XML_m, XML_sepChr,
484 [ + - ][ + - ]: 6 : FSNS( XML_m, XML_val ), mathSymbolToString( math ).getStr(), FSEND );
485 : 6 : separatorWritten = true;
486 : : }
487 : : }
488 : : else
489 [ + - ]: 69 : subnodes.push_back( subnode );
490 : : }
491 : : }
492 : : else
493 [ # # ][ # # ]: 0 : subnodes.push_back( pNode->Body());
494 : : m_pSerializer->singleElementNS( XML_m, XML_endChr,
495 [ + - ][ + - ]: 66 : FSNS( XML_m, XML_val ), mathSymbolToString( pNode->ClosingBrace()).getStr(), FSEND );
[ + - ]
496 [ + - ]: 66 : m_pSerializer->endElementNS( XML_m, XML_dPr );
497 [ + + ]: 135 : for( unsigned int i = 0; i < subnodes.size(); ++i )
498 : : {
499 [ + - ]: 69 : m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
500 [ + - ]: 69 : HandleNode( subnodes[ i ], nLevel + 1 );
501 [ + - ]: 69 : m_pSerializer->endElementNS( XML_m, XML_e );
502 : : }
503 [ + - ]: 66 : m_pSerializer->endElementNS( XML_m, XML_d );
504 : 66 : }
505 : :
506 : 6 : void SmOoxmlExport::HandleVerticalBrace( const SmVerticalBraceNode* pNode, int nLevel )
507 : : {
508 : : SAL_INFO( "starmath.ooxml", "Vertical: " << int( pNode->GetToken().eType ));
509 [ + - ]: 6 : switch( pNode->GetToken().eType )
510 : : {
511 : : case TOVERBRACE:
512 : : case TUNDERBRACE:
513 : : {
514 : 6 : bool top = ( pNode->GetToken().eType == TOVERBRACE );
515 [ + + ]: 6 : m_pSerializer->startElementNS( XML_m, top ? XML_limUpp : XML_limLow, FSEND );
516 : 6 : m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
517 : 6 : m_pSerializer->startElementNS( XML_m, XML_groupChr, FSEND );
518 : 6 : m_pSerializer->startElementNS( XML_m, XML_groupChrPr, FSEND );
519 : : m_pSerializer->singleElementNS( XML_m, XML_chr,
520 [ + - ]: 6 : FSNS( XML_m, XML_val ), mathSymbolToString( pNode->Brace()).getStr(), FSEND );
521 : : // TODO not sure if pos and vertJc are correct
522 : : m_pSerializer->singleElementNS( XML_m, XML_pos,
523 [ + + ]: 6 : FSNS( XML_m, XML_val ), top ? "top" : "bot", FSEND );
524 [ + + ]: 6 : m_pSerializer->singleElementNS( XML_m, XML_vertJc, FSNS( XML_m, XML_val ), top ? "bot" : "top", FSEND );
525 : 6 : m_pSerializer->endElementNS( XML_m, XML_groupChrPr );
526 : 6 : m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
527 : 6 : HandleNode( pNode->Body(), nLevel + 1 );
528 : 6 : m_pSerializer->endElementNS( XML_m, XML_e );
529 : 6 : m_pSerializer->endElementNS( XML_m, XML_groupChr );
530 : 6 : m_pSerializer->endElementNS( XML_m, XML_e );
531 : 6 : m_pSerializer->startElementNS( XML_m, XML_lim, FSEND );
532 : 6 : HandleNode( pNode->Script(), nLevel + 1 );
533 : 6 : m_pSerializer->endElementNS( XML_m, XML_lim );
534 [ + + ]: 6 : m_pSerializer->endElementNS( XML_m, top ? XML_limUpp : XML_limLow );
535 : 6 : break;
536 : : }
537 : : default:
538 : : OSL_FAIL( "Unhandled vertical brace" );
539 : 0 : HandleAllSubNodes( pNode, nLevel );
540 : 0 : break;
541 : : }
542 : 6 : }
543 : :
544 : 0 : void SmOoxmlExport::HandleBlank()
545 : : {
546 : 0 : m_pSerializer->startElementNS( XML_m, XML_r, FSEND );
547 : 0 : m_pSerializer->startElementNS( XML_m, XML_t, FSNS( XML_xml, XML_space ), "preserve", FSEND );
548 : 0 : m_pSerializer->write( " " );
549 : 0 : m_pSerializer->endElementNS( XML_m, XML_t );
550 : 0 : m_pSerializer->endElementNS( XML_m, XML_r );
551 [ + - ][ + - ]: 30 : }
552 : :
553 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|