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