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

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

Webmaster