Line data Source code
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 :
11 : #include "ooxmlimport.hxx"
12 :
13 : #include <oox/token/tokens.hxx>
14 : #include <oox/token/namespaces.hxx>
15 : #include <rtl/ustring.hxx>
16 :
17 : using namespace oox;
18 : using namespace oox::formulaimport;
19 :
20 : /*
21 : The primary internal data structure for the formula is the text representation
22 : (the SmNode tree is built from it), so read data must be converted into this format.
23 : */
24 :
25 : #define M_TOKEN( token ) OOX_TOKEN( officeMath, token )
26 : #define OPENING( token ) XML_STREAM_OPENING( token )
27 : #define CLOSING( token ) XML_STREAM_CLOSING( token )
28 :
29 : // TODO create IS_OPENING(), IS_CLOSING() instead of doing 'next == OPENING( next )' ?
30 :
31 534 : SmOoxmlImport::SmOoxmlImport( oox::formulaimport::XmlStream& s )
32 534 : : stream( s )
33 : {
34 534 : }
35 :
36 534 : OUString SmOoxmlImport::ConvertToStarMath()
37 : {
38 534 : return handleStream();
39 : }
40 :
41 : // "toplevel" of reading, there will be oMath (if there was oMathPara, that was
42 : // up to the parent component to handle)
43 :
44 : // NOT complete
45 534 : OUString SmOoxmlImport::handleStream()
46 : {
47 534 : stream.ensureOpeningTag( M_TOKEN( oMath ));
48 534 : OUString ret;
49 1602 : while( !stream.atEnd() && stream.currentToken() != CLOSING( M_TOKEN( oMath )))
50 : {
51 : // strictly speaking, it is not OMathArg here, but currently supported
52 : // functionality is the same like OMathArg, in the future this may need improving
53 534 : OUString item = readOMathArg( M_TOKEN( oMath ));
54 534 : if( item.isEmpty())
55 0 : continue;
56 534 : if( !ret.isEmpty())
57 0 : ret += " ";
58 534 : ret += item;
59 534 : }
60 534 : stream.ensureClosingTag( M_TOKEN( oMath ));
61 : // Placeholders are written out as nothing (i.e. nothing inside e.g. the <e> element),
62 : // which will result in "{}" in the formula text. Fix this up.
63 534 : ret = ret.replaceAll( "{}", "<?>" );
64 : // And as a result, empty parts of the formula that are not placeholders are written out
65 : // as a single space, so fix that up too.
66 534 : ret = ret.replaceAll( "{ }", "{}" );
67 : SAL_INFO( "starmath.ooxml", "Formula: " << ret );
68 534 : return ret;
69 : }
70 :
71 2908 : OUString SmOoxmlImport::readOMathArg( int stoptoken )
72 : {
73 2908 : OUString ret;
74 10066 : while( !stream.atEnd() && stream.currentToken() != CLOSING( stoptoken ))
75 : {
76 4250 : if( !ret.isEmpty())
77 1468 : ret += " ";
78 4250 : switch( stream.currentToken())
79 : {
80 : case OPENING( M_TOKEN( acc )):
81 144 : ret += handleAcc();
82 144 : break;
83 : case OPENING( M_TOKEN( bar )):
84 12 : ret += handleBar();
85 12 : break;
86 : case OPENING( M_TOKEN( box )):
87 4 : ret += handleBox();
88 4 : break;
89 : case OPENING( M_TOKEN( borderBox )):
90 12 : ret += handleBorderBox();
91 12 : break;
92 : case OPENING( M_TOKEN( d )):
93 288 : ret += handleD();
94 288 : break;
95 : case OPENING( M_TOKEN( eqArr )):
96 30 : ret += handleEqArr();
97 30 : break;
98 : case OPENING( M_TOKEN( f )):
99 182 : ret += handleF();
100 182 : break;
101 : case OPENING( M_TOKEN( func )):
102 50 : ret += handleFunc();
103 50 : break;
104 : case OPENING( M_TOKEN( limLow )):
105 34 : ret += handleLimLowUpp( LimLow );
106 34 : break;
107 : case OPENING( M_TOKEN( limUpp )):
108 24 : ret += handleLimLowUpp( LimUpp );
109 24 : break;
110 : case OPENING( M_TOKEN( groupChr )):
111 24 : ret += handleGroupChr();
112 24 : break;
113 : case OPENING( M_TOKEN( m )):
114 12 : ret += handleM();
115 12 : break;
116 : case OPENING( M_TOKEN( nary )):
117 96 : ret += handleNary();
118 96 : break;
119 : case OPENING( M_TOKEN( r )):
120 2928 : ret += handleR();
121 2928 : break;
122 : case OPENING( M_TOKEN( rad )):
123 52 : ret += handleRad();
124 52 : break;
125 : case OPENING( M_TOKEN( sPre )):
126 24 : ret += handleSpre();
127 24 : break;
128 : case OPENING( M_TOKEN( sSub )):
129 60 : ret += handleSsub();
130 60 : break;
131 : case OPENING( M_TOKEN( sSubSup )):
132 48 : ret += handleSsubsup();
133 48 : break;
134 : case OPENING( M_TOKEN( sSup )):
135 218 : ret += handleSsup();
136 218 : break;
137 : default:
138 8 : stream.handleUnexpectedTag();
139 8 : break;
140 : }
141 : }
142 2908 : return ret;
143 : }
144 :
145 2374 : OUString SmOoxmlImport::readOMathArgInElement( int token )
146 : {
147 2374 : stream.ensureOpeningTag( token );
148 2374 : OUString ret = readOMathArg( token );
149 2374 : stream.ensureClosingTag( token );
150 2374 : return ret;
151 : }
152 :
153 144 : OUString SmOoxmlImport::handleAcc()
154 : {
155 144 : stream.ensureOpeningTag( M_TOKEN( acc ));
156 144 : sal_Unicode accChr = 0x302;
157 144 : if( XmlStream::Tag accPr = stream.checkOpeningTag( M_TOKEN( accPr )))
158 : {
159 144 : if( XmlStream::Tag chr = stream.checkOpeningTag( M_TOKEN( chr )))
160 : {
161 140 : accChr = chr.attribute( M_TOKEN( val ), accChr );
162 140 : stream.ensureClosingTag( M_TOKEN( chr ));
163 144 : }
164 144 : stream.ensureClosingTag( M_TOKEN( accPr ));
165 144 : }
166 : // see aTokenTable in parse.cxx
167 144 : OUString acc;
168 144 : switch( accChr )
169 : {
170 : case MS_BAR:
171 : case MS_COMBBAR:
172 0 : acc = "bar";
173 0 : break;
174 : case MS_CHECK:
175 : case MS_COMBCHECK:
176 12 : acc = "check";
177 12 : break;
178 : case MS_ACUTE:
179 : case MS_COMBACUTE:
180 12 : acc = "acute";
181 12 : break;
182 : case MS_GRAVE:
183 : case MS_COMBGRAVE:
184 12 : acc = "grave";
185 12 : break;
186 : case MS_BREVE:
187 : case MS_COMBBREVE:
188 12 : acc = "breve";
189 12 : break;
190 : case MS_CIRCLE:
191 : case MS_COMBCIRCLE:
192 12 : acc = "circle";
193 12 : break;
194 : case MS_RIGHTARROW:
195 : case MS_VEC:
196 : // prefer wide variants for these 3, .docx can't seem to differentiate
197 : // between e.g. 'vec' and 'widevec', if whatever the accent is above is short, this
198 : // shouldn't matter, but short above a longer expression doesn't look right
199 36 : acc = "widevec";
200 36 : break;
201 : case MS_TILDE:
202 : case MS_COMBTILDE:
203 24 : acc = "widetilde";
204 24 : break;
205 : case MS_HAT:
206 : case MS_COMBHAT:
207 12 : acc = "widehat";
208 12 : break;
209 : case MS_DOT:
210 12 : acc = "dot";
211 12 : break;
212 : case MS_DDOT:
213 0 : acc = "ddot";
214 0 : break;
215 : case MS_DDDOT:
216 0 : acc = "dddot";
217 0 : break;
218 : default:
219 0 : acc = "acute";
220 : SAL_WARN( "starmath.ooxml", "Unknown m:chr in m:acc \'" << accChr << "\'" );
221 0 : break;
222 : }
223 144 : OUString e = readOMathArgInElement( M_TOKEN( e ));
224 144 : stream.ensureClosingTag( M_TOKEN( acc ));
225 144 : return acc + " {" + e + "}";
226 : }
227 :
228 12 : OUString SmOoxmlImport::handleBar()
229 : {
230 12 : stream.ensureOpeningTag( M_TOKEN( bar ));
231 12 : enum pos_t { top, bot } topbot = bot;
232 12 : if( stream.checkOpeningTag( M_TOKEN( barPr )))
233 : {
234 12 : if( XmlStream::Tag pos = stream.checkOpeningTag( M_TOKEN( pos )))
235 : {
236 8 : if( pos.attribute( M_TOKEN( val )) == "top" )
237 0 : topbot = top;
238 8 : else if( pos.attribute( M_TOKEN( val )) == "bot" )
239 8 : topbot = bot;
240 8 : stream.ensureClosingTag( M_TOKEN( pos ));
241 12 : }
242 12 : stream.ensureClosingTag( M_TOKEN( barPr ));
243 : }
244 12 : OUString e = readOMathArgInElement( M_TOKEN( e ));
245 12 : stream.ensureClosingTag( M_TOKEN( bar ));
246 12 : if( topbot == top )
247 0 : return "overline {" + e + "}";
248 : else
249 12 : return "underline {" + e + "}";
250 : }
251 :
252 4 : OUString SmOoxmlImport::handleBox()
253 : {
254 : // there does not seem to be functionality in LO to actually implement this
255 : // (or is there), but at least read in the contents instead of ignoring them
256 4 : stream.ensureOpeningTag( M_TOKEN( box ));
257 4 : OUString e = readOMathArgInElement( M_TOKEN( e ));
258 4 : stream.ensureClosingTag( M_TOKEN( box ));
259 4 : return e;
260 : }
261 :
262 :
263 12 : OUString SmOoxmlImport::handleBorderBox()
264 : {
265 12 : stream.ensureOpeningTag( M_TOKEN( borderBox ));
266 12 : bool isStrikeH = false;
267 12 : if( stream.checkOpeningTag( M_TOKEN( borderBoxPr )))
268 : {
269 12 : if( XmlStream::Tag strikeH = stream.checkOpeningTag( M_TOKEN( strikeH )))
270 : {
271 12 : if( strikeH.attribute( M_TOKEN( val ), false ))
272 12 : isStrikeH = true;
273 12 : stream.ensureClosingTag( M_TOKEN( strikeH ));
274 12 : }
275 12 : stream.ensureClosingTag( M_TOKEN( borderBoxPr ));
276 : }
277 12 : OUString e = readOMathArgInElement( M_TOKEN( e ));
278 12 : stream.ensureClosingTag( M_TOKEN( borderBox ));
279 12 : if( isStrikeH )
280 12 : return "overstrike {" + e + "}";
281 : // LO does not seem to implement anything for handling the other cases
282 0 : return e;
283 : }
284 :
285 288 : OUString SmOoxmlImport::handleD()
286 : {
287 288 : stream.ensureOpeningTag( M_TOKEN( d ));
288 288 : OUString opening = "(";
289 576 : OUString closing = ")";
290 576 : OUString separator = "|";
291 288 : if( XmlStream::Tag dPr = stream.checkOpeningTag( M_TOKEN( dPr )))
292 : {
293 288 : if( XmlStream::Tag begChr = stream.checkOpeningTag( M_TOKEN( begChr )))
294 : {
295 200 : opening = begChr.attribute( M_TOKEN( val ), opening );
296 200 : stream.ensureClosingTag( M_TOKEN( begChr ));
297 288 : }
298 288 : if( XmlStream::Tag sepChr = stream.checkOpeningTag( M_TOKEN( sepChr )))
299 : {
300 20 : separator = sepChr.attribute( M_TOKEN( val ), separator );
301 20 : stream.ensureClosingTag( M_TOKEN( sepChr ));
302 288 : }
303 288 : if( XmlStream::Tag endChr = stream.checkOpeningTag( M_TOKEN( endChr )))
304 : {
305 200 : closing = endChr.attribute( M_TOKEN( val ), closing );
306 200 : stream.ensureClosingTag( M_TOKEN( endChr ));
307 288 : }
308 288 : stream.ensureClosingTag( M_TOKEN( dPr ));
309 288 : }
310 288 : if( opening == "{" )
311 10 : opening = "left lbrace ";
312 288 : if( closing == "}" )
313 6 : closing = " right rbrace";
314 288 : if( opening == OUString( sal_Unicode( 0x27e6 )))
315 12 : opening = "left ldbracket ";
316 288 : if( closing == OUString( sal_Unicode( 0x27e7 )))
317 12 : closing = " right rdbracket";
318 288 : if( opening == "|" )
319 12 : opening = "left lline ";
320 288 : if( closing == "|" )
321 12 : closing = " right rline";
322 288 : if (opening == OUString(MS_DLINE) || opening == OUString(MS_DVERTLINE))
323 12 : opening = "left ldline ";
324 288 : if (closing == OUString(MS_DLINE) || closing == OUString(MS_DVERTLINE))
325 12 : closing = " right rdline";
326 288 : if (opening == OUString(MS_LANGLE) || opening == OUString(MS_LMATHANGLE))
327 24 : opening = "left langle ";
328 288 : if (closing == OUString(MS_RANGLE) || closing == OUString(MS_RMATHANGLE))
329 24 : closing = " right rangle";
330 : // use scalable brackets (the explicit "left" or "right")
331 288 : if( opening == "(" || opening == "[" )
332 208 : opening = "left " + opening;
333 288 : if( closing == ")" || closing == "]" )
334 208 : closing = " right " + closing;
335 288 : if( separator == "|" ) // plain "|" would be actually "V" (logical or)
336 284 : separator = " mline ";
337 288 : if( opening.isEmpty())
338 6 : opening = "left none ";
339 288 : if( closing.isEmpty())
340 10 : closing = " right none";
341 576 : OUStringBuffer ret;
342 288 : ret.append( opening );
343 288 : bool first = true;
344 898 : while( stream.findTag( OPENING( M_TOKEN( e ))))
345 : {
346 322 : if( !first )
347 44 : ret.append( separator );
348 322 : first = false;
349 322 : ret.append( readOMathArgInElement( M_TOKEN( e )));
350 : }
351 288 : ret.append( closing );
352 288 : stream.ensureClosingTag( M_TOKEN( d ));
353 576 : return ret.makeStringAndClear();
354 : }
355 :
356 30 : OUString SmOoxmlImport::handleEqArr()
357 : {
358 30 : stream.ensureOpeningTag( M_TOKEN( eqArr ));
359 30 : OUString ret;
360 64 : do
361 : { // there must be at least one m:e
362 64 : if( !ret.isEmpty())
363 34 : ret += "#";
364 64 : ret += " ";
365 64 : ret += readOMathArgInElement( M_TOKEN( e ));
366 64 : ret += " ";
367 64 : } while( !stream.atEnd() && stream.findTag( OPENING( M_TOKEN( e ))));
368 30 : stream.ensureClosingTag( M_TOKEN( eqArr ));
369 30 : return "stack {" + ret + "}";
370 : }
371 :
372 182 : OUString SmOoxmlImport::handleF()
373 : {
374 182 : stream.ensureOpeningTag( M_TOKEN( f ));
375 182 : enum operation_t { bar, lin, noBar } operation = bar;
376 182 : if( stream.checkOpeningTag( M_TOKEN( fPr )))
377 : {
378 110 : if( XmlStream::Tag type = stream.checkOpeningTag( M_TOKEN( type )))
379 : {
380 40 : if( type.attribute( M_TOKEN( val )) == "bar" )
381 0 : operation = bar;
382 40 : else if( type.attribute( M_TOKEN( val )) == "lin" )
383 10 : operation = lin;
384 30 : else if( type.attribute( M_TOKEN( val )) == "noBar" )
385 30 : operation = noBar;
386 40 : stream.ensureClosingTag( M_TOKEN( type ));
387 110 : }
388 110 : stream.ensureClosingTag( M_TOKEN( fPr ));
389 : }
390 182 : OUString num = readOMathArgInElement( M_TOKEN( num ));
391 364 : OUString den = readOMathArgInElement( M_TOKEN( den ));
392 182 : stream.ensureClosingTag( M_TOKEN( f ));
393 182 : if( operation == bar )
394 142 : return "{" + num + "} over {" + den + "}";
395 40 : else if( operation == lin )
396 10 : return "{" + num + "} / {" + den + "}";
397 : else // noBar
398 : {
399 30 : return "binom {" + num + "} {" + den + "}";
400 182 : }
401 : }
402 :
403 50 : OUString SmOoxmlImport::handleFunc()
404 : {
405 : //lim from{x rightarrow 1} x
406 50 : stream.ensureOpeningTag( M_TOKEN( func ));
407 50 : OUString fname = readOMathArgInElement( M_TOKEN( fName ));
408 : // fix the various functions
409 50 : if( fname.startsWith( "lim csub {" ))
410 10 : fname = "lim from {" + fname.copy( 10 );
411 50 : OUString ret = fname + " {" + readOMathArgInElement( M_TOKEN( e )) + "}";
412 50 : stream.ensureClosingTag( M_TOKEN( func ));
413 50 : return ret;
414 : }
415 :
416 58 : OUString SmOoxmlImport::handleLimLowUpp( LimLowUpp_t limlowupp )
417 : {
418 58 : int token = limlowupp == LimLow ? M_TOKEN( limLow ) : M_TOKEN( limUpp );
419 58 : stream.ensureOpeningTag( token );
420 58 : OUString e = readOMathArgInElement( M_TOKEN( e ));
421 116 : OUString lim = readOMathArgInElement( M_TOKEN( lim ));
422 58 : stream.ensureClosingTag( token );
423 : // fix up overbrace/underbrace (use { }, as {} will be converted to a placeholder)
424 58 : if( limlowupp == LimUpp && e.endsWith( " overbrace { }" ))
425 12 : return e.copy( 0, e.getLength() - 2 ) + lim + "}";
426 46 : if( limlowupp == LimLow && e.endsWith( " underbrace { }" ))
427 12 : return e.copy( 0, e.getLength() - 2 ) + lim + "}";
428 : return e
429 90 : + ( limlowupp == LimLow ? OUString( " csub {" ) : OUString( " csup {" ))
430 104 : + lim + "}";
431 : }
432 :
433 24 : OUString SmOoxmlImport::handleGroupChr()
434 : {
435 24 : stream.ensureOpeningTag( M_TOKEN( groupChr ));
436 24 : sal_Unicode chr = 0x23df;
437 24 : enum pos_t { top, bot } pos = bot;
438 24 : if( stream.checkOpeningTag( M_TOKEN( groupChrPr )))
439 : {
440 24 : if( XmlStream::Tag chrTag = stream.checkOpeningTag( M_TOKEN( chr )))
441 : {
442 20 : chr = chrTag.attribute( M_TOKEN( val ), chr );
443 20 : stream.ensureClosingTag( M_TOKEN( chr ));
444 24 : }
445 24 : if( XmlStream::Tag posTag = stream.checkOpeningTag( M_TOKEN( pos )))
446 : {
447 20 : if( posTag.attribute( M_TOKEN( val ), OUString( "bot" )) == "top" )
448 12 : pos = top;
449 20 : stream.ensureClosingTag( M_TOKEN( pos ));
450 24 : }
451 24 : stream.ensureClosingTag( M_TOKEN( groupChrPr ));
452 : }
453 24 : OUString e = readOMathArgInElement( M_TOKEN( e ));
454 24 : stream.ensureClosingTag( M_TOKEN( groupChr ));
455 24 : if( pos == top && chr == sal_Unicode( 0x23de ))
456 12 : return "{" + e + "} overbrace { }";
457 12 : if( pos == bot && chr == sal_Unicode( 0x23df ))
458 12 : return "{" + e + "} underbrace { }";
459 0 : if( pos == top )
460 0 : return "{" + e + "} csup {" + OUString( chr ) + "}";
461 : else
462 0 : return "{" + e + "} csub {" + OUString( chr ) + "}";
463 : }
464 :
465 12 : OUString SmOoxmlImport::handleM()
466 : {
467 12 : stream.ensureOpeningTag( M_TOKEN( m ));
468 12 : OUString allrows;
469 24 : do // there must be at least one m:mr
470 : {
471 24 : stream.ensureOpeningTag( M_TOKEN( mr ));
472 24 : OUString row;
473 48 : do // there must be at least one m:e
474 : {
475 48 : if( !row.isEmpty())
476 24 : row += " # ";
477 48 : row += readOMathArgInElement( M_TOKEN( e ));
478 48 : } while( !stream.atEnd() && stream.findTag( OPENING( M_TOKEN( e ))));
479 24 : if( !allrows.isEmpty())
480 12 : allrows += " ## ";
481 24 : allrows += row;
482 24 : stream.ensureClosingTag( M_TOKEN( mr ));
483 24 : } while( !stream.atEnd() && stream.findTag( OPENING( M_TOKEN( mr ))));
484 12 : stream.ensureClosingTag( M_TOKEN( m ));
485 12 : return "matrix {" + allrows + "}";
486 : }
487 :
488 96 : OUString SmOoxmlImport::handleNary()
489 : {
490 96 : stream.ensureOpeningTag( M_TOKEN( nary ));
491 96 : sal_Unicode chr = 0x222b;
492 96 : bool subHide = false;
493 96 : bool supHide = false;
494 96 : if( stream.checkOpeningTag( M_TOKEN( naryPr )))
495 : {
496 96 : if( XmlStream::Tag chrTag = stream.checkOpeningTag( M_TOKEN( chr )))
497 : {
498 94 : chr = chrTag.attribute( M_TOKEN( val ), chr );
499 94 : stream.ensureClosingTag( M_TOKEN( chr ));
500 96 : }
501 96 : if( XmlStream::Tag subHideTag = stream.checkOpeningTag( M_TOKEN( subHide )))
502 : {
503 10 : subHide = subHideTag.attribute( M_TOKEN( val ), subHide );
504 10 : stream.ensureClosingTag( M_TOKEN( subHide ));
505 96 : }
506 96 : if( XmlStream::Tag supHideTag = stream.checkOpeningTag( M_TOKEN( supHide )))
507 : {
508 10 : supHide = supHideTag.attribute( M_TOKEN( val ), supHide );
509 10 : stream.ensureClosingTag( M_TOKEN( supHide ));
510 96 : }
511 96 : stream.ensureClosingTag( M_TOKEN( naryPr ));
512 : }
513 96 : OUString sub = readOMathArgInElement( M_TOKEN( sub ));
514 192 : OUString sup = readOMathArgInElement( M_TOKEN( sup ));
515 192 : OUString e = readOMathArgInElement( M_TOKEN( e ));
516 96 : OUString ret;
517 96 : switch( chr )
518 : {
519 : case MS_INT:
520 2 : ret = "int";
521 2 : break;
522 : case MS_IINT:
523 0 : ret = "iint";
524 0 : break;
525 : case MS_IIINT:
526 12 : ret = "iiint";
527 12 : break;
528 : case MS_LINT:
529 0 : ret = "lint";
530 0 : break;
531 : case MS_LLINT:
532 12 : ret = "llint";
533 12 : break;
534 : case MS_LLLINT:
535 10 : ret = "lllint";
536 10 : break;
537 : case MS_PROD:
538 10 : ret = "prod";
539 10 : break;
540 : case MS_COPROD:
541 0 : ret = "coprod";
542 0 : break;
543 : case MS_SUM:
544 50 : ret = "sum";
545 50 : break;
546 : default:
547 : SAL_WARN( "starmath.ooxml", "Unknown m:nary chr \'" << chr << "\'" );
548 0 : break;
549 : }
550 96 : if( !subHide )
551 86 : ret += " from {" + sub + "}";
552 96 : if( !supHide )
553 86 : ret += " to {" + sup + "}";
554 96 : ret += " {" + e + "}";
555 96 : stream.ensureClosingTag( M_TOKEN( nary ));
556 192 : return ret;
557 : }
558 :
559 : // NOT complete
560 2928 : OUString SmOoxmlImport::handleR()
561 : {
562 2928 : stream.ensureOpeningTag( M_TOKEN( r ));
563 2928 : bool normal = false;
564 2928 : bool literal = false;
565 2928 : if( XmlStream::Tag rPr = stream.checkOpeningTag( M_TOKEN( rPr )))
566 : {
567 174 : if( XmlStream::Tag litTag = stream.checkOpeningTag( M_TOKEN( lit )))
568 : {
569 26 : literal = litTag.attribute( M_TOKEN( val ), true );
570 26 : stream.ensureClosingTag( M_TOKEN( lit ));
571 174 : }
572 174 : if( XmlStream::Tag norTag = stream.checkOpeningTag( M_TOKEN( nor )))
573 : {
574 44 : normal = norTag.attribute( M_TOKEN( val ), true );
575 44 : stream.ensureClosingTag( M_TOKEN( nor ));
576 174 : }
577 174 : stream.ensureClosingTag( M_TOKEN( rPr ));
578 2928 : }
579 2928 : OUString text;
580 9652 : while( !stream.atEnd() && stream.currentToken() != CLOSING( stream.currentToken()))
581 : {
582 3796 : switch( stream.currentToken())
583 : {
584 : case OPENING( M_TOKEN( t )):
585 : {
586 2928 : XmlStream::Tag rtag = stream.ensureOpeningTag( M_TOKEN( t ));
587 2928 : if( rtag.attribute( OOX_TOKEN( xml, space )) != "preserve" )
588 1760 : text += rtag.text.trim();
589 : else
590 1168 : text += rtag.text;
591 2928 : stream.ensureClosingTag( M_TOKEN( t ));
592 2928 : break;
593 : }
594 : default:
595 868 : stream.handleUnexpectedTag();
596 868 : break;
597 : }
598 : }
599 2928 : stream.ensureClosingTag( M_TOKEN( r ));
600 2928 : if( normal || literal )
601 44 : text = "\"" + text + "\"";
602 2928 : return text.replaceAll("{", "\\{").replaceAll("}", "\\}");
603 : }
604 :
605 52 : OUString SmOoxmlImport::handleRad()
606 : {
607 52 : stream.ensureOpeningTag( M_TOKEN( rad ));
608 52 : bool degHide = false;
609 52 : if( stream.checkOpeningTag( M_TOKEN( radPr )))
610 : {
611 44 : if( XmlStream::Tag degHideTag = stream.checkOpeningTag( M_TOKEN( degHide )))
612 : {
613 42 : degHide = degHideTag.attribute( M_TOKEN( val ), degHide );
614 42 : stream.ensureClosingTag( M_TOKEN( degHide ));
615 44 : }
616 44 : stream.ensureClosingTag( M_TOKEN( radPr ));
617 : }
618 52 : OUString deg = readOMathArgInElement( M_TOKEN( deg ));
619 104 : OUString e = readOMathArgInElement( M_TOKEN( e ));
620 52 : stream.ensureClosingTag( M_TOKEN( rad ));
621 52 : if( degHide )
622 42 : return "sqrt {" + e + "}";
623 : else
624 62 : return "nroot {" + deg + "} {" + e + "}";
625 : }
626 :
627 24 : OUString SmOoxmlImport::handleSpre()
628 : {
629 24 : stream.ensureOpeningTag( M_TOKEN( sPre ));
630 24 : OUString sub = readOMathArgInElement( M_TOKEN( sub ));
631 48 : OUString sup = readOMathArgInElement( M_TOKEN( sup ));
632 48 : OUString e = readOMathArgInElement( M_TOKEN( e ));
633 24 : stream.ensureClosingTag( M_TOKEN( sPre ));
634 48 : return "{" + e + "} lsub {" + sub + "} lsup {" + sup + "}";
635 : }
636 :
637 60 : OUString SmOoxmlImport::handleSsub()
638 : {
639 60 : stream.ensureOpeningTag( M_TOKEN( sSub ));
640 60 : OUString e = readOMathArgInElement( M_TOKEN( e ));
641 120 : OUString sub = readOMathArgInElement( M_TOKEN( sub ));
642 60 : stream.ensureClosingTag( M_TOKEN( sSub ));
643 120 : return "{" + e + "} rsub {" + sub + "}";
644 : }
645 :
646 48 : OUString SmOoxmlImport::handleSsubsup()
647 : {
648 48 : stream.ensureOpeningTag( M_TOKEN( sSubSup ));
649 48 : OUString e = readOMathArgInElement( M_TOKEN( e ));
650 96 : OUString sub = readOMathArgInElement( M_TOKEN( sub ));
651 96 : OUString sup = readOMathArgInElement( M_TOKEN( sup ));
652 48 : stream.ensureClosingTag( M_TOKEN( sSubSup ));
653 96 : return "{" + e + "} rsub {" + sub + "} rsup {" + sup + "}";
654 : }
655 :
656 218 : OUString SmOoxmlImport::handleSsup()
657 : {
658 218 : stream.ensureOpeningTag( M_TOKEN( sSup ));
659 218 : OUString e = readOMathArgInElement( M_TOKEN( e ));
660 436 : OUString sup = readOMathArgInElement( M_TOKEN( sup ));
661 218 : stream.ensureClosingTag( M_TOKEN( sSup ));
662 436 : return "{" + e + "} ^ {" + sup + "}";
663 72 : }
664 :
665 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|