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