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

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

Webmaster