LCOV - code coverage report
Current view: top level - starmath/source - ooxmlimport.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 405 429 94.4 %
Date: 2014-04-11 Functions: 23 23 100.0 %
Legend: Lines: hit not hit

          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: */

Generated by: LCOV version 1.10