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

1.1       cvs         1: /*
                      2:  *
1.30    ! cvs         3:  *  (c) COPYRIGHT MIT and INRIA, 1996-2001.
1.1       cvs         4:  *  Please first read the full copyright statement in file COPYRIGHT.
                      5:  *
                      6:  */
                      7: 
                      8: /*
1.30    ! cvs         9:  * XHTMLbuilder.c
1.23      cvs        10:  * Builds the corresponding abstract tree for a Thot document of type HTML.
1.1       cvs        11:  *
1.20      cvs        12:  * Authors: L. Carcone
                     13:  *          V. Quint 
1.1       cvs        14:  */
                     15: 
                     16: #define THOT_EXPORT extern
                     17: #include "amaya.h"
                     18: #include "css.h"
1.2       cvs        19: #include "parser.h"
                     20: #include "HTML.h"
1.30    ! cvs        21: #include "fetchHTMLname.h"
1.2       cvs        22: 
1.13      cvs        23: #include "css_f.h"
                     24: #include "fetchXMLname_f.h"
1.30    ! cvs        25: #include "fetchHTMLname_f.h"
1.22      cvs        26: #include "html2thot_f.h"
1.1       cvs        27: #include "HTMLactions_f.h"
                     28: #include "HTMLedit_f.h"
1.22      cvs        29: #include "HTMLform_f.h"
1.1       cvs        30: #include "HTMLimage_f.h"
                     31: #include "HTMLtable_f.h"
                     32: #include "HTMLimage_f.h"
                     33: #include "UIcss_f.h"
1.13      cvs        34: #include "styleparser_f.h"
1.2       cvs        35: #include "XHTMLbuilder_f.h"
1.13      cvs        36: #include "Xml2thot_f.h"
1.1       cvs        37: 
                     38: /* maximum length of a Thot structure schema name */
                     39: #define MAX_SS_NAME_LENGTH 32
                     40: 
1.30    ! cvs        41: #define MaxMsgLength 200
        !            42: 
1.14      cvs        43: /* Mapping table of HTML attribute values */
                     44: AttrValueMapping XhtmlAttrValueMappingTable[] =
1.1       cvs        45: {
                     46:    {HTML_ATTR_dir, TEXT("ltr"), HTML_ATTR_dir_VAL_ltr},
                     47:    {HTML_ATTR_dir, TEXT("rtl"), HTML_ATTR_dir_VAL_rtl},
                     48: 
                     49:    {HTML_ATTR_TextAlign, TEXT("left"), HTML_ATTR_TextAlign_VAL_left_},
                     50:    {HTML_ATTR_TextAlign, TEXT("center"), HTML_ATTR_TextAlign_VAL_center_},
                     51:    {HTML_ATTR_TextAlign, TEXT("right"), HTML_ATTR_TextAlign_VAL_right_},
                     52:    {HTML_ATTR_TextAlign, TEXT("justify"), HTML_ATTR_TextAlign_VAL_justify_},
                     53: 
                     54:    {HTML_ATTR_Align, TEXT("left"), HTML_ATTR_Align_VAL_left_},
                     55:    {HTML_ATTR_Align, TEXT("center"), HTML_ATTR_Align_VAL_center_},
                     56:    {HTML_ATTR_Align, TEXT("right"), HTML_ATTR_Align_VAL_right_},
                     57: 
                     58:    {HTML_ATTR_LAlign, TEXT("top"), HTML_ATTR_LAlign_VAL_Top_},
                     59:    {HTML_ATTR_LAlign, TEXT("bottom"), HTML_ATTR_LAlign_VAL_Bottom_},
                     60:    {HTML_ATTR_LAlign, TEXT("left"), HTML_ATTR_LAlign_VAL_Left_},
                     61:    {HTML_ATTR_LAlign, TEXT("right"), HTML_ATTR_LAlign_VAL_Right_},
                     62: 
                     63:    {HTML_ATTR_Clear, TEXT("left"), HTML_ATTR_Clear_VAL_Left_},
                     64:    {HTML_ATTR_Clear, TEXT("right"), HTML_ATTR_Clear_VAL_Right_},
                     65:    {HTML_ATTR_Clear, TEXT("all"), HTML_ATTR_Clear_VAL_All_},
                     66:    {HTML_ATTR_Clear, TEXT("none"), HTML_ATTR_Clear_VAL_None_},
                     67: 
                     68:    {HTML_ATTR_NumberStyle, TEXT("1"), HTML_ATTR_NumberStyle_VAL_Arabic_},
                     69:    {HTML_ATTR_NumberStyle, TEXT("a"), HTML_ATTR_NumberStyle_VAL_LowerAlpha},
                     70:    {HTML_ATTR_NumberStyle, TEXT("A"), HTML_ATTR_NumberStyle_VAL_UpperAlpha},
                     71:    {HTML_ATTR_NumberStyle, TEXT("i"), HTML_ATTR_NumberStyle_VAL_LowerRoman},
                     72:    {HTML_ATTR_NumberStyle, TEXT("I"), HTML_ATTR_NumberStyle_VAL_UpperRoman},
                     73: 
                     74:    {HTML_ATTR_BulletStyle, TEXT("disc"), HTML_ATTR_BulletStyle_VAL_disc},
                     75:    {HTML_ATTR_BulletStyle, TEXT("square"), HTML_ATTR_BulletStyle_VAL_square},
                     76:    {HTML_ATTR_BulletStyle, TEXT("circle"), HTML_ATTR_BulletStyle_VAL_circle},
                     77: 
                     78:    {HTML_ATTR_ItemStyle, TEXT("1"), HTML_ATTR_ItemStyle_VAL_Arabic_},
                     79:    {HTML_ATTR_ItemStyle, TEXT("a"), HTML_ATTR_ItemStyle_VAL_LowerAlpha},
                     80:    {HTML_ATTR_ItemStyle, TEXT("A"), HTML_ATTR_ItemStyle_VAL_UpperAlpha},
                     81:    {HTML_ATTR_ItemStyle, TEXT("i"), HTML_ATTR_ItemStyle_VAL_LowerRoman},
                     82:    {HTML_ATTR_ItemStyle, TEXT("I"), HTML_ATTR_ItemStyle_VAL_UpperRoman},
                     83:    {HTML_ATTR_ItemStyle, TEXT("disc"), HTML_ATTR_ItemStyle_VAL_disc},
                     84:    {HTML_ATTR_ItemStyle, TEXT("square"), HTML_ATTR_ItemStyle_VAL_square},
                     85:    {HTML_ATTR_ItemStyle, TEXT("circle"), HTML_ATTR_ItemStyle_VAL_circle},
                     86: 
                     87:    {HTML_ATTR_Button_type, TEXT("button"), HTML_ATTR_Button_type_VAL_button},
                     88:    {HTML_ATTR_Button_type, TEXT("submit"), HTML_ATTR_Button_type_VAL_submit},
                     89:    {HTML_ATTR_Button_type, TEXT("reset"), HTML_ATTR_Button_type_VAL_reset},
                     90: 
                     91:    {HTML_ATTR_frame, TEXT("void"), HTML_ATTR_frame_VAL_void},
                     92:    {HTML_ATTR_frame, TEXT("above"), HTML_ATTR_frame_VAL_above},
                     93:    {HTML_ATTR_frame, TEXT("below"), HTML_ATTR_frame_VAL_below},
                     94:    {HTML_ATTR_frame, TEXT("hsides"), HTML_ATTR_frame_VAL_hsides},
                     95:    {HTML_ATTR_frame, TEXT("lhs"), HTML_ATTR_frame_VAL_lhs},
                     96:    {HTML_ATTR_frame, TEXT("rhs"), HTML_ATTR_frame_VAL_rhs},
                     97:    {HTML_ATTR_frame, TEXT("vsides"), HTML_ATTR_frame_VAL_vsides},
                     98:    {HTML_ATTR_frame, TEXT("box"), HTML_ATTR_frame_VAL_box},
                     99:    {HTML_ATTR_frame, TEXT("border"), HTML_ATTR_frame_VAL_border},
                    100: 
                    101:    {HTML_ATTR_frameborder, TEXT("0"), HTML_ATTR_frameborder_VAL_Border0},
                    102:    {HTML_ATTR_frameborder, TEXT("1"), HTML_ATTR_frameborder_VAL_Border1},
                    103: 
                    104:    {HTML_ATTR_scrolling, TEXT("yes"), HTML_ATTR_scrolling_VAL_Yes_},
                    105:    {HTML_ATTR_scrolling, TEXT("no"), HTML_ATTR_scrolling_VAL_No_},
                    106:    {HTML_ATTR_scrolling, TEXT("auto"), HTML_ATTR_scrolling_VAL_auto_},
                    107: 
                    108:    {HTML_ATTR_rules_, TEXT("none"), HTML_ATTR_rules__VAL_none_},
                    109:    {HTML_ATTR_rules_, TEXT("groups"), HTML_ATTR_rules__VAL_groups},
                    110:    {HTML_ATTR_rules_, TEXT("rows"), HTML_ATTR_rules__VAL_rows},
                    111:    {HTML_ATTR_rules_, TEXT("cols"), HTML_ATTR_rules__VAL_cols},
                    112:    {HTML_ATTR_rules_, TEXT("all"), HTML_ATTR_rules__VAL_all},
                    113: 
                    114:    {HTML_ATTR_Cell_align, TEXT("left"), HTML_ATTR_Cell_align_VAL_Cell_left},
                    115:    {HTML_ATTR_Cell_align, TEXT("center"), HTML_ATTR_Cell_align_VAL_Cell_center},
                    116:    {HTML_ATTR_Cell_align, TEXT("right"), HTML_ATTR_Cell_align_VAL_Cell_right},
                    117:    {HTML_ATTR_Cell_align, TEXT("justify"), HTML_ATTR_Cell_align_VAL_Cell_justify},
                    118:    {HTML_ATTR_Cell_align, TEXT("char"), HTML_ATTR_Cell_align_VAL_Cell_char},
                    119: 
                    120:    {HTML_ATTR_Alignment, TEXT("top"), HTML_ATTR_Alignment_VAL_Top_},
                    121:    {HTML_ATTR_Alignment, TEXT("middle"), HTML_ATTR_Alignment_VAL_Middle_},
                    122:    {HTML_ATTR_Alignment, TEXT("bottom"), HTML_ATTR_Alignment_VAL_Bottom_},
                    123:    {HTML_ATTR_Alignment, TEXT("left"), HTML_ATTR_Alignment_VAL_Left_},
                    124:    {HTML_ATTR_Alignment, TEXT("right"), HTML_ATTR_Alignment_VAL_Right_},
                    125: 
                    126:    {HTML_ATTR_METHOD, TEXT("get"), HTML_ATTR_METHOD_VAL_Get_},
                    127:    {HTML_ATTR_METHOD, TEXT("post"), HTML_ATTR_METHOD_VAL_Post_},
                    128: 
                    129:    {HTML_ATTR_Position, TEXT("top"), HTML_ATTR_Position_VAL_Position_top},
                    130:    {HTML_ATTR_Position, TEXT("bottom"), HTML_ATTR_Position_VAL_Position_bottom},
                    131:    {HTML_ATTR_Position, TEXT("left"), HTML_ATTR_Position_VAL_Position_left},
                    132:    {HTML_ATTR_Position, TEXT("right"), HTML_ATTR_Position_VAL_Position_right},
                    133: 
                    134:    {HTML_ATTR_Row_valign, TEXT("top"), HTML_ATTR_Row_valign_VAL_Row_top},
                    135:    {HTML_ATTR_Row_valign, TEXT("middle"), HTML_ATTR_Row_valign_VAL_Row_middle},
                    136:    {HTML_ATTR_Row_valign, TEXT("bottom"), HTML_ATTR_Row_valign_VAL_Row_bottom},
                    137:    {HTML_ATTR_Row_valign, TEXT("baseline"), HTML_ATTR_Row_valign_VAL_Row_baseline},
                    138: 
                    139:    {HTML_ATTR_Cell_valign, TEXT("top"), HTML_ATTR_Cell_valign_VAL_Cell_top},
                    140:    {HTML_ATTR_Cell_valign, TEXT("middle"), HTML_ATTR_Cell_valign_VAL_Cell_middle},
                    141:    {HTML_ATTR_Cell_valign, TEXT("bottom"), HTML_ATTR_Cell_valign_VAL_Cell_bottom},
                    142:    {HTML_ATTR_Cell_valign, TEXT("baseline"), HTML_ATTR_Cell_valign_VAL_Cell_baseline},
                    143: 
                    144:    {HTML_ATTR_shape, TEXT("rect"), HTML_ATTR_shape_VAL_rectangle},
                    145:    {HTML_ATTR_shape, TEXT("circle"), HTML_ATTR_shape_VAL_circle},
                    146:    {HTML_ATTR_shape, TEXT("poly"), HTML_ATTR_shape_VAL_polygon},
                    147: 
                    148:    {HTML_ATTR_valuetype, TEXT("data"), HTML_ATTR_valuetype_VAL_data_},
                    149:    {HTML_ATTR_valuetype, TEXT("ref"), HTML_ATTR_valuetype_VAL_ref},
                    150:    {HTML_ATTR_valuetype, TEXT("object"), HTML_ATTR_valuetype_VAL_object_},
                    151: 
                    152: /* HTML attribute TYPE generates a Thot element */
                    153:    {DummyAttribute, TEXT("button"), HTML_EL_Button_Input},
                    154:    {DummyAttribute, TEXT("checkbox"), HTML_EL_Checkbox_Input},
                    155:    {DummyAttribute, TEXT("file"), HTML_EL_File_Input},
                    156:    {DummyAttribute, TEXT("hidden"), HTML_EL_Hidden_Input},
                    157:    {DummyAttribute, TEXT("image"), HTML_EL_PICTURE_UNIT},
                    158:    {DummyAttribute, TEXT("password"), HTML_EL_Password_Input},
                    159:    {DummyAttribute, TEXT("radio"), HTML_EL_Radio_Input},
                    160:    {DummyAttribute, TEXT("reset"), HTML_EL_Reset_Input},
                    161:    {DummyAttribute, TEXT("submit"), HTML_EL_Submit_Input},
                    162:    {DummyAttribute, TEXT("text"), HTML_EL_Text_Input},
                    163: 
                    164: /* The following declarations allow the parser to accept boolean attributes */
                    165: /* written "checked=CHECKED"), for instance */
                    166:    {HTML_ATTR_ISMAP, TEXT("ismap"), HTML_ATTR_ISMAP_VAL_Yes_},
                    167:    {HTML_ATTR_nohref, TEXT("nohref"), HTML_ATTR_nohref_VAL_Yes_},
                    168:    {HTML_ATTR_COMPACT, TEXT("compact"), HTML_ATTR_COMPACT_VAL_Yes_},
                    169:    {HTML_ATTR_Multiple, TEXT("multiple"), HTML_ATTR_Multiple_VAL_Yes_},
                    170:    {HTML_ATTR_Selected, TEXT("selected"), HTML_ATTR_Selected_VAL_Yes_},
                    171:    {HTML_ATTR_Checked, TEXT("checked"), HTML_ATTR_Checked_VAL_Yes_},
                    172:    {HTML_ATTR_No_wrap, TEXT("nowrap"), HTML_ATTR_No_wrap_VAL_no_wrap},
                    173:    {HTML_ATTR_NoShade, TEXT("noshade"), HTML_ATTR_NoShade_VAL_NoShade_},
                    174:    {HTML_ATTR_declare, TEXT("declare"), HTML_ATTR_declare_VAL_Yes_},
                    175:    {HTML_ATTR_defer, TEXT("defer"), HTML_ATTR_defer_VAL_Yes_},
                    176:    {HTML_ATTR_disabled, TEXT("disabled"), HTML_ATTR_disabled_VAL_Yes_},
                    177:    {HTML_ATTR_readonly, TEXT("readonly"), HTML_ATTR_readonly_VAL_Yes_},
                    178:    {HTML_ATTR_no_resize, TEXT("noresize"), HTML_ATTR_no_resize_VAL_Yes_},
1.21      cvs       179: 
                    180:    /* XML attribute xml:space */
                    181:    {HTML_ATTR_xml_space, TEXT("default"), HTML_ATTR_xml_space_VAL_xml_space_default},
                    182:    {HTML_ATTR_xml_space, TEXT("preserve"), HTML_ATTR_xml_space_VAL_xml_space_preserve},
                    183: 
1.1       cvs       184:    {0, TEXT(""), 0}                    /* Last entry. Mandatory */
                    185: };
1.6       cvs       186: 
1.28      cvs       187: /* Define a pointer to let parser functions access the HTML entity table */
                    188: extern XmlEntity *pXhtmlEntityTable;
1.6       cvs       189: 
1.30    ! cvs       190: /* maximum size of error messages */
        !           191: #define MaxMsgLength 200
        !           192: 
1.6       cvs       193: /*----------------------------------------------------------------------
1.15      cvs       194:   ParseCharset:
1.6       cvs       195:   Parses the element HTTP-EQUIV and looks for the charset value.
                    196:   ----------------------------------------------------------------------*/
1.30    ! cvs       197: void             ParseCharset (Element el, Document doc) 
        !           198: 
1.6       cvs       199: {
1.15      cvs       200:    AttributeType attrType;
                    201:    Attribute     attr;
                    202:    SSchema       docSSchema;
                    203:    CHARSET       charset;
1.6       cvs       204:    CHAR_T       *text, *text2, *ptrText, *str;
                    205:    CHAR_T        charsetname[MAX_LENGTH];
1.15      cvs       206:    int           length;
1.6       cvs       207:    int           pos, index = 0;
                    208: 
1.15      cvs       209:    charset = TtaGetDocumentCharset (doc);
                    210:    if (charset != UNDEFINED_CHARSET)
                    211:      /* the charset was already defined by the http header */
                    212:      return;
1.6       cvs       213: 
                    214:    docSSchema = TtaGetDocumentSSchema (doc);
                    215:    attrType.AttrSSchema = docSSchema;
                    216:    attrType.AttrTypeNum = HTML_ATTR_http_equiv;
                    217:    attr = TtaGetAttribute (el, attrType);
                    218:    if (attr != NULL)
                    219:      {
                    220:        /* There is a HTTP-EQUIV attribute */
                    221:        length = TtaGetTextAttributeLength (attr);
                    222:        if (length > 0)
                    223:         {
                    224:           text = TtaAllocString (length + 1);
                    225:           TtaGiveTextAttributeValue (attr, text, &length);
                    226:           if (!ustrcasecmp (text, TEXT("content-type")))
                    227:             {
                    228:               attrType.AttrTypeNum = HTML_ATTR_meta_content;
                    229:               attr = TtaGetAttribute (el, attrType);
                    230:               if (attr != NULL)
                    231:                 {
                    232:                   length = TtaGetTextAttributeLength (attr);
                    233:                   if (length > 0)
                    234:                     {
                    235:                       text2 = TtaAllocString (length + 1);
                    236:                       TtaGiveTextAttributeValue (attr, text2, &length);
                    237:                       ptrText = text2;
                    238:                       while (*ptrText)
                    239:                         {
                    240:                           *ptrText = utolower (*ptrText);
                    241:                           ptrText++;
                    242:                         }
                    243:                       
                    244:                       str = ustrstr (text2, TEXT("charset="));
                    245:                       if (str)
                    246:                         {
                    247:                           pos = str - text2 + 8;
                    248:                           while (text2[pos] != WC_SPACE &&
                    249:                                  text2[pos] != WC_TAB && text2[pos] != WC_EOS)
                    250:                             charsetname[index++] = text2[pos++];
                    251:                           charsetname[index] = WC_EOS;
1.15      cvs       252:                           charset = TtaGetCharset (charsetname);
                    253:                           if (charset != UNDEFINED_CHARSET)
                    254:                             TtaSetDocumentCharset (doc, charset);
1.6       cvs       255:                         }
                    256:                       TtaFreeMemory (text2);
                    257:                     }       
                    258:                 } 
                    259:             }
                    260:           TtaFreeMemory (text);
                    261:         }
                    262:      }
                    263: }
                    264: 
1.23      cvs       265: /*----------------------------------------------------------------------
                    266:    XhtmlEntityCreated
                    267:    A XTHML entity has been created by the XML parser.
                    268:   ----------------------------------------------------------------------*/
1.30    ! cvs       269: void             XhtmlEntityCreated (int entityValue,
        !           270:                                     STRING entityName,
        !           271:                                     ParserData *context)
        !           272: 
1.23      cvs       273: { 
1.29      cvs       274:   ElementType   elType;
                    275:   Element       elText;
                    276:   AttributeType  attrType;
                    277:   Attribute     attr;
                    278:   Language      lang;
                    279:   int           len;
                    280:   CHAR_T        buffer[MaxEntityLength+10];
                    281: #define MAX_ENTITY_LENGTH 80
                    282:   
                    283:   if (entityValue < 255)
1.23      cvs       284:     {
1.29      cvs       285:       buffer[0] = ((UCHAR_T) entityValue);
                    286:       buffer[1] = WC_EOS;
                    287:       lang = TtaGetLanguageIdFromAlphabet('L');
1.23      cvs       288:     }
1.29      cvs       289:   else
                    290:     /* try to find a fallback character */
                    291:     GetFallbackCharacter (entityValue, buffer, &lang);
                    292: 
                    293:   /* create a new text leaf */
                    294:   elType.ElSSchema = TtaGetDocumentSSchema (context->doc);
                    295:   elType.ElTypeNum = HTML_EL_TEXT_UNIT;
                    296:   elText = TtaNewElement (context->doc, elType);
                    297:   XmlSetElemLineNumber (elText);
                    298:   InsertXmlElement (&elText);
                    299:   TtaSetTextContent (elText, buffer, lang, context->doc);
                    300:   context->lastElement = elText;
                    301:   context->lastElementClosed = TRUE;
                    302:   context->mergeText = FALSE;
                    303:   
                    304:   /* Make that text leaf read-only */
                    305:   TtaSetAccessRight (elText, ReadOnly, context->doc);
                    306:   
                    307:   /* Associate an attribute EntityName with the new text leaf */
                    308:   attrType.AttrSSchema = TtaGetDocumentSSchema (context->doc);
                    309:   attrType.AttrTypeNum = HTML_ATTR_EntityName;
                    310:   attr = TtaNewAttribute (attrType);
                    311:   TtaAttachAttribute (elText, attr, context->doc);
                    312: 
                    313:   len = ustrlen (entityName);
                    314:   if (len > MAX_ENTITY_LENGTH -3)
                    315:     len = MAX_ENTITY_LENGTH -3;
                    316:   buffer[0] = '&';
                    317:   ustrncpy (&buffer[1], entityName, len);
                    318:   buffer[len+1] = ';';
                    319:   buffer[len+2] = WC_EOS;
                    320:   TtaSetAttributeText (attr, buffer, elText, context->doc);
1.23      cvs       321: }
                    322: 
1.6       cvs       323: /*----------------------------------------------------------------------
                    324:   XhtmlElementComplete
1.20      cvs       325:   Complete Xhtml elements.
1.6       cvs       326:   Check its attributes and its contents.
                    327:   ----------------------------------------------------------------------*/
1.30    ! cvs       328: void              XhtmlElementComplete (Element el, Document doc, int *error)
        !           329: 
        !           330: {
        !           331:    ElementType    elType, newElType, childType;
        !           332:    Element        constElem, child, desc, leaf, prev, next, last,
        !           333:                  elFrames, lastFrame, lastChild;
        !           334:    Attribute      attr;
        !           335:    AttributeType  attrType;
        !           336:    Language       lang;
        !           337:    STRING         text;
        !           338:    CHAR_T         lastChar[2];
        !           339:    STRING         name1;
        !           340:    int            length;
        !           341:    SSchema        docSSchema;
1.6       cvs       342: 
                    343:    *error = 0;
                    344:    docSSchema = TtaGetDocumentSSchema (doc);
                    345: 
                    346:    elType = TtaGetElementType (el);
                    347:    /* is this a block-level element in a character-level element? */
1.27      cvs       348:    if (!IsXMLElementInline (elType) &&
1.24      cvs       349:        elType.ElTypeNum != HTML_EL_Comment_ &&
                    350:        elType.ElTypeNum != HTML_EL_XMLPI)
1.6       cvs       351:        BlockInCharLevelElem (el);
                    352: 
                    353:    newElType.ElSSchema = elType.ElSSchema;
                    354:    switch (elType.ElTypeNum)
                    355:      {
                    356:      case HTML_EL_Object:      /*  it's an object */
                    357:        /* create Object_Content */
                    358:        child = TtaGetFirstChild (el);
                    359:        if (child != NULL)
                    360:           elType = TtaGetElementType (child);
                    361:         
                    362:        /* is it the PICTURE element ? */
                    363:        if (child == NULL || elType.ElTypeNum != HTML_EL_PICTURE_UNIT)
                    364:         {
                    365:           desc = child;
                    366:           /* create the PICTURE element */
                    367:           elType.ElTypeNum = HTML_EL_PICTURE_UNIT;
                    368:           child = TtaNewTree (doc, elType, "");
                    369:           if (desc == NULL)
                    370:               TtaInsertFirstChild (&child, el, doc);
                    371:           else
                    372:               TtaInsertSibling (child, desc, TRUE, doc);
                    373:         }
                    374: 
                    375:        /* copy attribute data into SRC attribute of Object_Image */
                    376:        attrType.AttrSSchema = docSSchema;
                    377:        attrType.AttrTypeNum = HTML_ATTR_data;
                    378:        attr = TtaGetAttribute (el, attrType);
                    379:        if (attr != NULL)
                    380:         {
                    381:           length = TtaGetTextAttributeLength (attr);
                    382:           if (length > 0)
                    383:             {
                    384:               name1 = TtaAllocString (length + 1);
                    385:               TtaGiveTextAttributeValue (attr, name1, &length);
                    386:               attrType.AttrTypeNum = HTML_ATTR_SRC;
                    387:               attr = TtaGetAttribute (child, attrType);
                    388:               if (attr == NULL)
                    389:                 {
                    390:                   attr = TtaNewAttribute (attrType);
                    391:                   TtaAttachAttribute (child, attr, doc);
                    392:                 }
                    393:               TtaSetAttributeText (attr, name1, child, doc);
                    394:               TtaFreeMemory (name1);
                    395:             }
                    396:         }
                    397: 
                    398:        /* is the Object_Content element already created ? */
                    399:        desc = child;
                    400:        TtaNextSibling(&desc);
                    401:        if (desc != NULL)
                    402:           elType = TtaGetElementType (desc);
                    403:         
                    404:        /* is it the Object_Content element ? */
                    405:        if (desc == NULL || elType.ElTypeNum != HTML_EL_Object_Content)
                    406:         {
                    407:           /* create Object_Content */
                    408:           elType.ElTypeNum = HTML_EL_Object_Content;
                    409:           desc = TtaNewTree (doc, elType, "");
                    410:           TtaInsertSibling (desc, child, FALSE, doc);
                    411:           /* move previous existing children into Object_Content */
                    412:           child = TtaGetLastChild(el);
                    413:           while (child != desc)
                    414:             {
                    415:               TtaRemoveTree (child, doc);
                    416:               TtaInsertFirstChild (&child, desc, doc);
                    417:               child = TtaGetLastChild(el);
                    418:             }
                    419:         }
                    420:        break;
                    421:        
                    422:      case HTML_EL_Unnumbered_List:
                    423:      case HTML_EL_Numbered_List:
                    424:      case HTML_EL_Menu:
                    425:      case HTML_EL_Directory:
                    426:        /* It's a List element. It should only have List_Item children.
                    427:          If it has List element chidren, move these List elements
                    428:          within their previous List_Item sibling.  This is to fix
                    429:          a bug in document generated by Mozilla. */
                    430:        prev = NULL;
                    431:        next = 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_Unnumbered_List ||
                    439:               elType.ElTypeNum == HTML_EL_Numbered_List ||
                    440:               elType.ElTypeNum == HTML_EL_Menu ||
                    441:               elType.ElTypeNum == HTML_EL_Directory)
                    442:             /* this list element is a child of another list element */
                    443:             if (prev)
                    444:               {
                    445:                 elType = TtaGetElementType (prev);
                    446:                 if (elType.ElTypeNum == HTML_EL_List_Item)
                    447:                   {
                    448:                     /* get the last child of the previous List_Item */
                    449:                     desc = TtaGetFirstChild (prev);
                    450:                     last = NULL;
                    451:                     while (desc)
                    452:                       {
                    453:                         last = desc;
                    454:                         TtaNextSibling (&desc);
                    455:                       }
                    456:                     /* move the list element after the last child of the
                    457:                        previous List_Item */
                    458:                     TtaRemoveTree (child, doc);
                    459:                     if (last)
                    460:                       TtaInsertSibling (child, last, FALSE, doc);
                    461:                     else
                    462:                       TtaInsertFirstChild (&child, prev, doc);
                    463:                     child = prev;
                    464:                   }
                    465:               }
                    466:           prev = child;
                    467:           child = next;
                    468:         }
                    469:        break;
                    470:        
                    471:      case HTML_EL_FRAMESET:
                    472:        /* The FRAMESET element is now complete.  Gather all its FRAMESET
                    473:          and FRAME children and wrap them up in a Frames element */
                    474:        elFrames = NULL; lastFrame = NULL;
                    475:        lastChild = NULL;
                    476:        child = TtaGetFirstChild (el);
                    477:        while (child != NULL)
                    478:         {
                    479:           next = child;
                    480:           TtaNextSibling (&next);
                    481:           elType = TtaGetElementType (child);
                    482:           if (elType.ElTypeNum == HTML_EL_FRAMESET ||
                    483:               elType.ElTypeNum == HTML_EL_FRAME ||
                    484:               elType.ElTypeNum == HTML_EL_Comment_)
                    485:             {
                    486:               /* create the Frames element if it does not exist */
                    487:               if (elFrames == NULL)
                    488:                 {
                    489:                   newElType.ElSSchema = docSSchema;
                    490:                   newElType.ElTypeNum = HTML_EL_Frames;
                    491:                   elFrames = TtaNewElement (doc, newElType);
                    492:                   XmlSetElemLineNumber (elFrames);
                    493:                   TtaInsertSibling (elFrames, child, TRUE, doc);
                    494:                 }
                    495:               /* move the element as the last child of the Frames element */
                    496:               TtaRemoveTree (child, doc);
                    497:               if (lastFrame == NULL)
                    498:                 TtaInsertFirstChild (&child, elFrames, doc);
                    499:               else
                    500:                 TtaInsertSibling (child, lastFrame, FALSE, doc);
                    501:               lastFrame = child;
                    502:             }
                    503:           child = next;
                    504:         }
                    505:        break;
                    506:        
                    507:      case HTML_EL_Input:       /* it's an INPUT without any TYPE attribute */
                    508:        /* Create a child of type Text_Input */
                    509:        elType.ElTypeNum = HTML_EL_Text_Input;
                    510:        child = TtaNewTree (doc, elType, "");
                    511:        XmlSetElemLineNumber (child);
                    512:        TtaInsertFirstChild (&child, el, doc);
                    513:        /* now, process it like a Text_Input element */
                    514: 
                    515:      case HTML_EL_Text_Input:
                    516:      case HTML_EL_Password_Input:
                    517:      case HTML_EL_File_Input:
                    518:        /* get element Inserted_Text */
                    519:        child = TtaGetFirstChild (el);
                    520:        if (child != NULL)
                    521:         {
                    522:           attrType.AttrSSchema = docSSchema;
                    523:           attrType.AttrTypeNum = HTML_ATTR_Value_;
                    524:           attr = TtaGetAttribute (el, attrType);
                    525:           if (attr != NULL)
                    526:             {
                    527:               /* copy the value of attribute "value" into the first text
                    528:                  leaf of element */
                    529:               length = TtaGetTextAttributeLength (attr);
                    530:               if (length > 0)
                    531:                 {
                    532:                   /* get the text leaf */
                    533:                   leaf = TtaGetFirstChild (child);
                    534:                   if (leaf != NULL)
                    535:                     {
                    536:                       childType = TtaGetElementType (leaf);
                    537:                       if (childType.ElTypeNum == HTML_EL_TEXT_UNIT)
                    538:                         {
                    539:                           /* copy attribute value into the text leaf */
                    540:                           text = TtaAllocString (length + 1);
                    541:                           TtaGiveTextAttributeValue (attr, text, &length);
                    542:                           TtaSetTextContent (leaf, text, 
                    543:                                              TtaGetDefaultLanguage (), doc);
                    544:                           TtaFreeMemory (text);
                    545:                         }
                    546:                     }
                    547:                 }
                    548:             }
                    549:         }
                    550:        break;
                    551:        
                    552:      case HTML_EL_META:
1.15      cvs       553:        ParseCharset (el, doc);
1.6       cvs       554:        break;
                    555: 
                    556:      case HTML_EL_STYLE_:      /* it's a STYLE element */
1.8       cvs       557:      case HTML_EL_SCRIPT:      /* it's a SCRIPT element */
1.6       cvs       558:      case HTML_EL_Preformatted:        /* it's a PRE */
                    559:        /* if the last line of the Preformatted is empty, remove it */
                    560:        leaf = XmlLastLeafInElement (el);
                    561:        if (leaf != NULL)
                    562:         {
                    563:           elType = TtaGetElementType (leaf);
                    564:           if (elType.ElTypeNum == HTML_EL_TEXT_UNIT)
                    565:             /* the last leaf is a TEXT element */
                    566:             {
                    567:               length = TtaGetTextLength (leaf);
                    568:               if (length > 0)
                    569:                 {
                    570:                   TtaGiveSubString (leaf, lastChar, length, 1);
                    571:                   if (lastChar[0] == EOL)
                    572:                     /* last character is new line, delete it */
                    573:                     {
                    574:                       if (length == 1)
                    575:                         /* empty TEXT element */
                    576:                         TtaDeleteTree (leaf, doc);
                    577:                       else
                    578:                         /* remove the last character */
                    579:                         TtaDeleteTextContent (leaf, length, 1, doc);
                    580:                     }
                    581:                 }
                    582:             }
                    583:         }
                    584:        if (IsParsingCSS ())
                    585:         {
                    586:           text = GetStyleContents (el);
                    587:           if (text)
                    588:             {
                    589:               ReadCSSRules (doc, NULL, text, FALSE);
                    590:               TtaFreeMemory (text);
                    591:             }
                    592:           SetParsingCSS (FALSE);
                    593:         }
                    594:        /* and continue as if it were a Preformatted or a Script */
                    595:        break;
                    596:        
                    597:      case HTML_EL_Text_Area:   /* it's a Text_Area */
                    598:        SetParsingTextArea (FALSE);
                    599:        child = TtaGetFirstChild (el);
                    600:        if (child == NULL)
                    601:         /* it's an empty Text_Area */
                    602:         /* insert a Inserted_Text element in the element */
                    603:         {
                    604:           newElType.ElTypeNum = HTML_EL_Inserted_Text;
                    605:           child = TtaNewTree (doc, newElType, "");
                    606:           TtaInsertFirstChild (&child, el, doc);
                    607:         }
                    608:        else
                    609:         {
                    610:           /* save the text into Default_Value attribute */
                    611:           attrType.AttrSSchema = docSSchema;
                    612:           attrType.AttrTypeNum = HTML_ATTR_Default_Value;
                    613:           if (TtaGetAttribute (el, attrType) == NULL)
                    614:             /* attribute Default_Value is missing */
                    615:             {
                    616:               attr = TtaNewAttribute (attrType);
                    617:               TtaAttachAttribute (el, attr, doc);
                    618:               desc = TtaGetFirstChild (child);
                    619:               length = TtaGetTextLength (desc) + 1;
                    620:               text = TtaAllocString (length);
                    621:               TtaGiveTextContent (desc, text, &length, &lang);
                    622:               TtaSetAttributeText (attr, text, el, doc);
                    623:               TtaFreeMemory (text);
                    624:             }
                    625:         }
                    626:        /* insert a Frame element */
                    627:        newElType.ElTypeNum = HTML_EL_Frame;
                    628:        constElem = TtaNewTree (doc, newElType, "");
                    629:        TtaInsertSibling (constElem, child, FALSE, doc);
                    630:        break;
                    631:        
                    632:      case HTML_EL_Radio_Input:
                    633:      case HTML_EL_Checkbox_Input:
                    634:        /* put an attribute Checked if it is missing */
                    635:        attrType.AttrSSchema = docSSchema;
                    636:        attrType.AttrTypeNum = HTML_ATTR_Checked;
                    637:        if (TtaGetAttribute (el, attrType) == NULL)
                    638:         /* attribute Checked is missing */
                    639:         {
                    640:           attr = TtaNewAttribute (attrType);
                    641:           TtaAttachAttribute (el, attr, doc);
                    642:           TtaSetAttributeValue (attr, HTML_ATTR_Checked_VAL_No_, el, doc);
                    643:         }
                    644:        break;
                    645:        
                    646:      case HTML_EL_Option_Menu:
                    647:        /* Check that at least one option has a SELECTED attribute */
                    648:        OnlyOneOptionSelected (el, doc, TRUE);
                    649:        break;
                    650: 
                    651:      case HTML_EL_PICTURE_UNIT:
                    652:        break;
                    653:        
                    654:      case HTML_EL_LINK:
                    655:        CheckCSSLink (el, doc, docSSchema);
                    656:        break;
                    657:        
                    658:      case HTML_EL_Data_cell:
                    659:      case HTML_EL_Heading_cell:
                    660:        /* insert a pseudo paragraph into empty cells */
                    661:        child = TtaGetFirstChild (el);
                    662:        if (child == NULL)
                    663:         {
                    664:           elType.ElTypeNum = HTML_EL_Pseudo_paragraph;
                    665:           child = TtaNewTree (doc, elType, "");
                    666:           if (child != NULL)
                    667:               TtaInsertFirstChild (&child, el, doc);
                    668:         }
                    669:        
                    670:        /* detect whether we're parsing a whole table or just a cell */
                    671:        if (IsWithinTable ())
                    672:           NewCell (el, doc, FALSE);
                    673:        break;
                    674:        
                    675:      case HTML_EL_Table:
                    676:        CheckTable (el, doc);
                    677:        SubWithinTable ();
                    678:        break;
                    679:        
                    680:      case HTML_EL_TITLE:
                    681:        /* show the TITLE in the main window */
                    682:        UpdateTitle (el, doc);
                    683:        break;
                    684:        
                    685:      default:
                    686:        break;
                    687:      }
                    688: }
1.1       cvs       689: 
                    690: /*----------------------------------------------------------------------
1.30    ! cvs       691:    PutInContent    
        !           692:    Put the string ChrString in the leaf of current element.
        !           693:   ----------------------------------------------------------------------*/
        !           694: Element         PutInContent (STRING ChrString, ParserData *context)
        !           695: 
        !           696: {
        !           697:    Element      el, child;
        !           698:    ElementType  elType;
        !           699:    int          length;
        !           700: 
        !           701:    el = NULL;
        !           702:    if (context->lastElement != NULL)
        !           703:      {
        !           704:        /* search first leaf of current element */
        !           705:        el = context->lastElement;
        !           706:        do
        !           707:          {
        !           708:             child = TtaGetFirstChild (el);
        !           709:             if (child != NULL)
        !           710:                el = child;
        !           711:          }
        !           712:        while (child != NULL);
        !           713:        elType = TtaGetElementType (el);
        !           714:        length = 0;
        !           715:        if (elType.ElTypeNum == 1)
        !           716:           length = TtaGetTextLength (el);
        !           717:        if (length == 0)
        !           718:           TtaSetTextContent (el, ChrString, context->language, context->doc);
        !           719:        else
        !           720:           TtaAppendTextContent (el, ChrString, context->doc);
        !           721:      }
        !           722:    return el;
        !           723: }
        !           724: 
        !           725: /*----------------------------------------------------------------------
        !           726:    CreateHTMLAttribute
        !           727:    create an attribute of type attrType for the element el.
        !           728:   ----------------------------------------------------------------------*/
        !           729: void           CreateHTMLAttribute (Element       el,
        !           730:                                    AttributeType attrType,
        !           731:                                    CHAR_T*       text,
        !           732:                                    ThotBool      isInvalid,
        !           733:                                    Document      doc,
        !           734:                                    Attribute    *lastAttribute,
        !           735:                                    Element      *lastAttrElement)
        !           736:      
        !           737: {
        !           738:    int         attrKind;
        !           739:    int         length;
        !           740:    CHAR_T*     buffer;
        !           741:    Attribute   attr, oldAttr;
        !           742: 
        !           743:    if (attrType.AttrTypeNum != 0)
        !           744:      {
        !           745:        oldAttr = TtaGetAttribute (el, attrType);
        !           746:        if (oldAttr != NULL)
        !           747:         /* this attribute already exists */
        !           748:         attr = oldAttr;
        !           749:        else
        !           750:         /* create a new attribute and attach it to the element */
        !           751:         {
        !           752:           attr = TtaNewAttribute (attrType);
        !           753:           TtaAttachAttribute (el, attr, doc);
        !           754:         }
        !           755:        *lastAttribute = attr;
        !           756:        *lastAttrElement = el;
        !           757: 
        !           758:        TtaGiveAttributeType (attr, &attrType, &attrKind);
        !           759:        if (attrKind == 0)      /* enumerate */
        !           760:         TtaSetAttributeValue (attr, 1, el, doc);
        !           761: 
        !           762:        /* attribute BORDER without any value (ThotBool attribute) is */
        !           763:        /* considered as BORDER=1 */
        !           764:        if (attrType.AttrTypeNum == HTML_ATTR_Border)
        !           765:         TtaSetAttributeValue (attr, 1, el, doc);
        !           766: 
        !           767:        if (isInvalid)
        !           768:         /* Copy the name of the invalid attribute as the content */
        !           769:         /* of the Invalid_attribute attribute. */
        !           770:         {
        !           771:           length = ustrlen (text) + 2;
        !           772:           length += TtaGetTextAttributeLength (attr);
        !           773:           buffer = TtaAllocString (length + 1);
        !           774:           TtaGiveTextAttributeValue (attr, buffer, &length);
        !           775:           ustrcat (buffer, TEXT(" "));
        !           776:           ustrcat (buffer, text);
        !           777:           TtaSetAttributeText (attr, buffer, el, doc);
        !           778:           TtaFreeMemory (buffer);
        !           779:         }
        !           780:      }
        !           781: }
        !           782: 
        !           783: /*----------------------------------------------------------------------
        !           784:    HTMLTypeAttrValue
        !           785:    Value val has been read for the HTML attribute TYPE.
        !           786:    Create a child for the current Thot element INPUT accordingly.
        !           787:   ----------------------------------------------------------------------*/
        !           788: void               HTMLTypeAttrValue (CHAR_T     *val,
        !           789:                                      Attribute   lastAttribute,
        !           790:                                      Element     lastAttrElement,
        !           791:                                      ParserData *context)
        !           792: 
        !           793: {
        !           794:   ElementType      elType;
        !           795:   Element          newChild;
        !           796:   AttributeType    attrType;
        !           797:   Attribute        attr;
        !           798:   CHAR_T           msgBuffer[MaxMsgLength];
        !           799:   int              value;
        !           800:   int              numberOfLinesRead;
        !           801: 
        !           802:   value = MapAttrValue (DummyAttribute, val);
        !           803:   if (value < 0)
        !           804:     {
        !           805:       if (ustrlen (val) > MaxMsgLength - 40)
        !           806:          val[MaxMsgLength - 40] = WC_EOS;
        !           807:       usprintf (msgBuffer, TEXT("Unknown attribute value \"type = %s\""), val);
        !           808:       ParseHTMLError (context->doc, msgBuffer);
        !           809:       attrType.AttrSSchema = TtaGetDocumentSSchema (context->doc);
        !           810:       attrType.AttrTypeNum = pHTMLAttributeMapping[0].ThotAttribute;
        !           811:       usprintf (msgBuffer, TEXT("type=%s"), val);
        !           812:       CreateHTMLAttribute (context->lastElement, attrType, msgBuffer, TRUE,
        !           813:                           context->doc, &lastAttribute, &lastAttrElement);
        !           814:     }
        !           815:   else
        !           816:     {
        !           817:       elType = TtaGetElementType (context->lastElement);
        !           818:       if (elType.ElTypeNum != HTML_EL_Input)
        !           819:        {
        !           820:          if (ustrlen (val) > MaxMsgLength - 40)
        !           821:            val[MaxMsgLength - 40] = WC_EOS;
        !           822:          usprintf (msgBuffer, TEXT("Duplicate attribute \"type = %s\""), val);
        !           823:        }
        !           824:       else
        !           825:        {
        !           826:          elType.ElSSchema = TtaGetDocumentSSchema (context->doc);
        !           827:          elType.ElTypeNum = value;
        !           828:          newChild = TtaNewTree (context->doc, elType, "");
        !           829:          numberOfLinesRead = 0;
        !           830:          TtaSetElementLineNumber (newChild, numberOfLinesRead);
        !           831:          TtaInsertFirstChild (&newChild, context->lastElement, context->doc);
        !           832:          if (value == HTML_EL_PICTURE_UNIT)
        !           833:            {
        !           834:              /* add the attribute IsInput to input pictures */
        !           835:              attrType.AttrSSchema = elType.ElSSchema;
        !           836:              attrType.AttrTypeNum = HTML_ATTR_IsInput;
        !           837:              attr = TtaNewAttribute (attrType);
        !           838:              TtaAttachAttribute (newChild, attr, context->doc);
        !           839:            }
        !           840:        }
        !           841:     }
        !           842: }
        !           843: 
        !           844: /*----------------------------------------------------------------------
        !           845:    XhtmlTypeAttrValue 
        !           846:    Value val has been read for the HTML attribute TYPE.
        !           847:    Create a child for the current Thot element INPUT accordingly.
        !           848:   ----------------------------------------------------------------------*/
        !           849: void              XhtmlTypeAttrValue (CHAR_T     *val,
        !           850:                                      Attribute   currentAttribute,
        !           851:                                      Element     lastAttrElement,
        !           852:                                      ParserData *context)
        !           853: 
        !           854: {
        !           855:   ElementType     elType;
        !           856:   Element         newChild;
        !           857:   AttributeType   attrType;
        !           858:   Attribute       attr;
        !           859:   CHAR_T          msgBuffer[MaxMsgLength];
        !           860:   int             value;
        !           861:   int             attrKind;
        !           862:   ThotBool        level;
        !           863: 
        !           864:   TtaGiveAttributeType (currentAttribute, &attrType, &attrKind);
        !           865:   attrType.AttrTypeNum = DummyAttribute;
        !           866:   MapHTMLAttributeValue (val, attrType, &value);
        !           867:   if (value < 0)
        !           868:     {
        !           869:       usprintf (msgBuffer, TEXT("Unknown attribute value \"type=%s\""), val);
        !           870:       XmlParseError (errorParsing, msgBuffer, 0);
        !           871:       MapHTMLAttribute (TEXT("unknown_attr"), &attrType, NULL,
        !           872:                        &level, context->doc);
        !           873:       usprintf (msgBuffer, TEXT("type=%s"), val);
        !           874:       CreateHTMLAttribute (context->lastElement, attrType, msgBuffer, TRUE,
        !           875:                           context->doc, &currentAttribute, &lastAttrElement);
        !           876:     }
        !           877:   else
        !           878:     {
        !           879:       elType = TtaGetElementType (context->lastElement);
        !           880:       if (elType.ElTypeNum != HTML_EL_Input)
        !           881:        {
        !           882:          usprintf (msgBuffer, TEXT("Duplicate attribute \"type = %s\""), val);
        !           883:          XmlParseError (errorParsing, msgBuffer, 0);
        !           884:        }
        !           885:       else
        !           886:        {
        !           887:          /* elType.ElSSchema = currentParserCtxt->XMLSSchema; */
        !           888:          elType.ElTypeNum = value;
        !           889:          newChild = TtaNewTree (context->doc, elType, "");
        !           890:          XmlSetElemLineNumber (newChild);
        !           891:          TtaInsertFirstChild (&newChild, context->lastElement, context->doc);
        !           892:          if (value == HTML_EL_PICTURE_UNIT)
        !           893:            {
        !           894:              /* add the attribute IsInput to input pictures */
        !           895:              attrType.AttrSSchema = elType.ElSSchema;
        !           896:              attrType.AttrTypeNum = HTML_ATTR_IsInput;
        !           897:              attr = TtaNewAttribute (attrType);
        !           898:              TtaAttachAttribute (newChild, attr, context->doc);
        !           899:            }
        !           900:        }
        !           901:     }
        !           902: }
        !           903: 
        !           904: /*----------------------------------------------------------------------
        !           905:    CreateAttrWidthPercentPxl
        !           906:    an HTML attribute "width" has been created for a Table of a HR.
        !           907:    Create the corresponding attribute IntWidthPercent or IntWidthPxl.
        !           908:    oldWidth is -1 or the old image width.
        !           909:   ----------------------------------------------------------------------*/
        !           910: void              CreateAttrWidthPercentPxl (STRING buffer, Element el,
        !           911:                                             Document doc, int oldWidth)
        !           912: 
        !           913: {
        !           914:   AttributeType   attrTypePxl, attrTypePercent;
        !           915:   Attribute       attrOld, attrNew;
        !           916:   int             length, val;
        !           917:   CHAR_T          msgBuffer[MaxMsgLength];
        !           918:   ElementType    elType;
        !           919:   int             w, h;
        !           920:   ThotBool        isImage;
        !           921: 
        !           922:   elType = TtaGetElementType (el);
        !           923:   isImage = (elType.ElTypeNum == HTML_EL_PICTURE_UNIT ||
        !           924:             elType.ElTypeNum == HTML_EL_Data_cell ||
        !           925:             elType.ElTypeNum == HTML_EL_Heading_cell);
        !           926: 
        !           927:   /* remove trailing spaces */
        !           928:   length = ustrlen (buffer) - 1;
        !           929:   while (length > 0 && buffer[length] <= SPACE)
        !           930:     length--;
        !           931:   attrTypePxl.AttrSSchema = TtaGetDocumentSSchema (doc);
        !           932:   attrTypePercent.AttrSSchema = TtaGetDocumentSSchema (doc);
        !           933:   attrTypePxl.AttrTypeNum = HTML_ATTR_IntWidthPxl;
        !           934:   attrTypePercent.AttrTypeNum = HTML_ATTR_IntWidthPercent;
        !           935:   /* is the last character a '%' ? */
        !           936:   if (buffer[length] == '%')
        !           937:     {
        !           938:       /* remove IntWidthPxl */
        !           939:       attrOld = TtaGetAttribute (el, attrTypePxl);
        !           940:       /* update IntWidthPercent */
        !           941:       attrNew = TtaGetAttribute (el, attrTypePercent);
        !           942:       if (attrNew == NULL)
        !           943:        {
        !           944:          attrNew = TtaNewAttribute (attrTypePercent);
        !           945:          TtaAttachAttribute (el, attrNew, doc);
        !           946:        }
        !           947:       else if (isImage && oldWidth == -1)
        !           948:        {
        !           949:          if (attrOld == NULL)
        !           950:            oldWidth = TtaGetAttributeValue (attrNew);
        !           951:          else
        !           952:            oldWidth = TtaGetAttributeValue (attrOld);
        !           953:        }
        !           954:     }
        !           955:   else
        !           956:     {
        !           957:       /* remove IntWidthPercent */
        !           958:       attrOld = TtaGetAttribute (el, attrTypePercent);
        !           959:       /* update IntWidthPxl */
        !           960:       attrNew = TtaGetAttribute (el, attrTypePxl);
        !           961:       if (attrNew == NULL)
        !           962:        {
        !           963:          attrNew = TtaNewAttribute (attrTypePxl);
        !           964:          TtaAttachAttribute (el, attrNew, doc);
        !           965:        }
        !           966:       else if (isImage && oldWidth == -1)
        !           967:        {
        !           968:          TtaGiveBoxSize (el, doc, 1, UnPixel, &w, &h);
        !           969:          if (attrOld == NULL)
        !           970:            oldWidth = w * TtaGetAttributeValue (attrNew) / 100;
        !           971:          else
        !           972:            oldWidth = w * TtaGetAttributeValue (attrOld) / 100;          
        !           973:        }
        !           974:     }
        !           975: 
        !           976:   if (attrOld != NULL)
        !           977:     TtaRemoveAttribute (el, attrOld, doc);
        !           978:   if (usscanf (buffer, TEXT("%d"), &val))
        !           979:     TtaSetAttributeValue (attrNew, val, el, doc);
        !           980:   else
        !           981:     /* its not a number. Delete attribute and send an error message */
        !           982:     {
        !           983:     TtaRemoveAttribute (el, attrNew, doc);
        !           984:     if (ustrlen (buffer) > MaxMsgLength - 30)
        !           985:         buffer[MaxMsgLength - 30] = EOS;
        !           986:     usprintf (msgBuffer, TEXT("Invalid attribute value \"%s\""), buffer);
        !           987:     ParseHTMLError (doc, msgBuffer);
        !           988:     }
        !           989:   if (isImage)
        !           990:     UpdateImageMap (el, doc, oldWidth, -1);
        !           991: }
        !           992: 
        !           993: /*----------------------------------------------------------------------
        !           994:    CreateAttrIntSize
        !           995:    an HTML attribute "size" has been created for a Font element.
        !           996:    Create the corresponding internal attribute.
        !           997:   ----------------------------------------------------------------------*/
        !           998: void              CreateAttrIntSize (STRING buffer,
        !           999:                                     Element el,
        !          1000:                                     Document doc)
        !          1001: 
        !          1002: {
        !          1003:    AttributeType  attrType;
        !          1004:    int            val, ind, factor, delta;
        !          1005:    Attribute      attr;
        !          1006:    CHAR_T         msgBuffer[MaxMsgLength];
        !          1007: 
        !          1008:    /* is the first character a '+' or a '-' ? */
        !          1009:    ind = 0;
        !          1010:    factor = 1;
        !          1011:    delta = 0;
        !          1012:    if (buffer[0] == '+')
        !          1013:      {
        !          1014:        attrType.AttrTypeNum = HTML_ATTR_IntSizeIncr;
        !          1015:        ind++;
        !          1016:        factor = 2;
        !          1017:      }
        !          1018:    else if (buffer[0] == '-')
        !          1019:      {
        !          1020:        attrType.AttrTypeNum = HTML_ATTR_IntSizeDecr;
        !          1021:        ind++;
        !          1022:        factor = 2;
        !          1023:      }
        !          1024:    else
        !          1025:      {
        !          1026:        attrType.AttrTypeNum = HTML_ATTR_IntSizeRel;
        !          1027:        delta = 1;
        !          1028:      }
        !          1029:    attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
        !          1030:    attr = TtaGetAttribute (el, attrType);
        !          1031:    if (usscanf (&buffer[ind], TEXT("%d"), &val))
        !          1032:      {
        !          1033:        val = val * factor + delta;
        !          1034:        if (attr == NULL)
        !          1035:         {
        !          1036:           /* this attribute doesn't exist, create it */
        !          1037:           attr = TtaNewAttribute (attrType);
        !          1038:           TtaAttachAttribute (el, attr, doc);
        !          1039:         }
        !          1040:        TtaSetAttributeValue (attr, val, el, doc);
        !          1041:      }
        !          1042:    else
        !          1043:      /* its not a number. Delete attribute and send an error message */
        !          1044:      {
        !          1045:        if (attr)
        !          1046:          TtaRemoveAttribute (el, attr, doc);
        !          1047:        if (ustrlen (buffer) > MaxMsgLength - 30)
        !          1048:          buffer[MaxMsgLength - 30] = EOS;
        !          1049:        usprintf (msgBuffer, TEXT("Invalid attribute value \"%s\""), buffer);
        !          1050:        ParseHTMLError (doc, msgBuffer);
        !          1051:      }
        !          1052: }
        !          1053: /*----------------------------------------------------------------------
        !          1054:    EndOfHTMLAttributeValue
        !          1055:    Filling of an HTML attribute value
        !          1056:   ----------------------------------------------------------------------*/
        !          1057: void               EndOfHTMLAttributeValue (CHAR_T     *attrValue,
        !          1058:                                            AttributeMapping *lastMappedAttr,
        !          1059:                                            Attribute   currentAttribute,
        !          1060:                                            Element     lastAttrElement,
        !          1061:                                            ThotBool    UnknownAttr,
        !          1062:                                            ParserData *context,
        !          1063:                                            ThotBool    isXML)
        !          1064: 
        !          1065: {
        !          1066:    AttributeType   attrType, attrType1;
        !          1067:    Attribute       attr;
        !          1068:    ElementType    elType;
        !          1069:    Element         child;
        !          1070:    Language        lang;
        !          1071:    CHAR_T          translation;
        !          1072:    char            shape;
        !          1073:    STRING          buffer;
        !          1074:    STRING          attrName;
        !          1075:    int             val;
        !          1076:    int             length;
        !          1077:    int             attrKind;
        !          1078:    ThotBool        done = FALSE;
        !          1079:    ThotBool        level;
        !          1080:    CHAR_T          msgBuffer[MaxMsgLength];
        !          1081: 
        !          1082:    /* treatments of some particular HTML attributes */
        !          1083:    if (!ustrcmp (lastMappedAttr->XMLattribute, TEXT("style")))
        !          1084:      {
        !          1085:        TtaSetAttributeText (currentAttribute, attrValue,
        !          1086:                            lastAttrElement, context->doc);
        !          1087:        ParseHTMLSpecificStyle (context->lastElement, attrValue,
        !          1088:                               context->doc, 1, FALSE);
        !          1089:        done = TRUE;
        !          1090:      }
        !          1091:    else
        !          1092:      {
        !          1093:        if (!ustrcmp (lastMappedAttr->XMLattribute, TEXT("link")))
        !          1094:           HTMLSetAlinkColor (context->doc, attrValue);
        !          1095:        else if (!ustrcmp (lastMappedAttr->XMLattribute, TEXT("alink")))
        !          1096:         HTMLSetAactiveColor (context->doc, attrValue);
        !          1097:        else if (!ustrcmp (lastMappedAttr->XMLattribute, TEXT("vlink")))
        !          1098:         HTMLSetAvisitedColor (context->doc, attrValue);
        !          1099:      }
        !          1100: 
        !          1101:    if (!done)
        !          1102:      {
        !          1103:        val = 0;
        !          1104:        translation = lastMappedAttr->AttrOrContent;
        !          1105: 
        !          1106:        switch (translation)
        !          1107:         {
        !          1108:         case 'C':      /* Content */
        !          1109:           child = PutInContent (attrValue, context);
        !          1110:           if (child != NULL)
        !          1111:               TtaAppendTextContent (child, TEXT("\" "), context->doc);
        !          1112:           break;
        !          1113: 
        !          1114:         case 'A':
        !          1115:           if (currentAttribute != NULL)
        !          1116:             {
        !          1117:               TtaGiveAttributeType (currentAttribute, &attrType, &attrKind);
        !          1118:               switch (attrKind)
        !          1119:                 {
        !          1120:                 case 0:        /* enumerate */
        !          1121:                   if (isXML)
        !          1122:                     MapHTMLAttributeValue (attrValue, attrType, &val);
        !          1123:                   else
        !          1124:                     val = MapAttrValue (lastMappedAttr->ThotAttribute,
        !          1125:                                         attrValue);
        !          1126:                   if (val < 0)
        !          1127:                     {
        !          1128:                       TtaGiveAttributeType (currentAttribute,
        !          1129:                                             &attrType, &attrKind);
        !          1130:                       attrName = TtaGetAttributeName (attrType);
        !          1131:                       usprintf (msgBuffer,
        !          1132:                                 TEXT("Unknown attribute value \"%s = %s\""),
        !          1133:                                 attrName, attrValue);
        !          1134:                       if (isXML)
        !          1135:                         XmlParseError (errorParsing, msgBuffer, 0);
        !          1136:                       else
        !          1137:                         ParseHTMLError (context->doc, msgBuffer);
        !          1138: 
        !          1139:                       /* remove the attribute and replace it by an */
        !          1140:                       /* Invalid_attribute */
        !          1141:                       TtaRemoveAttribute (lastAttrElement,
        !          1142:                                           currentAttribute, context->doc);
        !          1143:                       if (isXML)
        !          1144:                         MapHTMLAttribute (TEXT("unknown_attr"), &attrType,
        !          1145:                                           NULL, &level, context->doc);
        !          1146:                       else
        !          1147:                         {
        !          1148:                           attrType.AttrSSchema = 
        !          1149:                             TtaGetDocumentSSchema (context->doc);
        !          1150:                           attrType.AttrTypeNum =
        !          1151:                             pHTMLAttributeMapping[0].ThotAttribute;
        !          1152:                         }
        !          1153:                       usprintf (msgBuffer, TEXT("%s=%s"), attrName, attrValue);
        !          1154:                       CreateHTMLAttribute (lastAttrElement, attrType,
        !          1155:                                            msgBuffer, TRUE, context->doc,
        !          1156:                                            &currentAttribute, &lastAttrElement);
        !          1157:                     }
        !          1158:                   else
        !          1159:                       TtaSetAttributeValue (currentAttribute, val,
        !          1160:                                             lastAttrElement, context->doc);
        !          1161:                   break;
        !          1162:                 case 1:        /* integer */
        !          1163:                   if (attrType.AttrTypeNum == HTML_ATTR_Border &&
        !          1164:                       !ustrcasecmp (attrValue, TEXT("border")))
        !          1165:                     {
        !          1166:                       /* border="border" for a table */
        !          1167:                       val = 1;
        !          1168:                       TtaSetAttributeValue (currentAttribute, val,
        !          1169:                                             lastAttrElement, context->doc);
        !          1170:                     }
        !          1171:                   else if (usscanf (attrValue, TEXT("%d"), &val))
        !          1172:                     TtaSetAttributeValue (currentAttribute, val,
        !          1173:                                           lastAttrElement, context->doc);
        !          1174:                   else
        !          1175:                     {
        !          1176:                       TtaRemoveAttribute (lastAttrElement, currentAttribute,
        !          1177:                                           context->doc);
        !          1178:                       usprintf (msgBuffer,
        !          1179:                                 TEXT("Unknown attribute value \"%s\""),
        !          1180:                                 attrValue);
        !          1181:                       if (isXML)
        !          1182:                         XmlParseError (errorParsing, msgBuffer, 0);
        !          1183:                       else
        !          1184:                         ParseHTMLError (context->doc, msgBuffer);
        !          1185:                     }
        !          1186:                   break;
        !          1187:                 case 2:        /* text */
        !          1188:                   if (!UnknownAttr)
        !          1189:                     {
        !          1190:                       TtaSetAttributeText (currentAttribute, attrValue,
        !          1191:                                            lastAttrElement, context->doc);
        !          1192:                       if (attrType.AttrTypeNum == HTML_ATTR_Langue)
        !          1193:                         {
        !          1194:                           /* it's a LANG attribute value */
        !          1195:                           lang = TtaGetLanguageIdFromName (attrValue);
        !          1196:                           if (lang == 0)
        !          1197:                             {
        !          1198:                               usprintf (msgBuffer, TEXT("Unknown language: %s"),
        !          1199:                                         attrValue);
        !          1200:                               if (isXML)
        !          1201:                                 XmlParseError (errorParsing, msgBuffer, 0);
        !          1202:                               else
        !          1203:                                 ParseHTMLError (context->doc, msgBuffer);
        !          1204:                             }
        !          1205:                           else
        !          1206:                             {
        !          1207:                               /* change current language */
        !          1208:                               context->language = lang;
        !          1209:                               if (isXML)
        !          1210:                                 SetLanguagInXmlStack (lang);
        !          1211:                               else
        !          1212:                                 SetLanguagInHTMLStack (lang);
        !          1213:                             }
        !          1214:                           if (!TtaGetParent (lastAttrElement))
        !          1215:                             /* it's a LANG attribute on the root element */
        !          1216:                             /* set the RealLang attribute */
        !          1217:                             {
        !          1218:                               attrType1.AttrSSchema = TtaGetDocumentSSchema (context->doc);
        !          1219:                               attrType1.AttrTypeNum = HTML_ATTR_RealLang;
        !          1220:                               attr = TtaNewAttribute (attrType1);
        !          1221:                               TtaAttachAttribute (lastAttrElement,
        !          1222:                                                   attr, context->doc);
        !          1223:                               TtaSetAttributeValue (attr,
        !          1224:                                                     HTML_ATTR_RealLang_VAL_Yes_,
        !          1225:                                                     lastAttrElement,
        !          1226:                                                     context->doc);
        !          1227:                             }
        !          1228:                         }
        !          1229:                       else if (attrType.AttrTypeNum == HTML_ATTR_accesskey)
        !          1230:                         TtaAddAccessKey (context->doc, (int)attrValue[0],
        !          1231:                                          lastAttrElement);
        !          1232:                     }
        !          1233:                   else
        !          1234:                     /* this is the content of an invalid attribute */
        !          1235:                     /* append it to the current Invalid_attribute */
        !          1236:                     {
        !          1237:                       length = ustrlen (attrValue) + 2;
        !          1238:                       length += TtaGetTextAttributeLength (currentAttribute);
        !          1239:                       buffer = TtaAllocString (length + 1);
        !          1240:                       TtaGiveTextAttributeValue (currentAttribute,
        !          1241:                                                  buffer, &length);
        !          1242:                       ustrcat (buffer, TEXT("="));
        !          1243:                       ustrcat (buffer, attrValue);
        !          1244:                       TtaSetAttributeText (currentAttribute, buffer,
        !          1245:                                            lastAttrElement, context->doc);
        !          1246:                       TtaFreeMemory (buffer);
        !          1247:                     }
        !          1248:                   break;
        !          1249:                 case 3:        /* reference */
        !          1250:                   break;
        !          1251:                 }
        !          1252:             }
        !          1253:           break;
        !          1254:           
        !          1255:         case SPACE:
        !          1256:           if (isXML)
        !          1257:             XhtmlTypeAttrValue (attrValue, currentAttribute,
        !          1258:                                 lastAttrElement, context);
        !          1259:           else
        !          1260:             HTMLTypeAttrValue (attrValue, currentAttribute,
        !          1261:                                lastAttrElement, context);
        !          1262:           break;
        !          1263: 
        !          1264:         default:
        !          1265:           break;
        !          1266:         }
        !          1267: 
        !          1268:       if (lastMappedAttr->ThotAttribute == HTML_ATTR_Width__)
        !          1269:         /* HTML attribute "width" for a table or a hr */
        !          1270:         /* create the corresponding attribute IntWidthPercent or */
        !          1271:         /* IntWidthPxl */
        !          1272:         CreateAttrWidthPercentPxl (attrValue, lastAttrElement, context->doc, -1);
        !          1273:       else
        !          1274:         if (!ustrcmp (lastMappedAttr->XMLattribute, TEXT("size")))
        !          1275:           {
        !          1276:             TtaGiveAttributeType (currentAttribute, &attrType, &attrKind);
        !          1277:             if (attrType.AttrTypeNum == HTML_ATTR_Font_size)
        !          1278:                 CreateAttrIntSize (attrValue, lastAttrElement, context->doc);
        !          1279:           }
        !          1280:       else
        !          1281:         if (!ustrcmp (lastMappedAttr->XMLattribute, TEXT("shape")))
        !          1282:             {
        !          1283:               child = TtaGetFirstChild (lastAttrElement);
        !          1284:               if (child != NULL)
        !          1285:                 {
        !          1286:                   switch (val)
        !          1287:                     {
        !          1288:                     case HTML_ATTR_shape_VAL_rectangle:
        !          1289:                       shape = 'R';
        !          1290:                       break;
        !          1291:                     case HTML_ATTR_shape_VAL_circle:
        !          1292:                       shape = 'a';
        !          1293:                       break;
        !          1294:                     case HTML_ATTR_shape_VAL_polygon:
        !          1295:                       shape = 'p';
        !          1296:                       break;
        !          1297:                     default:
        !          1298:                       shape = SPACE;
        !          1299:                       break;
        !          1300:                     }
        !          1301:                   TtaSetGraphicsShape (child, shape, context->doc);
        !          1302:                 }
        !          1303:             }
        !          1304:           else
        !          1305:             if (!ustrcmp (lastMappedAttr->XMLattribute, TEXT("value")))
        !          1306:               {
        !          1307:                 elType = TtaGetElementType (lastAttrElement);
        !          1308:                 if (elType.ElTypeNum == HTML_EL_Text_Input ||
        !          1309:                     elType.ElTypeNum == HTML_EL_Password_Input ||
        !          1310:                     elType.ElTypeNum == HTML_EL_File_Input ||
        !          1311:                     elType.ElTypeNum == HTML_EL_Input)
        !          1312:                   /* create a Default_Value attribute with the same content */
        !          1313:                   {
        !          1314:                     attrType1.AttrSSchema = attrType.AttrSSchema;
        !          1315:                     attrType1.AttrTypeNum = HTML_ATTR_Default_Value;
        !          1316:                     attr = TtaNewAttribute (attrType1);
        !          1317:                     TtaAttachAttribute (lastAttrElement, attr, context->doc);
        !          1318:                     TtaSetAttributeText (attr, attrValue,
        !          1319:                                          lastAttrElement, context->doc);
        !          1320:                   }
        !          1321:               }
        !          1322: 
        !          1323:        /* Some HTML attributes are equivalent to a CSS property:      */
        !          1324:        /*      background     ->                   background         */
        !          1325:        /*      bgcolor        ->                   background         */
        !          1326:        /*      text           ->                   color              */
        !          1327:        /*      color          ->                   color              */
        !          1328:             else
        !          1329:               if (!ustrcmp (lastMappedAttr->XMLattribute, TEXT("background")))
        !          1330:                 {
        !          1331:                   if (ustrlen (attrValue) > MaxMsgLength - 30)
        !          1332:                       attrValue[MaxMsgLength - 30] = WC_EOS;
        !          1333:                   usprintf (msgBuffer, TEXT("background: url(%s)"), attrValue);
        !          1334:                   ParseHTMLSpecificStyle (context->lastElement, msgBuffer,
        !          1335:                                           context->doc, 1, FALSE);
        !          1336:                 }
        !          1337:               else
        !          1338:                 if (!ustrcmp (lastMappedAttr->XMLattribute, TEXT("bgcolor")))
        !          1339:                     HTMLSetBackgroundColor (context->doc,
        !          1340:                                             context->lastElement, attrValue);
        !          1341:                 else
        !          1342:                   if (!ustrcmp (lastMappedAttr->XMLattribute, TEXT("text")) ||
        !          1343:                       !ustrcmp (lastMappedAttr->XMLattribute, TEXT("color")))
        !          1344:                     HTMLSetForegroundColor (context->doc,
        !          1345:                                             context->lastElement, attrValue);
        !          1346:      }
        !          1347: }
        !          1348: 
        !          1349: /*----------------------------------------------------------------------
1.16      cvs      1350:    MapHTMLAttributeValue
1.2       cvs      1351:    Search in the Attribute Value Mapping Table the entry for the attribute
                   1352:    ThotAtt and its value AttrVal. Returns the corresponding Thot value.
1.1       cvs      1353:   ----------------------------------------------------------------------*/
1.30    ! cvs      1354: void    MapHTMLAttributeValue (CHAR_T        *AttrVal,
        !          1355:                               AttributeType  attrType,
        !          1356:                               int           *value)
        !          1357: 
1.1       cvs      1358: {
1.30    ! cvs      1359:    int  i;
1.1       cvs      1360: 
1.2       cvs      1361:    *value = 0;
1.1       cvs      1362:    i = 0;
                   1363: 
1.2       cvs      1364:    while (XhtmlAttrValueMappingTable[i].ThotAttr != attrType.AttrTypeNum &&
                   1365:          XhtmlAttrValueMappingTable[i].ThotAttr != 0)
                   1366:        i++;
                   1367: 
                   1368:    if (XhtmlAttrValueMappingTable[i].ThotAttr == attrType.AttrTypeNum)
                   1369:      {
                   1370:        do
1.18      cvs      1371:            if (!ustrcmp (XhtmlAttrValueMappingTable[i].XMLattrValue, AttrVal))
1.2       cvs      1372:               *value = XhtmlAttrValueMappingTable[i].ThotAttrValue;
1.1       cvs      1373:           else 
1.2       cvs      1374:               i++;
                   1375:        while (*value <= 0 &&
                   1376:              XhtmlAttrValueMappingTable[i].ThotAttr != 0);
1.1       cvs      1377:      }
                   1378: }

Webmaster