Annotation of Amaya/amaya/XHTMLbuilder.c, revision 1.54
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: {
1.53 vatton 256: *ptrText = tolower (*ptrText);
1.6 cvs 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: /*----------------------------------------------------------------------
1.47 cvs 282: XhtmlCannotContainText
283: Return TRUE if element el is a block element.
284: ----------------------------------------------------------------------*/
285: ThotBool XhtmlCannotContainText (ElementType elType)
286:
287: {
288: int i;
289: ThotBool ret;
290:
291: if (strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML"))
292: /* not an HTML element */
293: ret = TRUE;
294: else
295: {
296: ret = FALSE;
297: i = 0;
298: while (NoTextChild[i] > 0 && NoTextChild[i] != elType.ElTypeNum)
299: i++;
300: if (NoTextChild[i] == elType.ElTypeNum)
301: ret = TRUE;
302: }
303: return ret;
1.23 cvs 304: }
305:
1.6 cvs 306: /*----------------------------------------------------------------------
307: XhtmlElementComplete
1.20 cvs 308: Complete Xhtml elements.
1.6 cvs 309: Check its attributes and its contents.
310: ----------------------------------------------------------------------*/
1.51 cvs 311: void XhtmlElementComplete (Element el, Document doc, int *error)
1.30 cvs 312:
313: {
314: ElementType elType, newElType, childType;
315: Element constElem, child, desc, leaf, prev, next, last,
1.41 cvs 316: elFrames, lastFrame, lastChild, parent;
1.30 cvs 317: Attribute attr;
318: AttributeType attrType;
319: Language lang;
1.41 cvs 320: char *text;
1.39 cvs 321: char lastChar[2];
322: char *name1;
1.30 cvs 323: int length;
324: SSchema docSSchema;
1.6 cvs 325:
326: *error = 0;
327: docSSchema = TtaGetDocumentSSchema (doc);
328:
329: elType = TtaGetElementType (el);
330: /* is this a block-level element in a character-level element? */
1.27 cvs 331: if (!IsXMLElementInline (elType) &&
1.24 cvs 332: elType.ElTypeNum != HTML_EL_Comment_ &&
333: elType.ElTypeNum != HTML_EL_XMLPI)
1.6 cvs 334: BlockInCharLevelElem (el);
335:
336: newElType.ElSSchema = elType.ElSSchema;
337: switch (elType.ElTypeNum)
338: {
339: case HTML_EL_Object: /* it's an object */
340: /* create Object_Content */
341: child = TtaGetFirstChild (el);
342: if (child != NULL)
343: elType = TtaGetElementType (child);
344:
345: /* is it the PICTURE element ? */
346: if (child == NULL || elType.ElTypeNum != HTML_EL_PICTURE_UNIT)
347: {
348: desc = child;
349: /* create the PICTURE element */
350: elType.ElTypeNum = HTML_EL_PICTURE_UNIT;
351: child = TtaNewTree (doc, elType, "");
352: if (desc == NULL)
353: TtaInsertFirstChild (&child, el, doc);
354: else
355: TtaInsertSibling (child, desc, TRUE, doc);
356: }
357:
358: /* copy attribute data into SRC attribute of Object_Image */
359: attrType.AttrSSchema = docSSchema;
360: attrType.AttrTypeNum = HTML_ATTR_data;
361: attr = TtaGetAttribute (el, attrType);
362: if (attr != NULL)
363: {
364: length = TtaGetTextAttributeLength (attr);
365: if (length > 0)
366: {
1.37 cvs 367: name1 = TtaGetMemory (length + 1);
1.6 cvs 368: TtaGiveTextAttributeValue (attr, name1, &length);
369: attrType.AttrTypeNum = HTML_ATTR_SRC;
370: attr = TtaGetAttribute (child, attrType);
371: if (attr == NULL)
372: {
373: attr = TtaNewAttribute (attrType);
374: TtaAttachAttribute (child, attr, doc);
375: }
376: TtaSetAttributeText (attr, name1, child, doc);
377: TtaFreeMemory (name1);
378: }
379: }
380:
381: /* is the Object_Content element already created ? */
382: desc = child;
383: TtaNextSibling(&desc);
384: if (desc != NULL)
385: elType = TtaGetElementType (desc);
386:
387: /* is it the Object_Content element ? */
388: if (desc == NULL || elType.ElTypeNum != HTML_EL_Object_Content)
389: {
390: /* create Object_Content */
391: elType.ElTypeNum = HTML_EL_Object_Content;
392: desc = TtaNewTree (doc, elType, "");
393: TtaInsertSibling (desc, child, FALSE, doc);
394: /* move previous existing children into Object_Content */
395: child = TtaGetLastChild(el);
396: while (child != desc)
397: {
398: TtaRemoveTree (child, doc);
399: TtaInsertFirstChild (&child, desc, doc);
400: child = TtaGetLastChild(el);
401: }
402: }
403: break;
404:
405: case HTML_EL_Unnumbered_List:
406: case HTML_EL_Numbered_List:
407: case HTML_EL_Menu:
408: case HTML_EL_Directory:
409: /* It's a List element. It should only have List_Item children.
410: If it has List element chidren, move these List elements
411: within their previous List_Item sibling. This is to fix
412: a bug in document generated by Mozilla. */
413: prev = NULL;
414: next = NULL;
415: child = TtaGetFirstChild (el);
416: while (child != NULL)
417: {
418: next = child;
419: TtaNextSibling (&next);
420: elType = TtaGetElementType (child);
421: if (elType.ElTypeNum == HTML_EL_Unnumbered_List ||
422: elType.ElTypeNum == HTML_EL_Numbered_List ||
423: elType.ElTypeNum == HTML_EL_Menu ||
424: elType.ElTypeNum == HTML_EL_Directory)
425: /* this list element is a child of another list element */
426: if (prev)
427: {
428: elType = TtaGetElementType (prev);
429: if (elType.ElTypeNum == HTML_EL_List_Item)
430: {
431: /* get the last child of the previous List_Item */
432: desc = TtaGetFirstChild (prev);
433: last = NULL;
434: while (desc)
435: {
436: last = desc;
437: TtaNextSibling (&desc);
438: }
439: /* move the list element after the last child of the
440: previous List_Item */
441: TtaRemoveTree (child, doc);
442: if (last)
443: TtaInsertSibling (child, last, FALSE, doc);
444: else
445: TtaInsertFirstChild (&child, prev, doc);
446: child = prev;
447: }
448: }
449: prev = child;
450: child = next;
451: }
452: break;
453:
454: case HTML_EL_FRAMESET:
455: /* The FRAMESET element is now complete. Gather all its FRAMESET
456: and FRAME children and wrap them up in a Frames element */
457: elFrames = NULL; lastFrame = NULL;
458: lastChild = NULL;
459: child = TtaGetFirstChild (el);
460: while (child != NULL)
461: {
462: next = child;
463: TtaNextSibling (&next);
464: elType = TtaGetElementType (child);
465: if (elType.ElTypeNum == HTML_EL_FRAMESET ||
466: elType.ElTypeNum == HTML_EL_FRAME ||
467: elType.ElTypeNum == HTML_EL_Comment_)
468: {
469: /* create the Frames element if it does not exist */
470: if (elFrames == NULL)
471: {
472: newElType.ElSSchema = docSSchema;
473: newElType.ElTypeNum = HTML_EL_Frames;
474: elFrames = TtaNewElement (doc, newElType);
475: XmlSetElemLineNumber (elFrames);
476: TtaInsertSibling (elFrames, child, TRUE, doc);
477: }
478: /* move the element as the last child of the Frames element */
479: TtaRemoveTree (child, doc);
480: if (lastFrame == NULL)
481: TtaInsertFirstChild (&child, elFrames, doc);
482: else
483: TtaInsertSibling (child, lastFrame, FALSE, doc);
484: lastFrame = child;
485: }
486: child = next;
487: }
488: break;
489:
490: case HTML_EL_Input: /* it's an INPUT without any TYPE attribute */
491: /* Create a child of type Text_Input */
492: elType.ElTypeNum = HTML_EL_Text_Input;
493: child = TtaNewTree (doc, elType, "");
494: XmlSetElemLineNumber (child);
495: TtaInsertFirstChild (&child, el, doc);
496: /* now, process it like a Text_Input element */
497:
498: case HTML_EL_Text_Input:
499: case HTML_EL_Password_Input:
500: case HTML_EL_File_Input:
501: /* get element Inserted_Text */
502: child = TtaGetFirstChild (el);
503: if (child != NULL)
504: {
505: attrType.AttrSSchema = docSSchema;
506: attrType.AttrTypeNum = HTML_ATTR_Value_;
507: attr = TtaGetAttribute (el, attrType);
508: if (attr != NULL)
509: {
510: /* copy the value of attribute "value" into the first text
511: leaf of element */
512: length = TtaGetTextAttributeLength (attr);
513: if (length > 0)
514: {
515: /* get the text leaf */
516: leaf = TtaGetFirstChild (child);
517: if (leaf != NULL)
518: {
519: childType = TtaGetElementType (leaf);
520: if (childType.ElTypeNum == HTML_EL_TEXT_UNIT)
521: {
522: /* copy attribute value into the text leaf */
1.37 cvs 523: text = TtaGetMemory (length + 1);
1.6 cvs 524: TtaGiveTextAttributeValue (attr, text, &length);
525: TtaSetTextContent (leaf, text,
526: TtaGetDefaultLanguage (), doc);
527: TtaFreeMemory (text);
528: }
529: }
530: }
531: }
532: }
533: break;
534:
535: case HTML_EL_META:
1.15 cvs 536: ParseCharset (el, doc);
1.6 cvs 537: break;
538:
539: case HTML_EL_STYLE_: /* it's a STYLE element */
1.8 cvs 540: case HTML_EL_SCRIPT: /* it's a SCRIPT element */
1.6 cvs 541: case HTML_EL_Preformatted: /* it's a PRE */
542: /* if the last line of the Preformatted is empty, remove it */
543: leaf = XmlLastLeafInElement (el);
544: if (leaf != NULL)
545: {
546: elType = TtaGetElementType (leaf);
547: if (elType.ElTypeNum == HTML_EL_TEXT_UNIT)
548: /* the last leaf is a TEXT element */
549: {
550: length = TtaGetTextLength (leaf);
551: if (length > 0)
552: {
553: TtaGiveSubString (leaf, lastChar, length, 1);
554: if (lastChar[0] == EOL)
555: /* last character is new line, delete it */
556: {
557: if (length == 1)
558: /* empty TEXT element */
559: TtaDeleteTree (leaf, doc);
560: else
561: /* remove the last character */
562: TtaDeleteTextContent (leaf, length, 1, doc);
563: }
564: }
565: }
566: }
567: if (IsParsingCSS ())
568: {
569: text = GetStyleContents (el);
570: if (text)
571: {
1.42 cvs 572: ReadCSSRules (doc, NULL, text,
573: TtaGetElementLineNumber (el), FALSE);
1.6 cvs 574: TtaFreeMemory (text);
575: }
576: SetParsingCSS (FALSE);
577: }
578: /* and continue as if it were a Preformatted or a Script */
579: break;
580:
581: case HTML_EL_Text_Area: /* it's a Text_Area */
582: SetParsingTextArea (FALSE);
583: child = TtaGetFirstChild (el);
584: if (child == NULL)
585: /* it's an empty Text_Area */
586: /* insert a Inserted_Text element in the element */
587: {
588: newElType.ElTypeNum = HTML_EL_Inserted_Text;
589: child = TtaNewTree (doc, newElType, "");
590: TtaInsertFirstChild (&child, el, doc);
591: }
592: else
593: {
594: /* save the text into Default_Value attribute */
595: attrType.AttrSSchema = docSSchema;
596: attrType.AttrTypeNum = HTML_ATTR_Default_Value;
597: if (TtaGetAttribute (el, attrType) == NULL)
598: /* attribute Default_Value is missing */
599: {
600: attr = TtaNewAttribute (attrType);
601: TtaAttachAttribute (el, attr, doc);
602: desc = TtaGetFirstChild (child);
603: length = TtaGetTextLength (desc) + 1;
1.37 cvs 604: text = TtaGetMemory (length);
1.6 cvs 605: TtaGiveTextContent (desc, text, &length, &lang);
606: TtaSetAttributeText (attr, text, el, doc);
607: TtaFreeMemory (text);
608: }
609: }
610: /* insert a Frame element */
611: newElType.ElTypeNum = HTML_EL_Frame;
612: constElem = TtaNewTree (doc, newElType, "");
613: TtaInsertSibling (constElem, child, FALSE, doc);
614: break;
615:
616: case HTML_EL_Radio_Input:
617: case HTML_EL_Checkbox_Input:
618: /* put an attribute Checked if it is missing */
619: attrType.AttrSSchema = docSSchema;
620: attrType.AttrTypeNum = HTML_ATTR_Checked;
621: if (TtaGetAttribute (el, attrType) == NULL)
622: /* attribute Checked is missing */
623: {
624: attr = TtaNewAttribute (attrType);
625: TtaAttachAttribute (el, attr, doc);
626: TtaSetAttributeValue (attr, HTML_ATTR_Checked_VAL_No_, el, doc);
627: }
628: break;
629:
630: case HTML_EL_Option_Menu:
631: /* Check that at least one option has a SELECTED attribute */
632: OnlyOneOptionSelected (el, doc, TRUE);
633: break;
634:
635: case HTML_EL_PICTURE_UNIT:
636: break;
637:
638: case HTML_EL_LINK:
639: CheckCSSLink (el, doc, docSSchema);
640: break;
641:
642: case HTML_EL_Data_cell:
643: case HTML_EL_Heading_cell:
644: /* insert a pseudo paragraph into empty cells */
645: child = TtaGetFirstChild (el);
646: if (child == NULL)
647: {
648: elType.ElTypeNum = HTML_EL_Pseudo_paragraph;
649: child = TtaNewTree (doc, elType, "");
650: if (child != NULL)
651: TtaInsertFirstChild (&child, el, doc);
652: }
653:
654: /* detect whether we're parsing a whole table or just a cell */
655: if (IsWithinTable ())
656: NewCell (el, doc, FALSE);
657: break;
658:
659: case HTML_EL_Table:
660: CheckTable (el, doc);
661: SubWithinTable ();
662: break;
663:
664: case HTML_EL_TITLE:
665: /* show the TITLE in the main window */
666: UpdateTitle (el, doc);
667: break;
1.41 cvs 668:
669: case HTML_EL_rbc:
670: /* an rbc element has been read. Its parent should be a complex_ruby.
671: Change the type of the parent, as simple_ruby are created by
672: default */
673: parent = TtaGetParent (el);
674: if (parent)
675: {
676: newElType = TtaGetElementType (parent);
677: if (newElType.ElSSchema == elType.ElSSchema &&
678: newElType.ElTypeNum == HTML_EL_simple_ruby)
679: ChangeElementType (parent, HTML_EL_complex_ruby);
680: }
681: break;
682:
683: case HTML_EL_rtc1:
684: /* an rtc element has been parsed. If it has already a rtc1 sibling,
685: change its type to rtc2 */
686: prev = el;
687: do
688: {
689: TtaPreviousSibling(&prev);
690: if (prev)
691: {
692: newElType = TtaGetElementType (prev);
693: if (newElType.ElSSchema == elType.ElSSchema &&
694: newElType.ElTypeNum == HTML_EL_rtc1)
695: {
696: ChangeElementType (el, HTML_EL_rtc2);
697: prev = NULL;
698: }
699: }
700: }
701: while (prev);
702: break;
703:
1.6 cvs 704: default:
705: break;
706: }
707: }
1.1 cvs 708:
709: /*----------------------------------------------------------------------
1.30 cvs 710: PutInContent
711: Put the string ChrString in the leaf of current element.
712: ----------------------------------------------------------------------*/
1.39 cvs 713: Element PutInContent (char *ChrString, ParserData *context)
1.30 cvs 714:
715: {
716: Element el, child;
717: ElementType elType;
718: int length;
719:
720: el = NULL;
721: if (context->lastElement != NULL)
722: {
723: /* search first leaf of current element */
724: el = context->lastElement;
725: do
726: {
727: child = TtaGetFirstChild (el);
728: if (child != NULL)
729: el = child;
730: }
731: while (child != NULL);
732: elType = TtaGetElementType (el);
733: length = 0;
734: if (elType.ElTypeNum == 1)
735: length = TtaGetTextLength (el);
736: if (length == 0)
737: TtaSetTextContent (el, ChrString, context->language, context->doc);
738: else
739: TtaAppendTextContent (el, ChrString, context->doc);
740: }
741: return el;
742: }
743:
744: /*----------------------------------------------------------------------
1.51 cvs 745: UnknownXhtmlNameSpace
746: Create an element that belongs to a non-supported namespace
747: ----------------------------------------------------------------------*/
748: void UnknownXhtmlNameSpace (ParserData *context, char* content)
749: {
750: ElementType elType;
751: Element elInv, elText;
752:
753: /* Create a new Invalid_element */
754: elType.ElSSchema = GetXMLSSchema (XHTML_TYPE, context->doc);
755: elType.ElTypeNum = HTML_EL_Unknown_namespace;
756: elInv = TtaNewElement (context->doc, elType);
757: if (elInv != NULL)
758: {
759: XmlSetElemLineNumber (elInv);
760: InsertXmlElement (&elInv);
761: context->lastElementClosed = TRUE;
762: elType.ElTypeNum = HTML_EL_TEXT_UNIT;
763: elText = TtaNewElement (context->doc, elType);
764: XmlSetElemLineNumber (elText);
765: TtaInsertFirstChild (&elText, elInv, context->doc);
766: TtaSetTextContent (elText, content, context->language, context->doc);
767: TtaSetAccessRight (elText, ReadOnly, context->doc);
768: }
769: }
770:
771: /*----------------------------------------------------------------------
1.30 cvs 772: CreateHTMLAttribute
773: create an attribute of type attrType for the element el.
774: ----------------------------------------------------------------------*/
775: void CreateHTMLAttribute (Element el,
776: AttributeType attrType,
1.46 cvs 777: char* text,
1.30 cvs 778: ThotBool isInvalid,
779: Document doc,
780: Attribute *lastAttribute,
781: Element *lastAttrElement)
782:
783: {
784: int attrKind;
785: int length;
1.39 cvs 786: char *buffer;
1.30 cvs 787: Attribute attr, oldAttr;
788:
789: if (attrType.AttrTypeNum != 0)
790: {
791: oldAttr = TtaGetAttribute (el, attrType);
792: if (oldAttr != NULL)
793: /* this attribute already exists */
794: attr = oldAttr;
795: else
796: /* create a new attribute and attach it to the element */
797: {
798: attr = TtaNewAttribute (attrType);
799: TtaAttachAttribute (el, attr, doc);
800: }
801: *lastAttribute = attr;
802: *lastAttrElement = el;
803:
804: TtaGiveAttributeType (attr, &attrType, &attrKind);
805: if (attrKind == 0) /* enumerate */
806: TtaSetAttributeValue (attr, 1, el, doc);
807:
808: /* attribute BORDER without any value (ThotBool attribute) is */
809: /* considered as BORDER=1 */
810: if (attrType.AttrTypeNum == HTML_ATTR_Border)
811: TtaSetAttributeValue (attr, 1, el, doc);
812:
813: if (isInvalid)
814: /* Copy the name of the invalid attribute as the content */
815: /* of the Invalid_attribute attribute. */
816: {
1.37 cvs 817: length = strlen (text) + 2;
1.30 cvs 818: length += TtaGetTextAttributeLength (attr);
1.37 cvs 819: buffer = TtaGetMemory (length + 1);
1.30 cvs 820: TtaGiveTextAttributeValue (attr, buffer, &length);
1.37 cvs 821: strcat (buffer, " ");
822: strcat (buffer, text);
1.30 cvs 823: TtaSetAttributeText (attr, buffer, el, doc);
824: TtaFreeMemory (buffer);
825: }
826: }
827: }
828:
829: /*----------------------------------------------------------------------
830: HTMLTypeAttrValue
831: Value val has been read for the HTML attribute TYPE.
832: Create a child for the current Thot element INPUT accordingly.
833: ----------------------------------------------------------------------*/
1.46 cvs 834: void HTMLTypeAttrValue (char *val,
1.30 cvs 835: Attribute lastAttribute,
836: Element lastAttrElement,
837: ParserData *context)
838:
839: {
840: ElementType elType;
841: Element newChild;
842: AttributeType attrType;
843: Attribute attr;
1.39 cvs 844: char msgBuffer[MaxMsgLength];
1.30 cvs 845: int value;
846: int numberOfLinesRead;
847:
848: value = MapAttrValue (DummyAttribute, val);
849: if (value < 0)
850: {
1.37 cvs 851: if (strlen (val) > MaxMsgLength - 40)
852: val[MaxMsgLength - 40] = EOS;
853: sprintf (msgBuffer, "Unknown attribute value \"type = %s\"", val);
1.42 cvs 854: HTMLParseError (context->doc, msgBuffer);
1.30 cvs 855: attrType.AttrSSchema = TtaGetDocumentSSchema (context->doc);
856: attrType.AttrTypeNum = pHTMLAttributeMapping[0].ThotAttribute;
1.37 cvs 857: sprintf (msgBuffer, "type=%s", val);
1.30 cvs 858: CreateHTMLAttribute (context->lastElement, attrType, msgBuffer, TRUE,
859: context->doc, &lastAttribute, &lastAttrElement);
860: }
861: else
862: {
863: elType = TtaGetElementType (context->lastElement);
864: if (elType.ElTypeNum != HTML_EL_Input)
865: {
1.37 cvs 866: if (strlen (val) > MaxMsgLength - 40)
867: val[MaxMsgLength - 40] = EOS;
868: sprintf (msgBuffer, "Duplicate attribute \"type = %s\"", val);
1.30 cvs 869: }
870: else
871: {
872: elType.ElSSchema = TtaGetDocumentSSchema (context->doc);
873: elType.ElTypeNum = value;
874: newChild = TtaNewTree (context->doc, elType, "");
875: numberOfLinesRead = 0;
876: TtaSetElementLineNumber (newChild, numberOfLinesRead);
877: TtaInsertFirstChild (&newChild, context->lastElement, context->doc);
878: if (value == HTML_EL_PICTURE_UNIT)
879: {
880: /* add the attribute IsInput to input pictures */
881: attrType.AttrSSchema = elType.ElSSchema;
882: attrType.AttrTypeNum = HTML_ATTR_IsInput;
883: attr = TtaNewAttribute (attrType);
884: TtaAttachAttribute (newChild, attr, context->doc);
885: }
886: }
887: }
888: }
889:
890: /*----------------------------------------------------------------------
891: XhtmlTypeAttrValue
892: Value val has been read for the HTML attribute TYPE.
893: Create a child for the current Thot element INPUT accordingly.
894: ----------------------------------------------------------------------*/
1.46 cvs 895: void XhtmlTypeAttrValue (char *val,
1.30 cvs 896: Attribute currentAttribute,
897: Element lastAttrElement,
898: ParserData *context)
899:
900: {
901: ElementType elType;
902: Element newChild;
903: AttributeType attrType;
904: Attribute attr;
1.39 cvs 905: char msgBuffer[MaxMsgLength];
1.30 cvs 906: int value;
907: ThotBool level;
908:
909: attrType.AttrTypeNum = DummyAttribute;
910: MapHTMLAttributeValue (val, attrType, &value);
911: if (value < 0)
912: {
1.37 cvs 913: sprintf (msgBuffer, "Unknown attribute value \"type=%s\"", val);
1.30 cvs 914: XmlParseError (errorParsing, msgBuffer, 0);
1.36 cvs 915: MapHTMLAttribute ("unknown_attr", &attrType, NULL,
1.30 cvs 916: &level, context->doc);
1.37 cvs 917: sprintf (msgBuffer, "type=%s", val);
1.30 cvs 918: CreateHTMLAttribute (context->lastElement, attrType, msgBuffer, TRUE,
919: context->doc, ¤tAttribute, &lastAttrElement);
920: }
921: else
922: {
923: elType = TtaGetElementType (context->lastElement);
924: if (elType.ElTypeNum != HTML_EL_Input)
925: {
1.37 cvs 926: sprintf (msgBuffer, "Duplicate attribute \"type = %s\"", val);
1.30 cvs 927: XmlParseError (errorParsing, msgBuffer, 0);
928: }
929: else
930: {
931: elType.ElTypeNum = value;
932: newChild = TtaNewTree (context->doc, elType, "");
933: XmlSetElemLineNumber (newChild);
934: TtaInsertFirstChild (&newChild, context->lastElement, context->doc);
935: if (value == HTML_EL_PICTURE_UNIT)
936: {
937: /* add the attribute IsInput to input pictures */
938: attrType.AttrSSchema = elType.ElSSchema;
939: attrType.AttrTypeNum = HTML_ATTR_IsInput;
940: attr = TtaNewAttribute (attrType);
941: TtaAttachAttribute (newChild, attr, context->doc);
942: }
943: }
944: }
945: }
946:
947: /*----------------------------------------------------------------------
948: CreateAttrWidthPercentPxl
949: an HTML attribute "width" has been created for a Table of a HR.
950: Create the corresponding attribute IntWidthPercent or IntWidthPxl.
951: oldWidth is -1 or the old image width.
952: ----------------------------------------------------------------------*/
1.39 cvs 953: void CreateAttrWidthPercentPxl (char *buffer, Element el,
1.30 cvs 954: Document doc, int oldWidth)
955:
956: {
957: AttributeType attrTypePxl, attrTypePercent;
958: Attribute attrOld, attrNew;
959: int length, val;
1.39 cvs 960: char msgBuffer[MaxMsgLength];
1.30 cvs 961: ElementType elType;
962: int w, h;
963: ThotBool isImage;
964:
965: elType = TtaGetElementType (el);
966: isImage = (elType.ElTypeNum == HTML_EL_PICTURE_UNIT ||
967: elType.ElTypeNum == HTML_EL_Data_cell ||
968: elType.ElTypeNum == HTML_EL_Heading_cell);
969:
970: /* remove trailing spaces */
1.37 cvs 971: length = strlen (buffer) - 1;
1.30 cvs 972: while (length > 0 && buffer[length] <= SPACE)
973: length--;
974: attrTypePxl.AttrSSchema = TtaGetDocumentSSchema (doc);
975: attrTypePercent.AttrSSchema = TtaGetDocumentSSchema (doc);
976: attrTypePxl.AttrTypeNum = HTML_ATTR_IntWidthPxl;
977: attrTypePercent.AttrTypeNum = HTML_ATTR_IntWidthPercent;
978: /* is the last character a '%' ? */
979: if (buffer[length] == '%')
980: {
981: /* remove IntWidthPxl */
982: attrOld = TtaGetAttribute (el, attrTypePxl);
983: /* update IntWidthPercent */
984: attrNew = TtaGetAttribute (el, attrTypePercent);
985: if (attrNew == NULL)
986: {
987: attrNew = TtaNewAttribute (attrTypePercent);
988: TtaAttachAttribute (el, attrNew, doc);
989: }
990: else if (isImage && oldWidth == -1)
991: {
992: if (attrOld == NULL)
993: oldWidth = TtaGetAttributeValue (attrNew);
994: else
995: oldWidth = TtaGetAttributeValue (attrOld);
996: }
997: }
998: else
999: {
1000: /* remove IntWidthPercent */
1001: attrOld = TtaGetAttribute (el, attrTypePercent);
1002: /* update IntWidthPxl */
1003: attrNew = TtaGetAttribute (el, attrTypePxl);
1004: if (attrNew == NULL)
1005: {
1006: attrNew = TtaNewAttribute (attrTypePxl);
1007: TtaAttachAttribute (el, attrNew, doc);
1008: }
1009: else if (isImage && oldWidth == -1)
1010: {
1011: TtaGiveBoxSize (el, doc, 1, UnPixel, &w, &h);
1012: if (attrOld == NULL)
1013: oldWidth = w * TtaGetAttributeValue (attrNew) / 100;
1014: else
1015: oldWidth = w * TtaGetAttributeValue (attrOld) / 100;
1016: }
1017: }
1018:
1019: if (attrOld != NULL)
1020: TtaRemoveAttribute (el, attrOld, doc);
1.43 cvs 1021: if (sscanf (buffer, "%d", &val))
1.30 cvs 1022: TtaSetAttributeValue (attrNew, val, el, doc);
1023: else
1024: /* its not a number. Delete attribute and send an error message */
1025: {
1026: TtaRemoveAttribute (el, attrNew, doc);
1.37 cvs 1027: if (strlen (buffer) > MaxMsgLength - 30)
1.30 cvs 1028: buffer[MaxMsgLength - 30] = EOS;
1.37 cvs 1029: sprintf (msgBuffer, "Invalid attribute value \"%s\"", buffer);
1.42 cvs 1030: HTMLParseError (doc, msgBuffer);
1.30 cvs 1031: }
1032: if (isImage)
1033: UpdateImageMap (el, doc, oldWidth, -1);
1034: }
1035:
1036: /*----------------------------------------------------------------------
1037: CreateAttrIntSize
1038: an HTML attribute "size" has been created for a Font element.
1039: Create the corresponding internal attribute.
1040: ----------------------------------------------------------------------*/
1.46 cvs 1041: void CreateAttrIntSize (char *buffer, Element el, Document doc)
1.30 cvs 1042:
1043: {
1044: AttributeType attrType;
1045: int val, ind, factor, delta;
1046: Attribute attr;
1.37 cvs 1047: char msgBuffer[MaxMsgLength];
1.30 cvs 1048:
1049: /* is the first character a '+' or a '-' ? */
1050: ind = 0;
1051: factor = 1;
1052: delta = 0;
1053: if (buffer[0] == '+')
1054: {
1055: attrType.AttrTypeNum = HTML_ATTR_IntSizeIncr;
1056: ind++;
1057: factor = 2;
1058: }
1059: else if (buffer[0] == '-')
1060: {
1061: attrType.AttrTypeNum = HTML_ATTR_IntSizeDecr;
1062: ind++;
1063: factor = 2;
1064: }
1065: else
1066: {
1067: attrType.AttrTypeNum = HTML_ATTR_IntSizeRel;
1068: delta = 1;
1069: }
1070: attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
1071: attr = TtaGetAttribute (el, attrType);
1.43 cvs 1072: if (sscanf (&buffer[ind], "%d", &val))
1.30 cvs 1073: {
1074: val = val * factor + delta;
1075: if (attr == NULL)
1076: {
1077: /* this attribute doesn't exist, create it */
1078: attr = TtaNewAttribute (attrType);
1079: TtaAttachAttribute (el, attr, doc);
1080: }
1081: TtaSetAttributeValue (attr, val, el, doc);
1082: }
1083: else
1084: /* its not a number. Delete attribute and send an error message */
1085: {
1086: if (attr)
1087: TtaRemoveAttribute (el, attr, doc);
1.37 cvs 1088: if (strlen (buffer) > MaxMsgLength - 30)
1.30 cvs 1089: buffer[MaxMsgLength - 30] = EOS;
1.37 cvs 1090: sprintf (msgBuffer, "Invalid attribute value \"%s\"", buffer);
1.42 cvs 1091: HTMLParseError (doc, msgBuffer);
1.30 cvs 1092: }
1093: }
1094: /*----------------------------------------------------------------------
1095: EndOfHTMLAttributeValue
1096: Filling of an HTML attribute value
1097: ----------------------------------------------------------------------*/
1.48 vatton 1098: void EndOfHTMLAttributeValue (char *attrValue,
1099: AttributeMapping *lastMappedAttr,
1100: Attribute currentAttribute,
1101: Element lastAttrElement,
1102: ThotBool UnknownAttr,
1103: ParserData *context,
1104: ThotBool isXML)
1.30 cvs 1105: {
1.48 vatton 1106: AttributeType attrType, attrType1;
1107: Attribute attr;
1108: ElementType elType;
1109: Element child, root;
1110: Language lang;
1111: char translation;
1112: char shape;
1113: char *buffer;
1114: char *attrName;
1115: char msgBuffer[MaxMsgLength];
1116: int val;
1117: int length;
1118: int attrKind;
1119: ThotBool done = FALSE;
1.30 cvs 1120:
1.48 vatton 1121: /* treatments of some particular HTML attributes */
1122: if (!strcmp (lastMappedAttr->XMLattribute, "style"))
1123: {
1124: TtaSetAttributeText (currentAttribute, attrValue,
1125: lastAttrElement, context->doc);
1126: ParseHTMLSpecificStyle (context->lastElement, attrValue,
1127: context->doc, 1, FALSE);
1128: done = TRUE;
1129: }
1130: else
1131: {
1132: if (!strcmp (lastMappedAttr->XMLattribute, "link"))
1133: HTMLSetAlinkColor (context->doc, attrValue);
1134: else if (!strcmp (lastMappedAttr->XMLattribute, "alink"))
1135: HTMLSetAactiveColor (context->doc, attrValue);
1136: else if (!strcmp (lastMappedAttr->XMLattribute, "vlink"))
1137: HTMLSetAvisitedColor (context->doc, attrValue);
1138: }
1.30 cvs 1139:
1.48 vatton 1140: if (!done)
1141: {
1142: val = 0;
1143: translation = lastMappedAttr->AttrOrContent;
1144: switch (translation)
1145: {
1146: case 'C': /* Content */
1147: child = PutInContent (attrValue, context);
1148: if (child != NULL)
1149: TtaAppendTextContent (child, "\" ", context->doc);
1150: break;
1151:
1152: case 'A':
1153: if (currentAttribute != NULL)
1154: {
1155: TtaGiveAttributeType (currentAttribute, &attrType, &attrKind);
1156: switch (attrKind)
1157: {
1158: case 0: /* enumerate */
1159: if (isXML)
1160: MapHTMLAttributeValue (attrValue, attrType, &val);
1161: else
1162: val = MapAttrValue (lastMappedAttr->ThotAttribute,
1.40 cvs 1163: attrValue);
1.48 vatton 1164: if (val < 0)
1165: {
1166: TtaGiveAttributeType (currentAttribute,
1167: &attrType, &attrKind);
1168: attrName = TtaGetAttributeName (attrType);
1169: sprintf (msgBuffer,
1.51 cvs 1170: "Invalid attribute value \"%s = %s\"",
1.48 vatton 1171: attrName, attrValue);
1172: if (isXML)
1173: XmlParseError (errorParsing, msgBuffer, 0);
1174: else
1.51 cvs 1175: {
1176: HTMLParseError (context->doc, msgBuffer);
1.48 vatton 1177: /* remove the attribute and replace it by an */
1.51 cvs 1178: /* Invalid_attribute (not for XHTML) */
1179: TtaRemoveAttribute (lastAttrElement,
1180: currentAttribute, context->doc);
1.48 vatton 1181: attrType.AttrSSchema =
1182: TtaGetDocumentSSchema (context->doc);
1183: attrType.AttrTypeNum =
1184: pHTMLAttributeMapping[0].ThotAttribute;
1.51 cvs 1185: sprintf (msgBuffer, "%s=%s", attrName, attrValue);
1186: CreateHTMLAttribute (lastAttrElement, attrType,
1187: msgBuffer, TRUE, context->doc,
1188: ¤tAttribute,
1189: &lastAttrElement);
1.48 vatton 1190: }
1191: }
1192: else
1193: TtaSetAttributeValue (currentAttribute, val,
1194: lastAttrElement, context->doc);
1195: break;
1196: case 1: /* integer */
1197: if (attrType.AttrTypeNum == HTML_ATTR_Border &&
1198: !strcasecmp (attrValue, "border"))
1199: {
1200: /* border="border" for a table */
1201: val = 1;
1202: TtaSetAttributeValue (currentAttribute, val,
1.30 cvs 1203: lastAttrElement, context->doc);
1.48 vatton 1204: }
1205: else if (sscanf (attrValue, "%d", &val))
1206: TtaSetAttributeValue (currentAttribute, val,
1207: lastAttrElement, context->doc);
1208: else
1209: {
1210: TtaRemoveAttribute (lastAttrElement, currentAttribute,
1211: context->doc);
1212: sprintf (msgBuffer,
1213: "Unknown attribute value \"%s\"",
1214: attrValue);
1215: if (isXML)
1216: XmlParseError (errorParsing, msgBuffer, 0);
1217: else
1218: HTMLParseError (context->doc, msgBuffer);
1219: }
1220: break;
1221: case 2: /* text */
1222: if (!UnknownAttr)
1223: {
1224: TtaSetAttributeText (currentAttribute, attrValue,
1225: lastAttrElement, context->doc);
1226: if (attrType.AttrTypeNum == HTML_ATTR_Langue)
1227: {
1228: /* it's a LANG attribute value */
1229: lang = TtaGetLanguageIdFromName (attrValue);
1230: if (lang == 0)
1231: {
1232: sprintf (msgBuffer,
1233: "warning - unsupported language: %s",
1234: attrValue);
1235: if (isXML)
1236: XmlParseError (errorParsing, msgBuffer, 0);
1237: else
1238: HTMLParseError (context->doc, msgBuffer);
1239: }
1240: else
1241: {
1242: /* change current language */
1243: context->language = lang;
1244: if (isXML)
1245: SetLanguagInXmlStack (lang);
1246: else
1247: SetLanguagInHTMLStack (lang);
1248: }
1249: root = TtaGetRootElement (context->doc);
1250: if (lastAttrElement == root)
1251: /* it's a LANG attribute on the root element */
1252: /* set the RealLang attribute */
1253: {
1254: attrType1.AttrSSchema = TtaGetDocumentSSchema (context->doc);
1255: attrType1.AttrTypeNum = HTML_ATTR_RealLang;
1256: /* this attribute could be already present,
1257: (lang and xml:lang attributes) */
1258: if (!TtaGetAttribute (lastAttrElement,
1259: attrType1))
1260: /* it's not present. Add it */
1261: {
1262: attr = TtaNewAttribute (attrType1);
1263: TtaAttachAttribute (lastAttrElement,
1264: attr, context->doc);
1265: TtaSetAttributeValue (attr,
1266: HTML_ATTR_RealLang_VAL_Yes_,
1267: lastAttrElement,
1268: context->doc);
1269: }
1270: }
1271: }
1272: else if (attrType.AttrTypeNum == HTML_ATTR_accesskey)
1273: TtaAddAccessKey (context->doc, (unsigned int)attrValue[0],
1274: lastAttrElement);
1275: }
1276: else
1277: {
1.51 cvs 1278: /* this is the content of an invalid attribute */
1279: /* append it to the current Invalid_attribute */
1280: if (!isXML)
1281: {
1282: length = strlen (attrValue) + 2;
1283: length += TtaGetTextAttributeLength (currentAttribute);
1284: buffer = TtaGetMemory (length + 1);
1285: TtaGiveTextAttributeValue (currentAttribute,
1286: buffer, &length);
1287: strcat (buffer, "=");
1288: strcat (buffer, attrValue);
1289: TtaSetAttributeText (currentAttribute, buffer,
1290: lastAttrElement, context->doc);
1291: TtaFreeMemory (buffer);
1292: }
1.48 vatton 1293: }
1294: break;
1295: case 3: /* reference */
1296: break;
1297: }
1298: }
1299: break;
1300:
1301: case SPACE:
1302: if (isXML)
1303: XhtmlTypeAttrValue (attrValue, currentAttribute,
1.30 cvs 1304: lastAttrElement, context);
1.48 vatton 1305: else
1306: HTMLTypeAttrValue (attrValue, currentAttribute,
1307: lastAttrElement, context);
1308: break;
1309:
1.30 cvs 1310: default:
1311: break;
1.48 vatton 1312: }
1.30 cvs 1313:
1314: if (lastMappedAttr->ThotAttribute == HTML_ATTR_Width__)
1.48 vatton 1315: /* HTML attribute "width" for a table or a hr */
1316: /* create the corresponding attribute IntWidthPercent or */
1317: /* IntWidthPxl */
1318: CreateAttrWidthPercentPxl (attrValue, lastAttrElement, context->doc, -1);
1319: else if (!strcmp (lastMappedAttr->XMLattribute, "size"))
1320: {
1321: TtaGiveAttributeType (currentAttribute, &attrType, &attrKind);
1322: if (attrType.AttrTypeNum == HTML_ATTR_Font_size)
1323: CreateAttrIntSize (attrValue, lastAttrElement, context->doc);
1324: }
1325: else if (!strcmp (lastMappedAttr->XMLattribute, "shape"))
1326: {
1327: child = TtaGetFirstChild (lastAttrElement);
1328: if (child != NULL)
1329: {
1330: switch (val)
1331: {
1332: case HTML_ATTR_shape_VAL_rectangle:
1333: shape = 'R';
1334: break;
1335: case HTML_ATTR_shape_VAL_circle:
1336: shape = 'a';
1337: break;
1338: case HTML_ATTR_shape_VAL_polygon:
1339: shape = 'p';
1340: break;
1341: default:
1342: shape = SPACE;
1343: break;
1344: }
1345: TtaSetGraphicsShape (child, shape, context->doc);
1346: }
1347: }
1348: else if (!strcmp (lastMappedAttr->XMLattribute, "value"))
1349: {
1350: elType = TtaGetElementType (lastAttrElement);
1351: if (elType.ElTypeNum == HTML_EL_Text_Input ||
1352: elType.ElTypeNum == HTML_EL_Password_Input ||
1353: elType.ElTypeNum == HTML_EL_File_Input ||
1354: elType.ElTypeNum == HTML_EL_Input)
1355: /* create a Default_Value attribute with the same content */
1356: {
1357: attrType1.AttrSSchema = attrType.AttrSSchema;
1358: attrType1.AttrTypeNum = HTML_ATTR_Default_Value;
1359: attr = TtaNewAttribute (attrType1);
1360: TtaAttachAttribute (lastAttrElement, attr, context->doc);
1361: TtaSetAttributeText (attr, attrValue,
1362: lastAttrElement, context->doc);
1363: }
1364: }
1.30 cvs 1365: else
1.48 vatton 1366: {
1367: /* Some HTML attributes are equivalent to a CSS property: */
1368: /* background -> background */
1369: /* bgcolor -> background */
1370: /* text -> color */
1371: /* color -> color */
1372: if (!strcmp (lastMappedAttr->XMLattribute, "background"))
1373: {
1374: if (strlen (attrValue) > MaxMsgLength - 30)
1375: attrValue[MaxMsgLength - 30] = EOS;
1376: HTMLSetBackgroundImage (context->doc,
1377: context->lastElement, STYLE_REPEAT, attrValue);
1378: }
1379: else if (!strcmp (lastMappedAttr->XMLattribute, "bgcolor"))
1380: HTMLSetBackgroundColor (context->doc,
1381: context->lastElement, attrValue);
1382: else if (!strcmp (lastMappedAttr->XMLattribute, "text") ||
1383: !strcmp (lastMappedAttr->XMLattribute, "color"))
1384: HTMLSetForegroundColor (context->doc,
1385: context->lastElement, attrValue);
1386: }
1387: }
1.30 cvs 1388: }
1389:
1390: /*----------------------------------------------------------------------
1.16 cvs 1391: MapHTMLAttributeValue
1.2 cvs 1392: Search in the Attribute Value Mapping Table the entry for the attribute
1393: ThotAtt and its value AttrVal. Returns the corresponding Thot value.
1.1 cvs 1394: ----------------------------------------------------------------------*/
1.39 cvs 1395: void MapHTMLAttributeValue (char *AttrVal,
1.30 cvs 1396: AttributeType attrType,
1397: int *value)
1.1 cvs 1398: {
1.45 cvs 1399: int i;
1.2 cvs 1400:
1.45 cvs 1401: *value = 0;
1402: i = 0;
1403: while (XhtmlAttrValueMappingTable[i].ThotAttr != attrType.AttrTypeNum &&
1404: XhtmlAttrValueMappingTable[i].ThotAttr != 0)
1405: i++;
1406: if (XhtmlAttrValueMappingTable[i].ThotAttr == attrType.AttrTypeNum)
1407: do
1408: if (!strcmp (XhtmlAttrValueMappingTable[i].XMLattrValue, AttrVal))
1409: *value = XhtmlAttrValueMappingTable[i].ThotAttrValue;
1410: else
1411: i++;
1412: while (*value <= 0 &&
1413: XhtmlAttrValueMappingTable[i].ThotAttr == attrType.AttrTypeNum);
1.1 cvs 1414: }
Webmaster