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