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