00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include <qpainter.h>
00022
00023
#include <kdebug.h>
00024
00025
#include "elementvisitor.h"
00026
#include "formulacursor.h"
00027
#include "formulaelement.h"
00028
#include "kformulacommand.h"
00029
#include "sequenceelement.h"
00030
#include "symbolelement.h"
00031
00032 KFORMULA_NAMESPACE_BEGIN
00033
00034
00035
class SymbolSequenceElement :
public SequenceElement {
00036
typedef SequenceElement inherited;
00037
public:
00038
00039 SymbolSequenceElement(
BasicElement* parent = 0 ) :
SequenceElement( parent ) {}
00040
00049
virtual KCommand* buildCommand(
Container*, Request* );
00050 };
00051
00052
00053 KCommand* SymbolSequenceElement::buildCommand(
Container* container, Request* request )
00054 {
00055
FormulaCursor* cursor = container->
activeCursor();
00056
if ( cursor->
isReadOnly() ) {
00057
return 0;
00058 }
00059
00060
switch ( *request ) {
00061
case req_addIndex: {
00062
FormulaCursor* cursor = container->
activeCursor();
00063
if ( cursor->
isSelection() ||
00064 ( cursor->
getPos() > 0 && cursor->
getPos() < countChildren() ) ) {
00065
break;
00066 }
00067 IndexRequest* ir = static_cast<IndexRequest*>( request );
00068
if ( ( ir->index() == upperMiddlePos ) || ( ir->index() == lowerMiddlePos ) ) {
00069
SymbolElement* element = static_cast<SymbolElement*>( getParent() );
00070 ElementIndexPtr index = element->
getIndex( ir->index() );
00071
if ( !index->hasIndex() ) {
00072
KFCAddGenericIndex* command =
new KFCAddGenericIndex( container, index );
00073
return command;
00074 }
00075
else {
00076 index->moveToIndex( cursor, afterCursor );
00077 cursor->
setSelection(
false );
00078 formula()->cursorHasMoved( cursor );
00079
return 0;
00080 }
00081 }
00082 }
00083
default:
00084
break;
00085 }
00086
return inherited::buildCommand( container, request );
00087 }
00088
00089
00090 SymbolElement::SymbolElement(SymbolType type,
BasicElement* parent)
00091 :
BasicElement(parent), symbol( 0 ), symbolType( type )
00092 {
00093 content =
new SymbolSequenceElement(
this );
00094 upper = 0;
00095 lower = 0;
00096 }
00097
00098 SymbolElement::~SymbolElement()
00099 {
00100
delete lower;
00101
delete upper;
00102
delete content;
00103
delete symbol;
00104 }
00105
00106
00107 SymbolElement::SymbolElement(
const SymbolElement& other )
00108 :
BasicElement( other ), symbol( 0 ), symbolType( other.symbolType )
00109 {
00110 content =
new SymbolSequenceElement( *dynamic_cast<SymbolSequenceElement*>( other.
content ) );
00111 content->setParent(
this );
00112
00113
if ( other.
upper ) {
00114 upper =
new SequenceElement( *( other.
upper ) );
00115 upper->setParent(
this );
00116 }
00117
else {
00118 upper = 0;
00119 }
00120
if ( other.
lower ) {
00121 lower =
new SequenceElement( *( other.
lower ) );
00122 lower->setParent(
this );
00123 }
00124
else {
00125 lower = 0;
00126 }
00127 }
00128
00129
00130 bool SymbolElement::accept(
ElementVisitor* visitor )
00131 {
00132
return visitor->
visit(
this );
00133 }
00134
00135
00136 BasicElement*
SymbolElement::goToPos(
FormulaCursor* cursor,
bool& handled,
00137
const LuPixelPoint& point,
const LuPixelPoint& parentOrigin )
00138 {
00139
BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin);
00140
if (e != 0) {
00141
LuPixelPoint myPos(parentOrigin.x() + getX(),
00142 parentOrigin.y() + getY());
00143
00144 e = content->
goToPos(cursor, handled, point, myPos);
00145
if (e != 0) {
00146
return e;
00147 }
00148
if (hasLower()) {
00149 e = lower->
goToPos(cursor, handled, point, myPos);
00150
if (e != 0) {
00151
return e;
00152 }
00153 }
00154
if (
hasUpper()) {
00155 e = upper->
goToPos(cursor, handled, point, myPos);
00156
if (e != 0) {
00157
return e;
00158 }
00159 }
00160
00161
00162 luPixel dx = point.x() - myPos.x();
00163 luPixel dy = point.y() - myPos.y();
00164
if (dy < symbol->getY()) {
00165
if (
hasUpper() && (dx > upper->
getX())) {
00166 upper->
moveLeft(cursor,
this);
00167 handled =
true;
00168
return upper;
00169 }
00170 }
00171
else if (dy > symbol->getY()+symbol->getHeight()) {
00172
if (hasLower() && (dx > lower->
getX())) {
00173 lower->
moveLeft(cursor,
this);
00174 handled =
true;
00175
return lower;
00176 }
00177 }
00178
00179
00180
if ( ( dx < symbol->getX()+symbol->getWidth() ) &&
00181 ( dx > symbol->getX()+symbol->getWidth()/2 ) ) {
00182 content->
moveRight( cursor,
this );
00183 handled =
true;
00184
return content;
00185 }
00186
00187
return this;
00188 }
00189
return 0;
00190 }
00191
00192
00197 void SymbolElement::calcSizes(
const ContextStyle& style, ContextStyle::TextStyle tstyle, ContextStyle::IndexStyle istyle )
00198 {
00199 luPt mySize = style.getAdjustedSize( tstyle );
00200 luPixel distX = style.ptToPixelX( style.getThinSpace( tstyle ) );
00201 luPixel distY = style.ptToPixelY( style.getThinSpace( tstyle ) );
00202
00203
00204
delete symbol;
00205 symbol = style.fontStyle().createArtwork( symbolType );
00206
00207
00208 symbol->calcSizes(style, tstyle, mySize);
00209 content->
calcSizes(style, tstyle, istyle);
00210
00211
00212
00213 luPixel upperWidth = 0;
00214 luPixel upperHeight = 0;
00215
if (
hasUpper()) {
00216 upper->
calcSizes(style, style.convertTextStyleIndex( tstyle ),
00217 style.convertIndexStyleUpper( istyle ) );
00218 upperWidth = upper->
getWidth();
00219 upperHeight = upper->
getHeight() + distY;
00220 }
00221
00222 luPixel lowerWidth = 0;
00223 luPixel lowerHeight = 0;
00224
if (hasLower()) {
00225 lower->
calcSizes(style, style.convertTextStyleIndex( tstyle ),
00226 style.convertIndexStyleLower( istyle ) );
00227 lowerWidth = lower->
getWidth();
00228 lowerHeight = lower->
getHeight() + distY;
00229 }
00230
00231
00232 luPixel xOffset = QMAX(symbol->getWidth(), QMAX(upperWidth, lowerWidth));
00233
if (style.getCenterSymbol()) {
00234 symbol->setX((xOffset - symbol->getWidth()) / 2);
00235 }
00236
else {
00237 symbol->setX(xOffset - symbol->getWidth());
00238 }
00239
00240 content->
setX(xOffset +
00241 static_cast<luPixel>( symbol->slant()*symbol->getHeight()/2 ) +
00242 distX/2);
00243
00244 setWidth(QMAX(content->
getX() + content->
getWidth(),
00245 QMAX(upperWidth, lowerWidth)));
00246
00247
00248
00249 luPixel toMidline = QMAX(content->
axis( style, tstyle ),
00250 upperHeight + symbol->getHeight()/2);
00251
00252 luPixel fromMidline = QMAX(content->
getHeight() - content->
axis( style, tstyle ),
00253 lowerHeight + symbol->getHeight()/2);
00254 setHeight(toMidline + fromMidline);
00255
00256
00257 symbol->setY(toMidline - symbol->getHeight()/2);
00258
00259 content->
setY(toMidline - content->
axis( style, tstyle ));
00260
00261
if (
hasUpper()) {
00262 luPixel slant =
00263 static_cast<luPixel>( symbol->slant()*( symbol->getHeight()+distY ) );
00264
if (style.getCenterSymbol()) {
00265 upper->
setX((xOffset - upperWidth) / 2 + slant );
00266 }
00267
else {
00268
if (upperWidth < symbol->getWidth()) {
00269 upper->
setX(symbol->getX() +
00270 (symbol->getWidth() - upperWidth) / 2 + slant );
00271 }
00272
else {
00273 upper->
setX(xOffset - upperWidth);
00274 }
00275 }
00276 upper->
setY(toMidline - upperHeight - symbol->getHeight()/2);
00277 }
00278
if (hasLower()) {
00279 luPixel slant = static_cast<luPixel>( -symbol->slant()*distY );
00280
if (style.getCenterSymbol()) {
00281 lower->
setX((xOffset - lowerWidth) / 2 + slant);
00282 }
00283
else {
00284
if (lowerWidth < symbol->getWidth()) {
00285 lower->
setX(symbol->getX() +
00286 (symbol->getWidth() - lowerWidth) / 2 + slant );
00287 }
00288
else {
00289 lower->
setX(xOffset - lowerWidth);
00290 }
00291 }
00292 lower->
setY(toMidline + symbol->getHeight()/2 + distY);
00293 }
00294 setBaseline(content->
getBaseline() + content->
getY());
00295 }
00296
00302 void SymbolElement::draw(
QPainter& painter,
const LuPixelRect& r,
00303
const ContextStyle& style,
00304 ContextStyle::TextStyle tstyle,
00305 ContextStyle::IndexStyle istyle,
00306
const LuPixelPoint& parentOrigin )
00307 {
00308
LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() );
00309
00310
00311
00312 luPt mySize = style.getAdjustedSize( tstyle );
00313 symbol->draw( painter, r, style, tstyle, mySize, myPos );
00314 content->
draw( painter, r, style, tstyle, istyle, myPos );
00315
if (
hasUpper() ) {
00316 upper->
draw( painter, r, style, style.convertTextStyleIndex( tstyle ),
00317 style.convertIndexStyleUpper( istyle ), myPos );
00318 }
00319
if ( hasLower() ) {
00320 lower->
draw( painter, r, style, style.convertTextStyleIndex( tstyle ),
00321 style.convertIndexStyleLower( istyle ), myPos );
00322 }
00323
00324
00325
#if 0
00326
painter.setBrush(Qt::NoBrush);
00327 painter.setPen(Qt::red);
00328
00329
00330
00331
00332 painter.drawRect( style.layoutUnitToPixelX( myPos.x()+symbol->getX() ),
00333 style.layoutUnitToPixelY( myPos.y()+symbol->getY() ),
00334 style.layoutUnitToPixelX( symbol->getWidth() ),
00335 style.layoutUnitToPixelY( symbol->getHeight() ) );
00336 painter.setPen(Qt::green);
00337 painter.drawLine( style.layoutUnitToPixelX( myPos.x() ),
00338 style.layoutUnitToPixelY( myPos.y()+axis(style, tstyle) ),
00339 style.layoutUnitToPixelX( myPos.x()+getWidth() ),
00340 style.layoutUnitToPixelY( myPos.y()+axis(style, tstyle) ) );
00341
#endif
00342
}
00343
00344
00345 void SymbolElement::dispatchFontCommand(
FontCommand* cmd )
00346 {
00347 content->
dispatchFontCommand( cmd );
00348
if (
hasUpper() ) {
00349 upper->
dispatchFontCommand( cmd );
00350 }
00351
if ( hasLower() ) {
00352 lower->
dispatchFontCommand( cmd );
00353 }
00354 }
00355
00356
00357
00358
00359
00360
00361
00362
00363
00369 void SymbolElement::moveLeft(
FormulaCursor* cursor,
BasicElement* from)
00370 {
00371
if (cursor->
isSelectionMode()) {
00372 getParent()->
moveLeft(cursor,
this);
00373 }
00374
else {
00375
bool linear = cursor->
getLinearMovement();
00376
if (from == getParent()) {
00377 content->
moveLeft(cursor,
this);
00378 }
00379
else if (from == content) {
00380
if (linear && hasLower()) {
00381 lower->
moveLeft(cursor,
this);
00382 }
00383
else if (linear &&
hasUpper()) {
00384 upper->
moveLeft(cursor,
this);
00385 }
00386
else {
00387 getParent()->moveLeft(cursor,
this);
00388 }
00389 }
00390
else if (from == lower) {
00391
if (linear &&
hasUpper()) {
00392 upper->
moveLeft(cursor,
this);
00393 }
00394
else {
00395 getParent()->moveLeft(cursor,
this);
00396 }
00397 }
00398
else if (from == upper) {
00399 getParent()->moveLeft(cursor,
this);
00400 }
00401 }
00402 }
00403
00409 void SymbolElement::moveRight(
FormulaCursor* cursor,
BasicElement* from)
00410 {
00411
if (cursor->
isSelectionMode()) {
00412 getParent()->
moveRight(cursor,
this);
00413 }
00414
else {
00415
bool linear = cursor->
getLinearMovement();
00416
if (from == getParent()) {
00417
if (linear &&
hasUpper()) {
00418 upper->
moveRight(cursor,
this);
00419 }
00420
else if (linear && hasLower()) {
00421 lower->
moveRight(cursor,
this);
00422 }
00423
else {
00424 content->
moveRight(cursor,
this);
00425 }
00426 }
00427
else if (from == upper) {
00428
if (linear && hasLower()) {
00429 lower->
moveRight(cursor,
this);
00430 }
00431
else {
00432 content->
moveRight(cursor,
this);
00433 }
00434 }
00435
else if (from == lower) {
00436 content->
moveRight(cursor,
this);
00437 }
00438
else if (from == content) {
00439 getParent()->moveRight(cursor,
this);
00440 }
00441 }
00442 }
00443
00449 void SymbolElement::moveUp(
FormulaCursor* cursor,
BasicElement* from)
00450 {
00451
if (cursor->
isSelectionMode()) {
00452 getParent()->
moveUp(cursor,
this);
00453 }
00454
else {
00455
if (from == content) {
00456
if (
hasUpper()) {
00457 upper->
moveLeft(cursor,
this);
00458 }
00459
else {
00460 getParent()->
moveUp(cursor,
this);
00461 }
00462 }
00463
else if (from == upper) {
00464 getParent()->
moveUp(cursor,
this);
00465 }
00466
else if ((from == getParent()) || (from == lower)) {
00467 content->
moveRight(cursor,
this);
00468 }
00469 }
00470 }
00471
00477 void SymbolElement::moveDown(
FormulaCursor* cursor,
BasicElement* from)
00478 {
00479
if (cursor->
isSelectionMode()) {
00480 getParent()->
moveDown(cursor,
this);
00481 }
00482
else {
00483
if (from == content) {
00484
if (hasLower()) {
00485 lower->
moveLeft(cursor,
this);
00486 }
00487
else {
00488 getParent()->
moveDown(cursor,
this);
00489 }
00490 }
00491
else if (from == lower) {
00492 getParent()->
moveDown(cursor,
this);
00493 }
00494
else if ((from == getParent()) || (from == upper)) {
00495 content->
moveRight(cursor,
this);
00496 }
00497 }
00498 }
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00525 void SymbolElement::insert(
FormulaCursor* cursor,
00526
QPtrList<BasicElement>& newChildren,
00527 Direction direction)
00528 {
00529 SequenceElement* index = static_cast<SequenceElement*>(newChildren.take(0));
00530 index->setParent(
this);
00531
00532
switch (cursor->
getPos()) {
00533
case upperMiddlePos:
00534 upper = index;
00535
break;
00536
case lowerMiddlePos:
00537 lower = index;
00538
break;
00539
default:
00540
00541
return;
00542 }
00543
00544
if (direction == beforeCursor) {
00545 index->moveLeft(cursor,
this);
00546 }
00547
else {
00548 index->moveRight(cursor,
this);
00549 }
00550 cursor->
setSelection(
false);
00551
formula()->
changed();
00552 }
00553
00565 void SymbolElement::remove(
FormulaCursor* cursor,
00566
QPtrList<BasicElement>& removedChildren,
00567 Direction direction)
00568 {
00569
int pos = cursor->
getPos();
00570
switch (pos) {
00571
case upperMiddlePos:
00572 removedChildren.append(upper);
00573
formula()->
elementRemoval(upper);
00574 upper = 0;
00575 setToUpper(cursor);
00576
break;
00577
case lowerMiddlePos:
00578 removedChildren.append(lower);
00579
formula()->
elementRemoval(lower);
00580 lower = 0;
00581 setToLower(cursor);
00582
break;
00583
case contentPos: {
00584
BasicElement* parent = getParent();
00585 parent->
selectChild(cursor,
this);
00586 parent->
remove(cursor, removedChildren, direction);
00587
break;
00588 }
00589 }
00590
formula()->
changed();
00591 }
00592
00597 void SymbolElement::normalize(
FormulaCursor* cursor, Direction direction)
00598 {
00599
if (direction == beforeCursor) {
00600 content->
moveLeft(cursor,
this);
00601 }
00602
else {
00603 content->
moveRight(cursor,
this);
00604 }
00605 }
00606
00610 BasicElement*
SymbolElement::getChild(
FormulaCursor* cursor, Direction)
00611 {
00612
int pos = cursor->
getPos();
00613
switch (pos) {
00614
case contentPos:
00615
return content;
00616
case upperMiddlePos:
00617
return upper;
00618
case lowerMiddlePos:
00619
return lower;
00620 }
00621
return 0;
00622 }
00623
00628 void SymbolElement::selectChild(
FormulaCursor* cursor,
BasicElement* child)
00629 {
00630
if (child == content) {
00631 setToContent(cursor);
00632 }
00633
else if (child == upper) {
00634 setToUpper(cursor);
00635 }
00636
else if (child == lower) {
00637 setToLower(cursor);
00638 }
00639 }
00640
00641
void SymbolElement::setToUpper(
FormulaCursor* cursor)
00642 {
00643 cursor->
setTo(
this, upperMiddlePos);
00644 }
00645
00646
void SymbolElement::setToLower(
FormulaCursor* cursor)
00647 {
00648 cursor->
setTo(
this, lowerMiddlePos);
00649 }
00650
00657
void SymbolElement::setToContent(
FormulaCursor* cursor)
00658 {
00659 cursor->
setTo(
this, contentPos);
00660 }
00661
00662
00663
void SymbolElement::moveToUpper(
FormulaCursor* cursor, Direction direction)
00664 {
00665
if (
hasUpper()) {
00666
if (direction == beforeCursor) {
00667 upper->
moveLeft(cursor,
this);
00668 }
00669
else {
00670 upper->
moveRight(cursor,
this);
00671 }
00672 }
00673 }
00674
00675
void SymbolElement::moveToLower(
FormulaCursor* cursor, Direction direction)
00676 {
00677
if (hasLower()) {
00678
if (direction == beforeCursor) {
00679 lower->
moveLeft(cursor,
this);
00680 }
00681
else {
00682 lower->
moveRight(cursor,
this);
00683 }
00684 }
00685 }
00686
00687
00688 ElementIndexPtr
SymbolElement::getIndex(
int position )
00689 {
00690
switch ( position ) {
00691
case lowerMiddlePos:
00692
return getLowerIndex();
00693
case upperMiddlePos:
00694
return getUpperIndex();
00695 }
00696
return getUpperIndex();
00697 }
00698
00699
00703 void SymbolElement::writeDom(
QDomElement element)
00704 {
00705 BasicElement::writeDom(element);
00706
00707 element.setAttribute(
"TYPE", symbolType);
00708
00709
QDomDocument doc = element.ownerDocument();
00710
00711
QDomElement con = doc.createElement(
"CONTENT");
00712 con.appendChild(content->
getElementDom(doc));
00713 element.appendChild(con);
00714
00715
if(hasLower()) {
00716
QDomElement ind = doc.createElement(
"LOWER");
00717 ind.appendChild(lower->
getElementDom(doc));
00718 element.appendChild(ind);
00719 }
00720
if(
hasUpper()) {
00721
QDomElement ind = doc.createElement(
"UPPER");
00722 ind.appendChild(upper->
getElementDom(doc));
00723 element.appendChild(ind);
00724 }
00725 }
00726
00731 bool SymbolElement::readAttributesFromDom(
QDomElement element)
00732 {
00733
if (!BasicElement::readAttributesFromDom(element)) {
00734
return false;
00735 }
00736
00737
QString typeStr = element.attribute(
"TYPE");
00738
if(!typeStr.isNull()) {
00739 symbolType = static_cast<SymbolType>(typeStr.toInt());
00740 }
00741
00742
return true;
00743 }
00744
00750 bool SymbolElement::readContentFromDom(
QDomNode& node)
00751 {
00752
if (!BasicElement::readContentFromDom(node)) {
00753
return false;
00754 }
00755
00756
if ( !buildChild( content, node,
"CONTENT" ) ) {
00757 kdWarning( DEBUGID ) <<
"Empty content in SymbolElement." << endl;
00758
return false;
00759 }
00760 node = node.nextSibling();
00761
00762
bool lowerRead =
false;
00763
bool upperRead =
false;
00764
00765
while (!node.isNull() && !(upperRead && lowerRead)) {
00766
00767
if (!lowerRead && (node.nodeName().upper() ==
"LOWER")) {
00768 lowerRead = buildChild( lower=
new SequenceElement(
this ), node,
"LOWER" );
00769
if ( !lowerRead )
return false;
00770 }
00771
00772
if (!upperRead && (node.nodeName().upper() ==
"UPPER")) {
00773 upperRead = buildChild( upper=
new SequenceElement(
this ), node,
"UPPER" );
00774
if ( !upperRead )
return false;
00775 }
00776
00777 node = node.nextSibling();
00778 }
00779
return true;
00780 }
00781
00782 QString SymbolElement::toLatex()
00783 {
00784
QString sym;
00785
00786
switch(symbolType) {
00787
00788
case 1001:
00789 sym=
"\\int";
00790
break;
00791
case 1002:
00792 sym=
"\\sum";
00793
break;
00794
case 1003:
00795 sym=
"\\prod";
00796
break;
00797
00798
default:
00799 sym=
" ";
00800
00801 }
00802
00803
00804
if(hasLower()) {
00805 sym+=
"_{";
00806 sym+=lower->
toLatex();
00807 sym+=
"}";
00808 }
00809
00810
if(
hasUpper()) {
00811 sym+=
"^{";
00812 sym+=upper->
toLatex();
00813 sym+=
"}";
00814 }
00815
00816 sym+=
"{";
00817 sym+=content->
toLatex();
00818 sym+=
"}";
00819
00820
00821
return sym;
00822 }
00823
00824
QString SymbolElement::formulaString()
00825 {
00826
QString sym;
00827
switch ( symbolType ) {
00828
case 1001:
00829 sym=
"int(";
00830
break;
00831
case 1002:
00832 sym=
"sum(";
00833
break;
00834
case 1003:
00835 sym=
"prod(";
00836
break;
00837
default:
00838 sym=
"(";
00839 }
00840 sym += content->
formulaString();
00841
if ( hasLower() ) {
00842 sym +=
", " + lower->
formulaString();
00843 }
00844
if (
hasUpper() ) {
00845 sym +=
", " + upper->
formulaString();
00846 }
00847
return sym +
")";
00848 }
00849
00850 void SymbolElement::writeMathML(
QDomDocument doc,
QDomNode parent )
00851 {
00852
QDomElement de = doc.createElement(
"mrow" );
00853
QDomElement mo = doc.createElement(
"mo" );
00854
00855
QString value;
00856
00857
switch( symbolType )
00858 {
00859
case EmptyBracket:
break;
00860
case LeftLineBracket:
case RightLineBracket:
00861 mo.appendChild( doc.createTextNode(
"|" ) );
break;
00862
case Integral:
00863 mo.appendChild( doc.createEntityReference(
"int" ) );
break;
00864
case Sum:
00865 mo.appendChild( doc.createEntityReference(
"sum" ) );
break;
00866
case Product:
00867 mo.appendChild( doc.createEntityReference(
"prod" ) );
break;
00868
default:
00869 mo.appendChild( doc.createTextNode(
QChar( symbolType ) ) );
00870 }
00871
00872
QDomElement between;
00873
if (
hasUpper() && hasLower() )
00874 {
00875 between = doc.createElement(
"msubsup" );
00876 between.appendChild( mo );
00877 lower->
writeMathML( doc, between );
00878 upper->
writeMathML( doc, between );
00879 }
00880
else if (
hasUpper() )
00881 {
00882 between = doc.createElement(
"msup" );
00883 between.appendChild( mo );
00884 upper->
writeMathML( doc, between );
00885 }
00886
else if ( hasLower() )
00887 {
00888 between = doc.createElement(
"msub" );
00889 between.appendChild( mo );
00890 lower->
writeMathML( doc, between );
00891 }
00892
else
00893 between = mo;
00894
00895 de.appendChild( between );
00896 content->
writeMathML( doc, de );
00897
00898 parent.appendChild( de );
00899 }
00900
00901 KFORMULA_NAMESPACE_END