comparison libpurple/protocols/jabber/google.c @ 15522:ccbdf500f13a

Google Talk uses structured text formatting where *this* is bold and _this_ is italic. If you're using Google Talk and receive a message, do that conversion. I admit this is proably the silliest Google Talk extension to add support for. But it seemed like it might be fun (turns out I was wrong).
author Sean Egan <seanegan@gmail.com>
date Sat, 03 Feb 2007 23:32:43 +0000
parents 2c81b0a81790
children 32c366eeeb99
comparison
equal deleted inserted replaced
15521:aa0c1aa85fd3 15522:ccbdf500f13a
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22 #include "internal.h" 22 #include "internal.h"
23 #include "debug.h" 23 #include "debug.h"
24 #include "util.h"
24 #include "privacy.h" 25 #include "privacy.h"
25 26
26 #include "buddy.h" 27 #include "buddy.h"
27 #include "google.h" 28 #include "google.h"
28 #include "jabber.h" 29 #include "jabber.h"
366 jabber_iq_send(iq); 367 jabber_iq_send(iq);
367 368
368 /* See if he's online */ 369 /* See if he's online */
369 jabber_presence_subscription_set(js, who, "probe"); 370 jabber_presence_subscription_set(js, who, "probe");
370 } 371 }
372
373 /* This does two passes on the string. The first pass goes through
374 * and determine if all the structured text is properly balanced, and
375 * how many instances of each there is. The second pass goes and converts
376 * everything to HTML, depending on what's figured out by the first pass.
377 * It will short circuit once it knows it has no more replacements to make
378 */
379 char *jabber_google_format_to_html(const char *text)
380 {
381 const char *p;
382
383 /* The start of the screen may be consdiered a space for this purpose */
384 gboolean preceding_space = TRUE;
385
386 gboolean in_bold = FALSE, in_italic = FALSE;
387 gboolean in_tag = FALSE;
388
389 gint bold_count = 0, italic_count = 0;
390
391 GString *str;
392
393 for (p = text; *p != '\0'; p = g_utf8_next_char(p)) {
394 gunichar c = g_utf8_get_char(p);
395 if (c == '*' && !in_tag) {
396 if (in_bold && (g_unichar_isspace(*(p+1)) ||
397 *(p+1) == '\0' ||
398 *(p+1) == '<')) {
399 bold_count++;
400 in_bold = FALSE;
401 } else if (preceding_space && !in_bold) {
402 bold_count++;
403 in_bold = TRUE;
404 }
405 preceding_space = TRUE;
406 } else if (c == '_' && !in_tag) {
407 if (in_italic && (g_unichar_isspace(*(p+1)) ||
408 *(p+1) == '\0' ||
409 *(p+1) == '<')) {
410 italic_count++;
411 in_italic = FALSE;
412 } else if (preceding_space && !in_italic) {
413 italic_count++;
414 in_italic = TRUE;
415 }
416 preceding_space = TRUE;
417 } else if (c == '<' && !in_tag) {
418 in_tag = TRUE;
419 } else if (c == '>' && in_tag) {
420 in_tag = FALSE;
421 } else if (!in_tag) {
422 if (g_unichar_isspace(c))
423 preceding_space = TRUE;
424 else
425 preceding_space = FALSE;
426 }
427 }
428
429 str = g_string_new(NULL);
430 in_bold = in_italic = in_tag = FALSE;
431 preceding_space = TRUE;
432
433 for (p = text; *p != '\0'; p = g_utf8_next_char(p)) {
434 gunichar c = g_utf8_get_char(p);
435
436 if (bold_count < 2 && italic_count < 2 && !in_bold && !in_italic) {
437 g_string_append(str, p);
438 return g_string_free(str, FALSE);
439 }
440
441
442 if (c == '*' && !in_tag) {
443 if (in_bold &&
444 (g_unichar_isspace(*(p+1))||*(p+1)=='<')) { /* This is safe in UTF-8 */
445 str = g_string_append(str, "</b>");
446 in_bold = FALSE;
447 bold_count--;
448 } else if (preceding_space && bold_count > 1) {
449 str = g_string_append(str, "<b>");
450 bold_count--;
451 in_bold = TRUE;
452 } else {
453 str = g_string_append_unichar(str, c);
454 }
455 preceding_space = TRUE;
456 } else if (c == '_' && !in_tag) {
457 if (in_italic &&
458 (g_unichar_isspace(*(p+1))||*(p+1)=='<')) {
459 str = g_string_append(str, "</i>");
460 italic_count--;
461 in_italic = FALSE;
462 } else if (preceding_space && italic_count > 1) {
463 str = g_string_append(str, "<i>");
464 italic_count--;
465 in_italic = TRUE;
466 } else {
467 str = g_string_append_unichar(str, c);
468 }
469 preceding_space = TRUE;
470 } else if (c == '<' && !in_tag) {
471 str = g_string_append_unichar(str, c);
472 in_tag = TRUE;
473 } else if (c == '>' && in_tag) {
474 str = g_string_append_unichar(str, c);
475 in_tag = FALSE;
476 } else if (!in_tag) {
477 str = g_string_append_unichar(str, c);
478 if (g_unichar_isspace(c))
479 preceding_space = TRUE;
480 else
481 preceding_space = FALSE;
482 } else {
483 str = g_string_append_unichar(str, c);
484 }
485 }
486 return g_string_free(str, FALSE);
487 }