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