OSDN Git Service

ec2580613adfb6889ad1af876e22d877517af0b8
[modchxj/mod_chxj.git] / src / chxj_android.c
1 /*
2  * Copyright (C) 2005-2011 Atsushi Konno All rights reserved.
3  * Copyright (C) 2005 QSDN,Inc. All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #include "chxj_android.h"
18 #include "chxj_hdml.h"
19 #include "chxj_dump.h"
20 #include "chxj_img_conv.h"
21 #include "chxj_qr_code.h"
22 #include "chxj_encoding.h"
23 #include "chxj_url_encode.h"
24 #include "chxj_str_util.h"
25 #include "chxj_header_inf.h"
26 #include "chxj_jreserved_tag.h"
27 #include "chxj_conv_z2h.h"
28 #include "chxj_google.h"
29
30
31 #define GET_ANDROID(X) ((android_t *)(X))
32 #undef W_L
33 #undef W_V
34 #define W_L(X)          do { android->out = BUFFERED_WRITE_LITERAL(android->out, &doc->buf, (X)); } while(0)
35 #define W_V(X)          do { android->out = (X) ? BUFFERED_WRITE_VALUE(android->out, &doc->buf, (X))  \
36                                                : BUFFERED_WRITE_LITERAL(android->out, &doc->buf, ""); } while(0)
37 #undef W_NLCODE
38 #define W_NLCODE()     do { char *nlcode = TO_NLCODE(android->conf); W_V(nlcode); } while (0)
39
40 #define BLINK_KEYFRAME \
41 "\n@-webkit-keyframes blink {\n" \
42 " 0% {\n" \
43 "   opacity: 1.0;\n" \
44 " }\n" \
45 " 100% {\n" \
46 "   opacity: 0.0;\n" \
47 " }\n" \
48 "}\n" 
49
50 #define STYLE_BLINK \
51 "-webkit-animation-name: blink;" \
52 "-webkit-animation-duration: 0.6s;" \
53 "-webkit-animation-iteration-count:infinite;" \
54 "-webkit-animation-timing-function:ease-in-out;" \
55 "-webkit-animation-direction: alternate;" \
56 "-webkit-animation-delay: 0s;"
57
58
59
60 static char *s_android_start_html_tag     (void *pdoc, Node *node);
61 static char *s_android_end_html_tag       (void *pdoc, Node *node);
62 static char *s_android_start_meta_tag     (void *pdoc, Node *node);
63 static char *s_android_end_meta_tag       (void *pdoc, Node *node);
64 static char *s_android_start_head_tag     (void *pdoc, Node *node);
65 static char *s_android_end_head_tag       (void *pdoc, Node *node);
66 static char *s_android_start_title_tag    (void *pdoc, Node *node);
67 static char *s_android_end_title_tag      (void *pdoc, Node *node);
68 static char *s_android_start_base_tag     (void *pdoc, Node *node);
69 static char *s_android_end_base_tag       (void *pdoc, Node *node);
70 static char *s_android_start_body_tag     (void *pdoc, Node *node);
71 static char *s_android_end_body_tag       (void *pdoc, Node *node);
72 static char *s_android_start_a_tag        (void *pdoc, Node *node);
73 static char *s_android_end_a_tag          (void *pdoc, Node *node);
74 static char *s_android_start_pre_tag      (void *pdoc, Node *node);
75 static char *s_android_end_pre_tag        (void *pdoc, Node *node);
76 static char *s_android_start_p_tag        (void *pdoc, Node *node);
77 static char *s_android_end_p_tag          (void *pdoc, Node *node);
78 static char *s_android_start_ul_tag       (void *pdoc, Node *node);
79 static char *s_android_end_ul_tag         (void *pdoc, Node *node);
80 static char *s_android_start_ol_tag       (void *pdoc, Node *node);
81 static char *s_android_end_ol_tag         (void *pdoc, Node *node);
82 static char *s_android_start_li_tag       (void *pdoc, Node *node);
83 static char *s_android_end_li_tag         (void *pdoc, Node *node);
84 static char *s_android_start_br_tag       (void *pdoc, Node *node);
85 static char *s_android_end_br_tag         (void *pdoc, Node *node);
86
87 static char *s_android_start_table_tag    (void *pdoc, Node *node);
88 static char *s_android_end_table_tag      (void *pdoc, Node *node);
89 static char *s_android_start_tr_tag       (void *pdoc, Node *node);
90 static char *s_android_end_tr_tag         (void *pdoc, Node *node);
91 static char *s_android_start_td_or_th_tag       (void *pdoc, Node *node,char *tagName);
92 static char *s_android_end_td_or_th_tag         (void *pdoc, Node *node,char *tagName);
93 static char *s_android_start_td_tag       (void *pdoc, Node *node);
94 static char *s_android_end_td_tag         (void *pdoc, Node *node);
95 static char *s_android_start_th_tag       (void *pdoc, Node *node);
96 static char *s_android_end_th_tag         (void *pdoc, Node *node);
97
98 static char *s_android_start_font_tag     (void *pdoc, Node *node);
99 static char *s_android_end_font_tag       (void *pdoc, Node *node);
100 static char *s_android_start_form_tag     (void *pdoc, Node *node);
101 static char *s_android_end_form_tag       (void *pdoc, Node *node);
102 static char *s_android_start_input_tag    (void *pdoc, Node *node);
103 static char *s_android_end_input_tag      (void *pdoc, Node *node);
104 static char *s_android_start_center_tag   (void *pdoc, Node *node);
105 static char *s_android_end_center_tag     (void *pdoc, Node *node);
106 static char *s_android_start_hr_tag       (void *pdoc, Node *node);
107 static char *s_android_end_hr_tag         (void *pdoc, Node *node);
108 static char *s_android_start_img_tag      (void *pdoc, Node *node);
109 static char *s_android_end_img_tag        (void *pdoc, Node *node);
110 static char *s_android_start_select_tag   (void *pdoc, Node *node);
111 static char *s_android_end_select_tag     (void *pdoc, Node *node);
112 static char *s_android_start_option_tag   (void *pdoc, Node *node);
113 static char *s_android_end_option_tag     (void *pdoc, Node *node);
114 static char *s_android_start_div_tag      (void *pdoc, Node *node);
115 static char *s_android_end_div_tag        (void *pdoc, Node *node);
116 static char *s_android_start_textarea_tag (void *pdoc, Node *node);
117 static char *s_android_end_textarea_tag   (void *pdoc, Node *node);
118 static char *s_android_start_b_tag        (void *pdoc, Node *node);
119 static char *s_android_end_b_tag          (void *pdoc, Node *node);
120 static char *s_android_chxjif_tag         (void *pdoc, Node *node); 
121 static char *s_android_text_tag           (void *pdoc, Node *node);
122 static char *s_android_start_blockquote_tag (void *pdoc, Node *node);
123 static char *s_android_end_blockquote_tag  (void *pdoc, Node *node);
124 static char *s_android_start_dir_tag      (void *pdoc, Node *node);
125 static char *s_android_end_dir_tag        (void *pdoc, Node *node);
126 static char *s_android_start_dl_tag       (void *pdoc, Node *node);
127 static char *s_android_end_dl_tag         (void *pdoc, Node *node);
128 static char *s_android_start_dt_tag       (void *pdoc, Node *node);
129 static char *s_android_end_dt_tag         (void *pdoc, Node *node);
130 static char *s_android_start_dd_tag       (void *pdoc, Node *node);
131 static char *s_android_end_dd_tag         (void *pdoc, Node *node);
132 static char *s_android_start_h1_tag       (void *pdoc, Node *node);
133 static char *s_android_end_h1_tag         (void *pdoc, Node *node);
134 static char *s_android_start_h2_tag       (void *pdoc, Node *node);
135 static char *s_android_end_h2_tag         (void *pdoc, Node *node);
136 static char *s_android_start_h3_tag       (void *pdoc, Node *node);
137 static char *s_android_end_h3_tag         (void *pdoc, Node *node);
138 static char *s_android_start_h4_tag       (void *pdoc, Node *node);
139 static char *s_android_end_h4_tag         (void *pdoc, Node *node);
140 static char *s_android_start_h5_tag       (void *pdoc, Node *node);
141 static char *s_android_end_h5_tag         (void *pdoc, Node *node);
142 static char *s_android_start_h6_tag       (void *pdoc, Node *node);
143 static char *s_android_end_h6_tag         (void *pdoc, Node *node);
144 static char *s_android_start_menu_tag     (void *pdoc, Node *node);
145 static char *s_android_end_menu_tag       (void *pdoc, Node *node);
146 static char *s_android_start_plaintext_tag       (void *pdoc, Node *node);
147 static char *s_android_start_plaintext_tag_inner (void *pdoc, Node *node);
148 static char *s_android_end_plaintext_tag         (void *pdoc, Node *node);
149 static char *s_android_start_blink_tag  (void *pdoc, Node *node);
150 static char *s_android_end_blink_tag    (void *pdoc, Node *node);
151 static char *s_android_start_marquee_tag (void *pdoc, Node *node);
152 static char *s_android_end_marquee_tag  (void *pdoc, Node *node);
153 static char *s_android_newline_mark       (void *pdoc, Node *node);
154 static char *s_android_link_tag           (void *pdoc, Node *node);
155 static char *s_android_start_span_tag     (void *pdoc, Node *node);
156 static char *s_android_end_span_tag       (void *pdoc, Node *node);
157 static char *s_android_style_tag       (void *pdoc, Node *node);
158 static char *s_android_start_object_tag     (void *pdoc, Node *node);
159 static char *s_android_end_object_tag       (void *pdoc, Node *node);
160 static char *s_android_start_param_tag     (void *pdoc, Node *node);
161 static char *s_android_start_caption_tag     (void *pdoc, Node *node);
162 static char *s_android_end_caption_tag       (void *pdoc, Node *node);
163
164 static void  s_init_android(android_t *android, Doc *doc, request_rec *r, device_table *spec);
165
166 static int   s_android_search_emoji(android_t *android, char *txt, char **rslt);
167
168 static css_prop_list_t *s_android_nopush_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value);
169 static css_prop_list_t *s_android_push_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value);
170 static char *s_android_create_style_data(apr_pool_t *pool, const char *style_data);
171
172
173
174 tag_handler android_handler[] = {
175   /* tagHTML */
176   {
177     s_android_start_html_tag,
178     s_android_end_html_tag,
179   },
180   /* tagMETA */
181   {
182     s_android_start_meta_tag,
183     s_android_end_meta_tag,
184   },
185   /* tagTEXTAREA */
186   {
187     s_android_start_textarea_tag,
188     s_android_end_textarea_tag,
189   },
190   /* tagP */
191   {
192     s_android_start_p_tag,
193     s_android_end_p_tag,
194   },
195   /* tagPRE */
196   {
197     s_android_start_pre_tag,
198     s_android_end_pre_tag,
199   },
200   /* tagUL */
201   {
202     s_android_start_ul_tag,
203     s_android_end_ul_tag,
204   },
205   /* tagLI */
206   {
207     s_android_start_li_tag,
208     s_android_end_li_tag,
209   },
210   /* tagOL */
211   {
212     s_android_start_ol_tag,
213     s_android_end_ol_tag,
214   },
215   /* tagH1 */
216   {
217     s_android_start_h1_tag,
218     s_android_end_h1_tag,
219   },
220   /* tagH2 */
221   {
222     s_android_start_h2_tag,
223     s_android_end_h2_tag,
224   },
225   /* tagH3 */
226   {
227     s_android_start_h3_tag,
228     s_android_end_h3_tag,
229   },
230   /* tagH4 */
231   {
232     s_android_start_h4_tag,
233     s_android_end_h4_tag,
234   },
235   /* tagH5 */
236   {
237     s_android_start_h5_tag,
238     s_android_end_h5_tag,
239   },
240   /* tagH6 */
241   {
242     s_android_start_h6_tag,
243     s_android_end_h6_tag,
244   },
245   /* tagHEAD */
246   {
247     s_android_start_head_tag,
248     s_android_end_head_tag,
249   },
250   /* tagTITLE */
251   {
252     s_android_start_title_tag,
253     s_android_end_title_tag,
254   },
255   /* tagBASE */
256   {
257     s_android_start_base_tag,
258     s_android_end_base_tag,
259   },
260   /* tagBODY */
261   {
262     s_android_start_body_tag,
263     s_android_end_body_tag,
264   },
265   /* tagA */
266   {
267     s_android_start_a_tag,
268     s_android_end_a_tag,
269   },
270   /* tagBR */
271   {
272     s_android_start_br_tag,
273     s_android_end_br_tag,
274   },
275   /* tagTABLE */
276   {
277     s_android_start_table_tag,
278     s_android_end_table_tag,
279   },
280   /* tagTR */
281   {
282     s_android_start_tr_tag,
283     s_android_end_tr_tag,
284   },
285   /* tagTD */
286   {
287     s_android_start_td_tag,
288     s_android_end_td_tag,
289   },
290   /* tagTBODY */
291   {
292     NULL,
293     NULL,
294   },
295   /* tagFONT */
296   {
297     s_android_start_font_tag,
298     s_android_end_font_tag,
299   },
300   /* tagFORM */
301   {
302     s_android_start_form_tag,
303     s_android_end_form_tag,
304   },
305   /* tagINPUT */
306   {
307     s_android_start_input_tag,
308     s_android_end_input_tag,
309   },
310   /* tagCENTER */
311   {
312     s_android_start_center_tag,
313     s_android_end_center_tag,
314   },
315   /* tagHR */
316   {
317     s_android_start_hr_tag,
318     s_android_end_hr_tag,
319   },
320   /* tagIMG */
321   {
322     s_android_start_img_tag,
323     s_android_end_img_tag,
324   },
325   /* tagSELECT */
326   {
327     s_android_start_select_tag,
328     s_android_end_select_tag,
329   },
330   /* tagOPTION */
331   {
332     s_android_start_option_tag,
333     s_android_end_option_tag,
334   },
335   /* tagDIV */
336   {
337     s_android_start_div_tag,
338     s_android_end_div_tag,
339   },
340   /* tagCHXJIF */
341   {
342     s_android_chxjif_tag,
343     NULL,
344   },
345   /* tagCHXJRAW */
346   {
347     s_android_chxjif_tag,
348     NULL,
349   },
350   /* tagNOBR */
351   {
352     NULL,
353     NULL,
354   },
355   /* tagSMALL */
356   {
357     NULL,
358     NULL,
359   },
360   /* tagSTYLE */
361   {
362     s_android_style_tag,
363     NULL,
364   },
365   /* tagSPAN */
366   {
367     s_android_start_span_tag,
368     s_android_end_span_tag,
369   },
370   /* tagTEXT */
371   {
372     s_android_text_tag,
373     NULL,
374   },
375   /* tagTH */
376   {
377     s_android_start_th_tag,
378     s_android_end_th_tag,
379   },
380   /* tagB */
381   {
382     s_android_start_b_tag,
383     s_android_end_b_tag,
384   },
385   /* tagFIELDSET */
386   {
387     NULL,
388     NULL,
389   },
390   /* tagDT */
391   {
392     s_android_start_dt_tag,
393     s_android_end_dt_tag,
394   },
395   /* tagLEGEND */
396   {
397     NULL,
398     NULL,
399   },
400   /* tagLABEL */
401   {
402     NULL,
403     NULL,
404   },
405   /* tagBLOCKQUOTE */
406   {
407     s_android_start_blockquote_tag,
408     s_android_end_blockquote_tag,
409   },
410   /* tagDIR */
411   {
412     s_android_start_dir_tag,
413     s_android_end_dir_tag,
414   },
415   /* tagDL */
416   {
417     s_android_start_dl_tag,
418     s_android_end_dl_tag,
419   },
420   /* tagDD */
421   {
422     s_android_start_dd_tag,
423     s_android_end_dd_tag,
424   },
425   /* tagMENU */
426   {
427     s_android_start_menu_tag,
428     s_android_end_menu_tag,
429   },
430   /* tagPLAINTEXT */
431   {
432     s_android_start_plaintext_tag,
433     s_android_end_plaintext_tag,
434   },
435   /* tagBLINK */
436   {
437     s_android_start_blink_tag,
438     s_android_end_blink_tag,
439   },
440   /* tagMARQUEE */
441   {
442     s_android_start_marquee_tag,
443     s_android_end_marquee_tag,
444   },
445   /* tagLINK */
446   {
447     s_android_link_tag,
448     NULL,
449   },
450   /* tagNLMARK */
451   {
452     s_android_newline_mark,
453     NULL,
454   },
455   /* tagObject */
456   {
457     s_android_start_object_tag,
458     s_android_end_object_tag,
459   },
460   /* tagParam */
461   {
462     s_android_start_param_tag,
463     NULL,
464   },
465   /* tagCAPTION */
466   {
467     s_android_start_caption_tag,
468     s_android_end_caption_tag,
469   },
470 };
471
472
473 /**
474  * converts from CHTML5.0 to ANDROID.
475  *
476  * @param r     [i]   Requet_rec is appointed.
477  * @param spec  [i]   The result of the device specification processing which 
478  *                    was done in advance is appointed.
479  * @param src   [i]   The character string before the converting is appointed.
480  * @return The character string after the converting is returned.
481  */
482 char *
483 chxj_convert_android(
484   request_rec         *r,
485   device_table        *spec,
486   const char          *src,
487   apr_size_t          srclen,
488   apr_size_t          *dstlen,
489   chxjconvrule_entry  *entryp,
490   cookie_t            *cookie
491 )
492 {
493   char      *dst;
494   char      *ss;
495   android_t   android;
496   Doc       doc;
497
498   dst = NULL;
499
500   /*--------------------------------------------------------------------------*/
501   /* If qrcode xml                                                            */
502   /*--------------------------------------------------------------------------*/
503   *dstlen = srclen;
504   dst = chxj_qr_code_blob_handler(r, src, (size_t*)dstlen);
505   if (dst) {
506     DBG(r,"REQ[%X] I found qrcode xml",TO_ADDR(r));
507     return dst;
508   }
509
510   /*--------------------------------------------------------------------------*/
511   /* The CHTML structure is initialized.                                      */
512   /*--------------------------------------------------------------------------*/
513   s_init_android(&android, &doc, r, spec);
514
515   android.entryp = entryp;
516   android.cookie = cookie;
517   android.head_tag_out = 0;
518   if (strcasecmp(spec->output_encoding,"UTF-8") == 0 ){
519     apr_table_setn(r->headers_out,HTTP_X_CHXJ_SET_CONTENT_TYPE,"application/xhtml+xml; charset=UTF-8");
520   }
521   chxj_set_content_type(r, chxj_header_inf_set_content_type(r, "application/xhtml+xml; charset=Windows-31J"));
522
523   /*--------------------------------------------------------------------------*/
524   /* The character string of the input is analyzed.                           */
525   /*--------------------------------------------------------------------------*/
526   qs_init_malloc(&doc);
527   qs_init_root_node(&doc);
528
529   ss = apr_pcalloc(r->pool, srclen + 1);
530
531   memset(ss,   0, srclen + 1);
532   memcpy(ss, src, srclen);
533
534   if (IS_CSS_ON(android.entryp)) {
535     /* current property list */
536     android.css_prop_stack = chxj_new_prop_list_stack(&doc);
537   }
538 #ifdef DUMP_LOG
539   chxj_dump_out("[src] CHTML -> ANDROID", ss, srclen);
540 #endif
541
542   qs_parse_string(&doc,ss,strlen(ss));
543
544   chxj_buffered_write_init(r->pool, &doc.buf);
545   /*--------------------------------------------------------------------------*/
546   /* It converts it from CHTML to ANDROID.                                     */
547   /*--------------------------------------------------------------------------*/
548   chxj_node_convert(spec,r,(void*)&android, &doc, qs_get_root(&doc), 0);
549   android.out = chxj_buffered_write_flush(android.out, &doc.buf);
550   dst = apr_pstrcat(r->pool, (! android.prev_style_data) ? "" : android.prev_style_data,
551                              s_android_create_style_data(doc.pool, android.style_data),
552                              android.out, NULL);
553   chxj_buffered_write_terminate(&doc.buf);
554
555
556   qs_all_free(&doc,QX_LOGMARK);
557
558   if (! dst) 
559     return apr_pstrdup(r->pool,ss);
560
561   if (! strlen(dst)) 
562     dst = apr_psprintf(r->pool, "\n");
563
564   *dstlen = strlen(dst);
565
566 #ifdef DUMP_LOG
567   chxj_dump_out("[dst] CHTML -> ANDROID", dst, *dstlen);
568 #endif
569
570   return dst;
571 }
572
573
574 /**
575  * The ANDROID structure is initialized.
576  *
577  * @param android [i/o] The pointer to the ANDROID structure that wants to be
578  *                   initialized is specified.
579  * @param doc   [i]   The Doc structure that should be set to the initialized
580  *                   ANDROID structure is specified.
581  * @param r     [i]   To use POOL, the pointer to request_rec is specified.
582  * @param spec  [i]   The pointer to the device_table
583  */
584 static void
585 s_init_android(android_t *android, Doc *doc, request_rec *r, device_table *spec)
586 {
587   memset(doc,   0, sizeof(Doc));
588   memset(android, 0, sizeof(android_t));
589
590   doc->r      = r;
591   android->doc  = doc;
592   android->spec = spec;
593   android->out  = qs_alloc_zero_byte_string(r->pool);
594   android->conf = chxj_get_module_config(r->per_dir_config, &chxj_module);
595   android->doc->parse_mode = PARSE_MODE_CHTML;
596   android->prev_style_data = NULL;
597   android->style_data = NULL;
598   android->blink_keyframe_out = 0;
599   android->charset_out = 0;
600 }
601
602
603 /**
604  * Corresponding EMOJI to a current character-code is retrieved. 
605  * The substitution character string is stored in the rslt pointer if agreeing.
606  *
607  * @param android   [i]   The pointer to the ANDROID structure is specified. 
608  * @param txt     [i]   The character string to want to examine whether it is 
609  *                      EMOJI is specified. 
610  * @param rslt    [o]   The pointer to the pointer that stores the result is 
611  *                      specified. 
612  * @return When corresponding EMOJI exists, it returns it excluding 0. 
613  */
614 static int
615 s_android_search_emoji(android_t *android, char *txt, char **rslt)
616 {
617   emoji_t       *ee;
618   request_rec   *r;
619   device_table  *spec;
620   int           len;
621
622   spec = android->spec;
623
624   len = strlen(txt);
625   r = android->doc->r;
626
627   if (! spec) DBG(r,"REQ[%X] spec is NULL",TO_ADDR(r));
628
629   if (spec->html_spec_type == CHXJ_SPEC_docomo_android) {
630     /*=======================================================================*/
631     /* docomo                                                                */
632     /*=======================================================================*/
633     for (ee = android->conf->emoji;
634          ee;
635          ee = ee->next) {
636       if (ee->imode == NULL) {
637         DBG(r,"REQ[%X] emoji->imode is NULL",TO_ADDR(r));
638         continue;
639       }
640   
641       if (ee->imode->string != NULL
642       &&  strlen(ee->imode->string) > 0
643       &&  strncasecmp(ee->imode->string, txt, strlen(ee->imode->string)) == 0) {
644   
645         if (spec == NULL || spec->emoji_type == NULL) {
646           *rslt = apr_palloc(r->pool, 3);
647           (*rslt)[0] = ee->imode->hex1byte & 0xff;
648           (*rslt)[1] = ee->imode->hex2byte & 0xff;
649           (*rslt)[2] = 0;
650           
651           return strlen(ee->imode->string);
652         }
653   
654         return 0;
655       }
656     }
657   }
658   else if (spec->html_spec_type == CHXJ_SPEC_au_android) {
659     /*=======================================================================*/
660     /* au KDDI                                                               */
661     /*=======================================================================*/
662     for (ee = android->conf->emoji;
663          ee;
664          ee = ee->next) {
665       unsigned char hex1byte;
666       unsigned char hex2byte;
667       if (!ee->imode) {
668         DBG(r,"REQ[%X] emoji->imode is NULL",TO_ADDR(r));
669         continue;
670       }
671   
672       if (ee->imode->string != NULL
673       &&  strlen(ee->imode->string) > 0
674       &&  strncasecmp(ee->imode->string, txt, strlen(ee->imode->string)) == 0) {
675         if (spec == NULL || spec->emoji_type == NULL) {
676           if (ee->ezweb != NULL && ee->ezweb->typeA != NULL) {
677             if (android->conf->use_emoji_image 
678                 && android->conf->emoji_image_url 
679                 && strcasecmp(ee->ezweb->typeA,"image") == 0) {
680               *rslt = apr_psprintf(r->pool, "<img src=\"%s/%d\" />",android->conf->emoji_image_url, ee->no);
681             }
682             else if (strncasecmp(ee->ezweb->typeA,"raw:",4) == 0) {
683               *rslt = apr_psprintf(r->pool,"%s",&(ee->ezweb->typeA[4]));
684             }
685             else {
686               *rslt = apr_psprintf(r->pool,
687                               "<img localsrc=%s>",
688                               ee->ezweb->typeA);
689             } 
690           }
691           return strlen(ee->imode->string);
692         }
693   
694         if (strcasecmp(android->spec->emoji_type, "a") == 0) {
695           if (ee->ezweb != NULL && ee->ezweb->typeA != NULL) {
696             if (android->conf->use_emoji_image 
697                 && android->conf->emoji_image_url 
698                 && strcasecmp(ee->ezweb->typeA,"image") == 0) {
699               *rslt = apr_psprintf(r->pool, "<img src=\"%s/%d\" />",android->conf->emoji_image_url, ee->no);
700             }
701             else if (strncasecmp(ee->ezweb->typeA,"raw:",4) == 0) {
702               *rslt = apr_psprintf(r->pool,"%s",&(ee->ezweb->typeA[4]));
703             }
704             else {
705               *rslt = apr_psprintf(r->pool,
706                               "<img localsrc=%s>",
707                               ee->ezweb->typeA);
708             }
709           }
710           return strlen(ee->imode->string);
711         } 
712         else
713         if (strcasecmp(android->spec->emoji_type, "b") == 0) {
714           if (ee->ezweb != NULL && ee->ezweb->typeB != NULL) {
715             if (android->conf->use_emoji_image
716                 && android->conf->emoji_image_url
717                 && strcasecmp(ee->ezweb->typeB,"image") == 0) {
718               *rslt = apr_psprintf(r->pool, "<img src=\"%s/%d\" />",android->conf->emoji_image_url, ee->no);
719             }
720             else if (strncasecmp(ee->ezweb->typeB,"raw:",4) == 0) {
721               *rslt = apr_psprintf(r->pool,"%s",&(ee->ezweb->typeB[4]));
722             }
723             else {
724               *rslt = apr_psprintf(r->pool,
725                               "<img localsrc=%s>",
726                               ee->ezweb->typeB);
727             }
728           }
729           return strlen(ee->imode->string);
730         }
731         else
732         if (strcasecmp(android->spec->emoji_type, "c") == 0) {
733           if (ee->ezweb != NULL && ee->ezweb->typeC != NULL) {
734             if (android->conf->use_emoji_image
735                 && android->conf->emoji_image_url
736                 && strcasecmp(ee->ezweb->typeC,"image") == 0) {
737               *rslt = apr_psprintf(r->pool, "<img src=\"%s/%d\" />",android->conf->emoji_image_url, ee->no);
738             }
739             else if (strncasecmp(ee->ezweb->typeC,"raw:",4) == 0) {
740               *rslt = apr_psprintf(r->pool,"%s",&(ee->ezweb->typeC[4]));
741             }
742             else {
743               *rslt = apr_psprintf(r->pool,
744                               "<img localsrc=%s>",
745                               ee->ezweb->typeC);
746             }
747           }
748           return strlen(ee->imode->string);
749         }
750         else
751         if (strcasecmp(android->spec->emoji_type, "d") == 0) {
752           if (ee->ezweb != NULL && ee->ezweb->typeD != NULL) {
753             if (android->conf->use_emoji_image
754                 && android->conf->emoji_image_url
755                 && strcasecmp(ee->ezweb->typeD,"image") == 0) {
756               *rslt = apr_psprintf(r->pool, "<img src=\"%s/%d\" />",android->conf->emoji_image_url, ee->no);
757             }
758             else if (strncasecmp(ee->ezweb->typeD,"raw:",4) == 0) {
759               *rslt = apr_psprintf(r->pool,"%s",&(ee->ezweb->typeD[4]));
760             }
761             else {
762               *rslt = apr_psprintf(r->pool,
763                               "<img localsrc=%s>",
764                               ee->ezweb->typeD);
765             }
766           }
767           return strlen(ee->imode->string);
768         }
769         else {
770           if (ee->ezweb != NULL && ee->ezweb->typeA != NULL) {
771             if (android->conf->use_emoji_image
772                 && android->conf->emoji_image_url
773                 && strcasecmp(ee->ezweb->typeA,"image") == 0) {
774               *rslt = apr_psprintf(r->pool, "<img src=\"%s/%d\" />",android->conf->emoji_image_url, ee->no);
775             }
776             else if (strncasecmp(ee->ezweb->typeA,"raw:",4) == 0) {
777               *rslt = apr_psprintf(r->pool,"%s",&(ee->ezweb->typeA[4]));
778             }
779             else {
780               *rslt = apr_psprintf(r->pool,
781                               "<img localsrc=%s>",
782                               ee->ezweb->typeA);
783             }
784           }
785           return strlen(ee->imode->string);
786         }
787         return 0;
788       }
789       hex1byte = ee->imode->hex1byte & 0xff;
790       hex2byte = ee->imode->hex2byte & 0xff;
791       if (len >= 2
792       && ((unsigned char)txt[0] & 0xff) == ((unsigned char)hex1byte)
793       && ((unsigned char)txt[1] & 0xff) == ((unsigned char)hex2byte)) {
794         if (spec == NULL || spec->emoji_type == NULL) {
795           if (ee->ezweb != NULL && ee->ezweb->typeA != NULL) {
796             if (android->conf->use_emoji_image
797                 && android->conf->emoji_image_url
798                 && strcasecmp(ee->ezweb->typeA,"image") == 0) {
799               *rslt = apr_psprintf(r->pool, "<img src=\"%s/%d\" />",android->conf->emoji_image_url, ee->no);
800             }
801             else if (strncasecmp(ee->ezweb->typeA,"raw:",4) == 0) {
802               *rslt = apr_psprintf(r->pool,"%s",&(ee->ezweb->typeA[4]));
803             }
804             else {
805               *rslt = apr_psprintf(r->pool,
806                               "<img localsrc=\"%s\">",
807                               ee->ezweb->typeA);
808             }
809           }
810           return 2;
811         }
812   
813         if (strcasecmp(android->spec->emoji_type, "a") == 0) {
814           if (ee->ezweb != NULL && ee->ezweb->typeA != NULL) {
815             if (android->conf->use_emoji_image
816                 && android->conf->emoji_image_url
817                 && strcasecmp(ee->ezweb->typeA,"image") == 0) {
818               *rslt = apr_psprintf(r->pool, "<img src=\"%s/%d\" />",android->conf->emoji_image_url, ee->no);
819             }
820             else if (strncasecmp(ee->ezweb->typeA,"raw:",4) == 0) {
821               *rslt = apr_psprintf(r->pool,"%s",&(ee->ezweb->typeA[4]));
822             }
823             else {
824               *rslt = apr_psprintf(r->pool,
825                               "<img localsrc=\"%s\">",
826                               ee->ezweb->typeA);
827             }
828           }
829           return 2;
830         } 
831         else
832         if (strcasecmp(android->spec->emoji_type, "b") == 0) {
833           if (ee->ezweb != NULL && ee->ezweb->typeB != NULL) {
834             if (android->conf->use_emoji_image
835                 && android->conf->emoji_image_url
836                 && strcasecmp(ee->ezweb->typeB,"image") == 0) {
837               *rslt = apr_psprintf(r->pool, "<img src=\"%s/%d\" />",android->conf->emoji_image_url, ee->no);
838             }
839             else if (strncasecmp(ee->ezweb->typeB,"raw:",4) == 0) {
840               *rslt = apr_psprintf(r->pool,"%s",&(ee->ezweb->typeB[4]));
841             }
842             else {
843               *rslt = apr_psprintf(r->pool,
844                               "<img localsrc=\"%s\">",
845                               ee->ezweb->typeB);
846             }
847           }
848           return 2;
849         }
850         else
851         if (strcasecmp(android->spec->emoji_type, "c") == 0) {
852           if (ee->ezweb != NULL && ee->ezweb->typeC != NULL) {
853             if (android->conf->use_emoji_image
854                 && android->conf->emoji_image_url
855                 && strcasecmp(ee->ezweb->typeC,"image") == 0) {
856               *rslt = apr_psprintf(r->pool, "<img src=\"%s/%d\" />",android->conf->emoji_image_url, ee->no);
857             }
858             else if (strncasecmp(ee->ezweb->typeC,"raw:",4) == 0) {
859               *rslt = apr_psprintf(r->pool,"%s",&(ee->ezweb->typeC[4]));
860             }
861             else {
862               *rslt = apr_psprintf(r->pool,
863                               "<img localsrc=\"%s\">",
864                               ee->ezweb->typeC);
865             }
866           }
867           return 2;
868         }
869         else
870         if (strcasecmp(android->spec->emoji_type, "d") == 0) {
871           if (ee->ezweb != NULL && ee->ezweb->typeD != NULL) {
872             if (android->conf->use_emoji_image
873                 && android->conf->emoji_image_url
874                 && strcasecmp(ee->ezweb->typeD,"image") == 0) {
875               *rslt = apr_psprintf(r->pool, "<img src=\"%s/%d\" />",android->conf->emoji_image_url, ee->no);
876             }
877             else if (strncasecmp(ee->ezweb->typeD,"raw:",4) == 0) {
878               *rslt = apr_psprintf(r->pool,"%s",&(ee->ezweb->typeD[4]));
879             }
880             else {
881               *rslt = apr_psprintf(r->pool,
882                               "<img localsrc=\"%s\">",
883                               ee->ezweb->typeD);
884             }
885           }
886           return 2;
887         }
888         else {
889           if (ee->ezweb != NULL && ee->ezweb->typeA != NULL) {
890             if (android->conf->use_emoji_image
891                 && android->conf->emoji_image_url
892                 && strcasecmp(ee->ezweb->typeA,"image") == 0) {
893               *rslt = apr_psprintf(r->pool, "<img src=\"%s/%d\" />",android->conf->emoji_image_url, ee->no);
894             }
895             else if (strncasecmp(ee->ezweb->typeA,"raw:",4) == 0) {
896               *rslt = apr_psprintf(r->pool,"%s",&(ee->ezweb->typeA[4]));
897             }
898             else {
899               *rslt = apr_psprintf(r->pool,
900                               "<img localsrc=\"%s\">",
901                               ee->ezweb->typeA);
902             }
903           }
904           return 2;
905         }
906         return 0;
907       }
908     }
909   }
910   else if (spec->html_spec_type == CHXJ_SPEC_softbank_android) {
911     /*=======================================================================*/
912     /* softbank                                                              */
913     /*=======================================================================*/
914     for (ee = android->conf->emoji;
915          ee;
916          ee = ee->next) {
917   
918       unsigned char hex1byte;
919       unsigned char hex2byte;
920   
921       if (! ee->imode) { 
922         DBG(r,"REQ[%X] emoji->imode is NULL",TO_ADDR(r));
923         continue;
924       }
925   
926       hex1byte = ee->imode->hex1byte & 0xff;
927       hex2byte = ee->imode->hex2byte & 0xff;
928   
929       if (ee->imode->string
930       &&  strlen(ee->imode->string) > 0
931       &&  strncasecmp(ee->imode->string, txt, strlen(ee->imode->string)) == 0) {
932         if (spec == NULL || spec->emoji_type == NULL) {
933           if (ee->iphone != NULL && ee->iphone->string != NULL) {
934             if (android->conf->use_emoji_image
935                 && android->conf->emoji_image_url
936                 && (spec->html_spec_type == CHXJ_SPEC_iPhone2
937                   || strcasecmp(ee->iphone->string,"image") == 0)) {
938               *rslt = apr_psprintf(r->pool, "<img src=\"%s/%d\" />",android->conf->emoji_image_url, ee->no);
939             }
940             else if (strncasecmp(ee->iphone->string, "raw:", 4) == 0) {
941               *rslt = apr_psprintf(r->pool,"%s", &(ee->iphone->string[4]));
942             }
943             else {
944               *rslt = apr_psprintf(r->pool,"%s;", ee->iphone->string);
945             }
946           }
947           return strlen(ee->imode->string);
948         }
949         return 0;
950       }
951   
952       if (len >= 2
953       && ((unsigned char)txt[0] & 0xff) == ((unsigned char)hex1byte)
954       && ((unsigned char)txt[1] & 0xff) == ((unsigned char)hex2byte)) {
955         if (spec == NULL || spec->emoji_type == NULL) {
956           if (ee->iphone != NULL && ee->iphone->string != NULL) {
957             if (android->conf->use_emoji_image
958                 && android->conf->emoji_image_url
959                 && (spec->html_spec_type == CHXJ_SPEC_iPhone2
960                   || strcasecmp(ee->iphone->string,"image") == 0)) {
961               *rslt = apr_psprintf(r->pool, "<img src=\"%s/%d\" />",android->conf->emoji_image_url, ee->no);
962             }
963             else if (strncasecmp(ee->iphone->string, "raw:", 4) == 0) {
964               *rslt = apr_psprintf(r->pool,"%s", &(ee->iphone->string[4]));
965             }
966             else {
967               *rslt = apr_psprintf(r->pool,"%s;", ee->iphone->string);
968             }
969           }
970           return 2;
971         }
972   
973         return 0;
974       }
975     }
976   }
977   else if (spec->html_spec_type == CHXJ_SPEC_android) {
978     /*=======================================================================*/
979     /* other                                                                 */
980     /*=======================================================================*/
981     for (ee = android->conf->emoji;
982          ee;
983          ee = ee->next) {
984   
985       unsigned char hex1byte;
986       unsigned char hex2byte;
987   
988       if (! ee->imode) { 
989         DBG(r,"REQ[%X] emoji->imode is NULL",TO_ADDR(r));
990         continue;
991       }
992   
993       hex1byte = ee->imode->hex1byte & 0xff;
994       hex2byte = ee->imode->hex2byte & 0xff;
995   
996       if (ee->imode->string
997       &&  strlen(ee->imode->string) > 0
998       &&  strncasecmp(ee->imode->string, txt, strlen(ee->imode->string)) == 0) {
999         if (spec == NULL || spec->emoji_type == NULL) {
1000           if (ee->android != NULL && ee->android->string != NULL) {
1001             if (android->conf->use_emoji_image
1002                 && android->conf->emoji_image_url
1003                 && strcasecmp(ee->android->string,"image") == 0) {
1004               *rslt = apr_psprintf(r->pool, "<img src=\"%s/%d\" />",android->conf->emoji_image_url, ee->no);
1005             }
1006             else if (strncasecmp(ee->android->string, "raw:", 4) == 0) {
1007               *rslt = apr_psprintf(r->pool,"%s", &(ee->android->string[4]));
1008             }
1009             else if (strcasecmp(ee->android->string, "image") != 0) {
1010               *rslt = apr_psprintf(r->pool,"%s;", ee->android->string);
1011             }
1012             else {
1013               ERR(r, "Please set ChxjUseEmojiImage and ChxjEmojiImageUrl directives.");
1014             }
1015           }
1016           return strlen(ee->imode->string);
1017         }
1018         return 0;
1019       }
1020   
1021       if (len >= 2
1022       && ((unsigned char)txt[0] & 0xff) == ((unsigned char)hex1byte)
1023       && ((unsigned char)txt[1] & 0xff) == ((unsigned char)hex2byte)) {
1024         if (spec == NULL || spec->emoji_type == NULL) {
1025           if (ee->android != NULL && ee->android->string != NULL) {
1026             if (android->conf->use_emoji_image
1027                 && android->conf->emoji_image_url
1028                 && strcasecmp(ee->android->string,"image") == 0) {
1029               *rslt = apr_psprintf(r->pool, "<img src=\"%s/%d\" />",android->conf->emoji_image_url, ee->no);
1030             }
1031             else if (strncasecmp(ee->android->string, "raw:", 4) == 0) {
1032               *rslt = apr_psprintf(r->pool,"%s", &(ee->android->string[4]));
1033             }
1034             else {
1035               *rslt = apr_psprintf(r->pool,"%s;", ee->android->string);
1036             }
1037           }
1038           return 2;
1039         }
1040   
1041         return 0;
1042       }
1043     }
1044   }
1045   return 0;
1046 }
1047
1048
1049 char *
1050 chxj_android_emoji_only_converter(request_rec *r, device_table *spec, const char *src, apr_size_t len)
1051 {
1052   apr_size_t ii;
1053   Doc __doc;
1054   Doc *doc;
1055   android_t __android;
1056   android_t *android;
1057   char one_byte[2];
1058   char two_byte[3];
1059   apr_pool_t *pool;
1060
1061   android = &__android;
1062   doc    = &__doc;
1063
1064   DBG(r,"REQ[%X] start %s()",TO_ADDR(r),__func__);
1065   memset(doc,    0, sizeof(Doc));
1066   memset(android, 0, sizeof(android_t));
1067
1068   doc->r       = r;
1069   android->doc  = doc;
1070   android->spec = spec;
1071   android->out  = qs_alloc_zero_byte_string(r->pool);
1072   android->conf = chxj_get_module_config(r->per_dir_config, &chxj_module);
1073   android->doc->parse_mode = PARSE_MODE_CHTML;
1074
1075   apr_pool_create(&pool, r->pool);
1076
1077   chxj_buffered_write_init(pool, &doc->buf);
1078
1079   for (ii=0; ii<len; ii++) {
1080     char *out;
1081     int   rtn;
1082
1083     rtn = s_android_search_emoji(android, (char *)&src[ii], &out);
1084     if (rtn) {
1085       W_V(out);
1086       ii+=(rtn - 1);
1087       continue;
1088     }
1089
1090     if (is_sjis_kanji(src[ii])) {
1091       two_byte[0] = src[ii+0];
1092       two_byte[1] = src[ii+1];
1093       two_byte[2] = 0;
1094       W_V(two_byte);
1095       ii++;
1096     }
1097     else {
1098       one_byte[0] = src[ii+0];
1099       one_byte[1] = 0;
1100       W_V(one_byte);
1101     }
1102   }
1103   android->out = chxj_buffered_write_flush(android->out, &doc->buf);
1104
1105   DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
1106   return android->out;
1107 }
1108
1109
1110 /**
1111  * It is a handler who processes the HTML tag.
1112  *
1113  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1114  *                     destination is specified.
1115  * @param node   [i]   The HTML tag node is specified.
1116  * @return The conversion result is returned.
1117  */
1118 static char *
1119 s_android_start_html_tag(void *pdoc, Node *UNUSED(node)) 
1120 {
1121   android_t       *android;
1122   Doc           *doc;
1123   request_rec   *r;
1124
1125
1126   android  = GET_ANDROID(pdoc);
1127   doc    = android->doc;
1128   r      = doc->r;
1129   DBG(r,"REQ[%X] start %s()",TO_ADDR(r),__func__);
1130
1131   W_L("<?xml version=\"1.0\" encoding=\"");
1132   W_V(android->spec->output_encoding);
1133   W_L("\" ?>");
1134   W_NLCODE();
1135   W_L("<!DOCTYPE html PUBLIC \"-//WAPFORUM//DTD XHTML Mobile 1.1//EN\" \"http://www.openmobilealliance.org/tech/DTD/xhtml-mobile11.dtd\">");
1136   W_NLCODE();
1137
1138
1139   /*--------------------------------------------------------------------------*/
1140   /* start HTML tag                                                           */
1141   /*--------------------------------------------------------------------------*/
1142   W_L("<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"ja\" xml:lang=\"ja\">");
1143
1144   android->start_html_flag = 1;
1145
1146   DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
1147
1148   return android->out;
1149 }
1150
1151
1152 /**
1153  * It is a handler who processes the HTML tag.
1154  *
1155  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1156  *                     destination is specified.
1157  * @param node   [i]   The HTML tag node is specified.
1158  * @return The conversion result is returned.
1159  */
1160 static char *
1161 s_android_end_html_tag(void *pdoc, Node *UNUSED(child)) 
1162 {
1163   android_t      *android = GET_ANDROID(pdoc);
1164   Doc           *doc = android->doc;
1165
1166   W_L("</html>");
1167
1168   return android->out;
1169 }
1170
1171
1172 /**
1173  * It is a handler who processes the META tag.
1174  *
1175  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1176  *                     destination is specified.
1177  * @param node   [i]   The META tag node is specified.
1178  * @return The conversion result is returned.
1179  */
1180 static char *
1181 s_android_start_meta_tag(void *pdoc, Node *node) 
1182 {
1183   android_t     *android;
1184   Doc          *doc;
1185   request_rec  *r;
1186   Attr         *attr;
1187   int          content_type_flag;
1188   int          refresh_flag;
1189
1190   android             = GET_ANDROID(pdoc);
1191   doc               = android->doc;
1192   r                 = doc->r;
1193   refresh_flag      = 0;
1194   content_type_flag = 0;
1195
1196   W_L("<meta");
1197   /*--------------------------------------------------------------------------*/
1198   /* Get Attributes                                                           */
1199   /*--------------------------------------------------------------------------*/
1200   for (attr = qs_get_attr(doc,node);
1201        attr;
1202        attr = qs_get_next_attr(doc,attr)) {
1203     char *name   = qs_get_attr_name(doc,attr);
1204     char *value  = qs_get_attr_value(doc,attr);
1205     switch(*name) {
1206     case 'h':
1207     case 'H':
1208       if (strcasecmp(name, "http-equiv") == 0 && value && *value) {
1209         /*----------------------------------------------------------------------*/
1210         /* CHTML 2.0                                                            */
1211         /*----------------------------------------------------------------------*/
1212         W_L(" http-equiv=\"");
1213         W_V(value);
1214         W_L("\"");
1215         if (STRCASEEQ('c','C',"content-type",value)) {
1216           content_type_flag = 1;
1217         }
1218         if (STRCASEEQ('r','R',"refresh",value)) {
1219           refresh_flag = 1;
1220         }
1221       }
1222       break;
1223
1224     case 'c':
1225     case 'C':
1226       if (strcasecmp(name, "content") == 0 && value && *value) {
1227         /*----------------------------------------------------------------------*/
1228         /* CHTML 2.0                                                            */
1229         /*----------------------------------------------------------------------*/
1230         if (content_type_flag)  {
1231           W_L(" ");
1232           W_V(name);
1233           W_L("=\"");
1234           W_V(chxj_header_inf_set_content_type(r, "application/xhtml+xml; charset=SHIFT_JIS"));
1235           W_L("\"");
1236         }
1237         else
1238         if (refresh_flag) {
1239           char *buf;
1240           char *sec;
1241           char *url;
1242   
1243           buf = apr_pstrdup(r->pool, value);
1244   
1245           url = strchr(buf, ';');
1246           if (url) {
1247             sec = apr_pstrdup(r->pool, buf);
1248             sec[url-buf] = 0;
1249             url++;
1250             url = chxj_encoding_parameter(r, url, 1);
1251             W_L(" ");
1252             W_V(name);
1253             W_L("=\"");
1254             W_V(sec);
1255             W_L(";");
1256             W_V(url);
1257             W_L("\"");
1258           }
1259         }
1260         else {
1261           W_L(" ");
1262           W_V(name);
1263           W_L("=\"");
1264           W_V(value);
1265           W_L("\"");
1266         }
1267       }
1268       break;
1269     case 'n':
1270     case 'N':
1271       if (strcasecmp(name, "name") == 0 && value && *value) {
1272         W_L(" name=\"");
1273         W_V(value);
1274         W_L("\"");
1275       }
1276       break;
1277     default:
1278       break;
1279     }
1280   }
1281   W_L(" />");
1282
1283   if (content_type_flag) {
1284     android->charset_out = 1;
1285   }
1286   return android->out;
1287 }
1288
1289
1290 /**
1291  * It is a handler who processes the META tag.
1292  *
1293  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1294  *                     destination is specified.
1295  * @param node   [i]   The META tag node is specified.
1296  * @return The conversion result is returned.
1297  */
1298 static char *
1299 s_android_end_meta_tag(void *pdoc, Node *UNUSED(child)) 
1300 {
1301   android_t *android = GET_ANDROID(pdoc);
1302
1303   return android->out;
1304 }
1305
1306
1307 /**
1308  * It is a handler who processes the HEAD tag.
1309  *
1310  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1311  *                     destination is specified.
1312  * @param node   [i]   The HEAD tag node is specified.
1313  * @return The conversion result is returned.
1314  */
1315 static char *
1316 s_android_start_head_tag(void *pdoc, Node *node) 
1317 {
1318   android_t      *android;
1319   Attr          *attr;
1320   Doc           *doc;
1321   Node          *child;
1322   request_rec   *r;
1323
1324   android = GET_ANDROID(pdoc);
1325   doc   = android->doc;
1326   r     = doc->r;
1327   android->head_tag_out = 1;
1328
1329   W_L("<head>");
1330
1331   /* search <meta name="viewport"> */
1332   int found_viewport = 0;
1333   for (child = qs_get_child_node(doc,node);
1334        child;
1335        child = qs_get_next_node(doc,child)) {
1336     char *name = qs_get_node_name(doc,child);
1337     switch(*name) {
1338     case 'm':
1339     case 'M':
1340       if (strcasecmp("meta",name) == 0) {
1341         for (attr = qs_get_attr(doc,child);
1342              attr;
1343              attr = qs_get_next_attr(doc,attr)) {
1344           char *aname  = qs_get_attr_name(doc,attr);
1345           char *avalue = qs_get_attr_value(doc,attr);
1346           if (STRCASEEQ('n','N',"name",aname)) {
1347             if (STRCASEEQ('v','V',"viewport",avalue)) {
1348               found_viewport = 1;
1349               DBG(r, "REQ[%X] viewport Found!!",TO_ADDR(r));
1350               break;
1351             }
1352           }
1353         }
1354       }
1355       break;
1356
1357     default: 
1358       break;
1359     }
1360     if (found_viewport) {
1361       break;
1362     }
1363   }
1364
1365   if (!found_viewport) {
1366     W_L("<meta ");
1367     W_L("name=\"viewport\" ");
1368     W_L("id=\"android-viewport\" ");
1369     W_L("content=\"width=");
1370     char *ww = apr_psprintf(r->pool, "%d", (int)((double)android->spec->width * (double)1.5) - ADJUST_WIDTH_FOR_ANDROID);
1371     W_V(ww);
1372     W_L(",user-scalable=no,maximum-scale=0.6667\" />");
1373     W_L("<meta name=\"format-detection\" content=\"telephone=no\" />");
1374   }
1375   if (!android->charset_out) {
1376     W_L("<meta http-equiv=\"Content-Type\" content=\"application/xhtml+xml; charset=UTF-8\" />");
1377     W_L("<meta charset=\"UTF-8\" />");
1378     android->charset_out = 1;
1379   }
1380   return android->out;
1381 }
1382
1383
1384 /**
1385  * It is a handler who processes the HEAD tag.
1386  *
1387  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1388  *                     destination is specified.
1389  * @param node   [i]   The HEAD tag node is specified.
1390  * @return The conversion result is returned.
1391  */
1392 static char *
1393 s_android_end_head_tag(void *pdoc, Node *UNUSED(child)) 
1394 {
1395   android_t       *android;
1396   Doc           *doc;
1397   request_rec   *r;
1398
1399   android = GET_ANDROID(pdoc);
1400   doc   = android->doc;
1401   r     = doc->r;
1402
1403   android->out = chxj_buffered_write_flush(android->out, &doc->buf);
1404   android->prev_style_data = apr_pstrdup(doc->pool, android->out);
1405   android->out = qs_alloc_zero_byte_string(r->pool);
1406
1407   W_L("</head>");
1408   return android->out;
1409 }
1410
1411
1412 /**
1413  * It is a handler who processes the TITLE tag.
1414  *
1415  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1416  *                     destination is specified.
1417  * @param node   [i]   The TITLE tag node is specified.
1418  * @return The conversion result is returned.
1419  */
1420 static char *
1421 s_android_start_title_tag(void *pdoc, Node *UNUSED(node)) 
1422 {
1423   android_t      *android;
1424   Doc          *doc;
1425   request_rec  *r;
1426
1427   android = GET_ANDROID(pdoc);
1428   doc   = android->doc;
1429   r     = doc->r;
1430
1431   W_L("<title>");
1432   return android->out;
1433 }
1434
1435
1436 /**
1437  * It is a handler who processes the TITLE tag.
1438  *
1439  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1440  *                     destination is specified.
1441  * @param node   [i]   The TITLE tag node is specified.
1442  * @return The conversion result is returned.
1443  */
1444 static char *
1445 s_android_end_title_tag(void *pdoc, Node *UNUSED(child)) 
1446 {
1447   android_t      *android;
1448   Doc           *doc;
1449   request_rec   *r;
1450
1451   android = GET_ANDROID(pdoc);
1452   doc   = android->doc;
1453   r     = doc->r;
1454
1455   W_L("</title>");
1456   return android->out;
1457 }
1458
1459
1460 /**
1461  * It is a handler who processes the BASE tag.
1462  *
1463  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1464  *                     destination is specified.
1465  * @param node   [i]   The BASE tag node is specified.
1466  * @return The conversion result is returned.
1467  */
1468 static char *
1469 s_android_start_base_tag(void *pdoc, Node *node) 
1470 {
1471   android_t      *android;
1472   Attr          *attr;
1473   Doc           *doc;
1474   request_rec   *r;
1475
1476   android = GET_ANDROID(pdoc);
1477   doc   = android->doc;
1478   r     = doc->r;
1479
1480   W_L("<base");
1481   /*--------------------------------------------------------------------------*/
1482   /* Get Attributes                                                           */
1483   /*--------------------------------------------------------------------------*/
1484   for (attr = qs_get_attr(doc,node);
1485        attr;
1486        attr = qs_get_next_attr(doc,attr)) {
1487     char *name  = qs_get_attr_name(doc,attr);
1488     char *value = qs_get_attr_value(doc,attr);
1489     if (STRCASEEQ('h','H',"href",name)) {
1490       W_L(" href=\"");
1491       W_V(value);
1492       W_L("\"");
1493     }
1494   }
1495   W_L(" />");
1496   return android->out;
1497 }
1498
1499
1500 /**
1501  * It is a handler who processes the BASE tag.
1502  *
1503  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1504  *                     destination is specified.
1505  * @param node   [i]   The BASE tag node is specified.
1506  * @return The conversion result is returned.
1507  */
1508 static char *
1509 s_android_end_base_tag(void *pdoc, Node *UNUSED(child)) 
1510 {
1511   android_t *android = GET_ANDROID(pdoc);
1512   return android->out;
1513 }
1514
1515
1516 /**
1517  * It is a handler who processes the BODY tag.
1518  *
1519  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1520  *                     destination is specified.
1521  * @param node   [i]   The BODY tag node is specified.
1522  * @return The conversion result is returned.
1523  */
1524 static char *
1525 s_android_start_body_tag(void *pdoc, Node *node) 
1526 {
1527   android_t    *android;
1528   Doc         *doc;
1529   request_rec *r;
1530   Attr        *attr;
1531   char        *attr_bgcolor = NULL;
1532   char        *attr_text    = NULL;
1533   char        *attr_link    = NULL;
1534   char        *attr_vlink   = NULL;
1535   char        *attr_alink   = NULL;
1536   char        *attr_style   = NULL;
1537   char        *attr_background   = NULL;
1538   char        *style_data   = NULL;
1539
1540   android = GET_ANDROID(pdoc);
1541   doc   = android->doc;
1542   r     = doc->r;
1543
1544
1545   /*--------------------------------------------------------------------------*/
1546   /* Get Attributes                                                           */
1547   /*--------------------------------------------------------------------------*/
1548   for (attr = qs_get_attr(doc,node);
1549        attr;
1550        attr = qs_get_next_attr(doc,attr)) {
1551     char *name   = qs_get_attr_name(doc,attr);
1552     char *value  = qs_get_attr_value(doc,attr);
1553     if (STRCASEEQ('b','B',"bgcolor",name) && value && *value) {
1554       /*----------------------------------------------------------------------*/
1555       /* CHTML 2.0                                                            */
1556       /*----------------------------------------------------------------------*/
1557       attr_bgcolor = value;
1558     }
1559     else if (STRCASEEQ('t','T',"text",name) && value && *value) {
1560       /*----------------------------------------------------------------------*/
1561       /* CHTML 2.0                                                            */
1562       /*----------------------------------------------------------------------*/
1563       attr_text = value;
1564     }
1565     else if (STRCASEEQ('l','L',"link",name) && value && *value) {
1566       /*----------------------------------------------------------------------*/
1567       /* CHTML 2.0                                                            */
1568       /*----------------------------------------------------------------------*/
1569       attr_link = value;
1570     }
1571     else if (STRCASEEQ('a','A',"alink",name)) {
1572       /*----------------------------------------------------------------------*/
1573       /* CHTML 4.0                                                            */
1574       /*----------------------------------------------------------------------*/
1575       attr_alink = value;
1576     }
1577     else if (STRCASEEQ('v','V',"vlink",name)) {
1578       /*----------------------------------------------------------------------*/
1579       /* CHTML 4.0                                                            */
1580       /*----------------------------------------------------------------------*/
1581       attr_vlink = value;
1582     }
1583     else if (STRCASEEQ('b','B',"background",name) && value && *value) {
1584       /*----------------------------------------------------------------------*/
1585       /* CHTML 6.0                                                            */
1586       /*----------------------------------------------------------------------*/
1587       attr_background = value;
1588     }
1589     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
1590       attr_style = value;
1591     }
1592   }
1593
1594   if (IS_CSS_ON(android->entryp)) {
1595     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
1596     if (style) {
1597       css_property_t *color_prop      = chxj_css_get_property_value(doc, style, "color");
1598       css_property_t *bgcolor_prop    = chxj_css_get_property_value(doc, style, "background-color");
1599       css_property_t *bgimage_prop    = chxj_css_get_property_value(doc, style, "background-image");
1600       css_property_t *cur;
1601       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
1602         if (cur->value && *cur->value) {
1603           attr_text = apr_pstrdup(doc->pool, cur->value);
1604         }
1605       }
1606       for (cur = bgcolor_prop->next; cur != bgcolor_prop; cur = cur->next) {
1607         if (cur->value && *cur->value) {
1608           attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
1609         }
1610       }
1611       for (cur = bgimage_prop->next; cur != bgimage_prop; cur = cur->next) {
1612         if (cur->value && *cur->value) {
1613           char *tmp = apr_pstrdup(doc->pool, cur->value);
1614           char *tmps = strstr(tmp,"(");
1615           if(tmps){
1616             char *tmpe = strstr(tmp,")");
1617             size_t len = strlen(tmps) - strlen(tmpe) -1 ;
1618             tmps++;
1619             attr_background = apr_pstrndup(doc->pool, tmps,len);
1620           }
1621         }
1622       }
1623     }
1624     if (android->style) {
1625       css_stylesheet_t *pseudos = chxj_find_pseudo_selectors(doc, android->style);
1626       css_selector_t *cur_sel;
1627       for (cur_sel = pseudos->selector_head.next; cur_sel != &pseudos->selector_head; cur_sel = cur_sel->next) {
1628         if (cur_sel->name && strcasecmp(cur_sel->name, "a:link") == 0) {
1629           css_property_t *cur;
1630           for (cur = cur_sel->property_head.next; cur != &cur_sel->property_head; cur = cur->next) {
1631             if (cur->name && strcasecmp(cur->name, "color") == 0) {
1632               attr_link = apr_pstrdup(doc->pool, cur->value);
1633             }
1634           }
1635         }
1636         else if (cur_sel->name && strcasecmp(cur_sel->name, "a:visited") == 0) {
1637           css_property_t *cur;
1638           for (cur = cur_sel->property_head.next; cur != &cur_sel->property_head; cur = cur->next) {
1639             if (cur->name && strcasecmp(cur->name, "color") == 0) {
1640               attr_vlink = apr_pstrdup(doc->pool, cur->value);
1641             }
1642           }
1643         }
1644       }
1645     }
1646   }
1647
1648
1649   W_L("<body");
1650   if (attr_bgcolor || attr_text) {
1651     W_L(" style=\"");
1652     if (attr_bgcolor) {
1653       attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
1654       W_L("background-color:");
1655       W_V(attr_bgcolor);
1656       W_L(";");
1657     }
1658     if (attr_text) {
1659       attr_text = chxj_css_rgb_func_to_value(doc->pool, attr_text);
1660       W_L("color:");
1661       W_V(attr_text);
1662       W_L(";");
1663     }
1664     W_L("\"");
1665   }
1666   if (attr_link) {
1667     attr_link = chxj_css_rgb_func_to_value(doc->pool, attr_link);
1668     W_L(" link=\"");
1669     W_V(attr_link);
1670     W_L("\"");
1671   }
1672   if (attr_vlink) {
1673     attr_vlink = chxj_css_rgb_func_to_value(doc->pool, attr_vlink);
1674     W_L(" vlink=\"");
1675     W_V(attr_vlink);
1676     W_L("\"");
1677   }
1678   if (attr_alink) {
1679     attr_alink = chxj_css_rgb_func_to_value(doc->pool, attr_alink);
1680     style_data = apr_pstrcat(doc->pool, (style_data) ? style_data : "",
1681                                         apr_psprintf(doc->pool, "a:focus { color:%s; }", attr_alink), NULL);
1682   }
1683   if (attr_background) {
1684     W_L(" background=\"");
1685     W_V(attr_background);
1686     W_L("\"");
1687   }
1688   if (style_data) {
1689     android->style_data = apr_pstrcat(doc->pool, (android->style_data) ? android->style_data : "",
1690                                                 style_data,
1691                                                 NULL);
1692   }
1693   W_L("><div>");
1694   return android->out;
1695 }
1696
1697
1698 /**
1699  * It is a handler who processes the BODY tag.
1700  *
1701  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1702  *                     destination is specified.
1703  * @param node   [i]   The BODY tag node is specified.
1704  * @return The conversion result is returned.
1705  */
1706 static char *
1707 s_android_end_body_tag(void *pdoc, Node *UNUSED(child)) 
1708 {
1709   android_t       *android;
1710   Doc           *doc;
1711   request_rec   *r;
1712
1713   android = GET_ANDROID(pdoc);
1714   doc   = android->doc;
1715   r     = doc->r;
1716
1717   if (android->conf->use_google_analytics) {
1718     char *src = chxj_google_analytics_get_image_url(r);
1719     W_L("<img src=\"");
1720     W_V(src);
1721     W_L("\" />");
1722   }
1723   W_L("</div></body>");
1724   if (IS_CSS_ON(android->entryp)) {
1725     chxj_css_pop_prop_list(android->css_prop_stack);
1726   }
1727   return android->out;
1728 }
1729
1730
1731 /**
1732  * It is a handler who processes the A tag.
1733  *
1734  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1735  *                     destination is specified.
1736  * @param node   [i]   The A tag node is specified.
1737  * @return The conversion result is returned.
1738  */
1739 static char *
1740 s_android_start_a_tag(void *pdoc, Node *node) 
1741 {
1742   android_t    *android;
1743   Doc         *doc;
1744   request_rec *r;
1745   Attr        *attr;
1746   char        *attr_style = NULL;
1747   char        *attr_id    = NULL;
1748   char        *attr_name  = NULL;
1749
1750   android = GET_ANDROID(pdoc);
1751   doc   = android->doc;
1752   r     = doc->r;
1753
1754   W_L("<a");
1755   /*--------------------------------------------------------------------------*/
1756   /* Get Attributes                                                           */
1757   /*--------------------------------------------------------------------------*/
1758   for (attr = qs_get_attr(doc,node);
1759        attr; 
1760        attr = qs_get_next_attr(doc,attr)) {
1761     char *name  = qs_get_attr_name(doc,attr);
1762     char *value = qs_get_attr_value(doc,attr);
1763     if (STRCASEEQ('i','I',"id",name)){
1764       attr_id = chxj_jreserved_to_safe_tag(r, value, android->entryp);
1765     }
1766     else if (STRCASEEQ('n','N',"name",name)) {
1767       attr_name = chxj_jreserved_to_safe_tag(r, value, android->entryp);
1768     }
1769     else if (STRCASEEQ('h','H',"href",name)) {
1770       /*----------------------------------------------------------------------*/
1771       /* CHTML1.0                                                             */
1772       /*----------------------------------------------------------------------*/
1773       value = chxj_encoding_parameter(r, value, 1);
1774       if (! chxj_starts_with(value, "mailto:") && ! chxj_starts_with(value, "tel:")) {
1775         value = chxj_jreserved_tag_to_safe_for_query_string(r, value, android->entryp, 1);
1776       }
1777       W_L(" href=\"");
1778       W_V(value);
1779       W_L("\"");
1780     }
1781     else if (STRCASEEQ('a','A',"accesskey",name)) {
1782       /*----------------------------------------------------------------------*/
1783       /* CHTML1.0                                                             */
1784       /*----------------------------------------------------------------------*/
1785       /* not need */
1786     }
1787     else if (STRCASEEQ('c','C',"cti",name)) {
1788       /*----------------------------------------------------------------------*/
1789       /* CHTML 2.0                                                            */
1790       /*----------------------------------------------------------------------*/
1791       /* ignore */
1792     }
1793     else if (STRCASEEQ('i','I',"ijam",name)) {
1794       /*----------------------------------------------------------------------*/
1795       /* CHTML 3.0                                                            */
1796       /*----------------------------------------------------------------------*/
1797       /* ignore */
1798     }
1799     else if (STRCASEEQ('u','U',"utn",name)) {
1800       /*----------------------------------------------------------------------*/
1801       /* CHTML 3.0                                                            */
1802       /* It is special only for CHTML.                                        */
1803       /*----------------------------------------------------------------------*/
1804       /* ignore */
1805     }
1806     else if (STRCASEEQ('t','T',"telbook",name)) {
1807       /*----------------------------------------------------------------------*/
1808       /* CHTML 3.0                                                            */
1809       /*----------------------------------------------------------------------*/
1810       /* not support */
1811     }
1812     else if (STRCASEEQ('k','K',"kana",name)) {
1813       /*----------------------------------------------------------------------*/
1814       /* CHTML 3.0                                                            */
1815       /*----------------------------------------------------------------------*/
1816       /* not support */
1817     }
1818     else if (STRCASEEQ('e','E',"email",name)) {
1819       /*----------------------------------------------------------------------*/
1820       /* CHTML 3.0                                                            */
1821       /*----------------------------------------------------------------------*/
1822       /* not support */
1823     }
1824     else if (STRCASEEQ('i','I',"ista",name)) {
1825       /*----------------------------------------------------------------------*/
1826       /* CHTML 4.0                                                            */
1827       /*----------------------------------------------------------------------*/
1828       /* ignore */
1829     }
1830     else if (STRCASEEQ('i','I',"ilet",name)) {
1831       /*----------------------------------------------------------------------*/
1832       /* CHTML 5.0                                                            */
1833       /*----------------------------------------------------------------------*/
1834       /* ignore */
1835     }
1836     else if (STRCASEEQ('i','I',"iswf",name)) {
1837       /*----------------------------------------------------------------------*/
1838       /* CHTML 5.0                                                            */
1839       /*----------------------------------------------------------------------*/
1840       /* ignore */
1841     }
1842     else if (STRCASEEQ('i','I',"irst",name)) {
1843       /*----------------------------------------------------------------------*/
1844       /* CHTML 5.0                                                            */
1845       /*----------------------------------------------------------------------*/
1846       /* ignore */
1847     }
1848     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
1849       /*----------------------------------------------------------------------*/
1850       /* CHTML 5.0                                                            */
1851       /*----------------------------------------------------------------------*/
1852       attr_style = value;
1853     }
1854   }
1855   if(attr_id){
1856     W_L(" id=\"");
1857     W_V(attr_id);
1858     W_L("\"");
1859   }
1860   if (attr_name) {
1861     W_L(" name=\"");
1862     W_V(attr_name);
1863     W_L("\"");
1864   }
1865   W_L(">");
1866
1867   if (IS_CSS_ON(android->entryp)) {
1868     s_android_nopush_and_get_now_style(pdoc, node, attr_style);
1869   }
1870
1871   return android->out;
1872 }
1873
1874
1875 /**
1876  * It is a handler who processes the A tag.
1877  *
1878  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1879  *                     destination is specified.
1880  * @param node   [i]   The A tag node is specified.
1881  * @return The conversion result is returned.
1882  */
1883 static char *
1884 s_android_end_a_tag(void *pdoc, Node *UNUSED(child)) 
1885 {
1886   android_t      *android;
1887   Doc          *doc;
1888   request_rec  *r;
1889
1890   android = GET_ANDROID(pdoc);
1891   doc   = android->doc;
1892   r     = doc->r;
1893
1894   W_L("</a>");
1895
1896   if (IS_CSS_ON(android->entryp)) {
1897     chxj_css_pop_prop_list(android->css_prop_stack);
1898   }
1899
1900   return android->out;
1901 }
1902
1903
1904 /**
1905  * It is a handler who processes the BR tag.
1906  *
1907  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1908  *                     destination is specified.
1909  * @param node   [i]   The BR tag node is specified.
1910  * @return The conversion result is returned.
1911  */
1912 static char *
1913 s_android_start_br_tag(void *pdoc, Node *node)
1914 {
1915   android_t     *android;
1916   Doc          *doc;
1917   request_rec  *r;
1918   Attr         *attr;
1919
1920   android = GET_ANDROID(pdoc);
1921   doc   = android->doc;
1922   r     = doc->r;
1923   
1924   char         *attr_style = NULL;
1925   char         *attr_clear = NULL;
1926
1927   /*--------------------------------------------------------------------------*/
1928   /* Get Attributes                                                           */
1929   /*--------------------------------------------------------------------------*/
1930   for (attr = qs_get_attr(doc,node);
1931        attr;
1932        attr = qs_get_next_attr(doc,attr)) {
1933     char *name  = qs_get_attr_name(doc,attr);
1934     char *value = qs_get_attr_value(doc,attr);
1935     if (STRCASEEQ('c','C',"clear",name)) {
1936       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('a','A',"all",value))) {
1937         attr_clear = value;
1938       }
1939     }
1940     else if (STRCASEEQ('s','S',"style",name)) {
1941       attr_style = apr_pstrdup(doc->buf.pool, value);
1942     }
1943   }
1944   if (IS_CSS_ON(android->entryp)) {
1945     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
1946     if (style) {
1947       css_property_t *clear_prop = chxj_css_get_property_value(doc, style, "clear");
1948       css_property_t *cur;
1949       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
1950         if (cur->value && *cur->value) {
1951           if ( STRCASEEQ('l','L',"left",  cur->value)
1952             || STRCASEEQ('r','R',"right", cur->value)) {
1953             attr_clear = apr_pstrdup(doc->pool, cur->value);
1954           }
1955           else if(STRCASEEQ('b','B',"both"  ,cur->value)) {
1956             attr_clear = apr_pstrdup(doc->pool, "all");
1957           }
1958         }
1959       }
1960     }
1961   }
1962   W_L("<br");
1963   if(attr_clear){
1964     W_L(" clear=\"");
1965     W_V(attr_clear);
1966     W_L("\"");
1967   }
1968   W_L(" />");
1969   return android->out;
1970 }
1971
1972
1973 /**
1974  * It is a handler who processes the BR tag.
1975  *
1976  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1977  *                     destination is specified.
1978  * @param node   [i]   The BR tag node is specified.
1979  * @return The conversion result is returned.
1980  */
1981 static char *
1982 s_android_end_br_tag(void *pdoc, Node *UNUSED(child)) 
1983 {
1984   android_t *android = GET_ANDROID(pdoc);
1985   return android->out;
1986 }
1987
1988 /**
1989  * It is a handler who processes the TABLE tag.
1990  *
1991  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1992  *                     destination is specified.
1993  * @param node   [i]   The TR tag node is specified.
1994  * @return The conversion result is returned.
1995  */
1996 static char *
1997 s_android_start_table_tag(void *pdoc, Node *node) 
1998 {
1999   android_t     *android;
2000   Doc          *doc;
2001   request_rec  *r;
2002   Attr         *attr;
2003   
2004   char         *attr_style  = NULL;
2005   char         *attr_align  = NULL;
2006   char         *attr_width  = NULL;
2007   char         *attr_height = NULL;
2008   char         *attr_bgcolor = NULL;
2009   char         *attr_border_width  = NULL;
2010   char         *attr_border_color  = NULL;
2011
2012   android = GET_ANDROID(pdoc);
2013   doc   = android->doc;
2014   r     = doc->r;
2015   
2016   /*--------------------------------------------------------------------------*/
2017   /* Get Attributes                                                           */
2018   /*--------------------------------------------------------------------------*/
2019   for (attr = qs_get_attr(doc,node);
2020        attr;
2021        attr = qs_get_next_attr(doc,attr)) {
2022     char *name  = qs_get_attr_name(doc,attr);
2023     char *val   = qs_get_attr_value(doc,attr);
2024     if (STRCASEEQ('a','A',"align",name)) {
2025       if (val && (STRCASEEQ('l','L',"left",val) || STRCASEEQ('r','R',"right",val) || STRCASEEQ('c','C',"center",val))) {
2026         attr_align = apr_pstrdup(doc->buf.pool, val);
2027       }
2028     }
2029     else if (STRCASEEQ('h','H',"height",name) && val && *val) {
2030       attr_height = apr_pstrdup(doc->buf.pool, val);
2031     }
2032     else if (STRCASEEQ('w','W',"width",name) && val && *val) {
2033       attr_width = apr_pstrdup(doc->buf.pool, val);
2034     }
2035     else if (STRCASEEQ('s','S',"style",name) && val && *val) {
2036       attr_style = apr_pstrdup(doc->buf.pool, val);
2037     }
2038     else if (STRCASEEQ('b','B',"bgcolor",name) && val && *val) {
2039       attr_bgcolor = apr_pstrdup(doc->buf.pool, val);
2040       attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
2041     }
2042     else if (STRCASEEQ('b','B',"border",name) && val && *val) {
2043       attr_border_width = apr_pstrdup(doc->buf.pool, val);
2044     }
2045     else if (STRCASEEQ('b','B',"bordercolor",name) && val && *val) {
2046       attr_border_color = apr_pstrdup(doc->buf.pool, val);
2047       attr_border_color = chxj_css_rgb_func_to_value(doc->pool, attr_border_color);
2048     }
2049   }
2050   
2051   if (IS_CSS_ON(android->entryp)) {
2052     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
2053     if (style) {
2054       css_property_t *width_prop             = chxj_css_get_property_value(doc, style, "width");
2055       css_property_t *height_prop            = chxj_css_get_property_value(doc, style, "height");
2056       css_property_t *align_prop             = chxj_css_get_property_value(doc, style, "text-align");
2057       css_property_t *bgcolor_prop           = chxj_css_get_property_value(doc, style, "background-color");
2058       css_property_t *border_width_prop      = chxj_css_get_property_value(doc, style, "border-width");
2059       css_property_t *border_color_prop      = chxj_css_get_property_value(doc, style, "border-color");
2060       
2061       css_property_t *cur;
2062       for (cur = width_prop->next; cur != width_prop; cur = cur->next) {
2063         char *tmp = apr_pstrdup(doc->pool, cur->value);
2064         char *tmpp = strstr(tmp, "px");
2065         if (tmpp) {
2066           size_t len = strlen(tmp) - strlen(tmpp);
2067           attr_width = apr_pstrndup(doc->pool, tmp,len);
2068         }
2069         else{
2070           attr_width = apr_pstrdup(doc->pool, tmp);
2071         }
2072       }
2073       for (cur = height_prop->next; cur != height_prop; cur = cur->next) {
2074         char *tmp = apr_pstrdup(doc->pool, cur->value);
2075         char *tmpp = strstr(tmp, "px");
2076         if (tmpp) {
2077           size_t len = strlen(tmp) - strlen(tmpp);
2078           attr_height = apr_pstrndup(doc->pool, tmp,len);
2079         }
2080         else{
2081           attr_height = apr_pstrdup(doc->pool, tmp);
2082         }
2083       }
2084       for (cur = align_prop->next; cur != align_prop; cur = cur->next) {
2085         if (cur->value && (STRCASEEQ('l','L',"left",cur->value) || STRCASEEQ('r','R',"right",cur->value) || STRCASEEQ('c','C',"center",cur->value))) {
2086           attr_align = apr_pstrdup(doc->buf.pool, cur->value);
2087         }
2088       }
2089       for (cur = bgcolor_prop->next; cur != bgcolor_prop; cur = cur->next) {
2090         attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
2091         attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
2092       }
2093       for (cur = border_width_prop->next; cur != border_width_prop; cur = cur->next) {
2094         char *tmp = apr_pstrdup(doc->pool, cur->value);
2095         char *tmpp = strstr(tmp, "px");
2096         if (tmpp) {
2097           size_t len = strlen(tmp) - strlen(tmpp);
2098           attr_border_width = apr_pstrndup(doc->pool, tmp,len);
2099         }
2100         else{
2101           attr_border_width = apr_pstrdup(doc->pool, tmp);
2102         }
2103       }
2104       for (cur = border_color_prop->next; cur != border_color_prop; cur = cur->next) {
2105         attr_border_color = apr_pstrdup(doc->pool, cur->value);
2106         attr_border_color = chxj_css_rgb_func_to_value(doc->pool, attr_border_color);
2107       }
2108     }
2109   }
2110
2111   W_L("<table");
2112   if (attr_align){
2113     W_L(" align=\"");
2114     W_V(attr_align);
2115     W_L("\"");
2116   }
2117   if (attr_height){
2118     W_L(" height=\"");
2119     W_V(attr_height);
2120     W_L("\"");
2121   }
2122   if (attr_width){
2123     W_L(" width=\"");
2124     W_V(attr_width);
2125     W_L("\"");
2126   }
2127   if (attr_bgcolor && *attr_bgcolor){
2128     W_L(" bgcolor=\"");
2129     W_V(attr_bgcolor);
2130     W_L("\"");
2131   }
2132   if (attr_border_width || attr_border_color ){
2133     W_L(" style=\"border:");
2134     if (attr_border_width){
2135       W_V(attr_border_width);
2136     }
2137     else{
2138       W_L("1");
2139     }
2140     W_L("px solid");
2141     
2142     if (attr_border_color && *attr_border_color){
2143       W_L(" ");
2144       W_V(attr_border_color);
2145     }
2146     W_L(";\"");
2147   }
2148   W_L(">");
2149   
2150   return android->out;
2151 }
2152
2153 /**
2154  * It is a handler who processes the TABLE tag.
2155  *
2156  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2157  *                     destination is specified.
2158  * @param node   [i]   The TR tag node is specified.
2159  * @return The conversion result is returned.
2160  */
2161 static char *
2162 s_android_end_table_tag(void *pdoc, Node *UNUSED(node)) 
2163 {
2164   android_t      *android;
2165   request_rec  *r;
2166   Doc          *doc;
2167
2168   android = GET_ANDROID(pdoc);
2169   doc   = android->doc;
2170   r     = android->doc->r;
2171   
2172   W_L("</table>");
2173   return android->out;
2174 }
2175
2176
2177 /**
2178  * It is a handler who processes the TR tag.
2179  *
2180  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2181  *                     destination is specified.
2182  * @param node   [i]   The TR tag node is specified.
2183  * @return The conversion result is returned.
2184  */
2185 static char *
2186 s_android_start_tr_tag(void *pdoc, Node *node) 
2187 {
2188   android_t      *android;
2189   Doc          *doc;
2190   request_rec  *r;
2191   
2192   Attr         *attr;
2193   
2194   char         *attr_style  = NULL;
2195   char         *attr_align  = NULL;
2196   char         *attr_valign = NULL;
2197   char         *attr_bgcolor = NULL;
2198
2199   android = GET_ANDROID(pdoc);
2200   doc   = android->doc;
2201   r     = doc->r;
2202   
2203   /*--------------------------------------------------------------------------*/
2204   /* Get Attributes                                                           */
2205   /*--------------------------------------------------------------------------*/
2206   for (attr = qs_get_attr(doc,node);
2207        attr;
2208        attr = qs_get_next_attr(doc,attr)) {
2209     char *name  = qs_get_attr_name(doc,attr);
2210     char *val   = qs_get_attr_value(doc,attr);
2211     if (STRCASEEQ('a','A',"align",name)) {
2212       if (val && (STRCASEEQ('l','L',"left",val) || STRCASEEQ('r','R',"right",val) || STRCASEEQ('c','C',"center",val))) {
2213         attr_align = apr_pstrdup(doc->buf.pool, val);
2214       }
2215     }
2216     else if (STRCASEEQ('v','V',"valign",name) && val && *val) {
2217       if (val && (STRCASEEQ('t','T',"top",val) || STRCASEEQ('m','M',"middle",val) || STRCASEEQ('b','B',"bottom",val))) {
2218         attr_valign = apr_pstrdup(doc->buf.pool, val);
2219       }
2220     }
2221     else if (STRCASEEQ('s','S',"style",name) && val && *val) {
2222       attr_style = apr_pstrdup(doc->buf.pool, val);
2223     }
2224     else if (STRCASEEQ('b','B',"bgcolor",name) && val && *val) {
2225       attr_bgcolor = apr_pstrdup(doc->buf.pool, val);
2226       attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
2227     }
2228   }
2229   
2230   if (IS_CSS_ON(android->entryp)) {
2231     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
2232     if (style) {
2233       css_property_t *align_prop             = chxj_css_get_property_value(doc, style, "text-align");
2234       css_property_t *valign_prop            = chxj_css_get_property_value(doc, style, "vertical-align");
2235       css_property_t *bgcolor_prop           = chxj_css_get_property_value(doc, style, "background-color");
2236       
2237       css_property_t *cur;
2238       for (cur = align_prop->next; cur != align_prop; cur = cur->next) {
2239         if (cur->value && (STRCASEEQ('l','L',"left",cur->value) || STRCASEEQ('r','R',"right",cur->value) || STRCASEEQ('c','C',"center",cur->value))) {
2240           attr_align = apr_pstrdup(doc->buf.pool, cur->value);
2241         }
2242       }
2243       for (cur = valign_prop->next; cur != valign_prop; cur = cur->next) {
2244         if (cur->value && (STRCASEEQ('t','T',"top",cur->value) || STRCASEEQ('m','M',"middle",cur->value) || STRCASEEQ('b','B',"bottom",cur->value))) {
2245           attr_valign = apr_pstrdup(doc->buf.pool, cur->value);
2246         }
2247       }
2248       for (cur = bgcolor_prop->next; cur != bgcolor_prop; cur = cur->next) {
2249         attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
2250         attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
2251       }
2252     }
2253   }
2254
2255   W_L("<tr");
2256   if (attr_align){
2257     W_L(" align=\"");
2258     W_V(attr_align);
2259     W_L("\"");
2260   }
2261   if (attr_valign){
2262     W_L(" valign=\"");
2263     W_V(attr_valign);
2264     W_L("\"");
2265   }
2266   if (attr_bgcolor && *attr_bgcolor){
2267     W_L(" bgcolor=\"");
2268     W_V(attr_bgcolor);
2269     W_L("\"");
2270   }
2271   W_L(">");
2272   return android->out;
2273 }
2274
2275
2276 /**
2277  * It is a handler who processes the TR tag.
2278  *
2279  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2280  *                     destination is specified.
2281  * @param node   [i]   The TR tag node is specified.
2282  * @return The conversion result is returned.
2283  */
2284 static char *
2285 s_android_end_tr_tag(void *pdoc, Node *UNUSED(child)) 
2286 {
2287   android_t      *android;
2288   request_rec  *r;
2289   Doc          *doc;
2290
2291   android = GET_ANDROID(pdoc);
2292   doc   = android->doc;
2293   r     = android->doc->r;
2294   
2295   W_L("</tr>");
2296   return android->out;
2297 }
2298
2299 /**
2300  * It is a handler who processes the TD tag.
2301  *
2302  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2303  *                     destination is specified.
2304  * @param node   [i]   The TR tag node is specified.
2305  * @return The conversion result is returned.
2306  */
2307 static char *
2308 s_android_start_td_or_th_tag(void *pdoc, Node *node,char *tagName) 
2309 {
2310   android_t      *android;
2311   Doc          *doc;
2312   request_rec  *r;
2313
2314   Attr         *attr;
2315   
2316   char         *attr_style  = NULL;
2317   char         *attr_align  = NULL;
2318   char         *attr_valign = NULL;
2319   char         *attr_bgcolor = NULL;
2320   char         *attr_colspan = NULL;
2321   char         *attr_rowspan = NULL;
2322   char         *attr_width   = NULL;
2323   char         *attr_height  = NULL;
2324
2325   android = GET_ANDROID(pdoc);
2326   doc   = android->doc;
2327   r     = doc->r;
2328   
2329   /*--------------------------------------------------------------------------*/
2330   /* Get Attributes                                                           */
2331   /*--------------------------------------------------------------------------*/
2332   for (attr = qs_get_attr(doc,node);
2333        attr;
2334        attr = qs_get_next_attr(doc,attr)) {
2335     char *name  = qs_get_attr_name(doc,attr);
2336     char *val   = qs_get_attr_value(doc,attr);
2337     if (STRCASEEQ('a','A',"align",name)) {
2338       if (val && (STRCASEEQ('l','L',"left",val) || STRCASEEQ('r','R',"right",val) || STRCASEEQ('c','C',"center",val))) {
2339         attr_align = apr_pstrdup(doc->buf.pool, val);
2340       }
2341     }
2342     else if (STRCASEEQ('v','V',"valign",name) && val && *val) {
2343       if (val && (STRCASEEQ('t','T',"top",val) || STRCASEEQ('m','M',"middle",val) || STRCASEEQ('b','B',"bottom",val))) {
2344         attr_valign = apr_pstrdup(doc->buf.pool, val);
2345       }
2346     }
2347     else if (STRCASEEQ('s','S',"style",name) && val && *val) {
2348       attr_style = apr_pstrdup(doc->buf.pool, val);
2349     }
2350     else if (STRCASEEQ('b','B',"bgcolor",name) && val && *val) {
2351       attr_bgcolor = apr_pstrdup(doc->buf.pool, val);
2352       attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
2353     }
2354     else if (STRCASEEQ('c','C',"colspan",name) && val && *val) {
2355       attr_colspan = apr_pstrdup(doc->buf.pool, val);
2356     }
2357     else if (STRCASEEQ('r','R',"rowspan",name) && val && *val) {
2358       attr_rowspan = apr_pstrdup(doc->buf.pool, val);
2359     }
2360     else if (STRCASEEQ('w','W',"width",name) && val && *val) {
2361       char *tmp = strstr(val, "%");
2362       if(tmp){
2363         attr_width = apr_pstrdup(doc->buf.pool, val);
2364       }
2365       else{
2366         attr_width = apr_psprintf(doc->buf.pool,"%spx",val);
2367       }
2368     }
2369     else if (STRCASEEQ('h','H',"height",name) && val && *val) {
2370       char *tmp = strstr(val, "%");
2371       if(tmp){
2372         attr_height = apr_pstrdup(doc->buf.pool, val);
2373       }
2374       else{
2375         attr_height = apr_psprintf(doc->buf.pool,"%spx",val);
2376       }
2377     }
2378   }
2379   
2380   if (IS_CSS_ON(android->entryp)) {
2381     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
2382     if (style) {
2383       css_property_t *align_prop             = chxj_css_get_property_value(doc, style, "text-align");
2384       css_property_t *valign_prop            = chxj_css_get_property_value(doc, style, "vertical-align");
2385       css_property_t *bgcolor_prop           = chxj_css_get_property_value(doc, style, "background-color");
2386       css_property_t *width_prop             = chxj_css_get_property_value(doc, style, "width");
2387       css_property_t *height_prop            = chxj_css_get_property_value(doc, style, "height");
2388       
2389       css_property_t *cur;
2390       for (cur = align_prop->next; cur != align_prop; cur = cur->next) {
2391         if (cur->value && (STRCASEEQ('l','L',"left",cur->value) || STRCASEEQ('r','R',"right",cur->value) || STRCASEEQ('c','C',"center",cur->value))) {
2392           attr_align = apr_pstrdup(doc->buf.pool, cur->value);
2393         }
2394       }
2395       for (cur = valign_prop->next; cur != valign_prop; cur = cur->next) {
2396         if (cur->value && (STRCASEEQ('t','T',"top",cur->value) || STRCASEEQ('m','M',"middle",cur->value) || STRCASEEQ('b','B',"bottom",cur->value))) {
2397           attr_valign = apr_pstrdup(doc->buf.pool, cur->value);
2398         }
2399       }
2400       for (cur = bgcolor_prop->next; cur != bgcolor_prop; cur = cur->next) {
2401         attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
2402         attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
2403       }
2404       for (cur = width_prop->next; cur != width_prop; cur = cur->next) {
2405         attr_width = apr_pstrdup(doc->pool, cur->value);
2406       }
2407       for (cur = height_prop->next; cur != height_prop; cur = cur->next) {
2408         attr_height = apr_pstrdup(doc->pool, cur->value);
2409       }
2410     }
2411   }
2412
2413   W_L("<");
2414   W_V(tagName);
2415   if (attr_align){
2416     W_L(" align=\"");
2417     W_V(attr_align);
2418     W_L("\"");
2419   }
2420   if (attr_valign){
2421     W_L(" valign=\"");
2422     W_V(attr_valign);
2423     W_L("\"");
2424   }
2425   if (attr_colspan){
2426     W_L(" colspan=\"");
2427     W_V(attr_colspan);
2428     W_L("\"");
2429   }
2430   if (attr_rowspan){
2431     W_L(" rowspan=\"");
2432     W_V(attr_rowspan);
2433     W_L("\"");
2434   }
2435   if (attr_bgcolor && *attr_bgcolor){
2436     W_L(" bgcolor=\"");
2437     W_V(attr_bgcolor);
2438     W_L("\"");
2439   }
2440   if (attr_width || attr_height ){
2441     W_L(" style=\"");
2442     if (attr_width){
2443       W_L("width:");
2444       W_V(attr_width);
2445       W_L(";");
2446     }
2447     if (attr_height){
2448       W_L("height:");
2449       W_V(attr_height);
2450       W_L(";");
2451     }
2452     W_L("\"");
2453   }
2454   W_L(">");
2455   return android->out;
2456 }
2457
2458
2459 /**
2460  * It is a handler who processes the TD tag.
2461  *
2462  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2463  *                     destination is specified.
2464  * @param node   [i]   The TR tag node is specified.
2465  * @return The conversion result is returned.
2466  */
2467 static char *
2468 s_android_end_td_or_th_tag(void *pdoc, Node *UNUSED(child),char *tagName) 
2469 {
2470   android_t      *android;
2471   request_rec  *r;
2472   Doc          *doc;
2473
2474   android = GET_ANDROID(pdoc);
2475   doc   = android->doc;
2476   r     = android->doc->r;
2477   
2478   W_L("</");
2479   W_V(tagName);
2480   W_L(">");
2481   return android->out;
2482 }
2483
2484 /**
2485  * It is a handler who processes the TD tag.
2486  *
2487  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2488  *                     destination is specified.
2489  * @param node   [i]   The TD tag node is specified.
2490  * @return The conversion result is returned.
2491  */
2492 static char *
2493 s_android_start_td_tag(void *pdoc, Node *node) 
2494 {
2495   return s_android_start_td_or_th_tag(pdoc,node,"td");
2496 }
2497 /**
2498  * It is a handler who processes the TD tag.
2499  *
2500  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2501  *                     destination is specified.
2502  * @param node   [i]   The TD tag node is specified.
2503  * @return The conversion result is returned.
2504  */
2505 static char *
2506 s_android_end_td_tag(void *pdoc, Node *node) 
2507 {
2508   return s_android_end_td_or_th_tag(pdoc,node,"td");
2509 }
2510
2511 /**
2512  * It is a handler who processes the TD tag.
2513  *
2514  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2515  *                     destination is specified.
2516  * @param node   [i]   The TD tag node is specified.
2517  * @return The conversion result is returned.
2518  */
2519 static char *
2520 s_android_start_th_tag(void *pdoc, Node *node) 
2521 {
2522   return s_android_start_td_or_th_tag(pdoc,node,"th");
2523 }
2524 /**
2525  * It is a handler who processes the TD tag.
2526  *
2527  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2528  *                     destination is specified.
2529  * @param node   [i]   The TD tag node is specified.
2530  * @return The conversion result is returned.
2531  */
2532 static char *
2533 s_android_end_th_tag(void *pdoc, Node *node) 
2534 {
2535   return s_android_end_td_or_th_tag(pdoc,node,"th");
2536 }
2537
2538 /**
2539  * It is a handler who processes the FONT tag.
2540  *
2541  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2542  *                     destination is specified.
2543  * @param node   [i]   The FONT tag node is specified.
2544  * @return The conversion result is returned.
2545  */
2546 static char *
2547 s_android_start_font_tag(void *pdoc, Node *node) 
2548 {
2549   android_t      *android;
2550   Doc           *doc;
2551   request_rec   *r;
2552   Attr          *attr;
2553   char          *attr_color = NULL;
2554   char          *attr_size  = NULL;
2555   char          *attr_style = NULL;
2556
2557   android = GET_ANDROID(pdoc);
2558   doc   = android->doc;
2559   r     = doc->r;
2560
2561   /*--------------------------------------------------------------------------*/
2562   /* Get Attributes                                                           */
2563   /*--------------------------------------------------------------------------*/
2564   for (attr = qs_get_attr(doc,node);
2565        attr; 
2566        attr = qs_get_next_attr(doc,attr)) {
2567     char *name  = qs_get_attr_name(doc,attr);
2568     char *value = qs_get_attr_value(doc,attr);
2569     if (STRCASEEQ('c','C',"color",name) && value && *value) {
2570       attr_color = apr_pstrdup(doc->buf.pool, value);
2571     }
2572     else if (STRCASEEQ('s','S',"size",name) && value && *value) {
2573       /*----------------------------------------------------------------------*/
2574       /* CHTML 5.0                                                            */
2575       /*----------------------------------------------------------------------*/
2576       attr_size = apr_pstrdup(doc->buf.pool, value);
2577     }
2578     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
2579       attr_style = apr_pstrdup(doc->buf.pool, value);
2580     }
2581   }
2582   if (IS_CSS_ON(android->entryp)) {
2583     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
2584     if (style) {
2585       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
2586       css_property_t *size_prop  = chxj_css_get_property_value(doc, style, "font-size");
2587       css_property_t *cur;
2588       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
2589         if (cur->value && *cur->value) {
2590           attr_color = apr_pstrdup(doc->pool, cur->value);
2591         }
2592       }
2593       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
2594         if (cur->value && *cur->value) {
2595           attr_size = apr_pstrdup(doc->pool, cur->value);
2596           if (STRCASEEQ('x','X',"xx-small",attr_size)) {
2597             attr_size = apr_pstrdup(doc->pool, "1");
2598           }
2599           else if (STRCASEEQ('x','X',"x-small",attr_size)) {
2600             attr_size = apr_pstrdup(doc->pool, "2");
2601           }
2602           else if (STRCASEEQ('s','S',"small",attr_size)) {
2603             attr_size = apr_pstrdup(doc->pool, "3");
2604           }
2605           else if (STRCASEEQ('m','M',"medium",attr_size)) {
2606             attr_size = apr_pstrdup(doc->pool, "4");
2607           }
2608           else if (STRCASEEQ('l','L',"large",attr_size)) {
2609             attr_size = apr_pstrdup(doc->pool, "5");
2610           }
2611           else if (STRCASEEQ('x','X',"x-large",attr_size)) {
2612             attr_size = apr_pstrdup(doc->pool, "6");
2613           }
2614           else if (STRCASEEQ('x','X',"xx-large",attr_size)) {
2615             attr_size = apr_pstrdup(doc->pool, "7");
2616           }
2617         }
2618       }
2619     }
2620   }
2621   android_flags_t *flg = (android_flags_t *)apr_palloc(doc->pool, sizeof(*flg));
2622   memset(flg, 0, sizeof(*flg));
2623   if (attr_color) {
2624     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
2625     W_L("<font color=\"");
2626     W_V(attr_color);
2627     W_L("\">");
2628     flg->font_color_flag = 1;
2629   }
2630   if (attr_size) {
2631     flg->font_size_flag = 1;
2632     switch(*attr_size) {
2633     case '1': W_L("<span style=\"font-size: xx-small\">"); break;
2634     case '2': W_L("<span style=\"font-size: x-small\">");  break;
2635     case '3': W_L("<span style=\"font-size: small\">");    break;
2636     case '4': W_L("<span style=\"font-size: medium\">");   break;
2637     case '5': W_L("<span style=\"font-size: large\">");    break;
2638     case '6': W_L("<span style=\"font-size: x-large\">");  break;
2639     case '7': W_L("<span style=\"font-size: xx-large\">"); break;
2640     case '-':
2641       if (*(attr_size + 1) == '1') {
2642         W_L("<span style=\"font-size: small\">");
2643         break;
2644       }
2645       if (*(attr_size + 1) == '2') {
2646         W_L("<span style=\"font-size: x-small\">");
2647         break;
2648       }
2649       if (*(attr_size + 1) == '3') {
2650         W_L("<span style=\"font-size: xx-small\">");
2651         break;
2652       }
2653       flg->font_size_flag = 0;
2654       break;
2655
2656     case '+':
2657       if (*(attr_size + 1) == '1') {
2658         W_L("<span style=\"font-size: large\">");
2659         break;
2660       }
2661       if (*(attr_size + 1) == '2') {
2662         W_L("<span style=\"font-size: x-large\">");
2663         break;
2664       }
2665       if (*(attr_size + 1) == '3') {
2666         W_L("<span style=\"font-size: xx-large\">");
2667         break;
2668       }
2669       flg->font_size_flag = 0;
2670       break;
2671
2672     default:
2673       WRN(doc->r, "invlalid font size. [%s] != (1|2|3|4|5|6|7|+1|+2|+3|-1|-2|-3)", attr_size);
2674       flg->font_size_flag = 0;
2675     }
2676   }
2677   node->userData = flg;
2678   return android->out;
2679 }
2680
2681
2682 /**
2683  * It is a handler who processes the FONT tag.
2684  *
2685  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2686  *                     destination is specified.
2687  * @param node   [i]   The FONT tag node is specified.
2688  * @return The conversion result is returned.
2689  */
2690 static char *
2691 s_android_end_font_tag(void *pdoc, Node *node)
2692 {
2693   android_t      *android;
2694   request_rec  *r;
2695   Doc          *doc;
2696
2697   android = GET_ANDROID(pdoc);
2698   doc   = android->doc;
2699   r     = android->doc->r;
2700
2701   android_flags_t *flg = (android_flags_t *)node->userData;
2702   if (flg && flg->font_size_flag) {
2703     W_L("</span>");
2704   }
2705   if (flg && flg->font_color_flag) {
2706     W_L("</font>");
2707   }
2708   if (IS_CSS_ON(android->entryp)) {
2709     chxj_css_pop_prop_list(android->css_prop_stack);
2710   }
2711
2712   return android->out;
2713 }
2714
2715
2716 /**
2717  * It is a handler who processes the FORM tag.
2718  *
2719  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2720  *                     destination is specified.
2721  * @param node   [i]   The FORM tag node is specified.
2722  * @return The conversion result is returned.
2723  */
2724 static char *
2725 s_android_start_form_tag(void *pdoc, Node *node) 
2726 {
2727   android_t    *android;
2728   Doc         *doc;
2729   request_rec *r;
2730   Attr        *attr;
2731   char        *attr_action = NULL;
2732   char        *attr_method = NULL;
2733   char        *attr_style  = NULL;
2734   char        *attr_color  = NULL;
2735   char        *attr_align  = NULL;
2736   char        *attr_name   = NULL;
2737   char        *css_clear   = NULL;
2738   char        *new_hidden_tag = NULL;
2739
2740   android  = GET_ANDROID(pdoc);
2741   doc     = android->doc;
2742   r       = doc->r;
2743
2744   /*--------------------------------------------------------------------------*/
2745   /* Get Attributes                                                           */
2746   /*--------------------------------------------------------------------------*/
2747   for (attr = qs_get_attr(doc,node);
2748        attr;
2749        attr = qs_get_next_attr(doc,attr)) {
2750     char *name  = qs_get_attr_name(doc,attr);
2751     char *value = qs_get_attr_value(doc,attr);
2752     switch(*name) {
2753     case 'a':
2754     case 'A':
2755       if (strcasecmp(name, "action") == 0) {
2756         /*--------------------------------------------------------------------*/
2757         /* CHTML 1.0                                                          */
2758         /*--------------------------------------------------------------------*/
2759         attr_action = value;
2760       }
2761       break;
2762
2763     case 'm':
2764     case 'M':
2765       if (strcasecmp(name, "method") == 0) {
2766         /*--------------------------------------------------------------------*/
2767         /* CHTML 1.0                                                          */
2768         /*--------------------------------------------------------------------*/
2769         attr_method = value;
2770       }
2771       break;
2772
2773     case 'n':
2774     case 'N':
2775       if (strcasecmp(name, "name") == 0) {
2776         /*--------------------------------------------------------------------*/
2777         /* CHTML 1.0                                                          */
2778         /*--------------------------------------------------------------------*/
2779         attr_name = value;
2780       }
2781       break;
2782
2783     case 's':
2784     case 'S':
2785       if (strcasecmp(name, "style") == 0) {
2786         attr_style = value;
2787       }
2788       break;
2789
2790     default:
2791       break;
2792     }
2793   }
2794   if (IS_CSS_ON(android->entryp)) {
2795     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
2796     if (style) {
2797       css_property_t *text_align_prop = chxj_css_get_property_value(doc, style, "text-align");
2798       css_property_t *color_prop      = chxj_css_get_property_value(doc, style, "color");
2799       css_property_t *clear_prop      = chxj_css_get_property_value(doc, style, "clear");
2800       css_property_t *cur;
2801       for (cur = text_align_prop->next; cur != text_align_prop; cur = cur->next) {
2802         if (STRCASEEQ('l','L',"left", cur->value)) {
2803           attr_align = apr_pstrdup(doc->pool, "left");
2804         }
2805         else if (STRCASEEQ('c','C',"center",cur->value)) {
2806           attr_align = apr_pstrdup(doc->pool, "center");
2807         }
2808         else if (STRCASEEQ('r','R',"right",cur->value)) {
2809           attr_align = apr_pstrdup(doc->pool, "right");
2810         }
2811       }
2812       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
2813         attr_color = apr_pstrdup(doc->pool, cur->value);
2814       }
2815       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
2816         css_clear = apr_pstrdup(doc->pool, cur->value);
2817       }
2818     }
2819   }
2820
2821   int post_flag = (attr_method && strcasecmp(attr_method, "post") == 0) ? 1 : 0;
2822
2823   W_L("<form");
2824   if (attr_action) {
2825     attr_action = chxj_encoding_parameter(r, attr_action, 1);
2826     attr_action = chxj_add_cookie_parameter(r, attr_action, android->cookie);
2827     char *q;
2828     char *old_qs = NULL;
2829     q = strchr(attr_action, '?');
2830     if (q) {
2831       new_hidden_tag = chxj_form_action_to_hidden_tag(r, doc->pool, attr_action, 1, post_flag, &old_qs, CHXJ_FALSE, CHXJ_TRUE, android->entryp);
2832       if (new_hidden_tag || old_qs) {
2833         *q = 0;
2834       }
2835     }
2836     W_L(" action=\"");
2837     W_V(attr_action);
2838     if (old_qs) {
2839       W_L("?");
2840       W_V(old_qs);
2841     }
2842     W_L("\"");
2843   }
2844   if (attr_method) {
2845     W_L(" method=\"");
2846     W_V(attr_method);
2847     W_L("\"");
2848   }
2849   if (attr_name) {
2850     W_L(" name=\"");
2851     W_V(attr_name);
2852     W_L("\"");
2853   }
2854   if (css_clear) {
2855     W_L(" style=\"");
2856     W_L("clear:");
2857     W_V(css_clear);
2858     W_L("\"");
2859   }
2860   W_L(">");
2861
2862   android_flags_t *flg = (android_flags_t *)apr_palloc(doc->pool, sizeof(android_flags_t));
2863   memset(flg, 0, sizeof(*flg));
2864   if (attr_color) {
2865     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
2866     W_L("<font color=\"");
2867     W_V(attr_color);
2868     W_L("\">");
2869     flg->with_font_flag = 1;
2870   }
2871   if (attr_align) {
2872     W_L("<div align=\"");
2873     W_V(attr_align);
2874     W_L("\">");
2875     flg->with_div_flag = 1;
2876   }
2877   node->userData = flg;
2878   if (new_hidden_tag) {
2879     W_V(new_hidden_tag);
2880   }
2881   return android->out;
2882 }
2883
2884
2885 /**
2886  * It is a handler who processes the FORM tag.
2887  *
2888  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2889  *                     destination is specified.
2890  * @param node   [i]   The FORM tag node is specified.
2891  * @return The conversion result is returned.
2892  */
2893 static char *
2894 s_android_end_form_tag(void *pdoc, Node *node)
2895 {
2896   android_t *android = GET_ANDROID(pdoc);
2897   Doc      *doc    = android->doc;
2898
2899   android_flags_t *flg = (android_flags_t *)node->userData;
2900   if (flg && flg->with_div_flag) {
2901     W_L("</div>");
2902   }
2903   if (flg && flg->with_font_flag) {
2904     W_L("</font>");
2905   }
2906   W_L("</form>");
2907   if (IS_CSS_ON(android->entryp)) {
2908     chxj_css_pop_prop_list(android->css_prop_stack);
2909   }
2910
2911   return android->out;
2912 }
2913
2914 static char *
2915 s_android_istyle_to_wap_input_format(apr_pool_t *p, const char *s)
2916 {
2917   if (s) {
2918     switch (s[0]) {
2919     case '1': return apr_psprintf(p, "&quot;*&lt;ja:h&gt;&quot;");
2920     case '2': return apr_psprintf(p, "&quot;*&lt;ja:hk&gt;&quot;");
2921     case '3': return apr_psprintf(p, "&quot;*&lt;ja:en&gt;&quot;");
2922     case '4': return apr_psprintf(p, "&quot;*&lt;ja:n&gt;&quot;");
2923     default:
2924       return apr_pstrdup(p, "");
2925     }
2926   }
2927
2928   return apr_pstrdup(p,"");
2929 }
2930
2931
2932 /**
2933  * It is a handler who processes the INPUT tag.
2934  *
2935  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2936  *                     destination is specified.
2937  * @param node   [i]   The INPUT tag node is specified.
2938  * @return The conversion result is returned.
2939  */
2940 static char *
2941 s_android_start_input_tag(void *pdoc, Node *node) 
2942 {
2943   android_t    *android;
2944   Doc         *doc;
2945   request_rec *r;
2946   Attr        *attr;
2947   char        *attr_accesskey  = NULL;
2948   char        *attr_max_length = NULL;
2949   char        *attr_type       = NULL;
2950   char        *attr_name       = NULL;
2951   char        *attr_value      = NULL;
2952   char        *attr_istyle     = NULL;
2953   char        *attr_size       = NULL;
2954   char        *attr_checked    = NULL;
2955   char        *attr_style      = NULL;
2956
2957   android  = GET_ANDROID(pdoc);
2958   doc     = android->doc;
2959   r       = doc->r;
2960
2961   /*--------------------------------------------------------------------------*/
2962   /* Get Attributes                                                           */
2963   /*--------------------------------------------------------------------------*/
2964   for (attr = qs_get_attr(doc,node);
2965        attr;
2966        attr = qs_get_next_attr(doc,attr)) {
2967     char *name  = qs_get_attr_name(doc,attr);
2968     char *value = qs_get_attr_value(doc,attr);
2969     if (STRCASEEQ('t','T',"type",name) && value && *value) {
2970       char *tmp_type = qs_trim_string(doc->buf.pool, value);
2971       if (tmp_type && (STRCASEEQ('t','T',"text",    tmp_type) ||
2972                        STRCASEEQ('p','P',"password",tmp_type) ||
2973                        STRCASEEQ('c','C',"checkbox",tmp_type) ||
2974                        STRCASEEQ('r','R',"radio",   tmp_type) ||
2975                        STRCASEEQ('h','H',"hidden",  tmp_type) ||
2976                        STRCASEEQ('s','S',"submit",  tmp_type) ||
2977                        STRCASEEQ('r','R',"reset",   tmp_type))) {
2978         attr_type = tmp_type;
2979       }
2980     }
2981     else if (STRCASEEQ('n','N',"name",name) && value && *value) {
2982       attr_name = value;
2983     }
2984     else if (STRCASEEQ('v','V',"value",name) && value && *value) {
2985       attr_value = value;
2986     }
2987     else if (STRCASEEQ('i','I',"istyle",name) && value && *value) {
2988       attr_istyle = value;
2989     }
2990     else if (STRCASEEQ('m','M',"maxlength",name) && value && *value) {
2991       attr_max_length = value;
2992     }
2993     else if (STRCASEEQ('c','C',"checked", name)) {
2994       attr_checked = value;
2995     }
2996     else if (STRCASEEQ('a','A',"accesskey", name) && value && *value) {
2997       attr_accesskey = value;
2998     }
2999     else if (STRCASEEQ('s','S',"size", name) && value && *value) {
3000       attr_size = value;
3001     }
3002     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
3003       attr_style = value;
3004     }
3005   }
3006
3007   if (IS_CSS_ON(android->entryp)) {
3008     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
3009     if (style) {
3010       css_property_t *wap_input_format = chxj_css_get_property_value(doc, style, "-wap-input-format");
3011       css_property_t *cur;
3012       for (cur = wap_input_format->next; cur != wap_input_format; cur = cur->next) {
3013         if (strcasestr(cur->value, "<ja:n>")) {
3014           attr_istyle = "4";
3015         }
3016         else if (strcasestr(cur->value, "<ja:en>")) {
3017           attr_istyle = "3";
3018         }
3019         else if (strcasestr(cur->value, "<ja:hk>")) {
3020           attr_istyle = "2";
3021         }
3022         else if (strcasestr(cur->value, "<ja:h>")) {
3023           attr_istyle = "1";
3024         }
3025       }
3026     }
3027   }
3028
3029   W_L("<input");
3030   if (attr_size) {
3031     W_L(" size=\"");
3032     W_V(attr_size);
3033     W_L("\"");
3034   }
3035   if (attr_name) {
3036     W_L(" name=\"");
3037     W_V(chxj_jreserved_to_safe_tag(r, attr_name, android->entryp));
3038     W_L("\"");
3039   }
3040   if (attr_value) {
3041     W_L(" value=\"");
3042     W_V(chxj_add_slash_to_doublequote(doc->pool, attr_value));
3043     W_L("\"");
3044   }
3045   if (attr_istyle && (*attr_istyle == '1' || *attr_istyle == '2' || *attr_istyle == '3' || *attr_istyle == '4')) {
3046     if (attr_type && STRCASEEQ('t','T',"text",attr_type)) {
3047       /* 1 => ignore */ 
3048       /* 2 => ignore */
3049       /* 3 => ignore */
3050       /* 4 => number */
3051       if (*attr_istyle == '4') {
3052         attr_type = apr_pstrdup(r->pool, "number");
3053       }
3054     }
3055   }
3056   if (attr_type) {
3057     W_L(" type=\"");
3058     W_V(attr_type);
3059     W_L("\"");
3060   }
3061   /*--------------------------------------------------------------------------*/
3062   /* The figure is default for the password.                                  */
3063   /*--------------------------------------------------------------------------*/
3064   if (attr_max_length && *attr_max_length) {
3065     if (chxj_chk_numeric(attr_max_length) == 0) {
3066       W_L(" maxlength=\"");
3067       W_V(attr_max_length);
3068       W_L("\"");
3069     }
3070   }
3071   if (attr_checked) {
3072     W_L(" checked=\"checked\"");
3073   }
3074   W_L(" />");
3075   return android->out;
3076 }
3077
3078
3079 /**
3080  * It is a handler who processes the INPUT tag.
3081  *
3082  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3083  *                     destination is specified.
3084  * @param node   [i]   The INPUT tag node is specified.
3085  * @return The conversion result is returned.
3086  */
3087 static char *
3088 s_android_end_input_tag(void *pdoc, Node *UNUSED(child)) 
3089 {
3090   android_t *android = GET_ANDROID(pdoc);
3091   return android->out;
3092 }
3093
3094
3095 /**
3096  * It is a handler who processes the CENTER tag.
3097  *
3098  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3099  *                     destination is specified.
3100  * @param node   [i]   The CENTER tag node is specified.
3101  * @return The conversion result is returned.
3102  */
3103 static char *
3104 s_android_start_center_tag(void *pdoc, Node *node)
3105 {
3106   android_t *android;
3107   Doc       *doc;
3108   Attr      *attr;
3109   char      *attr_style = NULL;
3110   char      *attr_color = NULL;
3111   char      *attr_size  = NULL;
3112
3113   android = GET_ANDROID(pdoc);
3114   doc    = android->doc;
3115
3116   for (attr = qs_get_attr(doc,node);
3117        attr;
3118        attr = qs_get_next_attr(doc,attr)) {
3119     char *name  = qs_get_attr_name(doc,attr);
3120     char *value = qs_get_attr_value(doc,attr);
3121     if (STRCASEEQ('s','S',"style",name) && value && *value) {
3122       attr_style = value;
3123     }
3124   }
3125   if (IS_CSS_ON(android->entryp)) {
3126     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
3127     if (style) {
3128       css_property_t *color_prop      = chxj_css_get_property_value(doc, style, "color");
3129       css_property_t *size_prop       = chxj_css_get_property_value(doc, style, "font-size");
3130       css_property_t *cur;
3131       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
3132         if (cur->value && *cur->value) {
3133           attr_color = apr_pstrdup(doc->pool, cur->value);
3134         }
3135       }
3136       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
3137         if (cur->value && *cur->value) {
3138           attr_size = apr_pstrdup(doc->pool, cur->value);
3139         }
3140       }
3141     }
3142   }
3143
3144   W_L("<center");
3145   if (attr_size || attr_color) {
3146     W_L(" style=\"");
3147     if (attr_size) {
3148       W_L("font-size:");
3149       W_V(attr_size);
3150       W_L(";");
3151     }
3152     if (attr_color) {
3153       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
3154       W_L("color:");
3155       W_V(attr_color);
3156       W_L(";");
3157     }
3158     W_L("\"");
3159   }
3160   W_L(">");
3161   
3162   return android->out;
3163 }
3164
3165
3166 /**
3167  * It is a handler who processes the CENTER tag.
3168  *
3169  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3170  *                     destination is specified.
3171  * @param node   [i]   The CENTER tag node is specified.
3172  * @return The conversion result is returned.
3173  */
3174 static char *
3175 s_android_end_center_tag(void *pdoc, Node *UNUSED(node))
3176 {
3177   android_t    *android;
3178   Doc         *doc;
3179   request_rec *r;
3180
3181   android = GET_ANDROID(pdoc);
3182   doc    = android->doc;
3183   r      = doc->r;
3184
3185   W_L("</center>");
3186   if (IS_CSS_ON(android->entryp)) {
3187     chxj_css_pop_prop_list(android->css_prop_stack);
3188   }
3189   return android->out;
3190 }
3191
3192
3193 /**
3194  * It is a handler who processes the li tag.
3195  *
3196  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3197  *                     destination is specified.
3198  * @param node   [i]   The li tag node is specified.
3199  * @return The conversion result is returned.
3200  */
3201 static char *
3202 s_android_start_li_tag(void *pdoc, Node *node)
3203 {
3204   android_t    *android;
3205   Doc         *doc;
3206   request_rec *r;
3207   Attr        *attr;
3208   char        *attr_type  = NULL;
3209   char        *attr_value = NULL;
3210   char        *attr_style = NULL;
3211
3212   android = GET_ANDROID(pdoc);
3213   doc   = android->doc;
3214   r     = doc->r;
3215
3216   for (attr = qs_get_attr(doc,node);
3217        attr;
3218        attr = qs_get_next_attr(doc,attr)) {
3219     char *name  = qs_get_attr_name(doc,attr);
3220     char *value = qs_get_attr_value(doc,attr);
3221     if (STRCASEEQ('t','T',"type",name)) {
3222       if (value && (*value == '1' || *value == 'a' || *value == 'A' || STRCASEEQ('d','D',"disc",value) || STRCASEEQ('s','S',"square",value) || STRCASEEQ('c','C',"circle",value))) {
3223         if (*value == '1') {
3224           attr_type = apr_pstrdup(doc->pool, "decimal");
3225         }
3226         else if (*value == 'a') {
3227           attr_type = apr_pstrdup(doc->pool, "lower-alpha");
3228         }
3229         else if (*value == 'A') {
3230           attr_type = apr_pstrdup(doc->pool, "upper-alpha");
3231         }
3232         else {
3233           attr_type = value;
3234         }
3235       }
3236     }
3237     else if (STRCASEEQ('v','V',"value", name) && value && *value) {
3238       attr_value = value;
3239     }
3240     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
3241       attr_style = value;
3242     }
3243   }
3244   if (IS_CSS_ON(android->entryp)) {
3245     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
3246     if (style) {
3247       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type");
3248       css_property_t *cur;
3249       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3250         if (STRCASEEQ('d','D',"decimal", cur->value)) {
3251           attr_type = apr_pstrdup(doc->pool, "decimal");
3252         }
3253         else if (STRCASEEQ('u','U',"upper-alpha", cur->value)) {
3254           attr_type = apr_pstrdup(doc->pool, "upper-alpha");
3255         }
3256         else if (STRCASEEQ('l','L',"lower-alpha", cur->value)) {
3257           attr_type = apr_pstrdup(doc->pool, "lower-alpha");
3258         }
3259         else if (STRCASEEQ('d','D',"disc", cur->value)) {
3260           attr_type = apr_pstrdup(doc->pool, "disc");
3261         }
3262         else if (STRCASEEQ('s','S',"square", cur->value)) {
3263           attr_type = apr_pstrdup(doc->pool, "square");
3264         }
3265         else if (STRCASEEQ('c','C',"circle", cur->value)) {
3266           attr_type = apr_pstrdup(doc->pool, "circle");
3267         }
3268       }
3269     }
3270   }
3271
3272
3273   W_L("<li");
3274   if (attr_type) {
3275     W_L(" style=\"");
3276     W_L("list-style-type:");
3277     W_V(attr_type);
3278     W_L(";");
3279     W_L("\"");
3280   }
3281   if (attr_value) {
3282     W_L(" value=\"");
3283     W_V(attr_value);
3284     W_L("\"");
3285   }
3286   W_L(">");
3287   return android->out;
3288 }
3289
3290
3291 /**
3292  * It is a handler who processes the li tag.
3293  *
3294  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3295  *                     destination is specified.
3296  * @param node   [i]   The li tag node is specified.
3297  * @return The conversion result is returned.
3298  */
3299 static char *
3300 s_android_end_li_tag(void *pdoc, Node *UNUSED(child)) 
3301 {
3302   android_t     *android;
3303   Doc         *doc;
3304   request_rec *r;
3305
3306   android = GET_ANDROID(pdoc);
3307   doc   = android->doc;
3308   r     = doc->r;
3309
3310   if (IS_CSS_ON(android->entryp)) {
3311     chxj_css_pop_prop_list(android->css_prop_stack);
3312   }
3313   W_L("</li>");
3314   return android->out;
3315 }
3316
3317
3318 /**
3319  * It is a handler who processes the OL tag.
3320  *
3321  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3322  *                     destination is specified.
3323  * @param node   [i]   The OL tag node is specified.
3324  * @return The conversion result is returned.
3325  */
3326 static char *
3327 s_android_start_ol_tag(void *pdoc, Node *node)
3328 {
3329   android_t    *android;
3330   Doc         *doc;
3331   request_rec *r;
3332   Attr        *attr;
3333   char        *attr_style = NULL;
3334   char        *attr_start = NULL;
3335   char        *attr_type  = NULL;
3336   char        *css_clear  = NULL;
3337
3338   android = GET_ANDROID(pdoc);
3339   doc   = android->doc;
3340   r     = doc->r;
3341
3342   /*--------------------------------------------------------------------------*/
3343   /* Get Attributes                                                           */
3344   /*--------------------------------------------------------------------------*/
3345   for (attr = qs_get_attr(doc,node);
3346        attr;
3347        attr = qs_get_next_attr(doc,attr)) {
3348     char *name = qs_get_attr_name(doc,attr);
3349     char *value = qs_get_attr_value(doc,attr);
3350     if (STRCASEEQ('t','T',"type",name) && value) {
3351       if (*value == '1') {
3352         attr_type = apr_pstrdup(doc->pool, "decimal");
3353       }
3354       else if (*value == 'a') {
3355         attr_type = apr_pstrdup(doc->pool, "lower-alpha");
3356       }
3357       else if (*value == 'A') {
3358         attr_type = apr_pstrdup(doc->pool, "upper-alpha");
3359       }
3360     }
3361     else if (STRCASEEQ('s','S',"start",name) && value && *value) {
3362       attr_start = value;
3363     }
3364     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
3365       attr_style = value;
3366     }
3367   }
3368   if (IS_CSS_ON(android->entryp)) {
3369     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
3370     if (style) {
3371       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type");
3372       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
3373       
3374       css_property_t *cur;
3375       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3376         if (STRCASEEQ('d','D',"decimal", cur->value)) {
3377           attr_type = apr_pstrdup(doc->pool, "decimal");
3378         }
3379         else if (STRCASEEQ('u','U',"upper-alpha", cur->value)) {
3380           attr_type = apr_pstrdup(doc->pool, "upper-alpha");
3381         }
3382         else if (STRCASEEQ('l','L',"lower-alpha", cur->value)) {
3383           attr_type = apr_pstrdup(doc->pool, "lower-alpha");
3384         }
3385       }
3386       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
3387         css_clear = apr_pstrdup(doc->pool, cur->value);
3388       }
3389     }
3390   }
3391   W_L("<ol");
3392   if (attr_type || css_clear) {
3393     W_L(" style=\"");
3394     if (attr_type) {
3395       W_L("list-style-type:");
3396       W_V(attr_type);
3397       W_L(";");
3398     }
3399     if (css_clear){
3400       W_L("clear:");
3401       W_V(css_clear);
3402       W_L(";");
3403     }
3404     W_L("\"");
3405   }
3406   if (attr_start) {
3407     W_L(" start=\"");
3408     W_V(attr_start);
3409     W_L("\"");
3410   }
3411   W_L(">");
3412
3413   return android->out;
3414 }
3415
3416
3417 /**
3418  * It is a handler who processes the OL tag.
3419  *
3420  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3421  *                     destination is specified.
3422  * @param node   [i]   The OL tag node is specified.
3423  * @return The conversion result is returned.
3424  */
3425 static char *
3426 s_android_end_ol_tag(void *pdoc, Node *UNUSED(child)) 
3427 {
3428   android_t     *android;
3429   Doc         *doc;
3430   request_rec *r;
3431
3432   android = GET_ANDROID(pdoc);
3433   doc   = android->doc;
3434   r     = doc->r;
3435
3436   W_L("</ol>");
3437   if (IS_CSS_ON(android->entryp)) {
3438     chxj_css_pop_prop_list(android->css_prop_stack);
3439   }
3440   return android->out;
3441 }
3442
3443
3444 /**
3445  * It is a handler who processes the P tag.
3446  *
3447  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3448  *                     destination is specified.
3449  * @param node   [i]   The P tag node is specified.
3450  * @return The conversion result is returned.
3451  */
3452 static char *
3453 s_android_start_p_tag(void *pdoc, Node *node)
3454 {
3455   android_t    *android;
3456   Doc         *doc;
3457   request_rec *r;
3458   Attr        *attr;
3459   char        *attr_align = NULL;
3460   char        *attr_style = NULL;
3461   char        *attr_color = NULL;
3462   char        *attr_blink = NULL;
3463   char        *css_clear  = NULL;
3464
3465   android = GET_ANDROID(pdoc);
3466   doc   = android->doc;
3467   r     = doc->r;
3468
3469   for (attr = qs_get_attr(doc,node);
3470        attr;
3471        attr = qs_get_next_attr(doc,attr)) {
3472     char *nm  = qs_get_attr_name(doc,attr);
3473     char *val = qs_get_attr_value(doc,attr);
3474     if (STRCASEEQ('a','A',"align", nm)) {
3475       /*----------------------------------------------------------------------*/
3476       /* CHTML 1.0 (W3C version 3.2)                                          */
3477       /*----------------------------------------------------------------------*/
3478       if (val && (STRCASEEQ('l','L',"left",val) || STRCASEEQ('r','R',"right",val) || STRCASEEQ('c','C',"center",val))) {
3479         attr_align = apr_pstrdup(doc->buf.pool, val);
3480         break;
3481       }
3482     }
3483     else if (STRCASEEQ('s','S',"style", nm) && val && *val) {
3484       attr_style = apr_pstrdup(doc->buf.pool, val);
3485     }
3486   }
3487   if (IS_CSS_ON(android->entryp)) {
3488     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
3489     if (style) {
3490       css_property_t *text_align_prop = chxj_css_get_property_value(doc, style, "text-align");
3491       css_property_t *color_prop      = chxj_css_get_property_value(doc, style, "color");
3492       css_property_t *text_deco_prop  = chxj_css_get_property_value(doc, style, "text-decoration");
3493       css_property_t *clear_prop      = chxj_css_get_property_value(doc, style, "clear");
3494       css_property_t *cur;
3495       for (cur = text_align_prop->next; cur != text_align_prop; cur = cur->next) {
3496         if (STRCASEEQ('l','L',"left",cur->value)) {
3497           attr_align = apr_pstrdup(doc->pool, "left");
3498         }
3499         else if (STRCASEEQ('c','C',"center",cur->value)) {
3500           attr_align = apr_pstrdup(doc->pool, "center");
3501         }
3502         else if (STRCASEEQ('r','R',"right",cur->value)) {
3503           attr_align = apr_pstrdup(doc->pool, "right");
3504         }
3505       }
3506       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
3507         if (cur->value && *cur->value) {
3508           attr_color = apr_pstrdup(doc->pool, cur->value);
3509         }
3510       }
3511       for (cur = text_deco_prop->next; cur != text_deco_prop; cur = cur->next) {
3512         if (cur->value && *cur->value && STRCASEEQ('b','B',"blink",cur->value)) {
3513           attr_blink = apr_pstrdup(doc->pool, cur->value);
3514         }
3515       }
3516       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
3517         css_clear = apr_pstrdup(doc->pool, cur->value);
3518       }
3519     }
3520   }
3521   W_L("<p");
3522   if ((attr_align && *attr_align) || (attr_color && *attr_color) || (attr_blink && *attr_blink) || css_clear) {
3523     W_L(" style=\"");
3524     if (attr_align) {
3525       W_L("text-align:");
3526       W_V(attr_align);
3527       W_L(";");
3528     }
3529     if (attr_color) {
3530       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
3531       W_L("color:");
3532       W_V(attr_color);
3533       W_L(";");
3534     }
3535     if (attr_blink) {
3536       W_L("text-decoration:");
3537       W_V(attr_blink);
3538       W_L(";");
3539     }
3540     if (css_clear){
3541       W_L("clear:");
3542       W_V(css_clear);
3543       W_L(";");
3544     }
3545     W_L("\"");
3546   }
3547   W_L(">");
3548   return android->out;
3549 }
3550
3551
3552 /**
3553  * It is a handler who processes the P tag.
3554  *
3555  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3556  *                     destination is specified.
3557  * @param node   [i]   The P tag node is specified.
3558  * @return The conversion result is returned.
3559  */
3560 static char *
3561 s_android_end_p_tag(void *pdoc, Node *UNUSED(child)) 
3562 {
3563   android_t  *android = GET_ANDROID(pdoc);
3564   Doc       *doc    = android->doc;
3565
3566   W_L("</p>");
3567   if (IS_CSS_ON(android->entryp)) {
3568     chxj_css_pop_prop_list(android->css_prop_stack);
3569   }
3570   return android->out;
3571 }
3572
3573
3574 /**
3575  * It is a handler who processes the PRE tag.
3576  *
3577  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3578  *                     destination is specified.
3579  * @param node   [i]   The PRE tag node is specified.
3580  * @return The conversion result is returned.
3581  */
3582 static char *
3583 s_android_start_pre_tag(void *pdoc, Node *node)
3584 {
3585   android_t  *android = GET_ANDROID(pdoc);
3586   Doc       *doc   = android->doc;
3587   Attr      *attr;
3588   char      *attr_style = NULL;
3589   char      *css_clear  = NULL;
3590
3591   for (attr = qs_get_attr(doc,node);
3592        attr;
3593        attr = qs_get_next_attr(doc,attr)) {
3594     char *nm  = qs_get_attr_name(doc,attr);
3595     char *val = qs_get_attr_value(doc,attr);
3596     if (val && STRCASEEQ('s','S',"style", nm)) {
3597       attr_style = val;
3598     }
3599   }
3600
3601   if (IS_CSS_ON(android->entryp)) {
3602     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
3603     if (style) {
3604       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
3605       
3606       css_property_t *cur;
3607       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
3608         css_clear = apr_pstrdup(doc->pool, cur->value);
3609       }
3610     }
3611   }
3612
3613   android->pre_flag++;
3614   W_L("<pre");
3615   if (css_clear) {
3616     W_L(" style=\"");
3617     W_L("clear:");
3618     W_V(css_clear);
3619     W_L(";");
3620     W_L("\"");
3621   }
3622   W_L(">");
3623   return android->out;
3624 }
3625
3626
3627 /**
3628  * It is a handler who processes the PRE tag.
3629  *
3630  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3631  *                     destination is specified.
3632  * @param node   [i]   The PRE tag node is specified.
3633  * @return The conversion result is returned.
3634  */
3635 static char *
3636 s_android_end_pre_tag(void *pdoc, Node *UNUSED(child)) 
3637 {
3638   android_t *android = GET_ANDROID(pdoc);
3639   Doc     *doc   = android->doc;
3640
3641   W_L("</pre>");
3642   android->pre_flag--;
3643   if (IS_CSS_ON(android->entryp)) {
3644     chxj_css_pop_prop_list(android->css_prop_stack);
3645   }
3646
3647   return android->out;
3648 }
3649
3650
3651 /**
3652  * It is a handler who processes the UL tag.
3653  *
3654  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3655  *                     destination is specified.
3656  * @param node   [i]   The UL tag node is specified.
3657  * @return The conversion result is returned.
3658  */
3659 static char *
3660 s_android_start_ul_tag(void *pdoc, Node *node)
3661 {
3662   android_t *android = GET_ANDROID(pdoc);
3663   Doc      *doc    = android->doc;
3664   Attr     *attr;
3665   char     *attr_type = NULL;
3666   char     *attr_style = NULL;
3667   char     *css_clear  = NULL;
3668   
3669   /*--------------------------------------------------------------------------*/
3670   /* Get Attributes                                                           */
3671   /*--------------------------------------------------------------------------*/
3672   for (attr = qs_get_attr(doc,node);
3673        attr;
3674        attr = qs_get_next_attr(doc,attr)) {
3675     char *name   = qs_get_attr_name(doc,attr);
3676     char *value  = qs_get_attr_value(doc,attr);
3677     if (STRCASEEQ('t','T',"type",name)) {
3678       if (value && (STRCASEEQ('d','D',"disc",value) || STRCASEEQ('c','C',"circle",value) || STRCASEEQ('s','S',"square",value))) {
3679         attr_type = value;
3680       }
3681     }
3682     else if (value && *value && STRCASEEQ('s','S',"style", name)) {
3683       attr_style = value;
3684     }
3685   }
3686   if (IS_CSS_ON(android->entryp)) {
3687     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
3688     if (style) {
3689       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type");
3690       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
3691       
3692       css_property_t *cur;
3693       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3694         if (STRCASEEQ('d','D',"disc",cur->value)) {
3695           attr_type = apr_pstrdup(doc->pool, "disc");
3696         }
3697         else if (STRCASEEQ('c','C',"circle",cur->value)) {
3698           attr_type = apr_pstrdup(doc->pool, "circle");
3699         }
3700         else if (STRCASEEQ('s','S',"square",cur->value)) {
3701           attr_type = apr_pstrdup(doc->pool, "square");
3702         }
3703       }
3704       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
3705         css_clear = apr_pstrdup(doc->pool, cur->value);
3706       }
3707     }
3708   }
3709   W_L("<ul");
3710   if (attr_type || css_clear) {
3711     W_L(" style=\"");
3712     if (attr_type ){
3713       W_L("list-style-type:");
3714       W_V(attr_type);
3715       W_L(";");
3716     }
3717     if (css_clear){
3718       W_L("clear:");
3719       W_V(css_clear);
3720       W_L(";");
3721     }
3722     W_L("\"");
3723   }
3724   W_L(">");
3725   return android->out;
3726 }
3727
3728
3729 /**
3730  * It is a handler who processes the UL tag.
3731  *
3732  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3733  *                     destination is specified.
3734  * @param node   [i]   The UL tag node is specified.
3735  * @return The conversion result is returned.
3736  */
3737 static char *
3738 s_android_end_ul_tag(void *pdoc, Node *UNUSED(child)) 
3739 {
3740   android_t *android = GET_ANDROID(pdoc);
3741   Doc     *doc   = android->doc;
3742
3743   W_L("</ul>");
3744   if (IS_CSS_ON(android->entryp)) {
3745     chxj_css_pop_prop_list(android->css_prop_stack);
3746   }
3747   return android->out;
3748 }
3749
3750
3751 /**
3752  * It is a handler who processes the HR tag.
3753  *
3754  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3755  *                     destination is specified.
3756  * @param node   [i]   The HR tag node is specified.
3757  * @return The conversion result is returned.
3758  */
3759 static char *
3760 s_android_start_hr_tag(void *pdoc, Node *node) 
3761 {
3762   Attr        *attr;
3763   android_t     *android;
3764   Doc         *doc;
3765   request_rec *r;
3766   char        *attr_align   = NULL;
3767   char        *attr_size    = NULL;
3768   char        *attr_width   = NULL;
3769   char        *attr_noshade = NULL;
3770   char        *attr_style   = NULL;
3771   char        *attr_color   = NULL;
3772   char        *attr_bgcolor = NULL;
3773   
3774   char        *style_border_color = NULL;
3775   char        *css_clear          = NULL;
3776
3777   android   = GET_ANDROID(pdoc);
3778   doc     = android->doc;
3779   r       = doc->r;
3780
3781   for (attr = qs_get_attr(doc,node);
3782        attr; 
3783        attr = qs_get_next_attr(doc,attr)) {
3784     char *name  = qs_get_attr_name (doc,attr);
3785     char *value = qs_get_attr_value(doc,attr);
3786     switch(*name) {
3787     case 'a':
3788     case 'A':
3789       if (strcasecmp(name, "align") == 0) {
3790         /*--------------------------------------------------------------------*/
3791         /* CHTML 1.0                                                          */
3792         /*--------------------------------------------------------------------*/
3793         if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3794           if (value[0] == 'c' || value[0] == 'C') {
3795             attr_align = apr_pstrdup(doc->pool, "none");
3796           }
3797           else {
3798             attr_align = value;
3799           }
3800         }
3801       }
3802       break;
3803
3804     case 's':
3805     case 'S':
3806       if (strcasecmp(name, "size") == 0) {
3807         /*--------------------------------------------------------------------*/
3808         /* CHTML 1.0                                                          */
3809         /*--------------------------------------------------------------------*/
3810         if (value && *value) {
3811           attr_size = value;
3812         }
3813       }
3814       else if (strcasecmp(name, "style") == 0) {
3815         if (value && *value) {
3816           attr_style = value;
3817         }
3818       }
3819       break;
3820
3821     case 'w':
3822     case 'W':
3823       if (strcasecmp(name, "width") == 0) {
3824         /*--------------------------------------------------------------------*/
3825         /* CHTML 1.0                                                          */
3826         /*--------------------------------------------------------------------*/
3827         if (value && *value) {
3828           attr_width = value;
3829         }
3830       }
3831       break;
3832
3833     case 'n':
3834     case 'N':
3835       if (strcasecmp(name, "noshade") == 0) {
3836         /*--------------------------------------------------------------------*/
3837         /* CHTML 1.0                                                          */
3838         /*--------------------------------------------------------------------*/
3839         attr_noshade = apr_pstrdup(doc->pool, "noshade");
3840       }
3841       break;
3842
3843     case 'c':
3844     case 'C':
3845       if (strcasecmp(name, "color") == 0 && value && *value) {
3846         /*--------------------------------------------------------------------*/
3847         /* CHTML 4.0                                                          */
3848         /*--------------------------------------------------------------------*/
3849         attr_color = value;
3850       }
3851       break;
3852
3853     default:
3854       break;
3855     }
3856   }
3857   if (IS_CSS_ON(android->entryp)) {
3858     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
3859     if (style) {
3860       css_property_t *border_style_prop = chxj_css_get_property_value(doc, style, "border-style");
3861       css_property_t *height_prop       = chxj_css_get_property_value(doc, style, "height");
3862       css_property_t *width_prop        = chxj_css_get_property_value(doc, style, "width");
3863       
3864       css_property_t *bgcolor_prop      = chxj_css_get_property_value(doc, style, "background-color");
3865       css_property_t *float_prop        = chxj_css_get_property_value(doc, style, "float");
3866       css_property_t *border_color_prop = chxj_css_get_property_value(doc, style, "border-color");
3867       css_property_t *clear_prop        = chxj_css_get_property_value(doc, style, "clear");
3868       css_property_t *cur;
3869       
3870       for (cur = border_style_prop->next; cur != border_style_prop; cur = cur->next) {
3871         if (STRCASEEQ('s','S',"solid",cur->value)) {
3872           attr_noshade = "noshade";
3873         }
3874       }
3875       for (cur = height_prop->next; cur != height_prop; cur = cur->next) {
3876         attr_size = apr_pstrdup(doc->pool, cur->value);
3877       }
3878       for (cur = bgcolor_prop->next; cur != bgcolor_prop; cur = cur->next) {
3879         attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
3880       }
3881       if (!attr_align) {
3882         for (cur = float_prop->next; cur != float_prop; cur = cur->next) {
3883           attr_align = apr_pstrdup(doc->pool,cur->value);
3884         }
3885       }
3886       
3887       
3888       for (cur = width_prop->next; cur != width_prop; cur = cur->next) {
3889         char *tmp = apr_pstrdup(doc->pool, cur->value);
3890         char *tmpp = strstr(tmp, "px");
3891         if (tmpp) {
3892           attr_width = apr_pstrdup(doc->pool, tmp);
3893         }
3894         else {
3895           tmpp = strstr(tmp, "%");
3896           if (tmpp) {
3897             attr_width = apr_pstrdup(doc->pool, tmp);
3898           }
3899         }
3900       }
3901       
3902       for (cur = border_color_prop->next; cur != border_color_prop; cur = cur->next) {
3903         char *tmp = apr_pstrdup(doc->pool, cur->value);
3904         if(tmp){
3905           style_border_color = apr_pstrdup(doc->pool, tmp);
3906         }
3907       }
3908       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
3909         css_clear = apr_pstrdup(doc->pool, cur->value);
3910       }
3911     }
3912   }
3913   W_L("<hr");
3914   if (attr_align || attr_size || attr_width || attr_noshade || style_border_color || css_clear || attr_bgcolor) {
3915     W_L(" style=\"");
3916     if (attr_align) {
3917       W_L("float:");
3918       W_V(attr_align);
3919       W_L(";");
3920     }
3921     if (attr_size) {
3922       W_L("height:");
3923       W_V(attr_size);
3924       if (chxj_chk_numeric(attr_size) == 0) {
3925         W_L("px");
3926       }
3927       W_L(";");
3928     }
3929     if (attr_width) {
3930       W_L("width:");
3931       W_V(attr_width);
3932       if (!strstr(attr_width, "px") && !strstr(attr_width, "%")) {
3933         W_L("px");
3934       }
3935       W_L(";");
3936     }
3937     if (attr_noshade) {
3938       W_L("border-style:solid;");
3939     }
3940     if(style_border_color){
3941       W_L("border-color:");
3942       W_V(style_border_color);
3943       W_L(";");
3944     }
3945     if (attr_bgcolor) {
3946       W_L("background-color:");
3947       W_V(attr_bgcolor);
3948       W_L(";");
3949     }
3950     if (css_clear){
3951       W_L("clear:");
3952       W_V(css_clear);
3953       W_L(";");
3954     }
3955     W_L("\"");
3956   }
3957   if (attr_color) {
3958     W_L(" color=\"");
3959     W_V(attr_color);
3960     W_L("\"");
3961   }
3962   
3963   W_L(" />");
3964
3965   return android->out;
3966 }
3967
3968
3969 /**
3970  * It is a handler who processes the HR tag.
3971  *
3972  * @param android  [i/o] The pointer to the ANDROID structure at the output
3973  *                     destination is specified.
3974  * @param node   [i]   The HR tag node is specified.
3975  * @return The conversion result is returned.
3976  */
3977 static char *
3978 s_android_end_hr_tag(void *pdoc, Node *UNUSED(child)) 
3979 {
3980   android_t *android = GET_ANDROID(pdoc);
3981   return android->out;
3982 }
3983
3984
3985 /**
3986  * It is a handler who processes the IMG tag.
3987  *
3988  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3989  *                     destination is specified.
3990  * @param node   [i]   The IMG tag node is specified.
3991  * @return The conversion result is returned.
3992  */
3993 static char *
3994 s_android_start_img_tag(void *pdoc, Node *node) 
3995 {
3996   android_t    *android = GET_ANDROID(pdoc);
3997   Doc         *doc   = android->doc;
3998   request_rec *r     = doc->r;
3999   Attr        *attr;
4000   char        *attr_src    = NULL;
4001   char        *attr_height = NULL;
4002   char        *attr_width  = NULL;
4003   char        *attr_alt    = NULL;
4004   char        *attr_style  = NULL;
4005   char        *attr_hspace = NULL;
4006   char        *attr_vspace = NULL;
4007   
4008   char        *css_float          = NULL;
4009   char        *css_margin_left    = NULL;
4010   char        *css_margin_right   = NULL;
4011   char        *css_margin_top     = NULL;
4012   char        *css_margin_bottom  = NULL;
4013   char        *css_display        = NULL;
4014   char        *css_valign         = NULL;
4015   
4016 #ifndef IMG_NOT_CONVERT_FILENAME
4017   device_table  *spec = android->spec;
4018 #endif
4019
4020   /*--------------------------------------------------------------------------*/
4021   /* Get Attributes                                                           */
4022   /*--------------------------------------------------------------------------*/
4023   for (attr = qs_get_attr(doc,node);
4024        attr;
4025        attr = qs_get_next_attr(doc,attr)) {
4026     char *name  = qs_get_attr_name(doc,attr);
4027     char *value = qs_get_attr_value(doc,attr);
4028     if (STRCASEEQ('s','S',"src",name)) {
4029       /*----------------------------------------------------------------------*/
4030       /* CHTML 1.0                                                            */
4031       /*----------------------------------------------------------------------*/
4032 #ifdef IMG_NOT_CONVERT_FILENAME
4033       value = chxj_encoding_parameter(r, value, 1);
4034       value = chxj_jreserved_tag_to_safe_for_query_string(r, value, android->entryp, 1);
4035       value = chxj_add_cookie_no_update_parameter(r, value);
4036       value = chxj_img_rewrite_parameter(r,android->conf,value);
4037       attr_src = value;
4038 #else
4039       value = chxj_img_conv(r, spec, value);
4040       value = chxj_encoding_parameter(r, value, 1);
4041       value = chxj_jreserved_tag_to_safe_for_query_string(r, value, android->entryp, 1);
4042       value = chxj_add_cookie_no_update_parameter(r, value);
4043       value = chxj_img_rewrite_parameter(r,android->conf,value);
4044       attr_src = value;
4045 #endif
4046     }
4047     else if (STRCASEEQ('a','A',"align",name)) {
4048       /*----------------------------------------------------------------------*/
4049       /* CHTML 1.0                                                            */
4050       /*----------------------------------------------------------------------*/
4051       if (value) {
4052         if (STRCASEEQ('t','T',"top",   value) ||
4053             STRCASEEQ('m','M',"middle",value) ||
4054             STRCASEEQ('b','B',"bottom",value)){
4055           css_valign = value;
4056         }else if (STRCASEEQ('l','L',"left",  value) || STRCASEEQ('r','R',"right", value)) {
4057           css_float = value;
4058         }
4059         else if (STRCASEEQ('c','C',"center",value)) {
4060           css_valign = apr_pstrdup(doc->pool, "middle");
4061         }
4062       }
4063     }
4064     else if (STRCASEEQ('w','W',"width",name) && value && *value) {
4065       /*----------------------------------------------------------------------*/
4066       /* CHTML 1.0                                                            */
4067       /*----------------------------------------------------------------------*/
4068       attr_width = value;
4069     }
4070     else if (STRCASEEQ('h','H',"height",name) && value && *value) {
4071       /*----------------------------------------------------------------------*/
4072       /* CHTML 1.0                                                            */
4073       /*----------------------------------------------------------------------*/
4074       attr_height = value;
4075     }
4076     else if (STRCASEEQ('h','H',"hspace",name)) {
4077       /*----------------------------------------------------------------------*/
4078       /* CHTML 1.0                                                            */
4079       /*----------------------------------------------------------------------*/
4080       attr_hspace = value;
4081     }
4082     else if (STRCASEEQ('v','V',"vspace",name)) {
4083       /*----------------------------------------------------------------------*/
4084       /* CHTML 1.0                                                            */
4085       /*----------------------------------------------------------------------*/
4086       attr_vspace = value;
4087     }
4088     else if (STRCASEEQ('a','A',"alt",name) && value && *value) {
4089       /*----------------------------------------------------------------------*/
4090       /* CHTML 1.0                                                            */
4091       /*----------------------------------------------------------------------*/
4092       attr_alt = value;
4093     }
4094     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
4095       /*----------------------------------------------------------------------*/
4096       /* CHTML 1.0                                                            */
4097       /*----------------------------------------------------------------------*/
4098       attr_style = value;
4099     }
4100   }
4101
4102   if (IS_CSS_ON(android->entryp)) {
4103     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
4104     if (style) {
4105       css_property_t *height_prop = chxj_css_get_property_value(doc, style, "height");
4106       css_property_t *width_prop  = chxj_css_get_property_value(doc, style, "width");
4107       css_property_t *valign_prop = chxj_css_get_property_value(doc, style, "vertical-align");
4108       css_property_t *margin_left_prop   = chxj_css_get_property_value(doc, style, "margin-left");
4109       css_property_t *margin_right_prop  = chxj_css_get_property_value(doc, style, "margin-right");
4110       css_property_t *margin_top_prop    = chxj_css_get_property_value(doc, style, "margin-top");
4111       css_property_t *margin_bottom_prop = chxj_css_get_property_value(doc, style, "margin-bottom");
4112       
4113       
4114       css_property_t *cur;
4115       for (cur = height_prop->next; cur != height_prop; cur = cur->next) {
4116         attr_height = apr_pstrdup(doc->pool, cur->value);
4117       }
4118       for (cur = width_prop->next; cur != width_prop; cur = cur->next) {
4119         attr_width = apr_pstrdup(doc->pool, cur->value);
4120       }
4121       if(!css_valign){
4122         for (cur = valign_prop->next; cur != valign_prop; cur = cur->next) {
4123           css_valign = apr_pstrdup(doc->pool, cur->value);
4124         }
4125       }
4126       if (! attr_hspace) {
4127         for (cur = margin_left_prop->next; cur != margin_left_prop; cur = cur->next) {
4128           css_margin_left   = apr_pstrdup(doc->pool, cur->value);
4129         }
4130         for (cur = margin_right_prop->next; cur != margin_right_prop; cur = cur->next) {
4131           css_margin_right  = apr_pstrdup(doc->pool, cur->value);
4132         }
4133       }
4134       if (! attr_vspace) {
4135         for (cur = margin_top_prop->next; cur != margin_top_prop; cur = cur->next) {
4136           css_margin_top = apr_pstrdup(doc->pool, cur->value);
4137         }
4138         for (cur = margin_bottom_prop->next; cur != margin_bottom_prop; cur = cur->next) {
4139           css_margin_bottom = apr_pstrdup(doc->pool, cur->value);
4140         }
4141       }
4142       if(!css_float){
4143         css_property_t *float_prop = chxj_css_get_property_value(doc, style, "float");
4144         for (cur = float_prop->next; cur != float_prop; cur = cur->next) {
4145           css_float = apr_pstrdup(doc->pool, cur->value);
4146         }
4147       }
4148       
4149       css_property_t *display_prop       = chxj_css_get_property_value(doc, style, "display");
4150       for (cur = display_prop->next; cur != display_prop; cur = cur->next) {
4151         char *tmp = apr_pstrdup(doc->pool, cur->value);
4152         char *tmpp = strstr(tmp, "none");
4153         if(tmpp){
4154           css_display = apr_pstrdup(doc->pool, tmp);
4155         }
4156       }
4157     }
4158   }
4159
4160   W_L("<img");
4161   if (attr_src) {
4162     W_L(" src=\"");
4163     W_V(attr_src);
4164     W_L("\"");
4165   }
4166   if (attr_hspace || attr_vspace || css_float || css_margin_left || css_margin_right || css_margin_top || css_margin_bottom || css_valign || css_display) {
4167     W_L(" style=\"");
4168     if(css_float){
4169       W_L("float:");
4170       W_V(css_float);
4171       W_L(";");
4172     }
4173     if(css_valign){
4174       W_L("vertical-align:");
4175       W_V(css_valign);
4176       W_L(";");
4177     }
4178     if (attr_hspace) {
4179       W_L("margin-left:");
4180       W_V(attr_hspace);
4181       W_L(";");
4182       W_L("margin-right:");
4183       W_V(attr_hspace);
4184       W_L(";");
4185     }
4186     else{
4187       if(css_margin_left){
4188         W_L("margin-left:");
4189         W_V(css_margin_left);
4190         W_L(";");
4191       }
4192       if(css_margin_right){
4193         W_L("margin-right:");
4194         W_V(css_margin_right);
4195         W_L(";");
4196       }
4197     }
4198     if (attr_vspace) {
4199       W_L("margin-top:");
4200       W_V(attr_vspace);
4201       W_L(";");
4202       W_L("margin-bottom:");
4203       W_V(attr_vspace);
4204       W_L(";");
4205     }
4206     else{
4207       if(css_margin_top){
4208         W_L("margin-top:");
4209         W_V(css_margin_top);
4210         W_L(";");
4211       }
4212       if(css_margin_bottom){
4213         W_L("margin-bottom:");
4214         W_V(css_margin_bottom);
4215         W_L(";");
4216       }
4217     }
4218     if(css_display){
4219       W_L("display:none;");
4220     }
4221     W_L("\"");
4222   }
4223   
4224   if (attr_width) {
4225     W_L(" width=\"");
4226     W_V(attr_width);
4227     W_L("\"");
4228   }
4229   if (attr_height) {
4230     W_L(" height=\"");
4231     W_V(attr_height);
4232     W_L("\"");
4233   }
4234   if (attr_alt) {
4235     W_L(" alt=\"");
4236     W_V(attr_alt);
4237     W_L("\"");
4238   } 
4239   else {
4240     W_L(" alt=\"\"");
4241   }
4242   W_L(" />");
4243   return android->out;
4244 }
4245
4246
4247 /**
4248  * It is a handler who processes the IMG tag.
4249  *
4250  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4251  *                     destination is specified.
4252  * @param node   [i]   The IMG tag node is specified.
4253  * @return The conversion result is returned.
4254  */
4255 static char *
4256 s_android_end_img_tag(void *pdoc, Node *UNUSED(child)) 
4257 {
4258   android_t *android = GET_ANDROID(pdoc);
4259   return android->out;
4260 }
4261
4262
4263 /**
4264  * It is a handler who processes the SELECT tag.
4265  *
4266  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4267  *                     destination is specified.
4268  * @param node   [i]   The SELECT tag node is specified.
4269  * @return The conversion result is returned.
4270  */
4271 static char *
4272 s_android_start_select_tag(void *pdoc, Node *node)
4273 {
4274   android_t *android    = GET_ANDROID(pdoc);
4275   Doc     *doc      = android->doc;
4276   Attr    *attr;
4277   char    *size     = NULL;
4278   char    *name     = NULL;
4279   char    *multiple = NULL;
4280   char    *attr_style = NULL;
4281
4282   W_L("<select");
4283   for (attr = qs_get_attr(doc,node);
4284        attr;
4285        attr = qs_get_next_attr(doc,attr)) {
4286     char *nm  = qs_get_attr_name(doc,attr);
4287     char *val = qs_get_attr_value(doc,attr);
4288     if (STRCASEEQ('s','S',"size",nm)) {
4289       /*----------------------------------------------------------------------*/
4290       /* CHTML 1.0 version 2.0                                                */
4291       /*----------------------------------------------------------------------*/
4292       size = apr_pstrdup(doc->buf.pool, val);
4293     }
4294     else if (STRCASEEQ('s','S',"style",nm) && val && *val) {
4295       /*----------------------------------------------------------------------*/
4296       /* CHTML 1.0 version 2.0                                                */
4297       /*----------------------------------------------------------------------*/
4298       attr_style = apr_pstrdup(doc->buf.pool, val);
4299     }
4300     else if (STRCASEEQ('n','N',"name",nm)) {
4301       /*----------------------------------------------------------------------*/
4302       /* CHTML 1.0 version 2.0                                                */
4303       /*----------------------------------------------------------------------*/
4304       name = apr_pstrdup(doc->buf.pool, val);
4305     }
4306     else if (STRCASEEQ('m','M',"multiple", nm)) {
4307       /*----------------------------------------------------------------------*/
4308       /* CHTML 1.0 version 2.0                                                */
4309       /*----------------------------------------------------------------------*/
4310       multiple = apr_pstrdup(doc->buf.pool, val);
4311     }
4312   }
4313   if (size && *size) {
4314     W_L(" size=\"");
4315     W_V(size);
4316     W_L("\"");
4317   }
4318   if (name && *name) {
4319     W_L(" name=\"");
4320     W_V(name);
4321     W_L("\"");
4322   }
4323   if (multiple) {
4324     W_L(" multiple=\"multiple\"");
4325   }
4326   W_L(">");
4327
4328   if (IS_CSS_ON(android->entryp)) {
4329     s_android_nopush_and_get_now_style(pdoc, node, attr_style);
4330   }
4331
4332   return android->out;
4333 }
4334
4335
4336 /**
4337  * It is a handler who processes the SELECT tag.
4338  *
4339  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4340  *                     destination is specified.
4341  * @param node   [i]   The SELECT tag node is specified.
4342  * @return The conversion result is returned.
4343  */
4344 static char *
4345 s_android_end_select_tag(void *pdoc, Node *UNUSED(child))
4346 {
4347   android_t *android = GET_ANDROID(pdoc);
4348   Doc     *doc   = android->doc;
4349
4350   W_L("</select>");
4351   if (IS_CSS_ON(android->entryp)) {
4352     chxj_css_pop_prop_list(android->css_prop_stack);
4353   }
4354
4355   return android->out;
4356 }
4357
4358 /**
4359  * It is a handler who processes the OPTION tag.
4360  *
4361  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4362  *                     destination is specified.
4363  * @param node   [i]   The OPTION tag node is specified.
4364  * @return The conversion result is returned.
4365  */
4366 static char *
4367 s_android_start_option_tag(void *pdoc, Node *node)
4368 {
4369   android_t *android = GET_ANDROID(pdoc);
4370   Doc     *doc   = android->doc;
4371   Attr    *attr;
4372
4373   char *selected   = NULL;
4374   char *value      = NULL;
4375   char *attr_style = NULL;
4376
4377   W_L("<option");
4378   for (attr = qs_get_attr(doc,node);
4379        attr;
4380        attr = qs_get_next_attr(doc,attr)) {
4381     char *nm  = qs_get_attr_name(doc,attr);
4382     char *val = qs_get_attr_value(doc,attr);
4383     if (STRCASEEQ('s','S',"selected",nm)) {
4384       /*----------------------------------------------------------------------*/
4385       /* CHTML 1.0 version 2.0                                                */
4386       /*----------------------------------------------------------------------*/
4387       selected = apr_pstrdup(doc->buf.pool, val);
4388     }
4389     else if (STRCASEEQ('s','S',"style",nm) && val && *val) {
4390       /*----------------------------------------------------------------------*/
4391       /* CHTML 1.0 version 2.0                                                */
4392       /*----------------------------------------------------------------------*/
4393       attr_style = apr_pstrdup(doc->buf.pool, val);
4394     }
4395     else if (STRCASEEQ('v','V',"value",nm)) {
4396       /*----------------------------------------------------------------------*/
4397       /* CHTML 1.0 version 2.0                                                */
4398       /*----------------------------------------------------------------------*/
4399       value = apr_pstrdup(doc->buf.pool, val);
4400     }
4401   }
4402   if (value) {
4403     W_L(" value=\"");
4404     W_V(value);
4405     W_L("\"");
4406   }
4407   if (selected) {
4408     W_L(" selected=\"selected\"");
4409   }
4410   W_L(">");
4411
4412   if (IS_CSS_ON(android->entryp)) {
4413     s_android_nopush_and_get_now_style(pdoc, node, attr_style);
4414   }
4415
4416   return android->out;
4417 }
4418
4419
4420 /**
4421  * It is a handler who processes the OPTION tag.
4422  *
4423  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4424  *                     destination is specified.
4425  * @param node   [i]   The OPTION tag node is specified.
4426  * @return The conversion result is returned.
4427  */
4428 static char *
4429 s_android_end_option_tag(void *pdoc, Node *UNUSED(child))
4430 {
4431   android_t *android = GET_ANDROID(pdoc);
4432   Doc      *doc = android->doc;
4433
4434   W_L("</option>");
4435   if (IS_CSS_ON(android->entryp)) {
4436     chxj_css_pop_prop_list(android->css_prop_stack);
4437   }
4438
4439   return android->out;
4440 }
4441
4442
4443 /**
4444  * It is a handler who processes the DIV tag.
4445  *
4446  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4447  *                     destination is specified.
4448  * @param node   [i]   The DIV tag node is specified.
4449  * @return The conversion result is returned.
4450  */
4451 static char *
4452 s_android_start_div_tag(void *pdoc, Node *node)
4453 {
4454   android_t    *android;
4455   Doc         *doc;
4456   request_rec *r;
4457   Attr        *attr;
4458   char        *attr_style             = NULL;
4459   char        *attr_align             = NULL;
4460   char        *attr_display           = NULL;
4461   char        *attr_decoration        = NULL;
4462   char        *attr_wap_marquee_style = NULL;
4463   char        *attr_wap_marquee_dir   = NULL;
4464   char        *attr_wap_marquee_loop  = NULL;
4465   char        *attr_wap_marquee_speed = NULL;
4466   char        *attr_color             = NULL;
4467   char        *attr_bgcolor           = NULL;
4468   char        *attr_font_size         = NULL;
4469   char        *css_clear              = NULL;
4470
4471   android = GET_ANDROID(pdoc);
4472   doc   = android->doc;
4473   r     = doc->r;
4474
4475   for (attr = qs_get_attr(doc,node);
4476        attr;
4477        attr = qs_get_next_attr(doc,attr)) {
4478     char *nm  = qs_get_attr_name(doc,attr);
4479     char *val = qs_get_attr_value(doc,attr);
4480     if (STRCASEEQ('a','A',"align",nm)) {
4481       /*----------------------------------------------------------------------*/
4482       /* CHTML 1.0 (W3C version 3.2)                                          */
4483       /*----------------------------------------------------------------------*/
4484       if (val && (STRCASEEQ('l','L',"left",val) || STRCASEEQ('r','R',"right",val) || STRCASEEQ('c','C',"center",val))) {
4485         attr_align = apr_pstrdup(doc->buf.pool, val);
4486       }
4487     }
4488     else if (STRCASEEQ('s','S',"style",nm) && val && *val) {
4489       attr_style = apr_pstrdup(doc->buf.pool, val);
4490     }
4491   }
4492
4493   if (IS_CSS_ON(android->entryp)) {
4494     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
4495     if (style) {
4496       css_property_t *display_prop           = chxj_css_get_property_value(doc, style, "display");
4497       css_property_t *text_decoration_prop   = chxj_css_get_property_value(doc, style, "text-decoration");
4498       css_property_t *color_prop             = chxj_css_get_property_value(doc, style, "color");
4499       css_property_t *text_align_prop        = chxj_css_get_property_value(doc, style, "text-align");
4500       css_property_t *font_size_prop         = chxj_css_get_property_value(doc, style, "font-size");
4501       css_property_t *background_color_prop  = chxj_css_get_property_value(doc, style, "background-color");
4502       css_property_t *background_prop        = chxj_css_get_property_value(doc, style, "background");
4503       css_property_t *clear_prop             = chxj_css_get_property_value(doc, style, "clear");
4504
4505       css_property_t *cur;
4506       for (cur = display_prop->next; cur != display_prop; cur = cur->next) {
4507         if (strcasecmp("-wap-marquee", cur->value) == 0) {
4508           attr_display = apr_pstrdup(doc->pool, cur->value);
4509         }
4510       }
4511       for (cur = text_decoration_prop->next; cur != text_decoration_prop; cur = cur->next) {
4512         if (STRCASEEQ('b','B',"blink", cur->value)) {
4513           attr_decoration = apr_pstrdup(doc->pool, cur->value);
4514         }
4515       }
4516       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
4517         attr_color = apr_pstrdup(doc->pool, cur->value);
4518       }
4519       for (cur = background_color_prop->next; cur != background_color_prop; cur = cur->next) {
4520         attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
4521         attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
4522       }
4523       for (cur = background_prop->next; cur != background_prop; cur = cur->next) {
4524         char *ss = strchr(cur->value, '#');
4525         if (!ss || !*ss) {
4526           ss = strstr(cur->value, "rgb");
4527         }
4528         if (ss && *ss) {
4529           attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
4530           attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
4531         }
4532       }
4533       for (cur = text_align_prop->next; cur != text_align_prop; cur = cur->next) {
4534         attr_align = apr_pstrdup(doc->pool, cur->value);
4535       }
4536       for (cur = font_size_prop->next; cur != font_size_prop; cur = cur->next) {
4537         if (   STRCASEEQ('x','X',"xx-small",cur->value)
4538             || STRCASEEQ('x','X',"x-small",cur->value)
4539             || STRCASEEQ('s','S',"small",cur->value)
4540             || STRCASEEQ('m','M',"medium",cur->value)
4541             || STRCASEEQ('l','L',"large",cur->value)
4542             || STRCASEEQ('x','X',"x-large",cur->value)
4543             || STRCASEEQ('x','X',"xx-large",cur->value)) {
4544           attr_font_size = apr_pstrdup(doc->pool, cur->value);
4545         }
4546       }
4547       if (attr_display) {
4548         css_property_t *wap_marquee_style_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-style");
4549         css_property_t *wap_marquee_dir_prop   = chxj_css_get_property_value(doc, style, "-wap-marquee-dir");
4550         css_property_t *wap_marquee_loop_prop  = chxj_css_get_property_value(doc, style, "-wap-marquee-loop");
4551         css_property_t *wap_marquee_speed_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-speed");
4552         for (cur = wap_marquee_style_prop->next; cur != wap_marquee_style_prop; cur = cur->next) {
4553           if (STRCASEEQ('s','S',"scroll", cur->value) || STRCASEEQ('s','S',"slide",cur->value) || STRCASEEQ('a','A',"alternate",cur->value)) {
4554             attr_wap_marquee_style = apr_pstrdup(doc->pool, cur->value);
4555           }
4556         }
4557         for (cur = wap_marquee_dir_prop->next; cur != wap_marquee_dir_prop; cur = cur->next) {
4558           if (STRCASEEQ('l','L',"ltr",cur->value)) {
4559             attr_wap_marquee_dir = apr_pstrdup(doc->pool, cur->value);
4560           }
4561           else if (STRCASEEQ('r','R',"rtl",cur->value)) {
4562             attr_wap_marquee_dir = apr_pstrdup(doc->pool, cur->value);
4563           }
4564         }
4565         for (cur = wap_marquee_loop_prop->next; cur != wap_marquee_loop_prop; cur = cur->next) {
4566           if(strcmp(cur->value,"0") == 0 || strcmp(cur->value,"-1") == 0){
4567             attr_wap_marquee_loop = "infinite";
4568           }
4569           else{
4570             attr_wap_marquee_loop = apr_pstrdup(doc->pool, cur->value);
4571           }
4572         }
4573         for (cur = wap_marquee_speed_prop->next; cur != wap_marquee_speed_prop; cur = cur->next) {
4574           attr_wap_marquee_speed = apr_pstrdup(doc->pool, cur->value);
4575         }
4576       }
4577       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
4578         css_clear = apr_pstrdup(doc->pool, cur->value);
4579       }
4580     }
4581   }  
4582   W_L("<div");
4583   if (attr_align
4584       || attr_display
4585       || attr_decoration
4586       || attr_wap_marquee_style
4587       || attr_wap_marquee_dir
4588       || attr_wap_marquee_loop
4589       || attr_wap_marquee_speed
4590       || attr_color
4591       || attr_bgcolor
4592       || attr_font_size
4593       || css_clear ) {
4594     W_L(" style=\"");
4595     if (attr_align) {
4596       W_L("text-align:");
4597       W_V(attr_align);
4598       W_L(";");
4599     }
4600     if (attr_display) {
4601       /* only marquee */
4602       W_L("overflow:-webkit-marquee;");
4603     }
4604     if (attr_decoration) {
4605       if (STRCASEEQ('b','B',"blink",attr_decoration)) {
4606         W_L(STYLE_BLINK);
4607         if (android->blink_keyframe_out == 0) {
4608           android->style_data = apr_pstrcat(doc->pool, (android->style_data) ? android->style_data : "",
4609                                                       BLINK_KEYFRAME,
4610                                                       NULL);
4611           android->blink_keyframe_out = 1;
4612         }
4613       }
4614       else {
4615         W_L("text-decoration:");
4616         W_V(attr_decoration);
4617         W_L(";");
4618       }
4619     }
4620     if (attr_wap_marquee_style) {
4621       W_L("-webkit-marquee-style:");
4622       W_V(attr_wap_marquee_style);
4623       W_L(";");
4624     }
4625     if (attr_wap_marquee_dir) {
4626       W_L("-webkit-marquee-direction:");
4627       if (STRCASEEQ('r','R',"rtl",attr_wap_marquee_dir)) {
4628         W_L("left");
4629       }
4630       else if (STRCASEEQ('l','L',"ltr",attr_wap_marquee_dir)) {
4631         W_L("right");
4632       }
4633       W_L(";");
4634     }
4635     if (attr_wap_marquee_loop) {
4636       W_L("-webkit-marquee-repetition:");
4637       W_V(attr_wap_marquee_loop);
4638       W_L(";");
4639     }
4640     if (attr_wap_marquee_speed) {
4641       W_L("-webkit-marquee-speed:");
4642       W_V(attr_wap_marquee_speed);
4643       W_L(";");
4644     }
4645     if (attr_color) {
4646       W_L("color:");
4647       W_V(attr_color);
4648       W_L(";");
4649     }
4650     if (attr_bgcolor) {
4651       W_L("background-color:");
4652       W_V(attr_bgcolor);
4653       W_L(";");
4654     }
4655     if (attr_font_size) {
4656       W_L("font-size:");
4657       W_V(attr_font_size);
4658       W_L(";");
4659     }
4660     if (css_clear){
4661       W_L("clear:");
4662       W_V(css_clear);
4663       W_L(";");
4664     }
4665     W_L("\"");
4666   }
4667   W_L(">");
4668   return android->out;
4669 }
4670
4671
4672 /**
4673  * It is a handler who processes the DIV tag.
4674  *
4675  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4676  *                     destination is specified.
4677  * @param node   [i]   The DIV tag node is specified.
4678  * @return The conversion result is returned.
4679  */
4680 static char *
4681 s_android_end_div_tag(void *pdoc, Node *UNUSED(child))
4682 {
4683   android_t      *android;
4684   Doc          *doc;
4685   request_rec  *r;
4686
4687   android = GET_ANDROID(pdoc);
4688   doc   = android->doc;
4689   r     = doc->r;
4690
4691   W_L("</div>");
4692   if (IS_CSS_ON(android->entryp)) {
4693     chxj_css_pop_prop_list(android->css_prop_stack);
4694   }
4695   return android->out;
4696 }
4697
4698
4699 static char *
4700 s_android_chxjif_tag(void *pdoc, Node *node)
4701 {
4702   android_t *android;
4703   Doc     *doc;
4704   Node    *child;
4705   request_rec *r;
4706
4707   android = GET_ANDROID(pdoc);
4708   doc   = android->doc;
4709   r     = doc->r;
4710
4711   for (child = qs_get_child_node(doc, node);
4712        child;
4713        child = qs_get_next_node(doc, child)) {
4714     W_V(child->otext);
4715     s_android_chxjif_tag(android, child);
4716   }
4717   return NULL;
4718 }
4719
4720
4721 /**
4722  * It is a handler who processes the TEXTARE tag.
4723  *
4724  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4725  *                     destination is specified.
4726  * @param node   [i]   The TEXTAREA tag node is specified.
4727  * @return The conversion result is returned.
4728  */
4729 static char *
4730 s_android_start_textarea_tag(void *pdoc, Node *node) 
4731 {
4732   android_t      *android;
4733   Doc           *doc;
4734   request_rec   *r;
4735   Attr          *attr;
4736   char          *attr_accesskey = NULL;
4737   char          *attr_name      = NULL;
4738   char          *attr_rows      = NULL;
4739   char          *attr_cols      = NULL;
4740   char          *attr_istyle    = NULL;
4741   char          *attr_style     = NULL;
4742
4743
4744   android = GET_ANDROID(pdoc);
4745   doc   = android->doc;
4746   r     = doc->r;
4747
4748   android->textarea_flag++;
4749   for (attr = qs_get_attr(doc,node);
4750        attr;
4751        attr = qs_get_next_attr(doc,attr)) {
4752     char *name  = qs_get_attr_name(doc,attr);
4753     char *value = qs_get_attr_value(doc,attr);
4754     if (STRCASEEQ('a','A',"accesskey",name) && value && *value != 0) {
4755       attr_accesskey = value;
4756     }
4757     else if (STRCASEEQ('i','I',"istyle", name) && value && (*value == '1' || *value == '2' || *value == '3' || *value == '4')) {
4758       attr_istyle = value;
4759     }
4760     else if (STRCASEEQ('n','N',"name", name) && value && *value) {
4761       attr_name = value;
4762     }
4763     else if (STRCASEEQ('r','R',"rows", name) && value && *value) {
4764       attr_rows = value;
4765     }
4766     else if (STRCASEEQ('c','C',"cols", name) && value && *value) {
4767       attr_cols = value;
4768     }
4769     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
4770       attr_style = value;
4771     }
4772   }
4773   if (IS_CSS_ON(android->entryp)) {
4774     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
4775     if (style) {
4776       css_property_t *wap_input_format = chxj_css_get_property_value(doc, style, "-wap-input-format");
4777       css_property_t *cur;
4778       for (cur = wap_input_format->next; cur != wap_input_format; cur = cur->next) {
4779         if (strcasestr(cur->value, "<ja:n>")) {
4780           attr_istyle = "4";
4781         }
4782         else if (strcasestr(cur->value, "<ja:en>")) {
4783           attr_istyle = "3";
4784         }
4785         else if (strcasestr(cur->value, "<ja:hk>")) {
4786           attr_istyle = "2";
4787         }
4788         else if (strcasestr(cur->value, "<ja:h>")) {
4789           attr_istyle = "1";
4790         }
4791       }
4792     }
4793   }
4794   W_L("<textarea");
4795   if (attr_name) {
4796     W_L(" name=\"");
4797     W_V(attr_name);
4798     W_L("\"");
4799   }
4800   if (attr_rows) {
4801     W_L(" rows=\"");
4802     W_V(attr_rows);
4803     W_L("\"");
4804   }
4805   if (attr_cols) {
4806     W_L(" cols=\"");
4807     W_V(attr_cols);
4808     W_L("\"");
4809   }
4810   W_L(">");
4811   return android->out;
4812 }
4813
4814
4815 /**
4816  * It is a handler who processes the TEXTAREA tag.
4817  *
4818  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4819  *                     destination is specified.
4820  * @param node   [i]   The TEXTAREA tag node is specified.
4821  * @return The conversion result is returned.
4822  */
4823 static char *
4824 s_android_end_textarea_tag(void *pdoc, Node *UNUSED(child)) 
4825 {
4826   android_t       *android;
4827   Doc           *doc;
4828   request_rec   *r;
4829
4830   android = GET_ANDROID(pdoc);
4831   doc   = android->doc;
4832   r     = doc->r;
4833
4834   W_L("</textarea>");
4835   android->textarea_flag--;
4836
4837   return android->out;
4838 }
4839
4840
4841 /**
4842  * It is a handler who processes the B tag.
4843  *
4844  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4845  *                     destination is specified.
4846  * @param node   [i]   The B tag node is specified.
4847  * @return The conversion result is returned.
4848  */
4849 static char*
4850 s_android_start_b_tag(void* pdoc, Node* UNUSED(node)) 
4851 {
4852   android_t*      android;
4853   Doc*          doc;
4854   request_rec*  r;
4855
4856   android = GET_ANDROID(pdoc);
4857   doc   = android->doc;
4858   r     = doc->r;
4859
4860   W_L("<b>");
4861   return android->out;
4862 }
4863
4864
4865 /**
4866  * It is a handler who processes the B tag.
4867  *
4868  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4869  *                     destination is specified.
4870  * @param node   [i]   The B tag node is specified.
4871  * @return The conversion result is returned.
4872  */
4873 static char*
4874 s_android_end_b_tag(void* pdoc, Node* UNUSED(child)) 
4875 {
4876   android_t*      android = GET_ANDROID(pdoc);
4877   Doc*          doc   = android->doc;
4878
4879   W_L("</b>");
4880   return android->out;
4881 }
4882
4883 static char*
4884 s_android_text_tag(void* pdoc, Node* child)
4885 {
4886   android_t*     android;
4887   Doc*         doc;
4888   char*        textval;
4889   char*        tmp;
4890   char*        tdst;
4891   char         one_byte[2];
4892   int          ii;
4893   int          tdst_len;
4894   request_rec* r;
4895   apr_size_t   z2h_input_len;
4896
4897   android = GET_ANDROID(pdoc);
4898   doc   = android->doc;
4899   r     = doc->r;
4900
4901   textval = qs_get_node_value(doc,child);
4902   if (strlen(textval) == 0) {
4903     return android->out;
4904   }
4905
4906   tmp = apr_palloc(r->pool, qs_get_node_size(doc,child)+1);
4907   memset(tmp, 0, qs_get_node_size(doc,child)+1);
4908
4909   tdst     = qs_alloc_zero_byte_string(doc->buf.pool);
4910   memset(one_byte, 0, sizeof(one_byte));
4911   tdst_len = 0;
4912
4913   for (ii=0; ii<qs_get_node_size(doc,child); ii++) {
4914     char* out;
4915     int rtn = s_android_search_emoji(android, &textval[ii], &out);
4916     if (rtn) {
4917       tdst = qs_out_apr_pstrcat(r, tdst, out, &tdst_len);
4918       ii+=(rtn - 1);
4919       continue;
4920     }
4921
4922     if (is_sjis_kanji(textval[ii])) {
4923       one_byte[0] = textval[ii+0];
4924       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
4925       one_byte[0] = textval[ii+1];
4926       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
4927       ii++;
4928     }
4929     else 
4930     if (android->pre_flag) {
4931       one_byte[0] = textval[ii+0];
4932       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
4933     }
4934     else
4935     if (android->textarea_flag) {
4936       one_byte[0] = textval[ii+0];
4937       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
4938     }
4939     else {
4940       if (textval[ii] != '\r' && textval[ii] != '\n') {
4941         one_byte[0] = textval[ii+0];
4942         tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
4943       }
4944     }
4945   }
4946   z2h_input_len = strlen(tdst);
4947   tdst = chxj_conv_z2h(r, tdst, &z2h_input_len, android->entryp);
4948
4949   W_V(tdst);
4950   return android->out;
4951 }
4952
4953
4954 /**
4955  * It is a handler who processes the BLOCKQUOTE tag.
4956  *
4957  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4958  *                     destination is specified.
4959  * @param node   [i]   The BLOCKQUOTE tag node is specified.
4960  * @return The conversion result is returned.
4961  */
4962 static char *
4963 s_android_start_blockquote_tag(void *pdoc, Node *node)
4964 {
4965   android_t *android;
4966   Doc      *doc;
4967   Attr     *attr;
4968   char     *attr_style = NULL;
4969   char     *attr_color = NULL;
4970   char     *attr_size  = NULL;
4971   char     *css_clear  = NULL;
4972
4973   android  = GET_ANDROID(pdoc);
4974   doc     = android->doc;
4975   for (attr = qs_get_attr(doc,node);
4976        attr;
4977        attr = qs_get_next_attr(doc,attr)) {
4978     char *nm  = qs_get_attr_name(doc,attr);
4979     char *val = qs_get_attr_value(doc,attr);
4980     if (val && STRCASEEQ('s','S',"style", nm)) {
4981       attr_style = val;
4982     }
4983   }
4984   if (IS_CSS_ON(android->entryp)) {
4985     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
4986     if (style) {
4987       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
4988       css_property_t *font_size_prop = chxj_css_get_property_value(doc, style, "font-size");
4989       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
4990       
4991       css_property_t *cur;
4992       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
4993         if (cur->value && *cur->value) {
4994           attr_color = apr_pstrdup(doc->pool, cur->value);
4995         }
4996       }
4997       for (cur = font_size_prop->next; cur != font_size_prop; cur = cur->next) {
4998         if (cur->value && *cur->value) {
4999           if (STRCASEEQ('x','X',"xx-small",cur->value)) {
5000             attr_size = apr_pstrdup(doc->pool, cur->value);
5001           }
5002           else if (STRCASEEQ('x','X',"x-small",cur->value)) {
5003             attr_size = apr_pstrdup(doc->pool, cur->value);
5004           }
5005           else if (STRCASEEQ('s','S',"small",cur->value)) {
5006             attr_size = apr_pstrdup(doc->pool, cur->value);
5007           }
5008           else if (STRCASEEQ('m','M',"medium",cur->value)) {
5009             attr_size = apr_pstrdup(doc->pool, cur->value);
5010           }
5011           else if (STRCASEEQ('l','L',"large",cur->value)) {
5012             attr_size = apr_pstrdup(doc->pool, cur->value);
5013           }
5014           else if (STRCASEEQ('x','X',"x-large",cur->value)) {
5015             attr_size = apr_pstrdup(doc->pool, cur->value);
5016           }
5017           else if (STRCASEEQ('x','X',"xx-large",cur->value)) {
5018             attr_size = apr_pstrdup(doc->pool, cur->value);
5019           }
5020         }
5021       }
5022       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
5023         css_clear = apr_pstrdup(doc->pool, cur->value);
5024       }
5025     }
5026   }
5027   W_L("<blockquote");
5028   if (attr_color || attr_size || css_clear) {
5029     W_L(" style=\"");
5030     if (attr_color) {
5031       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
5032       W_L("color:");
5033       W_V(attr_color);
5034       W_L(";");
5035     }
5036     if (attr_size) {
5037       W_L("font-size:");
5038       W_V(attr_size);
5039       W_L(";");
5040     }
5041     if (css_clear){
5042       W_L("clear:");
5043       W_V(css_clear);
5044       W_L(";");
5045     }
5046     W_L("\"");
5047   }
5048   W_L(">");
5049   return android->out;
5050 }
5051
5052
5053 /**
5054  * It is a handler who processes the BLOCKQUOTE tag.
5055  *
5056  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5057  *                     destination is specified.
5058  * @param node   [i]   The BLOCKQUOTE tag node is specified.
5059  * @return The conversion result is returned.
5060  */
5061 static char *
5062 s_android_end_blockquote_tag(void *pdoc, Node *UNUSED(child))
5063 {
5064   android_t *android = GET_ANDROID(pdoc);
5065   Doc     *doc   = android->doc;
5066   W_L("</blockquote>");
5067   if (IS_CSS_ON(android->entryp)) {
5068     chxj_css_pop_prop_list(android->css_prop_stack);
5069   }
5070   return android->out;
5071 }
5072
5073
5074 /**
5075  * It is a handler who processes the DIR tag.
5076  *
5077  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5078  *                     destination is specified.
5079  * @param node   [i]   The DIR tag node is specified.
5080  * @return The conversion result is returned.
5081  */
5082 static char *
5083 s_android_start_dir_tag(void *pdoc, Node *node)
5084 {
5085   android_t *android      = GET_ANDROID(pdoc);
5086   Doc       *doc        = android->doc;
5087   Attr      *attr;
5088   char      *attr_style = NULL;
5089   char      *attr_color = NULL;
5090   char      *attr_type  = NULL;
5091   char      *attr_size  = NULL;
5092   for (attr = qs_get_attr(doc,node);
5093        attr;
5094        attr = qs_get_next_attr(doc,attr)) {
5095     char *name   = qs_get_attr_name(doc,attr);
5096     char *value  = qs_get_attr_value(doc,attr);
5097     if (STRCASEEQ('t','T',"type",name)) {
5098       if (value && (STRCASEEQ('d','D',"disc",value) || STRCASEEQ('c','C',"circle",value) || STRCASEEQ('s','S',"square",value))) {
5099         attr_type = value;
5100       }
5101     }
5102     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
5103       attr_style = value;
5104     }
5105   }
5106   if (IS_CSS_ON(android->entryp)) {
5107     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
5108     if (style) {
5109       css_property_t *color_prop           = chxj_css_get_property_value(doc, style, "color");
5110       css_property_t *size_prop            = chxj_css_get_property_value(doc, style, "font-size");
5111       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type");
5112       css_property_t *cur;
5113       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
5114         if (cur->value && *cur->value) {
5115           attr_color = apr_pstrdup(doc->pool, cur->value);
5116         }
5117       }
5118       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
5119         if (cur->value && *cur->value) {
5120           attr_type = apr_pstrdup(doc->pool, cur->value);
5121         }
5122       }
5123       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
5124         if (cur->value && *cur->value) {
5125           if (STRCASEEQ('x','X',"xx-small",cur->value)) {
5126             attr_size = apr_pstrdup(doc->pool, cur->value);
5127           }
5128           else if (STRCASEEQ('x','X',"x-small",cur->value)) {
5129             attr_size = apr_pstrdup(doc->pool, cur->value);
5130           }
5131           else if (STRCASEEQ('s','S',"small",cur->value)) {
5132             attr_size = apr_pstrdup(doc->pool, cur->value);
5133           }
5134           else if (STRCASEEQ('m','M',"medium",cur->value)) {
5135             attr_size = apr_pstrdup(doc->pool, cur->value);
5136           }
5137           else if (STRCASEEQ('l','L',"large",cur->value)) {
5138             attr_size = apr_pstrdup(doc->pool, cur->value);
5139           }
5140           else if (STRCASEEQ('x','X',"x-large",cur->value)) {
5141             attr_size = apr_pstrdup(doc->pool, cur->value);
5142           }
5143           else if (STRCASEEQ('x','X',"xx-large",cur->value)) {
5144             attr_size = apr_pstrdup(doc->pool, cur->value);
5145           }
5146         }
5147       }
5148     }
5149   }
5150   W_L("<dir");
5151   if (attr_type || attr_color || attr_size) {
5152     W_L(" style=\"");
5153     if (attr_type) {
5154       W_L("list-style-type:");
5155       W_V(attr_type);
5156       W_L(";");
5157     }
5158     if (attr_color) {
5159       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
5160       W_L("color:");
5161       W_V(attr_color);
5162       W_L(";");
5163     }
5164     if (attr_size) {
5165       W_L("font-size:");
5166       W_V(attr_size);
5167       W_L(";");
5168     }
5169     W_L("\"");
5170   }
5171   W_L(">");
5172   return android->out;
5173 }
5174
5175
5176 /**
5177  * It is a handler who processes the DIR tag.
5178  *
5179  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5180  *                     destination is specified.
5181  * @param node   [i]   The DIR tag node is specified.
5182  * @return The conversion result is returned.
5183  */
5184 static char *
5185 s_android_end_dir_tag(void *pdoc, Node *UNUSED(child))
5186 {
5187   android_t *android = GET_ANDROID(pdoc);
5188   Doc *doc = android->doc;
5189   W_L("</dir>");
5190   if (IS_CSS_ON(android->entryp)) {
5191     chxj_css_pop_prop_list(android->css_prop_stack);
5192   }
5193   return android->out;
5194 }
5195
5196
5197 /**
5198  * It is a handler who processes the DL tag.
5199  *
5200  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5201  *                     destination is specified.
5202  * @param node   [i]   The DL tag node is specified.
5203  * @return The conversion result is returned.
5204  */
5205 static char *
5206 s_android_start_dl_tag(void *pdoc, Node *node)
5207 {
5208   android_t *android      = GET_ANDROID(pdoc);
5209   Doc       *doc        = android->doc;
5210   Attr      *attr;
5211   char      *attr_style = NULL;
5212   char      *attr_color = NULL;
5213   char      *attr_size  = NULL;
5214   char      *css_clear  = NULL;
5215   
5216   for (attr = qs_get_attr(doc,node);
5217        attr;
5218        attr = qs_get_next_attr(doc,attr)) {
5219     char *name   = qs_get_attr_name(doc,attr);
5220     char *value  = qs_get_attr_value(doc,attr);
5221     if (STRCASEEQ('s','S',"style", name) && value && *value) {
5222       attr_style = value;
5223     }
5224   }
5225   if (IS_CSS_ON(android->entryp)) {
5226     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
5227     if (style) {
5228       css_property_t *color_prop           = chxj_css_get_property_value(doc, style, "color");
5229       css_property_t *size_prop            = chxj_css_get_property_value(doc, style, "font-size");
5230       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
5231       
5232       css_property_t *cur;
5233       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
5234         if (cur->value && *cur->value) {
5235           attr_color = apr_pstrdup(doc->pool, cur->value);
5236         }
5237       }
5238       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
5239         if (cur->value && *cur->value) {
5240           if (STRCASEEQ('x','X',"xx-small",cur->value)) {
5241             attr_size = apr_pstrdup(doc->pool, cur->value);
5242           }
5243           else if (STRCASEEQ('x','X',"x-small",cur->value)) {
5244             attr_size = apr_pstrdup(doc->pool, cur->value);
5245           }
5246           else if (STRCASEEQ('s','S',"small",cur->value)) {
5247             attr_size = apr_pstrdup(doc->pool, cur->value);
5248           }
5249           else if (STRCASEEQ('m','M',"medium",cur->value)) {
5250             attr_size = apr_pstrdup(doc->pool, cur->value);
5251           }
5252           else if (STRCASEEQ('l','L',"large",cur->value)) {
5253             attr_size = apr_pstrdup(doc->pool, cur->value);
5254           }
5255           else if (STRCASEEQ('x','X',"x-large",cur->value)) {
5256             attr_size = apr_pstrdup(doc->pool, cur->value);
5257           }
5258           else if (STRCASEEQ('x','X',"xx-large",cur->value)) {
5259             attr_size = apr_pstrdup(doc->pool, cur->value);
5260           }
5261         }
5262       }
5263       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
5264         css_clear = apr_pstrdup(doc->pool, cur->value);
5265       }
5266     }
5267   }
5268   W_L("<dl");
5269   if (attr_color || attr_size || css_clear) {
5270     W_L(" style=\"");
5271     if (attr_color) {
5272       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
5273       W_L("color:");
5274       W_V(attr_color);
5275       W_L(";");
5276     }
5277     if (attr_size) {
5278       W_L("font-size:");
5279       W_V(attr_size);
5280       W_L(";");
5281     }
5282     if (css_clear){
5283       W_L("clear:");
5284       W_V(css_clear);
5285       W_L(";");
5286     }
5287     W_L("\"");
5288   }
5289   W_L(">");
5290   return android->out;
5291 }
5292
5293
5294 /**
5295  * It is a handler who processes the DL tag.
5296  *
5297  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5298  *                     destination is specified.
5299  * @param node   [i]   The DL tag node is specified.
5300  * @return The conversion result is returned.
5301  */
5302 static char *
5303 s_android_end_dl_tag(void *pdoc, Node *UNUSED(child))
5304 {
5305   android_t *android = GET_ANDROID(pdoc);
5306   Doc *doc = android->doc;
5307   W_L("</dl>");
5308   if (IS_CSS_ON(android->entryp)) {
5309     chxj_css_pop_prop_list(android->css_prop_stack);
5310   }
5311   return android->out;
5312 }
5313
5314
5315 /**
5316  * It is a handler who processes the DT tag.
5317  *
5318  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5319  *                     destination is specified.
5320  * @param node   [i]   The DT tag node is specified.
5321  * @return The conversion result is returned.
5322  */
5323 static char *
5324 s_android_start_dt_tag(void *pdoc, Node *node)
5325 {
5326   android_t *android      = GET_ANDROID(pdoc);
5327   Doc       *doc        = android->doc;
5328   Attr      *attr;
5329   char      *attr_style = NULL;
5330   char      *attr_color = NULL;
5331   char      *attr_size  = NULL;
5332   for (attr = qs_get_attr(doc,node);
5333        attr;
5334        attr = qs_get_next_attr(doc,attr)) {
5335     char *name   = qs_get_attr_name(doc,attr);
5336     char *value  = qs_get_attr_value(doc,attr);
5337     if (STRCASEEQ('s','S',"style", name) && value && *value) {
5338       attr_style = value;
5339     }
5340   }
5341   if (IS_CSS_ON(android->entryp)) {
5342     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
5343     if (style) {
5344       css_property_t *color_prop           = chxj_css_get_property_value(doc, style, "color");
5345       css_property_t *size_prop            = chxj_css_get_property_value(doc, style, "font-size");
5346       css_property_t *cur;
5347       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
5348         if (cur->value && *cur->value) {
5349           attr_color = apr_pstrdup(doc->pool, cur->value);
5350         }
5351       }
5352       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
5353         if (cur->value && *cur->value) {
5354           if (STRCASEEQ('x','X',"xx-small",cur->value)) {
5355             attr_size = apr_pstrdup(doc->pool, cur->value);
5356           }
5357           else if (STRCASEEQ('x','X',"x-small",cur->value)) {
5358             attr_size = apr_pstrdup(doc->pool, cur->value);
5359           }
5360           else if (STRCASEEQ('s','S',"small",cur->value)) {
5361             attr_size = apr_pstrdup(doc->pool, cur->value);
5362           }
5363           else if (STRCASEEQ('m','M',"medium",cur->value)) {
5364             attr_size = apr_pstrdup(doc->pool, cur->value);
5365           }
5366           else if (STRCASEEQ('l','L',"large",cur->value)) {
5367             attr_size = apr_pstrdup(doc->pool, cur->value);
5368           }
5369           else if (STRCASEEQ('x','X',"x-large",cur->value)) {
5370             attr_size = apr_pstrdup(doc->pool, cur->value);
5371           }
5372           else if (STRCASEEQ('x','X',"xx-large",cur->value)) {
5373             attr_size = apr_pstrdup(doc->pool, cur->value);
5374           }
5375         }
5376       }
5377     }
5378   }
5379   W_L("<dt");
5380   if (attr_color || attr_size) {
5381     W_L(" style=\"");
5382     if (attr_color) {
5383       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
5384       W_L("color:");
5385       W_V(attr_color);
5386       W_L(";");
5387     }
5388     if (attr_size) {
5389       W_L("font-size:");
5390       W_V(attr_size);
5391       W_L(";");
5392     }
5393     W_L("\"");
5394   }
5395   W_L(">");
5396   return android->out;
5397 }
5398
5399
5400 /**
5401  * It is a handler who processes the DT tag.
5402  *
5403  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5404  *                     destination is specified.
5405  * @param node   [i]   The DT tag node is specified.
5406  * @return The conversion result is returned.
5407  */
5408 static char *
5409 s_android_end_dt_tag(void *pdoc, Node *UNUSED(child))
5410 {
5411   android_t *android = GET_ANDROID(pdoc);
5412   Doc      *doc    = android->doc;
5413   W_L("</dt>");
5414   if (IS_CSS_ON(android->entryp)) {
5415     chxj_css_pop_prop_list(android->css_prop_stack);
5416   }
5417   return android->out;
5418 }
5419
5420
5421 /**
5422  * It is a handler who processes the DD tag.
5423  *
5424  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5425  *                     destination is specified.
5426  * @param node   [i]   The DD tag node is specified.
5427  * @return The conversion result is returned.
5428  */
5429 static char *
5430 s_android_start_dd_tag(void *pdoc, Node *node)
5431 {
5432   android_t *android      = GET_ANDROID(pdoc);
5433   Doc       *doc        = android->doc;
5434   Attr      *attr;
5435   char      *attr_style = NULL;
5436   char      *attr_color = NULL;
5437   char      *attr_size  = NULL;
5438   for (attr = qs_get_attr(doc,node);
5439        attr;
5440        attr = qs_get_next_attr(doc,attr)) {
5441     char *name   = qs_get_attr_name(doc,attr);
5442     char *value  = qs_get_attr_value(doc,attr);
5443     if (STRCASEEQ('s','S',"style", name) && value && *value) {
5444       attr_style = value;
5445     }
5446   }
5447   if (IS_CSS_ON(android->entryp)) {
5448     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
5449     if (style) {
5450       css_property_t *color_prop           = chxj_css_get_property_value(doc, style, "color");
5451       css_property_t *size_prop            = chxj_css_get_property_value(doc, style, "font-size");
5452       css_property_t *cur;
5453       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
5454         if (cur->value && *cur->value) {
5455           attr_color = apr_pstrdup(doc->pool, cur->value);
5456         }
5457       }
5458       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
5459         if (cur->value && *cur->value) {
5460           if (STRCASEEQ('x','X',"xx-small",cur->value)) {
5461             attr_size = apr_pstrdup(doc->pool, cur->value);
5462           }
5463           else if (STRCASEEQ('x','X',"x-small",cur->value)) {
5464             attr_size = apr_pstrdup(doc->pool, cur->value);
5465           }
5466           else if (STRCASEEQ('s','S',"small",cur->value)) {
5467             attr_size = apr_pstrdup(doc->pool, cur->value);
5468           }
5469           else if (STRCASEEQ('m','M',"medium",cur->value)) {
5470             attr_size = apr_pstrdup(doc->pool, cur->value);
5471           }
5472           else if (STRCASEEQ('l','L',"large",cur->value)) {
5473             attr_size = apr_pstrdup(doc->pool, cur->value);
5474           }
5475           else if (STRCASEEQ('x','X',"x-large",cur->value)) {
5476             attr_size = apr_pstrdup(doc->pool, cur->value);
5477           }
5478           else if (STRCASEEQ('x','X',"xx-large",cur->value)) {
5479             attr_size = apr_pstrdup(doc->pool, cur->value);
5480           }
5481         }
5482       }
5483     }
5484   }
5485   W_L("<dd");
5486   if (attr_color || attr_size) {
5487     W_L(" style=\"");
5488     if (attr_color) {
5489       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
5490       W_L("color:");
5491       W_V(attr_color);
5492       W_L(";");
5493     }
5494     if (attr_size) {
5495       W_L("font-size:");
5496       W_V(attr_size);
5497       W_L(";");
5498     }
5499     W_L("\"");
5500   }
5501   W_L(">");
5502   return android->out;
5503 }
5504
5505
5506 /**
5507  * It is a handler who processes the DD tag.
5508  *
5509  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5510  *                     destination is specified.
5511  * @param node   [i]   The DD tag node is specified.
5512  * @return The conversion result is returned.
5513  */
5514 static char *
5515 s_android_end_dd_tag(void *pdoc, Node *UNUSED(child))
5516 {
5517   android_t *android = GET_ANDROID(pdoc);
5518   Doc      *doc = android->doc;
5519   W_L("</dd>");
5520   if (IS_CSS_ON(android->entryp)) {
5521     chxj_css_pop_prop_list(android->css_prop_stack);
5522   }
5523   return android->out;
5524 }
5525
5526
5527 /**
5528  * It is a handler who processes the H1 tag.
5529  *
5530  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5531  *                     destination is specified.
5532  * @param node   [i]   The H1 tag node is specified.
5533  * @return The conversion result is returned.
5534  */
5535 static char *
5536 s_android_start_h1_tag(void *pdoc, Node *node)
5537 {
5538   android_t    *android;
5539   Doc         *doc;
5540   request_rec *r;
5541   Attr        *attr;
5542   char        *attr_style = NULL;
5543   char        *attr_align = NULL;
5544   char        *css_clear  = NULL;
5545
5546   android = GET_ANDROID(pdoc);
5547   doc    = android->doc;
5548   r      = doc->r;
5549
5550   for (attr = qs_get_attr(doc,node);
5551        attr;
5552        attr = qs_get_next_attr(doc,attr)) {
5553     char *name  = qs_get_attr_name(doc,attr);
5554     char *value = qs_get_attr_value(doc,attr);
5555     if (STRCASEEQ('a','A',"align", name)) {
5556       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
5557         attr_align = value;
5558       }
5559     }
5560     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
5561       attr_style = value;
5562     }
5563   }
5564   if (IS_CSS_ON(android->entryp)) {
5565     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
5566     if (style) {
5567       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
5568       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
5569       css_property_t *cur;
5570       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
5571         if (STRCASEEQ('l','L',"left", cur->value)) {
5572           attr_align = apr_pstrdup(doc->pool, "left");
5573         }
5574         else if (STRCASEEQ('c','C',"center",cur->value)) {
5575           attr_align = apr_pstrdup(doc->pool, "center");
5576         }
5577         else if (STRCASEEQ('r','R',"right",cur->value)) {
5578           attr_align = apr_pstrdup(doc->pool, "right");
5579         }
5580       }
5581       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
5582         if (STRCASEEQ('b','B',"both", cur->value)) {
5583           css_clear = apr_pstrdup(doc->pool, "both");
5584         }
5585         else if (STRCASEEQ('r','R',"right", cur->value)) {
5586           css_clear = apr_pstrdup(doc->pool, "right");
5587         }
5588         else if (STRCASEEQ('l','L',"left", cur->value)) {
5589           css_clear = apr_pstrdup(doc->pool, "left");
5590         }
5591       }
5592     }
5593   }
5594   W_L("<h1");
5595   if (attr_align || css_clear ) {
5596     W_L(" style=\"");
5597     if(attr_align){
5598       W_L("text-align:");
5599       W_V(attr_align);
5600       W_L(";");
5601     }
5602     if(css_clear){
5603       W_L("clear:");
5604       W_V(css_clear);
5605       W_L(";");
5606     }
5607     W_L("\"");
5608   }
5609   W_L(">");
5610
5611   return android->out;
5612 }
5613
5614
5615 /**
5616  * It is a handler who processes the H1 tag.
5617  *
5618  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5619  *                     destination is specified.
5620  * @param node   [i]   The H1 tag node is specified.
5621  * @return The conversion result is returned.
5622  */
5623 static char *
5624 s_android_end_h1_tag(void *pdoc, Node *UNUSED(child)) 
5625 {
5626   android_t*    android;
5627   Doc*          doc;
5628   request_rec*  r;
5629
5630   android = GET_ANDROID(pdoc);
5631   doc     = android->doc;
5632   r       = doc->r;
5633   
5634   W_L("</h1>");
5635   if (IS_CSS_ON(android->entryp)) {
5636     chxj_css_pop_prop_list(android->css_prop_stack);
5637   }
5638
5639   return android->out;
5640 }
5641
5642
5643 /**
5644  * It is a handler who processes the H2 tag.
5645  *
5646  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5647  *                     destination is specified.
5648  * @param node   [i]   The H1 tag node is specified.
5649  * @return The conversion result is returned.
5650  */
5651 static char *
5652 s_android_start_h2_tag(void *pdoc, Node *node)
5653 {
5654   android_t    *android;
5655   Doc         *doc;
5656   request_rec *r;
5657   Attr        *attr;
5658   char        *attr_style = NULL;
5659   char        *attr_align = NULL;
5660   char        *css_clear  = NULL;
5661
5662   android   = GET_ANDROID(pdoc);
5663   doc     = android->doc;
5664   r       = doc->r;
5665
5666   for (attr = qs_get_attr(doc,node);
5667        attr;
5668        attr = qs_get_next_attr(doc,attr)) {
5669     char *name  = qs_get_attr_name(doc,attr);
5670     char *value = qs_get_attr_value(doc,attr);
5671     if (STRCASEEQ('a','A',"align", name)) {
5672       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
5673         attr_align = value;
5674       }
5675     }
5676     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
5677       attr_style = value;
5678     }
5679   }
5680   if (IS_CSS_ON(android->entryp)) {
5681     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
5682     if (style) {
5683       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
5684       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
5685       css_property_t *cur;
5686       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
5687         if (STRCASEEQ('l','L',"left", cur->value)) {
5688           attr_align = apr_pstrdup(doc->pool, "left");
5689         }
5690         else if (STRCASEEQ('c','C',"center",cur->value)) {
5691           attr_align = apr_pstrdup(doc->pool, "center");
5692         }
5693         else if (STRCASEEQ('r','R',"right",cur->value)) {
5694           attr_align = apr_pstrdup(doc->pool, "right");
5695         }
5696       }
5697       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
5698         if (STRCASEEQ('b','B',"both", cur->value)) {
5699           css_clear = apr_pstrdup(doc->pool, "both");
5700         }
5701         else if (STRCASEEQ('r','R',"right", cur->value)) {
5702           css_clear = apr_pstrdup(doc->pool, "right");
5703         }
5704         else if (STRCASEEQ('l','L',"left", cur->value)) {
5705           css_clear = apr_pstrdup(doc->pool, "left");
5706         }
5707       }
5708     }
5709   }
5710   W_L("<h2");
5711   if (attr_align || css_clear ) {
5712     W_L(" style=\"");
5713     if(attr_align){
5714       W_L("text-align:");
5715       W_V(attr_align);
5716       W_L(";");
5717     }
5718     if(css_clear){
5719       W_L("clear:");
5720       W_V(css_clear);
5721       W_L(";");
5722     }
5723     W_L("\"");
5724   }
5725   W_L(">");
5726
5727   return android->out;
5728 }
5729
5730
5731 /**
5732  * It is a handler who processes the H2 tag.
5733  *
5734  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5735  *                     destination is specified.
5736  * @param node   [i]   The H1 tag node is specified.
5737  * @return The conversion result is returned.
5738  */
5739 static char *
5740 s_android_end_h2_tag(void *pdoc, Node *UNUSED(child)) 
5741 {
5742   android_t*    android;
5743   Doc*          doc;
5744   request_rec*  r;
5745
5746   android = GET_ANDROID(pdoc);
5747   doc     = android->doc;
5748   r       = doc->r;
5749   
5750   W_L("</h2>");
5751   if (IS_CSS_ON(android->entryp)) {
5752     chxj_css_pop_prop_list(android->css_prop_stack);
5753   }
5754   return android->out;
5755 }
5756
5757
5758 /**
5759  * It is a handler who processes the H3 tag.
5760  *
5761  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5762  *                     destination is specified.
5763  * @param node   [i]   The H1 tag node is specified.
5764  * @return The conversion result is returned.
5765  */
5766 static char *
5767 s_android_start_h3_tag(void *pdoc, Node *node)
5768 {
5769   android_t    *android;
5770   Doc         *doc;
5771   request_rec *r;
5772   Attr        *attr;
5773   char        *attr_style = NULL;
5774   char        *attr_align = NULL;
5775   char        *css_clear  = NULL;
5776
5777   android   = GET_ANDROID(pdoc);
5778   doc     = android->doc;
5779   r       = doc->r;
5780
5781   for (attr = qs_get_attr(doc,node);
5782        attr;
5783        attr = qs_get_next_attr(doc,attr)) {
5784     char *name  = qs_get_attr_name(doc,attr);
5785     char *value = qs_get_attr_value(doc,attr);
5786     if (STRCASEEQ('a','A',"align", name)) {
5787       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
5788         attr_align = value;
5789       }
5790     }
5791     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
5792       attr_style = value;
5793     }
5794   }
5795   if (IS_CSS_ON(android->entryp)) {
5796     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
5797     if (style) {
5798       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
5799       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
5800       css_property_t *cur;
5801       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
5802         if (STRCASEEQ('l','L',"left", cur->value)) {
5803           attr_align = apr_pstrdup(doc->pool, "left");
5804         }
5805         else if (STRCASEEQ('c','C',"center",cur->value)) {
5806           attr_align = apr_pstrdup(doc->pool, "center");
5807         }
5808         else if (STRCASEEQ('r','R',"right",cur->value)) {
5809           attr_align = apr_pstrdup(doc->pool, "right");
5810         }
5811       }
5812       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
5813         if (STRCASEEQ('b','B',"both", cur->value)) {
5814           css_clear = apr_pstrdup(doc->pool, "both");
5815         }
5816         else if (STRCASEEQ('r','R',"right", cur->value)) {
5817           css_clear = apr_pstrdup(doc->pool, "right");
5818         }
5819         else if (STRCASEEQ('l','L',"left", cur->value)) {
5820           css_clear = apr_pstrdup(doc->pool, "left");
5821         }
5822       }
5823     }
5824   }
5825   W_L("<h3");
5826   if (attr_align || css_clear ) {
5827     W_L(" style=\"");
5828     if(attr_align){
5829       W_L("text-align:");
5830       W_V(attr_align);
5831       W_L(";");
5832     }
5833     if(css_clear){
5834       W_L("clear:");
5835       W_V(css_clear);
5836       W_L(";");
5837     }
5838     W_L("\"");
5839   }
5840   W_L(">");
5841
5842   return android->out;
5843 }
5844
5845
5846 /**
5847  * It is a handler who processes the H3 tag.
5848  *
5849  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5850  *                     destination is specified.
5851  * @param node   [i]   The H1 tag node is specified.
5852  * @return The conversion result is returned.
5853  */
5854 static char *
5855 s_android_end_h3_tag(void *pdoc, Node *UNUSED(child)) 
5856 {
5857   android_t*    android;
5858   Doc*          doc;
5859   request_rec*  r;
5860
5861   android = GET_ANDROID(pdoc);
5862   doc     = android->doc;
5863   r       = doc->r;
5864
5865   W_L("</h3>");
5866   if (IS_CSS_ON(android->entryp)) {
5867     chxj_css_pop_prop_list(android->css_prop_stack);
5868   }
5869   return android->out;
5870 }
5871
5872
5873 /**
5874  * It is a handler who processes the H4 tag.
5875  *
5876  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5877  *                     destination is specified.
5878  * @param node   [i]   The H1 tag node is specified.
5879  * @return The conversion result is returned.
5880  */
5881 static char *
5882 s_android_start_h4_tag(void *pdoc, Node *node)
5883 {
5884   android_t    *android;
5885   Doc         *doc;
5886   request_rec *r;
5887   Attr        *attr;
5888   char        *attr_style = NULL;
5889   char        *attr_align = NULL;
5890   char        *css_clear  = NULL;
5891
5892   android   = GET_ANDROID(pdoc);
5893   doc     = android->doc;
5894   r       = doc->r;
5895
5896   for (attr = qs_get_attr(doc,node);
5897        attr;
5898        attr = qs_get_next_attr(doc,attr)) {
5899     char *name  = qs_get_attr_name(doc,attr);
5900     char *value = qs_get_attr_value(doc,attr);
5901     if (STRCASEEQ('a','A',"align", name)) {
5902       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
5903         attr_align = value;
5904       }
5905     }
5906     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
5907       attr_style = value;
5908     }
5909   }
5910   if (IS_CSS_ON(android->entryp)) {
5911     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
5912     if (style) {
5913       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
5914       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
5915       css_property_t *cur;
5916       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
5917         if (STRCASEEQ('l','L',"left", cur->value)) {
5918           attr_align = apr_pstrdup(doc->pool, "left");
5919         }
5920         else if (STRCASEEQ('c','C',"center",cur->value)) {
5921           attr_align = apr_pstrdup(doc->pool, "center");
5922         }
5923         else if (STRCASEEQ('r','R',"right",cur->value)) {
5924           attr_align = apr_pstrdup(doc->pool, "right");
5925         }
5926       }
5927       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
5928         if (STRCASEEQ('b','B',"both", cur->value)) {
5929           css_clear = apr_pstrdup(doc->pool, "both");
5930         }
5931         else if (STRCASEEQ('r','R',"right", cur->value)) {
5932           css_clear = apr_pstrdup(doc->pool, "right");
5933         }
5934         else if (STRCASEEQ('l','L',"left", cur->value)) {
5935           css_clear = apr_pstrdup(doc->pool, "left");
5936         }
5937       }
5938     }
5939   }
5940   W_L("<h4");
5941   if (attr_align || css_clear ) {
5942     W_L(" style=\"");
5943     if(attr_align){
5944       W_L("text-align:");
5945       W_V(attr_align);
5946       W_L(";");
5947     }
5948     if(css_clear){
5949       W_L("clear:");
5950       W_V(css_clear);
5951       W_L(";");
5952     }
5953     W_L("\"");
5954   }
5955   W_L(">");
5956
5957   return android->out;
5958 }
5959
5960
5961 /**
5962  * It is a handler who processes the H4 tag.
5963  *
5964  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5965  *                     destination is specified.
5966  * @param node   [i]   The H1 tag node is specified.
5967  * @return The conversion result is returned.
5968  */
5969 static char *
5970 s_android_end_h4_tag(void *pdoc, Node *UNUSED(child)) 
5971 {
5972   android_t      *android;
5973   Doc           *doc;
5974   request_rec   *r;
5975
5976   android = GET_ANDROID(pdoc);
5977   doc     = android->doc;
5978   r       = doc->r;
5979   
5980   W_L("</h4>");
5981   if (IS_CSS_ON(android->entryp)) {
5982     chxj_css_pop_prop_list(android->css_prop_stack);
5983   }
5984
5985   return android->out;
5986 }
5987
5988
5989 /**
5990  * It is a handler who processes the H5 tag.
5991  *
5992  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5993  *                     destination is specified.
5994  * @param node   [i]   The H1 tag node is specified.
5995  * @return The conversion result is returned.
5996  */
5997 static char *
5998 s_android_start_h5_tag(void *pdoc, Node *node)
5999 {
6000   android_t    *android;
6001   Doc         *doc;
6002   request_rec *r;
6003   Attr        *attr;
6004   char        *attr_style = NULL;
6005   char        *attr_align = NULL;
6006   char        *css_clear  = NULL;
6007
6008   android   = GET_ANDROID(pdoc);
6009   doc     = android->doc;
6010   r       = doc->r;
6011
6012   for (attr = qs_get_attr(doc,node);
6013        attr;
6014        attr = qs_get_next_attr(doc,attr)) {
6015     char *name  = qs_get_attr_name(doc,attr);
6016     char *value = qs_get_attr_value(doc,attr);
6017     if (STRCASEEQ('a','A',"align", name)) {
6018       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
6019         attr_align = value;
6020       }
6021     }
6022     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
6023       attr_style = value;
6024     }
6025   }
6026   if (IS_CSS_ON(android->entryp)) {
6027     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
6028     if (style) {
6029       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
6030       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
6031       css_property_t *cur;
6032       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
6033         if (STRCASEEQ('l','L',"left", cur->value)) {
6034           attr_align = apr_pstrdup(doc->pool, "left");
6035         }
6036         else if (STRCASEEQ('c','C',"center",cur->value)) {
6037           attr_align = apr_pstrdup(doc->pool, "center");
6038         }
6039         else if (STRCASEEQ('r','R',"right",cur->value)) {
6040           attr_align = apr_pstrdup(doc->pool, "right");
6041         }
6042       }
6043       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
6044         if (STRCASEEQ('b','B',"both", cur->value)) {
6045           css_clear = apr_pstrdup(doc->pool, "both");
6046         }
6047         else if (STRCASEEQ('r','R',"right", cur->value)) {
6048           css_clear = apr_pstrdup(doc->pool, "right");
6049         }
6050         else if (STRCASEEQ('l','L',"left", cur->value)) {
6051           css_clear = apr_pstrdup(doc->pool, "left");
6052         }
6053       }
6054     }
6055   }
6056   W_L("<h5");
6057   if (attr_align || css_clear ) {
6058     W_L(" style=\"");
6059     if(attr_align){
6060       W_L("text-align:");
6061       W_V(attr_align);
6062       W_L(";");
6063     }
6064     if(css_clear){
6065       W_L("clear:");
6066       W_V(css_clear);
6067       W_L(";");
6068     }
6069     W_L("\"");
6070   }
6071   W_L(">");
6072
6073   return android->out;
6074 }
6075
6076
6077 /**
6078  * It is a handler who processes the H5 tag.
6079  *
6080  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6081  *                     destination is specified.
6082  * @param node   [i]   The H1 tag node is specified.
6083  * @return The conversion result is returned.
6084  */
6085 static char *
6086 s_android_end_h5_tag(void *pdoc, Node *UNUSED(child)) 
6087 {
6088   android_t    *android;
6089   Doc         *doc;
6090   request_rec *r;
6091
6092   android = GET_ANDROID(pdoc);
6093   doc     = android->doc;
6094   r       = doc->r;
6095   
6096   W_L("</h5>");
6097   if (IS_CSS_ON(android->entryp)) {
6098     chxj_css_pop_prop_list(android->css_prop_stack);
6099   }
6100
6101   return android->out;
6102 }
6103
6104
6105 /**
6106  * It is a handler who processes the H6 tag.
6107  *
6108  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6109  *                     destination is specified.
6110  * @param node   [i]   The H1 tag node is specified.
6111  * @return The conversion result is returned.
6112  */
6113 static char *
6114 s_android_start_h6_tag(void *pdoc, Node *node)
6115 {
6116   android_t    *android;
6117   Doc         *doc;
6118   request_rec *r;
6119   Attr        *attr;
6120   char        *attr_style = NULL;
6121   char        *attr_align = NULL;
6122   char        *css_clear  = NULL;
6123
6124   android   = GET_ANDROID(pdoc);
6125   doc     = android->doc;
6126   r       = doc->r;
6127
6128   for (attr = qs_get_attr(doc,node);
6129        attr;
6130        attr = qs_get_next_attr(doc,attr)) {
6131     char *name  = qs_get_attr_name(doc,attr);
6132     char *value = qs_get_attr_value(doc,attr);
6133     if (STRCASEEQ('a','A',"align", name)) {
6134       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
6135         attr_align = value;
6136       }
6137     }
6138     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
6139       attr_style = value;
6140     }
6141   }
6142   if (IS_CSS_ON(android->entryp)) {
6143     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
6144     if (style) {
6145       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
6146       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
6147       css_property_t *cur;
6148       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
6149         if (STRCASEEQ('l','L',"left", cur->value)) {
6150           attr_align = apr_pstrdup(doc->pool, "left");
6151         }
6152         else if (STRCASEEQ('c','C',"center",cur->value)) {
6153           attr_align = apr_pstrdup(doc->pool, "center");
6154         }
6155         else if (STRCASEEQ('r','R',"right",cur->value)) {
6156           attr_align = apr_pstrdup(doc->pool, "right");
6157         }
6158       }
6159       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
6160         if (STRCASEEQ('b','B',"both", cur->value)) {
6161           css_clear = apr_pstrdup(doc->pool, "both");
6162         }
6163         else if (STRCASEEQ('r','R',"right", cur->value)) {
6164           css_clear = apr_pstrdup(doc->pool, "right");
6165         }
6166         else if (STRCASEEQ('l','L',"left", cur->value)) {
6167           css_clear = apr_pstrdup(doc->pool, "left");
6168         }
6169       }
6170     }
6171   }
6172   W_L("<h6");
6173   if (attr_align || css_clear ) {
6174     W_L(" style=\"");
6175     if(attr_align){
6176       W_L("text-align:");
6177       W_V(attr_align);
6178       W_L(";");
6179     }
6180     if(css_clear){
6181       W_L("clear:");
6182       W_V(css_clear);
6183       W_L(";");
6184     }
6185     W_L("\"");
6186   }
6187   W_L(">");
6188
6189   return android->out;
6190 }
6191
6192
6193 /**
6194  * It is a handler who processes the H6 tag.
6195  *
6196  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6197  *                     destination is specified.
6198  * @param node   [i]   The H1 tag node is specified.
6199  * @return The conversion result is returned.
6200  */
6201 static char *
6202 s_android_end_h6_tag(void *pdoc, Node *UNUSED(child)) 
6203 {
6204   android_t    *android;
6205   Doc         *doc;
6206   request_rec *r;
6207
6208   android = GET_ANDROID(pdoc);
6209   doc     = android->doc;
6210   r       = doc->r;
6211   
6212   W_L("</h6>");
6213   if (IS_CSS_ON(android->entryp)) {
6214     chxj_css_pop_prop_list(android->css_prop_stack);
6215   }
6216
6217   return android->out;
6218 }
6219
6220
6221 /**
6222  * It is a handler who processes the MENU tag.
6223  *
6224  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6225  *                     destination is specified.
6226  * @param node   [i]   The MENU tag node is specified.
6227  * @return The conversion result is returned.
6228  */
6229 static char *
6230 s_android_start_menu_tag(void *pdoc, Node *node)
6231 {
6232   android_t *android      = GET_ANDROID(pdoc);
6233   Doc       *doc        = android->doc;
6234   Attr      *attr;
6235   char      *attr_style = NULL;
6236   char      *attr_color = NULL;
6237   char      *attr_type  = NULL;
6238   char      *attr_size  = NULL;
6239   for (attr = qs_get_attr(doc,node);
6240        attr;
6241        attr = qs_get_next_attr(doc,attr)) {
6242     char *name   = qs_get_attr_name(doc,attr);
6243     char *value  = qs_get_attr_value(doc,attr);
6244     if (STRCASEEQ('t','T',"type",name)) {
6245       if (value && (STRCASEEQ('d','D',"disc",value) || STRCASEEQ('c','C',"circle",value) || STRCASEEQ('s','S',"square",value))) {
6246         attr_type = value;
6247       }
6248     }
6249     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
6250       attr_style = value;
6251     }
6252   }
6253   if (IS_CSS_ON(android->entryp)) {
6254     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
6255     if (style) {
6256       css_property_t *color_prop           = chxj_css_get_property_value(doc, style, "color");
6257       css_property_t *size_prop            = chxj_css_get_property_value(doc, style, "font-size");
6258       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type");
6259       css_property_t *cur;
6260       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
6261         if (cur->value && *cur->value) {
6262           attr_color = apr_pstrdup(doc->pool, cur->value);
6263         }
6264       }
6265       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
6266         if (cur->value && *cur->value) {
6267           attr_type = apr_pstrdup(doc->pool, cur->value);
6268         }
6269       }
6270       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
6271         if (cur->value && *cur->value) {
6272           if (STRCASEEQ('x','X',"xx-small",cur->value)) {
6273             attr_size = apr_pstrdup(doc->pool, cur->value);
6274           }
6275           else if (STRCASEEQ('x','X',"x-small",cur->value)) {
6276             attr_size = apr_pstrdup(doc->pool, cur->value);
6277           }
6278           else if (STRCASEEQ('s','S',"small",cur->value)) {
6279             attr_size = apr_pstrdup(doc->pool, cur->value);
6280           }
6281           else if (STRCASEEQ('m','M',"medium",cur->value)) {
6282             attr_size = apr_pstrdup(doc->pool, cur->value);
6283           }
6284           else if (STRCASEEQ('l','L',"large",cur->value)) {
6285             attr_size = apr_pstrdup(doc->pool, cur->value);
6286           }
6287           else if (STRCASEEQ('x','X',"x-large",cur->value)) {
6288             attr_size = apr_pstrdup(doc->pool, cur->value);
6289           }
6290           else if (STRCASEEQ('x','X',"xx-large",cur->value)) {
6291             attr_size = apr_pstrdup(doc->pool, cur->value);
6292           }
6293         }
6294       }
6295     }
6296   }
6297   W_L("<menu");
6298   if (attr_type || attr_color || attr_size) {
6299     W_L(" style=\"");
6300     if (attr_type) {
6301       W_L("list-style-type:");
6302       W_V(attr_type);
6303       W_L(";");
6304     }
6305     if (attr_color) {
6306       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
6307       W_L("color:");
6308       W_V(attr_color);
6309       W_L(";");
6310     }
6311     if (attr_size) {
6312       W_L("font-size:");
6313       W_V(attr_size);
6314       W_L(";");
6315     }
6316     W_L("\"");
6317   }
6318   W_L(">");
6319   return android->out;
6320 }
6321
6322
6323 /**
6324  * It is a handler who processes the MENU tag.
6325  *
6326  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6327  *                     destination is specified.
6328  * @param node   [i]   The MENU tag node is specified.
6329  * @return The conversion result is returned.
6330  */
6331 static char *
6332 s_android_end_menu_tag(void *pdoc, Node *UNUSED(child))
6333 {
6334   android_t *android = GET_ANDROID(pdoc);
6335   Doc *doc = android->doc;
6336   W_L("</menu>");
6337   if (IS_CSS_ON(android->entryp)) {
6338     chxj_css_pop_prop_list(android->css_prop_stack);
6339   }
6340   return android->out;
6341 }
6342
6343
6344 /**
6345  * It is a handler who processes the PLAINTEXT tag.
6346  *
6347  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6348  *                     destination is specified.
6349  * @param node   [i]   The PLAINTEXT tag node is specified.
6350  * @return The conversion result is returned.
6351  */
6352 static char *
6353 s_android_start_plaintext_tag(void *pdoc, Node *node)
6354 {
6355   android_t *android;
6356   Doc *doc;
6357
6358   android = GET_ANDROID(pdoc);
6359   doc     = android->doc;
6360   W_L("<plaintext>");
6361   s_android_start_plaintext_tag_inner(pdoc,node);
6362   return android->out;
6363 }
6364
6365 static char *
6366 s_android_start_plaintext_tag_inner(void *pdoc, Node *node)
6367 {
6368   android_t *android;
6369   Doc *doc;
6370   Node *child;
6371   android = GET_ANDROID(pdoc);
6372   doc     = android->doc;
6373   for (child = qs_get_child_node(doc, node);
6374        child;
6375        child = qs_get_next_node(doc, child)) {
6376     W_V(child->otext);
6377     s_android_start_plaintext_tag_inner(pdoc, child);
6378   }
6379   return android->out;
6380 }
6381
6382
6383 /**
6384  * It is a handler who processes the PLAINTEXT tag.
6385  *
6386  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6387  *                     destination is specified.
6388  * @param node   [i]   The PLAINTEXT tag node is specified.
6389  * @return The conversion result is returned.
6390  */
6391 static char *
6392 s_android_end_plaintext_tag(void *pdoc, Node *UNUSED(child))
6393 {
6394   android_t *android = GET_ANDROID(pdoc);
6395   return android->out;
6396 }
6397
6398
6399 /**
6400  * It is a handler who processes the BLINK tag.
6401  *
6402  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6403  *                     destination is specified.
6404  * @param node   [i]   The BLINK tag node is specified.
6405  * @return The conversion result is returned.
6406  */
6407 static char *
6408 s_android_start_blink_tag(void *pdoc, Node *node)
6409 {
6410   android_t *android      = GET_ANDROID(pdoc);
6411   Doc       *doc        = android->doc;
6412   Attr      *attr;
6413   char      *attr_style = NULL;
6414   char      *attr_color = NULL;
6415   char      *attr_size  = NULL;
6416   for (attr = qs_get_attr(doc,node);
6417        attr;
6418        attr = qs_get_next_attr(doc,attr)) {
6419     char *name   = qs_get_attr_name(doc,attr);
6420     char *value  = qs_get_attr_value(doc,attr);
6421     if (STRCASEEQ('s','S',"style", name) && value && *value) {
6422       attr_style = value;
6423     }
6424   }
6425   if (IS_CSS_ON(android->entryp)) {
6426     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
6427     if (style) {
6428       css_property_t *color_prop           = chxj_css_get_property_value(doc, style, "color");
6429       css_property_t *size_prop            = chxj_css_get_property_value(doc, style, "font-size");
6430       css_property_t *cur;
6431       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
6432         if (cur->value && *cur->value) {
6433           attr_color = apr_pstrdup(doc->pool, cur->value);
6434         }
6435       }
6436       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
6437         if (cur->value && *cur->value) {
6438           if (STRCASEEQ('x','X',"xx-small",cur->value)) {
6439             attr_size = apr_pstrdup(doc->pool, cur->value);
6440           }
6441           else if (STRCASEEQ('x','X',"x-small",cur->value)) {
6442             attr_size = apr_pstrdup(doc->pool, cur->value);
6443           }
6444           else if (STRCASEEQ('s','S',"small",cur->value)) {
6445             attr_size = apr_pstrdup(doc->pool, cur->value);
6446           }
6447           else if (STRCASEEQ('m','M',"medium",cur->value)) {
6448             attr_size = apr_pstrdup(doc->pool, cur->value);
6449           }
6450           else if (STRCASEEQ('l','L',"large",cur->value)) {
6451             attr_size = apr_pstrdup(doc->pool, cur->value);
6452           }
6453           else if (STRCASEEQ('x','X',"x-large",cur->value)) {
6454             attr_size = apr_pstrdup(doc->pool, cur->value);
6455           }
6456           else if (STRCASEEQ('x','X',"xx-large",cur->value)) {
6457             attr_size = apr_pstrdup(doc->pool, cur->value);
6458           }
6459         }
6460       }
6461     }
6462   }
6463
6464   W_L("<span");
6465   W_L(" style=\"");
6466   W_L(STYLE_BLINK);
6467   if (android->blink_keyframe_out == 0) {
6468     android->style_data = apr_pstrcat(doc->pool, (android->style_data) ? android->style_data : "",
6469                                                 BLINK_KEYFRAME,
6470                                                 NULL);
6471     android->blink_keyframe_out = 1;
6472   }
6473   if (attr_color) {
6474     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
6475     W_L("color:");
6476     W_V(attr_color);
6477     W_L(";");
6478   }
6479   if (attr_size) {
6480     W_L("font-size:");
6481     W_V(attr_size);
6482     W_L(";");
6483   }
6484   W_L("\"");
6485   W_L(">");
6486   
6487   return android->out;
6488 }
6489
6490
6491 /**
6492  * It is a handler who processes the BLINK tag.
6493  *
6494  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6495  *                     destination is specified.
6496  * @param node   [i]   The BLINK tag node is specified.
6497  * @return The conversion result is returned.
6498  */
6499 static char *
6500 s_android_end_blink_tag(void *pdoc, Node *UNUSED(child))
6501 {
6502   android_t *android = GET_ANDROID(pdoc);
6503   Doc      *doc = android->doc;
6504   W_L("</span>");
6505   if (IS_CSS_ON(android->entryp)) {
6506     chxj_css_pop_prop_list(android->css_prop_stack);
6507   }
6508   return android->out;
6509 }
6510
6511
6512 /**
6513  * It is a handler who processes the MARQUEE tag.
6514  *
6515  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6516  *                     destination is specified.
6517  * @param node   [i]   The MARQUEE tag node is specified.
6518  * @return The conversion result is returned.
6519  */
6520 static char *
6521 s_android_start_marquee_tag(void *pdoc, Node *node)
6522 {
6523   android_t *android = GET_ANDROID(pdoc);
6524   Doc       *doc = android->doc;
6525   Attr      *attr;
6526   char      *attr_style     = NULL;
6527   char      *attr_color     = NULL;
6528   char      *attr_size      = NULL;
6529   char      *attr_wap_marquee_loop  = NULL;
6530   char      *attr_wap_marquee_style = NULL;
6531   char      *attr_wap_marquee_dir   = NULL;
6532   char      *attr_wap_marquee_speed = NULL;
6533   char      *attr_bgcolor   = NULL;
6534   /*--------------------------------------------------------------------------*/
6535   /* Get Attributes                                                           */
6536   /*--------------------------------------------------------------------------*/
6537   for (attr = qs_get_attr(doc,node);
6538        attr;
6539        attr = qs_get_next_attr(doc,attr)) {
6540     char *name   = qs_get_attr_name(doc,attr);
6541     char *value  = qs_get_attr_value(doc,attr);
6542     if (STRCASEEQ('d','D',"direction", name)) {
6543       if (value) {
6544         if (STRCASEEQ('l','L',"left",value)) {
6545           attr_wap_marquee_dir = "rtl";
6546         }
6547         else if (STRCASEEQ('r','R',"right",value)) {
6548           attr_wap_marquee_dir = "ltr";
6549         }
6550       }
6551     }
6552     else if (STRCASEEQ('b','B',"behavior",name)) {
6553       if (value && *value) {
6554         attr_wap_marquee_style = value;
6555       }
6556     }
6557     else if (STRCASEEQ('l','L',"loop",name)) {
6558       if (value && *value) {
6559         if(strcmp(value,"0") == 0 || strcmp(value,"-1") == 0){
6560           attr_wap_marquee_loop = "infinite";
6561         }
6562         else{
6563           attr_wap_marquee_loop = value;
6564         }
6565       }
6566     }
6567     else if (STRCASEEQ('b','B',"bgcolor",name)) {
6568       if (value && *value) {
6569         attr_bgcolor = value;
6570       }
6571     }
6572     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
6573       attr_style = value;
6574     }
6575   }
6576   if (IS_CSS_ON(android->entryp)) {
6577     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
6578     if (style) {
6579       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
6580       css_property_t *size_prop  = chxj_css_get_property_value(doc, style, "font-size");
6581       css_property_t *bgcolor_prop  = chxj_css_get_property_value(doc, style, "background-color");
6582       css_property_t *wap_marquee_style_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-style");
6583       css_property_t *wap_marquee_dir_prop   = chxj_css_get_property_value(doc, style, "-wap-marquee-dir");
6584       css_property_t *wap_marquee_loop_prop  = chxj_css_get_property_value(doc, style, "-wap-marquee-loop");
6585       css_property_t *wap_marquee_speed_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-speed");
6586       css_property_t *cur;
6587       if (!attr_wap_marquee_style) {
6588         for (cur = wap_marquee_style_prop->next; cur != wap_marquee_style_prop; cur = cur->next) {
6589           if (STRCASEEQ('s','S',"scroll", cur->value) || STRCASEEQ('s','S',"slide",cur->value) || STRCASEEQ('a','A',"alternate",cur->value)) {
6590             attr_wap_marquee_style = apr_pstrdup(doc->pool, cur->value);
6591           }
6592         }
6593       }
6594       if (!attr_wap_marquee_dir) {
6595         for (cur = wap_marquee_dir_prop->next; cur != wap_marquee_dir_prop; cur = cur->next) {
6596           if (STRCASEEQ('l','L',"ltr",cur->value)) {
6597             attr_wap_marquee_dir = apr_pstrdup(doc->pool, cur->value);
6598           }
6599           else if (STRCASEEQ('r','R',"rtl",cur->value)) {
6600             attr_wap_marquee_dir = apr_pstrdup(doc->pool, cur->value);
6601           }
6602         }
6603       }
6604       if (!attr_wap_marquee_loop) {
6605         for (cur = wap_marquee_loop_prop->next; cur != wap_marquee_loop_prop; cur = cur->next) {
6606           if(strcmp(cur->value,"0") == 0 || strcmp(cur->value,"-1") == 0){
6607             attr_wap_marquee_loop = "infinite";
6608           }
6609           else{
6610             attr_wap_marquee_loop = apr_pstrdup(doc->pool, cur->value);
6611           }
6612         }
6613       }
6614       if (!attr_wap_marquee_speed) {
6615         for (cur = wap_marquee_speed_prop->next; cur != wap_marquee_speed_prop; cur = cur->next) {
6616           attr_wap_marquee_speed = apr_pstrdup(doc->pool, cur->value);
6617         }
6618       }
6619       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
6620         if (cur->value && *cur->value) {
6621           attr_color = apr_pstrdup(doc->pool, cur->value);
6622         }
6623       }
6624       for (cur = bgcolor_prop->next; cur != bgcolor_prop; cur = cur->next) {
6625         if (cur->value && *cur->value) {
6626           attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
6627         }
6628       }
6629       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
6630         if (cur->value && *cur->value) {
6631           if ( STRCASEEQ('x','X',"xx-small",cur->value)
6632             || STRCASEEQ('x','X',"x-small", cur->value)
6633             || STRCASEEQ('s','S',"small",   cur->value)
6634             || STRCASEEQ('m','M',"medium",  cur->value)
6635             || STRCASEEQ('l','L',"large",   cur->value)
6636             || STRCASEEQ('x','X',"x-large", cur->value)
6637             || STRCASEEQ('x','X',"xx-large",cur->value)) {
6638             attr_size = apr_pstrdup(doc->pool, cur->value);
6639           }
6640         }
6641       }
6642     }
6643   }
6644
6645   W_L("<div style=\"");
6646   W_L("overflow:-webkit-marquee;");
6647   if (attr_wap_marquee_dir) {
6648     W_L("-webkit-marquee-direction:");
6649     if (STRCASEEQ('r','R',"rtl",attr_wap_marquee_dir)) {
6650       W_L("left");
6651     }
6652     else if (STRCASEEQ('l','L',"ltr",attr_wap_marquee_dir)) {
6653       W_L("right");
6654     }
6655     W_L(";");
6656   }
6657   if (attr_wap_marquee_style) {
6658     W_L("-webkit-marquee-style:");
6659     W_V(attr_wap_marquee_style);
6660     W_L(";");
6661   }
6662   if (attr_wap_marquee_loop) {
6663     W_L("-webkit-marquee-repetition:");
6664     W_V(attr_wap_marquee_loop);
6665     W_L(";");
6666   }
6667   if (attr_wap_marquee_speed) {
6668     W_L("-webkit-marquee-speed:");
6669     W_V(attr_wap_marquee_speed);
6670     W_L(";");
6671   }
6672   if (attr_bgcolor) {
6673     attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
6674     W_L("background-color:");
6675     W_V(attr_bgcolor);
6676     W_L(";");
6677   }
6678   if (attr_color) {
6679     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
6680     W_L("color:");
6681     W_V(attr_color);
6682     W_L(";");
6683   }
6684   if (attr_size) {
6685     W_L("font-size:");
6686     W_V(attr_size);
6687     W_L(";");
6688   }
6689   W_L("\"");
6690   W_L(">");
6691
6692   return android->out;
6693 }
6694
6695
6696 /**
6697  * It is a handler who processes the MARQUEE tag.
6698  *
6699  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6700  *                     destination is specified.
6701  * @param node   [i]   The MARQUEE tag node is specified.
6702  * @return The conversion result is returned.
6703  */
6704 static char *
6705 s_android_end_marquee_tag(void *pdoc, Node *UNUSED(node))
6706 {
6707   android_t *android = GET_ANDROID(pdoc);
6708   Doc      *doc     = android->doc;
6709   W_L("</div>");
6710   if (IS_CSS_ON(android->entryp)) {
6711     chxj_css_pop_prop_list(android->css_prop_stack);
6712   }
6713   return android->out;
6714 }
6715
6716
6717 /**
6718  * It is handler who processes the New Line Code.
6719  */
6720 static char *
6721 s_android_newline_mark(void *pdoc, Node *UNUSED(node))
6722 {
6723   android_t *android = GET_ANDROID(pdoc);
6724   if (android->start_html_flag) {
6725     Doc *doc = android->doc;
6726     W_NLCODE();
6727   }
6728   return android->out;
6729 }
6730
6731
6732 /**
6733  * It is a handler who processes the LINK tag.
6734  *
6735  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6736  *                     destination is specified.
6737  * @param node   [i]   The LINK tag node is specified.
6738  * @return The conversion result is returned.
6739  */
6740 static char *
6741 s_android_link_tag(void *pdoc, Node *node)
6742 {
6743   android_t      *android;
6744   Doc           *doc;
6745   Attr          *attr;
6746   char          *rel  = NULL;
6747   char          *href = NULL;
6748   char          *type = NULL;
6749
6750   android = GET_ANDROID(pdoc);
6751   doc    = android->doc;
6752
6753   if (! IS_CSS_ON(android->entryp)) {
6754     return android->out;
6755   }
6756
6757   for (attr = qs_get_attr(doc,node);
6758        attr;
6759        attr = qs_get_next_attr(doc,attr)) {
6760     char *name  = qs_get_attr_name(doc,attr);
6761     char *value = qs_get_attr_value(doc,attr);
6762     if (STRCASEEQ('r','R',"rel", name)) {
6763       if (value && *value && STRCASEEQ('s','S',"stylesheet", value)) {
6764         rel = value;
6765       }
6766     }
6767     else if (STRCASEEQ('h','H',"href", name)) {
6768       if (value && *value) {
6769         href = value;
6770       }
6771     }
6772     else if (STRCASEEQ('t','T',"type", name)) {
6773       if (value && *value && STRCASEEQ('t','T',"text/css",value)) {
6774         type = value;
6775       }
6776     }
6777   }
6778
6779   if (rel && href && type) {
6780     DBG(doc->r,"REQ[%X] start load CSS. url:[%s]", TO_ADDR(doc->r),href);
6781     android->style = chxj_css_parse_from_uri(doc->r, doc->pool, android->style, href);
6782     DBG(doc->r,"REQ[%X] end load CSS. url:[%s]", TO_ADDR(doc->r),href);
6783   }
6784
6785   return android->out;
6786 }
6787
6788
6789 static css_prop_list_t *
6790 s_android_push_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value)
6791 {
6792   android_t *android = GET_ANDROID(pdoc);
6793   Doc *doc = android->doc;
6794   css_prop_list_t *last_css = NULL;
6795   if (IS_CSS_ON(android->entryp)) {
6796     css_prop_list_t *dup_css;
6797     css_selector_t  *selector;
6798
6799     last_css = chxj_css_get_last_prop_list(android->css_prop_stack);
6800     dup_css  = chxj_dup_css_prop_list(doc, last_css);
6801     selector = chxj_css_find_selector(doc, android->style, node);
6802     if (selector) {
6803       chxj_css_prop_list_merge_property(doc, dup_css, selector);
6804     }
6805     chxj_css_push_prop_list(android->css_prop_stack, dup_css);
6806     last_css = chxj_css_get_last_prop_list(android->css_prop_stack);
6807
6808     if (style_attr_value) {
6809       css_stylesheet_t *ssheet = chxj_css_parse_style_attr(doc, NULL, apr_pstrdup(doc->pool, node->name), NULL, NULL, apr_pstrdup(doc->pool, style_attr_value));
6810       if (ssheet) {
6811         chxj_css_prop_list_merge_property(doc, last_css, ssheet->selector_head.next);
6812       }
6813     }
6814   }
6815   return last_css;
6816 }
6817
6818
6819 static css_prop_list_t *
6820 s_android_nopush_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value)
6821 {
6822   android_t *android = GET_ANDROID(pdoc);
6823   Doc *doc = android->doc;
6824   css_prop_list_t *last_css = NULL;
6825   if (IS_CSS_ON(android->entryp)) {
6826     css_prop_list_t *dup_css;
6827     css_selector_t  *selector;
6828
6829     last_css = chxj_css_get_last_prop_list(android->css_prop_stack);
6830     dup_css  = chxj_dup_css_prop_list(doc, last_css);
6831     selector = chxj_css_find_selector(doc, android->style, node);
6832     if (selector) {
6833       chxj_css_prop_list_merge_property(doc, dup_css, selector);
6834     }
6835     last_css = dup_css;
6836
6837     if (style_attr_value) {
6838       css_stylesheet_t *ssheet = chxj_css_parse_style_attr(doc, NULL, apr_pstrdup(doc->pool, node->name), NULL, NULL, apr_pstrdup(doc->pool, style_attr_value));
6839       if (ssheet) {
6840         chxj_css_prop_list_merge_property(doc, last_css, ssheet->selector_head.next);
6841       }
6842     }
6843   }
6844   return last_css;
6845 }
6846
6847
6848 /**
6849  * It is a handler who processes the SPAN tag.
6850  *
6851  * @param pdoc  [i/o] The pointer to the JHTML structure at the output
6852  *                     destination is specified.
6853  * @param node   [i]   The SPAN tag node is specified.
6854  * @return The conversion result is returned.
6855  */
6856 static char *
6857 s_android_start_span_tag(void *pdoc, Node *node)
6858 {
6859   android_t *android;
6860   Doc *doc;
6861   Attr *attr;
6862   char *attr_style = NULL;
6863   char *attr_color = NULL;
6864   char *attr_size = NULL;
6865   char *attr_align = NULL;
6866   char *attr_blink = NULL;
6867   char *attr_marquee = NULL;
6868   char *attr_marquee_dir = NULL;
6869   char *attr_marquee_style = NULL;
6870   char *attr_marquee_loop = NULL;
6871   char *attr_marquee_speed = NULL;
6872   char *css_bgcolor        = NULL;
6873
6874   android = GET_ANDROID(pdoc);
6875   doc     = android->doc;
6876
6877   for (attr = qs_get_attr(doc,node);
6878        attr;
6879        attr = qs_get_next_attr(doc,attr)) {
6880     char *nm  = qs_get_attr_name(doc,attr);
6881     char *val = qs_get_attr_value(doc,attr);
6882     if (val && STRCASEEQ('s','S',"style", nm)) {
6883       attr_style = val;
6884     }
6885   }
6886   if (IS_CSS_ON(android->entryp)) {
6887     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
6888     if (style) {
6889       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
6890       css_property_t *size_prop = chxj_css_get_property_value(doc, style, "font-size");
6891       css_property_t *text_align_prop = chxj_css_get_property_value(doc, style, "text-align");
6892       css_property_t *decoration_prop = chxj_css_get_property_value(doc, style, "text-decoration");
6893       css_property_t *display_prop = chxj_css_get_property_value(doc, style, "display");
6894       css_property_t *marquee_dir_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-dir");
6895       css_property_t *marquee_style_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-style");
6896       css_property_t *marquee_loop_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-loop");
6897       css_property_t *marquee_speed_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-speed");
6898       css_property_t *bgcolor_prop = chxj_css_get_property_value(doc, style, "background-color");
6899       
6900       css_property_t *cur;
6901       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
6902         attr_color = apr_pstrdup(doc->pool, cur->value);
6903       }
6904       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
6905         if (cur->value && *cur->value) {
6906           if ( STRCASEEQ('x','X',"xx-small",cur->value)
6907             || STRCASEEQ('x','X',"x-small", cur->value)
6908             || STRCASEEQ('s','S',"small",   cur->value)
6909             || STRCASEEQ('m','M',"medium",  cur->value)
6910             || STRCASEEQ('l','L',"large",   cur->value)
6911             || STRCASEEQ('x','X',"x-large", cur->value)
6912             || STRCASEEQ('x','X',"xx-large",cur->value)) {
6913             attr_size = apr_pstrdup(doc->pool, cur->value);
6914           }
6915         }
6916       }
6917       for (cur = decoration_prop->next; cur != decoration_prop; cur = cur->next) {
6918         if (cur->value && STRCASEEQ('b','B',"blink",cur->value)) {
6919           attr_blink = apr_pstrdup(doc->pool, cur->value);
6920         }
6921       }
6922       for (cur = display_prop->next; cur != display_prop; cur = cur->next) {
6923         if (cur->value && strcasecmp("-wap-marquee",cur->value) == 0) {
6924           attr_marquee = apr_pstrdup(doc->pool, cur->value);
6925         }
6926       }
6927       for (cur = marquee_dir_prop->next; cur != marquee_dir_prop; cur = cur->next) {
6928         if (cur->value && *cur->value) {
6929           if ( STRCASEEQ('l','L',"ltr",cur->value)
6930             || STRCASEEQ('r','R',"rtl",cur->value)) {
6931             attr_marquee_dir = apr_pstrdup(doc->pool, cur->value);
6932           }
6933         }
6934       }
6935       for (cur = marquee_style_prop->next; cur != marquee_style_prop; cur = cur->next) {
6936         if (cur->value && *cur->value) {
6937           if ( STRCASEEQ('s','S',"scroll",cur->value)
6938             || STRCASEEQ('s','S',"slide",cur->value)
6939             || STRCASEEQ('a','A',"alternate",cur->value)) {
6940             attr_marquee_style = apr_pstrdup(doc->pool, cur->value);
6941           }
6942         }
6943       }
6944       for (cur = marquee_loop_prop->next; cur != marquee_loop_prop; cur = cur->next) {
6945         if (cur->value && *cur->value) {
6946           if(strcmp(cur->value,"0") == 0 || strcmp(cur->value,"-1") == 0){
6947             attr_marquee_loop = "infinite";
6948           }
6949           else{
6950             attr_marquee_loop = apr_pstrdup(doc->pool, cur->value);
6951           }
6952         }
6953       }
6954       for (cur = marquee_speed_prop->next; cur != marquee_speed_prop; cur = cur->next) {
6955         if (cur->value && *cur->value) {
6956           attr_marquee_speed = apr_pstrdup(doc->pool, cur->value);
6957         }
6958       }
6959       for (cur = text_align_prop->next; cur != text_align_prop; cur = cur->next) {
6960         if (STRCASEEQ('l','L',"left", cur->value)) {
6961           attr_align = apr_pstrdup(doc->pool, "left");
6962         }
6963         else if (STRCASEEQ('c','C',"center",cur->value)) {
6964           attr_align = apr_pstrdup(doc->pool, "center");
6965         }
6966         else if (STRCASEEQ('r','R',"right",cur->value)) {
6967           attr_align = apr_pstrdup(doc->pool, "right");
6968         }
6969       }
6970       for (cur = bgcolor_prop->next; cur != bgcolor_prop; cur = cur->next) {
6971         if (cur->value && *cur->value) {
6972           css_bgcolor = apr_pstrdup(doc->pool, cur->value);
6973         }
6974       }
6975     }
6976   }
6977
6978   W_L("<div");
6979   if (attr_marquee) {
6980     W_L(" style=\"");
6981     W_L("overflow:-webkit-marquee;");
6982     if (attr_marquee_style) {
6983       W_L("-webkit-marquee-style:");
6984       W_V(attr_marquee_style);
6985       W_L(";");
6986     }
6987     if (attr_marquee_dir) {
6988       W_L("-webkit-marquee-direction:");
6989       if (STRCASEEQ('r','R',"rtl",attr_marquee_dir)) {
6990         W_L("left");
6991       }
6992       else if (STRCASEEQ('l','L',"ltr",attr_marquee_dir)) {
6993         W_L("right");
6994       }
6995       W_L(";");
6996     }
6997     if (attr_marquee_loop) {
6998       W_L("-webkit-marquee-repetition:");
6999       W_V(attr_marquee_loop);
7000       W_L(";");
7001     }
7002     if (attr_marquee_speed) {
7003       W_L("-webkit-marquee-speed:");
7004       W_V(attr_marquee_speed);
7005       W_L(";");
7006     }
7007     W_L("\"");
7008   }
7009   W_L(">");
7010   W_L("<span");
7011   if (attr_color || attr_size || attr_align || attr_blink || attr_marquee || css_bgcolor) {
7012     W_L(" style=\"");
7013     if (attr_color) {
7014       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
7015       W_L("color:");
7016       W_V(attr_color);
7017       W_L(";");
7018     }
7019     if (attr_size) {
7020       W_L("font-size:");
7021       W_V(attr_size);
7022       W_L(";");
7023     }
7024     if (attr_align) {
7025       W_L("text-align:");
7026       W_V(attr_align);
7027       W_L(";");
7028     }
7029     if (attr_blink) {
7030       W_L(STYLE_BLINK);
7031       if (android->blink_keyframe_out == 0) {
7032         android->style_data = apr_pstrcat(doc->pool, (android->style_data) ? android->style_data : "",
7033                                                     BLINK_KEYFRAME,
7034                                                     NULL);
7035         android->blink_keyframe_out = 1;
7036       }
7037     }
7038     if(css_bgcolor){
7039       W_L("background-color:");
7040       W_V(css_bgcolor);
7041       W_L(";");
7042     }
7043     W_L("\"");
7044   }
7045   W_L(">");
7046   return android->out;
7047 }
7048
7049
7050 /**
7051  * It is a handler who processes the SPAN tag.
7052  *
7053  * @param pdoc  [i/o] The pointer to the JHTML structure at the output
7054  *                     destination is specified.
7055  * @param node   [i]   The SPAN tag node is specified.
7056  * @return The conversion result is returned.
7057  */
7058 static char *
7059 s_android_end_span_tag(void *pdoc, Node *UNUSED(node))
7060 {
7061   android_t *android = GET_ANDROID(pdoc);
7062   Doc *doc = android->doc;
7063
7064   W_L("</span>");
7065   W_L("</div>");
7066   if (IS_CSS_ON(android->entryp)) {
7067     chxj_css_pop_prop_list(android->css_prop_stack);
7068   }
7069   return android->out;
7070 }
7071
7072
7073 /**
7074  * It is a handler who processes the STYLE tag.
7075  *
7076  * @param pdoc  [i/o] The pointer to the XHTML structure at the output
7077  *                     destination is specified.
7078  * @param node   [i]   The STYLE tag node is specified.
7079  * @return The conversion result is returned.
7080  */
7081 static char *
7082 s_android_style_tag(void *pdoc, Node *node)
7083 {
7084   android_t     *android;
7085   Doc           *doc;
7086   Attr          *attr;
7087   char          *type = NULL;
7088   Node          *child   = NULL;
7089   char          *style;
7090
7091   android = GET_ANDROID(pdoc);
7092   doc     = android->doc;
7093
7094   if (! IS_CSS_ON(android->entryp)) {
7095     return android->out;
7096   }
7097
7098   for (attr = qs_get_attr(doc,node);
7099        attr;
7100        attr = qs_get_next_attr(doc,attr)) {
7101     char *name  = qs_get_attr_name(doc,attr);
7102     char *value = qs_get_attr_value(doc,attr);
7103     if (STRCASEEQ('t','T',"type", name)) {
7104       if (value && *value && STRCASEEQ('t','T',"text/css",value)) {
7105         type = value;
7106       }
7107     }
7108   }
7109   if (type) {
7110     style = "";
7111     for (child = qs_get_child_node(doc, node);
7112          child;
7113          child = qs_get_next_node(doc, child)) {
7114       char *name = qs_get_node_name(doc, child);
7115       if (STRCASEEQ('t','T',"text", name)) {
7116         char *value = qs_get_node_value(doc, child);
7117         if (value && *value) {
7118           style = apr_pstrcat(doc->r->pool, style, value, NULL);
7119         }
7120       }
7121     }
7122     if (strlen(style) > 0) {
7123       DBG(doc->r,"REQ[%X] start load CSS. buf:[%s]", TO_ADDR(doc->r),style);
7124       android->style = chxj_css_parse_style_value(doc, android->style, style);
7125       DBG(doc->r,"REQ[%X] end load CSS. value:[%s]", TO_ADDR(doc->r),style);
7126     }
7127   }
7128   return android->out;
7129 }
7130
7131
7132 static char *
7133 s_android_create_style_data(apr_pool_t *pool, const char *style_data)
7134 {
7135   if (! style_data) {
7136     return "";
7137   }
7138   return apr_pstrcat(pool, "<style type=\"text/css\"><![CDATA[",style_data, "]]></style>", NULL);
7139 }
7140
7141 /**
7142  * It is a handler who processes the OBJECT tag.
7143  *
7144  * @param pdoc  [i/o] The pointer to the JHTML structure at the output
7145  *                     destination is specified.
7146  * @param node   [i]   The OBJECT tag node is specified.
7147  * @return The conversion result is returned.
7148  */
7149 static char *
7150 s_android_start_object_tag(void *pdoc, Node *node)
7151 {
7152   android_t *android = GET_ANDROID(pdoc);
7153   Doc *doc = android->doc;
7154   Attr *attr;
7155   
7156   char *attr_id            = NULL;
7157   char *attr_width         = NULL;
7158   char *attr_height        = NULL;
7159   char *attr_data          = NULL;
7160   char *attr_type          = NULL;
7161   char *attr_declare       = NULL;
7162   char *attr_classid       = NULL;
7163   char *attr_codebase      = NULL;
7164   
7165   /*--------------------------------------------------------------------------*/
7166   /* Get Attributes                                                           */
7167   /*--------------------------------------------------------------------------*/
7168   for (attr = qs_get_attr(doc,node);
7169        attr;
7170        attr = qs_get_next_attr(doc,attr)) {
7171     char *name   = qs_get_attr_name(doc,attr);
7172     char *value  = qs_get_attr_value(doc,attr);
7173     if (STRCASEEQ('i','I',"id",name)) {
7174       attr_id = apr_pstrdup(doc->pool, value);
7175     }
7176     else if (STRCASEEQ('w','W',"width",name)) {
7177       attr_width = apr_pstrdup(doc->pool, value);
7178     }
7179     else if (STRCASEEQ('h','H',"height",name)) {
7180       attr_height = apr_pstrdup(doc->pool, value);
7181     }
7182     else if (STRCASEEQ('d','D',"data",name)) {
7183       attr_data = apr_pstrdup(doc->pool, value);
7184     }
7185     else if  (STRCASEEQ('t','T',"type",name)) {
7186       attr_type = apr_pstrdup(doc->pool, value);
7187     }
7188     else if  (STRCASEEQ('d','D',"declare",name)) {
7189       attr_declare = apr_pstrdup(doc->pool, value);
7190     }
7191     else if (STRCASEEQ('c','C',"classid",name)) {
7192       attr_classid = apr_pstrdup(doc->pool, value);
7193     }
7194     else if (STRCASEEQ('c','C',"codebase",name)) {
7195       attr_codebase = apr_pstrdup(doc->pool, value);
7196     }
7197     
7198   }
7199   W_L("<object");
7200   
7201   if(attr_id){
7202     W_L(" id=\"");
7203     W_V(attr_id);
7204     W_L("\"");
7205   }
7206   if(attr_width){
7207     W_L(" width=\"");
7208     W_V(attr_width);
7209     W_L("\"");
7210   }
7211   if(attr_height){
7212     W_L(" height=\"");
7213     W_V(attr_height);
7214     W_L("\"");
7215   }
7216   if(attr_data){
7217     W_L(" data=\"");
7218     W_V(attr_data);
7219     W_L("\"");
7220   }
7221   if(attr_type){
7222     W_L(" type=\"");
7223     W_V(attr_type);
7224     W_L("\"");
7225   }
7226   if(attr_declare){
7227     W_L(" declare=\"declare\"");
7228   }
7229   if(attr_classid){
7230     W_L(" classid=\"");
7231     W_V(attr_classid);
7232     W_L("\"");
7233   }
7234   if(attr_codebase){
7235     W_L(" codebase=\"");
7236     W_V(attr_codebase);
7237     W_L("\"");
7238   }
7239   
7240   W_L(">");
7241   return android->out;
7242 }
7243 /**
7244  * It is a handler who processes the OBJECT tag.
7245  *
7246  * @param pdoc  [i/o] The pointer to the JHTML structure at the output
7247  *                     destination is specified.
7248  * @param node   [i]   The OBJECT tag node is specified.
7249  * @return The conversion result is returned.
7250  */
7251 static char *
7252 s_android_end_object_tag(void *pdoc, Node *UNUSED(node))
7253 {
7254   android_t *android = GET_ANDROID(pdoc);
7255   Doc *doc = android->doc;
7256
7257   W_L("</object>");
7258   return android->out;
7259 }
7260 /**
7261  * It is a handler who processes the OBJECT tag.
7262  *
7263  * @param pdoc  [i/o] The pointer to the JHTML structure at the output
7264  *                     destination is specified.
7265  * @param node   [i]   The OBJECT tag node is specified.
7266  * @return The conversion result is returned.
7267  */
7268 static char *
7269 s_android_start_param_tag(void *pdoc, Node *node)
7270 {
7271   android_t *android = GET_ANDROID(pdoc);
7272   Doc *doc = android->doc;
7273
7274   Attr *attr;
7275   char *attr_name          = NULL;
7276   char *attr_value         = NULL;
7277   char *attr_valuetype     = NULL;
7278   
7279   /*--------------------------------------------------------------------------*/
7280   /* Get Attributes                                                           */
7281   /*--------------------------------------------------------------------------*/
7282   for (attr = qs_get_attr(doc,node);
7283        attr;
7284        attr = qs_get_next_attr(doc,attr)) {
7285     char *name   = qs_get_attr_name(doc,attr);
7286     char *value  = qs_get_attr_value(doc,attr);
7287     if (STRCASEEQ('n','N',"name",name)) {
7288       attr_name = apr_pstrdup(doc->pool, value);
7289     }
7290     else if (STRCASEEQ('v','V',"value",name)) {
7291       attr_value = apr_pstrdup(doc->pool, value);
7292     }
7293     else if (STRCASEEQ('v','V',"valuetype",name)) {
7294       attr_valuetype = apr_pstrdup(doc->pool, value);
7295     }
7296   }
7297   W_L("<param");
7298   
7299   if(attr_name){
7300     W_L(" name=\"");
7301     W_V(attr_name);
7302     W_L("\"");
7303   }
7304   if(attr_value){
7305     W_L(" value=\"");
7306     W_V(attr_value);
7307     W_L("\"");
7308   }
7309   if(attr_valuetype){
7310     W_L(" valuetype=\"");
7311     W_V(attr_valuetype);
7312     W_L("\"");
7313   }
7314   W_L(" />");
7315   return android->out;
7316 }
7317 /**
7318  * It is a handler who processes the CAPTION tag.
7319  *
7320  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
7321  *                     destination is specified.
7322  * @param node   [i]   The CAPTION tag node is specified.
7323  * @return The conversion result is returned.
7324  */
7325 static char *
7326 s_android_start_caption_tag(void *pdoc, Node *node)
7327 {
7328   android_t    *android;
7329   Doc         *doc;
7330   request_rec *r;
7331   Attr        *attr;
7332   char        *attr_style = NULL;
7333   char        *attr_align = NULL;
7334
7335   android = GET_ANDROID(pdoc);
7336   doc    = android->doc;
7337   r      = doc->r;
7338
7339   for (attr = qs_get_attr(doc,node);
7340        attr;
7341        attr = qs_get_next_attr(doc,attr)) {
7342     char *name  = qs_get_attr_name(doc,attr);
7343     char *value = qs_get_attr_value(doc,attr);
7344     if (STRCASEEQ('a','A',"align", name)) {
7345       if (value && 
7346           (STRCASEEQ('l','L',"left",value) 
7347         || STRCASEEQ('r','R',"right",value) 
7348         || STRCASEEQ('t','T',"top",value)
7349         || STRCASEEQ('b','B',"bottom",value) 
7350         )) {
7351         attr_align = value;
7352       }
7353     }
7354     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
7355       attr_style = value;
7356     }
7357   }
7358   
7359   W_L("<caption");
7360   if(attr_align){
7361     W_L(" align=\"");
7362     W_V(attr_align);
7363     W_L("\"");
7364   }
7365   W_L(">");
7366
7367   return android->out;
7368 }
7369
7370
7371 /**
7372  * It is a handler who processes the CAPTION tag.
7373  *
7374  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
7375  *                     destination is specified.
7376  * @param node   [i]   The CAPTION tag node is specified.
7377  * @return The conversion result is returned.
7378  */
7379 static char *
7380 s_android_end_caption_tag(void *pdoc, Node *UNUSED(child)) 
7381 {
7382   android_t*    android = GET_ANDROID(pdoc);
7383   Doc*          doc     = android->doc;
7384   
7385   W_L("</caption>");
7386   
7387   return android->out;
7388 }
7389
7390
7391 /*
7392  * vim:ts=2 et
7393  */