[cbhm] License is changed to Flora License
[framework/uifw/cbhm.git] / src / xconverter.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3
4  * Licensed under the Flora License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7
8  * http://www.tizenopensource.org/license
9
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include "xconverter.h"
19
20 static char *html_to_entry(AppData *ad, int type_index, const char *str);
21 static char *efl_to_entry(AppData *ad, int type_index, const char *str);
22 static char *text_to_entry(AppData *ad, int type_index, const char *str);
23 static char *image_path_to_entry(AppData *ad, int type_index, const char *str);
24
25 static char *make_close_tag(Eina_List* nodes);
26 static char *do_not_convert(AppData *ad, int type_index, const char *str);
27 static char *html_to_efl(AppData *ad, int type_index, const char *str);
28 static char *efl_to_html(AppData *ad, int type_index, const char *str);
29 static char *text_to_html(AppData *ad, int type_index, const char *str);
30 static char *text_to_efl(AppData *ad, int type_index, const char *str);
31 static char *to_text(AppData *ad, int type_index, const char *str);
32 static char *image_path_to_html(AppData *ad, int type_index, const char *str);
33 static char *image_path_to_efl(AppData *ad, int type_index, const char *str);
34 //static char *image_path_to_text(AppData *ad, int type_index, const char *str);
35 //static char *efl_to_efl(AppData *ad, int type_index, const char *str);
36 //static char *html_to_html(AppData *ad, int type_index, const char *str);
37 static char *image_path_to_image_path(AppData *ad, int type_index, const char *str);
38
39 int atom_type_index_get(AppData *ad, Ecore_X_Atom atom)
40 {
41         int i, j;
42         for (i = 0; i < ATOM_INDEX_MAX; i++)
43         {
44                 for (j = 0; j < ad->targetAtoms[i].atom_cnt; j++)
45                         if (ad->targetAtoms[i].atom[j] == atom)
46                                 return i;
47         }
48         return -1;
49 }
50
51 void init_target_atoms(AppData *ad)
52 {
53         int atom_cnt[ATOM_INDEX_MAX] = {
54                 1, 5, 2, 1, 2
55         };
56         char *targetAtomNames[][5] = {
57                 { "TARGETS" },
58                 { "UTF8_STRING", "STRING", "TEXT", "text/plain;charset=utf-8", "text/plain" },
59                 { "text/html;charset=utf-8", "text/html" },
60                 { "application/x-elementary-markup" },
61                 { "text/uri", "text/uri-list" }
62         };
63         text_converter_func converts_for_entry[ATOM_INDEX_MAX] = {
64                 NULL, text_to_entry, html_to_entry, efl_to_entry, image_path_to_entry
65         };
66
67         text_converter_func converts[ATOM_INDEX_MAX][ATOM_INDEX_MAX] = {
68                 {NULL, NULL, NULL, NULL, NULL},
69                 {NULL, do_not_convert, text_to_html, text_to_efl, NULL},
70                 {NULL, to_text, do_not_convert, html_to_efl, NULL},
71                 {NULL, to_text, efl_to_html, do_not_convert, NULL},
72                 {NULL, NULL, image_path_to_html, image_path_to_efl, image_path_to_image_path}
73         };
74
75         int i, j;
76         for (i = 0; i < ATOM_INDEX_MAX; i++)
77         {
78                 ad->targetAtoms[i].atom_cnt = atom_cnt[i];
79                 ad->targetAtoms[i].name = MALLOC(sizeof(char *) * atom_cnt[i]);
80                 ad->targetAtoms[i].atom = MALLOC(sizeof(Ecore_X_Atom) * atom_cnt[i]);
81                 for (j = 0; j < atom_cnt[i]; j++)
82                 {
83                         DMSG("atomName: %s\n", targetAtomNames[i][j]);
84                         ad->targetAtoms[i].name[j] = strdup(targetAtomNames[i][j]);
85                         ad->targetAtoms[i].atom[j] = ecore_x_atom_get(targetAtomNames[i][j]);
86                 }
87                 ad->targetAtoms[i].convert_for_entry = converts_for_entry[i];
88
89                 for (j = 0; j < ATOM_INDEX_MAX; j++)
90                         ad->targetAtoms[i].convert_to_target[j] = converts[i][j];
91                 //ecore_x_selection_converter_atom_add(ad->targetAtoms[i].atom, target_converters[i]);
92                 //ecore_x_selection_converter_atom_add(ad->targetAtoms[i].atom, generic_converter);
93         }
94 }
95
96 void depose_target_atoms(AppData *ad)
97 {
98         int i, j;
99         for (i = 0; i < ATOM_INDEX_MAX; i++)
100         {
101                 for (j = 0; j < ad->targetAtoms[i].atom_cnt; j++)
102                 {
103                         if (ad->targetAtoms[i].name[j])
104                                 FREE(ad->targetAtoms[i].name[j]);
105                 }
106                 if (ad->targetAtoms[i].name)
107                         FREE(ad->targetAtoms[i].name);
108                 if (ad->targetAtoms[i].atom)
109                         FREE(ad->targetAtoms[i].atom);
110         }
111 }
112
113 static Eina_Bool targets_converter(AppData *ad, Ecore_X_Atom reqAtom, CNP_ITEM *item, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *tsize)
114 {
115         CALLED();
116
117         int count;
118         int i, j;
119
120         int item_type_index = ATOM_INDEX_TEXT;
121         if (item)
122                 item_type_index = item->type_index;
123
124         for (i = 0, count = 0; i < ATOM_INDEX_MAX; i++)
125         {
126                 if (ad->targetAtoms[item_type_index].convert_to_target[i])
127                         count += ad->targetAtoms[i].atom_cnt;
128         }
129
130         *data_ret = MALLOC(sizeof(Ecore_X_Atom) * count);
131         DMSG("item_type: %d, target Atom cnt: %d\n", item_type_index, count);
132         if (!*data_ret)
133                 return EINA_FALSE;
134
135         for (i = 0, count = 0; i < ATOM_INDEX_MAX; i++)
136         {
137                 if (ad->targetAtoms[item_type_index].convert_to_target[i])
138                 {
139                         for(j = 0; j < ad->targetAtoms[i].atom_cnt; j++)
140                         {
141                                 ((Ecore_X_Atom *)*data_ret)[count++] = ad->targetAtoms[i].atom[j];
142                                 DMSG("send target atom: %s\n", ad->targetAtoms[i].name[j]);
143                         }
144                 }
145         }
146
147         if (size_ret) *size_ret = count;
148         if (ttype) *ttype = ECORE_X_ATOM_ATOM;
149         if (tsize) *tsize = 32;
150         return EINA_TRUE;
151 }
152
153 Eina_Bool generic_converter(AppData *ad, Ecore_X_Atom reqAtom, CNP_ITEM *item, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *tsize)
154 {
155         CALLED();
156
157         if (ad->targetAtoms[ATOM_INDEX_TARGET].atom[0] == reqAtom)
158                 return targets_converter(ad, reqAtom, item, data_ret, size_ret, ttype, tsize);
159
160         int req_index = atom_type_index_get(ad, reqAtom);
161         int item_type_index = ATOM_INDEX_TEXT;
162         void *item_data = "";
163         if (item)
164         {
165                 item_type_index = item->type_index;
166                 item_data = item->data;
167         }
168
169         if (ad->targetAtoms[item_type_index].convert_to_target[req_index])
170         {
171                 *data_ret = ad->targetAtoms[item_type_index].convert_to_target[req_index](ad, item_type_index, item_data);
172                 if (!*data_ret)
173                         return EINA_FALSE;
174                 if (size_ret) *size_ret = strlen(*data_ret);
175                 if (ttype) *ttype = ad->targetAtoms[item_type_index].atom[0];
176                 if (tsize) *tsize = 8;
177                 return EINA_TRUE;
178         }
179
180         return EINA_FALSE;
181 }
182
183 /* For convert EFL to HTML */
184
185 #define TAGPOS_START    0x00000001
186 #define TAGPOS_END      0x00000002
187 #define TAGPOS_ALONE    0x00000003
188
189 /* TEXTBLOCK tag using stack but close tag word has no mean maybe bug...
190  * TEXTBLOCK <b>bold<font>font</b>bold</font>
191  * HTML <b>bold<font>font bold</b>font</font> */
192
193 typedef struct _TagTable {
194         char *src;
195         char *dst;
196 }TagTable;
197
198 TagTable _EFLtoHTMLConvertTable[] = {
199         {"font", "font"},
200         {"underline", "del"},
201         {"strikethrough", "ins"},
202         {"br", "br"},
203         {"br/", "br"},
204         {"ps", "br"},
205         {"b", "b"},
206         {"item", "img"}
207 };
208
209 TagTable _HTMLtoEFLConvertTable[] = {
210         {"font", ""},
211         {"del", "underline"},
212         {"u", "underline"},
213         {"ins", "strikethrough"},
214         {"s", "strikethrough"},
215         {"br", "br"},
216         {"b", "b"},
217         {"strong", "b"},
218         {"img", "item"}
219 };
220
221
222 typedef struct _TagNode TagNode, *PTagNode;
223 struct _TagNode {
224         char *tag;  //EINA_STRINGSHARE if NULL just str
225         char *tag_str;
226         char *str;
227         const char *pos_in_ori_str;
228         PTagNode matchTag;
229         void *tagData;
230         unsigned char tagPosType;
231 };
232
233 typedef struct _FontTagData FontTagData, *PFontTagData;
234 struct _FontTagData {
235         char *name;
236         char *color;
237         char *size;
238         char *bg_color;
239 };
240
241
242 typedef struct _ItemTagData ItemTagData, *PItemTagData;
243 struct _ItemTagData {
244         char *href;
245         char *width;
246         char *height;
247 };
248
249 #define SAFEFREE(ptr) \
250         do\
251 {\
252         if (ptr)\
253         FREE(ptr);\
254         ptr = NULL;\
255 } while(0);\
256
257 #define freeAndAssign(dst, value) \
258         do\
259 {\
260         if (value)\
261         {\
262                 SAFEFREE(dst);\
263                 dst = value;\
264         }\
265 } while(0);
266
267 static PTagNode _new_tag_node(char *tag, char *tag_str, char* str, const char *pos_in_ori_str);
268 static PTagNode _get_start_node(const char *str);
269 static PTagNode _get_next_node(PTagNode prev);
270 static void _delete_node(PTagNode node);
271 static void _link_match_tags(Eina_List *nodes);
272 static char *_get_tag_value(const char *tag_str, const char *tag_name);
273 static char *_convert_to_html(Eina_List* nodes);
274 static void _set_EFL_tag_data(Eina_List* nodes);
275 static char *_convert_to_edje(Eina_List* nodes);
276 static void _set_HTML_tag_data(Eina_List* nodes);
277 static void cleanup_tag_list(Eina_List *nodeList);
278 static PFontTagData _set_EFL_font_data(PFontTagData data, const char *tag_str);
279 static PItemTagData _set_EFL_item_data(PItemTagData data, const char *tag_str);
280 static PFontTagData _set_HTML_font_data(PFontTagData data, const char *tag_str);
281 static PItemTagData _set_HTML_img_data(PItemTagData data, const char *tag_str);
282
283 #ifdef DEBUG
284 static void _dumpNode(Eina_List* nodes);
285 #endif
286
287 static PTagNode
288 _new_tag_node(char *tag, char *tag_str, char* str, const char *pos_in_ori_str)
289 {
290         PTagNode newNode = CALLOC(1, sizeof(TagNode));
291         if (tag)
292                 eina_str_tolower(&tag);
293         newNode->tag = tag;
294         if (tag_str)
295                 eina_str_tolower(&tag_str);
296         newNode->tag_str = tag_str;
297         newNode->str = str;
298         newNode->pos_in_ori_str = pos_in_ori_str;
299         return newNode;
300 }
301
302 static PTagNode
303 _get_start_node(const char *str)
304 {
305         char *startStr = NULL;
306         if (!str || str[0] == '\0')
307                 return NULL;
308
309         if (str[0] != '<')
310         {
311                 char *tagStart = strchr(str, '<');
312                 if (!tagStart)
313                         startStr = strdup(str);
314                 else
315                 {
316                         int strLength = tagStart - str;
317                         startStr = MALLOC(sizeof(char) * (strLength + 1));
318                         strncpy(startStr, str, strLength);
319                         startStr[strLength] = '\0';
320                 }
321         }
322
323         return _new_tag_node(NULL, NULL, startStr, str);
324 }
325
326 static PTagNode
327 _get_next_node(PTagNode prev)
328 {
329         PTagNode retTag = NULL;
330         char *tagStart;
331         char *tagEnd;
332         char *tagNameEnd = NULL;
333         char *nextTagStart;
334
335         if (prev->tag == NULL)
336                 tagStart = strchr(prev->pos_in_ori_str, '<');
337         else
338                 tagStart = strchr(prev->pos_in_ori_str + 1, '<');
339
340         if (!tagStart)
341                 return retTag;
342
343         tagEnd = strchr(tagStart, '>');
344         nextTagStart = strchr(tagStart + 1, '<');
345
346         if (!tagEnd || (nextTagStart && (nextTagStart < tagEnd)))
347                 return _get_start_node(tagStart + 1);
348
349         int spCnt = 5;
350         char *spArray[spCnt];
351         spArray[0] = strchr(tagStart, '=');
352         spArray[1] = strchr(tagStart, '_');
353         spArray[2] = strchr(tagStart, ' ');
354         spArray[3] = strchr(tagStart, '\t');
355         spArray[4] = strchr(tagStart, '\n');
356         tagNameEnd = tagEnd;
357
358         int i;
359         for (i = 0; i < spCnt; i++)
360         {
361                 if (spArray[i] && spArray[i] < tagNameEnd)
362                         tagNameEnd = spArray[i];
363         }
364
365         int tagLength = tagNameEnd - tagStart - 1;
366         char *tagName = NULL;
367         if (!strncmp(&tagStart[1], "/item", tagLength))
368                 tagName = strdup("");
369         else
370                 tagName = strndup(&tagStart[1], tagLength);
371
372         int tagStrLength = 0;
373         char *tagStr = NULL;
374         if (tagName)
375         {
376                 tagStrLength = tagEnd - tagStart + 1;
377                 tagStr = strndup(tagStart, tagStrLength);
378         }
379
380         unsigned int strLength = nextTagStart ? (unsigned int)(nextTagStart - tagEnd - 1) : strlen(&tagEnd[1]);
381         char *str = strndup(&tagEnd[1], strLength);
382
383         retTag = _new_tag_node(tagName, tagStr, str, tagStart);
384         return retTag;
385 }
386
387
388 static void
389 _delete_node(PTagNode node)
390 {
391         if (node)
392         {
393                 SAFEFREE(node->tag_str);
394                 SAFEFREE(node->str);
395
396                 if (node->tagData)
397                 {
398                         if (node->tag)
399                         {
400                                 if (!strcmp("font", node->tag))
401                                 {
402                                         PFontTagData data = node->tagData;
403                                         SAFEFREE(data->name);
404                                         SAFEFREE(data->color);
405                                         SAFEFREE(data->size);
406                                         SAFEFREE(data->bg_color);
407                                 }
408                                 if (!strcmp("item", node->tag))
409                                 {
410                                         PItemTagData data = node->tagData;
411                                         SAFEFREE(data->href);
412                                         SAFEFREE(data->width);
413                                         SAFEFREE(data->height);
414                                 }
415
416                         }
417                         SAFEFREE(node->tagData);
418                 }
419                 SAFEFREE(node->tag);
420                 SAFEFREE(node);
421         }
422 }
423
424 static void
425 _link_match_tags(Eina_List *nodes)
426 {
427         Eina_List *stack = NULL;
428
429         PTagNode trail, popData;
430         Eina_List *l, *r;
431
432         EINA_LIST_FOREACH(nodes, l, trail)
433         {
434                 if (!trail->tag || trail->tag[0] == '\0')
435                         continue;
436                 if (!strcmp("br/", trail->tag))
437                 {
438                         trail->tagPosType = TAGPOS_ALONE;
439                         continue;
440                 }
441                 else if (!strcmp("item", trail->tag) || !strcmp("img", trail->tag))
442                 {
443                         trail->tagPosType = TAGPOS_ALONE;
444                         continue;
445                 }
446
447                 if (trail->tag[0] != '/') // PUSH
448                 {
449                         stack = eina_list_append(stack, trail);
450                         /*             eina_array_push(stack, trail);
451                                                    DMSG("stack: %d, tag %s\n", eina_array_count_get(stack), trail->tag);*/
452                         DMSG("stack: %d, tag %s\n", eina_list_count(stack), trail->tag);
453                 }
454                 else // POP
455                 {
456                         if (!eina_list_count(stack))
457                         {
458                                 DMSG("tag not matched %s\n", trail->tag);
459                                 continue;
460                         }
461
462                         EINA_LIST_REVERSE_FOREACH(stack, r, popData)
463                         {
464                                 if (popData->tag && !strcmp(popData->tag, &trail->tag[1]))
465                                 {
466                                         popData->tagPosType = TAGPOS_START;
467                                         trail->tagPosType = TAGPOS_END;
468                                         popData->matchTag = trail;
469                                         trail->matchTag = popData;
470                                         stack = eina_list_remove_list(stack, r);
471                                         break;
472                                 }
473                         }
474                         /*             popData = eina_array_pop(stack);
475
476                                                    popData->tagPosType = TAGPOS_START;
477                                                    trail->tagPosType = TAGPOS_END;
478                                                    popData->matchTag = trail;
479                                                    trail->matchTag = popData;
480                                                    DMSG("pop stack: %d, tag %s\n", eina_array_count_get(stack), trail->tag);
481                          */
482                 }
483         }
484
485         /*   if (eina_array_count_get(stack))
486                  DMSG("stack state: %d, tag %s\n", eina_array_count_get(stack), trail->tag);*/
487
488         /* Make Dummy close tag */
489         /*   while ((popData = eina_array_pop(stack)))  */
490
491         EINA_LIST_REVERSE_FOREACH(stack, r, popData)
492         {
493                 PTagNode newData;
494                 int tagLength = strlen(popData->tag);
495                 char *tagName = MALLOC(sizeof(char) * (tagLength + 2));
496
497                 tagName[0] = '/';
498                 tagName[1] = '\0';
499                 strcat(tagName, popData->tag);
500
501                 newData = _new_tag_node(tagName, NULL, NULL, NULL);
502                 popData->tagPosType = TAGPOS_START;
503                 newData->tagPosType = TAGPOS_END;
504                 popData->matchTag = newData;
505                 newData->matchTag = popData;
506                 nodes = eina_list_append(nodes, newData);
507                 /*        DMSG("stack: %d, tag %s\n", eina_array_count_get(stack), popData->tag);*/
508         }
509         /*   DMSG("stack_top: %d\n", eina_array_count_get(stack));
510                  eina_array_free(stack);*/
511         eina_list_free(stack);
512 }
513
514 static char *
515 _get_tag_value(const char *tag_str, const char *tag_name)
516 {
517         if (!tag_name || !tag_str)
518                 return NULL;
519
520         char *tag;
521         if ((tag = strstr(tag_str, tag_name)))
522         {
523                 if (tag[strlen(tag_name)] == '_')
524                         return NULL;
525                 char *value = strchr(tag, '=');
526                 if (value)
527                 {
528                         do
529                         {
530                                 value++;
531                         } while (!isalnum(*value) && *value != '#');
532
533                         int spCnt = 6;
534                         char *spArray[spCnt];
535                         spArray[0] = strchr(value, ' ');
536                         spArray[1] = strchr(value, '>');
537                         spArray[2] = strchr(value, '\"');
538                         spArray[3] = strchr(value, '\'');
539                         spArray[4] = strchr(value, '\t');
540                         spArray[5] = strchr(value, '\n');
541                         char *valueEnd = strchr(value, '\0');
542
543                         int i;
544                         int start = 0;
545                         if ((!strncmp(tag_str, "<item", 5) && !strcmp(tag_name, "href")) // EFL img tag
546                || (!strncmp(tag_str, "<img", 4) && !strcmp(tag_name, "src"))) // HTML img tag
547                start = 1;
548
549                         for (i = start; i < spCnt; i++)
550                         {
551                                 if (spArray[i] && spArray[i] < valueEnd)
552                                         valueEnd = spArray[i];
553                         }
554
555                         int valueLength = valueEnd - value;
556                         return strndup(value, valueLength);
557                 }
558         }
559         return NULL;
560 }
561
562 static PFontTagData
563 _set_EFL_font_data(PFontTagData data, const char *tag_str)
564 {
565         char *value;
566
567         if (!data)
568                 data = CALLOC(1, sizeof(FontTagData));
569         value = _get_tag_value(tag_str, "font_size");
570         freeAndAssign(data->size, value);
571         value = _get_tag_value(tag_str, "color");
572         freeAndAssign(data->color, value);
573         value = _get_tag_value(tag_str, "bgcolor");
574         freeAndAssign(data->bg_color, value);
575         value = _get_tag_value(tag_str, "font");
576         freeAndAssign(data->name, value);
577
578         return data;
579 }
580
581 static PItemTagData
582 _set_EFL_item_data(PItemTagData data, const char *tag_str)
583 {
584         char *value;
585
586         if (!data)
587                 data = CALLOC(1, sizeof(ItemTagData));
588         value = _get_tag_value(tag_str, "href");
589         if (value)
590         {
591                 char *path = strstr(value, "file://");
592                 if (path)
593                 {
594                         char *modify = MALLOC(sizeof(char) * (strlen(value) + 1));
595                         strncpy(modify, "file://", 8);
596                         path += 7;
597                         while (path[1] && path[0] && path[1] == '/' && path[0] == '/')
598                         {
599                                 path++;
600                         }
601                         strcat(modify, path);
602                         data->href = modify;
603                         DMSG("image href ---%s---\n", data->href);
604                         FREE(value);
605                 }
606                 else
607                         freeAndAssign(data->href, value);
608         }
609
610         value = _get_tag_value(tag_str, "absize");
611         if (value)
612         {
613                 char *xpos = strchr(value, 'x');
614                 if (xpos)
615                 {
616                         int absizeLen = strlen(value);
617                         freeAndAssign(data->width, strndup(value, xpos - value));
618                         freeAndAssign(data->height, strndup(xpos + 1, absizeLen - (xpos - value) - 1));
619                         DMSG("image width: -%s-, height: -%s-\n", data->width, data->height);
620                 }
621                 FREE(value);
622         }
623         return data;
624 }
625
626 static void
627 _set_EFL_tag_data(Eina_List* nodes)
628 {
629         PTagNode trail;
630         Eina_List *l;
631
632         EINA_LIST_FOREACH(nodes, l, trail)
633         {
634                 if (!trail->tag)
635                         continue;
636                 if (!strcmp("font", trail->tag) || !strcmp("color", trail->tag))
637                         trail->tagData = _set_EFL_font_data(trail->tagData, trail->tag_str);
638                 else if (!strcmp("item", trail->tag))
639                         trail->tagData = _set_EFL_item_data(trail->tagData, trail->tag_str);
640         }
641 }
642
643 static PFontTagData
644 _set_HTML_font_data(PFontTagData data, const char *tag_str)
645 {
646         char *value;
647
648         if (!data)
649                 data = CALLOC(1, sizeof(FontTagData));
650         value = _get_tag_value(tag_str, "size");
651         freeAndAssign(data->size, value);
652         value = _get_tag_value(tag_str, "color");
653         freeAndAssign(data->color, value);
654         value = _get_tag_value(tag_str, "bgcolor");
655         freeAndAssign(data->bg_color, value);
656         value = _get_tag_value(tag_str, "face");
657         freeAndAssign(data->name, value);
658
659         return data;
660 }
661
662 static PItemTagData
663 _set_HTML_img_data(PItemTagData data, const char *tag_str)
664 {
665         char *value;
666
667         if (!data)
668                 data = CALLOC(1, sizeof(ItemTagData));
669         value = _get_tag_value(tag_str, "src");
670         if (value)
671         {
672                 char *path = strstr(value, "file://");
673                 if (path)
674                 {
675                         char *modify = MALLOC(sizeof(char) * (strlen(value) + 1));
676                         strncpy(modify, "file://", 8);
677                         path += 7;
678                         while (path[1] && path[0] && path[1] == '/' && path[0] == '/')
679                         {
680                                 path++;
681                         }
682                         strcat(modify, path);
683                         data->href = modify;
684                         DMSG("image src ---%s---\n", data->href);
685                         FREE(value);
686                 }
687                 else
688                         freeAndAssign(data->href, value);
689         }
690
691         value = _get_tag_value(tag_str, "width");
692         freeAndAssign(data->width, value);
693         value = _get_tag_value(tag_str, "height");
694         freeAndAssign(data->height, value);
695         return data;
696 }
697
698 static void
699 _set_HTML_tag_data(Eina_List* nodes)
700 {
701         PTagNode trail;
702         Eina_List *l;
703
704         EINA_LIST_FOREACH(nodes, l, trail)
705         {
706                 if (!trail->tag)
707                         continue;
708                 if (!strcmp("font", trail->tag) || !strcmp("color", trail->tag))
709                         trail->tagData = _set_HTML_font_data(trail->tagData, trail->tag_str);
710                 else if (!strcmp("img", trail->tag))
711                         trail->tagData = _set_HTML_img_data(trail->tagData, trail->tag_str);
712         }
713 }
714
715 #ifdef DEBUG
716 static void
717 _dumpNode(Eina_List* nodes)
718 {
719         PTagNode trail;
720         Eina_List *l;
721
722         EINA_LIST_FOREACH(nodes, l, trail)
723         {
724                 DMSG("tag: %s, tag_str: %s, str: %s, tagPosType: %d\n",
725                                 trail->tag, trail->tag_str, trail->str, trail->tagPosType);
726                 DMSG("matchTag: %x ", (unsigned int)trail->matchTag);
727                 if (trail->matchTag)
728                         DMSG("matchTag->tag_str: %s", trail->matchTag->tag_str);
729                 if (trail->tagData)
730                 {
731                         if (!strcmp(trail->tag, "font"))
732                         {
733                                 PFontTagData data = trail->tagData;
734                                 DMSG(" tagData->name: %s, tagData->color: %s, tagData->size: %s, tagData->bg_color: %s",
735                                                 data->name, data->color, data->size, data->bg_color);
736                         }
737                         else if (!strcmp(trail->tag, "item") || !strcmp(trail->tag, "img"))
738                         {
739                                 PItemTagData data = trail->tagData;
740                                 DMSG(" tagData->href: %s, tagData->width: %s, tagData->height: %s",
741                                                 data->href, data->width, data->height);
742                         }
743                         else
744                                 DMSG("\nERROR!!!! not need tagData");
745                 }
746                 DMSG("\n");
747         }
748 }
749 #endif
750
751 static char *
752 _convert_to_html(Eina_List* nodes)
753 {
754         PTagNode trail;
755         Eina_List *l;
756
757         Eina_Strbuf *html = eina_strbuf_new();
758
759         int tableCnt = sizeof(_EFLtoHTMLConvertTable) / sizeof(TagTable);
760
761         EINA_LIST_FOREACH(nodes, l, trail)
762         {
763                 if (trail->tag)
764                 {
765                         char *tagName = trail->tagPosType == TAGPOS_END ?
766                                 trail->matchTag->tag : trail->tag;
767                         int j;
768                         for(j = 0; j < tableCnt; j++)
769                         {
770                                 if (!strcmp(_EFLtoHTMLConvertTable[j].src, tagName))
771                                 {
772                                         switch(trail->tagPosType)
773                                         {
774                                                 case TAGPOS_END:
775                                                         eina_strbuf_append(html, "</");
776                                                         break;
777                                                 default:
778                                                         eina_strbuf_append(html, "<");
779                                                         break;
780                                         }
781
782                                         eina_strbuf_append(html, _EFLtoHTMLConvertTable[j].dst);
783                                         if (trail->tagPosType != TAGPOS_END)
784                                         {
785                                                 if (!strcmp(_EFLtoHTMLConvertTable[j].src, "font"))
786                                                 {
787                                                         PFontTagData data = trail->tagData;
788                                                         if (data->name)
789                                                         {
790                                                         }
791                                                         if (data->color)
792                                                         {
793                                                                 char *color = strdup(data->color);
794                                                                 if (color && color[0] == '#' && strlen(color) == 9)
795                                                                 {
796                                                                         color[7] = '\0';
797                                                                         eina_strbuf_append_printf(html, " color=\"%s\"", color);
798                                                                         FREE(color);
799                                                                 }
800                                                                 else
801                                                                         eina_strbuf_append_printf(html, " color=\"%s\"", data->color);
802                                                         }
803                                                         if (data->size)
804                                                                 eina_strbuf_append_printf(html, " size=\"%s\"", data->size);
805                                                         if (data->bg_color)
806                                                         {
807                                                         }
808                                                 }
809                                                 else if (!strcmp(_EFLtoHTMLConvertTable[j].src, "item"))
810                                                 {
811                                                         PItemTagData data = trail->tagData;
812                                                         if (data->href)
813                                                                 eina_strbuf_append_printf(html, " src=\"%s\"", data->href);
814                                                         if (data->width)
815                                                                 eina_strbuf_append_printf(html, " width=\"%s\"", data->width);
816                                                         if (data->height)
817                                                                 eina_strbuf_append_printf(html, " height=\"%s\"", data->height);
818                                                 }
819                                         }
820                                         switch(trail->tagPosType)
821                                         {
822                                                 /* closed tag does not need in HTML
823                                                    case TAGPOS_ALONE:
824                                                    eina_strbuf_append(html, " />");
825                                                    break;*/
826                                                 default:
827                                                         eina_strbuf_append(html, ">");
828                                                         break;
829                                         }
830                                         break;
831                                 }
832                         }
833                 }
834                 if (trail->str)
835                         eina_strbuf_append(html, trail->str);
836         }
837
838         eina_strbuf_replace_all(html, "  ", " &nbsp;");
839         char *ret = eina_strbuf_string_steal(html);
840         eina_strbuf_free(html);
841         return ret;
842 }
843
844 #define IMAGE_DEFAULT_WIDTH "240"
845 #define IMAGE_DEFAULT_HEIGHT "180"
846
847
848 static char *
849 _convert_to_edje(Eina_List* nodes)
850 {
851         PTagNode trail;
852         Eina_List *l;
853
854         Eina_Strbuf *edje = eina_strbuf_new();
855
856         int tableCnt = sizeof(_HTMLtoEFLConvertTable) / sizeof(TagTable);
857
858         EINA_LIST_FOREACH(nodes, l, trail)
859         {
860                 if (trail->tag)
861                 {
862                         char *tagName = trail->tagPosType == TAGPOS_END ?
863                                 trail->matchTag->tag : trail->tag;
864                         int j;
865                         for(j = 0; j < tableCnt; j++)
866                         {
867                                 if (!strcmp(_HTMLtoEFLConvertTable[j].src, tagName))
868                                 {
869                                         if (_HTMLtoEFLConvertTable[j].dst[0] != '\0')
870                                         {
871                                                 switch(trail->tagPosType)
872                                                 {
873                                                         case TAGPOS_END:
874                                                                 eina_strbuf_append(edje, "</");
875                                                                 break;
876                                                         default:
877                                                                 eina_strbuf_append(edje, "<");
878                                                                 break;
879                                                 }
880
881                                                 eina_strbuf_append(edje, _HTMLtoEFLConvertTable[j].dst);
882                                         }
883                                         if (trail->tagPosType != TAGPOS_END)
884                                         {
885                                                 if (!strcmp(_HTMLtoEFLConvertTable[j].src, "font"))
886                                                 {
887                                                         PFontTagData data = trail->tagData;
888                                                         if (data->name)
889                                                         {
890                                                         }
891                                                         if (data->color)
892                                                         {
893                                                                 if (data->color[0] == '#' && strlen(data->color) == 7)
894                                                                         eina_strbuf_append_printf(edje, "<color=%sff>", data->color);
895                                                                 else
896                                                                         eina_strbuf_append_printf(edje, "<color=%s>", data->color);
897
898                                                         }
899                                                         if (data->size)
900                                                                 eina_strbuf_append_printf(edje, "<font_size=%s>", data->size);
901                                                         if (data->bg_color)
902                                                         {
903                                                         }
904                                                         break;
905                                                 }
906                                                 else if (!strcmp(_HTMLtoEFLConvertTable[j].src, "img"))
907                                                 {
908                                                         PItemTagData data = trail->tagData;
909                                                         char *width = IMAGE_DEFAULT_WIDTH, *height = IMAGE_DEFAULT_HEIGHT;
910                                                         if (data->width)
911                                                                 width = data->width;
912                                                         if (data->height)
913                                                                 height = data->height;
914                                                         eina_strbuf_append_printf(edje, " absize=%sx%s", width, height);
915                                                         if (data->href)
916                                                                 eina_strbuf_append_printf(edje, " href=%s></item>", data->href);
917                                                         break;
918                                                 }
919                                         }
920                                         else
921                                         {
922                                                 if (_HTMLtoEFLConvertTable[j].dst[0] == '\0')
923                                                 {
924                                                         if (!strcmp(_HTMLtoEFLConvertTable[j].src, "font"))
925                                                         {
926                                                                 if (trail->matchTag->tagData)
927                                                                 {
928                                                                         PFontTagData data = trail->matchTag->tagData;
929                                                                         if (data->name)
930                                                                         {
931                                                                         }
932                                                                         if (data->color)
933                                                                                 eina_strbuf_append_printf(edje, "</color>");
934                                                                         if (data->size)
935                                                                                 eina_strbuf_append_printf(edje, "</font>");
936                                                                         if (data->bg_color)
937                                                                         {
938                                                                         }
939                                                                         break;
940                                                                 }
941                                                         }
942                                                 }
943                                         }
944                                         switch(trail->tagPosType)
945                                         {
946                                                 /* not support in efl
947                                                    case TAGPOS_ALONE:
948                                                    eina_strbuf_append(edje, " />");
949                                                    break;
950                                                  */
951                                                 default:
952                                                         eina_strbuf_append(edje, ">");
953                                                         break;
954                                         }
955                                         break;
956                                 }
957                         }/* for(j = 0; j < tableCnt; j++) end */
958                 }
959                 if (trail->str)
960                         eina_strbuf_append(edje, trail->str);
961         }
962
963         eina_strbuf_replace_all(edje, "&nbsp;", " ");
964         char *ret = eina_strbuf_string_steal(edje);
965         eina_strbuf_free(edje);
966         return ret;
967 }
968
969 char *string_for_entry_get(AppData *ad, int type_index, const char *str)
970 {
971         DMSG("type_index: %d ", type_index);
972         DMSG("str: %s\n", str);
973         if (ad->targetAtoms[type_index].convert_for_entry)
974                 return ad->targetAtoms[type_index].convert_for_entry(ad, type_index, str);
975         return NULL;
976 }
977
978 static char *make_close_tag(Eina_List* nodes)
979 {
980         CALLED();
981         PTagNode trail;
982         Eina_List *l;
983
984         Eina_Strbuf *tag_str = eina_strbuf_new();
985
986         EINA_LIST_FOREACH(nodes, l, trail)
987         {
988                 if (trail->tag)
989                 {
990                         if (trail->tag_str)
991                                 eina_strbuf_append(tag_str, trail->tag_str);
992                         else
993                         {
994                                 eina_strbuf_append(tag_str, "<");
995                                 eina_strbuf_append(tag_str, trail->tag);
996                                 eina_strbuf_append(tag_str, ">");
997                         }
998                 }
999                 if (trail->str)
1000                         eina_strbuf_append(tag_str, trail->str);
1001         }
1002
1003         char *ret = eina_strbuf_string_steal(tag_str);
1004         eina_strbuf_free(tag_str);
1005         return ret;
1006 }
1007
1008 static char *do_not_convert(AppData *ad, int type_index, const char *str)
1009 {
1010         DMSG("str: %s\n", str);
1011         if (type_index != ATOM_INDEX_TEXT)
1012         {
1013                 Eina_List *nodeList = NULL;
1014                 PTagNode nodeData;
1015
1016                 nodeData = _get_start_node(str);
1017
1018                 while (nodeData)
1019                 {
1020                         nodeList = eina_list_append(nodeList, nodeData);
1021                         nodeData = _get_next_node(nodeData);
1022                 }
1023
1024                 _link_match_tags(nodeList);
1025
1026 #ifdef DEBUG
1027                 _dumpNode(nodeList);
1028 #endif
1029                 char *ret = make_close_tag(nodeList);
1030                 cleanup_tag_list(nodeList);
1031                 DMSG("convert str: %s\n", ret);
1032                 return ret;
1033         }
1034         return strdup(str);
1035 }
1036 /*
1037    static char *efl_to_efl(AppData *ad, int type_index, const char *str)
1038    {
1039    CALLED();
1040    return NULL;
1041    }
1042
1043    static char *html_to_html(AppData *ad, int type_index, const char *str)
1044    {
1045    CALLED();
1046    return NULL;
1047    }
1048  */
1049
1050 #define IMAGE_DEFAULT_WIDTH "240"
1051 #define IMAGE_DEFAULT_HEIGHT "180"
1052 static char *make_image_path_tag(int type_index, const char *str)
1053 {
1054         char *img_tag_str = "file://%s";
1055         char *efl_img_tag = "<item absize="IMAGE_DEFAULT_WIDTH"x"IMAGE_DEFAULT_HEIGHT" href=file://%s>";
1056         char *html_img_tag = "<img src=\"file://%s\">";
1057
1058         switch (type_index)
1059         {
1060                 case ATOM_INDEX_HTML:
1061                         img_tag_str = html_img_tag;
1062                         break;
1063                 case ATOM_INDEX_EFL:
1064                         img_tag_str = efl_img_tag;
1065                         break;
1066                 case ATOM_INDEX_TEXT:
1067                 case ATOM_INDEX_IMAGE:
1068                         break;
1069                 default:
1070                         DMSG("ERROR: wrong type_index: %d\n", type_index);
1071                         return NULL;
1072         }
1073
1074         size_t len = snprintf(NULL, 0, img_tag_str, str) + 1;
1075         char *ret = MALLOC(sizeof(char) * len);
1076         if (ret)
1077                 snprintf(ret, len, img_tag_str, str);
1078         return ret;
1079 }
1080
1081 /*
1082 static char *image_path_to_text(AppData *ad, int type_index, const char *str)
1083 {
1084         DMSG("str: %s\n", str);
1085         return make_image_path_tag(ATOM_INDEX_TEXT, str);
1086 }
1087 */
1088
1089 static char *image_path_to_html(AppData *ad, int type_index, const char *str)
1090 {
1091         DMSG("str: %s\n", str);
1092         return make_image_path_tag(ATOM_INDEX_HTML, str);
1093 }
1094
1095 static char *image_path_to_efl(AppData *ad, int type_index, const char *str)
1096 {
1097         DMSG("str: %s\n", str);
1098         return make_image_path_tag(ATOM_INDEX_EFL, str);
1099 }
1100
1101 static char *image_path_to_image_path(AppData *ad, int type_index, const char *str)
1102 {
1103         DMSG("str: %s\n", str);
1104         return make_image_path_tag(ATOM_INDEX_IMAGE, str);;
1105 }
1106 static char *markup_to_entry(AppData *ad, int type_index, const char *str)
1107 {
1108         CALLED();
1109         if (!str)
1110                 return NULL;
1111
1112         Eina_Strbuf *strbuf = eina_strbuf_new();
1113         if (!strbuf)
1114                 return strdup(str);
1115         eina_strbuf_prepend(strbuf, "<font_size=18><color=#000000FF>");
1116
1117         const char *trail = str;
1118         char *image_tag_str = NULL;
1119         char *html_img_tag = "img";
1120         char *efl_img_tag = "item";
1121         if (type_index == ATOM_INDEX_HTML) /* HTML */
1122                 image_tag_str = html_img_tag;
1123         else if (type_index == ATOM_INDEX_EFL) /* EFL */
1124                 image_tag_str = efl_img_tag;
1125
1126         while (trail && *trail)
1127         {
1128                 const char *pretrail = trail;
1129                 unsigned long length;
1130                 char *temp;
1131                 char *endtag;
1132
1133                 trail = strchr(trail, '<');
1134                 if (!trail)
1135                 {
1136                         eina_strbuf_append(strbuf, pretrail);
1137                         break;
1138                 }
1139                 endtag = strchr(trail, '>');
1140                 if (!endtag)
1141                         break;
1142
1143                 length = trail - pretrail;
1144
1145                 temp = strndup(pretrail, length);
1146                 if (!temp)
1147                 {
1148                         trail++;
1149                         continue;
1150                 }
1151
1152                 eina_strbuf_append(strbuf, temp);
1153                 FREE(temp);
1154                 trail++;
1155
1156                 if (trail[0] == '/')
1157                 {
1158                         trail = endtag + 1;
1159                         continue;
1160                 }
1161
1162                 if (strncmp(trail, "br", 2) == 0)
1163                 {
1164                         eina_strbuf_append(strbuf, "<br>");
1165                         trail = endtag + 1;
1166                         continue;
1167                 }
1168
1169                 if (image_tag_str && strncmp(trail, image_tag_str, strlen(image_tag_str)) == 0)
1170                 {
1171                         char *src = strstr(trail, "file://");
1172                         char *src_endtag = strchr(trail, '>');
1173                         if (!src || !src_endtag || src_endtag < src)
1174                                 continue;
1175
1176                         length = src_endtag - src;
1177
1178                         src = strndup(src, length);
1179                         if (!src)
1180                         {
1181                                 trail = endtag + 1;
1182                                 continue;
1183                         }
1184                         temp = src;
1185                         while(*temp)
1186                         {
1187                                 if (*temp == '\"' || *temp == '>')
1188                                         *temp = '\0';
1189                                 else
1190                                         temp++;
1191                         }
1192
1193                         eina_strbuf_append_printf(strbuf, "<item absize=66x62 href=%s></item>", src);
1194                         DTRACE("src str: %s \n", src);
1195                         FREE(src);
1196                 }
1197                 trail = endtag + 1;
1198         }
1199
1200         if (type_index == ATOM_INDEX_HTML)
1201                 eina_strbuf_replace_all(strbuf, "&nbsp;", " ");
1202
1203         char *entry_str = eina_strbuf_string_steal(strbuf);
1204         eina_strbuf_free(strbuf);
1205         return entry_str;
1206 }
1207
1208 static char *html_to_entry(AppData *ad, int type_index, const char *str)
1209 {
1210         DMSG("str: %s\n", str);
1211         return markup_to_entry(ad, type_index, str);
1212 }
1213
1214 static char *efl_to_entry(AppData *ad, int type_index, const char *str)
1215 {
1216         DMSG("str: %s\n", str);
1217         return markup_to_entry(ad, type_index, str);
1218 }
1219
1220 static char *image_path_to_entry(AppData *ad, int type_index, const char *str)
1221 {
1222         CALLED();
1223         return NULL;
1224 }
1225
1226 static char *text_to_entry(AppData *ad, int type_index, const char *str)
1227 {
1228         DMSG("str: %s\n", str);
1229         char *markup = NULL;
1230         markup = (char*)_elm_util_text_to_mkup(str);
1231         char *for_entry = markup_to_entry(ad, type_index, markup);
1232         FREE(markup);
1233         return for_entry;
1234 }
1235
1236 static Eina_List *make_tag_list(int type_index, const char *str)
1237 {
1238         Eina_List *nodeList = NULL;
1239         PTagNode nodeData;
1240
1241         nodeData = _get_start_node(str);
1242
1243         while (nodeData)
1244         {
1245                 nodeList = eina_list_append(nodeList, nodeData);
1246                 nodeData = _get_next_node(nodeData);
1247         }
1248
1249         _link_match_tags(nodeList);
1250
1251         switch(type_index)
1252         {
1253                 case ATOM_INDEX_EFL:
1254                         _set_EFL_tag_data(nodeList);
1255                         break;
1256                 case ATOM_INDEX_HTML:
1257                         _set_HTML_tag_data(nodeList);
1258                         break;
1259                 default:
1260                         DMSG("wrong index: %d\n");
1261         }
1262
1263 #ifdef DEBUG
1264         _dumpNode(nodeList);
1265 #endif
1266         return nodeList;
1267 }
1268
1269 static void cleanup_tag_list(Eina_List *nodeList)
1270 {
1271         Eina_List *trail;
1272         PTagNode nodeData;
1273
1274         EINA_LIST_FOREACH(nodeList, trail, nodeData)
1275                 _delete_node(nodeData);
1276         eina_list_free(nodeList);
1277 }
1278
1279 static char *html_to_efl(AppData *ad, int type_index, const char *str)
1280 {
1281         CALLED();
1282         Eina_List *nodeList = NULL;
1283         nodeList = make_tag_list(type_index, str);
1284         char *ret = _convert_to_edje(nodeList);
1285         DMSG("efl: %s\n", ret);
1286         cleanup_tag_list(nodeList);
1287
1288         return ret;
1289 }
1290
1291 static char *efl_to_html(AppData *ad, int type_index, const char *str)
1292 {
1293         CALLED();
1294         Eina_List *nodeList = NULL;
1295         nodeList = make_tag_list(type_index, str);
1296         char *ret = _convert_to_html(nodeList);
1297         DMSG("html: %s\n", ret);
1298         cleanup_tag_list(nodeList);
1299
1300         return ret;
1301 }
1302
1303 static char *text_to_html(AppData *ad, int type_index, const char *str)
1304 {
1305         DMSG("str: %s\n", str);
1306         char *markup = NULL;
1307         markup = (char*)_elm_util_text_to_mkup(str);
1308         char *html = efl_to_html(ad, ATOM_INDEX_EFL, markup);
1309         FREE(markup);
1310         return html;
1311 }
1312
1313 static char *text_to_efl(AppData *ad, int type_index, const char *str)
1314 {
1315         DMSG("str: %s\n", str);
1316         char *ret = NULL;
1317         ret = (char*)_elm_util_text_to_mkup(str);
1318         return ret;
1319 }
1320
1321 static char *to_text(AppData *ad, int type_index, const char *str)
1322 {
1323         DMSG("str: %s\n", str);
1324         char *text = NULL;
1325         if (type_index == ATOM_INDEX_HTML)
1326         {
1327                 Eina_Strbuf *buf = eina_strbuf_new();
1328                 if (buf)
1329                 {
1330                         char *html;
1331                         eina_strbuf_append(buf, str);
1332                         eina_strbuf_replace_all(buf, "&nbsp;", " ");
1333                         html = eina_strbuf_string_steal(buf);
1334                         eina_strbuf_free(buf);
1335                         text = (char*)_elm_util_mkup_to_text(html);
1336                         free(html);
1337                         return text;
1338                 }
1339         }
1340
1341         text = (char*)_elm_util_mkup_to_text(str);
1342         return text;
1343 }
1344