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