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