Annotation of Amaya/amaya/XHTMLbuilder.c, revision 1.66

1.1       cvs         1: /*
                      2:  *
1.64      vatton      3:  *  (c) COPYRIGHT MIT and INRIA, 1996-2002
1.1       cvs         4:  *  Please first read the full copyright statement in file COPYRIGHT.
                      5:  *
                      6:  */
                      7: 
                      8: /*
1.30      cvs         9:  * XHTMLbuilder.c
1.23      cvs        10:  * Builds the corresponding abstract tree for a Thot document of type HTML.
1.1       cvs        11:  *
1.20      cvs        12:  * Authors: L. Carcone
                     13:  *          V. Quint 
1.1       cvs        14:  */
                     15: 
                     16: #define THOT_EXPORT extern
                     17: #include "amaya.h"
                     18: #include "css.h"
1.2       cvs        19: #include "parser.h"
                     20: #include "HTML.h"
1.30      cvs        21: #include "fetchHTMLname.h"
1.2       cvs        22: 
1.13      cvs        23: #include "css_f.h"
                     24: #include "fetchXMLname_f.h"
1.30      cvs        25: #include "fetchHTMLname_f.h"
1.22      cvs        26: #include "html2thot_f.h"
1.1       cvs        27: #include "HTMLactions_f.h"
                     28: #include "HTMLedit_f.h"
1.22      cvs        29: #include "HTMLform_f.h"
1.1       cvs        30: #include "HTMLimage_f.h"
                     31: #include "HTMLtable_f.h"
                     32: #include "HTMLimage_f.h"
                     33: #include "UIcss_f.h"
1.13      cvs        34: #include "styleparser_f.h"
1.2       cvs        35: #include "XHTMLbuilder_f.h"
1.13      cvs        36: #include "Xml2thot_f.h"
1.1       cvs        37: 
                     38: /* maximum length of a Thot structure schema name */
                     39: #define MAX_SS_NAME_LENGTH 32
                     40: 
1.30      cvs        41: #define MaxMsgLength 200
                     42: 
1.47      cvs        43: /* Elements that cannot contain text as immediate children.
                     44:    When some text is present in the HTML file it must be 
                     45:    surrounded by a Pseudo_paragraph element */
                     46: static int          NoTextChild[] =
                     47: {
                     48:    HTML_EL_Document, HTML_EL_HTML, HTML_EL_HEAD, HTML_EL_BODY,
                     49:    HTML_EL_Definition_List, HTML_EL_Block_Quote, HTML_EL_Directory,
                     50:    HTML_EL_Form, HTML_EL_Menu, HTML_EL_FIELDSET,
                     51:    HTML_EL_Numbered_List, HTML_EL_Option_Menu,
                     52:    HTML_EL_Unnumbered_List, HTML_EL_Definition, HTML_EL_List_Item,
                     53:    HTML_EL_MAP, HTML_EL_map, HTML_EL_Applet,
                     54:    HTML_EL_Object, HTML_EL_IFRAME, HTML_EL_NOFRAMES,
                     55:    HTML_EL_Division, HTML_EL_Center, HTML_EL_NOSCRIPT,
                     56:    HTML_EL_Data_cell, HTML_EL_Heading_cell,
                     57:    0};
                     58: 
1.28      cvs        59: /* Define a pointer to let parser functions access the HTML entity table */
                     60: extern XmlEntity *pXhtmlEntityTable;
1.6       cvs        61: 
1.30      cvs        62: /* maximum size of error messages */
                     63: #define MaxMsgLength 200
                     64: 
1.6       cvs        65: /*----------------------------------------------------------------------
1.15      cvs        66:   ParseCharset:
1.6       cvs        67:   Parses the element HTTP-EQUIV and looks for the charset value.
                     68:   ----------------------------------------------------------------------*/
1.30      cvs        69: void             ParseCharset (Element el, Document doc) 
                     70: 
1.6       cvs        71: {
1.15      cvs        72:    AttributeType attrType;
                     73:    Attribute     attr;
                     74:    SSchema       docSSchema;
                     75:    CHARSET       charset;
1.39      cvs        76:    char         *text, *text2, *ptrText, *str;
                     77:    char          charsetname[MAX_LENGTH];
1.15      cvs        78:    int           length;
1.6       cvs        79:    int           pos, index = 0;
                     80: 
1.15      cvs        81:    charset = TtaGetDocumentCharset (doc);
                     82:    if (charset != UNDEFINED_CHARSET)
                     83:      /* the charset was already defined by the http header */
                     84:      return;
1.6       cvs        85: 
                     86:    docSSchema = TtaGetDocumentSSchema (doc);
                     87:    attrType.AttrSSchema = docSSchema;
                     88:    attrType.AttrTypeNum = HTML_ATTR_http_equiv;
                     89:    attr = TtaGetAttribute (el, attrType);
                     90:    if (attr != NULL)
                     91:      {
                     92:        /* There is a HTTP-EQUIV attribute */
                     93:        length = TtaGetTextAttributeLength (attr);
                     94:        if (length > 0)
                     95:         {
1.37      cvs        96:           text = TtaGetMemory (length + 1);
1.6       cvs        97:           TtaGiveTextAttributeValue (attr, text, &length);
1.37      cvs        98:           if (!strcasecmp (text, "content-type"))
1.6       cvs        99:             {
                    100:               attrType.AttrTypeNum = HTML_ATTR_meta_content;
                    101:               attr = TtaGetAttribute (el, attrType);
                    102:               if (attr != NULL)
                    103:                 {
                    104:                   length = TtaGetTextAttributeLength (attr);
                    105:                   if (length > 0)
                    106:                     {
1.37      cvs       107:                       text2 = TtaGetMemory (length + 1);
1.6       cvs       108:                       TtaGiveTextAttributeValue (attr, text2, &length);
                    109:                       ptrText = text2;
                    110:                       while (*ptrText)
                    111:                         {
1.53      vatton    112:                           *ptrText = tolower (*ptrText);
1.6       cvs       113:                           ptrText++;
                    114:                         }
                    115:                       
1.37      cvs       116:                       str = strstr (text2, "charset=");
1.6       cvs       117:                       if (str)
                    118:                         {
                    119:                           pos = str - text2 + 8;
1.37      cvs       120:                           while (text2[pos] != SPACE &&
                    121:                                  text2[pos] != TAB && text2[pos] != EOS)
1.6       cvs       122:                             charsetname[index++] = text2[pos++];
1.37      cvs       123:                           charsetname[index] = EOS;
1.15      cvs       124:                           charset = TtaGetCharset (charsetname);
                    125:                           if (charset != UNDEFINED_CHARSET)
                    126:                             TtaSetDocumentCharset (doc, charset);
1.6       cvs       127:                         }
                    128:                       TtaFreeMemory (text2);
                    129:                     }       
                    130:                 } 
                    131:             }
                    132:           TtaFreeMemory (text);
                    133:         }
                    134:      }
                    135: }
                    136: 
1.23      cvs       137: /*----------------------------------------------------------------------
1.47      cvs       138:    XhtmlCannotContainText 
                    139:    Return TRUE if element el is a block element.
                    140:   ----------------------------------------------------------------------*/
                    141: ThotBool      XhtmlCannotContainText (ElementType elType)
                    142: 
                    143: {
                    144:    int        i;
                    145:    ThotBool   ret;
                    146: 
                    147:    if (strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML"))
                    148:       /* not an HTML element */
                    149:       ret = TRUE;
                    150:    else
                    151:      {
                    152:        ret = FALSE;
                    153:        i = 0;
                    154:        while (NoTextChild[i] > 0 && NoTextChild[i] != elType.ElTypeNum)
                    155:            i++;
                    156:        if (NoTextChild[i] == elType.ElTypeNum)
                    157:            ret = TRUE;
                    158:      }
                    159:    return ret;
1.23      cvs       160: }
                    161: 
1.6       cvs       162: /*----------------------------------------------------------------------
                    163:   XhtmlElementComplete
1.20      cvs       164:   Complete Xhtml elements.
1.6       cvs       165:   Check its attributes and its contents.
                    166:   ----------------------------------------------------------------------*/
1.51      cvs       167: void       XhtmlElementComplete (Element el, Document doc, int *error)
1.30      cvs       168: 
                    169: {
                    170:    ElementType    elType, newElType, childType;
                    171:    Element        constElem, child, desc, leaf, prev, next, last,
1.62      quint     172:                  elFrames, lastFrame, lastChild, parent, picture, content;
1.30      cvs       173:    Attribute      attr;
                    174:    AttributeType  attrType;
                    175:    Language       lang;
1.41      cvs       176:    char           *text;
1.39      cvs       177:    char           lastChar[2];
                    178:    char           *name1;
1.30      cvs       179:    int            length;
                    180:    SSchema        docSSchema;
1.62      quint     181:    ThotBool       isImage;
                    182:    PresentationValue    pval;
                    183:    PresentationContext  ctxt;
1.6       cvs       184: 
                    185:    *error = 0;
                    186:    docSSchema = TtaGetDocumentSSchema (doc);
                    187: 
                    188:    elType = TtaGetElementType (el);
                    189:    /* is this a block-level element in a character-level element? */
1.56      cvs       190:    if (!IsXMLElementInline (elType, doc) &&
1.24      cvs       191:        elType.ElTypeNum != HTML_EL_Comment_ &&
                    192:        elType.ElTypeNum != HTML_EL_XMLPI)
1.6       cvs       193:        BlockInCharLevelElem (el);
                    194: 
                    195:    newElType.ElSSchema = elType.ElSSchema;
                    196:    switch (elType.ElTypeNum)
                    197:      {
1.62      quint     198:      case HTML_EL_Object:      /* it's an object */
                    199:        isImage = FALSE;
                    200:        /* is there a type attribute on the object element? */
                    201:        attrType.AttrSSchema = elType.ElSSchema;
                    202:        attrType.AttrTypeNum = HTML_ATTR_Object_type;
1.6       cvs       203:        attr = TtaGetAttribute (el, attrType);
1.62      quint     204:        if (attr)
                    205:         /* there is a type attribute. Get its value to see if the object
                    206:            represents an image */
1.6       cvs       207:         {
                    208:           length = TtaGetTextAttributeLength (attr);
                    209:           if (length > 0)
                    210:             {
1.37      cvs       211:               name1 = TtaGetMemory (length + 1);
1.6       cvs       212:               TtaGiveTextAttributeValue (attr, name1, &length);
1.62      quint     213:               if (!strcmp (name1, "application/mathml+xml") ||
                    214:                   !strcmp (name1, "application/postscript") ||
                    215:                   !strcmp (name1, "image/x-bitmap") ||
                    216:                   !strcmp (name1, "image/x-xpixmap") ||
                    217:                   !strcmp (name1, "image/gif") ||
                    218:                   !strcmp (name1, "image/jpeg") ||
                    219:                   !strcmp (name1, "image/png") ||
                    220:                   !strcmp (name1, "image/svg"))
                    221:                 isImage = TRUE;
                    222:               TtaFreeMemory (name1);
                    223:             }
                    224:         }
                    225:        
                    226:        picture = NULL;     /* no PICTURE element yet */
                    227:        child = TtaGetFirstChild (el);
                    228:        if (isImage)
                    229:         /* the object represents an image. We need a PICTURE element as
                    230:            child of the object to hold the image */
                    231:         {
                    232:           if (child)
                    233:             {
                    234:               elType = TtaGetElementType (child);
                    235:               if (elType.ElTypeNum == HTML_EL_PICTURE_UNIT)
                    236:                 /* there is already a PICTURE element */
                    237:                 picture = child;
                    238:             }
                    239:           /* if the object element has no PICTURE element as first child
                    240:              create one */
                    241:           if (!picture)
                    242:             {
                    243:               elType.ElTypeNum = HTML_EL_PICTURE_UNIT;
                    244:               picture = TtaNewTree (doc, elType, "");
                    245:               if (child)
                    246:                 TtaInsertSibling (picture, child, TRUE, doc);
                    247:               else
                    248:                 TtaInsertFirstChild (&picture, el, doc);
                    249:               child = picture;
                    250:             }
                    251:           /* copy attribute data of the object into the SRC attribute of
                    252:              the PICTURE element */
                    253:           attrType.AttrSSchema = elType.ElSSchema;
                    254:           attrType.AttrTypeNum = HTML_ATTR_data;
                    255:           attr = TtaGetAttribute (el, attrType);
                    256:           if (attr)
                    257:             /* the object has a data attribute */
                    258:             {
                    259:               length = TtaGetTextAttributeLength (attr);
                    260:               if (length > 0)
1.6       cvs       261:                 {
1.62      quint     262:                   name1 = TtaGetMemory (length + 1);
                    263:                   TtaGiveTextAttributeValue (attr, name1, &length);
                    264:                   attrType.AttrTypeNum = HTML_ATTR_SRC;
                    265:                   attr = TtaGetAttribute (picture, attrType);
                    266:                   if (attr == NULL)
                    267:                     {
                    268:                       attr = TtaNewAttribute (attrType);
                    269:                       TtaAttachAttribute (picture, attr, doc);
                    270:                     }
                    271:                   TtaSetAttributeText (attr, name1, picture, doc);
                    272:                   TtaFreeMemory (name1);
1.6       cvs       273:                 }
                    274:             }
                    275:         }
                    276:        /* is the Object_Content element already created ? */
1.62      quint     277:        if (child)
                    278:         /* the object element has at least 1 child element */
                    279:         {
                    280:           content = NULL;
                    281:           desc = child;
1.6       cvs       282:           elType = TtaGetElementType (desc);
1.62      quint     283:           if (elType.ElTypeNum != HTML_EL_Object_Content)
                    284:             {
                    285:               TtaNextSibling(&desc);
                    286:               if (desc)
                    287:                 elType = TtaGetElementType (desc);
                    288:             }
                    289:           /* is it the Object_Content element ? */
                    290:           if (elType.ElTypeNum == HTML_EL_Object_Content)
                    291:             content = desc;
                    292:           else
1.6       cvs       293:             {
1.62      quint     294:               /* create an Object_Content element */
                    295:               elType.ElTypeNum = HTML_EL_Object_Content;
                    296:               content = TtaNewElement (doc, elType);
                    297:               if (picture)
                    298:                 TtaInsertSibling (content, picture, FALSE, doc);
                    299:               else
                    300:                 TtaInsertSibling (content, child, TRUE, doc);
                    301:               /* move previous existing children into Object_Content */
1.6       cvs       302:               child = TtaGetLastChild(el);
1.62      quint     303:               while (child != content)
                    304:                 {
                    305:                   TtaRemoveTree (child, doc);
                    306:                   TtaInsertFirstChild (&child, content, doc);
                    307:                   child = TtaGetLastChild(el);
                    308:                 }
                    309:             }
                    310:           if (picture && content)
                    311:             /* there is a picture element. The Object_Content must not be
                    312:                displayed in the main view */
                    313:             {
                    314:               ctxt = TtaGetSpecificStyleContext (doc);
                    315:               /* the presentation rule to be set is not a CSS rule */
                    316:               ctxt->cssSpecificity = 0;
                    317:               ctxt->destroy = FALSE;
                    318:               pval.typed_data.unit = STYLE_UNIT_PX;
                    319:               pval.typed_data.value = 0;
                    320:               pval.typed_data.real = FALSE;
                    321:               TtaSetStylePresentation (PRVisibility, content, NULL, ctxt, pval);
1.6       cvs       322:             }
                    323:         }
                    324:        break;
1.62      quint     325: 
1.6       cvs       326:      case HTML_EL_Unnumbered_List:
                    327:      case HTML_EL_Numbered_List:
                    328:      case HTML_EL_Menu:
                    329:      case HTML_EL_Directory:
                    330:        /* It's a List element. It should only have List_Item children.
                    331:          If it has List element chidren, move these List elements
                    332:          within their previous List_Item sibling.  This is to fix
                    333:          a bug in document generated by Mozilla. */
                    334:        prev = NULL;
                    335:        next = NULL;
                    336:        child = TtaGetFirstChild (el);
                    337:        while (child != NULL)
                    338:         {
                    339:           next = child;
                    340:           TtaNextSibling (&next);
                    341:           elType = TtaGetElementType (child);
                    342:           if (elType.ElTypeNum == HTML_EL_Unnumbered_List ||
                    343:               elType.ElTypeNum == HTML_EL_Numbered_List ||
                    344:               elType.ElTypeNum == HTML_EL_Menu ||
                    345:               elType.ElTypeNum == HTML_EL_Directory)
                    346:             /* this list element is a child of another list element */
                    347:             if (prev)
                    348:               {
                    349:                 elType = TtaGetElementType (prev);
                    350:                 if (elType.ElTypeNum == HTML_EL_List_Item)
                    351:                   {
                    352:                     /* get the last child of the previous List_Item */
                    353:                     desc = TtaGetFirstChild (prev);
                    354:                     last = NULL;
                    355:                     while (desc)
                    356:                       {
                    357:                         last = desc;
                    358:                         TtaNextSibling (&desc);
                    359:                       }
                    360:                     /* move the list element after the last child of the
                    361:                        previous List_Item */
                    362:                     TtaRemoveTree (child, doc);
                    363:                     if (last)
                    364:                       TtaInsertSibling (child, last, FALSE, doc);
                    365:                     else
                    366:                       TtaInsertFirstChild (&child, prev, doc);
                    367:                     child = prev;
                    368:                   }
                    369:               }
                    370:           prev = child;
                    371:           child = next;
                    372:         }
                    373:        break;
                    374:        
                    375:      case HTML_EL_FRAMESET:
                    376:        /* The FRAMESET element is now complete.  Gather all its FRAMESET
                    377:          and FRAME children and wrap them up in a Frames element */
                    378:        elFrames = NULL; lastFrame = NULL;
                    379:        lastChild = NULL;
                    380:        child = TtaGetFirstChild (el);
                    381:        while (child != NULL)
                    382:         {
                    383:           next = child;
                    384:           TtaNextSibling (&next);
                    385:           elType = TtaGetElementType (child);
                    386:           if (elType.ElTypeNum == HTML_EL_FRAMESET ||
                    387:               elType.ElTypeNum == HTML_EL_FRAME ||
                    388:               elType.ElTypeNum == HTML_EL_Comment_)
                    389:             {
                    390:               /* create the Frames element if it does not exist */
                    391:               if (elFrames == NULL)
                    392:                 {
                    393:                   newElType.ElSSchema = docSSchema;
                    394:                   newElType.ElTypeNum = HTML_EL_Frames;
                    395:                   elFrames = TtaNewElement (doc, newElType);
1.63      cvs       396:                   if (DocumentMeta[doc]->xmlformat)
                    397:                     XmlSetElemLineNumber (elFrames);
                    398:                   else
                    399:                     SetHtmlElemLineNumber (elFrames);
1.6       cvs       400:                   TtaInsertSibling (elFrames, child, TRUE, doc);
                    401:                 }
                    402:               /* move the element as the last child of the Frames element */
                    403:               TtaRemoveTree (child, doc);
                    404:               if (lastFrame == NULL)
                    405:                 TtaInsertFirstChild (&child, elFrames, doc);
                    406:               else
                    407:                 TtaInsertSibling (child, lastFrame, FALSE, doc);
                    408:               lastFrame = child;
                    409:             }
                    410:           child = next;
                    411:         }
                    412:        break;
                    413:        
                    414:      case HTML_EL_Input:       /* it's an INPUT without any TYPE attribute */
                    415:        /* Create a child of type Text_Input */
                    416:        elType.ElTypeNum = HTML_EL_Text_Input;
                    417:        child = TtaNewTree (doc, elType, "");
1.63      cvs       418:        if (DocumentMeta[doc]->xmlformat)
                    419:         XmlSetElemLineNumber (child);
                    420:        else
                    421:         SetHtmlElemLineNumber (child);
1.6       cvs       422:        TtaInsertFirstChild (&child, el, doc);
                    423:        /* now, process it like a Text_Input element */
                    424: 
                    425:      case HTML_EL_Text_Input:
                    426:      case HTML_EL_Password_Input:
                    427:      case HTML_EL_File_Input:
                    428:        /* get element Inserted_Text */
                    429:        child = TtaGetFirstChild (el);
                    430:        if (child != NULL)
                    431:         {
                    432:           attrType.AttrSSchema = docSSchema;
                    433:           attrType.AttrTypeNum = HTML_ATTR_Value_;
                    434:           attr = TtaGetAttribute (el, attrType);
                    435:           if (attr != NULL)
                    436:             {
                    437:               /* copy the value of attribute "value" into the first text
                    438:                  leaf of element */
                    439:               length = TtaGetTextAttributeLength (attr);
                    440:               if (length > 0)
                    441:                 {
                    442:                   /* get the text leaf */
                    443:                   leaf = TtaGetFirstChild (child);
                    444:                   if (leaf != NULL)
                    445:                     {
                    446:                       childType = TtaGetElementType (leaf);
                    447:                       if (childType.ElTypeNum == HTML_EL_TEXT_UNIT)
                    448:                         {
                    449:                           /* copy attribute value into the text leaf */
1.37      cvs       450:                           text = TtaGetMemory (length + 1);
1.6       cvs       451:                           TtaGiveTextAttributeValue (attr, text, &length);
                    452:                           TtaSetTextContent (leaf, text, 
                    453:                                              TtaGetDefaultLanguage (), doc);
                    454:                           TtaFreeMemory (text);
                    455:                         }
                    456:                     }
                    457:                 }
                    458:             }
                    459:         }
                    460:        break;
                    461:        
                    462:      case HTML_EL_META:
1.15      cvs       463:        ParseCharset (el, doc);
1.6       cvs       464:        break;
                    465: 
                    466:      case HTML_EL_STYLE_:      /* it's a STYLE element */
1.60      vatton    467:      case HTML_EL_SCRIPT_:     /* it's a SCRIPT element */
1.6       cvs       468:      case HTML_EL_Preformatted:        /* it's a PRE */
                    469:        /* if the last line of the Preformatted is empty, remove it */
                    470:        leaf = XmlLastLeafInElement (el);
                    471:        if (leaf != NULL)
                    472:         {
                    473:           elType = TtaGetElementType (leaf);
                    474:           if (elType.ElTypeNum == HTML_EL_TEXT_UNIT)
                    475:             /* the last leaf is a TEXT element */
                    476:             {
                    477:               length = TtaGetTextLength (leaf);
                    478:               if (length > 0)
                    479:                 {
                    480:                   TtaGiveSubString (leaf, lastChar, length, 1);
                    481:                   if (lastChar[0] == EOL)
                    482:                     /* last character is new line, delete it */
                    483:                     {
                    484:                       if (length == 1)
                    485:                         /* empty TEXT element */
                    486:                         TtaDeleteTree (leaf, doc);
                    487:                       else
                    488:                         /* remove the last character */
                    489:                         TtaDeleteTextContent (leaf, length, 1, doc);
                    490:                     }
                    491:                 }
                    492:             }
                    493:         }
1.63      cvs       494:        if (DocumentMeta[doc]->xmlformat)
                    495:         {
                    496:           if (IsXmlParsingCSS ())
                    497:             {
                    498:               text = GetStyleContents (el);
                    499:               if (text)
                    500:                 {
                    501:                   ReadCSSRules (doc, NULL, text,
                    502:                                 TtaGetElementLineNumber (el), FALSE);
                    503:                   TtaFreeMemory (text);
                    504:                 }
                    505:               SetXmlParsingCSS (FALSE);
                    506:             }
                    507:         }
                    508:        else
1.6       cvs       509:         {
1.63      cvs       510:           if (IsHtmlParsingCSS ())
1.6       cvs       511:             {
1.63      cvs       512:               text = GetStyleContents (el);
                    513:               if (text)
                    514:                 {
                    515:                   ReadCSSRules (doc, NULL, text,
                    516:                                 TtaGetElementLineNumber (el), FALSE);
                    517:                   TtaFreeMemory (text);
                    518:                 }
                    519:               SetHtmlParsingCSS (FALSE);
1.6       cvs       520:             }
                    521:         }
                    522:        /* and continue as if it were a Preformatted or a Script */
                    523:        break;
                    524:        
                    525:      case HTML_EL_Text_Area:   /* it's a Text_Area */
                    526:        SetParsingTextArea (FALSE);
                    527:        child = TtaGetFirstChild (el);
                    528:        if (child == NULL)
                    529:         /* it's an empty Text_Area */
                    530:         /* insert a Inserted_Text element in the element */
                    531:         {
                    532:           newElType.ElTypeNum = HTML_EL_Inserted_Text;
                    533:           child = TtaNewTree (doc, newElType, "");
                    534:           TtaInsertFirstChild (&child, el, doc);
                    535:         }
                    536:        else
                    537:         {
                    538:           /* save the text into Default_Value attribute */
                    539:           attrType.AttrSSchema = docSSchema;
                    540:           attrType.AttrTypeNum = HTML_ATTR_Default_Value;
                    541:           if (TtaGetAttribute (el, attrType) == NULL)
                    542:             /* attribute Default_Value is missing */
                    543:             {
                    544:               attr = TtaNewAttribute (attrType);
                    545:               TtaAttachAttribute (el, attr, doc);
                    546:               desc = TtaGetFirstChild (child);
                    547:               length = TtaGetTextLength (desc) + 1;
1.37      cvs       548:               text = TtaGetMemory (length);
1.6       cvs       549:               TtaGiveTextContent (desc, text, &length, &lang);
                    550:               TtaSetAttributeText (attr, text, el, doc);
                    551:               TtaFreeMemory (text);
                    552:             }
                    553:         }
                    554:        /* insert a Frame element */
                    555:        newElType.ElTypeNum = HTML_EL_Frame;
                    556:        constElem = TtaNewTree (doc, newElType, "");
                    557:        TtaInsertSibling (constElem, child, FALSE, doc);
                    558:        break;
                    559:        
                    560:      case HTML_EL_Radio_Input:
                    561:      case HTML_EL_Checkbox_Input:
                    562:        /* put an attribute Checked if it is missing */
                    563:        attrType.AttrSSchema = docSSchema;
                    564:        attrType.AttrTypeNum = HTML_ATTR_Checked;
                    565:        if (TtaGetAttribute (el, attrType) == NULL)
                    566:         /* attribute Checked is missing */
                    567:         {
                    568:           attr = TtaNewAttribute (attrType);
                    569:           TtaAttachAttribute (el, attr, doc);
                    570:           TtaSetAttributeValue (attr, HTML_ATTR_Checked_VAL_No_, el, doc);
                    571:         }
                    572:        break;
                    573:        
                    574:      case HTML_EL_Option_Menu:
                    575:        /* Check that at least one option has a SELECTED attribute */
                    576:        OnlyOneOptionSelected (el, doc, TRUE);
                    577:        break;
                    578: 
                    579:      case HTML_EL_PICTURE_UNIT:
                    580:        break;
                    581:        
                    582:      case HTML_EL_LINK:
                    583:        CheckCSSLink (el, doc, docSSchema);
                    584:        break;
                    585:        
                    586:      case HTML_EL_Data_cell:
                    587:      case HTML_EL_Heading_cell:
                    588:        /* insert a pseudo paragraph into empty cells */
                    589:        child = TtaGetFirstChild (el);
                    590:        if (child == NULL)
                    591:         {
                    592:           elType.ElTypeNum = HTML_EL_Pseudo_paragraph;
                    593:           child = TtaNewTree (doc, elType, "");
                    594:           if (child != NULL)
                    595:               TtaInsertFirstChild (&child, el, doc);
                    596:         }
                    597:        
                    598:        /* detect whether we're parsing a whole table or just a cell */
1.63      cvs       599:        if (DocumentMeta[doc]->xmlformat)
                    600:         {
                    601:           if (IsWithinXmlTable ())
                    602:             NewCell (el, doc, FALSE);
                    603:         }
                    604:        else
                    605:         {
                    606:           if (IsWithinHtmlTable ())
                    607:             NewCell (el, doc, FALSE);
                    608:         }
1.6       cvs       609:        break;
                    610:        
                    611:      case HTML_EL_Table:
                    612:        CheckTable (el, doc);
                    613:        SubWithinTable ();
                    614:        break;
                    615:        
                    616:      case HTML_EL_TITLE:
                    617:        /* show the TITLE in the main window */
                    618:        UpdateTitle (el, doc);
                    619:        break;
1.41      cvs       620: 
                    621:      case HTML_EL_rbc:
                    622:        /* an rbc element has been read. Its parent should be a complex_ruby.
                    623:          Change the type of the parent, as simple_ruby are created by
                    624:          default */
                    625:        parent = TtaGetParent (el);
                    626:        if (parent)
                    627:         {
                    628:           newElType = TtaGetElementType (parent);
                    629:           if (newElType.ElSSchema == elType.ElSSchema &&
                    630:               newElType.ElTypeNum == HTML_EL_simple_ruby)
                    631:              ChangeElementType (parent, HTML_EL_complex_ruby);
                    632:         }
                    633:        break;
                    634: 
                    635:      case HTML_EL_rtc1:
                    636:        /* an rtc element has been parsed. If it has already a rtc1 sibling,
                    637:          change its type to rtc2 */
                    638:        prev = el;
                    639:        do
                    640:         {
                    641:           TtaPreviousSibling(&prev);
                    642:           if (prev)
                    643:             {
                    644:               newElType = TtaGetElementType (prev);
                    645:               if (newElType.ElSSchema == elType.ElSSchema &&
                    646:                   newElType.ElTypeNum == HTML_EL_rtc1)
                    647:                 {
                    648:                   ChangeElementType (el, HTML_EL_rtc2);
                    649:                   prev = NULL;
                    650:                 }
                    651:             }
                    652:         }
                    653:        while (prev);
                    654:        break;
                    655: 
1.6       cvs       656:      default:
                    657:        break;
                    658:      }
                    659: }
1.1       cvs       660: 
                    661: /*----------------------------------------------------------------------
1.30      cvs       662:    PutInContent    
                    663:    Put the string ChrString in the leaf of current element.
                    664:   ----------------------------------------------------------------------*/
1.39      cvs       665: Element         PutInContent (char *ChrString, ParserData *context)
1.30      cvs       666: 
                    667: {
                    668:    Element      el, child;
                    669:    ElementType  elType;
                    670:    int          length;
                    671: 
                    672:    el = NULL;
                    673:    if (context->lastElement != NULL)
                    674:      {
                    675:        /* search first leaf of current element */
                    676:        el = context->lastElement;
                    677:        do
                    678:          {
                    679:             child = TtaGetFirstChild (el);
                    680:             if (child != NULL)
                    681:                el = child;
                    682:          }
                    683:        while (child != NULL);
                    684:        elType = TtaGetElementType (el);
                    685:        length = 0;
                    686:        if (elType.ElTypeNum == 1)
                    687:           length = TtaGetTextLength (el);
                    688:        if (length == 0)
                    689:           TtaSetTextContent (el, ChrString, context->language, context->doc);
                    690:        else
                    691:           TtaAppendTextContent (el, ChrString, context->doc);
                    692:      }
                    693:    return el;
                    694: }
                    695: 
                    696: /*----------------------------------------------------------------------
1.51      cvs       697:    UnknownXhtmlNameSpace
1.65      cvs       698:    The element doesn't belong to a supported namespace
1.51      cvs       699:   ----------------------------------------------------------------------*/
1.65      cvs       700: void               UnknownXhtmlNameSpace (ParserData *context,
                    701:                                          Element *unknownEl,
                    702:                                          char* content)
1.51      cvs       703: {
                    704:    ElementType     elType;
1.65      cvs       705:    Element         elText;
1.51      cvs       706: 
                    707:    /* Create a new Invalid_element */
                    708:    elType.ElSSchema = GetXMLSSchema (XHTML_TYPE, context->doc);
                    709:    elType.ElTypeNum = HTML_EL_Unknown_namespace;
1.65      cvs       710:    *unknownEl = TtaNewElement (context->doc, elType);
                    711:    if (*unknownEl != NULL)
1.51      cvs       712:      {
1.65      cvs       713:        XmlSetElemLineNumber (*unknownEl);
                    714:        InsertXmlElement (unknownEl);
1.51      cvs       715:        context->lastElementClosed = TRUE;
                    716:        elType.ElTypeNum = HTML_EL_TEXT_UNIT;
                    717:        elText = TtaNewElement (context->doc, elType);
                    718:        XmlSetElemLineNumber (elText);
1.65      cvs       719:        TtaInsertFirstChild (&elText, *unknownEl, context->doc);
1.51      cvs       720:        TtaSetTextContent (elText, content, context->language, context->doc);
                    721:        TtaSetAccessRight (elText, ReadOnly, context->doc);
                    722:      }
                    723: }
                    724: 
                    725: /*----------------------------------------------------------------------
1.30      cvs       726:    CreateHTMLAttribute
                    727:    create an attribute of type attrType for the element el.
                    728:   ----------------------------------------------------------------------*/
                    729: void           CreateHTMLAttribute (Element       el,
                    730:                                    AttributeType attrType,
1.46      cvs       731:                                    char*         text,
1.30      cvs       732:                                    ThotBool      isInvalid,
                    733:                                    Document      doc,
                    734:                                    Attribute    *lastAttribute,
                    735:                                    Element      *lastAttrElement)
                    736:      
                    737: {
                    738:    int         attrKind;
                    739:    int         length;
1.39      cvs       740:    char       *buffer;
1.30      cvs       741:    Attribute   attr, oldAttr;
                    742: 
                    743:    if (attrType.AttrTypeNum != 0)
                    744:      {
                    745:        oldAttr = TtaGetAttribute (el, attrType);
                    746:        if (oldAttr != NULL)
                    747:         /* this attribute already exists */
                    748:         attr = oldAttr;
                    749:        else
                    750:         /* create a new attribute and attach it to the element */
                    751:         {
                    752:           attr = TtaNewAttribute (attrType);
                    753:           TtaAttachAttribute (el, attr, doc);
                    754:         }
                    755:        *lastAttribute = attr;
                    756:        *lastAttrElement = el;
                    757: 
                    758:        TtaGiveAttributeType (attr, &attrType, &attrKind);
                    759:        if (attrKind == 0)      /* enumerate */
                    760:         TtaSetAttributeValue (attr, 1, el, doc);
                    761: 
                    762:        /* attribute BORDER without any value (ThotBool attribute) is */
                    763:        /* considered as BORDER=1 */
                    764:        if (attrType.AttrTypeNum == HTML_ATTR_Border)
                    765:         TtaSetAttributeValue (attr, 1, el, doc);
                    766: 
                    767:        if (isInvalid)
                    768:         /* Copy the name of the invalid attribute as the content */
                    769:         /* of the Invalid_attribute attribute. */
                    770:         {
1.37      cvs       771:           length = strlen (text) + 2;
1.30      cvs       772:           length += TtaGetTextAttributeLength (attr);
1.37      cvs       773:           buffer = TtaGetMemory (length + 1);
1.30      cvs       774:           TtaGiveTextAttributeValue (attr, buffer, &length);
1.37      cvs       775:           strcat (buffer, " ");
                    776:           strcat (buffer, text);
1.30      cvs       777:           TtaSetAttributeText (attr, buffer, el, doc);
                    778:           TtaFreeMemory (buffer);
                    779:         }
                    780:      }
                    781: }
                    782: 
                    783: /*----------------------------------------------------------------------
                    784:    HTMLTypeAttrValue
                    785:    Value val has been read for the HTML attribute TYPE.
                    786:    Create a child for the current Thot element INPUT accordingly.
                    787:   ----------------------------------------------------------------------*/
1.46      cvs       788: void               HTMLTypeAttrValue (char       *val,
1.30      cvs       789:                                      Attribute   lastAttribute,
                    790:                                      Element     lastAttrElement,
                    791:                                      ParserData *context)
                    792: 
                    793: {
                    794:   ElementType      elType;
                    795:   Element          newChild;
                    796:   AttributeType    attrType;
                    797:   Attribute        attr;
1.39      cvs       798:   char             msgBuffer[MaxMsgLength];
1.30      cvs       799:   int              value;
                    800:   int              numberOfLinesRead;
                    801: 
                    802:   value = MapAttrValue (DummyAttribute, val);
                    803:   if (value < 0)
                    804:     {
1.37      cvs       805:       if (strlen (val) > MaxMsgLength - 40)
                    806:          val[MaxMsgLength - 40] = EOS;
                    807:       sprintf (msgBuffer, "Unknown attribute value \"type = %s\"", val);
1.42      cvs       808:       HTMLParseError (context->doc, msgBuffer);
1.30      cvs       809:       attrType.AttrSSchema = TtaGetDocumentSSchema (context->doc);
                    810:       attrType.AttrTypeNum = pHTMLAttributeMapping[0].ThotAttribute;
1.37      cvs       811:       sprintf (msgBuffer, "type=%s", val);
1.30      cvs       812:       CreateHTMLAttribute (context->lastElement, attrType, msgBuffer, TRUE,
                    813:                           context->doc, &lastAttribute, &lastAttrElement);
                    814:     }
                    815:   else
                    816:     {
                    817:       elType = TtaGetElementType (context->lastElement);
                    818:       if (elType.ElTypeNum != HTML_EL_Input)
                    819:        {
1.37      cvs       820:          if (strlen (val) > MaxMsgLength - 40)
                    821:            val[MaxMsgLength - 40] = EOS;
                    822:          sprintf (msgBuffer, "Duplicate attribute \"type = %s\"", val);
1.30      cvs       823:        }
                    824:       else
                    825:        {
                    826:          elType.ElSSchema = TtaGetDocumentSSchema (context->doc);
                    827:          elType.ElTypeNum = value;
                    828:          newChild = TtaNewTree (context->doc, elType, "");
                    829:          numberOfLinesRead = 0;
                    830:          TtaSetElementLineNumber (newChild, numberOfLinesRead);
                    831:          TtaInsertFirstChild (&newChild, context->lastElement, context->doc);
                    832:          if (value == HTML_EL_PICTURE_UNIT)
                    833:            {
                    834:              /* add the attribute IsInput to input pictures */
                    835:              attrType.AttrSSchema = elType.ElSSchema;
                    836:              attrType.AttrTypeNum = HTML_ATTR_IsInput;
                    837:              attr = TtaNewAttribute (attrType);
                    838:              TtaAttachAttribute (newChild, attr, context->doc);
                    839:            }
                    840:        }
                    841:     }
                    842: }
                    843: 
                    844: /*----------------------------------------------------------------------
                    845:    XhtmlTypeAttrValue 
                    846:    Value val has been read for the HTML attribute TYPE.
                    847:    Create a child for the current Thot element INPUT accordingly.
                    848:   ----------------------------------------------------------------------*/
1.46      cvs       849: void              XhtmlTypeAttrValue (char       *val,
1.30      cvs       850:                                      Attribute   currentAttribute,
                    851:                                      Element     lastAttrElement,
                    852:                                      ParserData *context)
                    853: 
                    854: {
                    855:   ElementType     elType;
                    856:   Element         newChild;
                    857:   AttributeType   attrType;
                    858:   Attribute       attr;
1.39      cvs       859:   char            msgBuffer[MaxMsgLength];
1.30      cvs       860:   int             value;
                    861:   ThotBool        level;
                    862: 
                    863:   attrType.AttrTypeNum = DummyAttribute;
                    864:   MapHTMLAttributeValue (val, attrType, &value);
                    865:   if (value < 0)
                    866:     {
1.37      cvs       867:       sprintf (msgBuffer, "Unknown attribute value \"type=%s\"", val);
1.30      cvs       868:       XmlParseError (errorParsing, msgBuffer, 0);
1.36      cvs       869:       MapHTMLAttribute ("unknown_attr", &attrType, NULL,
1.30      cvs       870:                        &level, context->doc);
1.37      cvs       871:       sprintf (msgBuffer, "type=%s", val);
1.30      cvs       872:       CreateHTMLAttribute (context->lastElement, attrType, msgBuffer, TRUE,
                    873:                           context->doc, &currentAttribute, &lastAttrElement);
                    874:     }
                    875:   else
                    876:     {
                    877:       elType = TtaGetElementType (context->lastElement);
                    878:       if (elType.ElTypeNum != HTML_EL_Input)
                    879:        {
1.37      cvs       880:          sprintf (msgBuffer, "Duplicate attribute \"type = %s\"", val);
1.30      cvs       881:          XmlParseError (errorParsing, msgBuffer, 0);
                    882:        }
                    883:       else
                    884:        {
                    885:          elType.ElTypeNum = value;
                    886:          newChild = TtaNewTree (context->doc, elType, "");
                    887:          XmlSetElemLineNumber (newChild);
                    888:          TtaInsertFirstChild (&newChild, context->lastElement, context->doc);
                    889:          if (value == HTML_EL_PICTURE_UNIT)
                    890:            {
                    891:              /* add the attribute IsInput to input pictures */
                    892:              attrType.AttrSSchema = elType.ElSSchema;
                    893:              attrType.AttrTypeNum = HTML_ATTR_IsInput;
                    894:              attr = TtaNewAttribute (attrType);
                    895:              TtaAttachAttribute (newChild, attr, context->doc);
                    896:            }
                    897:        }
                    898:     }
                    899: }
                    900: 
                    901: /*----------------------------------------------------------------------
                    902:    CreateAttrWidthPercentPxl
                    903:    an HTML attribute "width" has been created for a Table of a HR.
                    904:    Create the corresponding attribute IntWidthPercent or IntWidthPxl.
                    905:    oldWidth is -1 or the old image width.
                    906:   ----------------------------------------------------------------------*/
1.58      vatton    907: void CreateAttrWidthPercentPxl (char *buffer, Element el,
                    908:                                Document doc, int oldWidth)
1.30      cvs       909: {
                    910:   AttributeType   attrTypePxl, attrTypePercent;
                    911:   Attribute       attrOld, attrNew;
                    912:   int             length, val;
1.39      cvs       913:   char            msgBuffer[MaxMsgLength];
1.30      cvs       914:   ElementType    elType;
                    915:   int             w, h;
                    916:   ThotBool        isImage;
                    917: 
                    918:   elType = TtaGetElementType (el);
                    919:   isImage = (elType.ElTypeNum == HTML_EL_PICTURE_UNIT ||
                    920:             elType.ElTypeNum == HTML_EL_Data_cell ||
                    921:             elType.ElTypeNum == HTML_EL_Heading_cell);
                    922: 
                    923:   /* remove trailing spaces */
1.37      cvs       924:   length = strlen (buffer) - 1;
1.30      cvs       925:   while (length > 0 && buffer[length] <= SPACE)
                    926:     length--;
                    927:   attrTypePxl.AttrSSchema = TtaGetDocumentSSchema (doc);
                    928:   attrTypePercent.AttrSSchema = TtaGetDocumentSSchema (doc);
                    929:   attrTypePxl.AttrTypeNum = HTML_ATTR_IntWidthPxl;
                    930:   attrTypePercent.AttrTypeNum = HTML_ATTR_IntWidthPercent;
                    931:   /* is the last character a '%' ? */
                    932:   if (buffer[length] == '%')
                    933:     {
                    934:       /* remove IntWidthPxl */
                    935:       attrOld = TtaGetAttribute (el, attrTypePxl);
                    936:       /* update IntWidthPercent */
                    937:       attrNew = TtaGetAttribute (el, attrTypePercent);
                    938:       if (attrNew == NULL)
                    939:        {
                    940:          attrNew = TtaNewAttribute (attrTypePercent);
                    941:          TtaAttachAttribute (el, attrNew, doc);
                    942:        }
                    943:       else if (isImage && oldWidth == -1)
                    944:        {
                    945:          if (attrOld == NULL)
                    946:            oldWidth = TtaGetAttributeValue (attrNew);
                    947:          else
                    948:            oldWidth = TtaGetAttributeValue (attrOld);
                    949:        }
                    950:     }
                    951:   else
                    952:     {
                    953:       /* remove IntWidthPercent */
                    954:       attrOld = TtaGetAttribute (el, attrTypePercent);
                    955:       /* update IntWidthPxl */
                    956:       attrNew = TtaGetAttribute (el, attrTypePxl);
                    957:       if (attrNew == NULL)
                    958:        {
                    959:          attrNew = TtaNewAttribute (attrTypePxl);
                    960:          TtaAttachAttribute (el, attrNew, doc);
                    961:        }
                    962:       else if (isImage && oldWidth == -1)
                    963:        {
                    964:          TtaGiveBoxSize (el, doc, 1, UnPixel, &w, &h);
                    965:          if (attrOld == NULL)
                    966:            oldWidth = w * TtaGetAttributeValue (attrNew) / 100;
                    967:          else
                    968:            oldWidth = w * TtaGetAttributeValue (attrOld) / 100;          
                    969:        }
                    970:     }
                    971: 
                    972:   if (attrOld != NULL)
                    973:     TtaRemoveAttribute (el, attrOld, doc);
1.43      cvs       974:   if (sscanf (buffer, "%d", &val))
1.30      cvs       975:     TtaSetAttributeValue (attrNew, val, el, doc);
                    976:   else
                    977:     /* its not a number. Delete attribute and send an error message */
                    978:     {
                    979:     TtaRemoveAttribute (el, attrNew, doc);
1.37      cvs       980:     if (strlen (buffer) > MaxMsgLength - 30)
1.30      cvs       981:         buffer[MaxMsgLength - 30] = EOS;
1.37      cvs       982:     sprintf (msgBuffer, "Invalid attribute value \"%s\"", buffer);
1.42      cvs       983:     HTMLParseError (doc, msgBuffer);
1.30      cvs       984:     }
                    985:   if (isImage)
                    986:     UpdateImageMap (el, doc, oldWidth, -1);
                    987: }
                    988: 
                    989: /*----------------------------------------------------------------------
1.58      vatton    990:    CreateAttrHeightPercentPxl
                    991:    an HTML attribute "width" has been created for a Table of a HR.
                    992:    Create the corresponding attribute IntHeightPercent or IntHeightPxl.
                    993:    oldHeight is -1 or the old image width.
                    994:   ----------------------------------------------------------------------*/
                    995: void CreateAttrHeightPercentPxl (char *buffer, Element el,
                    996:                                Document doc, int oldHeight)
                    997: {
                    998:   AttributeType   attrTypePxl, attrTypePercent;
                    999:   Attribute       attrOld, attrNew;
                   1000:   int             length, val;
                   1001:   char            msgBuffer[MaxMsgLength];
                   1002:   ElementType    elType;
                   1003:   int             w, h;
                   1004:   ThotBool        isImage;
                   1005: 
                   1006:   elType = TtaGetElementType (el);
                   1007:   isImage = (elType.ElTypeNum == HTML_EL_PICTURE_UNIT ||
                   1008:             elType.ElTypeNum == HTML_EL_Data_cell ||
                   1009:             elType.ElTypeNum == HTML_EL_Heading_cell);
                   1010: 
                   1011:   /* remove trailing spaces */
                   1012:   length = strlen (buffer) - 1;
                   1013:   while (length > 0 && buffer[length] <= SPACE)
                   1014:     length--;
                   1015:   attrTypePxl.AttrSSchema = TtaGetDocumentSSchema (doc);
                   1016:   attrTypePercent.AttrSSchema = TtaGetDocumentSSchema (doc);
                   1017:   attrTypePxl.AttrTypeNum = HTML_ATTR_IntHeightPxl;
                   1018:   attrTypePercent.AttrTypeNum = HTML_ATTR_IntHeightPercent;
                   1019:   /* is the last character a '%' ? */
                   1020:   if (buffer[length] == '%')
                   1021:     {
                   1022:       /* remove IntHeightPxl */
                   1023:       attrOld = TtaGetAttribute (el, attrTypePxl);
                   1024:       /* update IntHeightPercent */
                   1025:       attrNew = TtaGetAttribute (el, attrTypePercent);
                   1026:       if (attrNew == NULL)
                   1027:        {
                   1028:          attrNew = TtaNewAttribute (attrTypePercent);
                   1029:          TtaAttachAttribute (el, attrNew, doc);
                   1030:        }
                   1031:       else if (isImage && oldHeight == -1)
                   1032:        {
                   1033:          if (attrOld == NULL)
                   1034:            oldHeight = TtaGetAttributeValue (attrNew);
                   1035:          else
                   1036:            oldHeight = TtaGetAttributeValue (attrOld);
                   1037:        }
                   1038:     }
                   1039:   else
                   1040:     {
                   1041:       /* remove IntHeightPercent */
                   1042:       attrOld = TtaGetAttribute (el, attrTypePercent);
                   1043:       /* update IntHeightPxl */
                   1044:       attrNew = TtaGetAttribute (el, attrTypePxl);
                   1045:       if (attrNew == NULL)
                   1046:        {
                   1047:          attrNew = TtaNewAttribute (attrTypePxl);
                   1048:          TtaAttachAttribute (el, attrNew, doc);
                   1049:        }
                   1050:       else if (isImage && oldHeight == -1)
                   1051:        {
                   1052:          TtaGiveBoxSize (el, doc, 1, UnPixel, &w, &h);
                   1053:          if (attrOld == NULL)
                   1054:            oldHeight = w * TtaGetAttributeValue (attrNew) / 100;
                   1055:          else
                   1056:            oldHeight = w * TtaGetAttributeValue (attrOld) / 100;         
                   1057:        }
                   1058:     }
                   1059: 
                   1060:   if (attrOld != NULL)
                   1061:     TtaRemoveAttribute (el, attrOld, doc);
                   1062:   if (sscanf (buffer, "%d", &val))
                   1063:     TtaSetAttributeValue (attrNew, val, el, doc);
                   1064:   else
                   1065:     /* its not a number. Delete attribute and send an error message */
                   1066:     {
                   1067:     TtaRemoveAttribute (el, attrNew, doc);
                   1068:     if (strlen (buffer) > MaxMsgLength - 30)
                   1069:         buffer[MaxMsgLength - 30] = EOS;
                   1070:     sprintf (msgBuffer, "Invalid attribute value \"%s\"", buffer);
                   1071:     HTMLParseError (doc, msgBuffer);
                   1072:     }
                   1073:   if (isImage)
                   1074:     UpdateImageMap (el, doc, oldHeight, -1);
                   1075: }
                   1076: 
                   1077: /*----------------------------------------------------------------------
1.30      cvs      1078:    CreateAttrIntSize
                   1079:    an HTML attribute "size" has been created for a Font element.
                   1080:    Create the corresponding internal attribute.
                   1081:   ----------------------------------------------------------------------*/
1.46      cvs      1082: void              CreateAttrIntSize (char *buffer, Element el, Document doc)
1.30      cvs      1083: 
                   1084: {
                   1085:    AttributeType  attrType;
                   1086:    int            val, ind, factor, delta;
                   1087:    Attribute      attr;
1.37      cvs      1088:    char         msgBuffer[MaxMsgLength];
1.30      cvs      1089: 
                   1090:    /* is the first character a '+' or a '-' ? */
                   1091:    ind = 0;
                   1092:    factor = 1;
                   1093:    delta = 0;
                   1094:    if (buffer[0] == '+')
                   1095:      {
                   1096:        attrType.AttrTypeNum = HTML_ATTR_IntSizeIncr;
                   1097:        ind++;
                   1098:        factor = 2;
                   1099:      }
                   1100:    else if (buffer[0] == '-')
                   1101:      {
                   1102:        attrType.AttrTypeNum = HTML_ATTR_IntSizeDecr;
                   1103:        ind++;
                   1104:        factor = 2;
                   1105:      }
                   1106:    else
                   1107:      {
                   1108:        attrType.AttrTypeNum = HTML_ATTR_IntSizeRel;
                   1109:        delta = 1;
                   1110:      }
                   1111:    attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
                   1112:    attr = TtaGetAttribute (el, attrType);
1.43      cvs      1113:    if (sscanf (&buffer[ind], "%d", &val))
1.30      cvs      1114:      {
                   1115:        val = val * factor + delta;
                   1116:        if (attr == NULL)
                   1117:         {
                   1118:           /* this attribute doesn't exist, create it */
                   1119:           attr = TtaNewAttribute (attrType);
                   1120:           TtaAttachAttribute (el, attr, doc);
                   1121:         }
                   1122:        TtaSetAttributeValue (attr, val, el, doc);
                   1123:      }
                   1124:    else
                   1125:      /* its not a number. Delete attribute and send an error message */
                   1126:      {
                   1127:        if (attr)
                   1128:          TtaRemoveAttribute (el, attr, doc);
1.37      cvs      1129:        if (strlen (buffer) > MaxMsgLength - 30)
1.30      cvs      1130:          buffer[MaxMsgLength - 30] = EOS;
1.37      cvs      1131:        sprintf (msgBuffer, "Invalid attribute value \"%s\"", buffer);
1.42      cvs      1132:        HTMLParseError (doc, msgBuffer);
1.30      cvs      1133:      }
                   1134: }
                   1135: /*----------------------------------------------------------------------
                   1136:    EndOfHTMLAttributeValue
                   1137:    Filling of an HTML attribute value
                   1138:   ----------------------------------------------------------------------*/
1.48      vatton   1139: void EndOfHTMLAttributeValue (char *attrValue,
                   1140:                              AttributeMapping *lastMappedAttr,
                   1141:                              Attribute currentAttribute,
                   1142:                              Element lastAttrElement,
                   1143:                              ThotBool UnknownAttr,
                   1144:                              ParserData *context,
                   1145:                              ThotBool isXML)
1.30      cvs      1146: {
1.48      vatton   1147:   AttributeType   attrType, attrType1;
                   1148:   Attribute       attr;
                   1149:   ElementType     elType;
                   1150:   Element         child, root;
                   1151:   Language        lang;
                   1152:   char            translation;
                   1153:   char            shape;
                   1154:   char           *buffer;
                   1155:   char           *attrName;
                   1156:   char            msgBuffer[MaxMsgLength];
                   1157:   int             val;
                   1158:   int             length;
                   1159:   int             attrKind;
                   1160:   ThotBool        done = FALSE;
1.30      cvs      1161: 
1.48      vatton   1162:   /* treatments of some particular HTML attributes */
                   1163:   if (!strcmp (lastMappedAttr->XMLattribute, "style"))
                   1164:     {
                   1165:       TtaSetAttributeText (currentAttribute, attrValue,
                   1166:                           lastAttrElement, context->doc);
                   1167:       ParseHTMLSpecificStyle (context->lastElement, attrValue,
1.61      quint    1168:                              context->doc, 100, FALSE);
1.48      vatton   1169:       done = TRUE;
                   1170:     }
                   1171:   else
                   1172:     {
                   1173:       if (!strcmp (lastMappedAttr->XMLattribute, "link"))
                   1174:        HTMLSetAlinkColor (context->doc, attrValue);
                   1175:       else if (!strcmp (lastMappedAttr->XMLattribute, "alink"))
                   1176:        HTMLSetAactiveColor (context->doc, attrValue);
                   1177:       else if (!strcmp (lastMappedAttr->XMLattribute, "vlink"))
                   1178:        HTMLSetAvisitedColor (context->doc, attrValue);
                   1179:     }
1.30      cvs      1180: 
1.48      vatton   1181:   if (!done)
                   1182:     {
                   1183:       val = 0;
                   1184:       translation = lastMappedAttr->AttrOrContent;
                   1185:       switch (translation)
                   1186:        {
                   1187:        case 'C':       /* Content */
                   1188:          child = PutInContent (attrValue, context);
                   1189:          if (child != NULL)
                   1190:            TtaAppendTextContent (child, "\" ", context->doc);
                   1191:          break;
                   1192:          
                   1193:        case 'A':
                   1194:          if (currentAttribute != NULL)
                   1195:            {
                   1196:              TtaGiveAttributeType (currentAttribute, &attrType, &attrKind);
                   1197:              switch (attrKind)
                   1198:                {
                   1199:                case 0: /* enumerate */
                   1200:                  if (isXML)
                   1201:                    MapHTMLAttributeValue (attrValue, attrType, &val);
                   1202:                  else
                   1203:                    val = MapAttrValue (lastMappedAttr->ThotAttribute,
1.40      cvs      1204:                                        attrValue);
1.48      vatton   1205:                  if (val < 0)
                   1206:                    {
                   1207:                      TtaGiveAttributeType (currentAttribute,
                   1208:                                            &attrType, &attrKind);
                   1209:                      attrName = TtaGetAttributeName (attrType);
                   1210:                      sprintf (msgBuffer,
1.51      cvs      1211:                               "Invalid attribute value \"%s = %s\"",
1.48      vatton   1212:                               attrName, attrValue);
                   1213:                      if (isXML)
                   1214:                        XmlParseError (errorParsing, msgBuffer, 0);
                   1215:                      else
1.51      cvs      1216:                        {
                   1217:                          HTMLParseError (context->doc, msgBuffer);
1.48      vatton   1218:                      /* remove the attribute and replace it by an */
1.51      cvs      1219:                      /* Invalid_attribute (not for XHTML) */
                   1220:                          TtaRemoveAttribute (lastAttrElement,
                   1221:                                              currentAttribute, context->doc);
1.48      vatton   1222:                          attrType.AttrSSchema = 
                   1223:                            TtaGetDocumentSSchema (context->doc);
                   1224:                          attrType.AttrTypeNum =
                   1225:                            pHTMLAttributeMapping[0].ThotAttribute;
1.51      cvs      1226:                          sprintf (msgBuffer, "%s=%s", attrName, attrValue);
                   1227:                          CreateHTMLAttribute (lastAttrElement, attrType,
                   1228:                                               msgBuffer, TRUE, context->doc,
                   1229:                                               &currentAttribute,
                   1230:                                               &lastAttrElement);
1.48      vatton   1231:                        }
                   1232:                    }
                   1233:                  else
                   1234:                    TtaSetAttributeValue (currentAttribute, val,
                   1235:                                          lastAttrElement, context->doc);
                   1236:                  break;
                   1237:                case 1: /* integer */
                   1238:                  if (attrType.AttrTypeNum == HTML_ATTR_Border &&
                   1239:                      !strcasecmp (attrValue, "border"))
                   1240:                    {
                   1241:                      /* border="border" for a table */
                   1242:                      val = 1;
                   1243:                      TtaSetAttributeValue (currentAttribute, val,
1.30      cvs      1244:                                            lastAttrElement, context->doc);
1.48      vatton   1245:                    }
                   1246:                  else if (sscanf (attrValue, "%d", &val))
                   1247:                    TtaSetAttributeValue (currentAttribute, val,
                   1248:                                          lastAttrElement, context->doc);
                   1249:                  else
                   1250:                    {
                   1251:                      TtaRemoveAttribute (lastAttrElement, currentAttribute,
                   1252:                                          context->doc);
                   1253:                      sprintf (msgBuffer,
                   1254:                               "Unknown attribute value \"%s\"",
                   1255:                               attrValue);
                   1256:                      if (isXML)
                   1257:                        XmlParseError (errorParsing, msgBuffer, 0);
                   1258:                      else
                   1259:                        HTMLParseError (context->doc, msgBuffer);
                   1260:                    }
                   1261:                  break;
                   1262:                case 2: /* text */
                   1263:                  if (!UnknownAttr)
                   1264:                    {
                   1265:                      TtaSetAttributeText (currentAttribute, attrValue,
                   1266:                                           lastAttrElement, context->doc);
1.55      cvs      1267:                      if (attrType.AttrTypeNum == HTML_ATTR_Language)
1.48      vatton   1268:                        {
                   1269:                          /* it's a LANG attribute value */
                   1270:                          lang = TtaGetLanguageIdFromName (attrValue);
                   1271:                          if (lang == 0)
                   1272:                            {
                   1273:                              sprintf (msgBuffer,
                   1274:                                       "warning - unsupported language: %s",
                   1275:                                       attrValue);
                   1276:                              if (isXML)
                   1277:                                XmlParseError (errorParsing, msgBuffer, 0);
                   1278:                              else
                   1279:                                HTMLParseError (context->doc, msgBuffer);
                   1280:                            }
                   1281:                          else
                   1282:                            {
                   1283:                              /* change current language */
                   1284:                              context->language = lang;
                   1285:                              if (isXML)
                   1286:                                SetLanguagInXmlStack (lang);
                   1287:                              else
                   1288:                                SetLanguagInHTMLStack (lang);
                   1289:                            }
                   1290:                          root = TtaGetRootElement (context->doc);
                   1291:                          if (lastAttrElement == root)
                   1292:                            /* it's a LANG attribute on the root element */
                   1293:                            /* set the RealLang attribute */
                   1294:                            {
                   1295:                              attrType1.AttrSSchema = TtaGetDocumentSSchema (context->doc);
                   1296:                              attrType1.AttrTypeNum = HTML_ATTR_RealLang;
                   1297:                              /* this attribute could be already present,
                   1298:                                 (lang and xml:lang attributes) */
                   1299:                              if (!TtaGetAttribute (lastAttrElement,
                   1300:                                                    attrType1))
                   1301:                                /* it's not present. Add it */
                   1302:                                {
                   1303:                                  attr = TtaNewAttribute (attrType1);
                   1304:                                  TtaAttachAttribute (lastAttrElement,
                   1305:                                                      attr, context->doc);
                   1306:                                  TtaSetAttributeValue (attr,
                   1307:                                                        HTML_ATTR_RealLang_VAL_Yes_,
                   1308:                                                        lastAttrElement,
                   1309:                                                        context->doc);
                   1310:                                }
                   1311:                            }
                   1312:                        }
                   1313:                      else if (attrType.AttrTypeNum == HTML_ATTR_accesskey)
                   1314:                        TtaAddAccessKey (context->doc, (unsigned int)attrValue[0],
                   1315:                                         lastAttrElement);
                   1316:                    }
                   1317:                  else
                   1318:                    {
1.51      cvs      1319:                      /* this is the content of an invalid attribute */
                   1320:                      /* append it to the current Invalid_attribute */
                   1321:                      if (!isXML)
                   1322:                        {
                   1323:                          length = strlen (attrValue) + 2;
                   1324:                          length += TtaGetTextAttributeLength (currentAttribute);
                   1325:                          buffer = TtaGetMemory (length + 1);
                   1326:                          TtaGiveTextAttributeValue (currentAttribute,
                   1327:                                                     buffer, &length);
                   1328:                          strcat (buffer, "=");
                   1329:                          strcat (buffer, attrValue);
                   1330:                          TtaSetAttributeText (currentAttribute, buffer,
                   1331:                                               lastAttrElement, context->doc);
                   1332:                          TtaFreeMemory (buffer);
                   1333:                        }
1.48      vatton   1334:                    }
                   1335:                  break;
                   1336:                case 3: /* reference */
                   1337:                  break;
                   1338:                }
                   1339:            }
                   1340:          break;
                   1341:          
                   1342:        case SPACE:
                   1343:          if (isXML)
                   1344:            XhtmlTypeAttrValue (attrValue, currentAttribute,
1.30      cvs      1345:                                lastAttrElement, context);
1.48      vatton   1346:          else
                   1347:            HTMLTypeAttrValue (attrValue, currentAttribute,
                   1348:                               lastAttrElement, context);
                   1349:          break;
                   1350:          
1.30      cvs      1351:         default:
                   1352:           break;
1.48      vatton   1353:        }
1.30      cvs      1354: 
                   1355:       if (lastMappedAttr->ThotAttribute == HTML_ATTR_Width__)
1.48      vatton   1356:        /* HTML attribute "width" for a table or a hr */
                   1357:        /* create the corresponding attribute IntWidthPercent or */
                   1358:        /* IntWidthPxl */
                   1359:        CreateAttrWidthPercentPxl (attrValue, lastAttrElement, context->doc, -1);
1.58      vatton   1360:       else if (lastMappedAttr->ThotAttribute == HTML_ATTR_Height_)
                   1361:        /* HTML attribute "width" for a table or a hr */
                   1362:        /* create the corresponding attribute IntHeightPercent or */
                   1363:        /* IntHeightPxl */
                   1364:        CreateAttrHeightPercentPxl (attrValue, lastAttrElement, context->doc, -1);
1.48      vatton   1365:       else if (!strcmp (lastMappedAttr->XMLattribute, "size"))
                   1366:        {
                   1367:          TtaGiveAttributeType (currentAttribute, &attrType, &attrKind);
                   1368:          if (attrType.AttrTypeNum == HTML_ATTR_Font_size)
                   1369:            CreateAttrIntSize (attrValue, lastAttrElement, context->doc);
                   1370:        }
                   1371:       else if (!strcmp (lastMappedAttr->XMLattribute, "shape"))
                   1372:        {
                   1373:          child = TtaGetFirstChild (lastAttrElement);
                   1374:          if (child != NULL)
                   1375:            {
                   1376:              switch (val)
                   1377:                {
                   1378:                case HTML_ATTR_shape_VAL_rectangle:
                   1379:                  shape = 'R';
                   1380:                  break;
                   1381:                case HTML_ATTR_shape_VAL_circle:
                   1382:                  shape = 'a';
                   1383:                  break;
                   1384:                case HTML_ATTR_shape_VAL_polygon:
                   1385:                  shape = 'p';
                   1386:                  break;
                   1387:                default:
                   1388:                  shape = SPACE;
                   1389:                  break;
                   1390:                }
                   1391:              TtaSetGraphicsShape (child, shape, context->doc);
                   1392:            }
                   1393:        }
                   1394:       else if (!strcmp (lastMappedAttr->XMLattribute, "value"))
                   1395:        {
                   1396:          elType = TtaGetElementType (lastAttrElement);
                   1397:          if (elType.ElTypeNum == HTML_EL_Text_Input ||
                   1398:              elType.ElTypeNum == HTML_EL_Password_Input ||
                   1399:              elType.ElTypeNum == HTML_EL_File_Input ||
                   1400:              elType.ElTypeNum == HTML_EL_Input)
                   1401:            /* create a Default_Value attribute with the same content */
                   1402:            {
                   1403:              attrType1.AttrSSchema = attrType.AttrSSchema;
                   1404:              attrType1.AttrTypeNum = HTML_ATTR_Default_Value;
                   1405:              attr = TtaNewAttribute (attrType1);
                   1406:              TtaAttachAttribute (lastAttrElement, attr, context->doc);
                   1407:              TtaSetAttributeText (attr, attrValue,
                   1408:                                   lastAttrElement, context->doc);
                   1409:            }
                   1410:        }
1.30      cvs      1411:       else
1.48      vatton   1412:        {
                   1413:          /* Some HTML attributes are equivalent to a CSS property:      */
                   1414:          /*      background     ->                   background         */
                   1415:          /*      bgcolor        ->                   background         */
                   1416:          /*      text           ->                   color              */
                   1417:          /*      color          ->                   color              */
                   1418:          if (!strcmp (lastMappedAttr->XMLattribute, "background"))
                   1419:            {
                   1420:              if (strlen (attrValue) > MaxMsgLength - 30)
                   1421:                attrValue[MaxMsgLength - 30] = EOS;
                   1422:              HTMLSetBackgroundImage (context->doc,
                   1423:                                      context->lastElement, STYLE_REPEAT, attrValue);
                   1424:            }
                   1425:          else if (!strcmp (lastMappedAttr->XMLattribute, "bgcolor"))
                   1426:            HTMLSetBackgroundColor (context->doc,
                   1427:                                    context->lastElement, attrValue);
                   1428:          else if (!strcmp (lastMappedAttr->XMLattribute, "text") ||
                   1429:                   !strcmp (lastMappedAttr->XMLattribute, "color"))
                   1430:            HTMLSetForegroundColor (context->doc,
                   1431:                                    context->lastElement, attrValue);
                   1432:        }
                   1433:     }
1.30      cvs      1434: }
                   1435: 
                   1436: /*----------------------------------------------------------------------
1.16      cvs      1437:    MapHTMLAttributeValue
1.2       cvs      1438:    Search in the Attribute Value Mapping Table the entry for the attribute
1.66    ! vatton   1439:    ThotAtt and its value attVal. Returns the corresponding Thot value.
1.1       cvs      1440:   ----------------------------------------------------------------------*/
1.66    ! vatton   1441: void MapHTMLAttributeValue (char *attVal, AttributeType attrType, int *value)
1.1       cvs      1442: {
1.66    ! vatton   1443:   MapXMLAttributeValue (XHTML_TYPE, attVal, attrType, value);
1.1       cvs      1444: }

Webmaster