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