libpurple/protocols/myspace/markup.c

branch
soc.2013.gobjectification
changeset 34935
686fa55b0deb
parent 31804
847a13d5d3bb
equal deleted inserted replaced
34934:d50c4b767a5e 34935:686fa55b0deb
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
18 */ 18 */
19 19
20 #include "myspace.h" 20 #include "myspace.h"
21 21
22 typedef int (*MSIM_XMLNODE_CONVERT)(MsimSession *, xmlnode *, gchar **, gchar **); 22 typedef int (*MSIM_XMLNODE_CONVERT)(MsimSession *, PurpleXmlNode *, gchar **, gchar **);
23 23
24 /* Globals */ 24 /* Globals */
25 25
26 /* The names in in emoticon_names (for <i n=whatever>) map to corresponding 26 /* The names in in emoticon_names (for <i n=whatever>) map to corresponding
27 * entries in emoticon_symbols (for the ASCII representation of the emoticon). 27 * entries in emoticon_symbols (for the ASCII representation of the emoticon).
190 190
191 /** 191 /**
192 * Convert the msim markup <f> (font) tag into HTML. 192 * Convert the msim markup <f> (font) tag into HTML.
193 */ 193 */
194 static void 194 static void
195 msim_markup_f_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end) 195 msim_markup_f_to_html(MsimSession *session, PurpleXmlNode *root, gchar **begin, gchar **end)
196 { 196 {
197 const gchar *face, *height_str, *decor_str; 197 const gchar *face, *height_str, *decor_str;
198 GString *gs_end, *gs_begin; 198 GString *gs_end, *gs_begin;
199 guint decor, height; 199 guint decor, height;
200 200
201 face = xmlnode_get_attrib(root, "f"); 201 face = purple_xmlnode_get_attrib(root, "f");
202 height_str = xmlnode_get_attrib(root, "h"); 202 height_str = purple_xmlnode_get_attrib(root, "h");
203 decor_str = xmlnode_get_attrib(root, "s"); 203 decor_str = purple_xmlnode_get_attrib(root, "s");
204 204
205 /* Validate the font face, to avoid constructing invalid HTML later */ 205 /* Validate the font face, to avoid constructing invalid HTML later */
206 if (face != NULL && strchr(face, '\'') != NULL) 206 if (face != NULL && strchr(face, '\'') != NULL)
207 face = NULL; 207 face = NULL;
208 208
281 281
282 /** 282 /**
283 * Convert the msim markup <a> (anchor) tag into HTML. 283 * Convert the msim markup <a> (anchor) tag into HTML.
284 */ 284 */
285 static void 285 static void
286 msim_markup_a_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end) 286 msim_markup_a_to_html(MsimSession *session, PurpleXmlNode *root, gchar **begin, gchar **end)
287 { 287 {
288 const gchar *href; 288 const gchar *href;
289 289
290 href = xmlnode_get_attrib(root, "h"); 290 href = purple_xmlnode_get_attrib(root, "h");
291 if (!href) { 291 if (!href) {
292 href = ""; 292 href = "";
293 } 293 }
294 294
295 *begin = g_strdup_printf("<a href=\"%s\">%s", href, href); 295 *begin = g_strdup_printf("<a href=\"%s\">%s", href, href);
298 298
299 /** 299 /**
300 * Convert the msim markup <p> (paragraph) tag into HTML. 300 * Convert the msim markup <p> (paragraph) tag into HTML.
301 */ 301 */
302 static void 302 static void
303 msim_markup_p_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end) 303 msim_markup_p_to_html(MsimSession *session, PurpleXmlNode *root, gchar **begin, gchar **end)
304 { 304 {
305 /* Just pass through unchanged. 305 /* Just pass through unchanged.
306 * 306 *
307 * Note: attributes currently aren't passed, if there are any. */ 307 * Note: attributes currently aren't passed, if there are any. */
308 *begin = g_strdup("<p>"); 308 *begin = g_strdup("<p>");
311 311
312 /** 312 /**
313 * Convert the msim markup <c> tag (text color) into HTML. 313 * Convert the msim markup <c> tag (text color) into HTML.
314 */ 314 */
315 static void 315 static void
316 msim_markup_c_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end) 316 msim_markup_c_to_html(MsimSession *session, PurpleXmlNode *root, gchar **begin, gchar **end)
317 { 317 {
318 const gchar *color; 318 const gchar *color;
319 gchar *purple_color; 319 gchar *purple_color;
320 320
321 color = xmlnode_get_attrib(root, "v"); 321 color = purple_xmlnode_get_attrib(root, "v");
322 if (!color) { 322 if (!color) {
323 purple_debug_info("msim", "msim_markup_c_to_html: <c> tag w/o v attr\n"); 323 purple_debug_info("msim", "msim_markup_c_to_html: <c> tag w/o v attr\n");
324 *begin = g_strdup(""); 324 *begin = g_strdup("");
325 *end = g_strdup(""); 325 *end = g_strdup("");
326 /* TODO: log as unrecognized */ 326 /* TODO: log as unrecognized */
342 342
343 /** 343 /**
344 * Convert the msim markup <b> tag (background color) into HTML. 344 * Convert the msim markup <b> tag (background color) into HTML.
345 */ 345 */
346 static void 346 static void
347 msim_markup_b_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end) 347 msim_markup_b_to_html(MsimSession *session, PurpleXmlNode *root, gchar **begin, gchar **end)
348 { 348 {
349 const gchar *color; 349 const gchar *color;
350 gchar *purple_color; 350 gchar *purple_color;
351 351
352 color = xmlnode_get_attrib(root, "v"); 352 color = purple_xmlnode_get_attrib(root, "v");
353 if (!color) { 353 if (!color) {
354 *begin = g_strdup(""); 354 *begin = g_strdup("");
355 *end = g_strdup(""); 355 *end = g_strdup("");
356 purple_debug_info("msim", "msim_markup_b_to_html: <b> w/o v attr\n"); 356 purple_debug_info("msim", "msim_markup_b_to_html: <b> w/o v attr\n");
357 /* TODO: log as unrecognized. */ 357 /* TODO: log as unrecognized. */
373 373
374 /** 374 /**
375 * Convert the msim markup <i> tag (emoticon image) into HTML. 375 * Convert the msim markup <i> tag (emoticon image) into HTML.
376 */ 376 */
377 static void 377 static void
378 msim_markup_i_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end) 378 msim_markup_i_to_html(MsimSession *session, PurpleXmlNode *root, gchar **begin, gchar **end)
379 { 379 {
380 const gchar *name; 380 const gchar *name;
381 guint i; 381 guint i;
382 struct MSIM_EMOTICON *emote; 382 struct MSIM_EMOTICON *emote;
383 383
384 name = xmlnode_get_attrib(root, "n"); 384 name = purple_xmlnode_get_attrib(root, "n");
385 if (!name) { 385 if (!name) {
386 purple_debug_info("msim", "msim_markup_i_to_html: <i> w/o n\n"); 386 purple_debug_info("msim", "msim_markup_i_to_html: <i> w/o n\n");
387 *begin = g_strdup(""); 387 *begin = g_strdup("");
388 *end = g_strdup(""); 388 *end = g_strdup("");
389 /* TODO: log as unrecognized */ 389 /* TODO: log as unrecognized */
406 406
407 /** 407 /**
408 * Convert an individual msim markup tag to HTML. 408 * Convert an individual msim markup tag to HTML.
409 */ 409 */
410 static int 410 static int
411 msim_markup_tag_to_html(MsimSession *session, xmlnode *root, gchar **begin, 411 msim_markup_tag_to_html(MsimSession *session, PurpleXmlNode *root, gchar **begin,
412 gchar **end) 412 gchar **end)
413 { 413 {
414 g_return_val_if_fail(root != NULL, 0); 414 g_return_val_if_fail(root != NULL, 0);
415 415
416 if (g_str_equal(root->name, "f")) { 416 if (g_str_equal(root->name, "f")) {
437 437
438 /** 438 /**
439 * Convert an individual HTML tag to msim markup. 439 * Convert an individual HTML tag to msim markup.
440 */ 440 */
441 static int 441 static int
442 html_tag_to_msim_markup(MsimSession *session, xmlnode *root, gchar **begin, 442 html_tag_to_msim_markup(MsimSession *session, PurpleXmlNode *root, gchar **begin,
443 gchar **end) 443 gchar **end)
444 { 444 {
445 int ret = 0; 445 int ret = 0;
446 446
447 if (!purple_utf8_strcasecmp(root->name, "root") || 447 if (!purple_utf8_strcasecmp(root->name, "root") ||
451 /* TODO: Coalesce nested tags into one <f> tag! 451 /* TODO: Coalesce nested tags into one <f> tag!
452 * Currently, the 's' value will be overwritten when b/i/u is nested 452 * Currently, the 's' value will be overwritten when b/i/u is nested
453 * within another one, and only the inner-most formatting will be 453 * within another one, and only the inner-most formatting will be
454 * applied to the text. */ 454 * applied to the text. */
455 } else if (!purple_utf8_strcasecmp(root->name, "b")) { 455 } else if (!purple_utf8_strcasecmp(root->name, "b")) {
456 if (root->child->type == XMLNODE_TYPE_DATA) { 456 if (root->child->type == PURPLE_XMLNODE_TYPE_DATA) {
457 *begin = g_strdup_printf("<f s='%d'>", MSIM_TEXT_BOLD); 457 *begin = g_strdup_printf("<f s='%d'>", MSIM_TEXT_BOLD);
458 *end = g_strdup("</f>"); 458 *end = g_strdup("</f>");
459 } else { 459 } else {
460 if (!purple_utf8_strcasecmp(root->child->name,"i")) { 460 if (!purple_utf8_strcasecmp(root->child->name,"i")) {
461 ret++; 461 ret++;
462 if (root->child->child->type == XMLNODE_TYPE_DATA) { 462 if (root->child->child->type == PURPLE_XMLNODE_TYPE_DATA) {
463 *begin = g_strdup_printf("<f s='%d'>", (MSIM_TEXT_BOLD + MSIM_TEXT_ITALIC)); 463 *begin = g_strdup_printf("<f s='%d'>", (MSIM_TEXT_BOLD + MSIM_TEXT_ITALIC));
464 *end = g_strdup("</f>"); 464 *end = g_strdup("</f>");
465 } else { 465 } else {
466 if (!purple_utf8_strcasecmp(root->child->child->name,"u")) { 466 if (!purple_utf8_strcasecmp(root->child->child->name,"u")) {
467 ret++; 467 ret++;
474 *begin = g_strdup_printf("<f s='%d'>", (MSIM_TEXT_BOLD + MSIM_TEXT_UNDERLINE)); 474 *begin = g_strdup_printf("<f s='%d'>", (MSIM_TEXT_BOLD + MSIM_TEXT_UNDERLINE));
475 *end = g_strdup("</f>"); 475 *end = g_strdup("</f>");
476 } 476 }
477 } 477 }
478 } else if (!purple_utf8_strcasecmp(root->name, "i")) { 478 } else if (!purple_utf8_strcasecmp(root->name, "i")) {
479 if (root->child->type == XMLNODE_TYPE_DATA) { 479 if (root->child->type == PURPLE_XMLNODE_TYPE_DATA) {
480 *begin = g_strdup_printf("<f s='%d'>", MSIM_TEXT_ITALIC); 480 *begin = g_strdup_printf("<f s='%d'>", MSIM_TEXT_ITALIC);
481 *end = g_strdup("</f>"); 481 *end = g_strdup("</f>");
482 } else { 482 } else {
483 if (!purple_utf8_strcasecmp(root->child->name,"u")) { 483 if (!purple_utf8_strcasecmp(root->child->name,"u")) {
484 ret++; 484 ret++;
491 *end = g_strdup("</f>"); 491 *end = g_strdup("</f>");
492 } else if (!purple_utf8_strcasecmp(root->name, "a")) { 492 } else if (!purple_utf8_strcasecmp(root->name, "a")) {
493 const gchar *href; 493 const gchar *href;
494 gchar *link_text; 494 gchar *link_text;
495 495
496 href = xmlnode_get_attrib(root, "href"); 496 href = purple_xmlnode_get_attrib(root, "href");
497 497
498 if (!href) { 498 if (!href) {
499 href = xmlnode_get_attrib(root, "HREF"); 499 href = purple_xmlnode_get_attrib(root, "HREF");
500 } 500 }
501 501
502 link_text = xmlnode_get_data(root); 502 link_text = purple_xmlnode_get_data(root);
503 503
504 if (href) { 504 if (href) {
505 if (g_str_equal(link_text, href)) { 505 if (g_str_equal(link_text, href)) {
506 /* Purple gives us: <a href="URL">URL</a> 506 /* Purple gives us: <a href="URL">URL</a>
507 * Translate to <a h='URL' /> 507 * Translate to <a h='URL' />
520 } else { 520 } else {
521 *begin = g_strdup("<a />"); 521 *begin = g_strdup("<a />");
522 } 522 }
523 523
524 /* Sorry, kid. MySpace doesn't support you within <a> tags. */ 524 /* Sorry, kid. MySpace doesn't support you within <a> tags. */
525 xmlnode_free(root->child); 525 purple_xmlnode_free(root->child);
526 g_free(link_text); 526 g_free(link_text);
527 root->child = NULL; 527 root->child = NULL;
528 528
529 *end = g_strdup(""); 529 *end = g_strdup("");
530 } else if (!purple_utf8_strcasecmp(root->name, "font")) { 530 } else if (!purple_utf8_strcasecmp(root->name, "font")) {
531 GString *tmpbegin, *tmpend; 531 GString *tmpbegin, *tmpend;
532 const gchar *size; 532 const gchar *size;
533 const gchar *face; 533 const gchar *face;
534 const gchar *color; 534 const gchar *color;
535 535
536 size = xmlnode_get_attrib(root, "size"); 536 size = purple_xmlnode_get_attrib(root, "size");
537 face = xmlnode_get_attrib(root, "face"); 537 face = purple_xmlnode_get_attrib(root, "face");
538 color = xmlnode_get_attrib(root, "color"); 538 color = purple_xmlnode_get_attrib(root, "color");
539 539
540 tmpbegin = g_string_new("<f"); 540 tmpbegin = g_string_new("<f");
541 tmpend = g_string_new("</f>"); 541 tmpend = g_string_new("</f>");
542 542
543 if (face != NULL) 543 if (face != NULL)
560 *end = g_string_free(tmpend, FALSE); 560 *end = g_string_free(tmpend, FALSE);
561 561
562 } else if (!purple_utf8_strcasecmp(root->name, "body")) { 562 } else if (!purple_utf8_strcasecmp(root->name, "body")) {
563 const gchar *bgcolor; 563 const gchar *bgcolor;
564 564
565 bgcolor = xmlnode_get_attrib(root, "bgcolor"); 565 bgcolor = purple_xmlnode_get_attrib(root, "bgcolor");
566 566
567 if (bgcolor != NULL) { 567 if (bgcolor != NULL) {
568 *begin = g_strdup_printf("<b v='%s'>", bgcolor); 568 *begin = g_strdup_printf("<b v='%s'>", bgcolor);
569 *end = g_strdup("</b>"); 569 *end = g_strdup("</b>");
570 } 570 }
588 } 588 }
589 return ret; 589 return ret;
590 } 590 }
591 591
592 /** 592 /**
593 * Convert an xmlnode of msim markup or HTML to an HTML string or msim markup. 593 * Convert an PurpleXmlNode of msim markup or HTML to an HTML string or msim markup.
594 * 594 *
595 * @param f Function to convert tags. 595 * @param f Function to convert tags.
596 * 596 *
597 * @return An HTML string. Caller frees. 597 * @return An HTML string. Caller frees.
598 */ 598 */
599 static void 599 static void
600 msim_convert_xmlnode(MsimSession *session, GString *out, xmlnode *root, MSIM_XMLNODE_CONVERT f, int nodes_processed) 600 msim_convert_xmlnode(MsimSession *session, GString *out, PurpleXmlNode *root, MSIM_XMLNODE_CONVERT f, int nodes_processed)
601 { 601 {
602 xmlnode *node; 602 PurpleXmlNode *node;
603 gchar *begin, *end, *tmp; 603 gchar *begin, *end, *tmp;
604 int descended = nodes_processed; 604 int descended = nodes_processed;
605 605
606 if (!root || !root->name) 606 if (!root || !root->name)
607 return; 607 return;
618 g_free(begin); 618 g_free(begin);
619 619
620 /* Loop over all child nodes. */ 620 /* Loop over all child nodes. */
621 for (node = root->child; node != NULL; node = node->next) { 621 for (node = root->child; node != NULL; node = node->next) {
622 switch (node->type) { 622 switch (node->type) {
623 case XMLNODE_TYPE_ATTRIB: 623 case PURPLE_XMLNODE_TYPE_ATTRIB:
624 /* Attributes handled above. */ 624 /* Attributes handled above. */
625 break; 625 break;
626 626
627 case XMLNODE_TYPE_TAG: 627 case PURPLE_XMLNODE_TYPE_TAG:
628 /* A tag or tag with attributes. Recursively descend. */ 628 /* A tag or tag with attributes. Recursively descend. */
629 msim_convert_xmlnode(session, out, node, f, descended); 629 msim_convert_xmlnode(session, out, node, f, descended);
630 630
631 purple_debug_info("msim", " ** node name=%s\n", 631 purple_debug_info("msim", " ** node name=%s\n",
632 node->name ? node->name : "(NULL)"); 632 node->name ? node->name : "(NULL)");
633 break; 633 break;
634 634
635 case XMLNODE_TYPE_DATA: 635 case PURPLE_XMLNODE_TYPE_DATA:
636 /* Literal text. */ 636 /* Literal text. */
637 /* 637 /*
638 * TODO: Why is it necessary to escape here? I thought 638 * TODO: Why is it necessary to escape here? I thought
639 * node->data was already escaped? 639 * node->data was already escaped?
640 */ 640 */
661 * Convert XML to something based on MSIM_XMLNODE_CONVERT. 661 * Convert XML to something based on MSIM_XMLNODE_CONVERT.
662 */ 662 */
663 static gchar * 663 static gchar *
664 msim_convert_xml(MsimSession *session, const gchar *raw, MSIM_XMLNODE_CONVERT f) 664 msim_convert_xml(MsimSession *session, const gchar *raw, MSIM_XMLNODE_CONVERT f)
665 { 665 {
666 xmlnode *root; 666 PurpleXmlNode *root;
667 GString *str; 667 GString *str;
668 gchar *enclosed_raw; 668 gchar *enclosed_raw;
669 669
670 g_return_val_if_fail(raw != NULL, NULL); 670 g_return_val_if_fail(raw != NULL, NULL);
671 671
672 /* Enclose text in one root tag, to try to make it valid XML for parsing. */ 672 /* Enclose text in one root tag, to try to make it valid XML for parsing. */
673 enclosed_raw = g_strconcat("<root>", raw, "</root>", NULL); 673 enclosed_raw = g_strconcat("<root>", raw, "</root>", NULL);
674 674
675 root = xmlnode_from_str(enclosed_raw, -1); 675 root = purple_xmlnode_from_str(enclosed_raw, -1);
676 676
677 if (!root) { 677 if (!root) {
678 purple_debug_warning("msim", "msim_markup_to_html: couldn't parse " 678 purple_debug_warning("msim", "msim_markup_to_html: couldn't parse "
679 "%s as XML, returning raw: %s\n", enclosed_raw, raw); 679 "%s as XML, returning raw: %s\n", enclosed_raw, raw);
680 /* TODO: msim_unrecognized */ 680 /* TODO: msim_unrecognized */
684 684
685 g_free(enclosed_raw); 685 g_free(enclosed_raw);
686 686
687 str = g_string_new(NULL); 687 str = g_string_new(NULL);
688 msim_convert_xmlnode(session, str, root, f, 0); 688 msim_convert_xmlnode(session, str, root, f, 0);
689 xmlnode_free(root); 689 purple_xmlnode_free(root);
690 690
691 purple_debug_info("msim", "msim_markup_to_html: returning %s\n", str->str); 691 purple_debug_info("msim", "msim_markup_to_html: returning %s\n", str->str);
692 692
693 return g_string_free(str, FALSE); 693 return g_string_free(str, FALSE);
694 } 694 }

mercurial