| 859 |
859 |
| 860 /************************************************************************** |
860 /************************************************************************** |
| 861 * Markup Functions |
861 * Markup Functions |
| 862 **************************************************************************/ |
862 **************************************************************************/ |
| 863 |
863 |
| 864 /* Returns a NULL-terminated string after unescaping an entity |
|
| 865 * (eg. &, < & etc.) starting at s. Returns NULL on failure.*/ |
|
| 866 const char * |
864 const char * |
| 867 purple_markup_detect_entity(const char *text, int *length) |
865 purple_markup_unescape_entity(const char *text, int *length) |
| 868 { |
866 { |
| 869 const char *pln; |
867 const char *pln; |
| 870 int len, pound; |
868 int len, pound; |
| 871 |
869 |
| 872 if (!text || *text != '&') |
870 if (!text || *text != '&') |
| 907 if (length) |
905 if (length) |
| 908 *length = len; |
906 *length = len; |
| 909 return pln; |
907 return pln; |
| 910 } |
908 } |
| 911 |
909 |
| 912 gchar* |
910 char * |
| 913 purple_markup_get_css_property(const gchar *style, |
911 purple_markup_get_css_property(const gchar *style, |
| 914 const gchar *opt) |
912 const gchar *opt) |
| 915 { |
913 { |
| 916 const gchar *css_str = style; |
914 const gchar *css_str = style; |
| 917 const gchar *css_value_start; |
915 const gchar *css_value_start; |
| 918 const gchar *css_value_end; |
916 const gchar *css_value_end; |
| 919 gchar *tmp; |
917 gchar *tmp; |
| 920 gchar *ret; |
918 gchar *ret; |
| 921 |
919 |
| 922 if(!css_str) |
920 if (!css_str) |
| 923 return NULL; |
921 return NULL; |
| 924 |
922 |
| 925 /* find the CSS property */ |
923 /* find the CSS property */ |
| 926 while(1){ |
924 while (1) |
| 927 /* skip widespace characters */ |
925 { |
| 928 while(*css_str && g_ascii_isspace(*css_str)) |
926 /* skip whitespace characters */ |
| |
927 while (*css_str && g_ascii_isspace(*css_str)) |
| 929 css_str++; |
928 css_str++; |
| 930 if(!g_ascii_isalpha(*css_str)) |
929 if (!g_ascii_isalpha(*css_str)) |
| 931 return NULL; |
930 return NULL; |
| 932 if(g_ascii_strncasecmp(css_str, opt, strlen(opt))) |
931 if (g_ascii_strncasecmp(css_str, opt, strlen(opt))) |
| 933 { |
932 { |
| 934 /* go to next css property positioned after the next ';' */ |
933 /* go to next css property positioned after the next ';' */ |
| 935 while(*css_str && *css_str != '"' && *css_str != ';') |
934 while (*css_str && *css_str != '"' && *css_str != ';') |
| 936 css_str++; |
935 css_str++; |
| 937 if(*css_str != ';') |
936 if(*css_str != ';') |
| 938 return NULL; |
937 return NULL; |
| 939 css_str++; |
938 css_str++; |
| 940 } |
939 } |
| 941 else break; |
940 else |
| |
941 break; |
| 942 } |
942 } |
| 943 |
943 |
| 944 /* find the CSS value position in the string */ |
944 /* find the CSS value position in the string */ |
| 945 css_str += strlen(opt); |
945 css_str += strlen(opt); |
| 946 while(*css_str && g_ascii_isspace(*css_str)) |
946 while (*css_str && g_ascii_isspace(*css_str)) |
| 947 css_str++; |
947 css_str++; |
| 948 if(*css_str != ':') |
948 if (*css_str != ':') |
| 949 return NULL; |
949 return NULL; |
| 950 css_str++; |
950 css_str++; |
| 951 while(*css_str && g_ascii_isspace(*css_str)) |
951 while (*css_str && g_ascii_isspace(*css_str)) |
| 952 css_str++; |
952 css_str++; |
| 953 if(*css_str == '\0' || *css_str == '"' || *css_str == ';') |
953 if (*css_str == '\0' || *css_str == '"' || *css_str == ';') |
| 954 return NULL; |
954 return NULL; |
| 955 |
955 |
| 956 /* mark the CSS value */ |
956 /* mark the CSS value */ |
| 957 css_value_start = css_str; |
957 css_value_start = css_str; |
| 958 while(*css_str && *css_str != '"' && *css_str != ';') |
958 while (*css_str && *css_str != '"' && *css_str != ';') |
| 959 css_str++; |
959 css_str++; |
| 960 css_value_end = css_str - 1; |
960 css_value_end = css_str - 1; |
| 961 |
961 |
| 962 /* Removes trailing whitespace */ |
962 /* Removes trailing whitespace */ |
| 963 while(css_value_end > css_value_start && g_ascii_isspace(*css_value_end)) |
963 while (css_value_end > css_value_start && g_ascii_isspace(*css_value_end)) |
| 964 css_value_end--; |
964 css_value_end--; |
| 965 |
965 |
| 966 tmp = g_strndup(css_value_start, css_value_end - css_value_start + 1); |
966 tmp = g_strndup(css_value_start, css_value_end - css_value_start + 1); |
| 967 ret = purple_unescape_html(tmp); |
967 ret = purple_unescape_html(tmp); |
| 968 g_free(tmp); |
968 g_free(tmp); |
| 1568 } else if(*c == '&') { |
1568 } else if(*c == '&') { |
| 1569 char buf[7]; |
1569 char buf[7]; |
| 1570 const char *pln; |
1570 const char *pln; |
| 1571 int len; |
1571 int len; |
| 1572 |
1572 |
| 1573 if ((pln = purple_markup_detect_entity(c, &len)) == NULL) { |
1573 if ((pln = purple_markup_unescape_entity(c, &len)) == NULL) { |
| 1574 len = 1; |
1574 len = 1; |
| 1575 g_snprintf(buf, sizeof(buf), "%c", *c); |
1575 g_snprintf(buf, sizeof(buf), "%c", *c); |
| 1576 pln = buf; |
1576 pln = buf; |
| 1577 } |
1577 } |
| 1578 xhtml = g_string_append_len(xhtml, c, len); |
1578 xhtml = g_string_append_len(xhtml, c, len); |
| 2091 GString *ret = g_string_new(""); |
2091 GString *ret = g_string_new(""); |
| 2092 while (*c) { |
2092 while (*c) { |
| 2093 int len; |
2093 int len; |
| 2094 const char *ent; |
2094 const char *ent; |
| 2095 |
2095 |
| 2096 if ((ent = purple_markup_detect_entity(c, &len)) != NULL) { |
2096 if ((ent = purple_markup_unescape_entity(c, &len)) != NULL) { |
| 2097 ret = g_string_append(ret, ent); |
2097 ret = g_string_append(ret, ent); |
| 2098 c += len; |
2098 c += len; |
| 2099 } else if (!strncmp(c, "<br>", 4)) { |
2099 } else if (!strncmp(c, "<br>", 4)) { |
| 2100 ret = g_string_append_c(ret, '\n'); |
2100 ret = g_string_append_c(ret, '\n'); |
| 2101 c += 4; |
2101 c += 4; |