comparison src/html.c @ 5093:89c0c811befa

[gaim-migrate @ 5455] jabber XHTML support. since people tend to not like to write valid XHTML all of the time, we now have html_to_xhtml() which does its best to figure out what you meant. i'm tired, hope this works for everyone committer: Tailor Script <tailor@pidgin.im>
author Nathan Walp <nwalp@pidgin.im>
date Thu, 10 Apr 2003 06:09:26 +0000
parents e23a7e166680
children a7e9036cd46f
comparison
equal deleted inserted replaced
5092:a4ad609ee6b3 5093:89c0c811befa
320 g_free(gunk->url); 320 g_free(gunk->url);
321 g_free(gunk); 321 g_free(gunk);
322 callback(data, g_strdup(_("g003: Error opening connection.\n")), 0); 322 callback(data, g_strdup(_("g003: Error opening connection.\n")), 0);
323 } 323 }
324 } 324 }
325
326 #define ALLOW_TAG_ALT(x, y) if(!g_ascii_strncasecmp(c, "<" x " ", strlen("<" x " "))) { \
327 char *o = strchr(c+1, '<'); \
328 char *p = strchr(c+1, '>'); \
329 if(p && (!o || p < o)) { \
330 if(*(p-1) != '/') \
331 tags = g_list_prepend(tags, y); \
332 xhtml = g_string_append(xhtml, "<" y); \
333 c += strlen("<" x ); \
334 xhtml = g_string_append_len(xhtml, c, (p - c) + 1); \
335 c = p + 1; \
336 } else { \
337 xhtml = g_string_append(xhtml, "&lt;"); \
338 } \
339 continue; \
340 } \
341 if(!g_ascii_strncasecmp(c, "<" x, strlen("<" x)) && \
342 (*(c+strlen("<" x)) == '>' || \
343 !g_ascii_strncasecmp(c+strlen("<" x), "/>", 2))) { \
344 xhtml = g_string_append(xhtml, "<" y); \
345 c += strlen("<" x); \
346 if(*c != '/') \
347 tags = g_list_prepend(tags, y); \
348 continue; \
349 }
350 #define ALLOW_TAG(x) ALLOW_TAG_ALT(x, x)
351
352 char *html_to_xhtml(const char *html) {
353 GString *xhtml = g_string_new("");
354 GList *tags = NULL, *tag;
355 const char *q = NULL, *c = html;
356 char *ret;
357 while(*c) {
358 if(!q && (*c == '\"' || *c == '\'')) {
359 q = c;
360 xhtml = g_string_append_c(xhtml, *c);
361 c++;
362 } else if(q) {
363 if(*c == *q) {
364 q = NULL;
365 } else if(*c == '\\') {
366 xhtml = g_string_append_c(xhtml, *c);
367 c++;
368 }
369 xhtml = g_string_append_c(xhtml, *c);
370 c++;
371 } else if(*c == '<') {
372 if(*(c+1) == '/') { /* closing tag */
373 tag = tags;
374 while(tag) {
375 if(!g_ascii_strncasecmp((c+2), tag->data, strlen(tag->data)) && *(c+strlen(tag->data)+2) == '>') {
376 c += strlen(tag->data) + 3;
377 break;
378 }
379 tag = tag->next;
380 }
381 if(tag) {
382 while(tags) {
383 g_string_append_printf(xhtml, "</%s>", (char *)tags->data);
384 if(tags == tag)
385 break;
386 tags = g_list_remove(tags, tags->data);
387 }
388 tags = g_list_remove(tags, tag->data);
389 } else {
390 /* we tried to close a tag we never opened! escape it
391 * and move on */
392 xhtml = g_string_append(xhtml, "&lt;");
393 c++;
394 }
395 } else { /* opening tag */
396 ALLOW_TAG("a");
397 ALLOW_TAG("b");
398 ALLOW_TAG("blockquote");
399 ALLOW_TAG("body");
400 ALLOW_TAG_ALT("bold", "b");
401 ALLOW_TAG("br");
402 ALLOW_TAG("cite");
403 ALLOW_TAG("div");
404 ALLOW_TAG("em");
405 ALLOW_TAG("font");
406 ALLOW_TAG("h1");
407 ALLOW_TAG("h2");
408 ALLOW_TAG("h3");
409 ALLOW_TAG("h4");
410 ALLOW_TAG("h5");
411 ALLOW_TAG("h6");
412 ALLOW_TAG("head");
413 ALLOW_TAG("hr");
414 ALLOW_TAG("html");
415 ALLOW_TAG("i");
416 ALLOW_TAG_ALT("italic", "i");
417 ALLOW_TAG("li");
418 ALLOW_TAG("ol");
419 ALLOW_TAG("p");
420 ALLOW_TAG("pre");
421 ALLOW_TAG("q");
422 ALLOW_TAG_ALT("s", "strike");
423 ALLOW_TAG("span");
424 ALLOW_TAG("strike");
425 ALLOW_TAG("strong");
426 ALLOW_TAG("sub");
427 ALLOW_TAG("sup");
428 ALLOW_TAG("title");
429 ALLOW_TAG("u");
430 ALLOW_TAG_ALT("underline","u");
431 ALLOW_TAG("ul");
432
433 if(!g_ascii_strncasecmp(c, "<!--", strlen("<!--"))) {
434 char *p = strstr(c + strlen("<!--"), "-->");
435 if(p) {
436 xhtml = g_string_append(xhtml, "<!--");
437 c += strlen("<!--");
438 continue;
439 }
440 }
441
442 xhtml = g_string_append(xhtml, "&lt;");
443 c++;
444 }
445 } else {
446 xhtml = g_string_append_c(xhtml, *c);
447 c++;
448 }
449 }
450 tag = tags;
451 while(tag) {
452 g_string_append_printf(xhtml, "</%s>", (char *)tag->data);
453 tag = tag->next;
454 }
455 g_list_free(tags);
456 ret = g_strdup(xhtml->str);
457 g_string_free(xhtml, TRUE);
458 return ret;
459 }