fix parsing <br /> tags in markup_to_utf8
[framework/uifw/elementary.git] / src / lib / elm_util.c
1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4 #include <Elementary.h>
5 #include "elm_priv.h"
6
7 static char *
8 _str_ncpy(char *dest, const char *src, size_t count)
9 {
10    if ((!dest) || (!src)) return NULL;
11    return strncpy(dest, src, count);
12 }
13
14 static char *
15 _str_append(char *str, const char *txt, int *len, int *alloc)
16 {
17    int txt_len = strlen(txt);
18
19    if (txt_len <= 0) return str;
20    if ((*len + txt_len) >= *alloc)
21      {
22         char *str2;
23         int alloc2;
24
25         alloc2 = *alloc + txt_len + 128;
26         str2 = realloc(str, alloc2);
27         if (!str2) return str;
28         *alloc = alloc2;
29         str = str2;
30      }
31    strcpy(str + *len, txt);
32    *len += txt_len;
33    return str;
34 }
35
36 char *
37 _elm_util_mkup_to_text(const char *mkup)
38 {
39    char *str = NULL;
40    int str_len = 0, str_alloc = 0;
41    char *s, *p;
42    char *tag_start, *tag_end, *esc_start, *esc_end, *ts;
43
44    if (!mkup) return NULL;
45    tag_start = tag_end = esc_start = esc_end = NULL;
46    p = (char *)mkup;
47    s = p;
48    for (;;)
49      {
50         if ((!*p) ||
51             (tag_end) || (esc_end) ||
52             (tag_start) || (esc_start))
53           {
54              if (tag_end)
55                {
56                   char *ttag;
57
58                   ttag = malloc(tag_end - tag_start);
59                   if (ttag)
60                     {
61                        _str_ncpy(ttag, tag_start + 1, tag_end - tag_start - 1);
62                        ttag[tag_end - tag_start - 1] = 0;
63                        if (!strcmp(ttag, "br"))
64                          str = _str_append(str, "\n", &str_len, &str_alloc);
65                        else if (!strcmp(ttag, "\n"))
66                          str = _str_append(str, "\n", &str_len, &str_alloc);
67                        else if (!strcmp(ttag, "\\n"))
68                          str = _str_append(str, "\n", &str_len, &str_alloc);
69                        else if (!strcmp(ttag, "\t"))
70                          str = _str_append(str, "\t", &str_len, &str_alloc);
71                        else if (!strcmp(ttag, "\\t"))
72                          str = _str_append(str, "\t", &str_len, &str_alloc);
73                        else if (!strcmp(ttag, "ps")) /* Unicode paragraph separator */
74                          str = _str_append(str, "\xE2\x80\xA9", &str_len, &str_alloc);
75                        free(ttag);
76                     }
77                   tag_start = tag_end = NULL;
78                }
79              else if (esc_end)
80                {
81                   ts = malloc(esc_end - esc_start + 1);
82                   if (ts)
83                     {
84                        const char *esc;
85                        _str_ncpy(ts, esc_start, esc_end - esc_start);
86                        ts[esc_end - esc_start] = 0;
87                        esc = evas_textblock_escape_string_get(ts);
88                        if (esc)
89                          str = _str_append(str, esc, &str_len, &str_alloc);
90                        free(ts);
91                     }
92                   esc_start = esc_end = NULL;
93                }
94              else if ((!*p) && (s))
95                {
96                   ts = malloc(p - s + 1);
97                   if (ts)
98                     {
99                        _str_ncpy(ts, s, p - s);
100                        ts[p - s] = 0;
101                        str = _str_append(str, ts, &str_len, &str_alloc);
102                        free(ts);
103                     }
104                }
105
106              if (!*p) break;
107           }
108         if (*p == '<')
109           {
110              if ((s) && (!esc_start))
111                {
112                   tag_start = p;
113                   tag_end = NULL;
114                   ts = malloc(p - s + 1);
115                   if (ts)
116                     {
117                        _str_ncpy(ts, s, p - s);
118                        ts[p - s] = 0;
119                        str = _str_append(str, ts, &str_len, &str_alloc);
120                        free(ts);
121                     }
122                   s = NULL;
123                }
124           }
125         else if (*p == '>')
126           {
127              if (tag_start)
128                {
129                   tag_end = p;
130                   /* <br /> */
131                   /*  ^^^   */
132                   if ((p - mkup > 1) && (p[-1] == '/')) p--;
133                   s = p + 1;
134                }
135           }
136         else if (*p == '&')
137           {
138              if ((s) && (!tag_start))
139                {
140                   esc_start = p;
141                   esc_end = NULL;
142                   ts = malloc(p - s + 1);
143                   if (ts)
144                     {
145                        _str_ncpy(ts, s, p - s);
146                        ts[p - s] = 0;
147                        str = _str_append(str, ts, &str_len, &str_alloc);
148                        free(ts);
149                     }
150                   s = NULL;
151                }
152           }
153         else if (*p == ';')
154           {
155              if (esc_start)
156                {
157                   esc_end = p + 1;
158                   s = p + 1;
159                }
160           }
161         p++;
162      }
163    return str;
164 }
165
166 char *
167 _elm_util_text_to_mkup(const char *text)
168 {
169    char *str = NULL;
170    int str_len = 0, str_alloc = 0;
171    int ch, pos = 0, pos2 = 0;
172
173    if (!text) return NULL;
174    for (;;)
175      {
176         pos = pos2;
177         pos2 = evas_string_char_next_get((char *)(text), pos2, &ch);
178         if ((ch <= 0) || (pos2 <= 0)) break;
179         if (ch == '\n')
180           str = _str_append(str, "<br>", &str_len, &str_alloc);
181         else if (ch == '\t')
182           str = _str_append(str, "<\t>", &str_len, &str_alloc);
183         else if (ch == '<')
184           str = _str_append(str, "&lt;", &str_len, &str_alloc);
185         else if (ch == '>')
186           str = _str_append(str, "&gt;", &str_len, &str_alloc);
187         else if (ch == '&')
188           str = _str_append(str, "&amp;", &str_len, &str_alloc);
189         else if (ch == 0x2029) /* PS */
190           str = _str_append(str, "<ps>", &str_len, &str_alloc);
191         else
192           {
193              char tstr[16];
194
195              _str_ncpy(tstr, text + pos, pos2 - pos);
196              tstr[pos2 - pos] = 0;
197              str = _str_append(str, tstr, &str_len, &str_alloc);
198           }
199      }
200    return str;
201 }