Annotation of Amaya/amaya/MathMLbuilder.c, revision 1.131

1.1       cvs         1: /*
                      2:  *
1.110     cvs         3:  *  (c) COPYRIGHT MIT and INRIA, 1996-2001
1.1       cvs         4:  *  Please first read the full copyright statement in file COPYRIGHT.
                      5:  *
                      6:  */
                      7:  
                      8: /*
                      9:  *
                     10:  * MathMLbuilder
                     11:  *
                     12:  * Author: V. Quint
                     13:  */
                     14: 
1.51      cvs        15:  
1.1       cvs        16: #define THOT_EXPORT extern
1.4       cvs        17: #include "amaya.h"
1.25      cvs        18: #include "css.h"
1.59      cvs        19: #include "html2thot_f.h"
1.79      cvs        20: #include "Xml2thot_f.h"
1.25      cvs        21: #include "MathML.h"
                     22: #include "parser.h"
1.59      cvs        23: #include "styleparser_f.h"
                     24: #include "style.h"
                     25: #include "undo.h"
1.1       cvs        26: 
1.109     cvs        27: 
1.106     cvs        28: /* Define a pointer to let parser functions access the Math entity table */
                     29: extern XmlEntity *pMathEntityTable;
1.1       cvs        30: 
                     31: /* mapping table of attribute values */
                     32: static AttrValueMapping MathMLAttrValueMappingTable[] =
                     33: {
1.115     cvs        34:  {MathML_ATTR_accent, "true", MathML_ATTR_accent_VAL_true},
                     35:  {MathML_ATTR_accent, "false", MathML_ATTR_accent_VAL_false},
1.46      cvs        36: 
1.115     cvs        37:  {MathML_ATTR_accentunder, "true", MathML_ATTR_accentunder_VAL_true},
                     38:  {MathML_ATTR_accentunder, "false", MathML_ATTR_accentunder_VAL_false},
1.46      cvs        39: 
1.115     cvs        40:  {MathML_ATTR_align, "top", MathML_ATTR_align_VAL_top_},
                     41:  {MathML_ATTR_align, "bottom", MathML_ATTR_align_VAL_bottom_},
                     42:  {MathML_ATTR_align, "center", MathML_ATTR_align_VAL_center},
                     43:  {MathML_ATTR_align, "baseline", MathML_ATTR_align_VAL_baseline},
                     44:  {MathML_ATTR_align, "axis", MathML_ATTR_align_VAL_axis},
                     45: 
                     46:  {MathML_ATTR_bevelled, "true", MathML_ATTR_bevelled_VAL_true},
                     47:  {MathML_ATTR_bevelled, "false", MathML_ATTR_bevelled_VAL_false},
                     48: 
                     49:  {MathML_ATTR_columnalign_mtd, "center", MathML_ATTR_columnalign_mtd_VAL_center_},
                     50:  {MathML_ATTR_columnalign_mtd, "left", MathML_ATTR_columnalign_mtd_VAL_left_},
                     51:  {MathML_ATTR_columnalign_mtd, "right", MathML_ATTR_columnalign_mtd_VAL_right_},
                     52: 
                     53:  {MathML_ATTR_denomalign, "center", MathML_ATTR_denomalign_VAL_center_},
                     54:  {MathML_ATTR_denomalign, "left", MathML_ATTR_denomalign_VAL_left_},
                     55:  {MathML_ATTR_denomalign, "right", MathML_ATTR_denomalign_VAL_right_},
                     56: 
                     57:  {MathML_ATTR_display, "block", MathML_ATTR_display_VAL_block},
                     58:  {MathML_ATTR_display, "display", MathML_ATTR_display_VAL_block},
                     59:  {MathML_ATTR_display, "inline", MathML_ATTR_display_VAL_inline_},
                     60: 
                     61:  {MathML_ATTR_displaystyle, "true", MathML_ATTR_displaystyle_VAL_true},
                     62:  {MathML_ATTR_displaystyle, "false", MathML_ATTR_displaystyle_VAL_false},
                     63: 
                     64:  {MathML_ATTR_edge, "left", MathML_ATTR_edge_VAL_left_},
                     65:  {MathML_ATTR_edge, "right", MathML_ATTR_edge_VAL_right_},
                     66: 
                     67:  {MathML_ATTR_equalcolumns, "true", MathML_ATTR_equalcolumns_VAL_true},
                     68:  {MathML_ATTR_equalcolumns, "false", MathML_ATTR_equalcolumns_VAL_false},
                     69: 
                     70:  {MathML_ATTR_equalrows, "true", MathML_ATTR_equalrows_VAL_true},
                     71:  {MathML_ATTR_equalrows, "false", MathML_ATTR_equalrows_VAL_false},
                     72: 
                     73:  {MathML_ATTR_fence, "true", MathML_ATTR_fence_VAL_true},
                     74:  {MathML_ATTR_fence, "false", MathML_ATTR_fence_VAL_false},
                     75: 
                     76:  {MathML_ATTR_fontstyle, "italic", MathML_ATTR_fontstyle_VAL_italic},
                     77:  {MathML_ATTR_fontstyle, "normal", MathML_ATTR_fontstyle_VAL_normal_},
                     78: 
                     79:  {MathML_ATTR_fontweight, "normal", MathML_ATTR_fontweight_VAL_normal_},
                     80:  {MathML_ATTR_fontweight, "bold", MathML_ATTR_fontweight_VAL_bold_},
                     81: 
                     82:  {MathML_ATTR_form, "prefix", MathML_ATTR_form_VAL_prefix},
                     83:  {MathML_ATTR_form, "infix", MathML_ATTR_form_VAL_infix},
                     84:  {MathML_ATTR_form, "postfix", MathML_ATTR_form_VAL_postfix},
                     85: 
                     86:  {MathML_ATTR_frame, "none", MathML_ATTR_frame_VAL_none_},
                     87:  {MathML_ATTR_frame, "solid", MathML_ATTR_frame_VAL_solid_},
                     88:  {MathML_ATTR_frame, "dashed", MathML_ATTR_frame_VAL_dashed_},
                     89: 
                     90:  {MathML_ATTR_groupalign_malgr, "left", MathML_ATTR_groupalign_malgr_VAL_left_},
                     91:  {MathML_ATTR_groupalign_malgr, "center", MathML_ATTR_groupalign_malgr_VAL_center_},
                     92:  {MathML_ATTR_groupalign_malgr, "right", MathML_ATTR_groupalign_malgr_VAL_right_},
                     93:  {MathML_ATTR_groupalign_malgr, "decimalpoint", MathML_ATTR_groupalign_malgr_VAL_decimalpoint},
                     94: 
                     95:  {MathML_ATTR_largeop, "true", MathML_ATTR_largeop_VAL_true},
                     96:  {MathML_ATTR_largeop, "false", MathML_ATTR_largeop_VAL_false},
                     97: 
                     98:  {MathML_ATTR_linebreak_, "auto", MathML_ATTR_linebreak__VAL_auto_},
                     99:  {MathML_ATTR_linebreak_, "newline", MathML_ATTR_linebreak__VAL_newline},
                    100:  {MathML_ATTR_linebreak_, "indentingnewline", MathML_ATTR_linebreak__VAL_indentingnewline},
                    101:  {MathML_ATTR_linebreak_, "nobreak", MathML_ATTR_linebreak__VAL_nobreak_},
                    102:  {MathML_ATTR_linebreak_, "goodbreak", MathML_ATTR_linebreak__VAL_goodbreak},
                    103:  {MathML_ATTR_linebreak_, "badbreak", MathML_ATTR_linebreak__VAL_badbreak},
                    104: 
                    105:  {MathML_ATTR_mathvariant, "normal", MathML_ATTR_mathvariant_VAL_normal_},
                    106:  {MathML_ATTR_mathvariant, "bold", MathML_ATTR_mathvariant_VAL_bold_},
                    107:  {MathML_ATTR_mathvariant, "italic", MathML_ATTR_mathvariant_VAL_italic},
                    108:  {MathML_ATTR_mathvariant, "bold-italic", MathML_ATTR_mathvariant_VAL_bold_italic},
                    109:  {MathML_ATTR_mathvariant, "double-struck", MathML_ATTR_mathvariant_VAL_double_struck},
                    110:  {MathML_ATTR_mathvariant, "bold-fraktur", MathML_ATTR_mathvariant_VAL_bold_fraktur},
                    111:  {MathML_ATTR_mathvariant, "script", MathML_ATTR_mathvariant_VAL_script},
                    112:  {MathML_ATTR_mathvariant, "bold-script", MathML_ATTR_mathvariant_VAL_bold_script},
                    113:  {MathML_ATTR_mathvariant, "fraktur", MathML_ATTR_mathvariant_VAL_fraktur},
                    114:  {MathML_ATTR_mathvariant, "sans-serif", MathML_ATTR_mathvariant_VAL_sans_serif},
                    115:  {MathML_ATTR_mathvariant, "bold-sans-serif", MathML_ATTR_mathvariant_VAL_bold_sans_serif},
                    116:  {MathML_ATTR_mathvariant, "sans-serif-italic", MathML_ATTR_mathvariant_VAL_sans_serif_italic},
                    117:  {MathML_ATTR_mathvariant, "sans-serif-bold-italic", MathML_ATTR_mathvariant_VAL_sans_serif_bold_italic},
                    118:  {MathML_ATTR_mathvariant, "monospace", MathML_ATTR_mathvariant_VAL_monospace},
                    119: 
                    120:  {MathML_ATTR_movablelimits, "true", MathML_ATTR_movablelimits_VAL_true},
                    121:  {MathML_ATTR_movablelimits, "false", MathML_ATTR_movablelimits_VAL_false},
                    122: 
                    123:  {MathML_ATTR_notation, "longdiv", MathML_ATTR_notation_VAL_longdiv},
                    124:  {MathML_ATTR_notation, "actuarial", MathML_ATTR_notation_VAL_actuarial},
                    125:  {MathML_ATTR_notation, "radical", MathML_ATTR_notation_VAL_radical},
                    126: 
                    127:  {MathML_ATTR_numalign, "center", MathML_ATTR_numalign_VAL_center_},
                    128:  {MathML_ATTR_numalign, "left", MathML_ATTR_numalign_VAL_left_},
                    129:  {MathML_ATTR_numalign, "right", MathML_ATTR_numalign_VAL_right_},
                    130: 
                    131:  {MathML_ATTR_overflow, "scroll", MathML_ATTR_overflow_VAL_scroll},
                    132:  {MathML_ATTR_overflow, "elide", MathML_ATTR_overflow_VAL_elide},
                    133:  {MathML_ATTR_overflow, "truncate", MathML_ATTR_overflow_VAL_truncate},
                    134:  {MathML_ATTR_overflow, "scale", MathML_ATTR_overflow_VAL_scale_},
                    135: 
                    136:  {MathML_ATTR_rowalign_mtr, "top", MathML_ATTR_rowalign_mtr_VAL_top_},
                    137:  {MathML_ATTR_rowalign_mtr, "bottom", MathML_ATTR_rowalign_mtr_VAL_bottom_},
                    138:  {MathML_ATTR_rowalign_mtr, "center", MathML_ATTR_rowalign_mtr_VAL_center},
                    139:  {MathML_ATTR_rowalign_mtr, "baseline", MathML_ATTR_rowalign_mtr_VAL_baseline},
                    140:  {MathML_ATTR_rowalign_mtr, "axis", MathML_ATTR_rowalign_mtr_VAL_axis},
                    141: 
                    142:  {MathML_ATTR_separator, "true", MathML_ATTR_separator_VAL_true},
                    143:  {MathML_ATTR_separator, "false", MathML_ATTR_separator_VAL_false},
                    144: 
                    145:  {MathML_ATTR_side, "left", MathML_ATTR_side_VAL_left_},
                    146:  {MathML_ATTR_side, "leftoverlap", MathML_ATTR_side_VAL_leftoverlap},
                    147:  {MathML_ATTR_side, "right", MathML_ATTR_side_VAL_right_},
                    148:  {MathML_ATTR_side, "rightoverlap", MathML_ATTR_side_VAL_rightoverlap},
                    149: 
                    150:  {MathML_ATTR_stretchy, "true", MathML_ATTR_stretchy_VAL_true},
                    151:  {MathML_ATTR_stretchy, "false", MathML_ATTR_stretchy_VAL_false},
1.46      cvs       152: 
1.115     cvs       153:  {MathML_ATTR_symmetric, "true", MathML_ATTR_symmetric_VAL_true},
                    154:  {MathML_ATTR_symmetric, "false", MathML_ATTR_symmetric_VAL_false},
1.21      cvs       155: 
1.115     cvs       156:  {MathML_ATTR_xml_space, "default", MathML_ATTR_xml_space_VAL_xml_space_default},
                    157:  {MathML_ATTR_xml_space, "preserve", MathML_ATTR_xml_space_VAL_xml_space_preserve},
1.73      cvs       158: 
1.115     cvs       159:  {0, "", 0}                    /* Last entry. Mandatory */
1.1       cvs       160: };
                    161: 
                    162: #define MaxMsgLength 200
                    163: 
1.12      cvs       164: #include "HTMLtable_f.h"
1.29      cvs       165: #include "Mathedit_f.h"
                    166: #include "XMLparser_f.h"
                    167: #include "styleparser_f.h"
                    168: #include "fetchXMLname_f.h"
1.1       cvs       169: 
                    170: /*----------------------------------------------------------------------
                    171:    MapMathMLAttribute
                    172:    Search in the Attribute Mapping Table the entry for the
                    173:    attribute of name Attr and returns the corresponding Thot attribute type.
                    174:   ----------------------------------------------------------------------*/
1.120     cvs       175: void MapMathMLAttribute (char *attrName, AttributeType *attrType,
                    176:                         char *elementName, ThotBool *level, Document doc)
1.1       cvs       177: {
1.68      cvs       178:   attrType->AttrSSchema = GetMathMLSSchema (doc);
1.91      cvs       179:   MapXMLAttribute (MATH_TYPE, attrName, elementName, level, doc, &(attrType->AttrTypeNum));
1.1       cvs       180: }
                    181: 
                    182: /*----------------------------------------------------------------------
                    183:    MapMathMLAttributeValue
                    184:    Search in the Attribute Value Mapping Table the entry for the attribute
                    185:    ThotAtt and its value AttrVal. Returns the corresponding Thot value.
                    186:   ----------------------------------------------------------------------*/
1.120     cvs       187: void MapMathMLAttributeValue (char *AttrVal, AttributeType attrType,
                    188:                              int *value)
1.1       cvs       189: {
1.123     cvs       190:   int                 i;
1.1       cvs       191: 
1.123     cvs       192:   *value = 0;
                    193:   i = 0;
                    194:   while (MathMLAttrValueMappingTable[i].ThotAttr != attrType.AttrTypeNum &&
                    195:         MathMLAttrValueMappingTable[i].ThotAttr != 0)
                    196:     i++;
                    197:   if (MathMLAttrValueMappingTable[i].ThotAttr == attrType.AttrTypeNum)
                    198:     do
                    199:       if (!strcmp (MathMLAttrValueMappingTable[i].XMLattrValue, AttrVal))
                    200:        *value = MathMLAttrValueMappingTable[i].ThotAttrValue;
                    201:       else
                    202:        i++;
                    203:     while (*value == 0 &&
                    204:           MathMLAttrValueMappingTable[i].ThotAttr == attrType.AttrTypeNum);
1.1       cvs       205: }
                    206: 
                    207: /*----------------------------------------------------------------------
                    208:    MapMathMLEntity
                    209:    Search that entity in the entity table and return the corresponding value.
                    210:   ----------------------------------------------------------------------*/
1.120     cvs       211: void MapMathMLEntity (char *entityName, char *entityValue,
                    212:                      char *alphabet)
1.1       cvs       213: {
                    214:    int i;
1.67      cvs       215:   ThotBool       found;
1.1       cvs       216: 
1.67      cvs       217:   found = FALSE;
1.106     cvs       218:   for (i = 0; pMathEntityTable[i].charCode >= 0 && !found; i++)
1.116     cvs       219:     found = !strcmp (pMathEntityTable[i].charName, entityName);
1.67      cvs       220: 
                    221:   if (found)
                    222:     /* entity found */
                    223:     {
                    224:       i--;
1.116     cvs       225:       entityValue[0] = (unsigned char) pMathEntityTable[i].charCode;
1.1       cvs       226:       entityValue[1] = EOS;
1.110     cvs       227:       *alphabet = 'G';
1.109     cvs       228:       /* *alphabet = pMathEntityTable[i].charAlphabet;*/
1.67      cvs       229:     }
                    230:   else
                    231:     {
1.1       cvs       232:       entityValue[0] = EOS;
                    233:       *alphabet = EOS;
1.67      cvs       234:     }
1.1       cvs       235: }
                    236: 
                    237: /*----------------------------------------------------------------------
1.130     carcone   238:    MathMLEntityCreated
                    239:   ----------------------------------------------------------------------*/
                    240: void MathMLEntityCreated (unsigned char *entityValue, Language lang,
                    241:                         char *entityName, Document doc)
                    242: 
                    243:  {
                    244:  }
                    245: 
                    246: /*----------------------------------------------------------------------
1.1       cvs       247:   ElementNeedsPlaceholder
                    248:   returns TRUE if element el needs a sibling placeholder.
                    249:   ----------------------------------------------------------------------*/
1.18      cvs       250: ThotBool     ElementNeedsPlaceholder (Element el)
1.1       cvs       251: {
                    252:   ElementType   elType;
                    253:   Element      child, parent;
1.18      cvs       254:   ThotBool     ret;
1.1       cvs       255:  
                    256:   ret = FALSE;
                    257:   elType = TtaGetElementType (el);
1.43      cvs       258:   if (elType.ElTypeNum == MathML_EL_MS ||
                    259:       elType.ElTypeNum == MathML_EL_MSPACE ||
1.39      cvs       260:       elType.ElTypeNum == MathML_EL_MROW ||
                    261:       elType.ElTypeNum == MathML_EL_MFRAC ||
1.54      cvs       262:       elType.ElTypeNum == MathML_EL_BevelledMFRAC ||
1.39      cvs       263:       elType.ElTypeNum == MathML_EL_MSQRT ||
                    264:       elType.ElTypeNum == MathML_EL_MROOT ||
                    265:       elType.ElTypeNum == MathML_EL_MSTYLE ||
                    266:       elType.ElTypeNum == MathML_EL_MERROR ||
                    267:       elType.ElTypeNum == MathML_EL_MPADDED ||
                    268:       elType.ElTypeNum == MathML_EL_MPHANTOM ||
                    269:       elType.ElTypeNum == MathML_EL_MFENCED ||
1.1       cvs       270:       elType.ElTypeNum == MathML_EL_MF ||
                    271:       elType.ElTypeNum == MathML_EL_MSUB ||
                    272:       elType.ElTypeNum == MathML_EL_MSUP ||
1.39      cvs       273:       elType.ElTypeNum == MathML_EL_MSUBSUP ||
1.1       cvs       274:       elType.ElTypeNum == MathML_EL_MUNDER ||
                    275:       elType.ElTypeNum == MathML_EL_MOVER ||
                    276:       elType.ElTypeNum == MathML_EL_MUNDEROVER ||
1.28      cvs       277:       elType.ElTypeNum == MathML_EL_MMULTISCRIPTS ||
1.39      cvs       278:       elType.ElTypeNum == MathML_EL_MTABLE ||
                    279:       elType.ElTypeNum == MathML_EL_MACTION)
1.1       cvs       280:      ret = TRUE;
                    281:   else
                    282:      if (elType.ElTypeNum == MathML_EL_MO)
                    283:        /* an operator that contains a single Symbol needs a placeholder,
                    284:           except when it is in a Base or UnderOverBase */
                    285:        {
                    286:        child = TtaGetFirstChild (el);
                    287:        if (child != NULL)
                    288:           {
                    289:           elType = TtaGetElementType (child);
                    290:           if (elType.ElTypeNum == MathML_EL_SYMBOL_UNIT)
                    291:              {
                    292:              ret = TRUE;
                    293:              parent = TtaGetParent (el);
                    294:              if (parent != NULL)
                    295:                {
                    296:                elType = TtaGetElementType (parent);
                    297:                if (elType.ElTypeNum == MathML_EL_Base ||
                    298:                    elType.ElTypeNum == MathML_EL_UnderOverBase)
                    299:                   ret = FALSE;
                    300:                }
                    301:              }
                    302:           }
                    303:        }
                    304:   return ret;
                    305: }
                    306:  
                    307: /*----------------------------------------------------------------------
                    308:   CreatePlaceholders
                    309:   ----------------------------------------------------------------------*/
                    310: static void    CreatePlaceholders (Element el, Document doc)
                    311: {
                    312:    Element     sibling, prev, constr, child;
                    313:    Attribute   attr;
                    314:    ElementType elType;
                    315:    AttributeType       attrType;
1.18      cvs       316:    ThotBool    create;
1.1       cvs       317: 
1.55      cvs       318:    if (!el)
                    319:       return;
1.2       cvs       320:    elType.ElSSchema = GetMathMLSSchema (doc);
1.1       cvs       321:    prev = NULL;
                    322:    create = TRUE;
                    323:    sibling = el;
                    324:    while (sibling != NULL)
                    325:       {
                    326:       if (!ElementNeedsPlaceholder (sibling))
                    327:         create = FALSE;
                    328:       else
                    329:         {
                    330:         if (sibling == el)
                    331:            /* first element */
                    332:            {
                    333:            elType = TtaGetElementType (sibling);
                    334:            if (elType.ElTypeNum == MathML_EL_MF)
                    335:               /* the first element is a MF. Don't create a placeholder
                    336:                  before */
                    337:               create = FALSE;
                    338:            else if (elType.ElTypeNum == MathML_EL_MROW)
                    339:               /* the first element is a MROW */
                    340:               {
                    341:               child = TtaGetFirstChild (sibling);
                    342:               if (child != NULL)
                    343:                  {
                    344:                  elType = TtaGetElementType (child);
                    345:                  if (elType.ElTypeNum != MathML_EL_MF)
                    346:                     /* the first child of the MROW element is not a MF */
                    347:                     /* Don't create a placeholder before */
                    348:                     create = FALSE;
                    349:                  }
                    350:               }
                    351:            }
                    352:         if (create)
                    353:            {
                    354:             elType.ElTypeNum = MathML_EL_Construct;
                    355:            constr = TtaNewElement (doc, elType);
                    356:            TtaInsertSibling (constr, sibling, TRUE, doc);
                    357:            attrType.AttrSSchema = elType.ElSSchema;
1.22      cvs       358:            attrType.AttrTypeNum = MathML_ATTR_IntPlaceholder;
1.1       cvs       359:            attr = TtaNewAttribute (attrType);
                    360:            TtaAttachAttribute (constr, attr, doc);
1.55      cvs       361:            TtaSetAttributeValue (attr, MathML_ATTR_IntPlaceholder_VAL_yes_,
                    362:                                  constr, doc);
1.1       cvs       363:            }
                    364:         create = TRUE;
                    365:         }
                    366:       prev = sibling;
                    367:       TtaNextSibling (&sibling);
                    368:       }
                    369:    if (prev != NULL && create)
                    370:       {
                    371:        elType = TtaGetElementType (prev);
1.95      cvs       372:        /* don't insert a placeholder after the last element if it's a MF */
                    373:        if (elType.ElTypeNum == MathML_EL_MF)
1.1       cvs       374:           create = FALSE;
                    375:        else if (elType.ElTypeNum == MathML_EL_MROW)
                    376:           /* the last element is a MROW */
                    377:           {
                    378:           child = TtaGetLastChild (prev);
                    379:           if (child != NULL)
                    380:              {
                    381:              elType = TtaGetElementType (child);
                    382:              if (elType.ElTypeNum != MathML_EL_MF)
                    383:                 /* the last child of the MROW element is not a MF */
                    384:                 /* Don't create a placeholder before */
                    385:                 create = FALSE;
                    386:              }
                    387:           }
                    388:        if (create)
                    389:           {
                    390:            elType.ElTypeNum = MathML_EL_Construct;
                    391:           constr = TtaNewElement (doc, elType);
                    392:           TtaInsertSibling (constr, prev, FALSE, doc);
                    393:           attrType.AttrSSchema = elType.ElSSchema;
1.22      cvs       394:           attrType.AttrTypeNum = MathML_ATTR_IntPlaceholder;
1.1       cvs       395:           attr = TtaNewAttribute (attrType);
                    396:           TtaAttachAttribute (constr, attr, doc);
1.55      cvs       397:           TtaSetAttributeValue (attr, MathML_ATTR_IntPlaceholder_VAL_yes_,
                    398:                                 constr, doc);
1.1       cvs       399:           } 
                    400:       }
                    401: }
                    402: 
                    403: /*----------------------------------------------------------------------
1.95      cvs       404:   NextNotComment
                    405:   Return the next sibling of element el that is not an XMLcomment element.
                    406:   Return el itself if it's not a comment.
1.1       cvs       407:   ----------------------------------------------------------------------*/
1.95      cvs       408: static void    NextNotComment (Element* el, Element* prev)
1.1       cvs       409: {
                    410:    ElementType elType;
                    411: 
                    412:    if (*el == NULL)
                    413:       return;
                    414:    elType = TtaGetElementType (*el);
1.95      cvs       415:    while (*el != NULL && elType.ElTypeNum == MathML_EL_XMLcomment)
1.1       cvs       416:       {
                    417:       *prev = *el;
                    418:       TtaNextSibling (el);
                    419:       if (*el != NULL)
                    420:        elType = TtaGetElementType (*el);
                    421:       }
                    422: }
                    423: 
                    424: /*----------------------------------------------------------------------
                    425:   CheckMathSubExpressions
                    426:   Children of element el should be of type type1, type2, and type3.
1.56      cvs       427:   If they are not, wrap them in elements of these types.
1.124     cvs       428:   If element el has too many or not enough children, return FALSE.
1.1       cvs       429:   ----------------------------------------------------------------------*/
1.56      cvs       430: static ThotBool CheckMathSubExpressions (Element el, int type1, int type2, int type3, Document doc)
1.1       cvs       431: {
                    432:   Element      child, new, prev;
                    433:   ElementType  elType, childType;
1.124     cvs       434:   char          msgBuffer[200];
1.56      cvs       435:   ThotBool      result;
1.1       cvs       436: 
1.56      cvs       437:   result = TRUE;
1.2       cvs       438:   elType.ElSSchema = GetMathMLSSchema (doc);
1.1       cvs       439:   child = TtaGetFirstChild (el);
                    440:   prev = NULL;
1.95      cvs       441:   NextNotComment (&child, &prev);
1.56      cvs       442:   if (type1 == 0)
1.1       cvs       443:     {
1.56      cvs       444:     if (child)
                    445:       /* no child expected and there is one, error */
1.124     cvs       446:       {
                    447:        sprintf (msgBuffer, "No subexpression allowed in %s",
                    448:                 TtaGetElementTypeName (TtaGetElementType (el)));
                    449:        XmlParseError (errorParsing, msgBuffer, 0);
                    450:        result = FALSE;
                    451:       }
1.56      cvs       452:     }
                    453:   else
                    454:     if (!child)
                    455:       /* a first child is expected and it's missing */
1.124     cvs       456:       {
                    457:        sprintf (msgBuffer, "Missing subexpression in %s",
                    458:                 TtaGetElementTypeName (TtaGetElementType (el)));
                    459:        XmlParseError (errorParsing, msgBuffer, 0);
                    460:        result = FALSE;
                    461:       }
1.56      cvs       462:     else
                    463:       {
1.1       cvs       464:       elType.ElTypeNum = type1;
                    465:       childType = TtaGetElementType (child);
                    466:       if (TtaSameTypes (childType, elType) == 0)
                    467:        {
                    468:          TtaRemoveTree (child, doc);   
                    469:          new = TtaNewElement (doc, elType);
                    470:          if (prev == NULL)
                    471:            TtaInsertFirstChild (&new, el, doc);
                    472:          else
                    473:            TtaInsertSibling (new, prev, FALSE, doc);
                    474:          TtaInsertFirstChild (&child, new, doc);
                    475:          CreatePlaceholders (child, doc);
                    476:          child = new;
                    477:        }
1.56      cvs       478:       prev = child;
                    479:       TtaNextSibling (&child);
1.95      cvs       480:       NextNotComment (&child, &prev);
1.56      cvs       481:       if (type2 == 0)
                    482:         {
                    483:         if (child)
                    484:           /* this second child is not expected, error */
1.124     cvs       485:          {
                    486:            sprintf (msgBuffer, "Only 1 subexpression allowed in %s",
                    487:                     TtaGetElementTypeName (TtaGetElementType (el)));
                    488:            XmlParseError (errorParsing, msgBuffer, 0);
                    489:            result = FALSE;
                    490:          }
1.56      cvs       491:         }
                    492:       else
1.1       cvs       493:        {
1.56      cvs       494:          if (!child)
                    495:            /* a second child is expected and it's missing */
1.124     cvs       496:            {
                    497:              sprintf (msgBuffer, "2 subexpressions required in %s",
                    498:                       TtaGetElementTypeName (TtaGetElementType (el)));
                    499:              XmlParseError (errorParsing, msgBuffer, 0);
                    500:              result = FALSE;
                    501:            }
1.56      cvs       502:          else
1.1       cvs       503:            {
                    504:              elType.ElTypeNum = type2;
                    505:              childType = TtaGetElementType (child);
                    506:              if (TtaSameTypes (childType, elType) == 0)
                    507:                {
                    508:                  TtaRemoveTree (child, doc);
                    509:                  new = TtaNewElement (doc, elType);
                    510:                  TtaInsertSibling (new, prev, FALSE, doc);
                    511:                  TtaInsertFirstChild (&child, new, doc);
                    512:                  CreatePlaceholders (child, doc);
                    513:                  child = new;
                    514:                }
1.56      cvs       515:              prev = child;
                    516:              TtaNextSibling (&child);
1.95      cvs       517:              NextNotComment (&child, &prev);
1.56      cvs       518:              if (type3 == 0)
1.1       cvs       519:                {
1.56      cvs       520:                if (child)
                    521:                  /* this third child is not expected, error */
1.124     cvs       522:                  {
                    523:                    sprintf (msgBuffer, "Only 2 subexpressions allowed in %s",
                    524:                             TtaGetElementTypeName (TtaGetElementType (el)));
                    525:                    XmlParseError (errorParsing, msgBuffer, 0);
                    526:                    result = FALSE;
                    527:                  }
1.56      cvs       528:                }
                    529:              else
                    530:                {
                    531:                  if (!child)
                    532:                    /* a third child is expected and it's missing */
1.124     cvs       533:                    {
                    534:                      sprintf (msgBuffer, "3 subexpressions required in %s",
                    535:                               TtaGetElementTypeName (TtaGetElementType (el)));
                    536:                      XmlParseError (errorParsing, msgBuffer, 0);
                    537:                      result = FALSE;
                    538:                    }
1.56      cvs       539:                  else
1.1       cvs       540:                    {
                    541:                      elType.ElTypeNum = type3;
                    542:                      childType = TtaGetElementType (child);
                    543:                      if (TtaSameTypes (childType, elType) == 0)
                    544:                        {
                    545:                          TtaRemoveTree (child, doc);
                    546:                          new = TtaNewElement (doc, elType);
                    547:                          TtaInsertSibling (new, prev, FALSE, doc);
                    548:                          TtaInsertFirstChild (&child, new, doc);
                    549:                          CreatePlaceholders (child, doc);
1.56      cvs       550:                          child = new;
1.1       cvs       551:                        }
                    552:                    }
1.56      cvs       553:                  prev = child;
                    554:                  TtaNextSibling (&child);
1.95      cvs       555:                  NextNotComment (&child, &prev);
1.56      cvs       556:                  if (child)
                    557:                    /* this fourth child is unexpected */
1.124     cvs       558:                    {
                    559:                      sprintf (msgBuffer,"Only 3 subexpressions allowed in %s",
                    560:                               TtaGetElementTypeName (TtaGetElementType (el)));
                    561:                      XmlParseError (errorParsing, msgBuffer, 0);
                    562:                      result = FALSE;
                    563:                    }
1.1       cvs       564:                }
                    565:            }
                    566:         }
1.56      cvs       567:       }
                    568:   return result;
1.1       cvs       569: }
                    570: 
                    571: 
                    572: /*----------------------------------------------------------------------
1.22      cvs       573:    SetSingleIntHorizStretchAttr
1.1       cvs       574: 
1.22      cvs       575:    Put a IntHorizStretch attribute on element el if it contains only
1.1       cvs       576:    a MO element that is a stretchable symbol.
                    577:  -----------------------------------------------------------------------*/
1.22      cvs       578: void SetSingleIntHorizStretchAttr (Element el, Document doc, Element* selEl)
1.1       cvs       579: {
                    580:   Element      child, sibling, textEl, symbolEl;
                    581:   ElementType  elType;
                    582:   Attribute    attr;
                    583:   AttributeType        attrType;
1.55      cvs       584:   Language     lang;
1.128     vatton    585:   CHAR_T        text[2];
                    586:   char         alphabet;
1.49      cvs       587:   unsigned char c;
1.128     vatton    588:   int          len;
1.1       cvs       589: 
                    590:   if (el == NULL)
                    591:      return;
                    592:   child = TtaGetFirstChild (el);
1.55      cvs       593:   if (child)
1.1       cvs       594:      {
                    595:      elType = TtaGetElementType (child);
1.98      cvs       596:      while (elType.ElTypeNum == MathML_EL_MROW && child)
                    597:         /* the first child is a mrow. Look whether it contains a single
                    598:            child of type mo */
                    599:         {
                    600:         child = TtaGetFirstChild (child);
                    601:        if (child)
                    602:          {
                    603:            sibling = child;
                    604:            TtaNextSibling (&sibling);
                    605:            if (sibling == NULL)
                    606:              /* the mrow element has a single child. Get its type */
                    607:              elType = TtaGetElementType (child);
                    608:            else
                    609:              child = NULL;
                    610:          }
                    611:        }
                    612:      if (elType.ElTypeNum == MathML_EL_MO && child)
1.1       cvs       613:        /* the first child is a MO */
                    614:         {
                    615:         sibling = child;
                    616:         TtaNextSibling (&sibling);
                    617:        if (sibling == NULL)
                    618:           /* there is no other child */
                    619:           {
                    620:           textEl = TtaGetFirstChild (child);
                    621:           elType = TtaGetElementType (textEl);
                    622:           if (elType.ElTypeNum == MathML_EL_TEXT_UNIT)
1.55      cvs       623:              /* the MO child contains a TEXT element */
1.1       cvs       624:              {
1.128     vatton    625:              len = TtaGetVolume (textEl);
1.1       cvs       626:              if (len == 1)
1.123     cvs       627:                 /* the TEXT element contains a single character */
                    628:                 {
                    629:                 c = EOS;
                    630:                 /* get that character */
                    631:                 len = 2;
1.128     vatton    632:                 TtaGiveBufferContent (textEl, text, len, &lang);
1.123     cvs       633:                 alphabet = TtaGetAlphabet (lang);
                    634:                 if (alphabet == 'L')
                    635:                    {
                    636:                    if (text[0] == '-' || text[0] == '_' ||
1.128     vatton    637:                        text[0] == 175)
1.123     cvs       638:                      /* a horizontal line in the middle of the box */
                    639:                      c = 'h'; 
                    640:                    }
                    641:                 else if (alphabet == 'G')
                    642:                    /* a single Symbol character */
                    643:                    {
1.128     vatton    644:                    if (text[0] == 172)
1.123     cvs       645:                      c = 'L';  /* arrow left */
1.128     vatton    646:                    else if (text[0] == 174)
1.123     cvs       647:                      c = 'R';  /* arrow right */
1.128     vatton    648:                    else if (text[0] == 45)    /* - (minus) */
1.123     cvs       649:                      /* a horizontal line in the middle of the box */
                    650:                      c = 'h'; 
1.128     vatton    651:                    else if (text[0] == 132)
1.123     cvs       652:                      c = 'o';  /* Over brace */
1.128     vatton    653:                    else if (text[0] == 133)
1.123     cvs       654:                      c = 'u';  /* Under brace */
                    655:                    }
                    656:                 if (c != EOS)
                    657:                    {
                    658:                    /* attach a IntHorizStretch attribute to the mo */
                    659:                    attrType.AttrSSchema = elType.ElSSchema;
                    660:                    attrType.AttrTypeNum = MathML_ATTR_IntHorizStretch;
                    661:                    attr = TtaNewAttribute (attrType);
                    662:                    TtaAttachAttribute (el, attr, doc);
                    663:                    TtaSetAttributeValue (attr, MathML_ATTR_IntHorizStretch_VAL_yes_, el, doc);
                    664:                    /* replace the TEXT element by a Thot SYMBOL element */
                    665:                    elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
                    666:                    symbolEl = TtaNewElement (doc, elType);
                    667:                    TtaInsertSibling (symbolEl, textEl, FALSE, doc);
                    668:                    if (selEl != NULL)
                    669:                      if (*selEl == textEl)
                    670:                        *selEl = symbolEl;
                    671:                    TtaDeleteTree (textEl, doc);
                    672:                    if (c != EOS)
                    673:                      TtaSetGraphicsShape (symbolEl, c, doc);
                    674:                    }
                    675:                 }
1.1       cvs       676:              }
                    677:           }
                    678:        }
                    679:      }
                    680: }
1.123     cvs       681:  
1.1       cvs       682: /*----------------------------------------------------------------------
1.22      cvs       683:    SetIntHorizStretchAttr
1.1       cvs       684: 
1.22      cvs       685:    Put a IntHorizStretch attribute on all children of element el which
1.1       cvs       686:    contain only a MO element that is a stretchable symbol.
                    687:  -----------------------------------------------------------------------*/
1.22      cvs       688: static void SetIntHorizStretchAttr (Element el, Document doc)
1.1       cvs       689: {
                    690:   Element      child;
                    691: 
                    692:   if (el == NULL)
                    693:      return;
                    694:   child = TtaGetFirstChild (el);
                    695:   while (child != NULL)
                    696:      {
1.22      cvs       697:      SetSingleIntHorizStretchAttr (child, doc, NULL);
1.1       cvs       698:      TtaNextSibling (&child);
                    699:      }
                    700: }
                    701: 
                    702: /*----------------------------------------------------------------------
1.22      cvs       703:    SetIntVertStretchAttr
1.1       cvs       704: 
1.22      cvs       705:    Put a IntVertStretch attribute on element el if its base element
1.1       cvs       706:    (Base for a MSUBSUP, MSUP or MSUB; UnderOverBase for a MUNDEROVER,
                    707:    a MUNDER of a MOVER) contains only a MO element that is a vertically
                    708:    stretchable symbol.
                    709:  -----------------------------------------------------------------------*/
1.22      cvs       710: void SetIntVertStretchAttr (Element el, Document doc, int base, Element* selEl)
1.1       cvs       711: {
                    712:   Element      child, sibling, textEl, symbolEl, parent, operator;
                    713:   ElementType  elType;
                    714:   Attribute    attr;
                    715:   AttributeType        attrType;
1.131   ! cvs       716:   SSchema       MathMLSSchema;
1.128     vatton    717:   Language     lang;
1.116     cvs       718:   char         alphabet;
1.131   ! cvs       719: #define buflen 50
        !           720:   CHAR_T        text[buflen];
1.49      cvs       721:   unsigned char c;
1.131   ! cvs       722:   int          len, i;
        !           723:   ThotBool      inbase, integral;
1.1       cvs       724: 
                    725:   if (el == NULL)
1.131   ! cvs       726:     return;
1.1       cvs       727:   operator = NULL;
1.131   ! cvs       728:   inbase = FALSE;
        !           729:   MathMLSSchema = TtaGetElementType(el).ElSSchema;
        !           730:     
1.1       cvs       731:   if (base == 0)
1.131   ! cvs       732:     /* it's a MO */
        !           733:     {
        !           734:       parent = TtaGetParent (el);
        !           735:       if (parent != NULL)
1.1       cvs       736:        {
1.131   ! cvs       737:          /* don't process the mo if it is within a base. It will be processed
        !           738:             when the enclosing construct is processed (see below) */
        !           739:          elType = TtaGetElementType (parent);
        !           740:          if (elType.ElSSchema != MathMLSSchema ||
        !           741:              (elType.ElTypeNum != MathML_EL_Base &&
        !           742:               elType.ElTypeNum != MathML_EL_UnderOverBase &&
        !           743:               elType.ElTypeNum != MathML_EL_MSUBSUP &&
        !           744:               elType.ElTypeNum != MathML_EL_MSUB &&
        !           745:               elType.ElTypeNum != MathML_EL_MSUP &&
        !           746:               elType.ElTypeNum != MathML_EL_MUNDEROVER &&
        !           747:               elType.ElTypeNum != MathML_EL_MUNDER &&
        !           748:               elType.ElTypeNum != MathML_EL_MUNDEROVER))
        !           749:            operator = el;
1.1       cvs       750:         }
1.131   ! cvs       751:     }
1.1       cvs       752:   else
1.131   ! cvs       753:     /* it's not a MO */
        !           754:     {
        !           755:       /* search the Base or UnderOverBase child */
        !           756:       child = TtaGetFirstChild (el);
        !           757:       if (child != NULL)
1.1       cvs       758:         {
1.131   ! cvs       759:          elType = TtaGetElementType (child);
        !           760:          if (elType.ElTypeNum == base && elType.ElSSchema == MathMLSSchema)
        !           761:            /* the first child is a Base or UnderOverBase */
        !           762:            {
        !           763:              child = TtaGetFirstChild (child);
        !           764:              if (child != NULL)
        !           765:                {
        !           766:                  elType = TtaGetElementType (child);
        !           767:                  if (elType.ElTypeNum == MathML_EL_MO &&
        !           768:                      elType.ElSSchema == MathMLSSchema)
        !           769:                    /* its first child is a MO */
        !           770:                    {
        !           771:                      sibling = child;
        !           772:                      TtaNextSibling (&sibling);
        !           773:                      if (sibling == NULL)
        !           774:                        /* there is no other child */
        !           775:                        {
        !           776:                          operator = child;
        !           777:                          if (base == MathML_EL_Base ||
        !           778:                              base == MathML_EL_UnderOverBase)
        !           779:                            {
        !           780:                              parent = el;
        !           781:                              inbase = TRUE;
        !           782:                            }
        !           783:                        }
        !           784:                    }
        !           785:                }
        !           786:            }
1.1       cvs       787:        }
1.131   ! cvs       788:     }
        !           789:   if (operator)
        !           790:     {
        !           791:       textEl = TtaGetFirstChild (operator);
        !           792:       if (textEl != NULL)
1.84      cvs       793:         {
1.131   ! cvs       794:          elType = TtaGetElementType (textEl);
        !           795:          if (elType.ElTypeNum == MathML_EL_TEXT_UNIT)
        !           796:            {
        !           797:              len = TtaGetVolume (textEl);
        !           798:              if (len >= 1)
        !           799:                {
        !           800:                  if (len >= buflen)
        !           801:                    len = buflen-1;
        !           802:                  len++;
        !           803:                  TtaGiveBufferContent (textEl, text, len, &lang);
        !           804:                  len --;
        !           805:                  alphabet = TtaGetAlphabet (lang);
        !           806:                  if (alphabet == 'G')
        !           807:                    /* Adobe Symbol character set */
1.55      cvs       808:                    {
1.131   ! cvs       809:                    integral = TRUE;
        !           810:                    /* check all characters in this TEXT element */
        !           811:                    for (i = 0; i < len; i++)
        !           812:                      if (text[i] != 242)
        !           813:                        /**** accept also other symbols like double or triple
        !           814:                              integral, contour integral, etc. ****/
        !           815:                        integral = FALSE;
        !           816:                    if (integral)
        !           817:                      /* the operator contains only integral symbols */
        !           818:                      {
        !           819:                        /* attach a IntVertStretch attribute */
        !           820:                        attrType.AttrSSchema = MathMLSSchema;
        !           821:                        attrType.AttrTypeNum = MathML_ATTR_IntVertStretch;
        !           822:                        attr = TtaNewAttribute (attrType);
        !           823:                        TtaAttachAttribute (el, attr, doc);
        !           824:                        TtaSetAttributeValue (attr,
        !           825:                                           MathML_ATTR_IntVertStretch_VAL_yes_,
        !           826:                                           el, doc);
        !           827:                        TtaRegisterAttributeCreate (attr, el, doc);
        !           828: 
        !           829:                        /* replace the Integral characters by a Thot SYMBOL
        !           830:                           element. If there are several such characters in
        !           831:                           the mo (multiple integral), replace them too. */
        !           832:                        do
        !           833:                          {
        !           834:                            /* replace the TEXT element by a Thot SYMBOL */
        !           835:                            elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
        !           836:                            elType.ElSSchema = MathMLSSchema;
        !           837:                            for (i = 0; i < len; i++)
        !           838:                              if (text[i] == 242)
        !           839:                                {
        !           840:                                symbolEl = TtaNewElement (doc, elType);
        !           841:                                TtaInsertSibling (symbolEl, textEl, TRUE,doc);
        !           842:                                if (selEl != NULL)
        !           843:                                  if (*selEl == textEl)
        !           844:                                    *selEl = symbolEl;
        !           845:                                c = 'i';
        !           846:                                TtaSetGraphicsShape (symbolEl, c, doc);
        !           847:                                TtaRegisterElementCreate (symbolEl, doc);
        !           848:                                }
        !           849:                            TtaRegisterElementDelete (textEl, doc);
        !           850:                            TtaDeleteTree (textEl, doc);
        !           851:                            /* is there an other text element after the
        !           852:                               integral symbol? */
        !           853:                            textEl = symbolEl; TtaNextSibling (&textEl);
        !           854:                            if (textEl)
        !           855:                              {
        !           856:                                elType = TtaGetElementType (textEl);
        !           857:                                if (elType.ElTypeNum != MathML_EL_TEXT_UNIT)
        !           858:                                  textEl = NULL;
        !           859:                                else
        !           860:                                  /* there is another text element.
        !           861:                                     Is it a single integral symbol? */
        !           862:                                  {
        !           863:                                    len = TtaGetVolume (textEl);
        !           864:                                    if (len < 1)
        !           865:                                      /* not a single character */
        !           866:                                      textEl = NULL;
        !           867:                                    else
        !           868:                                      {
        !           869:                                        if (len >= buflen)
        !           870:                                          len = buflen-1;
        !           871:                                        len++;
        !           872:                                        TtaGiveBufferContent (textEl, text,
        !           873:                                                              len, &lang); 
        !           874:                                        alphabet = TtaGetAlphabet (lang);
        !           875:                                        if (alphabet != 'G')
        !           876:                                          /* not the right alphabet for an
        !           877:                                             integral*/
        !           878:                                          textEl = NULL;
        !           879:                                        else
        !           880:                                          if (text[0] != 242)
        !           881:                                            /* not an integral symbol */
        !           882:                                            textEl = NULL;
        !           883:                                      }
        !           884:                                  }
        !           885:                              }
        !           886:                          }
        !           887:                        while (textEl);
        !           888: 
        !           889:                        if (inbase)
        !           890:                          /* it's within a Base or UnderOverBase element */
        !           891:                          {
        !           892:                            sibling = parent;
        !           893:                            TtaNextSibling (&sibling);
        !           894:                            if (!sibling)
        !           895:                              /* the msubsup or munderover has no next sibling.
        !           896:                                 Add a Construct1 element as the next sibling,
        !           897:                                 to allow P rules to operate correctly */
        !           898:                              {
        !           899:                                elType.ElTypeNum = MathML_EL_Construct1;
        !           900:                                elType.ElSSchema = MathMLSSchema;
        !           901:                                sibling = TtaNewElement (doc, elType);
        !           902:                                TtaInsertSibling (sibling, parent, FALSE, doc);
        !           903:                                TtaRegisterElementCreate (sibling, doc);
        !           904:                              }
        !           905:                            else
        !           906:                              {
        !           907:                                elType = TtaGetElementType (sibling);
        !           908:                                if (elType.ElTypeNum == MathML_EL_Construct &&
        !           909:                                    elType.ElSSchema == MathMLSSchema)
        !           910:                                  {
        !           911:                                    TtaRegisterElementDelete (sibling, doc);
        !           912:                                    TtaRemoveTree (sibling, doc);
        !           913:                                    ChangeElementType (sibling,
        !           914:                                                       MathML_EL_Construct1);
        !           915:                                    TtaInsertSibling (sibling, parent, FALSE,
        !           916:                                                      doc);
        !           917:                                    TtaRegisterElementCreate (sibling, doc);
        !           918:                                  }
        !           919:                              }
        !           920:                            /* force the msubsup element to be reformatted and
        !           921:                               take into account its new next sibling */
        !           922:                            TtaRemoveTree (parent, doc);
        !           923:                            TtaInsertSibling (parent, sibling, TRUE, doc);
        !           924:                          } 
        !           925:                      }
1.55      cvs       926:                    }
1.131   ! cvs       927:                }
        !           928:            }
1.84      cvs       929:        }
1.131   ! cvs       930:     }
1.1       cvs       931: }
                    932: 
                    933: /*----------------------------------------------------------------------
1.22      cvs       934:    SetIntPlaceholderAttr
1.1       cvs       935: 
1.22      cvs       936:    Put a IntPlaceholder attribute on all Construct elements in the
1.1       cvs       937:    subtree of root el.
                    938:  -----------------------------------------------------------------------*/
1.22      cvs       939: static void SetIntPlaceholderAttr (Element el, Document doc)
1.1       cvs       940: {
                    941:   Element      child;
                    942:   ElementType  elType;
                    943:   Attribute    attr;
                    944:   AttributeType        attrType;
                    945: 
                    946:   if (el == NULL)
                    947:      return;
                    948:   elType = TtaGetElementType (el);
                    949:   if (elType.ElTypeNum == MathML_EL_Construct &&
1.2       cvs       950:       elType.ElSSchema == GetMathMLSSchema (doc))
1.1       cvs       951:      {
                    952:      attrType.AttrSSchema = elType.ElSSchema;
1.22      cvs       953:      attrType.AttrTypeNum = MathML_ATTR_IntPlaceholder;
1.1       cvs       954:      attr = TtaNewAttribute (attrType);
                    955:      TtaAttachAttribute (el, attr, doc);
1.22      cvs       956:      TtaSetAttributeValue (attr, MathML_ATTR_IntPlaceholder_VAL_yes_, el, doc);
1.1       cvs       957:      }
                    958:   else
                    959:      {
                    960:      child = TtaGetFirstChild (el);
                    961:      while (child != NULL)
                    962:         {
1.22      cvs       963:         SetIntPlaceholderAttr (child, doc);
1.1       cvs       964:         TtaNextSibling (&child);
                    965:         }
                    966:      }
                    967: }
                    968: 
                    969: /*----------------------------------------------------------------------
                    970:    BuildMultiscript
                    971: 
                    972:    The content of a MMULTISCRIPT element has been created following
                    973:    the original MathML structure.  Create all Thot elements defined
                    974:    in the MathML S schema.
                    975:  -----------------------------------------------------------------------*/
                    976: static void BuildMultiscript (Element elMMULTISCRIPT, Document doc)
                    977: {
                    978:   Element      elem, base, next, group, pair, script, prevPair, prevScript;
                    979:   ElementType  elType, elTypeGroup, elTypePair, elTypeScript;
1.2       cvs       980:   SSchema       MathMLSSchema;
1.1       cvs       981:   base = NULL;
                    982:   group = NULL;
                    983:   prevPair = NULL;
                    984:   prevScript = NULL;
                    985: 
1.2       cvs       986:   MathMLSSchema = GetMathMLSSchema (doc);
1.1       cvs       987:   elTypeGroup.ElSSchema = MathMLSSchema;
                    988:   elTypePair.ElSSchema = MathMLSSchema;
                    989:   elTypeScript.ElSSchema = MathMLSSchema;
                    990: 
                    991:   /* process all children of the MMULTISCRIPT element */
                    992:   elem = TtaGetFirstChild (elMMULTISCRIPT);
                    993:   while (elem != NULL)
                    994:     {
                    995:       /* remember the element to be processed after the current one */
                    996:       next = elem;
                    997:       TtaNextSibling (&next);
                    998: 
                    999:       /* remove the current element from the tree */
                   1000:       TtaRemoveTree (elem, doc);
                   1001: 
                   1002:       if (base == NULL)
                   1003:        /* the current element is the first child of the MMULTISCRIPT
                   1004:           element */
                   1005:        {
                   1006:          /* Create a MultiscriptBase element as the first child of
                   1007:             MMULTISCRIPT and move the current element as the first child
                   1008:             of the MultiscriptBase element */
                   1009:          elTypeGroup.ElTypeNum = MathML_EL_MultiscriptBase;
                   1010:          base = TtaNewElement (doc, elTypeGroup);
                   1011:          TtaInsertFirstChild (&base, elMMULTISCRIPT, doc);
                   1012:          TtaInsertFirstChild (&elem, base, doc);
                   1013:        }
                   1014:       else
                   1015:        /* the current element is a subscript or a superscript */
                   1016:        {
                   1017:          if (group == NULL)
                   1018:            /* there is no PostscriptPairs element. Create one */
                   1019:            {
                   1020:              elTypeGroup.ElTypeNum = MathML_EL_PostscriptPairs;
                   1021:              group = TtaNewElement (doc, elTypeGroup);
                   1022:              TtaInsertSibling (group, base, FALSE, doc);
                   1023:              elTypePair.ElTypeNum = MathML_EL_PostscriptPair;
                   1024:              /* create a first and a last PostscriptPair as placeholders */
1.47      cvs      1025:              pair = TtaNewTree (doc, elTypePair, "");
1.1       cvs      1026:              TtaInsertFirstChild (&pair, group, doc);
1.22      cvs      1027:              SetIntPlaceholderAttr (pair, doc);
1.1       cvs      1028:              prevPair = pair;
1.47      cvs      1029:              pair = TtaNewTree (doc, elTypePair, "");
1.1       cvs      1030:              TtaInsertSibling (pair, prevPair, FALSE, doc);
1.22      cvs      1031:              SetIntPlaceholderAttr (pair, doc);
1.1       cvs      1032:              prevScript = NULL;
                   1033:            }
                   1034:          if (prevScript == NULL)
                   1035:            /* the current element is the first subscript or superscript
                   1036:               in a pair */
                   1037:            {
                   1038:              /* create a PostscriptPair or PrescriptPair element */
                   1039:              pair = TtaNewElement (doc, elTypePair);
                   1040:              if (prevPair == NULL)
                   1041:                TtaInsertFirstChild (&pair, group, doc);
                   1042:              else
                   1043:                TtaInsertSibling (pair, prevPair, FALSE, doc);
                   1044:              prevPair = pair;
                   1045:              /* create a MSubscript element */
                   1046:              elTypeScript.ElTypeNum = MathML_EL_MSubscript;
                   1047:              script = TtaNewElement (doc, elTypeScript);
                   1048:              TtaInsertFirstChild (&script, pair, doc);
                   1049:              prevScript = script;        
                   1050:            }
                   1051:          else
                   1052:            /* the current element is a superscript in a pair */
                   1053:            {
                   1054:              /* create a MSuperscript element */
                   1055:              elTypeScript.ElTypeNum = MathML_EL_MSuperscript;
                   1056:              script = TtaNewElement (doc, elTypeScript);
                   1057:              /* insert it as a sibling of the previous MSubscript element */
                   1058:              TtaInsertSibling (script, prevScript, FALSE, doc);
                   1059:              prevScript = NULL;          
                   1060:            }
                   1061:          /* insert the current element as a child of the new MSuperscript or
                   1062:             MSubscript element */
                   1063:          TtaInsertFirstChild (&elem, script, doc);
1.22      cvs      1064:          SetIntPlaceholderAttr (elem, doc);
1.1       cvs      1065:        }
                   1066: 
                   1067:       CreatePlaceholders (elem, doc);
                   1068: 
                   1069:       /* get next child of the MMULTISCRIPT element */
                   1070:       elem = next;
                   1071:       if (elem != NULL)
                   1072:        {
                   1073:          elType = TtaGetElementType (elem);
                   1074:          if (elType.ElSSchema == MathMLSSchema &&
                   1075:              elType.ElTypeNum == MathML_EL_PrescriptPairs)
                   1076:            /* the next element is a PrescriptPairs */
                   1077:            {
                   1078:              /* if there there is no PostscriptPairs element, create one as a
                   1079:                 placeholder */
                   1080:              if (elTypeGroup.ElTypeNum != MathML_EL_PostscriptPairs)
                   1081:                {
                   1082:                  elTypeGroup.ElTypeNum = MathML_EL_PostscriptPairs;
1.47      cvs      1083:                  group = TtaNewTree (doc, elTypeGroup, "");
1.1       cvs      1084:                  TtaInsertSibling (group, elem, TRUE, doc);
1.22      cvs      1085:                  SetIntPlaceholderAttr (group, doc);
1.1       cvs      1086:                }
                   1087:              /* the following elements will be interpreted as sub- superscripts
                   1088:                 in PrescriptPair elements, wich will be children of this
                   1089:                 PrescriptPairs element */
                   1090:              elTypeGroup.ElTypeNum = MathML_EL_PrescriptPairs;
                   1091:              elTypePair.ElTypeNum = MathML_EL_PrescriptPair;
                   1092:              group = elem;
                   1093:              /* create a first and a last PostscriptPair as placeholders */
1.47      cvs      1094:              pair = TtaNewTree (doc, elTypePair, "");
1.1       cvs      1095:              TtaInsertFirstChild (&pair, group, doc);
1.22      cvs      1096:              SetIntPlaceholderAttr (pair, doc);
1.1       cvs      1097:              prevPair = pair;
1.47      cvs      1098:              pair = TtaNewTree (doc, elTypePair, "");
1.1       cvs      1099:              TtaInsertSibling (pair, prevPair, FALSE, doc);
1.22      cvs      1100:              SetIntPlaceholderAttr (pair, doc);
1.1       cvs      1101:              prevScript = NULL;
                   1102:              TtaNextSibling (&elem);
                   1103:            }
                   1104:        }
                   1105:     }
                   1106:   /* all children of element MMULTISCRIPTS have been processed */
                   1107:   /* if the last group processed is not a PrescriptPairs element,
                   1108:      create one as a placeholder */
                   1109:   if (elTypeGroup.ElTypeNum != MathML_EL_PrescriptPairs && base != NULL)
                   1110:     {
                   1111:       elTypeGroup.ElTypeNum = MathML_EL_PrescriptPairs;
1.47      cvs      1112:       elem = TtaNewTree (doc, elTypeGroup, "");
1.1       cvs      1113:       if (group == NULL)
                   1114:        group = base;
                   1115:       TtaInsertSibling (elem, group, TRUE, doc);
1.22      cvs      1116:       SetIntPlaceholderAttr (elem, doc);
1.1       cvs      1117:     }
                   1118: }
                   1119: 
1.39      cvs      1120: /*----------------------------------------------------------------------
                   1121:    CreateWrapper
                   1122: 
                   1123:    Create an element of type wrapperType as a child of element el and
                   1124:    move all chidren of element el within the new element.
                   1125:  -----------------------------------------------------------------------*/
                   1126: static void CreateWrapper (Element el, int wrapperType, Document doc)
                   1127: {
                   1128:    Element       wrapper, child, prevChild, nextChild;
                   1129:    ElementType   elType;
                   1130: 
                   1131:    child = TtaGetFirstChild (el);
                   1132:    elType.ElSSchema = GetMathMLSSchema (doc);
                   1133:    elType.ElTypeNum = wrapperType;
                   1134:    wrapper = TtaNewElement (doc, elType);
                   1135:    TtaInsertFirstChild (&wrapper, el, doc);
                   1136:    prevChild = NULL;
                   1137:    while (child)
                   1138:      {
                   1139:        nextChild = child;
                   1140:        TtaNextSibling (&nextChild);
                   1141:        TtaRemoveTree (child, doc);
                   1142:        if (prevChild == NULL)
                   1143:         TtaInsertFirstChild (&child, wrapper, doc);
                   1144:        else
                   1145:         TtaInsertSibling (child, prevChild, FALSE, doc);
                   1146:        prevChild = child;
                   1147:        child = nextChild;
                   1148:      }
                   1149: }
1.5       cvs      1150: 
                   1151: /*----------------------------------------------------------------------
                   1152:    CheckMTable
                   1153: 
                   1154:    The content of a MTABLE element has been created following
                   1155:    the original MathML structure.  Create all Thot elements defined
                   1156:    in the MathML S schema.
1.64      cvs      1157:    If placeholder, associate an attribute IntPlaceholder with all
1.103     cvs      1158:    cells generated in the MathML table.
1.5       cvs      1159:  -----------------------------------------------------------------------*/
1.64      cvs      1160: void CheckMTable (Element elMTABLE, Document doc, ThotBool placeholder)
1.5       cvs      1161: {
                   1162:   ElementType  elType;
                   1163:   Element      MTableHead, MTableBody, row, nextRow, el, prevRow, cell,
1.103     cvs      1164:                nextCell, newMTD, firstColHead, label;
1.5       cvs      1165:   SSchema      MathMLSSchema;
                   1166: 
                   1167:   MathMLSSchema = GetMathMLSSchema (doc);
                   1168:   row = TtaGetFirstChild (elMTABLE);
                   1169: 
                   1170:   /* create a MTable_head as the first child of element MTABLE */
                   1171:   elType.ElSSchema = MathMLSSchema;
                   1172:   elType.ElTypeNum = MathML_EL_MTable_head;
                   1173:   MTableHead = TtaNewElement (doc, elType);
                   1174:   TtaInsertFirstChild (&MTableHead, elMTABLE, doc);
                   1175:   elType.ElTypeNum = MathML_EL_MColumn_head;
1.47      cvs      1176:   firstColHead = TtaNewTree (doc, elType, "");
1.5       cvs      1177:   TtaInsertFirstChild (&firstColHead, MTableHead, doc);
                   1178: 
                   1179:   /* create a MTable_body */
                   1180:   elType.ElTypeNum = MathML_EL_MTable_body;
                   1181:   MTableBody = TtaNewElement (doc, elType);
                   1182:   TtaInsertSibling (MTableBody, MTableHead, FALSE, doc);
                   1183: 
                   1184:   /* move all children of element MTABLE into the new MTable_body element
1.103     cvs      1185:      and wrap each non-MTR element in a MTR, except comments */
1.5       cvs      1186:   prevRow = NULL;
                   1187:   while (row)
                   1188:     {
                   1189:     nextRow = row;
                   1190:     TtaNextSibling (&nextRow);
                   1191:     elType = TtaGetElementType (row);
                   1192:     TtaRemoveTree (row, doc);
                   1193:     if (TtaSameSSchemas (elType.ElSSchema, MathMLSSchema) &&
                   1194:        (elType.ElTypeNum == MathML_EL_XMLcomment ||
1.101     cvs      1195:         elType.ElTypeNum == MathML_EL_MTR ||
                   1196:          elType.ElTypeNum == MathML_EL_MLABELEDTR))
1.5       cvs      1197:        {
                   1198:        if (prevRow == NULL)
                   1199:          TtaInsertFirstChild (&row, MTableBody, doc);
                   1200:        else
                   1201:          TtaInsertSibling (row, prevRow, FALSE, doc);
                   1202:        prevRow = row;
1.101     cvs      1203:        if (elType.ElTypeNum == MathML_EL_MTR ||
                   1204:           elType.ElTypeNum == MathML_EL_MLABELEDTR)
1.103     cvs      1205:         {
1.5       cvs      1206:           cell = TtaGetFirstChild (row);
1.103     cvs      1207:          if (elType.ElTypeNum == MathML_EL_MLABELEDTR)
                   1208:            /* skip the first significant child of the mlabeledtr element */
                   1209:            {
                   1210:              /* skip comments first */
                   1211:              do
                   1212:                {
                   1213:                  elType = TtaGetElementType (cell);
                   1214:                  if (TtaSameSSchemas (elType.ElSSchema, MathMLSSchema) &&
                   1215:                      elType.ElTypeNum == MathML_EL_XMLcomment)
                   1216:                    TtaNextSibling (&cell);
                   1217:                }
                   1218:              while (cell && elType.ElTypeNum == MathML_EL_XMLcomment);
                   1219:              /* skip the first element after the comments: it's a label */
                   1220:              if (cell)
                   1221:                {
1.105     cvs      1222:                  /* if it's a MTD change its type into LabelCell */
                   1223:                  if (elType.ElTypeNum == MathML_EL_MTD &&
                   1224:                      elType.ElSSchema == MathMLSSchema)
                   1225:                     ChangeElementType (cell, MathML_EL_LabelCell);
1.103     cvs      1226:                  /* wrap this element in a RowLabel element */
1.105     cvs      1227:                  /* This will allow the P schema to specify the horizontal
                   1228:                     position of the label */
1.103     cvs      1229:                  elType.ElSSchema = MathMLSSchema;
                   1230:                  elType.ElTypeNum = MathML_EL_RowLabel;
                   1231:                  label = TtaNewElement (doc, elType);
                   1232:                  TtaInsertSibling (label, cell, TRUE, doc);
                   1233:                  TtaRemoveTree (cell, doc);
                   1234:                  TtaInsertFirstChild (&cell, label, doc);
                   1235:                  cell = label;
                   1236:                  TtaNextSibling (&cell);
                   1237:                }
                   1238:            } 
                   1239:         }
1.5       cvs      1240:        else
                   1241:          cell = NULL;
                   1242:        }
                   1243:     else
1.103     cvs      1244:        /* this child is not a MTR, MLABELEDTR, or a comment.
                   1245:          In MathML 2.0, this in an error, but we try to recover by
                   1246:          creating a MTR element */
1.5       cvs      1247:        {
                   1248:        elType.ElSSchema = MathMLSSchema;
                   1249:        elType.ElTypeNum = MathML_EL_MTR;
                   1250:        el = TtaNewElement (doc, elType);
                   1251:        if (prevRow == NULL)
                   1252:          TtaInsertFirstChild (&el, MTableBody, doc);
                   1253:        else
                   1254:          TtaInsertSibling (el, prevRow, FALSE, doc);
                   1255:        TtaInsertFirstChild (&row, el, doc);
                   1256:        cell = row;
                   1257:        prevRow = el;
                   1258:        }
                   1259:     while (cell)
                   1260:       /* check all children of the current MTR element */
                   1261:       {
                   1262:       nextCell = cell;
                   1263:       TtaNextSibling (&nextCell);
                   1264:       elType = TtaGetElementType (cell);
                   1265:       if (!TtaSameSSchemas (elType.ElSSchema, MathMLSSchema) ||
                   1266:           (elType.ElTypeNum != MathML_EL_XMLcomment &&
                   1267:            elType.ElTypeNum != MathML_EL_MTD))
                   1268:         /* this is not a MTD nor a comment, create a wrapping MTD */
                   1269:          {
                   1270:         elType.ElSSchema = MathMLSSchema;
                   1271:         elType.ElTypeNum = MathML_EL_MTD;
                   1272:         newMTD = TtaNewElement (doc, elType);
                   1273:         TtaInsertSibling (newMTD, cell, TRUE, doc);
                   1274:         TtaRemoveTree (cell, doc);
                   1275:         TtaInsertFirstChild (&cell, newMTD, doc);
                   1276:         cell = newMTD;
                   1277:         }
                   1278:       if (elType.ElTypeNum == MathML_EL_MTD)
                   1279:         /* This is a MTD element. Wrap its contents with a CellWrapper */
1.39      cvs      1280:          CreateWrapper (cell, MathML_EL_CellWrapper, doc);
1.5       cvs      1281:       cell = nextCell;
                   1282:       }
                   1283:     row = nextRow;
                   1284:     }
1.107     cvs      1285:   CheckAllRows (elMTABLE, doc, placeholder, FALSE);
1.5       cvs      1286: }
1.12      cvs      1287: 
1.46      cvs      1288: /*----------------------------------------------------------------------
1.1       cvs      1289:    SetFontstyleAttr
                   1290:    The content of a MI element has been created or modified.
                   1291:    Create or change attribute IntFontstyle for that element accordingly.
                   1292:  -----------------------------------------------------------------------*/
                   1293: void SetFontstyleAttr (Element el, Document doc)
                   1294: {
                   1295:   ElementType  elType;
                   1296:   AttributeType        attrType;
                   1297:   Attribute    attr, IntAttr;
1.54      cvs      1298:   Element       textEl;
1.1       cvs      1299:   int          len;
1.120     cvs      1300:   char         *value;
1.54      cvs      1301:   ThotBool      italic;
1.1       cvs      1302: 
                   1303:   if (el != NULL)
                   1304:      {
                   1305:      /* search the fontstyle attribute */
                   1306:      elType = TtaGetElementType (el);
                   1307:      attrType.AttrSSchema = elType.ElSSchema;
                   1308:      attrType.AttrTypeNum = MathML_ATTR_fontstyle;
                   1309:      attr = TtaGetAttribute (el, attrType);
                   1310:      attrType.AttrTypeNum = MathML_ATTR_IntFontstyle;
                   1311:      IntAttr = TtaGetAttribute (el, attrType);
                   1312:      if (attr != NULL)
                   1313:        /* there is a fontstyle attribute. Remove the corresponding
                   1314:           internal attribute that is not needed */
                   1315:        {
                   1316:        if (IntAttr != NULL)
1.54      cvs      1317:          TtaRemoveAttribute (el, IntAttr, doc);
1.1       cvs      1318:        }
                   1319:      else
                   1320:        /* there is no fontstyle attribute. Create an internal attribute
                   1321:           IntFontstyle with a value that depends on the content of the MI */
                   1322:        {
                   1323:         /* get content length */
                   1324:         len = TtaGetElementVolume (el);
                   1325:         if (len > 1)
                   1326:            /* put an attribute IntFontstyle = IntNormal */
                   1327:           {
                   1328:           if (IntAttr == NULL)
                   1329:              {
                   1330:              IntAttr = TtaNewAttribute (attrType);
                   1331:              TtaAttachAttribute (el, IntAttr, doc);
                   1332:              }
                   1333:           TtaSetAttributeValue (IntAttr, MathML_ATTR_IntFontstyle_VAL_IntNormal,
                   1334:                                 el, doc);
                   1335:           }
                   1336:         else
                   1337:           /* MI contains a single character. Remove attribute IntFontstyle
1.54      cvs      1338:              if it exists, except if it's ImaginaryI, ExponentialE or
1.124     cvs      1339:              DifferentialD */
1.1       cvs      1340:           {
1.54      cvs      1341:           italic = TRUE;
                   1342:           textEl = TtaGetFirstChild (el);
                   1343:           if (textEl != NULL)
                   1344:             {
                   1345:             /* is there an attribute EntityName on that character? */
                   1346:             attrType.AttrTypeNum = MathML_ATTR_EntityName;
                   1347:             attr = TtaGetAttribute (textEl, attrType);
                   1348:             if (attr)
                   1349:               {
                   1350:               len = TtaGetTextAttributeLength (attr);
                   1351:               if (len > 0)
                   1352:                  {
1.116     cvs      1353:                  value = TtaGetMemory (len+1);
1.54      cvs      1354:                  TtaGiveTextAttributeValue (attr, value, &len);
1.124     cvs      1355:                  if (strcmp (&value[1], "ImaginaryI;") == 0 ||
                   1356:                      strcmp (&value[1], "ExponentialE;") == 0 ||
                   1357:                      strcmp (&value[1], "DifferentialD;") == 0)
1.54      cvs      1358:                    italic = FALSE;
                   1359:                  TtaFreeMemory (value);
                   1360:                  }
                   1361:               }
                   1362:             if (italic)
                   1363:               {
                   1364:                 if (IntAttr != NULL)
                   1365:                   TtaRemoveAttribute (el, IntAttr, doc);
                   1366:               }
                   1367:             else
                   1368:               {
                   1369:                 /* put an attribute IntFontstyle = IntNormal */
                   1370:                 if (IntAttr == NULL)
                   1371:                   {
                   1372:                     attrType.AttrTypeNum = MathML_ATTR_IntFontstyle;
                   1373:                     IntAttr = TtaNewAttribute (attrType);
                   1374:                     TtaAttachAttribute (el, IntAttr, doc);
                   1375:                   }
                   1376:                 TtaSetAttributeValue (IntAttr, MathML_ATTR_IntFontstyle_VAL_IntNormal,
                   1377:                                       el, doc);
                   1378:               }
                   1379:             }
1.1       cvs      1380:           }
                   1381:         }
                   1382:      }
                   1383: }
                   1384: 
                   1385: /*----------------------------------------------------------------------
1.22      cvs      1386:    SetIntAddSpaceAttr
1.1       cvs      1387:    The content of a MO element has been created or modified.
1.22      cvs      1388:    Create or change attribute IntAddSpace for that element accordingly.
1.1       cvs      1389:  -----------------------------------------------------------------------*/
1.22      cvs      1390: void SetIntAddSpaceAttr (Element el, Document doc)
1.1       cvs      1391: {
                   1392:   Element      textEl, previous;
                   1393:   ElementType  elType;
                   1394:   AttributeType        attrType;
1.60      cvs      1395:   Attribute    attr, formAttr;
                   1396:   int          len, val, form;
1.1       cvs      1397: #define BUFLEN 10
1.116     cvs      1398:   unsigned char        text[BUFLEN];
1.1       cvs      1399:   Language     lang;
1.116     cvs      1400:   char         alphabet;
1.1       cvs      1401: 
1.60      cvs      1402:   /* get the content of the mo element */
1.1       cvs      1403:   textEl = TtaGetFirstChild (el);
                   1404:   if (textEl != NULL)
1.60      cvs      1405:      /* the mo element is not empty */
1.1       cvs      1406:      {
1.60      cvs      1407:      /* does the mo element have an IntAddSpace attribute? */
1.1       cvs      1408:      elType = TtaGetElementType (el);
                   1409:      attrType.AttrSSchema = elType.ElSSchema;
1.22      cvs      1410:      attrType.AttrTypeNum = MathML_ATTR_IntAddSpace;
1.1       cvs      1411:      attr = TtaGetAttribute (el, attrType);
                   1412:      if (attr == NULL)
1.60      cvs      1413:         /* no IntAddSpace Attr, create one */
1.1       cvs      1414:        {
                   1415:        attr = TtaNewAttribute (attrType);
                   1416:        TtaAttachAttribute (el, attr, doc);
                   1417:        }
1.60      cvs      1418:      /* nospace by default */
1.22      cvs      1419:      val = MathML_ATTR_IntAddSpace_VAL_nospace;
1.60      cvs      1420:      /* does the mo element have a form attribute? */
                   1421:      attrType.AttrTypeNum = MathML_ATTR_form;
                   1422:      formAttr = TtaGetAttribute (el, attrType);
                   1423:      if (formAttr)
                   1424:        /* there is a form attribute */
                   1425:        {
                   1426:        form = TtaGetAttributeValue (formAttr);
                   1427:        switch (form)
                   1428:         {
                   1429:         case MathML_ATTR_form_VAL_prefix:
                   1430:           val = MathML_ATTR_IntAddSpace_VAL_nospace;
                   1431:           break;
                   1432:         case MathML_ATTR_form_VAL_infix:
                   1433:           val = MathML_ATTR_IntAddSpace_VAL_both;
                   1434:           break;
                   1435:         case MathML_ATTR_form_VAL_postfix:
                   1436:           val = MathML_ATTR_IntAddSpace_VAL_spaceafter;
                   1437:           break;
                   1438:         } 
                   1439:        }
                   1440:      else
                   1441:        /* no form attribute. Analyze the content */
                   1442:        {
                   1443:        len = TtaGetTextLength (textEl);
                   1444:        if (len > 0 && len < BUFLEN)
                   1445:          {
                   1446:            len = BUFLEN;
                   1447:            TtaGiveTextContent (textEl, text, &len, &lang);
                   1448:            alphabet = TtaGetAlphabet (lang);
                   1449:            if (len == 1)
1.99      cvs      1450:              {
1.60      cvs      1451:               /* the mo element contains a single character */
                   1452:               if (alphabet == 'L')
                   1453:                  /* ISO-Latin 1 character */
                   1454:                  {
                   1455:                  if (text[0] == '-')
                   1456:                     /* prefix or infix operator? */
                   1457:                     {
                   1458:                     previous = el;
                   1459:                     TtaPreviousSibling (&previous);
                   1460:                     if (previous == NULL)
                   1461:                        /* no previous sibling => prefix operator */
                   1462:                        val = MathML_ATTR_IntAddSpace_VAL_nospace;
                   1463:                     else
                   1464:                        {
                   1465:                        elType = TtaGetElementType (previous);
                   1466:                        if (elType.ElTypeNum == MathML_EL_MO)
                   1467:                           /* after an operator => prefix operator */
                   1468:                           val = MathML_ATTR_IntAddSpace_VAL_nospace;
                   1469:                        else
                   1470:                           /* infix operator */
                   1471:                           val = MathML_ATTR_IntAddSpace_VAL_both;
                   1472:                        }
                   1473:                     }
1.111     cvs      1474:                  else if (text[0] == '&' ||
1.60      cvs      1475:                           text[0] == '*' ||
1.111     cvs      1476:                           text[0] == '+' ||
1.100     cvs      1477:                           text[0] == '/' ||
1.60      cvs      1478:                           text[0] == '<' ||
                   1479:                           text[0] == '=' ||
                   1480:                           text[0] == '>' ||
1.111     cvs      1481:                           text[0] == '^' ||
                   1482:                           (int)text[0] == 177 || /* plus or minus */
                   1483:                           (int)text[0] == 215 || /* times */
                   1484:                           (int)text[0] == 247)   /* divide */
1.60      cvs      1485:                     /* infix operator */
                   1486:                     val = MathML_ATTR_IntAddSpace_VAL_both;
                   1487:                  else if (text[0] == ',' ||
                   1488:                           text[0] == ';')
                   1489:                     /* separator */
                   1490:                     val = MathML_ATTR_IntAddSpace_VAL_spaceafter;
                   1491:                  }
                   1492:               else if (alphabet == 'G')
1.111     cvs      1493:                 /* Symbol character set */
1.60      cvs      1494:                 if ((int)text[0] == 163 || /* less or equal */
1.100     cvs      1495:                     (int)text[0] == 177 || /* plus or minus */
1.60      cvs      1496:                     (int)text[0] == 179 || /* greater or equal */
                   1497:                     (int)text[0] == 180 || /* times */
                   1498:                     (int)text[0] == 184 || /* divide */
                   1499:                     (int)text[0] == 185 || /* not equal */
                   1500:                     (int)text[0] == 186 || /* identical */
                   1501:                     (int)text[0] == 187 || /* equivalent */
                   1502:                     (int)text[0] == 196 || /* circle times */
                   1503:                     (int)text[0] == 197 || /* circle plus */
                   1504:                     ((int)text[0] >= 199 && (int)text[0] <= 209) || /*  */
                   1505:                     (int)text[0] == 217 || /* and */
                   1506:                     (int)text[0] == 218 )  /* or */
                   1507:                    /* infix operator */
                   1508:                    val = MathML_ATTR_IntAddSpace_VAL_both;
1.99      cvs      1509:              }
1.60      cvs      1510:          }
                   1511:        }
1.1       cvs      1512:      TtaSetAttributeValue (attr, val, el, doc);
                   1513:      }
                   1514: }
                   1515: 
                   1516: 
                   1517: /*----------------------------------------------------------------------
1.58      cvs      1518:    ChildOfMRowOrInferred
                   1519:    Return TRUE if element el is a child of a MROW element or an
                   1520:    inferred MROW element
                   1521:   ----------------------------------------------------------------------*/
                   1522: ThotBool      ChildOfMRowOrInferred (Element el)
                   1523: {
                   1524:    ElementType  elType;
                   1525:    Element       parent;
                   1526:    ThotBool      result;
                   1527: 
                   1528:    result = FALSE;
                   1529:    parent = TtaGetParent (el);
                   1530:    if (parent)
                   1531:       {
                   1532:       elType = TtaGetElementType (parent);
                   1533:       result = (elType.ElTypeNum == MathML_EL_MROW ||
                   1534:                elType.ElTypeNum == MathML_EL_SqrtBase ||
                   1535:                elType.ElTypeNum == MathML_EL_MSTYLE ||
                   1536:                elType.ElTypeNum == MathML_EL_MERROR ||
1.92      cvs      1537:                elType.ElTypeNum == MathML_EL_MENCLOSE ||
1.58      cvs      1538:                elType.ElTypeNum == MathML_EL_MPADDED ||
                   1539:                elType.ElTypeNum == MathML_EL_MPHANTOM ||
                   1540:                elType.ElTypeNum == MathML_EL_CellWrapper ||
1.92      cvs      1541:                elType.ElTypeNum == MathML_EL_MathML ||
1.58      cvs      1542:                 elType.ElTypeNum == MathML_EL_FencedExpression);
                   1543:       }
                   1544:    return result;   
                   1545: }
                   1546: 
                   1547: /*----------------------------------------------------------------------
1.1       cvs      1548:    CheckFence
1.84      cvs      1549:    If el is a MO element,
                   1550:     - if it's a large operator (&Sum; for instance), put a presentation
                   1551:       rule to enlarge the character.
                   1552:     - if it's a child of a MROW (or equivalent) element and if it contains
                   1553:       a single fence character, transform the MO into a MF and the fence
                   1554:       character into a Thot stretchable symbol.
1.1       cvs      1555:   ----------------------------------------------------------------------*/
1.84      cvs      1556: void      CheckFence (Element el, Document doc)
1.1       cvs      1557: {
1.128     vatton   1558:    ElementType        elType;
                   1559:    Element            content;
                   1560:    AttributeType       attrType;
                   1561:    Attribute          attr, attrStretchy;
                   1562:    Language           lang;
1.84      cvs      1563:    PresentationValue   pval;
                   1564:    PresentationContext ctxt;
1.128     vatton   1565:    CHAR_T              text[2];
                   1566:    char                       alphabet;
                   1567:    unsigned char       c;
                   1568:    int                 len, val;
1.1       cvs      1569: 
                   1570:    elType = TtaGetElementType (el);
                   1571:    if (elType.ElTypeNum == MathML_EL_MO)
1.58      cvs      1572:      /* the element is a MO */
                   1573:      {
1.84      cvs      1574:      content = TtaGetFirstChild (el);
                   1575:      if (content != NULL)
                   1576:        {
                   1577:        elType = TtaGetElementType (content);
                   1578:        if (elType.ElTypeNum == MathML_EL_TEXT_UNIT)
                   1579:         {
1.128     vatton   1580:         len = TtaGetVolume (content);
1.84      cvs      1581:         if (len == 1)
                   1582:           /* the MO element contains a single character */
                   1583:           {
                   1584:           len = 2;
1.128     vatton   1585:           TtaGiveBufferContent (content, text, len, &lang);
1.84      cvs      1586:           alphabet = TtaGetAlphabet (lang);
                   1587:           if ((alphabet == 'G') &&
1.128     vatton   1588:               (text[0] == 229 || text[0] == 213))  /* Sigma,  Pi */
1.84      cvs      1589:             /* it's a large operator */
                   1590:             {
                   1591:             ctxt = TtaGetSpecificStyleContext (doc);
                   1592:             ctxt->destroy = FALSE;
                   1593:             /* the specific presentation to be created is not a CSS rule */
                   1594:             ctxt->cssLevel = 0;
                   1595:             pval.typed_data.unit = STYLE_UNIT_PERCENT;
                   1596:             pval.typed_data.real = FALSE;
                   1597:             pval.typed_data.value = 180;
                   1598:             TtaSetStylePresentation (PRSize, content, NULL, ctxt, pval);
                   1599:             }
                   1600:           else if (ChildOfMRowOrInferred (el))
                   1601:             /* the MO element is a child of a MROW element */
1.1       cvs      1602:              {
1.102     cvs      1603:              if (((alphabet == 'L') &&
1.115     cvs      1604:                   (text[0] == '(' || text[0] == ')' ||
                   1605:                    text[0] == '[' || text[0] == ']' ||
                   1606:                    text[0] == '{' || text[0] == '}' ||
                   1607:                    text[0] == '|'))  ||
1.102     cvs      1608:                  ((alphabet == 'G') &&
1.128     vatton   1609:                   (text[0] == 225 || text[0] == 241)))
1.84      cvs      1610:                /* it's a stretchable parenthesis or equivalent */
                   1611:                {
                   1612:                /* remove the content of the MO element */
                   1613:                TtaDeleteTree (content, doc);
                   1614:                /* change the MO element into a MF element */
                   1615:                ChangeTypeOfElement (el, doc, MathML_EL_MF);
1.55      cvs      1616:                    
1.84      cvs      1617:                /* is there an attribute stretchy on this mo element? */
                   1618:                attrType.AttrSSchema = elType.ElSSchema;
                   1619:                attrType.AttrTypeNum = MathML_ATTR_stretchy;
                   1620:                attrStretchy = TtaGetAttribute (el, attrType);
                   1621:                if (attrStretchy)
                   1622:                  val = TtaGetAttributeValue (attrStretchy);
                   1623:                else
                   1624:                  val = MathML_ATTR_stretchy_VAL_true;
                   1625:                if (val == MathML_ATTR_stretchy_VAL_true)
                   1626:                  {
                   1627:                  /* attach a IntVertStretch attribute to the MF element*/
                   1628:                  attrType.AttrTypeNum = MathML_ATTR_IntVertStretch;
                   1629:                  attr = TtaNewAttribute (attrType);
                   1630:                  TtaAttachAttribute (el, attr, doc);
                   1631:                  TtaSetAttributeValue (attr,
                   1632:                                        MathML_ATTR_IntVertStretch_VAL_yes_,
                   1633:                                        el, doc);
                   1634:                  }
                   1635:                /* create a new content for the MF element */
1.87      cvs      1636:                elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
1.128     vatton   1637:                if (alphabet == 'G' && text[0] == 241)
1.102     cvs      1638:                  c = '>';    /* RightAngleBracket */
1.128     vatton   1639:                else if (alphabet == 'G' && text[0] == 225)
1.102     cvs      1640:                  c = '<';    /* LeftAngleBracket */
                   1641:                else
                   1642:                  c = (char) text[0];
1.84      cvs      1643:                content = TtaNewElement (doc, elType);
                   1644:                TtaInsertFirstChild (&content, el, doc);
                   1645:                TtaSetGraphicsShape (content, c, doc);
                   1646:                }
1.1       cvs      1647:              }
1.84      cvs      1648:           }
                   1649:         }
1.58      cvs      1650:        }
                   1651:      }
1.1       cvs      1652: }
                   1653: 
                   1654: /*----------------------------------------------------------------------
                   1655:    CreateFencedSeparators
                   1656:    Create FencedSeparator elements within the fencedExpression
                   1657:    according to attribute separators of the MFENCED element.
                   1658:   ----------------------------------------------------------------------*/
1.110     cvs      1659: void CreateFencedSeparators (Element fencedExpression, Document doc, ThotBool record)
1.1       cvs      1660: {
                   1661:    ElementType  elType;
                   1662:    Element      child, separator, leaf, next, prev, mfenced;
                   1663:    AttributeType attrType;
                   1664:    Attribute     attr;
                   1665:    int          length, sep, i;
                   1666:    Language     lang;
1.116     cvs      1667:    char         text[32], sepValue[4];
1.1       cvs      1668: 
                   1669:    /* get the separators attribute */
                   1670:    mfenced = TtaGetParent (fencedExpression);
                   1671:    elType = TtaGetElementType (fencedExpression);
                   1672:    attrType.AttrSSchema = elType.ElSSchema;
                   1673:    attrType.AttrTypeNum = MathML_ATTR_separators;
                   1674:    text[0] = ',';      /* default value is  sparators=","  */
                   1675:    text[1] = EOS;
                   1676:    length = 1;
                   1677:    attr = TtaGetAttribute (mfenced, attrType);
                   1678:    if (attr != NULL)
                   1679:       {
                   1680:       length = 31;
                   1681:       TtaGiveTextAttributeValue (attr, text, &length);
                   1682:       }
                   1683: 
                   1684:    /* create FencedSeparator elements in the FencedExpression */
                   1685:    prev = NULL;
                   1686:    sep = 0;
                   1687:    /* skip leading spaces in attribute separators */
                   1688:    while (text[sep] <= SPACE && text[sep] != EOS)
                   1689:       sep++;
                   1690:    /* if attribute separators is empty or contains only spaces, do not
                   1691:       insert any separator element */
                   1692:    if (text[sep] != EOS)
                   1693:      {
                   1694:      child = TtaGetFirstChild (fencedExpression);
                   1695:      while (child != NULL)
                   1696:        {
                   1697:        next = child;
                   1698:        TtaNextSibling (&next);
                   1699:        elType = TtaGetElementType (child);
                   1700:        if (elType.ElTypeNum != MathML_EL_Construct)
                   1701:          {
                   1702:          if (prev != NULL)
                   1703:            {
                   1704:            elType.ElTypeNum = MathML_EL_FencedSeparator;
                   1705:            separator = TtaNewElement (doc, elType);
                   1706:            TtaInsertSibling (separator, prev, FALSE, doc);
                   1707:            elType.ElTypeNum = MathML_EL_TEXT_UNIT;
                   1708:            leaf = TtaNewElement (doc, elType);
                   1709:            TtaInsertFirstChild (&leaf, separator, doc);
                   1710:            sepValue[0] = text[sep];
                   1711:            sepValue[1] = SPACE;
                   1712:            sepValue[2] = EOS;
                   1713:           lang = TtaGetLanguageIdFromAlphabet('L');
                   1714:            TtaSetTextContent (leaf, sepValue, lang, doc);
                   1715:           /* is there a following non-space character in separators? */
                   1716:           i = sep + 1;
                   1717:           while (text[i] <= SPACE && text[i] != EOS)
                   1718:              i++;
                   1719:            if (text[i] > SPACE && text[i] != EOS)
                   1720:               sep = i;
1.17      cvs      1721:           if (record)
                   1722:             TtaRegisterElementCreate (separator, doc);
1.1       cvs      1723:            }
                   1724:          prev = child;
                   1725:          }
                   1726:        child = next;
                   1727:        }
                   1728:      }
                   1729: }
                   1730: 
1.124     cvs      1731: /*----------------------------------------------------------------------
                   1732:    CreateOpeningOrClosingFence
                   1733:    Create the OpeningFence or ClosingFence element (depending on parameter
                   1734:    open) for the MFENCED element el which contain the fencedExpression
                   1735:    element.
                   1736:   ----------------------------------------------------------------------*/
                   1737: static void  CreateOpeningOrClosingFence (Element fencedExpression,
                   1738:                                          Element el, Document doc,
                   1739:                                          ThotBool open)
                   1740: {
                   1741:   ElementType  elType;
                   1742:   Element       leaf, fence;
                   1743:   AttributeType attrType;
                   1744:   Attribute     attr;
                   1745:   int           length;
                   1746:   char          text[32];
                   1747:   char          c;
                   1748: 
                   1749:   elType = TtaGetElementType (el);
                   1750:   attrType.AttrSSchema = elType.ElSSchema;
                   1751:   if (open)
                   1752:     {
                   1753:       c = '(';    /* default value of attribute 'open' */
                   1754:       attrType.AttrTypeNum = MathML_ATTR_open;
                   1755:       elType.ElTypeNum = MathML_EL_OpeningFence;
                   1756:     }
                   1757:   else
                   1758:     {
                   1759:       c = ')';    /* default value of attribute 'close' */
                   1760:       attrType.AttrTypeNum = MathML_ATTR_close;
                   1761:       elType.ElTypeNum = MathML_EL_ClosingFence;
                   1762:     }
                   1763:   attr = TtaGetAttribute (el, attrType);
                   1764:   if (attr != NULL)
                   1765:     {
                   1766:       length = 31;
                   1767:       TtaGiveTextAttributeValue (attr, text, &length);
                   1768:       if (length != 1)
                   1769:        /* content of attribute open or close should be a single character */
                   1770:        c = '?';
                   1771:       else
                   1772:        {
1.128     vatton   1773:          c = text[0];
1.124     cvs      1774:          /* filter characters that would represent strange symbols, such
                   1775:             as root, integrals, arrows, etc. */
                   1776:          if (c == 'r' || c == 'i' || c == 'c' || c == 'd' || c == 'S' ||
                   1777:              c == 'P' || c == 'I' || c == 'U' || c == 'o' || c == 'u' ||
                   1778:              c == 'h' || c == 'v' || c == 'R' || c == '^' || c == 'L' ||
                   1779:              c == 'V' || c == 'D')
                   1780:            c = '?';
                   1781:        }
                   1782:     }
                   1783:   fence = TtaNewElement (doc, elType);
                   1784:   TtaInsertSibling (fence, fencedExpression, open, doc);
                   1785:   elType.ElTypeNum = MathML_EL_SYMBOL_UNIT;
                   1786:   leaf = TtaNewElement (doc, elType);
                   1787:   TtaInsertFirstChild (&leaf, fence, doc);
                   1788:   TtaSetGraphicsShape (leaf, c, doc);
                   1789: }
1.1       cvs      1790: 
                   1791: /*----------------------------------------------------------------------
                   1792:    TransformMFENCED
                   1793:    Transform the content of a MFENCED element: create elements
                   1794:    OpeningFence, FencedExpression, ClosingFence and FencedSeparator.
                   1795:   ----------------------------------------------------------------------*/
1.46      cvs      1796: static void      TransformMFENCED (Element el, Document doc)
1.1       cvs      1797: {
                   1798:    ElementType  elType;
1.124     cvs      1799:    Element      child, fencedExpression, next, prev, firstChild;
1.1       cvs      1800: 
                   1801:    child = TtaGetFirstChild (el);
                   1802:    if (child != NULL)
                   1803:         elType = TtaGetElementType (child);
                   1804:    if (child != NULL && elType.ElTypeNum == MathML_EL_OpeningFence)
                   1805:       /* The first child of this MFENCED element is an OpeningFence.
                   1806:         This MFENCED expression has already been transformed, possibly
                   1807:         by the Transform command */
                   1808:       {
                   1809:       TtaNextSibling (&child);
                   1810:       fencedExpression = child;
                   1811:       if (fencedExpression != NULL)
                   1812:         elType = TtaGetElementType (fencedExpression);
                   1813:       if (elType.ElTypeNum == MathML_EL_FencedExpression)
                   1814:         /* the second child is a FencedExpression. OK.
                   1815:            Remove all existing FencedSeparator elements */
                   1816:         {
                   1817:         child = TtaGetFirstChild (fencedExpression);
                   1818:         prev = NULL;
                   1819:         while (child != NULL)
                   1820:            {
                   1821:            elType = TtaGetElementType (child);
                   1822:            next = child;
                   1823:            TtaNextSibling (&next);
                   1824:            if (elType.ElTypeNum == MathML_EL_FencedSeparator)
                   1825:                /* Remove this separator */
                   1826:                TtaDeleteTree (child, doc);
                   1827:            child = next;
                   1828:            }
                   1829:         /* create FencedSeparator elements in the FencedExpression */
1.17      cvs      1830:         CreateFencedSeparators (fencedExpression, doc, FALSE);
1.1       cvs      1831:         }
                   1832:       }
                   1833:    else
                   1834:       /* this MFENCED element must be transformed */
                   1835:       {
                   1836:       /* create a FencedExpression element as a child of the MFENCED elem. */
                   1837:       elType = TtaGetElementType (el);
                   1838:       elType.ElTypeNum = MathML_EL_FencedExpression;
                   1839:       fencedExpression = TtaNewElement (doc, elType);
                   1840:       TtaInsertFirstChild (&fencedExpression, el, doc);
                   1841:       if (child == NULL)
                   1842:        /* empty MFENCED element */
                   1843:        {
                   1844:         elType.ElTypeNum = MathML_EL_Construct;
                   1845:        child = TtaNewElement (doc, elType);
                   1846:        TtaInsertFirstChild (&child, fencedExpression, doc);
1.22      cvs      1847:        SetIntPlaceholderAttr (child, doc);
1.1       cvs      1848:        }
                   1849:       else
                   1850:        {
                   1851:         /* move the content of the MFENCED element within the new
                   1852:           FencedExpression element */
                   1853:         prev = NULL;
                   1854:        firstChild = NULL;
                   1855:         while (child != NULL)
                   1856:          {
                   1857:          next = child;
                   1858:          TtaNextSibling (&next);
                   1859:          TtaRemoveTree (child, doc);
                   1860:          if (prev == NULL)
                   1861:            {
                   1862:            TtaInsertFirstChild (&child, fencedExpression, doc);
                   1863:            firstChild = child;
                   1864:            }
                   1865:          else
                   1866:            TtaInsertSibling (child, prev, FALSE, doc);
                   1867:          prev = child;
                   1868:          child = next;
                   1869:          }
                   1870: 
                   1871:        /* create FencedSeparator elements in the FencedExpression */
1.17      cvs      1872:        CreateFencedSeparators (fencedExpression, doc, FALSE);
1.1       cvs      1873: 
                   1874:         /* Create placeholders within the FencedExpression element */
                   1875:         CreatePlaceholders (firstChild, doc);
                   1876:        }
                   1877: 
                   1878:       /* create the OpeningFence element according to the open attribute */
1.124     cvs      1879:       CreateOpeningOrClosingFence (fencedExpression, el, doc, TRUE);
1.1       cvs      1880: 
                   1881:       /* create the ClosingFence element according to close attribute */
1.124     cvs      1882:       CreateOpeningOrClosingFence (fencedExpression, el, doc, FALSE);
1.1       cvs      1883:       }
                   1884: }
                   1885: 
                   1886: /*----------------------------------------------------------------------
1.59      cvs      1887:  MathMLScriptShift
                   1888:  The MathML attribute attr (superscriptshift or subscriptshift) is associated
                   1889:  with element el (a msub, msup or msubsup).
                   1890:  If value is not NULL, generate the corresponding Thot VertPos rule for the
                   1891:  Subscript or  Superscript child of el.
                   1892:  If value is NULL, remove the Thot VertPos rule.
                   1893:  -----------------------------------------------------------------------*/
1.120     cvs      1894: void MathMLScriptShift (Document doc, Element el, char *value, int attr)
1.59      cvs      1895: {
                   1896:   ElementType         elType;
                   1897:   Element             script, child;
                   1898:   int                 scrType;
                   1899:   PresentationValue   pval;
                   1900:   PresentationContext ctxt;
                   1901: 
                   1902:   /* get the Superscript or Subscript child of el */
                   1903:   if (attr == MathML_ATTR_superscriptshift)
                   1904:      scrType = MathML_EL_Superscript;
                   1905:   else if (attr == MathML_ATTR_subscriptshift)
                   1906:      scrType = MathML_EL_Subscript;
                   1907:   else
                   1908:      return;
                   1909:   script = NULL;
                   1910:   child = TtaGetFirstChild (el);
                   1911:   while (!script && child)
                   1912:     {
                   1913:     elType = TtaGetElementType (child);
                   1914:     if (elType.ElTypeNum == scrType)
                   1915:        script = child;
                   1916:     else
                   1917:        TtaNextSibling (&child);
                   1918:     }
                   1919:   if (script)
                   1920:     /* Superscript or Subscript element found */
                   1921:     {
                   1922:     ctxt = TtaGetSpecificStyleContext (doc);
                   1923:     if (!value)
                   1924:        /* remove the presentation rule */
                   1925:        {
                   1926:        ctxt->destroy = TRUE;
1.75      cvs      1927:        pval.typed_data.value = 0;
1.59      cvs      1928:        TtaSetStylePresentation (PRVertPos, script, NULL, ctxt, pval);
                   1929:        }
                   1930:     else
                   1931:        {
                   1932:        ctxt->destroy = FALSE;
                   1933:        /* parse the attribute value (a number followed by a unit) */
1.119     cvs      1934:        value = TtaSkipBlanks (value);
1.59      cvs      1935:        value = ParseCSSUnit (value, &pval);
                   1936:        if (pval.typed_data.unit != STYLE_UNIT_INVALID)
                   1937:          {
1.78      cvs      1938:          /* the specific presentation to be created is not a CSS rule */
                   1939:          ctxt->cssLevel = 0;
1.59      cvs      1940:           if (attr == MathML_ATTR_superscriptshift)
                   1941:            pval.typed_data.value = - pval.typed_data.value;
                   1942:          TtaSetStylePresentation (PRVertPos, script, NULL, ctxt, pval);
                   1943:          }
                   1944:        }
                   1945:     TtaFreeMemory (ctxt);
                   1946:     }
                   1947: }
                   1948: 
                   1949: /*----------------------------------------------------------------------
                   1950:    SetScriptShift
                   1951:    If element el (which is a msup, msub or msubsup) has an attribute
                   1952:    att (which is subscriptshift or superscriptshift), generate the
                   1953:    corresponding Thot presentation rule.
                   1954:   ----------------------------------------------------------------------*/
1.120     cvs      1955: static void SetScriptShift (Element el, Document doc, int att)
1.59      cvs      1956: {
                   1957:    AttributeType     attrType;
                   1958:    ElementType       elType;
                   1959:    Attribute         attr;
1.120     cvs      1960:    char             *value;
1.59      cvs      1961:    int               length;
                   1962: 
                   1963:    elType = TtaGetElementType (el);
                   1964:    attrType.AttrSSchema = elType.ElSSchema;
                   1965:    attrType.AttrTypeNum = att;
                   1966:    attr = TtaGetAttribute (el, attrType);
                   1967:    if (attr)
                   1968:       {
                   1969:       length = TtaGetTextAttributeLength (attr);
                   1970:       if (length > 0)
                   1971:         {
1.116     cvs      1972:         value = TtaGetMemory (length+1);
1.59      cvs      1973:         value[0] = EOS;
                   1974:         TtaGiveTextAttributeValue (attr, value, &length);
                   1975:         MathMLScriptShift (doc, el, value, att);
                   1976:         TtaFreeMemory (value);
                   1977:         }
                   1978:       }
                   1979: }
                   1980: 
                   1981: /*----------------------------------------------------------------------
1.1       cvs      1982:    MathMLElementComplete
                   1983:    Check the Thot structure of the MathML element el.
                   1984:   ----------------------------------------------------------------------*/
1.56      cvs      1985: void      MathMLElementComplete (Element el, Document doc, int *error)
1.1       cvs      1986: {
1.74      cvs      1987:    ElementType         elType, parentType;
1.1       cvs      1988:    Element             child, parent, new, prev, next;
1.101     cvs      1989:    AttributeType        attrType;
                   1990:    Attribute            attr;
1.56      cvs      1991:    SSchema              MathMLSSchema;
                   1992:    ThotBool             ok;
1.1       cvs      1993: 
1.56      cvs      1994:    ok = TRUE;
                   1995:    *error = 0;
1.1       cvs      1996:    elType = TtaGetElementType (el);
1.2       cvs      1997:    MathMLSSchema = GetMathMLSSchema (doc);
1.1       cvs      1998: 
1.76      cvs      1999:    if (elType.ElSSchema == MathMLSSchema)
1.1       cvs      2000:      {
                   2001:      switch (elType.ElTypeNum)
                   2002:        {
1.76      cvs      2003:        case MathML_EL_MathML:
                   2004:          /* Create placeholders within the MathML element */
                   2005:          CreatePlaceholders (TtaGetFirstChild (el), doc);
1.1       cvs      2006:        case MathML_EL_MI:
                   2007:          SetFontstyleAttr (el, doc);
                   2008:          break;
                   2009:        case MathML_EL_MO:
1.22      cvs      2010:          SetIntAddSpaceAttr (el, doc);
                   2011:          SetIntVertStretchAttr (el, doc, 0, NULL);
1.58      cvs      2012:          /* if the MO element is a child of a MROW (or equivalent) and if it
                   2013:             contains a fence character, transform this MO into MF and
                   2014:             transform the fence character into a Thot SYMBOL */
                   2015:          CheckFence (el, doc);
1.1       cvs      2016:          break;
1.60      cvs      2017:        case MathML_EL_MSPACE:
                   2018:          break;
1.39      cvs      2019:        case MathML_EL_MROW:
1.55      cvs      2020:          /* Create placeholders within the MROW */
                   2021:           CreatePlaceholders (TtaGetFirstChild (el), doc);
1.39      cvs      2022:          break;
                   2023:        case MathML_EL_MFRAC:
1.54      cvs      2024:        case MathML_EL_BevelledMFRAC:
1.39      cvs      2025:          /* end of a fraction. Create a Numerator and a Denominator */
1.56      cvs      2026:          ok = CheckMathSubExpressions (el, MathML_EL_Numerator,
                   2027:                                        MathML_EL_Denominator, 0, doc);
1.39      cvs      2028:          break;
                   2029:        case MathML_EL_MSQRT:
1.50      cvs      2030:          /* end of a Square Root */
                   2031:          /* Create placeholders within the element */
                   2032:           CreatePlaceholders (TtaGetFirstChild (el), doc);
                   2033:          /* Create a SqrtBase that contains all children of the MSQRT */
1.39      cvs      2034:          CreateWrapper (el, MathML_EL_SqrtBase, doc);
                   2035:          break;
1.1       cvs      2036:        case MathML_EL_MROOT:
                   2037:          /* end of a Root. Create a RootBase and an Index */
1.56      cvs      2038:          ok = CheckMathSubExpressions (el, MathML_EL_RootBase,
                   2039:                                        MathML_EL_Index, 0, doc);
1.1       cvs      2040:          break;
1.50      cvs      2041:        case MathML_EL_MENCLOSE:
                   2042:          /* Create placeholders within the element */
                   2043:           CreatePlaceholders (TtaGetFirstChild (el), doc);
                   2044:          break;
1.39      cvs      2045:        case MathML_EL_MSTYLE:
                   2046:        case MathML_EL_MERROR:
                   2047:        case MathML_EL_MPADDED:
                   2048:        case MathML_EL_MPHANTOM:
                   2049:          /* Create placeholders within the element */
                   2050:           CreatePlaceholders (TtaGetFirstChild (el), doc);
1.1       cvs      2051:          break;
                   2052:        case MathML_EL_MFENCED:
                   2053:          TransformMFENCED (el, doc);
                   2054:          break;
                   2055:        case MathML_EL_MSUB:
                   2056:          /* end of a MSUB. Create Base and Subscript */
1.56      cvs      2057:          ok = CheckMathSubExpressions (el, MathML_EL_Base,
                   2058:                                        MathML_EL_Subscript, 0, doc);
1.59      cvs      2059:          SetScriptShift (el, doc, MathML_ATTR_subscriptshift);
1.22      cvs      2060:          SetIntVertStretchAttr (el, doc, MathML_EL_Base, NULL);
1.1       cvs      2061:          break;
                   2062:        case MathML_EL_MSUP:
                   2063:          /* end of a MSUP. Create Base and Superscript */
1.56      cvs      2064:          ok = CheckMathSubExpressions (el, MathML_EL_Base,
                   2065:                                        MathML_EL_Superscript, 0, doc);
1.59      cvs      2066:          SetScriptShift (el, doc, MathML_ATTR_superscriptshift);
1.22      cvs      2067:          SetIntVertStretchAttr (el, doc, MathML_EL_Base, NULL);
1.1       cvs      2068:          break;
1.39      cvs      2069:        case MathML_EL_MSUBSUP:
                   2070:          /* end of a MSUBSUP. Create Base, Subscript, and Superscript */
1.56      cvs      2071:          ok = CheckMathSubExpressions (el, MathML_EL_Base,
                   2072:                                        MathML_EL_Subscript,
                   2073:                                        MathML_EL_Superscript, doc);
1.59      cvs      2074:          SetScriptShift (el, doc, MathML_ATTR_subscriptshift);
                   2075:          SetScriptShift (el, doc, MathML_ATTR_superscriptshift);
1.39      cvs      2076:          SetIntVertStretchAttr (el, doc, MathML_EL_Base, NULL);
1.1       cvs      2077:          break;
                   2078:        case MathML_EL_MUNDER:
                   2079:          /* end of a MUNDER. Create UnderOverBase, and Underscript */
1.56      cvs      2080:          ok = CheckMathSubExpressions (el, MathML_EL_UnderOverBase,
                   2081:                                        MathML_EL_Underscript, 0, doc);
1.22      cvs      2082:          SetIntHorizStretchAttr (el, doc);
                   2083:          SetIntVertStretchAttr (el, doc, MathML_EL_UnderOverBase, NULL);
1.1       cvs      2084:          break;
                   2085:        case MathML_EL_MOVER:
                   2086:          /* end of a MOVER. Create UnderOverBase, and Overscript */
1.56      cvs      2087:          ok = CheckMathSubExpressions (el, MathML_EL_UnderOverBase,
                   2088:                                        MathML_EL_Overscript, 0, doc);
1.22      cvs      2089:          SetIntHorizStretchAttr (el, doc);
                   2090:          SetIntVertStretchAttr (el, doc, MathML_EL_UnderOverBase, NULL);
1.1       cvs      2091:          break;
1.39      cvs      2092:        case MathML_EL_MUNDEROVER:
                   2093:          /* end of a MUNDEROVER. Create UnderOverBase, Underscript, and
                   2094:             Overscript */
1.56      cvs      2095:          ok = CheckMathSubExpressions (el, MathML_EL_UnderOverBase,
                   2096:                                        MathML_EL_Underscript,
                   2097:                                        MathML_EL_Overscript, doc);
1.39      cvs      2098:          SetIntHorizStretchAttr (el, doc);
                   2099:          SetIntVertStretchAttr (el, doc, MathML_EL_UnderOverBase, NULL);
                   2100:          break;
1.1       cvs      2101:        case MathML_EL_MMULTISCRIPTS:
                   2102:          /* end of a MMULTISCRIPTS. Create all elements defined in the
                   2103:             MathML S schema */
                   2104:          BuildMultiscript (el, doc);
1.5       cvs      2105:          break;
                   2106:        case MathML_EL_MTABLE:
                   2107:          /* end of a MTABLE. Create all elements defined in the MathML S
                   2108:              schema */
1.64      cvs      2109:          CheckMTable (el, doc, TRUE);
1.101     cvs      2110:          /* if the table has a rowalign attribute, process it */
                   2111:           attrType.AttrSSchema = MathMLSSchema;
                   2112:           attrType.AttrTypeNum = MathML_ATTR_rowalign;
                   2113:          attr = TtaGetAttribute (el, attrType);
                   2114:          if (attr)
                   2115:             HandleRowalignAttribute (attr, el, doc, FALSE);
                   2116:          /* if the table has a columnalign attribute, process it */
                   2117:           attrType.AttrTypeNum = MathML_ATTR_columnalign;
                   2118:          attr = TtaGetAttribute (el, attrType);
                   2119:          if (attr)
1.108     cvs      2120:             HandleColalignAttribute (attr, el, doc, FALSE, FALSE);
1.101     cvs      2121:          break;
                   2122:        case MathML_EL_MTR:
                   2123:          /* if the row has a columnalign attribute, process it */
                   2124:           attrType.AttrSSchema = MathMLSSchema;
                   2125:           attrType.AttrTypeNum = MathML_ATTR_columnalign;
                   2126:          attr = TtaGetAttribute (el, attrType);
                   2127:          if (attr)
1.108     cvs      2128:             HandleColalignAttribute (attr, el, doc, FALSE, TRUE);
1.101     cvs      2129:          break;
                   2130:        case MathML_EL_MLABELEDTR:
                   2131:          /* if the row has a columnalign attribute, process it */
                   2132:           attrType.AttrSSchema = MathMLSSchema;
                   2133:           attrType.AttrTypeNum = MathML_ATTR_columnalign;
                   2134:          attr = TtaGetAttribute (el, attrType);
                   2135:          if (attr)
1.108     cvs      2136:             HandleColalignAttribute (attr, el, doc, FALSE, TRUE);
1.1       cvs      2137:          break;
1.39      cvs      2138:        case MathML_EL_MTD:
                   2139:          /* Create placeholders within the table cell */
                   2140:           CreatePlaceholders (TtaGetFirstChild (el), doc);
1.46      cvs      2141:          break;
1.39      cvs      2142:        case MathML_EL_MACTION:
                   2143:          /* Create placeholders within the MACTION element */
                   2144:           CreatePlaceholders (TtaGetFirstChild (el), doc);
1.1       cvs      2145:          break;
                   2146:        default:
                   2147:          break;
                   2148:        }
                   2149:      parent = TtaGetParent (el);
1.118     cvs      2150:      if (parent)
                   2151:        {
                   2152:         parentType = TtaGetElementType (parent);
                   2153:         if (parentType.ElSSchema != elType.ElSSchema)
                   2154:           /* root of a MathML tree, Create a MathML element if there is no */
                   2155:           if (elType.ElTypeNum != MathML_EL_MathML)
                   2156:             {
                   2157:               elType.ElSSchema = MathMLSSchema;
                   2158:               elType.ElTypeNum = MathML_EL_MathML;
                   2159:               new = TtaNewElement (doc, elType);
                   2160:               TtaInsertSibling (new, el, TRUE, doc);
                   2161:               next = el;
                   2162:               TtaNextSibling (&next);
                   2163:               TtaRemoveTree (el, doc);
                   2164:               TtaInsertFirstChild (&el, new, doc);
                   2165:               prev = el;
                   2166:               while (next != NULL)
                   2167:                 {
                   2168:                   child = next;
                   2169:                   TtaNextSibling (&next);
                   2170:                   TtaRemoveTree (child, doc);
                   2171:                   TtaInsertSibling (child, prev, FALSE, doc);
                   2172:                   prev = child;
                   2173:                 }
                   2174:               /* Create placeholders within the MathML element */
                   2175:               CreatePlaceholders (el, doc);
                   2176:             }
                   2177:        }
1.1       cvs      2178:      }
1.56      cvs      2179:    if (!ok)
                   2180:      /* send an error message */
                   2181:      *error = 1;
1.1       cvs      2182: }
                   2183: 
                   2184: /*----------------------------------------------------------------------
1.126     cvs      2185:    UnknownMathMLNameSpace
                   2186:    Create an element that belongs to a non-supported namespace
                   2187:   ----------------------------------------------------------------------*/
                   2188: void               UnknownMathMLNameSpace (ParserData *context, char* content)
                   2189: {
                   2190:    ElementType     elType;
                   2191:    AttributeType   attrType;
                   2192:    Element         elInv, elText;
                   2193:    Attribute       attr;
                   2194: 
                   2195:    /* Create a new Invalid_element */
                   2196:    elType.ElSSchema = GetXMLSSchema (MATH_TYPE, context->doc);
                   2197:    elType.ElTypeNum = MathML_EL_Unknown_namespace;
                   2198:    elInv = TtaNewElement (context->doc, elType);
                   2199:    if (elInv != NULL)
                   2200:      {
                   2201:        XmlSetElemLineNumber (elInv);
                   2202:        InsertXmlElement (&elInv);
                   2203:        context->lastElementClosed = TRUE;
                   2204:        elType.ElTypeNum = MathML_EL_TEXT_UNIT;
                   2205:        elText = TtaNewElement (context->doc, elType);
                   2206:        XmlSetElemLineNumber (elText);
                   2207:        TtaInsertFirstChild (&elText, elInv, context->doc);
                   2208:        TtaSetTextContent (elText, content, context->language, context->doc);
                   2209:        TtaSetAccessRight (elText, ReadOnly, context->doc);
                   2210:    }
                   2211: }
                   2212: 
                   2213: /*----------------------------------------------------------------------
1.24      cvs      2214:  SetFontfamily
                   2215:  -----------------------------------------------------------------------*/
1.120     cvs      2216: void SetFontfamily (Document doc, Element el, char *value)
1.24      cvs      2217: {
                   2218: #define buflen 50
1.116     cvs      2219:   char           css_command[buflen+20];
1.24      cvs      2220:  
1.116     cvs      2221:   sprintf (css_command, "font-family: %s", value);
1.72      cvs      2222:   ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.24      cvs      2223: }
                   2224: 
                   2225: /*----------------------------------------------------------------------
1.83      cvs      2226:  MathMLlinethickness
                   2227:  The MathML attribute linthickness is associated with element el. Generate
                   2228:  the corresponding style property for this element. 
                   2229:  -----------------------------------------------------------------------*/
1.120     cvs      2230: void MathMLlinethickness (Document doc, Element el, char *value)
1.83      cvs      2231: {
                   2232: #define buflen 50
1.116     cvs      2233:   char           css_command[buflen+20];
1.83      cvs      2234: 
1.116     cvs      2235:   if (strcmp (value, "thin") == 0)
                   2236:      strcpy (value, "1pt");
                   2237:   else if (strcmp (value, "medium") == 0)
                   2238:      strcpy (value, "1pt");
                   2239:   else if (strcmp (value, "thick") == 0)
                   2240:      strcpy (value, "2pt");
                   2241:   sprintf (css_command, "stroke-width: %s", value);
1.83      cvs      2242:   ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
                   2243: }
                   2244: 
                   2245: /*----------------------------------------------------------------------
1.58      cvs      2246:  MathMLAttrToStyleProperty
                   2247:  The MathML attribute attr is associated with element el. Generate
                   2248:  the corresponding style property for this element.
1.24      cvs      2249:  -----------------------------------------------------------------------*/
1.120     cvs      2250: void MathMLAttrToStyleProperty (Document doc, Element el, char *value, int attr)
1.24      cvs      2251: {
1.116     cvs      2252:   char           css_command[buflen+20];
1.58      cvs      2253: 
                   2254:   switch (attr)
                   2255:     {
                   2256:     case MathML_ATTR_fontsize:
1.116     cvs      2257:        sprintf (css_command, "font-size: %s", value);
1.58      cvs      2258:        break;
1.93      cvs      2259:     case MathML_ATTR_mathsize:
1.116     cvs      2260:        if (strcmp (value, "small") == 0)
                   2261:         strcpy (value, "80%");
                   2262:        else if (strcmp (value, "normal") == 0)
                   2263:         strcpy (value, "100%");
                   2264:        else if (strcmp (value, "big") == 0)
                   2265:         strcpy (value, "125%");
                   2266:        sprintf (css_command, "font-size: %s", value);
1.93      cvs      2267:        break;
1.58      cvs      2268:     case MathML_ATTR_lspace:
1.116     cvs      2269:        sprintf (css_command, "padding-left: %s", value);
1.58      cvs      2270:        break;
                   2271:     case MathML_ATTR_rspace:
1.116     cvs      2272:        sprintf (css_command, "padding-right: %s", value);
1.58      cvs      2273:        break;
                   2274:     }
1.72      cvs      2275:   ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.24      cvs      2276: }
                   2277: 
                   2278: /*----------------------------------------------------------------------
1.60      cvs      2279:  MathMLSetScriptLevel
                   2280:  A scriptlevel attribute with value value is associated with element el.
                   2281:  Generate the corresponding style property for this element.
                   2282:  -----------------------------------------------------------------------*/
1.120     cvs      2283: void MathMLSetScriptLevel (Document doc, Element el, char *value)
1.60      cvs      2284: {
                   2285:   PresentationValue   pval;
                   2286:   PresentationContext ctxt;
                   2287:   ThotBool            relative;
                   2288:   int                 percentage;
                   2289: 
                   2290:   ctxt = TtaGetSpecificStyleContext (doc);
                   2291:   if (!value)
                   2292:      /* remove the presentation rule */
                   2293:      {
                   2294:      ctxt->destroy = TRUE;
1.75      cvs      2295:      pval.typed_data.value = 0;
1.60      cvs      2296:      TtaSetStylePresentation (PRSize, el, NULL, ctxt, pval);
                   2297:      }
                   2298:   else
                   2299:      {
                   2300:      ctxt->destroy = FALSE;
                   2301:      /* parse the attribute value (an optional sign and an integer) */
1.119     cvs      2302:      value = TtaSkipBlanks (value);
1.60      cvs      2303:      relative = (value[0] == '-' || value[0] == '+');
                   2304:      value = ParseCSSUnit (value, &pval);
                   2305:      if (pval.typed_data.unit != STYLE_UNIT_REL &&
                   2306:         pval.typed_data.real)
                   2307:        /* this is an error: it should be an integer without any unit name */
                   2308:        /* error */;
                   2309:      else
                   2310:        {
                   2311:        if (relative)
                   2312:         {
1.63      cvs      2313:         percentage = 100;
1.60      cvs      2314:          if (pval.typed_data.value == 0)
                   2315:           /* scriptlevel="+0" */
                   2316:           percentage = 100;
                   2317:          else if (pval.typed_data.value == 1)
                   2318:           /* scriptlevel="+1" */
                   2319:           percentage = 71;
                   2320:         else if (pval.typed_data.value == 2)
                   2321:           /* scriptlevel="+2" */
                   2322:           percentage = 50;
                   2323:         else if (pval.typed_data.value >= 3)
                   2324:           /* scriptlevel="+3" or more */
                   2325:           percentage = 35;
                   2326:         else if (pval.typed_data.value == -1)
                   2327:           /* scriptlevel="-1" */
                   2328:           percentage = 141;
                   2329:         else if (pval.typed_data.value == -2)
                   2330:           /* scriptlevel="-2" */
                   2331:           percentage = 200;
                   2332:         else if (pval.typed_data.value <= -3)
                   2333:           /* scriptlevel="-3" or less */
                   2334:           percentage = 282;
                   2335:         pval.typed_data.value = percentage;
                   2336:         pval.typed_data.unit = STYLE_UNIT_PERCENT;
1.78      cvs      2337:         /* the specific presentation to be created is not a CSS rule */
                   2338:         ctxt->cssLevel = 0;
1.60      cvs      2339:         TtaSetStylePresentation (PRSize, el, NULL, ctxt, pval);       
                   2340:         }
                   2341:        else
                   2342:         /* absolute value */
                   2343:         {
                   2344:           /****  ****/;
                   2345:         }
                   2346:        }
                   2347:      }
                   2348:   TtaFreeMemory (ctxt);
                   2349: }
                   2350: 
                   2351: /*----------------------------------------------------------------------
                   2352:  MathMLSpacingAttr
                   2353:  The MathML attribute attr (height, width or depth) is associated
                   2354:  with element el (a mspace or mpadding).
                   2355:  If value is not NULL, generate the corresponding Thot presentation rule for
                   2356:  the element.
                   2357:  If value is NULL, remove the corresponding Thot presentation rule.
                   2358:  -----------------------------------------------------------------------*/
1.120     cvs      2359: void MathMLSpacingAttr (Document doc, Element el, char *value, int attr)
1.60      cvs      2360: {
                   2361:   ElementType         elType;
                   2362:   PresentationValue   pval;
                   2363:   PresentationContext ctxt;
                   2364:   int                 ruleType;
                   2365: 
                   2366:   /* provisionally, handles only mspace elements */
                   2367:   elType = TtaGetElementType (el);
1.96      cvs      2368:   if (elType.ElTypeNum != MathML_EL_MSPACE &&
1.97      cvs      2369:       elType.ElTypeNum != MathML_EL_MPADDED &&
                   2370:       elType.ElTypeNum != MathML_EL_MTABLE)
1.60      cvs      2371:      return;
                   2372:   switch (attr)
                   2373:     {
                   2374:     case MathML_ATTR_width_:
                   2375:       ruleType = PRWidth;
                   2376:       break;
                   2377:     case MathML_ATTR_height_:
                   2378:       ruleType = PRPaddingTop;
                   2379:       break;
                   2380:     case MathML_ATTR_depth_:
                   2381:       ruleType = PRPaddingBottom;
                   2382:       break;
                   2383:     default:
                   2384:       return;
                   2385:     }
                   2386:   ctxt = TtaGetSpecificStyleContext (doc);
1.116     cvs      2387:   if (!value || (strcmp (value, "auto") == 0))
1.60      cvs      2388:     /* remove the presentation rule */
                   2389:     {
                   2390:       ctxt->destroy = TRUE;
1.75      cvs      2391:       pval.typed_data.value = 0;
1.60      cvs      2392:       TtaSetStylePresentation (ruleType, el, NULL, ctxt, pval);
                   2393:     }
                   2394:   else
                   2395:     {
                   2396:       ctxt->destroy = FALSE;
                   2397:       /* parse the attribute value (a number followed by a unit) */
1.119     cvs      2398:       value = TtaSkipBlanks (value);
1.60      cvs      2399:       value = ParseCSSUnit (value, &pval);
                   2400:       /***** we should accept namedspace for width *****/
                   2401:       if (pval.typed_data.unit != STYLE_UNIT_INVALID)
1.78      cvs      2402:        {
                   2403:          /* the specific presentation to be created is not a CSS rule */
                   2404:          ctxt->cssLevel = 0;
                   2405:          TtaSetStylePresentation (ruleType, el, NULL, ctxt, pval);
                   2406:        }
1.60      cvs      2407:     }
                   2408:   TtaFreeMemory (ctxt);
                   2409: }
                   2410: 
                   2411: /*----------------------------------------------------------------------
1.1       cvs      2412:    MathMLAttributeComplete
1.58      cvs      2413:    The XML parser has completed parsing attribute attr (as well as its value)
                   2414:    that is associated with element el in document doc.
1.1       cvs      2415:   ----------------------------------------------------------------------*/
1.120     cvs      2416: void MathMLAttributeComplete (Attribute attr, Element el, Document doc)
1.1       cvs      2417: {
1.23      cvs      2418:    AttributeType     attrType;
                   2419:    int              attrKind;
1.50      cvs      2420:    ElementType       elType;
1.23      cvs      2421: #define buflen 50
1.120     cvs      2422:    char             *value;
1.50      cvs      2423:    int               val, length;
1.101     cvs      2424:    Attribute         intAttr;
1.23      cvs      2425:  
1.58      cvs      2426:    /* first get the type of that attribute */
1.23      cvs      2427:    TtaGiveAttributeType (attr, &attrType, &attrKind);
1.54      cvs      2428:    if (attrType.AttrTypeNum == MathML_ATTR_bevelled)
1.58      cvs      2429:      /* it's a bevelled attribute */
1.50      cvs      2430:      {
                   2431:        val = TtaGetAttributeValue (attr);
1.54      cvs      2432:        if (val == MathML_ATTR_bevelled_VAL_true)
                   2433:         /* bevelled = true.  Transform MFRAC into BevelledMFRAC */
1.50      cvs      2434:         {
                   2435:         elType = TtaGetElementType (el);
                   2436:         if (elType.ElTypeNum == MathML_EL_MFRAC)
1.54      cvs      2437:            ChangeTypeOfElement (el, doc, MathML_EL_BevelledMFRAC);
1.50      cvs      2438:         }
                   2439:      }
1.101     cvs      2440: 
                   2441:    else if (attrType.AttrTypeNum == MathML_ATTR_rowalign_mtr)
                   2442:      {
                   2443:        /* create an equivalent IntRowAlign attribute on the same element */
                   2444:        attrType.AttrTypeNum = MathML_ATTR_IntRowAlign;
                   2445:        intAttr = TtaGetAttribute (el, attrType);
                   2446:        if (!intAttr)
                   2447:         /* no IntRowAlign attribute, create one */
                   2448:         {
                   2449:           intAttr = TtaNewAttribute (attrType);
                   2450:           TtaAttachAttribute (el, intAttr, doc);
                   2451:         }
                   2452:        val = TtaGetAttributeValue (attr);
                   2453:        TtaSetAttributeValue (intAttr, val, el, doc);
                   2454:      }
                   2455: 
                   2456:    else if (attrType.AttrTypeNum == MathML_ATTR_rowalign)
                   2457:      {
                   2458:        /* parse the attribute value and create a IntRowAlign attribute
                   2459:          for each mrow contained in the element */
                   2460:        HandleRowalignAttribute (attr, el, doc, FALSE);
                   2461:      }
                   2462: 
                   2463:    else if (attrType.AttrTypeNum == MathML_ATTR_columnalign_mtd)
                   2464:      {
                   2465:        /* create an equivalent IntColAlign attribute on the same element */
                   2466:        attrType.AttrTypeNum = MathML_ATTR_IntColAlign;
                   2467:        intAttr = TtaGetAttribute (el, attrType);
                   2468:        if (!intAttr)
                   2469:         /* no IntColAlign attribute, create one */
                   2470:         {
                   2471:           intAttr = TtaNewAttribute (attrType);
                   2472:           TtaAttachAttribute (el, intAttr, doc);
                   2473:         }
                   2474:        val = TtaGetAttributeValue (attr);
                   2475:        TtaSetAttributeValue (intAttr, val, el, doc);
                   2476:      }
                   2477: 
1.104     cvs      2478:    /* don't handle attribute columnalign now: the table or the row is not
                   2479:       complete yet. Handle it when the element is complete.
1.101     cvs      2480:    else if (attrType.AttrTypeNum == MathML_ATTR_columnalign)
1.104     cvs      2481:    */
1.101     cvs      2482: 
1.50      cvs      2483:    else if (attrType.AttrTypeNum == MathML_ATTR_color ||
1.93      cvs      2484:            attrType.AttrTypeNum == MathML_ATTR_mathcolor ||
                   2485:            attrType.AttrTypeNum == MathML_ATTR_background_ ||
                   2486:            attrType.AttrTypeNum == MathML_ATTR_mathbackground ||
                   2487:            attrType.AttrTypeNum == MathML_ATTR_fontsize ||
                   2488:            attrType.AttrTypeNum == MathML_ATTR_mathsize ||
                   2489:            attrType.AttrTypeNum == MathML_ATTR_fontfamily ||
                   2490:            attrType.AttrTypeNum == MathML_ATTR_linethickness ||
                   2491:            attrType.AttrTypeNum == MathML_ATTR_lspace ||
                   2492:            attrType.AttrTypeNum == MathML_ATTR_rspace ||
                   2493:            attrType.AttrTypeNum == MathML_ATTR_scriptlevel ||
                   2494:            attrType.AttrTypeNum == MathML_ATTR_width_ ||
                   2495:            attrType.AttrTypeNum == MathML_ATTR_height_ ||
                   2496:            attrType.AttrTypeNum == MathML_ATTR_depth_ )
                   2497:      {
1.23      cvs      2498:       length = TtaGetTextAttributeLength (attr);
                   2499:       if (length >= buflen)
                   2500:          length = buflen - 1;
                   2501:       if (length > 0)
                   2502:         {
1.116     cvs      2503:           value = TtaGetMemory (buflen);
1.33      cvs      2504:           value[0] = EOS;
                   2505:           TtaGiveTextAttributeValue (attr, value, &length);
                   2506:           switch (attrType.AttrTypeNum)
                   2507:             {
                   2508:             case MathML_ATTR_color:
1.93      cvs      2509:             case MathML_ATTR_mathcolor:
1.24      cvs      2510:                HTMLSetForegroundColor (doc, el, value);
                   2511:               break;
1.33      cvs      2512:             case MathML_ATTR_background_:
1.93      cvs      2513:             case MathML_ATTR_mathbackground:
1.24      cvs      2514:                HTMLSetBackgroundColor (doc, el, value);
                   2515:               break;
1.33      cvs      2516:             case MathML_ATTR_fontfamily:
1.24      cvs      2517:               SetFontfamily (doc, el, value);
1.83      cvs      2518:               break;
                   2519:             case MathML_ATTR_linethickness:
                   2520:               MathMLlinethickness (doc, el, value);
1.58      cvs      2521:               break;
                   2522:             case MathML_ATTR_fontsize:
1.93      cvs      2523:             case MathML_ATTR_mathsize:
1.58      cvs      2524:             case MathML_ATTR_lspace:
                   2525:             case MathML_ATTR_rspace:
1.60      cvs      2526:               MathMLAttrToStyleProperty (doc, el, value,attrType.AttrTypeNum);
                   2527:               break;
                   2528:             case MathML_ATTR_scriptlevel:
                   2529:               MathMLSetScriptLevel (doc, el, value);
                   2530:               break;
                   2531:              case MathML_ATTR_width_:
                   2532:             case MathML_ATTR_height_:
                   2533:             case MathML_ATTR_depth_:
                   2534:               MathMLSpacingAttr (doc, el, value, attrType.AttrTypeNum);
1.59      cvs      2535:               break;
                   2536:             default:
1.24      cvs      2537:               break;
1.33      cvs      2538:             }
                   2539:           TtaFreeMemory (value);
1.23      cvs      2540:         }
                   2541:       }
1.1       cvs      2542: }
                   2543: 
                   2544: /*----------------------------------------------------------------------
                   2545:    MathMLGetDTDName
                   2546:   ----------------------------------------------------------------------*/
1.120     cvs      2547: void MathMLGetDTDName (char *DTDname, char *elementName)
1.1       cvs      2548: {
                   2549:    /* no other DTD allowed within MathML elements */
1.116     cvs      2550:    strcpy (DTDname, "");
1.1       cvs      2551: }
                   2552: 
                   2553: /* end of module */

Webmaster