OSDN Git Service

* Changed Mode=WP action for iPhone/Android.
[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 *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   if (android->conf->use_google_analytics) {
1433     android->pagetitle = "";
1434     Node         *child;
1435     for (child = qs_get_child_node(doc,node);
1436          child;
1437          child = qs_get_next_node(doc,child)) {
1438       char *textval = qs_get_node_value(doc,child);
1439       android->pagetitle = apr_pstrcat(doc->r->pool, android->pagetitle, textval, NULL);
1440     }
1441   }
1442
1443   return android->out;
1444 }
1445
1446
1447 /**
1448  * It is a handler who processes the TITLE tag.
1449  *
1450  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1451  *                     destination is specified.
1452  * @param node   [i]   The TITLE tag node is specified.
1453  * @return The conversion result is returned.
1454  */
1455 static char *
1456 s_android_end_title_tag(void *pdoc, Node *UNUSED(child)) 
1457 {
1458   android_t      *android;
1459   Doc           *doc;
1460   request_rec   *r;
1461
1462   android = GET_ANDROID(pdoc);
1463   doc   = android->doc;
1464   r     = doc->r;
1465
1466   W_L("</title>");
1467   return android->out;
1468 }
1469
1470
1471 /**
1472  * It is a handler who processes the BASE tag.
1473  *
1474  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1475  *                     destination is specified.
1476  * @param node   [i]   The BASE tag node is specified.
1477  * @return The conversion result is returned.
1478  */
1479 static char *
1480 s_android_start_base_tag(void *pdoc, Node *node) 
1481 {
1482   android_t      *android;
1483   Attr          *attr;
1484   Doc           *doc;
1485   request_rec   *r;
1486
1487   android = GET_ANDROID(pdoc);
1488   doc   = android->doc;
1489   r     = doc->r;
1490
1491   W_L("<base");
1492   /*--------------------------------------------------------------------------*/
1493   /* Get Attributes                                                           */
1494   /*--------------------------------------------------------------------------*/
1495   for (attr = qs_get_attr(doc,node);
1496        attr;
1497        attr = qs_get_next_attr(doc,attr)) {
1498     char *name  = qs_get_attr_name(doc,attr);
1499     char *value = qs_get_attr_value(doc,attr);
1500     if (STRCASEEQ('h','H',"href",name)) {
1501       W_L(" href=\"");
1502       W_V(value);
1503       W_L("\"");
1504     }
1505   }
1506   W_L(" />");
1507   return android->out;
1508 }
1509
1510
1511 /**
1512  * It is a handler who processes the BASE tag.
1513  *
1514  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1515  *                     destination is specified.
1516  * @param node   [i]   The BASE tag node is specified.
1517  * @return The conversion result is returned.
1518  */
1519 static char *
1520 s_android_end_base_tag(void *pdoc, Node *UNUSED(child)) 
1521 {
1522   android_t *android = GET_ANDROID(pdoc);
1523   return android->out;
1524 }
1525
1526
1527 /**
1528  * It is a handler who processes the BODY tag.
1529  *
1530  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1531  *                     destination is specified.
1532  * @param node   [i]   The BODY tag node is specified.
1533  * @return The conversion result is returned.
1534  */
1535 static char *
1536 s_android_start_body_tag(void *pdoc, Node *node) 
1537 {
1538   android_t    *android;
1539   Doc         *doc;
1540   request_rec *r;
1541   Attr        *attr;
1542   char        *attr_bgcolor = NULL;
1543   char        *attr_text    = NULL;
1544   char        *attr_link    = NULL;
1545   char        *attr_vlink   = NULL;
1546   char        *attr_alink   = NULL;
1547   char        *attr_style   = NULL;
1548   char        *attr_background   = NULL;
1549   char        *style_data   = NULL;
1550
1551   android = GET_ANDROID(pdoc);
1552   doc   = android->doc;
1553   r     = doc->r;
1554
1555
1556   /*--------------------------------------------------------------------------*/
1557   /* Get Attributes                                                           */
1558   /*--------------------------------------------------------------------------*/
1559   for (attr = qs_get_attr(doc,node);
1560        attr;
1561        attr = qs_get_next_attr(doc,attr)) {
1562     char *name   = qs_get_attr_name(doc,attr);
1563     char *value  = qs_get_attr_value(doc,attr);
1564     if (STRCASEEQ('b','B',"bgcolor",name) && value && *value) {
1565       /*----------------------------------------------------------------------*/
1566       /* CHTML 2.0                                                            */
1567       /*----------------------------------------------------------------------*/
1568       attr_bgcolor = value;
1569     }
1570     else if (STRCASEEQ('t','T',"text",name) && value && *value) {
1571       /*----------------------------------------------------------------------*/
1572       /* CHTML 2.0                                                            */
1573       /*----------------------------------------------------------------------*/
1574       attr_text = value;
1575     }
1576     else if (STRCASEEQ('l','L',"link",name) && value && *value) {
1577       /*----------------------------------------------------------------------*/
1578       /* CHTML 2.0                                                            */
1579       /*----------------------------------------------------------------------*/
1580       attr_link = value;
1581     }
1582     else if (STRCASEEQ('a','A',"alink",name)) {
1583       /*----------------------------------------------------------------------*/
1584       /* CHTML 4.0                                                            */
1585       /*----------------------------------------------------------------------*/
1586       attr_alink = value;
1587     }
1588     else if (STRCASEEQ('v','V',"vlink",name)) {
1589       /*----------------------------------------------------------------------*/
1590       /* CHTML 4.0                                                            */
1591       /*----------------------------------------------------------------------*/
1592       attr_vlink = value;
1593     }
1594     else if (STRCASEEQ('b','B',"background",name) && value && *value) {
1595       /*----------------------------------------------------------------------*/
1596       /* CHTML 6.0                                                            */
1597       /*----------------------------------------------------------------------*/
1598       attr_background = value;
1599     }
1600     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
1601       attr_style = value;
1602     }
1603   }
1604
1605   if (IS_CSS_ON(android->entryp)) {
1606     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
1607     if (style) {
1608       css_property_t *color_prop      = chxj_css_get_property_value(doc, style, "color");
1609       css_property_t *bgcolor_prop    = chxj_css_get_property_value(doc, style, "background-color");
1610       css_property_t *bgimage_prop    = chxj_css_get_property_value(doc, style, "background-image");
1611       css_property_t *cur;
1612       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
1613         if (cur->value && *cur->value) {
1614           attr_text = apr_pstrdup(doc->pool, cur->value);
1615         }
1616       }
1617       for (cur = bgcolor_prop->next; cur != bgcolor_prop; cur = cur->next) {
1618         if (cur->value && *cur->value) {
1619           attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
1620         }
1621       }
1622       for (cur = bgimage_prop->next; cur != bgimage_prop; cur = cur->next) {
1623         if (cur->value && *cur->value) {
1624           char *tmp = apr_pstrdup(doc->pool, cur->value);
1625           char *tmps = strstr(tmp,"(");
1626           if(tmps){
1627             char *tmpe = strstr(tmp,")");
1628             size_t len = strlen(tmps) - strlen(tmpe) -1 ;
1629             tmps++;
1630             attr_background = apr_pstrndup(doc->pool, tmps,len);
1631           }
1632         }
1633       }
1634     }
1635     if (android->style) {
1636       css_stylesheet_t *pseudos = chxj_find_pseudo_selectors(doc, android->style);
1637       css_selector_t *cur_sel;
1638       for (cur_sel = pseudos->selector_head.next; cur_sel != &pseudos->selector_head; cur_sel = cur_sel->next) {
1639         if (cur_sel->name && strcasecmp(cur_sel->name, "a:link") == 0) {
1640           css_property_t *cur;
1641           for (cur = cur_sel->property_head.next; cur != &cur_sel->property_head; cur = cur->next) {
1642             if (cur->name && strcasecmp(cur->name, "color") == 0) {
1643               attr_link = apr_pstrdup(doc->pool, cur->value);
1644             }
1645           }
1646         }
1647         else if (cur_sel->name && strcasecmp(cur_sel->name, "a:visited") == 0) {
1648           css_property_t *cur;
1649           for (cur = cur_sel->property_head.next; cur != &cur_sel->property_head; cur = cur->next) {
1650             if (cur->name && strcasecmp(cur->name, "color") == 0) {
1651               attr_vlink = apr_pstrdup(doc->pool, cur->value);
1652             }
1653           }
1654         }
1655       }
1656     }
1657   }
1658
1659
1660   W_L("<body");
1661   if (attr_bgcolor || attr_text) {
1662     W_L(" style=\"");
1663     if (attr_bgcolor) {
1664       attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
1665       W_L("background-color:");
1666       W_V(attr_bgcolor);
1667       W_L(";");
1668     }
1669     if (attr_text) {
1670       attr_text = chxj_css_rgb_func_to_value(doc->pool, attr_text);
1671       W_L("color:");
1672       W_V(attr_text);
1673       W_L(";");
1674     }
1675     W_L("\"");
1676   }
1677   if (attr_link) {
1678     attr_link = chxj_css_rgb_func_to_value(doc->pool, attr_link);
1679     W_L(" link=\"");
1680     W_V(attr_link);
1681     W_L("\"");
1682   }
1683   if (attr_vlink) {
1684     attr_vlink = chxj_css_rgb_func_to_value(doc->pool, attr_vlink);
1685     W_L(" vlink=\"");
1686     W_V(attr_vlink);
1687     W_L("\"");
1688   }
1689   if (attr_alink) {
1690     attr_alink = chxj_css_rgb_func_to_value(doc->pool, attr_alink);
1691     style_data = apr_pstrcat(doc->pool, (style_data) ? style_data : "",
1692                                         apr_psprintf(doc->pool, "a:focus { color:%s; }", attr_alink), NULL);
1693   }
1694   if (attr_background) {
1695     W_L(" background=\"");
1696     W_V(attr_background);
1697     W_L("\"");
1698   }
1699   if (style_data) {
1700     android->style_data = apr_pstrcat(doc->pool, (android->style_data) ? android->style_data : "",
1701                                                 style_data,
1702                                                 NULL);
1703   }
1704   W_L("><div>");
1705   return android->out;
1706 }
1707
1708
1709 /**
1710  * It is a handler who processes the BODY tag.
1711  *
1712  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1713  *                     destination is specified.
1714  * @param node   [i]   The BODY tag node is specified.
1715  * @return The conversion result is returned.
1716  */
1717 static char *
1718 s_android_end_body_tag(void *pdoc, Node *UNUSED(child)) 
1719 {
1720   android_t       *android;
1721   Doc           *doc;
1722   request_rec   *r;
1723
1724   android = GET_ANDROID(pdoc);
1725   doc   = android->doc;
1726   r     = doc->r;
1727
1728   if (android->conf->use_google_analytics) {
1729     char *src = chxj_google_analytics_get_image_url(r, android->pagetitle);
1730     W_L("<img src=\"");
1731     W_V(src);
1732     W_L("\" />");
1733   }
1734   W_L("</div></body>");
1735   if (IS_CSS_ON(android->entryp)) {
1736     chxj_css_pop_prop_list(android->css_prop_stack);
1737   }
1738   return android->out;
1739 }
1740
1741
1742 /**
1743  * It is a handler who processes the A tag.
1744  *
1745  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1746  *                     destination is specified.
1747  * @param node   [i]   The A tag node is specified.
1748  * @return The conversion result is returned.
1749  */
1750 static char *
1751 s_android_start_a_tag(void *pdoc, Node *node) 
1752 {
1753   android_t    *android;
1754   Doc         *doc;
1755   request_rec *r;
1756   Attr        *attr;
1757   char        *attr_style = NULL;
1758   char        *attr_id    = NULL;
1759   char        *attr_name  = NULL;
1760
1761   android = GET_ANDROID(pdoc);
1762   doc   = android->doc;
1763   r     = doc->r;
1764
1765   W_L("<a");
1766   /*--------------------------------------------------------------------------*/
1767   /* Get Attributes                                                           */
1768   /*--------------------------------------------------------------------------*/
1769   for (attr = qs_get_attr(doc,node);
1770        attr; 
1771        attr = qs_get_next_attr(doc,attr)) {
1772     char *name  = qs_get_attr_name(doc,attr);
1773     char *value = qs_get_attr_value(doc,attr);
1774     if (STRCASEEQ('i','I',"id",name)){
1775       attr_id = chxj_jreserved_to_safe_tag(r, value, android->entryp);
1776     }
1777     else if (STRCASEEQ('n','N',"name",name)) {
1778       attr_name = chxj_jreserved_to_safe_tag(r, value, android->entryp);
1779     }
1780     else if (STRCASEEQ('h','H',"href",name)) {
1781       /*----------------------------------------------------------------------*/
1782       /* CHTML1.0                                                             */
1783       /*----------------------------------------------------------------------*/
1784       value = chxj_encoding_parameter(r, value, 1);
1785       if (! chxj_starts_with(value, "mailto:") && ! chxj_starts_with(value, "tel:")) {
1786         value = chxj_jreserved_tag_to_safe_for_query_string(r, value, android->entryp, 1);
1787       }
1788       W_L(" href=\"");
1789       W_V(value);
1790       W_L("\"");
1791     }
1792     else if (STRCASEEQ('a','A',"accesskey",name)) {
1793       /*----------------------------------------------------------------------*/
1794       /* CHTML1.0                                                             */
1795       /*----------------------------------------------------------------------*/
1796       /* not need */
1797     }
1798     else if (STRCASEEQ('c','C',"cti",name)) {
1799       /*----------------------------------------------------------------------*/
1800       /* CHTML 2.0                                                            */
1801       /*----------------------------------------------------------------------*/
1802       /* ignore */
1803     }
1804     else if (STRCASEEQ('i','I',"ijam",name)) {
1805       /*----------------------------------------------------------------------*/
1806       /* CHTML 3.0                                                            */
1807       /*----------------------------------------------------------------------*/
1808       /* ignore */
1809     }
1810     else if (STRCASEEQ('u','U',"utn",name)) {
1811       /*----------------------------------------------------------------------*/
1812       /* CHTML 3.0                                                            */
1813       /* It is special only for CHTML.                                        */
1814       /*----------------------------------------------------------------------*/
1815       /* ignore */
1816     }
1817     else if (STRCASEEQ('t','T',"telbook",name)) {
1818       /*----------------------------------------------------------------------*/
1819       /* CHTML 3.0                                                            */
1820       /*----------------------------------------------------------------------*/
1821       /* not support */
1822     }
1823     else if (STRCASEEQ('k','K',"kana",name)) {
1824       /*----------------------------------------------------------------------*/
1825       /* CHTML 3.0                                                            */
1826       /*----------------------------------------------------------------------*/
1827       /* not support */
1828     }
1829     else if (STRCASEEQ('e','E',"email",name)) {
1830       /*----------------------------------------------------------------------*/
1831       /* CHTML 3.0                                                            */
1832       /*----------------------------------------------------------------------*/
1833       /* not support */
1834     }
1835     else if (STRCASEEQ('i','I',"ista",name)) {
1836       /*----------------------------------------------------------------------*/
1837       /* CHTML 4.0                                                            */
1838       /*----------------------------------------------------------------------*/
1839       /* ignore */
1840     }
1841     else if (STRCASEEQ('i','I',"ilet",name)) {
1842       /*----------------------------------------------------------------------*/
1843       /* CHTML 5.0                                                            */
1844       /*----------------------------------------------------------------------*/
1845       /* ignore */
1846     }
1847     else if (STRCASEEQ('i','I',"iswf",name)) {
1848       /*----------------------------------------------------------------------*/
1849       /* CHTML 5.0                                                            */
1850       /*----------------------------------------------------------------------*/
1851       /* ignore */
1852     }
1853     else if (STRCASEEQ('i','I',"irst",name)) {
1854       /*----------------------------------------------------------------------*/
1855       /* CHTML 5.0                                                            */
1856       /*----------------------------------------------------------------------*/
1857       /* ignore */
1858     }
1859     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
1860       /*----------------------------------------------------------------------*/
1861       /* CHTML 5.0                                                            */
1862       /*----------------------------------------------------------------------*/
1863       attr_style = value;
1864     }
1865   }
1866   if(attr_id){
1867     W_L(" id=\"");
1868     W_V(attr_id);
1869     W_L("\"");
1870   }
1871   if (attr_name) {
1872     W_L(" name=\"");
1873     W_V(attr_name);
1874     W_L("\"");
1875   }
1876   W_L(">");
1877
1878   if (IS_CSS_ON(android->entryp)) {
1879     s_android_nopush_and_get_now_style(pdoc, node, attr_style);
1880   }
1881
1882   return android->out;
1883 }
1884
1885
1886 /**
1887  * It is a handler who processes the A tag.
1888  *
1889  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1890  *                     destination is specified.
1891  * @param node   [i]   The A tag node is specified.
1892  * @return The conversion result is returned.
1893  */
1894 static char *
1895 s_android_end_a_tag(void *pdoc, Node *UNUSED(child)) 
1896 {
1897   android_t      *android;
1898   Doc          *doc;
1899   request_rec  *r;
1900
1901   android = GET_ANDROID(pdoc);
1902   doc   = android->doc;
1903   r     = doc->r;
1904
1905   W_L("</a>");
1906
1907   if (IS_CSS_ON(android->entryp)) {
1908     chxj_css_pop_prop_list(android->css_prop_stack);
1909   }
1910
1911   return android->out;
1912 }
1913
1914
1915 /**
1916  * It is a handler who processes the BR tag.
1917  *
1918  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1919  *                     destination is specified.
1920  * @param node   [i]   The BR tag node is specified.
1921  * @return The conversion result is returned.
1922  */
1923 static char *
1924 s_android_start_br_tag(void *pdoc, Node *node)
1925 {
1926   android_t     *android;
1927   Doc          *doc;
1928   request_rec  *r;
1929   Attr         *attr;
1930
1931   android = GET_ANDROID(pdoc);
1932   doc   = android->doc;
1933   r     = doc->r;
1934   
1935   char         *attr_style = NULL;
1936   char         *attr_clear = NULL;
1937
1938   /*--------------------------------------------------------------------------*/
1939   /* Get Attributes                                                           */
1940   /*--------------------------------------------------------------------------*/
1941   for (attr = qs_get_attr(doc,node);
1942        attr;
1943        attr = qs_get_next_attr(doc,attr)) {
1944     char *name  = qs_get_attr_name(doc,attr);
1945     char *value = qs_get_attr_value(doc,attr);
1946     if (STRCASEEQ('c','C',"clear",name)) {
1947       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('a','A',"all",value))) {
1948         attr_clear = value;
1949       }
1950     }
1951     else if (STRCASEEQ('s','S',"style",name)) {
1952       attr_style = apr_pstrdup(doc->buf.pool, value);
1953     }
1954   }
1955   if (IS_CSS_ON(android->entryp)) {
1956     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
1957     if (style) {
1958       css_property_t *clear_prop = chxj_css_get_property_value(doc, style, "clear");
1959       css_property_t *cur;
1960       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
1961         if (cur->value && *cur->value) {
1962           if ( STRCASEEQ('l','L',"left",  cur->value)
1963             || STRCASEEQ('r','R',"right", cur->value)) {
1964             attr_clear = apr_pstrdup(doc->pool, cur->value);
1965           }
1966           else if(STRCASEEQ('b','B',"both"  ,cur->value)) {
1967             attr_clear = apr_pstrdup(doc->pool, "all");
1968           }
1969         }
1970       }
1971     }
1972   }
1973   W_L("<br");
1974   if(attr_clear){
1975     W_L(" clear=\"");
1976     W_V(attr_clear);
1977     W_L("\"");
1978   }
1979   W_L(" />");
1980   return android->out;
1981 }
1982
1983
1984 /**
1985  * It is a handler who processes the BR tag.
1986  *
1987  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
1988  *                     destination is specified.
1989  * @param node   [i]   The BR tag node is specified.
1990  * @return The conversion result is returned.
1991  */
1992 static char *
1993 s_android_end_br_tag(void *pdoc, Node *UNUSED(child)) 
1994 {
1995   android_t *android = GET_ANDROID(pdoc);
1996   return android->out;
1997 }
1998
1999 /**
2000  * It is a handler who processes the TABLE tag.
2001  *
2002  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2003  *                     destination is specified.
2004  * @param node   [i]   The TR tag node is specified.
2005  * @return The conversion result is returned.
2006  */
2007 static char *
2008 s_android_start_table_tag(void *pdoc, Node *node) 
2009 {
2010   android_t     *android;
2011   Doc          *doc;
2012   request_rec  *r;
2013   Attr         *attr;
2014   
2015   char         *attr_style  = NULL;
2016   char         *attr_align  = NULL;
2017   char         *attr_width  = NULL;
2018   char         *attr_height = NULL;
2019   char         *attr_bgcolor = NULL;
2020   char         *attr_border_width  = NULL;
2021   char         *attr_border_color  = NULL;
2022
2023   android = GET_ANDROID(pdoc);
2024   doc   = android->doc;
2025   r     = doc->r;
2026   
2027   /*--------------------------------------------------------------------------*/
2028   /* Get Attributes                                                           */
2029   /*--------------------------------------------------------------------------*/
2030   for (attr = qs_get_attr(doc,node);
2031        attr;
2032        attr = qs_get_next_attr(doc,attr)) {
2033     char *name  = qs_get_attr_name(doc,attr);
2034     char *val   = qs_get_attr_value(doc,attr);
2035     if (STRCASEEQ('a','A',"align",name)) {
2036       if (val && (STRCASEEQ('l','L',"left",val) || STRCASEEQ('r','R',"right",val) || STRCASEEQ('c','C',"center",val))) {
2037         attr_align = apr_pstrdup(doc->buf.pool, val);
2038       }
2039     }
2040     else if (STRCASEEQ('h','H',"height",name) && val && *val) {
2041       attr_height = apr_pstrdup(doc->buf.pool, val);
2042     }
2043     else if (STRCASEEQ('w','W',"width",name) && val && *val) {
2044       attr_width = apr_pstrdup(doc->buf.pool, val);
2045     }
2046     else if (STRCASEEQ('s','S',"style",name) && val && *val) {
2047       attr_style = apr_pstrdup(doc->buf.pool, val);
2048     }
2049     else if (STRCASEEQ('b','B',"bgcolor",name) && val && *val) {
2050       attr_bgcolor = apr_pstrdup(doc->buf.pool, val);
2051       attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
2052     }
2053     else if (STRCASEEQ('b','B',"border",name) && val && *val) {
2054       attr_border_width = apr_pstrdup(doc->buf.pool, val);
2055     }
2056     else if (STRCASEEQ('b','B',"bordercolor",name) && val && *val) {
2057       attr_border_color = apr_pstrdup(doc->buf.pool, val);
2058       attr_border_color = chxj_css_rgb_func_to_value(doc->pool, attr_border_color);
2059     }
2060   }
2061   
2062   if (IS_CSS_ON(android->entryp)) {
2063     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
2064     if (style) {
2065       css_property_t *width_prop             = chxj_css_get_property_value(doc, style, "width");
2066       css_property_t *height_prop            = chxj_css_get_property_value(doc, style, "height");
2067       css_property_t *align_prop             = chxj_css_get_property_value(doc, style, "text-align");
2068       css_property_t *bgcolor_prop           = chxj_css_get_property_value(doc, style, "background-color");
2069       css_property_t *border_width_prop      = chxj_css_get_property_value(doc, style, "border-width");
2070       css_property_t *border_color_prop      = chxj_css_get_property_value(doc, style, "border-color");
2071       
2072       css_property_t *cur;
2073       for (cur = width_prop->next; cur != width_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_width = apr_pstrndup(doc->pool, tmp,len);
2079         }
2080         else{
2081           attr_width = apr_pstrdup(doc->pool, tmp);
2082         }
2083       }
2084       for (cur = height_prop->next; cur != height_prop; cur = cur->next) {
2085         char *tmp = apr_pstrdup(doc->pool, cur->value);
2086         char *tmpp = strstr(tmp, "px");
2087         if (tmpp) {
2088           size_t len = strlen(tmp) - strlen(tmpp);
2089           attr_height = apr_pstrndup(doc->pool, tmp,len);
2090         }
2091         else{
2092           attr_height = apr_pstrdup(doc->pool, tmp);
2093         }
2094       }
2095       for (cur = align_prop->next; cur != align_prop; cur = cur->next) {
2096         if (cur->value && (STRCASEEQ('l','L',"left",cur->value) || STRCASEEQ('r','R',"right",cur->value) || STRCASEEQ('c','C',"center",cur->value))) {
2097           attr_align = apr_pstrdup(doc->buf.pool, cur->value);
2098         }
2099       }
2100       for (cur = bgcolor_prop->next; cur != bgcolor_prop; cur = cur->next) {
2101         attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
2102         attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
2103       }
2104       for (cur = border_width_prop->next; cur != border_width_prop; cur = cur->next) {
2105         char *tmp = apr_pstrdup(doc->pool, cur->value);
2106         char *tmpp = strstr(tmp, "px");
2107         if (tmpp) {
2108           size_t len = strlen(tmp) - strlen(tmpp);
2109           attr_border_width = apr_pstrndup(doc->pool, tmp,len);
2110         }
2111         else{
2112           attr_border_width = apr_pstrdup(doc->pool, tmp);
2113         }
2114       }
2115       for (cur = border_color_prop->next; cur != border_color_prop; cur = cur->next) {
2116         attr_border_color = apr_pstrdup(doc->pool, cur->value);
2117         attr_border_color = chxj_css_rgb_func_to_value(doc->pool, attr_border_color);
2118       }
2119     }
2120   }
2121
2122   W_L("<table");
2123   if (attr_align){
2124     W_L(" align=\"");
2125     W_V(attr_align);
2126     W_L("\"");
2127   }
2128   if (attr_height){
2129     W_L(" height=\"");
2130     W_V(attr_height);
2131     W_L("\"");
2132   }
2133   if (attr_width){
2134     W_L(" width=\"");
2135     W_V(attr_width);
2136     W_L("\"");
2137   }
2138   if (attr_bgcolor && *attr_bgcolor){
2139     W_L(" bgcolor=\"");
2140     W_V(attr_bgcolor);
2141     W_L("\"");
2142   }
2143   if (attr_border_width || attr_border_color ){
2144     W_L(" style=\"border:");
2145     if (attr_border_width){
2146       W_V(attr_border_width);
2147     }
2148     else{
2149       W_L("1");
2150     }
2151     W_L("px solid");
2152     
2153     if (attr_border_color && *attr_border_color){
2154       W_L(" ");
2155       W_V(attr_border_color);
2156     }
2157     W_L(";\"");
2158   }
2159   W_L(">");
2160   
2161   return android->out;
2162 }
2163
2164 /**
2165  * It is a handler who processes the TABLE tag.
2166  *
2167  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2168  *                     destination is specified.
2169  * @param node   [i]   The TR tag node is specified.
2170  * @return The conversion result is returned.
2171  */
2172 static char *
2173 s_android_end_table_tag(void *pdoc, Node *UNUSED(node)) 
2174 {
2175   android_t      *android;
2176   request_rec  *r;
2177   Doc          *doc;
2178
2179   android = GET_ANDROID(pdoc);
2180   doc   = android->doc;
2181   r     = android->doc->r;
2182   
2183   W_L("</table>");
2184   return android->out;
2185 }
2186
2187
2188 /**
2189  * It is a handler who processes the TR tag.
2190  *
2191  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2192  *                     destination is specified.
2193  * @param node   [i]   The TR tag node is specified.
2194  * @return The conversion result is returned.
2195  */
2196 static char *
2197 s_android_start_tr_tag(void *pdoc, Node *node) 
2198 {
2199   android_t      *android;
2200   Doc          *doc;
2201   request_rec  *r;
2202   
2203   Attr         *attr;
2204   
2205   char         *attr_style  = NULL;
2206   char         *attr_align  = NULL;
2207   char         *attr_valign = NULL;
2208   char         *attr_bgcolor = NULL;
2209
2210   android = GET_ANDROID(pdoc);
2211   doc   = android->doc;
2212   r     = doc->r;
2213   
2214   /*--------------------------------------------------------------------------*/
2215   /* Get Attributes                                                           */
2216   /*--------------------------------------------------------------------------*/
2217   for (attr = qs_get_attr(doc,node);
2218        attr;
2219        attr = qs_get_next_attr(doc,attr)) {
2220     char *name  = qs_get_attr_name(doc,attr);
2221     char *val   = qs_get_attr_value(doc,attr);
2222     if (STRCASEEQ('a','A',"align",name)) {
2223       if (val && (STRCASEEQ('l','L',"left",val) || STRCASEEQ('r','R',"right",val) || STRCASEEQ('c','C',"center",val))) {
2224         attr_align = apr_pstrdup(doc->buf.pool, val);
2225       }
2226     }
2227     else if (STRCASEEQ('v','V',"valign",name) && val && *val) {
2228       if (val && (STRCASEEQ('t','T',"top",val) || STRCASEEQ('m','M',"middle",val) || STRCASEEQ('b','B',"bottom",val))) {
2229         attr_valign = apr_pstrdup(doc->buf.pool, val);
2230       }
2231     }
2232     else if (STRCASEEQ('s','S',"style",name) && val && *val) {
2233       attr_style = apr_pstrdup(doc->buf.pool, val);
2234     }
2235     else if (STRCASEEQ('b','B',"bgcolor",name) && val && *val) {
2236       attr_bgcolor = apr_pstrdup(doc->buf.pool, val);
2237       attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
2238     }
2239   }
2240   
2241   if (IS_CSS_ON(android->entryp)) {
2242     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
2243     if (style) {
2244       css_property_t *align_prop             = chxj_css_get_property_value(doc, style, "text-align");
2245       css_property_t *valign_prop            = chxj_css_get_property_value(doc, style, "vertical-align");
2246       css_property_t *bgcolor_prop           = chxj_css_get_property_value(doc, style, "background-color");
2247       
2248       css_property_t *cur;
2249       for (cur = align_prop->next; cur != align_prop; cur = cur->next) {
2250         if (cur->value && (STRCASEEQ('l','L',"left",cur->value) || STRCASEEQ('r','R',"right",cur->value) || STRCASEEQ('c','C',"center",cur->value))) {
2251           attr_align = apr_pstrdup(doc->buf.pool, cur->value);
2252         }
2253       }
2254       for (cur = valign_prop->next; cur != valign_prop; cur = cur->next) {
2255         if (cur->value && (STRCASEEQ('t','T',"top",cur->value) || STRCASEEQ('m','M',"middle",cur->value) || STRCASEEQ('b','B',"bottom",cur->value))) {
2256           attr_valign = apr_pstrdup(doc->buf.pool, cur->value);
2257         }
2258       }
2259       for (cur = bgcolor_prop->next; cur != bgcolor_prop; cur = cur->next) {
2260         attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
2261         attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
2262       }
2263     }
2264   }
2265
2266   W_L("<tr");
2267   if (attr_align){
2268     W_L(" align=\"");
2269     W_V(attr_align);
2270     W_L("\"");
2271   }
2272   if (attr_valign){
2273     W_L(" valign=\"");
2274     W_V(attr_valign);
2275     W_L("\"");
2276   }
2277   if (attr_bgcolor && *attr_bgcolor){
2278     W_L(" bgcolor=\"");
2279     W_V(attr_bgcolor);
2280     W_L("\"");
2281   }
2282   W_L(">");
2283   return android->out;
2284 }
2285
2286
2287 /**
2288  * It is a handler who processes the TR tag.
2289  *
2290  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2291  *                     destination is specified.
2292  * @param node   [i]   The TR tag node is specified.
2293  * @return The conversion result is returned.
2294  */
2295 static char *
2296 s_android_end_tr_tag(void *pdoc, Node *UNUSED(child)) 
2297 {
2298   android_t      *android;
2299   request_rec  *r;
2300   Doc          *doc;
2301
2302   android = GET_ANDROID(pdoc);
2303   doc   = android->doc;
2304   r     = android->doc->r;
2305   
2306   W_L("</tr>");
2307   return android->out;
2308 }
2309
2310 /**
2311  * It is a handler who processes the TD tag.
2312  *
2313  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2314  *                     destination is specified.
2315  * @param node   [i]   The TR tag node is specified.
2316  * @return The conversion result is returned.
2317  */
2318 static char *
2319 s_android_start_td_or_th_tag(void *pdoc, Node *node,char *tagName) 
2320 {
2321   android_t      *android;
2322   Doc          *doc;
2323   request_rec  *r;
2324
2325   Attr         *attr;
2326   
2327   char         *attr_style  = NULL;
2328   char         *attr_align  = NULL;
2329   char         *attr_valign = NULL;
2330   char         *attr_bgcolor = NULL;
2331   char         *attr_colspan = NULL;
2332   char         *attr_rowspan = NULL;
2333   char         *attr_width   = NULL;
2334   char         *attr_height  = NULL;
2335
2336   android = GET_ANDROID(pdoc);
2337   doc   = android->doc;
2338   r     = doc->r;
2339   
2340   /*--------------------------------------------------------------------------*/
2341   /* Get Attributes                                                           */
2342   /*--------------------------------------------------------------------------*/
2343   for (attr = qs_get_attr(doc,node);
2344        attr;
2345        attr = qs_get_next_attr(doc,attr)) {
2346     char *name  = qs_get_attr_name(doc,attr);
2347     char *val   = qs_get_attr_value(doc,attr);
2348     if (STRCASEEQ('a','A',"align",name)) {
2349       if (val && (STRCASEEQ('l','L',"left",val) || STRCASEEQ('r','R',"right",val) || STRCASEEQ('c','C',"center",val))) {
2350         attr_align = apr_pstrdup(doc->buf.pool, val);
2351       }
2352     }
2353     else if (STRCASEEQ('v','V',"valign",name) && val && *val) {
2354       if (val && (STRCASEEQ('t','T',"top",val) || STRCASEEQ('m','M',"middle",val) || STRCASEEQ('b','B',"bottom",val))) {
2355         attr_valign = apr_pstrdup(doc->buf.pool, val);
2356       }
2357     }
2358     else if (STRCASEEQ('s','S',"style",name) && val && *val) {
2359       attr_style = apr_pstrdup(doc->buf.pool, val);
2360     }
2361     else if (STRCASEEQ('b','B',"bgcolor",name) && val && *val) {
2362       attr_bgcolor = apr_pstrdup(doc->buf.pool, val);
2363       attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
2364     }
2365     else if (STRCASEEQ('c','C',"colspan",name) && val && *val) {
2366       attr_colspan = apr_pstrdup(doc->buf.pool, val);
2367     }
2368     else if (STRCASEEQ('r','R',"rowspan",name) && val && *val) {
2369       attr_rowspan = apr_pstrdup(doc->buf.pool, val);
2370     }
2371     else if (STRCASEEQ('w','W',"width",name) && val && *val) {
2372       char *tmp = strstr(val, "%");
2373       if(tmp){
2374         attr_width = apr_pstrdup(doc->buf.pool, val);
2375       }
2376       else{
2377         attr_width = apr_psprintf(doc->buf.pool,"%spx",val);
2378       }
2379     }
2380     else if (STRCASEEQ('h','H',"height",name) && val && *val) {
2381       char *tmp = strstr(val, "%");
2382       if(tmp){
2383         attr_height = apr_pstrdup(doc->buf.pool, val);
2384       }
2385       else{
2386         attr_height = apr_psprintf(doc->buf.pool,"%spx",val);
2387       }
2388     }
2389   }
2390   
2391   if (IS_CSS_ON(android->entryp)) {
2392     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
2393     if (style) {
2394       css_property_t *align_prop             = chxj_css_get_property_value(doc, style, "text-align");
2395       css_property_t *valign_prop            = chxj_css_get_property_value(doc, style, "vertical-align");
2396       css_property_t *bgcolor_prop           = chxj_css_get_property_value(doc, style, "background-color");
2397       css_property_t *width_prop             = chxj_css_get_property_value(doc, style, "width");
2398       css_property_t *height_prop            = chxj_css_get_property_value(doc, style, "height");
2399       
2400       css_property_t *cur;
2401       for (cur = align_prop->next; cur != align_prop; cur = cur->next) {
2402         if (cur->value && (STRCASEEQ('l','L',"left",cur->value) || STRCASEEQ('r','R',"right",cur->value) || STRCASEEQ('c','C',"center",cur->value))) {
2403           attr_align = apr_pstrdup(doc->buf.pool, cur->value);
2404         }
2405       }
2406       for (cur = valign_prop->next; cur != valign_prop; cur = cur->next) {
2407         if (cur->value && (STRCASEEQ('t','T',"top",cur->value) || STRCASEEQ('m','M',"middle",cur->value) || STRCASEEQ('b','B',"bottom",cur->value))) {
2408           attr_valign = apr_pstrdup(doc->buf.pool, cur->value);
2409         }
2410       }
2411       for (cur = bgcolor_prop->next; cur != bgcolor_prop; cur = cur->next) {
2412         attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
2413         attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
2414       }
2415       for (cur = width_prop->next; cur != width_prop; cur = cur->next) {
2416         attr_width = apr_pstrdup(doc->pool, cur->value);
2417       }
2418       for (cur = height_prop->next; cur != height_prop; cur = cur->next) {
2419         attr_height = apr_pstrdup(doc->pool, cur->value);
2420       }
2421     }
2422   }
2423
2424   W_L("<");
2425   W_V(tagName);
2426   if (attr_align){
2427     W_L(" align=\"");
2428     W_V(attr_align);
2429     W_L("\"");
2430   }
2431   if (attr_valign){
2432     W_L(" valign=\"");
2433     W_V(attr_valign);
2434     W_L("\"");
2435   }
2436   if (attr_colspan){
2437     W_L(" colspan=\"");
2438     W_V(attr_colspan);
2439     W_L("\"");
2440   }
2441   if (attr_rowspan){
2442     W_L(" rowspan=\"");
2443     W_V(attr_rowspan);
2444     W_L("\"");
2445   }
2446   if (attr_bgcolor && *attr_bgcolor){
2447     W_L(" bgcolor=\"");
2448     W_V(attr_bgcolor);
2449     W_L("\"");
2450   }
2451   if (attr_width || attr_height ){
2452     W_L(" style=\"");
2453     if (attr_width){
2454       W_L("width:");
2455       W_V(attr_width);
2456       W_L(";");
2457     }
2458     if (attr_height){
2459       W_L("height:");
2460       W_V(attr_height);
2461       W_L(";");
2462     }
2463     W_L("\"");
2464   }
2465   W_L(">");
2466   return android->out;
2467 }
2468
2469
2470 /**
2471  * It is a handler who processes the TD tag.
2472  *
2473  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2474  *                     destination is specified.
2475  * @param node   [i]   The TR tag node is specified.
2476  * @return The conversion result is returned.
2477  */
2478 static char *
2479 s_android_end_td_or_th_tag(void *pdoc, Node *UNUSED(child),char *tagName) 
2480 {
2481   android_t      *android;
2482   request_rec  *r;
2483   Doc          *doc;
2484
2485   android = GET_ANDROID(pdoc);
2486   doc   = android->doc;
2487   r     = android->doc->r;
2488   
2489   W_L("</");
2490   W_V(tagName);
2491   W_L(">");
2492   return android->out;
2493 }
2494
2495 /**
2496  * It is a handler who processes the TD tag.
2497  *
2498  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2499  *                     destination is specified.
2500  * @param node   [i]   The TD tag node is specified.
2501  * @return The conversion result is returned.
2502  */
2503 static char *
2504 s_android_start_td_tag(void *pdoc, Node *node) 
2505 {
2506   return s_android_start_td_or_th_tag(pdoc,node,"td");
2507 }
2508 /**
2509  * It is a handler who processes the TD tag.
2510  *
2511  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2512  *                     destination is specified.
2513  * @param node   [i]   The TD tag node is specified.
2514  * @return The conversion result is returned.
2515  */
2516 static char *
2517 s_android_end_td_tag(void *pdoc, Node *node) 
2518 {
2519   return s_android_end_td_or_th_tag(pdoc,node,"td");
2520 }
2521
2522 /**
2523  * It is a handler who processes the TD tag.
2524  *
2525  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2526  *                     destination is specified.
2527  * @param node   [i]   The TD tag node is specified.
2528  * @return The conversion result is returned.
2529  */
2530 static char *
2531 s_android_start_th_tag(void *pdoc, Node *node) 
2532 {
2533   return s_android_start_td_or_th_tag(pdoc,node,"th");
2534 }
2535 /**
2536  * It is a handler who processes the TD tag.
2537  *
2538  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2539  *                     destination is specified.
2540  * @param node   [i]   The TD tag node is specified.
2541  * @return The conversion result is returned.
2542  */
2543 static char *
2544 s_android_end_th_tag(void *pdoc, Node *node) 
2545 {
2546   return s_android_end_td_or_th_tag(pdoc,node,"th");
2547 }
2548
2549 /**
2550  * It is a handler who processes the FONT tag.
2551  *
2552  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2553  *                     destination is specified.
2554  * @param node   [i]   The FONT tag node is specified.
2555  * @return The conversion result is returned.
2556  */
2557 static char *
2558 s_android_start_font_tag(void *pdoc, Node *node) 
2559 {
2560   android_t      *android;
2561   Doc           *doc;
2562   request_rec   *r;
2563   Attr          *attr;
2564   char          *attr_color = NULL;
2565   char          *attr_size  = NULL;
2566   char          *attr_style = NULL;
2567
2568   android = GET_ANDROID(pdoc);
2569   doc   = android->doc;
2570   r     = doc->r;
2571
2572   /*--------------------------------------------------------------------------*/
2573   /* Get Attributes                                                           */
2574   /*--------------------------------------------------------------------------*/
2575   for (attr = qs_get_attr(doc,node);
2576        attr; 
2577        attr = qs_get_next_attr(doc,attr)) {
2578     char *name  = qs_get_attr_name(doc,attr);
2579     char *value = qs_get_attr_value(doc,attr);
2580     if (STRCASEEQ('c','C',"color",name) && value && *value) {
2581       attr_color = apr_pstrdup(doc->buf.pool, value);
2582     }
2583     else if (STRCASEEQ('s','S',"size",name) && value && *value) {
2584       /*----------------------------------------------------------------------*/
2585       /* CHTML 5.0                                                            */
2586       /*----------------------------------------------------------------------*/
2587       attr_size = apr_pstrdup(doc->buf.pool, value);
2588     }
2589     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
2590       attr_style = apr_pstrdup(doc->buf.pool, value);
2591     }
2592   }
2593   if (IS_CSS_ON(android->entryp)) {
2594     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
2595     if (style) {
2596       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
2597       css_property_t *size_prop  = chxj_css_get_property_value(doc, style, "font-size");
2598       css_property_t *cur;
2599       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
2600         if (cur->value && *cur->value) {
2601           attr_color = apr_pstrdup(doc->pool, cur->value);
2602         }
2603       }
2604       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
2605         if (cur->value && *cur->value) {
2606           attr_size = apr_pstrdup(doc->pool, cur->value);
2607           if (STRCASEEQ('x','X',"xx-small",attr_size)) {
2608             attr_size = apr_pstrdup(doc->pool, "1");
2609           }
2610           else if (STRCASEEQ('x','X',"x-small",attr_size)) {
2611             attr_size = apr_pstrdup(doc->pool, "2");
2612           }
2613           else if (STRCASEEQ('s','S',"small",attr_size)) {
2614             attr_size = apr_pstrdup(doc->pool, "3");
2615           }
2616           else if (STRCASEEQ('m','M',"medium",attr_size)) {
2617             attr_size = apr_pstrdup(doc->pool, "4");
2618           }
2619           else if (STRCASEEQ('l','L',"large",attr_size)) {
2620             attr_size = apr_pstrdup(doc->pool, "5");
2621           }
2622           else if (STRCASEEQ('x','X',"x-large",attr_size)) {
2623             attr_size = apr_pstrdup(doc->pool, "6");
2624           }
2625           else if (STRCASEEQ('x','X',"xx-large",attr_size)) {
2626             attr_size = apr_pstrdup(doc->pool, "7");
2627           }
2628         }
2629       }
2630     }
2631   }
2632   android_flags_t *flg = (android_flags_t *)apr_palloc(doc->pool, sizeof(*flg));
2633   memset(flg, 0, sizeof(*flg));
2634   if (attr_color) {
2635     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
2636     W_L("<font color=\"");
2637     W_V(attr_color);
2638     W_L("\">");
2639     flg->font_color_flag = 1;
2640   }
2641   if (attr_size) {
2642     flg->font_size_flag = 1;
2643     switch(*attr_size) {
2644     case '1': W_L("<span style=\"font-size: xx-small\">"); break;
2645     case '2': W_L("<span style=\"font-size: x-small\">");  break;
2646     case '3': W_L("<span style=\"font-size: small\">");    break;
2647     case '4': W_L("<span style=\"font-size: medium\">");   break;
2648     case '5': W_L("<span style=\"font-size: large\">");    break;
2649     case '6': W_L("<span style=\"font-size: x-large\">");  break;
2650     case '7': W_L("<span style=\"font-size: xx-large\">"); break;
2651     case '-':
2652       if (*(attr_size + 1) == '1') {
2653         W_L("<span style=\"font-size: small\">");
2654         break;
2655       }
2656       if (*(attr_size + 1) == '2') {
2657         W_L("<span style=\"font-size: x-small\">");
2658         break;
2659       }
2660       if (*(attr_size + 1) == '3') {
2661         W_L("<span style=\"font-size: xx-small\">");
2662         break;
2663       }
2664       flg->font_size_flag = 0;
2665       break;
2666
2667     case '+':
2668       if (*(attr_size + 1) == '1') {
2669         W_L("<span style=\"font-size: large\">");
2670         break;
2671       }
2672       if (*(attr_size + 1) == '2') {
2673         W_L("<span style=\"font-size: x-large\">");
2674         break;
2675       }
2676       if (*(attr_size + 1) == '3') {
2677         W_L("<span style=\"font-size: xx-large\">");
2678         break;
2679       }
2680       flg->font_size_flag = 0;
2681       break;
2682
2683     default:
2684       WRN(doc->r, "invlalid font size. [%s] != (1|2|3|4|5|6|7|+1|+2|+3|-1|-2|-3)", attr_size);
2685       flg->font_size_flag = 0;
2686     }
2687   }
2688   node->userData = flg;
2689   return android->out;
2690 }
2691
2692
2693 /**
2694  * It is a handler who processes the FONT tag.
2695  *
2696  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2697  *                     destination is specified.
2698  * @param node   [i]   The FONT tag node is specified.
2699  * @return The conversion result is returned.
2700  */
2701 static char *
2702 s_android_end_font_tag(void *pdoc, Node *node)
2703 {
2704   android_t      *android;
2705   request_rec  *r;
2706   Doc          *doc;
2707
2708   android = GET_ANDROID(pdoc);
2709   doc   = android->doc;
2710   r     = android->doc->r;
2711
2712   android_flags_t *flg = (android_flags_t *)node->userData;
2713   if (flg && flg->font_size_flag) {
2714     W_L("</span>");
2715   }
2716   if (flg && flg->font_color_flag) {
2717     W_L("</font>");
2718   }
2719   if (IS_CSS_ON(android->entryp)) {
2720     chxj_css_pop_prop_list(android->css_prop_stack);
2721   }
2722
2723   return android->out;
2724 }
2725
2726
2727 /**
2728  * It is a handler who processes the FORM tag.
2729  *
2730  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2731  *                     destination is specified.
2732  * @param node   [i]   The FORM tag node is specified.
2733  * @return The conversion result is returned.
2734  */
2735 static char *
2736 s_android_start_form_tag(void *pdoc, Node *node) 
2737 {
2738   android_t    *android;
2739   Doc         *doc;
2740   request_rec *r;
2741   Attr        *attr;
2742   char        *attr_action = NULL;
2743   char        *attr_method = NULL;
2744   char        *attr_style  = NULL;
2745   char        *attr_color  = NULL;
2746   char        *attr_align  = NULL;
2747   char        *attr_name   = NULL;
2748   char        *css_clear   = NULL;
2749   char        *new_hidden_tag = NULL;
2750
2751   android  = GET_ANDROID(pdoc);
2752   doc     = android->doc;
2753   r       = doc->r;
2754
2755   /*--------------------------------------------------------------------------*/
2756   /* Get Attributes                                                           */
2757   /*--------------------------------------------------------------------------*/
2758   for (attr = qs_get_attr(doc,node);
2759        attr;
2760        attr = qs_get_next_attr(doc,attr)) {
2761     char *name  = qs_get_attr_name(doc,attr);
2762     char *value = qs_get_attr_value(doc,attr);
2763     switch(*name) {
2764     case 'a':
2765     case 'A':
2766       if (strcasecmp(name, "action") == 0) {
2767         /*--------------------------------------------------------------------*/
2768         /* CHTML 1.0                                                          */
2769         /*--------------------------------------------------------------------*/
2770         attr_action = value;
2771       }
2772       break;
2773
2774     case 'm':
2775     case 'M':
2776       if (strcasecmp(name, "method") == 0) {
2777         /*--------------------------------------------------------------------*/
2778         /* CHTML 1.0                                                          */
2779         /*--------------------------------------------------------------------*/
2780         attr_method = value;
2781       }
2782       break;
2783
2784     case 'n':
2785     case 'N':
2786       if (strcasecmp(name, "name") == 0) {
2787         /*--------------------------------------------------------------------*/
2788         /* CHTML 1.0                                                          */
2789         /*--------------------------------------------------------------------*/
2790         attr_name = value;
2791       }
2792       break;
2793
2794     case 's':
2795     case 'S':
2796       if (strcasecmp(name, "style") == 0) {
2797         attr_style = value;
2798       }
2799       break;
2800
2801     default:
2802       break;
2803     }
2804   }
2805   if (IS_CSS_ON(android->entryp)) {
2806     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
2807     if (style) {
2808       css_property_t *text_align_prop = chxj_css_get_property_value(doc, style, "text-align");
2809       css_property_t *color_prop      = chxj_css_get_property_value(doc, style, "color");
2810       css_property_t *clear_prop      = chxj_css_get_property_value(doc, style, "clear");
2811       css_property_t *cur;
2812       for (cur = text_align_prop->next; cur != text_align_prop; cur = cur->next) {
2813         if (STRCASEEQ('l','L',"left", cur->value)) {
2814           attr_align = apr_pstrdup(doc->pool, "left");
2815         }
2816         else if (STRCASEEQ('c','C',"center",cur->value)) {
2817           attr_align = apr_pstrdup(doc->pool, "center");
2818         }
2819         else if (STRCASEEQ('r','R',"right",cur->value)) {
2820           attr_align = apr_pstrdup(doc->pool, "right");
2821         }
2822       }
2823       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
2824         attr_color = apr_pstrdup(doc->pool, cur->value);
2825       }
2826       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
2827         css_clear = apr_pstrdup(doc->pool, cur->value);
2828       }
2829     }
2830   }
2831
2832   int post_flag = (attr_method && strcasecmp(attr_method, "post") == 0) ? 1 : 0;
2833
2834   W_L("<form");
2835   if (attr_action) {
2836     attr_action = chxj_encoding_parameter(r, attr_action, 1);
2837     attr_action = chxj_add_cookie_parameter(r, attr_action, android->cookie);
2838     char *q;
2839     char *old_qs = NULL;
2840     q = strchr(attr_action, '?');
2841     if (q) {
2842       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);
2843       if (new_hidden_tag || old_qs) {
2844         *q = 0;
2845       }
2846     }
2847     W_L(" action=\"");
2848     W_V(attr_action);
2849     if (old_qs) {
2850       W_L("?");
2851       W_V(old_qs);
2852     }
2853     W_L("\"");
2854   }
2855   if (attr_method) {
2856     W_L(" method=\"");
2857     W_V(attr_method);
2858     W_L("\"");
2859   }
2860   if (attr_name) {
2861     W_L(" name=\"");
2862     W_V(attr_name);
2863     W_L("\"");
2864   }
2865   if (css_clear) {
2866     W_L(" style=\"");
2867     W_L("clear:");
2868     W_V(css_clear);
2869     W_L("\"");
2870   }
2871   W_L(">");
2872
2873   android_flags_t *flg = (android_flags_t *)apr_palloc(doc->pool, sizeof(android_flags_t));
2874   memset(flg, 0, sizeof(*flg));
2875   if (attr_color) {
2876     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
2877     W_L("<font color=\"");
2878     W_V(attr_color);
2879     W_L("\">");
2880     flg->with_font_flag = 1;
2881   }
2882   if (attr_align) {
2883     W_L("<div align=\"");
2884     W_V(attr_align);
2885     W_L("\">");
2886     flg->with_div_flag = 1;
2887   }
2888   node->userData = flg;
2889   if (new_hidden_tag) {
2890     W_V(new_hidden_tag);
2891   }
2892   return android->out;
2893 }
2894
2895
2896 /**
2897  * It is a handler who processes the FORM tag.
2898  *
2899  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2900  *                     destination is specified.
2901  * @param node   [i]   The FORM tag node is specified.
2902  * @return The conversion result is returned.
2903  */
2904 static char *
2905 s_android_end_form_tag(void *pdoc, Node *node)
2906 {
2907   android_t *android = GET_ANDROID(pdoc);
2908   Doc      *doc    = android->doc;
2909
2910   android_flags_t *flg = (android_flags_t *)node->userData;
2911   if (flg && flg->with_div_flag) {
2912     W_L("</div>");
2913   }
2914   if (flg && flg->with_font_flag) {
2915     W_L("</font>");
2916   }
2917   W_L("</form>");
2918   if (IS_CSS_ON(android->entryp)) {
2919     chxj_css_pop_prop_list(android->css_prop_stack);
2920   }
2921
2922   return android->out;
2923 }
2924
2925 static char *
2926 s_android_istyle_to_wap_input_format(apr_pool_t *p, const char *s)
2927 {
2928   if (s) {
2929     switch (s[0]) {
2930     case '1': return apr_psprintf(p, "&quot;*&lt;ja:h&gt;&quot;");
2931     case '2': return apr_psprintf(p, "&quot;*&lt;ja:hk&gt;&quot;");
2932     case '3': return apr_psprintf(p, "&quot;*&lt;ja:en&gt;&quot;");
2933     case '4': return apr_psprintf(p, "&quot;*&lt;ja:n&gt;&quot;");
2934     default:
2935       return apr_pstrdup(p, "");
2936     }
2937   }
2938
2939   return apr_pstrdup(p,"");
2940 }
2941
2942
2943 /**
2944  * It is a handler who processes the INPUT tag.
2945  *
2946  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
2947  *                     destination is specified.
2948  * @param node   [i]   The INPUT tag node is specified.
2949  * @return The conversion result is returned.
2950  */
2951 static char *
2952 s_android_start_input_tag(void *pdoc, Node *node) 
2953 {
2954   android_t    *android;
2955   Doc         *doc;
2956   request_rec *r;
2957   Attr        *attr;
2958   char        *attr_accesskey  = NULL;
2959   char        *attr_max_length = NULL;
2960   char        *attr_type       = NULL;
2961   char        *attr_name       = NULL;
2962   char        *attr_value      = NULL;
2963   char        *attr_istyle     = NULL;
2964   char        *attr_size       = NULL;
2965   char        *attr_checked    = NULL;
2966   char        *attr_style      = NULL;
2967
2968   android  = GET_ANDROID(pdoc);
2969   doc     = android->doc;
2970   r       = doc->r;
2971
2972   /*--------------------------------------------------------------------------*/
2973   /* Get Attributes                                                           */
2974   /*--------------------------------------------------------------------------*/
2975   for (attr = qs_get_attr(doc,node);
2976        attr;
2977        attr = qs_get_next_attr(doc,attr)) {
2978     char *name  = qs_get_attr_name(doc,attr);
2979     char *value = qs_get_attr_value(doc,attr);
2980     if (STRCASEEQ('t','T',"type",name) && value && *value) {
2981       char *tmp_type = qs_trim_string(doc->buf.pool, value);
2982       if (tmp_type && (STRCASEEQ('t','T',"text",    tmp_type) ||
2983                        STRCASEEQ('p','P',"password",tmp_type) ||
2984                        STRCASEEQ('c','C',"checkbox",tmp_type) ||
2985                        STRCASEEQ('r','R',"radio",   tmp_type) ||
2986                        STRCASEEQ('h','H',"hidden",  tmp_type) ||
2987                        STRCASEEQ('s','S',"submit",  tmp_type) ||
2988                        STRCASEEQ('r','R',"reset",   tmp_type))) {
2989         attr_type = tmp_type;
2990       }
2991     }
2992     else if (STRCASEEQ('n','N',"name",name) && value && *value) {
2993       attr_name = value;
2994     }
2995     else if (STRCASEEQ('v','V',"value",name) && value && *value) {
2996       attr_value = value;
2997     }
2998     else if (STRCASEEQ('i','I',"istyle",name) && value && *value) {
2999       attr_istyle = value;
3000     }
3001     else if (STRCASEEQ('m','M',"maxlength",name) && value && *value) {
3002       attr_max_length = value;
3003     }
3004     else if (STRCASEEQ('c','C',"checked", name)) {
3005       attr_checked = value;
3006     }
3007     else if (STRCASEEQ('a','A',"accesskey", name) && value && *value) {
3008       attr_accesskey = value;
3009     }
3010     else if (STRCASEEQ('s','S',"size", name) && value && *value) {
3011       attr_size = value;
3012     }
3013     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
3014       attr_style = value;
3015     }
3016   }
3017
3018   if (IS_CSS_ON(android->entryp)) {
3019     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
3020     if (style) {
3021       css_property_t *wap_input_format = chxj_css_get_property_value(doc, style, "-wap-input-format");
3022       css_property_t *cur;
3023       for (cur = wap_input_format->next; cur != wap_input_format; cur = cur->next) {
3024         if (strcasestr(cur->value, "<ja:n>")) {
3025           attr_istyle = "4";
3026         }
3027         else if (strcasestr(cur->value, "<ja:en>")) {
3028           attr_istyle = "3";
3029         }
3030         else if (strcasestr(cur->value, "<ja:hk>")) {
3031           attr_istyle = "2";
3032         }
3033         else if (strcasestr(cur->value, "<ja:h>")) {
3034           attr_istyle = "1";
3035         }
3036       }
3037     }
3038   }
3039
3040   W_L("<input");
3041   if (attr_size) {
3042     W_L(" size=\"");
3043     W_V(attr_size);
3044     W_L("\"");
3045   }
3046   if (attr_name) {
3047     W_L(" name=\"");
3048     W_V(chxj_jreserved_to_safe_tag(r, attr_name, android->entryp));
3049     W_L("\"");
3050   }
3051   if (attr_value) {
3052     W_L(" value=\"");
3053     W_V(chxj_add_slash_to_doublequote(doc->pool, attr_value));
3054     W_L("\"");
3055   }
3056   if (attr_istyle && (*attr_istyle == '1' || *attr_istyle == '2' || *attr_istyle == '3' || *attr_istyle == '4')) {
3057     if (attr_type && STRCASEEQ('t','T',"text",attr_type)) {
3058       /* 1 => ignore */ 
3059       /* 2 => ignore */
3060       /* 3 => ignore */
3061       /* 4 => number */
3062       if (*attr_istyle == '4') {
3063         attr_type = apr_pstrdup(r->pool, "number");
3064       }
3065     }
3066   }
3067   if (attr_type) {
3068     W_L(" type=\"");
3069     W_V(attr_type);
3070     W_L("\"");
3071   }
3072   /*--------------------------------------------------------------------------*/
3073   /* The figure is default for the password.                                  */
3074   /*--------------------------------------------------------------------------*/
3075   if (attr_max_length && *attr_max_length) {
3076     if (chxj_chk_numeric(attr_max_length) == 0) {
3077       W_L(" maxlength=\"");
3078       W_V(attr_max_length);
3079       W_L("\"");
3080     }
3081   }
3082   if (attr_checked) {
3083     W_L(" checked=\"checked\"");
3084   }
3085   W_L(" />");
3086   return android->out;
3087 }
3088
3089
3090 /**
3091  * It is a handler who processes the INPUT tag.
3092  *
3093  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3094  *                     destination is specified.
3095  * @param node   [i]   The INPUT tag node is specified.
3096  * @return The conversion result is returned.
3097  */
3098 static char *
3099 s_android_end_input_tag(void *pdoc, Node *UNUSED(child)) 
3100 {
3101   android_t *android = GET_ANDROID(pdoc);
3102   return android->out;
3103 }
3104
3105
3106 /**
3107  * It is a handler who processes the CENTER tag.
3108  *
3109  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3110  *                     destination is specified.
3111  * @param node   [i]   The CENTER tag node is specified.
3112  * @return The conversion result is returned.
3113  */
3114 static char *
3115 s_android_start_center_tag(void *pdoc, Node *node)
3116 {
3117   android_t *android;
3118   Doc       *doc;
3119   Attr      *attr;
3120   char      *attr_style = NULL;
3121   char      *attr_color = NULL;
3122   char      *attr_size  = NULL;
3123
3124   android = GET_ANDROID(pdoc);
3125   doc    = android->doc;
3126
3127   for (attr = qs_get_attr(doc,node);
3128        attr;
3129        attr = qs_get_next_attr(doc,attr)) {
3130     char *name  = qs_get_attr_name(doc,attr);
3131     char *value = qs_get_attr_value(doc,attr);
3132     if (STRCASEEQ('s','S',"style",name) && value && *value) {
3133       attr_style = value;
3134     }
3135   }
3136   if (IS_CSS_ON(android->entryp)) {
3137     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
3138     if (style) {
3139       css_property_t *color_prop      = chxj_css_get_property_value(doc, style, "color");
3140       css_property_t *size_prop       = chxj_css_get_property_value(doc, style, "font-size");
3141       css_property_t *cur;
3142       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
3143         if (cur->value && *cur->value) {
3144           attr_color = apr_pstrdup(doc->pool, cur->value);
3145         }
3146       }
3147       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
3148         if (cur->value && *cur->value) {
3149           attr_size = apr_pstrdup(doc->pool, cur->value);
3150         }
3151       }
3152     }
3153   }
3154
3155   W_L("<center");
3156   if (attr_size || attr_color) {
3157     W_L(" style=\"");
3158     if (attr_size) {
3159       W_L("font-size:");
3160       W_V(attr_size);
3161       W_L(";");
3162     }
3163     if (attr_color) {
3164       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
3165       W_L("color:");
3166       W_V(attr_color);
3167       W_L(";");
3168     }
3169     W_L("\"");
3170   }
3171   W_L(">");
3172   
3173   return android->out;
3174 }
3175
3176
3177 /**
3178  * It is a handler who processes the CENTER tag.
3179  *
3180  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3181  *                     destination is specified.
3182  * @param node   [i]   The CENTER tag node is specified.
3183  * @return The conversion result is returned.
3184  */
3185 static char *
3186 s_android_end_center_tag(void *pdoc, Node *UNUSED(node))
3187 {
3188   android_t    *android;
3189   Doc         *doc;
3190   request_rec *r;
3191
3192   android = GET_ANDROID(pdoc);
3193   doc    = android->doc;
3194   r      = doc->r;
3195
3196   W_L("</center>");
3197   if (IS_CSS_ON(android->entryp)) {
3198     chxj_css_pop_prop_list(android->css_prop_stack);
3199   }
3200   return android->out;
3201 }
3202
3203
3204 /**
3205  * It is a handler who processes the li tag.
3206  *
3207  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3208  *                     destination is specified.
3209  * @param node   [i]   The li tag node is specified.
3210  * @return The conversion result is returned.
3211  */
3212 static char *
3213 s_android_start_li_tag(void *pdoc, Node *node)
3214 {
3215   android_t    *android;
3216   Doc         *doc;
3217   request_rec *r;
3218   Attr        *attr;
3219   char        *attr_type  = NULL;
3220   char        *attr_value = NULL;
3221   char        *attr_style = NULL;
3222
3223   android = GET_ANDROID(pdoc);
3224   doc   = android->doc;
3225   r     = doc->r;
3226
3227   for (attr = qs_get_attr(doc,node);
3228        attr;
3229        attr = qs_get_next_attr(doc,attr)) {
3230     char *name  = qs_get_attr_name(doc,attr);
3231     char *value = qs_get_attr_value(doc,attr);
3232     if (STRCASEEQ('t','T',"type",name)) {
3233       if (value && (*value == '1' || *value == 'a' || *value == 'A' || STRCASEEQ('d','D',"disc",value) || STRCASEEQ('s','S',"square",value) || STRCASEEQ('c','C',"circle",value))) {
3234         if (*value == '1') {
3235           attr_type = apr_pstrdup(doc->pool, "decimal");
3236         }
3237         else if (*value == 'a') {
3238           attr_type = apr_pstrdup(doc->pool, "lower-alpha");
3239         }
3240         else if (*value == 'A') {
3241           attr_type = apr_pstrdup(doc->pool, "upper-alpha");
3242         }
3243         else {
3244           attr_type = value;
3245         }
3246       }
3247     }
3248     else if (STRCASEEQ('v','V',"value", name) && value && *value) {
3249       attr_value = value;
3250     }
3251     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
3252       attr_style = value;
3253     }
3254   }
3255   if (IS_CSS_ON(android->entryp)) {
3256     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
3257     if (style) {
3258       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type");
3259       css_property_t *cur;
3260       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3261         if (STRCASEEQ('d','D',"decimal", cur->value)) {
3262           attr_type = apr_pstrdup(doc->pool, "decimal");
3263         }
3264         else if (STRCASEEQ('u','U',"upper-alpha", cur->value)) {
3265           attr_type = apr_pstrdup(doc->pool, "upper-alpha");
3266         }
3267         else if (STRCASEEQ('l','L',"lower-alpha", cur->value)) {
3268           attr_type = apr_pstrdup(doc->pool, "lower-alpha");
3269         }
3270         else if (STRCASEEQ('d','D',"disc", cur->value)) {
3271           attr_type = apr_pstrdup(doc->pool, "disc");
3272         }
3273         else if (STRCASEEQ('s','S',"square", cur->value)) {
3274           attr_type = apr_pstrdup(doc->pool, "square");
3275         }
3276         else if (STRCASEEQ('c','C',"circle", cur->value)) {
3277           attr_type = apr_pstrdup(doc->pool, "circle");
3278         }
3279       }
3280     }
3281   }
3282
3283
3284   W_L("<li");
3285   if (attr_type) {
3286     W_L(" style=\"");
3287     W_L("list-style-type:");
3288     W_V(attr_type);
3289     W_L(";");
3290     W_L("\"");
3291   }
3292   if (attr_value) {
3293     W_L(" value=\"");
3294     W_V(attr_value);
3295     W_L("\"");
3296   }
3297   W_L(">");
3298   return android->out;
3299 }
3300
3301
3302 /**
3303  * It is a handler who processes the li tag.
3304  *
3305  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3306  *                     destination is specified.
3307  * @param node   [i]   The li tag node is specified.
3308  * @return The conversion result is returned.
3309  */
3310 static char *
3311 s_android_end_li_tag(void *pdoc, Node *UNUSED(child)) 
3312 {
3313   android_t     *android;
3314   Doc         *doc;
3315   request_rec *r;
3316
3317   android = GET_ANDROID(pdoc);
3318   doc   = android->doc;
3319   r     = doc->r;
3320
3321   if (IS_CSS_ON(android->entryp)) {
3322     chxj_css_pop_prop_list(android->css_prop_stack);
3323   }
3324   W_L("</li>");
3325   return android->out;
3326 }
3327
3328
3329 /**
3330  * It is a handler who processes the OL tag.
3331  *
3332  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3333  *                     destination is specified.
3334  * @param node   [i]   The OL tag node is specified.
3335  * @return The conversion result is returned.
3336  */
3337 static char *
3338 s_android_start_ol_tag(void *pdoc, Node *node)
3339 {
3340   android_t    *android;
3341   Doc         *doc;
3342   request_rec *r;
3343   Attr        *attr;
3344   char        *attr_style = NULL;
3345   char        *attr_start = NULL;
3346   char        *attr_type  = NULL;
3347   char        *css_clear  = NULL;
3348
3349   android = GET_ANDROID(pdoc);
3350   doc   = android->doc;
3351   r     = doc->r;
3352
3353   /*--------------------------------------------------------------------------*/
3354   /* Get Attributes                                                           */
3355   /*--------------------------------------------------------------------------*/
3356   for (attr = qs_get_attr(doc,node);
3357        attr;
3358        attr = qs_get_next_attr(doc,attr)) {
3359     char *name = qs_get_attr_name(doc,attr);
3360     char *value = qs_get_attr_value(doc,attr);
3361     if (STRCASEEQ('t','T',"type",name) && value) {
3362       if (*value == '1') {
3363         attr_type = apr_pstrdup(doc->pool, "decimal");
3364       }
3365       else if (*value == 'a') {
3366         attr_type = apr_pstrdup(doc->pool, "lower-alpha");
3367       }
3368       else if (*value == 'A') {
3369         attr_type = apr_pstrdup(doc->pool, "upper-alpha");
3370       }
3371     }
3372     else if (STRCASEEQ('s','S',"start",name) && value && *value) {
3373       attr_start = value;
3374     }
3375     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
3376       attr_style = value;
3377     }
3378   }
3379   if (IS_CSS_ON(android->entryp)) {
3380     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
3381     if (style) {
3382       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type");
3383       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
3384       
3385       css_property_t *cur;
3386       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3387         if (STRCASEEQ('d','D',"decimal", cur->value)) {
3388           attr_type = apr_pstrdup(doc->pool, "decimal");
3389         }
3390         else if (STRCASEEQ('u','U',"upper-alpha", cur->value)) {
3391           attr_type = apr_pstrdup(doc->pool, "upper-alpha");
3392         }
3393         else if (STRCASEEQ('l','L',"lower-alpha", cur->value)) {
3394           attr_type = apr_pstrdup(doc->pool, "lower-alpha");
3395         }
3396       }
3397       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
3398         css_clear = apr_pstrdup(doc->pool, cur->value);
3399       }
3400     }
3401   }
3402   W_L("<ol");
3403   if (attr_type || css_clear) {
3404     W_L(" style=\"");
3405     if (attr_type) {
3406       W_L("list-style-type:");
3407       W_V(attr_type);
3408       W_L(";");
3409     }
3410     if (css_clear){
3411       W_L("clear:");
3412       W_V(css_clear);
3413       W_L(";");
3414     }
3415     W_L("\"");
3416   }
3417   if (attr_start) {
3418     W_L(" start=\"");
3419     W_V(attr_start);
3420     W_L("\"");
3421   }
3422   W_L(">");
3423
3424   return android->out;
3425 }
3426
3427
3428 /**
3429  * It is a handler who processes the OL tag.
3430  *
3431  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3432  *                     destination is specified.
3433  * @param node   [i]   The OL tag node is specified.
3434  * @return The conversion result is returned.
3435  */
3436 static char *
3437 s_android_end_ol_tag(void *pdoc, Node *UNUSED(child)) 
3438 {
3439   android_t     *android;
3440   Doc         *doc;
3441   request_rec *r;
3442
3443   android = GET_ANDROID(pdoc);
3444   doc   = android->doc;
3445   r     = doc->r;
3446
3447   W_L("</ol>");
3448   if (IS_CSS_ON(android->entryp)) {
3449     chxj_css_pop_prop_list(android->css_prop_stack);
3450   }
3451   return android->out;
3452 }
3453
3454
3455 /**
3456  * It is a handler who processes the P tag.
3457  *
3458  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3459  *                     destination is specified.
3460  * @param node   [i]   The P tag node is specified.
3461  * @return The conversion result is returned.
3462  */
3463 static char *
3464 s_android_start_p_tag(void *pdoc, Node *node)
3465 {
3466   android_t    *android;
3467   Doc         *doc;
3468   request_rec *r;
3469   Attr        *attr;
3470   char        *attr_align = NULL;
3471   char        *attr_style = NULL;
3472   char        *attr_color = NULL;
3473   char        *attr_blink = NULL;
3474   char        *css_clear  = NULL;
3475
3476   android = GET_ANDROID(pdoc);
3477   doc   = android->doc;
3478   r     = doc->r;
3479
3480   for (attr = qs_get_attr(doc,node);
3481        attr;
3482        attr = qs_get_next_attr(doc,attr)) {
3483     char *nm  = qs_get_attr_name(doc,attr);
3484     char *val = qs_get_attr_value(doc,attr);
3485     if (STRCASEEQ('a','A',"align", nm)) {
3486       /*----------------------------------------------------------------------*/
3487       /* CHTML 1.0 (W3C version 3.2)                                          */
3488       /*----------------------------------------------------------------------*/
3489       if (val && (STRCASEEQ('l','L',"left",val) || STRCASEEQ('r','R',"right",val) || STRCASEEQ('c','C',"center",val))) {
3490         attr_align = apr_pstrdup(doc->buf.pool, val);
3491         break;
3492       }
3493     }
3494     else if (STRCASEEQ('s','S',"style", nm) && val && *val) {
3495       attr_style = apr_pstrdup(doc->buf.pool, val);
3496     }
3497   }
3498   if (IS_CSS_ON(android->entryp)) {
3499     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
3500     if (style) {
3501       css_property_t *text_align_prop = chxj_css_get_property_value(doc, style, "text-align");
3502       css_property_t *color_prop      = chxj_css_get_property_value(doc, style, "color");
3503       css_property_t *text_deco_prop  = chxj_css_get_property_value(doc, style, "text-decoration");
3504       css_property_t *clear_prop      = chxj_css_get_property_value(doc, style, "clear");
3505       css_property_t *cur;
3506       for (cur = text_align_prop->next; cur != text_align_prop; cur = cur->next) {
3507         if (STRCASEEQ('l','L',"left",cur->value)) {
3508           attr_align = apr_pstrdup(doc->pool, "left");
3509         }
3510         else if (STRCASEEQ('c','C',"center",cur->value)) {
3511           attr_align = apr_pstrdup(doc->pool, "center");
3512         }
3513         else if (STRCASEEQ('r','R',"right",cur->value)) {
3514           attr_align = apr_pstrdup(doc->pool, "right");
3515         }
3516       }
3517       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
3518         if (cur->value && *cur->value) {
3519           attr_color = apr_pstrdup(doc->pool, cur->value);
3520         }
3521       }
3522       for (cur = text_deco_prop->next; cur != text_deco_prop; cur = cur->next) {
3523         if (cur->value && *cur->value && STRCASEEQ('b','B',"blink",cur->value)) {
3524           attr_blink = apr_pstrdup(doc->pool, cur->value);
3525         }
3526       }
3527       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
3528         css_clear = apr_pstrdup(doc->pool, cur->value);
3529       }
3530     }
3531   }
3532   W_L("<p");
3533   if ((attr_align && *attr_align) || (attr_color && *attr_color) || (attr_blink && *attr_blink) || css_clear) {
3534     W_L(" style=\"");
3535     if (attr_align) {
3536       W_L("text-align:");
3537       W_V(attr_align);
3538       W_L(";");
3539     }
3540     if (attr_color) {
3541       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
3542       W_L("color:");
3543       W_V(attr_color);
3544       W_L(";");
3545     }
3546     if (attr_blink) {
3547       W_L("text-decoration:");
3548       W_V(attr_blink);
3549       W_L(";");
3550     }
3551     if (css_clear){
3552       W_L("clear:");
3553       W_V(css_clear);
3554       W_L(";");
3555     }
3556     W_L("\"");
3557   }
3558   W_L(">");
3559   return android->out;
3560 }
3561
3562
3563 /**
3564  * It is a handler who processes the P tag.
3565  *
3566  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3567  *                     destination is specified.
3568  * @param node   [i]   The P tag node is specified.
3569  * @return The conversion result is returned.
3570  */
3571 static char *
3572 s_android_end_p_tag(void *pdoc, Node *UNUSED(child)) 
3573 {
3574   android_t  *android = GET_ANDROID(pdoc);
3575   Doc       *doc    = android->doc;
3576
3577   W_L("</p>");
3578   if (IS_CSS_ON(android->entryp)) {
3579     chxj_css_pop_prop_list(android->css_prop_stack);
3580   }
3581   return android->out;
3582 }
3583
3584
3585 /**
3586  * It is a handler who processes the PRE tag.
3587  *
3588  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3589  *                     destination is specified.
3590  * @param node   [i]   The PRE tag node is specified.
3591  * @return The conversion result is returned.
3592  */
3593 static char *
3594 s_android_start_pre_tag(void *pdoc, Node *node)
3595 {
3596   android_t  *android = GET_ANDROID(pdoc);
3597   Doc       *doc   = android->doc;
3598   Attr      *attr;
3599   char      *attr_style = NULL;
3600   char      *css_clear  = NULL;
3601
3602   for (attr = qs_get_attr(doc,node);
3603        attr;
3604        attr = qs_get_next_attr(doc,attr)) {
3605     char *nm  = qs_get_attr_name(doc,attr);
3606     char *val = qs_get_attr_value(doc,attr);
3607     if (val && STRCASEEQ('s','S',"style", nm)) {
3608       attr_style = val;
3609     }
3610   }
3611
3612   if (IS_CSS_ON(android->entryp)) {
3613     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
3614     if (style) {
3615       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
3616       
3617       css_property_t *cur;
3618       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
3619         css_clear = apr_pstrdup(doc->pool, cur->value);
3620       }
3621     }
3622   }
3623
3624   android->pre_flag++;
3625   W_L("<pre");
3626   if (css_clear) {
3627     W_L(" style=\"");
3628     W_L("clear:");
3629     W_V(css_clear);
3630     W_L(";");
3631     W_L("\"");
3632   }
3633   W_L(">");
3634   return android->out;
3635 }
3636
3637
3638 /**
3639  * It is a handler who processes the PRE tag.
3640  *
3641  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3642  *                     destination is specified.
3643  * @param node   [i]   The PRE tag node is specified.
3644  * @return The conversion result is returned.
3645  */
3646 static char *
3647 s_android_end_pre_tag(void *pdoc, Node *UNUSED(child)) 
3648 {
3649   android_t *android = GET_ANDROID(pdoc);
3650   Doc     *doc   = android->doc;
3651
3652   W_L("</pre>");
3653   android->pre_flag--;
3654   if (IS_CSS_ON(android->entryp)) {
3655     chxj_css_pop_prop_list(android->css_prop_stack);
3656   }
3657
3658   return android->out;
3659 }
3660
3661
3662 /**
3663  * It is a handler who processes the UL tag.
3664  *
3665  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3666  *                     destination is specified.
3667  * @param node   [i]   The UL tag node is specified.
3668  * @return The conversion result is returned.
3669  */
3670 static char *
3671 s_android_start_ul_tag(void *pdoc, Node *node)
3672 {
3673   android_t *android = GET_ANDROID(pdoc);
3674   Doc      *doc    = android->doc;
3675   Attr     *attr;
3676   char     *attr_type = NULL;
3677   char     *attr_style = NULL;
3678   char     *css_clear  = NULL;
3679   
3680   /*--------------------------------------------------------------------------*/
3681   /* Get Attributes                                                           */
3682   /*--------------------------------------------------------------------------*/
3683   for (attr = qs_get_attr(doc,node);
3684        attr;
3685        attr = qs_get_next_attr(doc,attr)) {
3686     char *name   = qs_get_attr_name(doc,attr);
3687     char *value  = qs_get_attr_value(doc,attr);
3688     if (STRCASEEQ('t','T',"type",name)) {
3689       if (value && (STRCASEEQ('d','D',"disc",value) || STRCASEEQ('c','C',"circle",value) || STRCASEEQ('s','S',"square",value))) {
3690         attr_type = value;
3691       }
3692     }
3693     else if (value && *value && STRCASEEQ('s','S',"style", name)) {
3694       attr_style = value;
3695     }
3696   }
3697   if (IS_CSS_ON(android->entryp)) {
3698     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
3699     if (style) {
3700       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type");
3701       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
3702       
3703       css_property_t *cur;
3704       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3705         if (STRCASEEQ('d','D',"disc",cur->value)) {
3706           attr_type = apr_pstrdup(doc->pool, "disc");
3707         }
3708         else if (STRCASEEQ('c','C',"circle",cur->value)) {
3709           attr_type = apr_pstrdup(doc->pool, "circle");
3710         }
3711         else if (STRCASEEQ('s','S',"square",cur->value)) {
3712           attr_type = apr_pstrdup(doc->pool, "square");
3713         }
3714       }
3715       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
3716         css_clear = apr_pstrdup(doc->pool, cur->value);
3717       }
3718     }
3719   }
3720   W_L("<ul");
3721   if (attr_type || css_clear) {
3722     W_L(" style=\"");
3723     if (attr_type ){
3724       W_L("list-style-type:");
3725       W_V(attr_type);
3726       W_L(";");
3727     }
3728     if (css_clear){
3729       W_L("clear:");
3730       W_V(css_clear);
3731       W_L(";");
3732     }
3733     W_L("\"");
3734   }
3735   W_L(">");
3736   return android->out;
3737 }
3738
3739
3740 /**
3741  * It is a handler who processes the UL tag.
3742  *
3743  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3744  *                     destination is specified.
3745  * @param node   [i]   The UL tag node is specified.
3746  * @return The conversion result is returned.
3747  */
3748 static char *
3749 s_android_end_ul_tag(void *pdoc, Node *UNUSED(child)) 
3750 {
3751   android_t *android = GET_ANDROID(pdoc);
3752   Doc     *doc   = android->doc;
3753
3754   W_L("</ul>");
3755   if (IS_CSS_ON(android->entryp)) {
3756     chxj_css_pop_prop_list(android->css_prop_stack);
3757   }
3758   return android->out;
3759 }
3760
3761
3762 /**
3763  * It is a handler who processes the HR tag.
3764  *
3765  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
3766  *                     destination is specified.
3767  * @param node   [i]   The HR tag node is specified.
3768  * @return The conversion result is returned.
3769  */
3770 static char *
3771 s_android_start_hr_tag(void *pdoc, Node *node) 
3772 {
3773   Attr        *attr;
3774   android_t     *android;
3775   Doc         *doc;
3776   request_rec *r;
3777   char        *attr_align   = NULL;
3778   char        *attr_size    = NULL;
3779   char        *attr_width   = NULL;
3780   char        *attr_noshade = NULL;
3781   char        *attr_style   = NULL;
3782   char        *attr_color   = NULL;
3783   char        *attr_bgcolor = NULL;
3784   
3785   char        *style_border_color = NULL;
3786   char        *css_clear          = NULL;
3787
3788   android   = GET_ANDROID(pdoc);
3789   doc     = android->doc;
3790   r       = doc->r;
3791
3792   for (attr = qs_get_attr(doc,node);
3793        attr; 
3794        attr = qs_get_next_attr(doc,attr)) {
3795     char *name  = qs_get_attr_name (doc,attr);
3796     char *value = qs_get_attr_value(doc,attr);
3797     switch(*name) {
3798     case 'a':
3799     case 'A':
3800       if (strcasecmp(name, "align") == 0) {
3801         /*--------------------------------------------------------------------*/
3802         /* CHTML 1.0                                                          */
3803         /*--------------------------------------------------------------------*/
3804         if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3805           if (value[0] == 'c' || value[0] == 'C') {
3806             attr_align = apr_pstrdup(doc->pool, "none");
3807           }
3808           else {
3809             attr_align = value;
3810           }
3811         }
3812       }
3813       break;
3814
3815     case 's':
3816     case 'S':
3817       if (strcasecmp(name, "size") == 0) {
3818         /*--------------------------------------------------------------------*/
3819         /* CHTML 1.0                                                          */
3820         /*--------------------------------------------------------------------*/
3821         if (value && *value) {
3822           attr_size = value;
3823         }
3824       }
3825       else if (strcasecmp(name, "style") == 0) {
3826         if (value && *value) {
3827           attr_style = value;
3828         }
3829       }
3830       break;
3831
3832     case 'w':
3833     case 'W':
3834       if (strcasecmp(name, "width") == 0) {
3835         /*--------------------------------------------------------------------*/
3836         /* CHTML 1.0                                                          */
3837         /*--------------------------------------------------------------------*/
3838         if (value && *value) {
3839           attr_width = value;
3840         }
3841       }
3842       break;
3843
3844     case 'n':
3845     case 'N':
3846       if (strcasecmp(name, "noshade") == 0) {
3847         /*--------------------------------------------------------------------*/
3848         /* CHTML 1.0                                                          */
3849         /*--------------------------------------------------------------------*/
3850         attr_noshade = apr_pstrdup(doc->pool, "noshade");
3851       }
3852       break;
3853
3854     case 'c':
3855     case 'C':
3856       if (strcasecmp(name, "color") == 0 && value && *value) {
3857         /*--------------------------------------------------------------------*/
3858         /* CHTML 4.0                                                          */
3859         /*--------------------------------------------------------------------*/
3860         attr_color = value;
3861       }
3862       break;
3863
3864     default:
3865       break;
3866     }
3867   }
3868   if (IS_CSS_ON(android->entryp)) {
3869     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
3870     if (style) {
3871       css_property_t *border_style_prop = chxj_css_get_property_value(doc, style, "border-style");
3872       css_property_t *height_prop       = chxj_css_get_property_value(doc, style, "height");
3873       css_property_t *width_prop        = chxj_css_get_property_value(doc, style, "width");
3874       
3875       css_property_t *bgcolor_prop      = chxj_css_get_property_value(doc, style, "background-color");
3876       css_property_t *float_prop        = chxj_css_get_property_value(doc, style, "float");
3877       css_property_t *border_color_prop = chxj_css_get_property_value(doc, style, "border-color");
3878       css_property_t *clear_prop        = chxj_css_get_property_value(doc, style, "clear");
3879       css_property_t *cur;
3880       
3881       for (cur = border_style_prop->next; cur != border_style_prop; cur = cur->next) {
3882         if (STRCASEEQ('s','S',"solid",cur->value)) {
3883           attr_noshade = "noshade";
3884         }
3885       }
3886       for (cur = height_prop->next; cur != height_prop; cur = cur->next) {
3887         attr_size = apr_pstrdup(doc->pool, cur->value);
3888       }
3889       for (cur = bgcolor_prop->next; cur != bgcolor_prop; cur = cur->next) {
3890         attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
3891       }
3892       if (!attr_align) {
3893         for (cur = float_prop->next; cur != float_prop; cur = cur->next) {
3894           attr_align = apr_pstrdup(doc->pool,cur->value);
3895         }
3896       }
3897       
3898       
3899       for (cur = width_prop->next; cur != width_prop; cur = cur->next) {
3900         char *tmp = apr_pstrdup(doc->pool, cur->value);
3901         char *tmpp = strstr(tmp, "px");
3902         if (tmpp) {
3903           attr_width = apr_pstrdup(doc->pool, tmp);
3904         }
3905         else {
3906           tmpp = strstr(tmp, "%");
3907           if (tmpp) {
3908             attr_width = apr_pstrdup(doc->pool, tmp);
3909           }
3910         }
3911       }
3912       
3913       for (cur = border_color_prop->next; cur != border_color_prop; cur = cur->next) {
3914         char *tmp = apr_pstrdup(doc->pool, cur->value);
3915         if(tmp){
3916           style_border_color = apr_pstrdup(doc->pool, tmp);
3917         }
3918       }
3919       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
3920         css_clear = apr_pstrdup(doc->pool, cur->value);
3921       }
3922     }
3923   }
3924   W_L("<hr");
3925   if (attr_align || attr_size || attr_width || attr_noshade || style_border_color || css_clear || attr_bgcolor) {
3926     W_L(" style=\"");
3927     if (attr_align) {
3928       W_L("float:");
3929       W_V(attr_align);
3930       W_L(";");
3931     }
3932     if (attr_size) {
3933       W_L("height:");
3934       W_V(attr_size);
3935       if (chxj_chk_numeric(attr_size) == 0) {
3936         W_L("px");
3937       }
3938       W_L(";");
3939     }
3940     if (attr_width) {
3941       W_L("width:");
3942       W_V(attr_width);
3943       if (!strstr(attr_width, "px") && !strstr(attr_width, "%")) {
3944         W_L("px");
3945       }
3946       W_L(";");
3947     }
3948     if (attr_noshade) {
3949       W_L("border-style:solid;");
3950     }
3951     if(style_border_color){
3952       W_L("border-color:");
3953       W_V(style_border_color);
3954       W_L(";");
3955     }
3956     if (attr_bgcolor) {
3957       W_L("background-color:");
3958       W_V(attr_bgcolor);
3959       W_L(";");
3960     }
3961     if (css_clear){
3962       W_L("clear:");
3963       W_V(css_clear);
3964       W_L(";");
3965     }
3966     W_L("\"");
3967   }
3968   if (attr_color) {
3969     W_L(" color=\"");
3970     W_V(attr_color);
3971     W_L("\"");
3972   }
3973   
3974   W_L(" />");
3975
3976   return android->out;
3977 }
3978
3979
3980 /**
3981  * It is a handler who processes the HR tag.
3982  *
3983  * @param android  [i/o] The pointer to the ANDROID structure at the output
3984  *                     destination is specified.
3985  * @param node   [i]   The HR tag node is specified.
3986  * @return The conversion result is returned.
3987  */
3988 static char *
3989 s_android_end_hr_tag(void *pdoc, Node *UNUSED(child)) 
3990 {
3991   android_t *android = GET_ANDROID(pdoc);
3992   return android->out;
3993 }
3994
3995
3996 /**
3997  * It is a handler who processes the IMG tag.
3998  *
3999  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4000  *                     destination is specified.
4001  * @param node   [i]   The IMG tag node is specified.
4002  * @return The conversion result is returned.
4003  */
4004 static char *
4005 s_android_start_img_tag(void *pdoc, Node *node) 
4006 {
4007   android_t    *android = GET_ANDROID(pdoc);
4008   Doc         *doc   = android->doc;
4009   request_rec *r     = doc->r;
4010   Attr        *attr;
4011   char        *attr_src    = NULL;
4012   char        *attr_height = NULL;
4013   char        *attr_width  = NULL;
4014   char        *attr_alt    = NULL;
4015   char        *attr_style  = NULL;
4016   char        *attr_hspace = NULL;
4017   char        *attr_vspace = NULL;
4018   
4019   char        *css_float          = NULL;
4020   char        *css_margin_left    = NULL;
4021   char        *css_margin_right   = NULL;
4022   char        *css_margin_top     = NULL;
4023   char        *css_margin_bottom  = NULL;
4024   char        *css_display        = NULL;
4025   char        *css_valign         = NULL;
4026   
4027 #ifndef IMG_NOT_CONVERT_FILENAME
4028   device_table  *spec = android->spec;
4029 #endif
4030
4031   /*--------------------------------------------------------------------------*/
4032   /* Get Attributes                                                           */
4033   /*--------------------------------------------------------------------------*/
4034   for (attr = qs_get_attr(doc,node);
4035        attr;
4036        attr = qs_get_next_attr(doc,attr)) {
4037     char *name  = qs_get_attr_name(doc,attr);
4038     char *value = qs_get_attr_value(doc,attr);
4039     if (STRCASEEQ('s','S',"src",name)) {
4040       /*----------------------------------------------------------------------*/
4041       /* CHTML 1.0                                                            */
4042       /*----------------------------------------------------------------------*/
4043 #ifdef IMG_NOT_CONVERT_FILENAME
4044       value = chxj_encoding_parameter(r, value, 1);
4045       value = chxj_jreserved_tag_to_safe_for_query_string(r, value, android->entryp, 1);
4046       value = chxj_add_cookie_no_update_parameter(r, value, 1);
4047       value = chxj_img_rewrite_parameter(r,android->conf,value);
4048       attr_src = value;
4049 #else
4050       value = chxj_img_conv(r, spec, value);
4051       value = chxj_encoding_parameter(r, value, 1);
4052       value = chxj_jreserved_tag_to_safe_for_query_string(r, value, android->entryp, 1);
4053       value = chxj_add_cookie_no_update_parameter(r, value, 1);
4054       value = chxj_img_rewrite_parameter(r,android->conf,value);
4055       attr_src = value;
4056 #endif
4057     }
4058     else if (STRCASEEQ('a','A',"align",name)) {
4059       /*----------------------------------------------------------------------*/
4060       /* CHTML 1.0                                                            */
4061       /*----------------------------------------------------------------------*/
4062       if (value) {
4063         if (STRCASEEQ('t','T',"top",   value) ||
4064             STRCASEEQ('m','M',"middle",value) ||
4065             STRCASEEQ('b','B',"bottom",value)){
4066           css_valign = value;
4067         }else if (STRCASEEQ('l','L',"left",  value) || STRCASEEQ('r','R',"right", value)) {
4068           css_float = value;
4069         }
4070         else if (STRCASEEQ('c','C',"center",value)) {
4071           css_valign = apr_pstrdup(doc->pool, "middle");
4072         }
4073       }
4074     }
4075     else if (STRCASEEQ('w','W',"width",name) && value && *value) {
4076       /*----------------------------------------------------------------------*/
4077       /* CHTML 1.0                                                            */
4078       /*----------------------------------------------------------------------*/
4079       attr_width = value;
4080     }
4081     else if (STRCASEEQ('h','H',"height",name) && value && *value) {
4082       /*----------------------------------------------------------------------*/
4083       /* CHTML 1.0                                                            */
4084       /*----------------------------------------------------------------------*/
4085       attr_height = value;
4086     }
4087     else if (STRCASEEQ('h','H',"hspace",name)) {
4088       /*----------------------------------------------------------------------*/
4089       /* CHTML 1.0                                                            */
4090       /*----------------------------------------------------------------------*/
4091       attr_hspace = value;
4092     }
4093     else if (STRCASEEQ('v','V',"vspace",name)) {
4094       /*----------------------------------------------------------------------*/
4095       /* CHTML 1.0                                                            */
4096       /*----------------------------------------------------------------------*/
4097       attr_vspace = value;
4098     }
4099     else if (STRCASEEQ('a','A',"alt",name) && value && *value) {
4100       /*----------------------------------------------------------------------*/
4101       /* CHTML 1.0                                                            */
4102       /*----------------------------------------------------------------------*/
4103       attr_alt = value;
4104     }
4105     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
4106       /*----------------------------------------------------------------------*/
4107       /* CHTML 1.0                                                            */
4108       /*----------------------------------------------------------------------*/
4109       attr_style = value;
4110     }
4111   }
4112
4113   if (IS_CSS_ON(android->entryp)) {
4114     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
4115     if (style) {
4116       css_property_t *height_prop = chxj_css_get_property_value(doc, style, "height");
4117       css_property_t *width_prop  = chxj_css_get_property_value(doc, style, "width");
4118       css_property_t *valign_prop = chxj_css_get_property_value(doc, style, "vertical-align");
4119       css_property_t *margin_left_prop   = chxj_css_get_property_value(doc, style, "margin-left");
4120       css_property_t *margin_right_prop  = chxj_css_get_property_value(doc, style, "margin-right");
4121       css_property_t *margin_top_prop    = chxj_css_get_property_value(doc, style, "margin-top");
4122       css_property_t *margin_bottom_prop = chxj_css_get_property_value(doc, style, "margin-bottom");
4123       
4124       
4125       css_property_t *cur;
4126       for (cur = height_prop->next; cur != height_prop; cur = cur->next) {
4127         attr_height = apr_pstrdup(doc->pool, cur->value);
4128       }
4129       for (cur = width_prop->next; cur != width_prop; cur = cur->next) {
4130         attr_width = apr_pstrdup(doc->pool, cur->value);
4131       }
4132       if(!css_valign){
4133         for (cur = valign_prop->next; cur != valign_prop; cur = cur->next) {
4134           css_valign = apr_pstrdup(doc->pool, cur->value);
4135         }
4136       }
4137       if (! attr_hspace) {
4138         for (cur = margin_left_prop->next; cur != margin_left_prop; cur = cur->next) {
4139           css_margin_left   = apr_pstrdup(doc->pool, cur->value);
4140         }
4141         for (cur = margin_right_prop->next; cur != margin_right_prop; cur = cur->next) {
4142           css_margin_right  = apr_pstrdup(doc->pool, cur->value);
4143         }
4144       }
4145       if (! attr_vspace) {
4146         for (cur = margin_top_prop->next; cur != margin_top_prop; cur = cur->next) {
4147           css_margin_top = apr_pstrdup(doc->pool, cur->value);
4148         }
4149         for (cur = margin_bottom_prop->next; cur != margin_bottom_prop; cur = cur->next) {
4150           css_margin_bottom = apr_pstrdup(doc->pool, cur->value);
4151         }
4152       }
4153       if(!css_float){
4154         css_property_t *float_prop = chxj_css_get_property_value(doc, style, "float");
4155         for (cur = float_prop->next; cur != float_prop; cur = cur->next) {
4156           css_float = apr_pstrdup(doc->pool, cur->value);
4157         }
4158       }
4159       
4160       css_property_t *display_prop       = chxj_css_get_property_value(doc, style, "display");
4161       for (cur = display_prop->next; cur != display_prop; cur = cur->next) {
4162         char *tmp = apr_pstrdup(doc->pool, cur->value);
4163         char *tmpp = strstr(tmp, "none");
4164         if(tmpp){
4165           css_display = apr_pstrdup(doc->pool, tmp);
4166         }
4167       }
4168     }
4169   }
4170
4171   W_L("<img");
4172   if (attr_src) {
4173     W_L(" src=\"");
4174     W_V(attr_src);
4175     W_L("\"");
4176   }
4177   if (attr_hspace || attr_vspace || css_float || css_margin_left || css_margin_right || css_margin_top || css_margin_bottom || css_valign || css_display) {
4178     W_L(" style=\"");
4179     if(css_float){
4180       W_L("float:");
4181       W_V(css_float);
4182       W_L(";");
4183     }
4184     if(css_valign){
4185       W_L("vertical-align:");
4186       W_V(css_valign);
4187       W_L(";");
4188     }
4189     if (attr_hspace) {
4190       W_L("margin-left:");
4191       W_V(attr_hspace);
4192       W_L(";");
4193       W_L("margin-right:");
4194       W_V(attr_hspace);
4195       W_L(";");
4196     }
4197     else{
4198       if(css_margin_left){
4199         W_L("margin-left:");
4200         W_V(css_margin_left);
4201         W_L(";");
4202       }
4203       if(css_margin_right){
4204         W_L("margin-right:");
4205         W_V(css_margin_right);
4206         W_L(";");
4207       }
4208     }
4209     if (attr_vspace) {
4210       W_L("margin-top:");
4211       W_V(attr_vspace);
4212       W_L(";");
4213       W_L("margin-bottom:");
4214       W_V(attr_vspace);
4215       W_L(";");
4216     }
4217     else{
4218       if(css_margin_top){
4219         W_L("margin-top:");
4220         W_V(css_margin_top);
4221         W_L(";");
4222       }
4223       if(css_margin_bottom){
4224         W_L("margin-bottom:");
4225         W_V(css_margin_bottom);
4226         W_L(";");
4227       }
4228     }
4229     if(css_display){
4230       W_L("display:none;");
4231     }
4232     W_L("\"");
4233   }
4234   
4235   if (attr_width) {
4236     W_L(" width=\"");
4237     W_V(attr_width);
4238     W_L("\"");
4239   }
4240   if (attr_height) {
4241     W_L(" height=\"");
4242     W_V(attr_height);
4243     W_L("\"");
4244   }
4245   if (attr_alt) {
4246     W_L(" alt=\"");
4247     W_V(attr_alt);
4248     W_L("\"");
4249   } 
4250   else {
4251     W_L(" alt=\"\"");
4252   }
4253   W_L(" />");
4254   return android->out;
4255 }
4256
4257
4258 /**
4259  * It is a handler who processes the IMG tag.
4260  *
4261  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4262  *                     destination is specified.
4263  * @param node   [i]   The IMG tag node is specified.
4264  * @return The conversion result is returned.
4265  */
4266 static char *
4267 s_android_end_img_tag(void *pdoc, Node *UNUSED(child)) 
4268 {
4269   android_t *android = GET_ANDROID(pdoc);
4270   return android->out;
4271 }
4272
4273
4274 /**
4275  * It is a handler who processes the SELECT tag.
4276  *
4277  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4278  *                     destination is specified.
4279  * @param node   [i]   The SELECT tag node is specified.
4280  * @return The conversion result is returned.
4281  */
4282 static char *
4283 s_android_start_select_tag(void *pdoc, Node *node)
4284 {
4285   android_t *android    = GET_ANDROID(pdoc);
4286   Doc     *doc      = android->doc;
4287   Attr    *attr;
4288   char    *size     = NULL;
4289   char    *name     = NULL;
4290   char    *multiple = NULL;
4291   char    *attr_style = NULL;
4292
4293   W_L("<select");
4294   for (attr = qs_get_attr(doc,node);
4295        attr;
4296        attr = qs_get_next_attr(doc,attr)) {
4297     char *nm  = qs_get_attr_name(doc,attr);
4298     char *val = qs_get_attr_value(doc,attr);
4299     if (STRCASEEQ('s','S',"size",nm)) {
4300       /*----------------------------------------------------------------------*/
4301       /* CHTML 1.0 version 2.0                                                */
4302       /*----------------------------------------------------------------------*/
4303       size = apr_pstrdup(doc->buf.pool, val);
4304     }
4305     else if (STRCASEEQ('s','S',"style",nm) && val && *val) {
4306       /*----------------------------------------------------------------------*/
4307       /* CHTML 1.0 version 2.0                                                */
4308       /*----------------------------------------------------------------------*/
4309       attr_style = apr_pstrdup(doc->buf.pool, val);
4310     }
4311     else if (STRCASEEQ('n','N',"name",nm)) {
4312       /*----------------------------------------------------------------------*/
4313       /* CHTML 1.0 version 2.0                                                */
4314       /*----------------------------------------------------------------------*/
4315       name = apr_pstrdup(doc->buf.pool, val);
4316     }
4317     else if (STRCASEEQ('m','M',"multiple", nm)) {
4318       /*----------------------------------------------------------------------*/
4319       /* CHTML 1.0 version 2.0                                                */
4320       /*----------------------------------------------------------------------*/
4321       multiple = apr_pstrdup(doc->buf.pool, val);
4322     }
4323   }
4324   if (size && *size) {
4325     W_L(" size=\"");
4326     W_V(size);
4327     W_L("\"");
4328   }
4329   if (name && *name) {
4330     W_L(" name=\"");
4331     W_V(name);
4332     W_L("\"");
4333   }
4334   if (multiple) {
4335     W_L(" multiple=\"multiple\"");
4336   }
4337   W_L(">");
4338
4339   if (IS_CSS_ON(android->entryp)) {
4340     s_android_nopush_and_get_now_style(pdoc, node, attr_style);
4341   }
4342
4343   return android->out;
4344 }
4345
4346
4347 /**
4348  * It is a handler who processes the SELECT tag.
4349  *
4350  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4351  *                     destination is specified.
4352  * @param node   [i]   The SELECT tag node is specified.
4353  * @return The conversion result is returned.
4354  */
4355 static char *
4356 s_android_end_select_tag(void *pdoc, Node *UNUSED(child))
4357 {
4358   android_t *android = GET_ANDROID(pdoc);
4359   Doc     *doc   = android->doc;
4360
4361   W_L("</select>");
4362   if (IS_CSS_ON(android->entryp)) {
4363     chxj_css_pop_prop_list(android->css_prop_stack);
4364   }
4365
4366   return android->out;
4367 }
4368
4369 /**
4370  * It is a handler who processes the OPTION tag.
4371  *
4372  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4373  *                     destination is specified.
4374  * @param node   [i]   The OPTION tag node is specified.
4375  * @return The conversion result is returned.
4376  */
4377 static char *
4378 s_android_start_option_tag(void *pdoc, Node *node)
4379 {
4380   android_t *android = GET_ANDROID(pdoc);
4381   Doc     *doc   = android->doc;
4382   Attr    *attr;
4383
4384   char *selected   = NULL;
4385   char *value      = NULL;
4386   char *attr_style = NULL;
4387
4388   W_L("<option");
4389   for (attr = qs_get_attr(doc,node);
4390        attr;
4391        attr = qs_get_next_attr(doc,attr)) {
4392     char *nm  = qs_get_attr_name(doc,attr);
4393     char *val = qs_get_attr_value(doc,attr);
4394     if (STRCASEEQ('s','S',"selected",nm)) {
4395       /*----------------------------------------------------------------------*/
4396       /* CHTML 1.0 version 2.0                                                */
4397       /*----------------------------------------------------------------------*/
4398       selected = apr_pstrdup(doc->buf.pool, val);
4399     }
4400     else if (STRCASEEQ('s','S',"style",nm) && val && *val) {
4401       /*----------------------------------------------------------------------*/
4402       /* CHTML 1.0 version 2.0                                                */
4403       /*----------------------------------------------------------------------*/
4404       attr_style = apr_pstrdup(doc->buf.pool, val);
4405     }
4406     else if (STRCASEEQ('v','V',"value",nm)) {
4407       /*----------------------------------------------------------------------*/
4408       /* CHTML 1.0 version 2.0                                                */
4409       /*----------------------------------------------------------------------*/
4410       value = apr_pstrdup(doc->buf.pool, val);
4411     }
4412   }
4413   if (value) {
4414     W_L(" value=\"");
4415     W_V(value);
4416     W_L("\"");
4417   }
4418   if (selected) {
4419     W_L(" selected=\"selected\"");
4420   }
4421   W_L(">");
4422
4423   if (IS_CSS_ON(android->entryp)) {
4424     s_android_nopush_and_get_now_style(pdoc, node, attr_style);
4425   }
4426
4427   return android->out;
4428 }
4429
4430
4431 /**
4432  * It is a handler who processes the OPTION tag.
4433  *
4434  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4435  *                     destination is specified.
4436  * @param node   [i]   The OPTION tag node is specified.
4437  * @return The conversion result is returned.
4438  */
4439 static char *
4440 s_android_end_option_tag(void *pdoc, Node *UNUSED(child))
4441 {
4442   android_t *android = GET_ANDROID(pdoc);
4443   Doc      *doc = android->doc;
4444
4445   W_L("</option>");
4446   if (IS_CSS_ON(android->entryp)) {
4447     chxj_css_pop_prop_list(android->css_prop_stack);
4448   }
4449
4450   return android->out;
4451 }
4452
4453
4454 /**
4455  * It is a handler who processes the DIV tag.
4456  *
4457  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4458  *                     destination is specified.
4459  * @param node   [i]   The DIV tag node is specified.
4460  * @return The conversion result is returned.
4461  */
4462 static char *
4463 s_android_start_div_tag(void *pdoc, Node *node)
4464 {
4465   android_t    *android;
4466   Doc         *doc;
4467   request_rec *r;
4468   Attr        *attr;
4469   char        *attr_style             = NULL;
4470   char        *attr_align             = NULL;
4471   char        *attr_display           = NULL;
4472   char        *attr_decoration        = NULL;
4473   char        *attr_wap_marquee_style = NULL;
4474   char        *attr_wap_marquee_dir   = NULL;
4475   char        *attr_wap_marquee_loop  = NULL;
4476   char        *attr_wap_marquee_speed = NULL;
4477   char        *attr_color             = NULL;
4478   char        *attr_bgcolor           = NULL;
4479   char        *attr_font_size         = NULL;
4480   char        *css_clear              = NULL;
4481
4482   android = GET_ANDROID(pdoc);
4483   doc   = android->doc;
4484   r     = doc->r;
4485
4486   for (attr = qs_get_attr(doc,node);
4487        attr;
4488        attr = qs_get_next_attr(doc,attr)) {
4489     char *nm  = qs_get_attr_name(doc,attr);
4490     char *val = qs_get_attr_value(doc,attr);
4491     if (STRCASEEQ('a','A',"align",nm)) {
4492       /*----------------------------------------------------------------------*/
4493       /* CHTML 1.0 (W3C version 3.2)                                          */
4494       /*----------------------------------------------------------------------*/
4495       if (val && (STRCASEEQ('l','L',"left",val) || STRCASEEQ('r','R',"right",val) || STRCASEEQ('c','C',"center",val))) {
4496         attr_align = apr_pstrdup(doc->buf.pool, val);
4497       }
4498     }
4499     else if (STRCASEEQ('s','S',"style",nm) && val && *val) {
4500       attr_style = apr_pstrdup(doc->buf.pool, val);
4501     }
4502   }
4503
4504   if (IS_CSS_ON(android->entryp)) {
4505     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
4506     if (style) {
4507       css_property_t *display_prop           = chxj_css_get_property_value(doc, style, "display");
4508       css_property_t *text_decoration_prop   = chxj_css_get_property_value(doc, style, "text-decoration");
4509       css_property_t *color_prop             = chxj_css_get_property_value(doc, style, "color");
4510       css_property_t *text_align_prop        = chxj_css_get_property_value(doc, style, "text-align");
4511       css_property_t *font_size_prop         = chxj_css_get_property_value(doc, style, "font-size");
4512       css_property_t *background_color_prop  = chxj_css_get_property_value(doc, style, "background-color");
4513       css_property_t *background_prop        = chxj_css_get_property_value(doc, style, "background");
4514       css_property_t *clear_prop             = chxj_css_get_property_value(doc, style, "clear");
4515
4516       css_property_t *cur;
4517       for (cur = display_prop->next; cur != display_prop; cur = cur->next) {
4518         if (strcasecmp("-wap-marquee", cur->value) == 0) {
4519           attr_display = apr_pstrdup(doc->pool, cur->value);
4520         }
4521       }
4522       for (cur = text_decoration_prop->next; cur != text_decoration_prop; cur = cur->next) {
4523         if (STRCASEEQ('b','B',"blink", cur->value)) {
4524           attr_decoration = apr_pstrdup(doc->pool, cur->value);
4525         }
4526       }
4527       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
4528         attr_color = apr_pstrdup(doc->pool, cur->value);
4529       }
4530       for (cur = background_color_prop->next; cur != background_color_prop; cur = cur->next) {
4531         attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
4532         attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
4533       }
4534       for (cur = background_prop->next; cur != background_prop; cur = cur->next) {
4535         char *ss = strchr(cur->value, '#');
4536         if (!ss || !*ss) {
4537           ss = strstr(cur->value, "rgb");
4538         }
4539         if (ss && *ss) {
4540           attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
4541           attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
4542         }
4543       }
4544       for (cur = text_align_prop->next; cur != text_align_prop; cur = cur->next) {
4545         attr_align = apr_pstrdup(doc->pool, cur->value);
4546       }
4547       for (cur = font_size_prop->next; cur != font_size_prop; cur = cur->next) {
4548         if (   STRCASEEQ('x','X',"xx-small",cur->value)
4549             || STRCASEEQ('x','X',"x-small",cur->value)
4550             || STRCASEEQ('s','S',"small",cur->value)
4551             || STRCASEEQ('m','M',"medium",cur->value)
4552             || STRCASEEQ('l','L',"large",cur->value)
4553             || STRCASEEQ('x','X',"x-large",cur->value)
4554             || STRCASEEQ('x','X',"xx-large",cur->value)) {
4555           attr_font_size = apr_pstrdup(doc->pool, cur->value);
4556         }
4557       }
4558       if (attr_display) {
4559         css_property_t *wap_marquee_style_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-style");
4560         css_property_t *wap_marquee_dir_prop   = chxj_css_get_property_value(doc, style, "-wap-marquee-dir");
4561         css_property_t *wap_marquee_loop_prop  = chxj_css_get_property_value(doc, style, "-wap-marquee-loop");
4562         css_property_t *wap_marquee_speed_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-speed");
4563         for (cur = wap_marquee_style_prop->next; cur != wap_marquee_style_prop; cur = cur->next) {
4564           if (STRCASEEQ('s','S',"scroll", cur->value) || STRCASEEQ('s','S',"slide",cur->value) || STRCASEEQ('a','A',"alternate",cur->value)) {
4565             attr_wap_marquee_style = apr_pstrdup(doc->pool, cur->value);
4566           }
4567         }
4568         for (cur = wap_marquee_dir_prop->next; cur != wap_marquee_dir_prop; cur = cur->next) {
4569           if (STRCASEEQ('l','L',"ltr",cur->value)) {
4570             attr_wap_marquee_dir = apr_pstrdup(doc->pool, cur->value);
4571           }
4572           else if (STRCASEEQ('r','R',"rtl",cur->value)) {
4573             attr_wap_marquee_dir = apr_pstrdup(doc->pool, cur->value);
4574           }
4575         }
4576         for (cur = wap_marquee_loop_prop->next; cur != wap_marquee_loop_prop; cur = cur->next) {
4577           if(strcmp(cur->value,"0") == 0 || strcmp(cur->value,"-1") == 0){
4578             attr_wap_marquee_loop = "infinite";
4579           }
4580           else{
4581             attr_wap_marquee_loop = apr_pstrdup(doc->pool, cur->value);
4582           }
4583         }
4584         for (cur = wap_marquee_speed_prop->next; cur != wap_marquee_speed_prop; cur = cur->next) {
4585           attr_wap_marquee_speed = apr_pstrdup(doc->pool, cur->value);
4586         }
4587       }
4588       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
4589         css_clear = apr_pstrdup(doc->pool, cur->value);
4590       }
4591     }
4592   }  
4593   W_L("<div");
4594   if (attr_align
4595       || attr_display
4596       || attr_decoration
4597       || attr_wap_marquee_style
4598       || attr_wap_marquee_dir
4599       || attr_wap_marquee_loop
4600       || attr_wap_marquee_speed
4601       || attr_color
4602       || attr_bgcolor
4603       || attr_font_size
4604       || css_clear ) {
4605     W_L(" style=\"");
4606     if (attr_align) {
4607       W_L("text-align:");
4608       W_V(attr_align);
4609       W_L(";");
4610     }
4611     if (attr_display) {
4612       /* only marquee */
4613       W_L("overflow:-webkit-marquee;");
4614     }
4615     if (attr_decoration) {
4616       if (STRCASEEQ('b','B',"blink",attr_decoration)) {
4617         W_L(STYLE_BLINK);
4618         if (android->blink_keyframe_out == 0) {
4619           android->style_data = apr_pstrcat(doc->pool, (android->style_data) ? android->style_data : "",
4620                                                       BLINK_KEYFRAME,
4621                                                       NULL);
4622           android->blink_keyframe_out = 1;
4623         }
4624       }
4625       else {
4626         W_L("text-decoration:");
4627         W_V(attr_decoration);
4628         W_L(";");
4629       }
4630     }
4631     if (attr_wap_marquee_style) {
4632       W_L("-webkit-marquee-style:");
4633       W_V(attr_wap_marquee_style);
4634       W_L(";");
4635     }
4636     if (attr_wap_marquee_dir) {
4637       W_L("-webkit-marquee-direction:");
4638       if (STRCASEEQ('r','R',"rtl",attr_wap_marquee_dir)) {
4639         W_L("left");
4640       }
4641       else if (STRCASEEQ('l','L',"ltr",attr_wap_marquee_dir)) {
4642         W_L("right");
4643       }
4644       W_L(";");
4645     }
4646     if (attr_wap_marquee_loop) {
4647       W_L("-webkit-marquee-repetition:");
4648       W_V(attr_wap_marquee_loop);
4649       W_L(";");
4650     }
4651     if (attr_wap_marquee_speed) {
4652       W_L("-webkit-marquee-speed:");
4653       W_V(attr_wap_marquee_speed);
4654       W_L(";");
4655     }
4656     if (attr_color) {
4657       W_L("color:");
4658       W_V(attr_color);
4659       W_L(";");
4660     }
4661     if (attr_bgcolor) {
4662       W_L("background-color:");
4663       W_V(attr_bgcolor);
4664       W_L(";");
4665     }
4666     if (attr_font_size) {
4667       W_L("font-size:");
4668       W_V(attr_font_size);
4669       W_L(";");
4670     }
4671     if (css_clear){
4672       W_L("clear:");
4673       W_V(css_clear);
4674       W_L(";");
4675     }
4676     W_L("\"");
4677   }
4678   W_L(">");
4679   return android->out;
4680 }
4681
4682
4683 /**
4684  * It is a handler who processes the DIV tag.
4685  *
4686  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4687  *                     destination is specified.
4688  * @param node   [i]   The DIV tag node is specified.
4689  * @return The conversion result is returned.
4690  */
4691 static char *
4692 s_android_end_div_tag(void *pdoc, Node *UNUSED(child))
4693 {
4694   android_t      *android;
4695   Doc          *doc;
4696   request_rec  *r;
4697
4698   android = GET_ANDROID(pdoc);
4699   doc   = android->doc;
4700   r     = doc->r;
4701
4702   W_L("</div>");
4703   if (IS_CSS_ON(android->entryp)) {
4704     chxj_css_pop_prop_list(android->css_prop_stack);
4705   }
4706   return android->out;
4707 }
4708
4709
4710 static char *
4711 s_android_chxjif_tag(void *pdoc, Node *node)
4712 {
4713   android_t *android;
4714   Doc     *doc;
4715   Node    *child;
4716   request_rec *r;
4717
4718   android = GET_ANDROID(pdoc);
4719   doc   = android->doc;
4720   r     = doc->r;
4721
4722   for (child = qs_get_child_node(doc, node);
4723        child;
4724        child = qs_get_next_node(doc, child)) {
4725     W_V(child->otext);
4726     s_android_chxjif_tag(android, child);
4727   }
4728   return NULL;
4729 }
4730
4731
4732 /**
4733  * It is a handler who processes the TEXTARE tag.
4734  *
4735  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4736  *                     destination is specified.
4737  * @param node   [i]   The TEXTAREA tag node is specified.
4738  * @return The conversion result is returned.
4739  */
4740 static char *
4741 s_android_start_textarea_tag(void *pdoc, Node *node) 
4742 {
4743   android_t      *android;
4744   Doc           *doc;
4745   request_rec   *r;
4746   Attr          *attr;
4747   char          *attr_accesskey = NULL;
4748   char          *attr_name      = NULL;
4749   char          *attr_rows      = NULL;
4750   char          *attr_cols      = NULL;
4751   char          *attr_istyle    = NULL;
4752   char          *attr_style     = NULL;
4753
4754
4755   android = GET_ANDROID(pdoc);
4756   doc   = android->doc;
4757   r     = doc->r;
4758
4759   android->textarea_flag++;
4760   for (attr = qs_get_attr(doc,node);
4761        attr;
4762        attr = qs_get_next_attr(doc,attr)) {
4763     char *name  = qs_get_attr_name(doc,attr);
4764     char *value = qs_get_attr_value(doc,attr);
4765     if (STRCASEEQ('a','A',"accesskey",name) && value && *value != 0) {
4766       attr_accesskey = value;
4767     }
4768     else if (STRCASEEQ('i','I',"istyle", name) && value && (*value == '1' || *value == '2' || *value == '3' || *value == '4')) {
4769       attr_istyle = value;
4770     }
4771     else if (STRCASEEQ('n','N',"name", name) && value && *value) {
4772       attr_name = value;
4773     }
4774     else if (STRCASEEQ('r','R',"rows", name) && value && *value) {
4775       attr_rows = value;
4776     }
4777     else if (STRCASEEQ('c','C',"cols", name) && value && *value) {
4778       attr_cols = value;
4779     }
4780     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
4781       attr_style = value;
4782     }
4783   }
4784   if (IS_CSS_ON(android->entryp)) {
4785     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
4786     if (style) {
4787       css_property_t *wap_input_format = chxj_css_get_property_value(doc, style, "-wap-input-format");
4788       css_property_t *cur;
4789       for (cur = wap_input_format->next; cur != wap_input_format; cur = cur->next) {
4790         if (strcasestr(cur->value, "<ja:n>")) {
4791           attr_istyle = "4";
4792         }
4793         else if (strcasestr(cur->value, "<ja:en>")) {
4794           attr_istyle = "3";
4795         }
4796         else if (strcasestr(cur->value, "<ja:hk>")) {
4797           attr_istyle = "2";
4798         }
4799         else if (strcasestr(cur->value, "<ja:h>")) {
4800           attr_istyle = "1";
4801         }
4802       }
4803     }
4804   }
4805   W_L("<textarea");
4806   if (attr_name) {
4807     W_L(" name=\"");
4808     W_V(attr_name);
4809     W_L("\"");
4810   }
4811   if (attr_rows) {
4812     W_L(" rows=\"");
4813     W_V(attr_rows);
4814     W_L("\"");
4815   }
4816   if (attr_cols) {
4817     W_L(" cols=\"");
4818     W_V(attr_cols);
4819     W_L("\"");
4820   }
4821   W_L(">");
4822   return android->out;
4823 }
4824
4825
4826 /**
4827  * It is a handler who processes the TEXTAREA tag.
4828  *
4829  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4830  *                     destination is specified.
4831  * @param node   [i]   The TEXTAREA tag node is specified.
4832  * @return The conversion result is returned.
4833  */
4834 static char *
4835 s_android_end_textarea_tag(void *pdoc, Node *UNUSED(child)) 
4836 {
4837   android_t       *android;
4838   Doc           *doc;
4839   request_rec   *r;
4840
4841   android = GET_ANDROID(pdoc);
4842   doc   = android->doc;
4843   r     = doc->r;
4844
4845   W_L("</textarea>");
4846   android->textarea_flag--;
4847
4848   return android->out;
4849 }
4850
4851
4852 /**
4853  * It is a handler who processes the B tag.
4854  *
4855  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4856  *                     destination is specified.
4857  * @param node   [i]   The B tag node is specified.
4858  * @return The conversion result is returned.
4859  */
4860 static char*
4861 s_android_start_b_tag(void* pdoc, Node* UNUSED(node)) 
4862 {
4863   android_t*      android;
4864   Doc*          doc;
4865   request_rec*  r;
4866
4867   android = GET_ANDROID(pdoc);
4868   doc   = android->doc;
4869   r     = doc->r;
4870
4871   W_L("<b>");
4872   return android->out;
4873 }
4874
4875
4876 /**
4877  * It is a handler who processes the B tag.
4878  *
4879  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4880  *                     destination is specified.
4881  * @param node   [i]   The B tag node is specified.
4882  * @return The conversion result is returned.
4883  */
4884 static char*
4885 s_android_end_b_tag(void* pdoc, Node* UNUSED(child)) 
4886 {
4887   android_t*      android = GET_ANDROID(pdoc);
4888   Doc*          doc   = android->doc;
4889
4890   W_L("</b>");
4891   return android->out;
4892 }
4893
4894 static char*
4895 s_android_text_tag(void* pdoc, Node* child)
4896 {
4897   android_t*     android;
4898   Doc*         doc;
4899   char*        textval;
4900   char*        tmp;
4901   char*        tdst;
4902   char         one_byte[2];
4903   int          ii;
4904   int          tdst_len;
4905   request_rec* r;
4906   apr_size_t   z2h_input_len;
4907
4908   android = GET_ANDROID(pdoc);
4909   doc   = android->doc;
4910   r     = doc->r;
4911
4912   textval = qs_get_node_value(doc,child);
4913   if (strlen(textval) == 0) {
4914     return android->out;
4915   }
4916
4917   tmp = apr_palloc(r->pool, qs_get_node_size(doc,child)+1);
4918   memset(tmp, 0, qs_get_node_size(doc,child)+1);
4919
4920   tdst     = qs_alloc_zero_byte_string(doc->buf.pool);
4921   memset(one_byte, 0, sizeof(one_byte));
4922   tdst_len = 0;
4923
4924   for (ii=0; ii<qs_get_node_size(doc,child); ii++) {
4925     char* out;
4926     int rtn = s_android_search_emoji(android, &textval[ii], &out);
4927     if (rtn) {
4928       tdst = qs_out_apr_pstrcat(r, tdst, out, &tdst_len);
4929       ii+=(rtn - 1);
4930       continue;
4931     }
4932
4933     if (is_sjis_kanji(textval[ii])) {
4934       one_byte[0] = textval[ii+0];
4935       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
4936       one_byte[0] = textval[ii+1];
4937       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
4938       ii++;
4939     }
4940     else 
4941     if (android->pre_flag) {
4942       one_byte[0] = textval[ii+0];
4943       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
4944     }
4945     else
4946     if (android->textarea_flag) {
4947       one_byte[0] = textval[ii+0];
4948       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
4949     }
4950     else {
4951       if (textval[ii] != '\r' && textval[ii] != '\n') {
4952         one_byte[0] = textval[ii+0];
4953         tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
4954       }
4955     }
4956   }
4957   z2h_input_len = strlen(tdst);
4958   tdst = chxj_conv_z2h(r, tdst, &z2h_input_len, android->entryp);
4959
4960   W_V(tdst);
4961   return android->out;
4962 }
4963
4964
4965 /**
4966  * It is a handler who processes the BLOCKQUOTE tag.
4967  *
4968  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
4969  *                     destination is specified.
4970  * @param node   [i]   The BLOCKQUOTE tag node is specified.
4971  * @return The conversion result is returned.
4972  */
4973 static char *
4974 s_android_start_blockquote_tag(void *pdoc, Node *node)
4975 {
4976   android_t *android;
4977   Doc      *doc;
4978   Attr     *attr;
4979   char     *attr_style = NULL;
4980   char     *attr_color = NULL;
4981   char     *attr_size  = NULL;
4982   char     *css_clear  = NULL;
4983
4984   android  = GET_ANDROID(pdoc);
4985   doc     = android->doc;
4986   for (attr = qs_get_attr(doc,node);
4987        attr;
4988        attr = qs_get_next_attr(doc,attr)) {
4989     char *nm  = qs_get_attr_name(doc,attr);
4990     char *val = qs_get_attr_value(doc,attr);
4991     if (val && STRCASEEQ('s','S',"style", nm)) {
4992       attr_style = val;
4993     }
4994   }
4995   if (IS_CSS_ON(android->entryp)) {
4996     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
4997     if (style) {
4998       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
4999       css_property_t *font_size_prop = chxj_css_get_property_value(doc, style, "font-size");
5000       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
5001       
5002       css_property_t *cur;
5003       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
5004         if (cur->value && *cur->value) {
5005           attr_color = apr_pstrdup(doc->pool, cur->value);
5006         }
5007       }
5008       for (cur = font_size_prop->next; cur != font_size_prop; cur = cur->next) {
5009         if (cur->value && *cur->value) {
5010           if (STRCASEEQ('x','X',"xx-small",cur->value)) {
5011             attr_size = apr_pstrdup(doc->pool, cur->value);
5012           }
5013           else if (STRCASEEQ('x','X',"x-small",cur->value)) {
5014             attr_size = apr_pstrdup(doc->pool, cur->value);
5015           }
5016           else if (STRCASEEQ('s','S',"small",cur->value)) {
5017             attr_size = apr_pstrdup(doc->pool, cur->value);
5018           }
5019           else if (STRCASEEQ('m','M',"medium",cur->value)) {
5020             attr_size = apr_pstrdup(doc->pool, cur->value);
5021           }
5022           else if (STRCASEEQ('l','L',"large",cur->value)) {
5023             attr_size = apr_pstrdup(doc->pool, cur->value);
5024           }
5025           else if (STRCASEEQ('x','X',"x-large",cur->value)) {
5026             attr_size = apr_pstrdup(doc->pool, cur->value);
5027           }
5028           else if (STRCASEEQ('x','X',"xx-large",cur->value)) {
5029             attr_size = apr_pstrdup(doc->pool, cur->value);
5030           }
5031         }
5032       }
5033       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
5034         css_clear = apr_pstrdup(doc->pool, cur->value);
5035       }
5036     }
5037   }
5038   W_L("<blockquote");
5039   if (attr_color || attr_size || css_clear) {
5040     W_L(" style=\"");
5041     if (attr_color) {
5042       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
5043       W_L("color:");
5044       W_V(attr_color);
5045       W_L(";");
5046     }
5047     if (attr_size) {
5048       W_L("font-size:");
5049       W_V(attr_size);
5050       W_L(";");
5051     }
5052     if (css_clear){
5053       W_L("clear:");
5054       W_V(css_clear);
5055       W_L(";");
5056     }
5057     W_L("\"");
5058   }
5059   W_L(">");
5060   return android->out;
5061 }
5062
5063
5064 /**
5065  * It is a handler who processes the BLOCKQUOTE tag.
5066  *
5067  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5068  *                     destination is specified.
5069  * @param node   [i]   The BLOCKQUOTE tag node is specified.
5070  * @return The conversion result is returned.
5071  */
5072 static char *
5073 s_android_end_blockquote_tag(void *pdoc, Node *UNUSED(child))
5074 {
5075   android_t *android = GET_ANDROID(pdoc);
5076   Doc     *doc   = android->doc;
5077   W_L("</blockquote>");
5078   if (IS_CSS_ON(android->entryp)) {
5079     chxj_css_pop_prop_list(android->css_prop_stack);
5080   }
5081   return android->out;
5082 }
5083
5084
5085 /**
5086  * It is a handler who processes the DIR tag.
5087  *
5088  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5089  *                     destination is specified.
5090  * @param node   [i]   The DIR tag node is specified.
5091  * @return The conversion result is returned.
5092  */
5093 static char *
5094 s_android_start_dir_tag(void *pdoc, Node *node)
5095 {
5096   android_t *android      = GET_ANDROID(pdoc);
5097   Doc       *doc        = android->doc;
5098   Attr      *attr;
5099   char      *attr_style = NULL;
5100   char      *attr_color = NULL;
5101   char      *attr_type  = NULL;
5102   char      *attr_size  = NULL;
5103   for (attr = qs_get_attr(doc,node);
5104        attr;
5105        attr = qs_get_next_attr(doc,attr)) {
5106     char *name   = qs_get_attr_name(doc,attr);
5107     char *value  = qs_get_attr_value(doc,attr);
5108     if (STRCASEEQ('t','T',"type",name)) {
5109       if (value && (STRCASEEQ('d','D',"disc",value) || STRCASEEQ('c','C',"circle",value) || STRCASEEQ('s','S',"square",value))) {
5110         attr_type = value;
5111       }
5112     }
5113     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
5114       attr_style = value;
5115     }
5116   }
5117   if (IS_CSS_ON(android->entryp)) {
5118     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
5119     if (style) {
5120       css_property_t *color_prop           = chxj_css_get_property_value(doc, style, "color");
5121       css_property_t *size_prop            = chxj_css_get_property_value(doc, style, "font-size");
5122       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type");
5123       css_property_t *cur;
5124       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
5125         if (cur->value && *cur->value) {
5126           attr_color = apr_pstrdup(doc->pool, cur->value);
5127         }
5128       }
5129       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
5130         if (cur->value && *cur->value) {
5131           attr_type = apr_pstrdup(doc->pool, cur->value);
5132         }
5133       }
5134       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
5135         if (cur->value && *cur->value) {
5136           if (STRCASEEQ('x','X',"xx-small",cur->value)) {
5137             attr_size = apr_pstrdup(doc->pool, cur->value);
5138           }
5139           else if (STRCASEEQ('x','X',"x-small",cur->value)) {
5140             attr_size = apr_pstrdup(doc->pool, cur->value);
5141           }
5142           else if (STRCASEEQ('s','S',"small",cur->value)) {
5143             attr_size = apr_pstrdup(doc->pool, cur->value);
5144           }
5145           else if (STRCASEEQ('m','M',"medium",cur->value)) {
5146             attr_size = apr_pstrdup(doc->pool, cur->value);
5147           }
5148           else if (STRCASEEQ('l','L',"large",cur->value)) {
5149             attr_size = apr_pstrdup(doc->pool, cur->value);
5150           }
5151           else if (STRCASEEQ('x','X',"x-large",cur->value)) {
5152             attr_size = apr_pstrdup(doc->pool, cur->value);
5153           }
5154           else if (STRCASEEQ('x','X',"xx-large",cur->value)) {
5155             attr_size = apr_pstrdup(doc->pool, cur->value);
5156           }
5157         }
5158       }
5159     }
5160   }
5161   W_L("<dir");
5162   if (attr_type || attr_color || attr_size) {
5163     W_L(" style=\"");
5164     if (attr_type) {
5165       W_L("list-style-type:");
5166       W_V(attr_type);
5167       W_L(";");
5168     }
5169     if (attr_color) {
5170       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
5171       W_L("color:");
5172       W_V(attr_color);
5173       W_L(";");
5174     }
5175     if (attr_size) {
5176       W_L("font-size:");
5177       W_V(attr_size);
5178       W_L(";");
5179     }
5180     W_L("\"");
5181   }
5182   W_L(">");
5183   return android->out;
5184 }
5185
5186
5187 /**
5188  * It is a handler who processes the DIR tag.
5189  *
5190  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5191  *                     destination is specified.
5192  * @param node   [i]   The DIR tag node is specified.
5193  * @return The conversion result is returned.
5194  */
5195 static char *
5196 s_android_end_dir_tag(void *pdoc, Node *UNUSED(child))
5197 {
5198   android_t *android = GET_ANDROID(pdoc);
5199   Doc *doc = android->doc;
5200   W_L("</dir>");
5201   if (IS_CSS_ON(android->entryp)) {
5202     chxj_css_pop_prop_list(android->css_prop_stack);
5203   }
5204   return android->out;
5205 }
5206
5207
5208 /**
5209  * It is a handler who processes the DL tag.
5210  *
5211  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5212  *                     destination is specified.
5213  * @param node   [i]   The DL tag node is specified.
5214  * @return The conversion result is returned.
5215  */
5216 static char *
5217 s_android_start_dl_tag(void *pdoc, Node *node)
5218 {
5219   android_t *android      = GET_ANDROID(pdoc);
5220   Doc       *doc        = android->doc;
5221   Attr      *attr;
5222   char      *attr_style = NULL;
5223   char      *attr_color = NULL;
5224   char      *attr_size  = NULL;
5225   char      *css_clear  = NULL;
5226   
5227   for (attr = qs_get_attr(doc,node);
5228        attr;
5229        attr = qs_get_next_attr(doc,attr)) {
5230     char *name   = qs_get_attr_name(doc,attr);
5231     char *value  = qs_get_attr_value(doc,attr);
5232     if (STRCASEEQ('s','S',"style", name) && value && *value) {
5233       attr_style = value;
5234     }
5235   }
5236   if (IS_CSS_ON(android->entryp)) {
5237     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
5238     if (style) {
5239       css_property_t *color_prop           = chxj_css_get_property_value(doc, style, "color");
5240       css_property_t *size_prop            = chxj_css_get_property_value(doc, style, "font-size");
5241       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
5242       
5243       css_property_t *cur;
5244       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
5245         if (cur->value && *cur->value) {
5246           attr_color = apr_pstrdup(doc->pool, cur->value);
5247         }
5248       }
5249       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
5250         if (cur->value && *cur->value) {
5251           if (STRCASEEQ('x','X',"xx-small",cur->value)) {
5252             attr_size = apr_pstrdup(doc->pool, cur->value);
5253           }
5254           else if (STRCASEEQ('x','X',"x-small",cur->value)) {
5255             attr_size = apr_pstrdup(doc->pool, cur->value);
5256           }
5257           else if (STRCASEEQ('s','S',"small",cur->value)) {
5258             attr_size = apr_pstrdup(doc->pool, cur->value);
5259           }
5260           else if (STRCASEEQ('m','M',"medium",cur->value)) {
5261             attr_size = apr_pstrdup(doc->pool, cur->value);
5262           }
5263           else if (STRCASEEQ('l','L',"large",cur->value)) {
5264             attr_size = apr_pstrdup(doc->pool, cur->value);
5265           }
5266           else if (STRCASEEQ('x','X',"x-large",cur->value)) {
5267             attr_size = apr_pstrdup(doc->pool, cur->value);
5268           }
5269           else if (STRCASEEQ('x','X',"xx-large",cur->value)) {
5270             attr_size = apr_pstrdup(doc->pool, cur->value);
5271           }
5272         }
5273       }
5274       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
5275         css_clear = apr_pstrdup(doc->pool, cur->value);
5276       }
5277     }
5278   }
5279   W_L("<dl");
5280   if (attr_color || attr_size || css_clear) {
5281     W_L(" style=\"");
5282     if (attr_color) {
5283       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
5284       W_L("color:");
5285       W_V(attr_color);
5286       W_L(";");
5287     }
5288     if (attr_size) {
5289       W_L("font-size:");
5290       W_V(attr_size);
5291       W_L(";");
5292     }
5293     if (css_clear){
5294       W_L("clear:");
5295       W_V(css_clear);
5296       W_L(";");
5297     }
5298     W_L("\"");
5299   }
5300   W_L(">");
5301   return android->out;
5302 }
5303
5304
5305 /**
5306  * It is a handler who processes the DL tag.
5307  *
5308  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5309  *                     destination is specified.
5310  * @param node   [i]   The DL tag node is specified.
5311  * @return The conversion result is returned.
5312  */
5313 static char *
5314 s_android_end_dl_tag(void *pdoc, Node *UNUSED(child))
5315 {
5316   android_t *android = GET_ANDROID(pdoc);
5317   Doc *doc = android->doc;
5318   W_L("</dl>");
5319   if (IS_CSS_ON(android->entryp)) {
5320     chxj_css_pop_prop_list(android->css_prop_stack);
5321   }
5322   return android->out;
5323 }
5324
5325
5326 /**
5327  * It is a handler who processes the DT tag.
5328  *
5329  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5330  *                     destination is specified.
5331  * @param node   [i]   The DT tag node is specified.
5332  * @return The conversion result is returned.
5333  */
5334 static char *
5335 s_android_start_dt_tag(void *pdoc, Node *node)
5336 {
5337   android_t *android      = GET_ANDROID(pdoc);
5338   Doc       *doc        = android->doc;
5339   Attr      *attr;
5340   char      *attr_style = NULL;
5341   char      *attr_color = NULL;
5342   char      *attr_size  = NULL;
5343   for (attr = qs_get_attr(doc,node);
5344        attr;
5345        attr = qs_get_next_attr(doc,attr)) {
5346     char *name   = qs_get_attr_name(doc,attr);
5347     char *value  = qs_get_attr_value(doc,attr);
5348     if (STRCASEEQ('s','S',"style", name) && value && *value) {
5349       attr_style = value;
5350     }
5351   }
5352   if (IS_CSS_ON(android->entryp)) {
5353     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
5354     if (style) {
5355       css_property_t *color_prop           = chxj_css_get_property_value(doc, style, "color");
5356       css_property_t *size_prop            = chxj_css_get_property_value(doc, style, "font-size");
5357       css_property_t *cur;
5358       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
5359         if (cur->value && *cur->value) {
5360           attr_color = apr_pstrdup(doc->pool, cur->value);
5361         }
5362       }
5363       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
5364         if (cur->value && *cur->value) {
5365           if (STRCASEEQ('x','X',"xx-small",cur->value)) {
5366             attr_size = apr_pstrdup(doc->pool, cur->value);
5367           }
5368           else if (STRCASEEQ('x','X',"x-small",cur->value)) {
5369             attr_size = apr_pstrdup(doc->pool, cur->value);
5370           }
5371           else if (STRCASEEQ('s','S',"small",cur->value)) {
5372             attr_size = apr_pstrdup(doc->pool, cur->value);
5373           }
5374           else if (STRCASEEQ('m','M',"medium",cur->value)) {
5375             attr_size = apr_pstrdup(doc->pool, cur->value);
5376           }
5377           else if (STRCASEEQ('l','L',"large",cur->value)) {
5378             attr_size = apr_pstrdup(doc->pool, cur->value);
5379           }
5380           else if (STRCASEEQ('x','X',"x-large",cur->value)) {
5381             attr_size = apr_pstrdup(doc->pool, cur->value);
5382           }
5383           else if (STRCASEEQ('x','X',"xx-large",cur->value)) {
5384             attr_size = apr_pstrdup(doc->pool, cur->value);
5385           }
5386         }
5387       }
5388     }
5389   }
5390   W_L("<dt");
5391   if (attr_color || attr_size) {
5392     W_L(" style=\"");
5393     if (attr_color) {
5394       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
5395       W_L("color:");
5396       W_V(attr_color);
5397       W_L(";");
5398     }
5399     if (attr_size) {
5400       W_L("font-size:");
5401       W_V(attr_size);
5402       W_L(";");
5403     }
5404     W_L("\"");
5405   }
5406   W_L(">");
5407   return android->out;
5408 }
5409
5410
5411 /**
5412  * It is a handler who processes the DT tag.
5413  *
5414  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5415  *                     destination is specified.
5416  * @param node   [i]   The DT tag node is specified.
5417  * @return The conversion result is returned.
5418  */
5419 static char *
5420 s_android_end_dt_tag(void *pdoc, Node *UNUSED(child))
5421 {
5422   android_t *android = GET_ANDROID(pdoc);
5423   Doc      *doc    = android->doc;
5424   W_L("</dt>");
5425   if (IS_CSS_ON(android->entryp)) {
5426     chxj_css_pop_prop_list(android->css_prop_stack);
5427   }
5428   return android->out;
5429 }
5430
5431
5432 /**
5433  * It is a handler who processes the DD tag.
5434  *
5435  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5436  *                     destination is specified.
5437  * @param node   [i]   The DD tag node is specified.
5438  * @return The conversion result is returned.
5439  */
5440 static char *
5441 s_android_start_dd_tag(void *pdoc, Node *node)
5442 {
5443   android_t *android      = GET_ANDROID(pdoc);
5444   Doc       *doc        = android->doc;
5445   Attr      *attr;
5446   char      *attr_style = NULL;
5447   char      *attr_color = NULL;
5448   char      *attr_size  = NULL;
5449   for (attr = qs_get_attr(doc,node);
5450        attr;
5451        attr = qs_get_next_attr(doc,attr)) {
5452     char *name   = qs_get_attr_name(doc,attr);
5453     char *value  = qs_get_attr_value(doc,attr);
5454     if (STRCASEEQ('s','S',"style", name) && value && *value) {
5455       attr_style = value;
5456     }
5457   }
5458   if (IS_CSS_ON(android->entryp)) {
5459     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
5460     if (style) {
5461       css_property_t *color_prop           = chxj_css_get_property_value(doc, style, "color");
5462       css_property_t *size_prop            = chxj_css_get_property_value(doc, style, "font-size");
5463       css_property_t *cur;
5464       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
5465         if (cur->value && *cur->value) {
5466           attr_color = apr_pstrdup(doc->pool, cur->value);
5467         }
5468       }
5469       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
5470         if (cur->value && *cur->value) {
5471           if (STRCASEEQ('x','X',"xx-small",cur->value)) {
5472             attr_size = apr_pstrdup(doc->pool, cur->value);
5473           }
5474           else if (STRCASEEQ('x','X',"x-small",cur->value)) {
5475             attr_size = apr_pstrdup(doc->pool, cur->value);
5476           }
5477           else if (STRCASEEQ('s','S',"small",cur->value)) {
5478             attr_size = apr_pstrdup(doc->pool, cur->value);
5479           }
5480           else if (STRCASEEQ('m','M',"medium",cur->value)) {
5481             attr_size = apr_pstrdup(doc->pool, cur->value);
5482           }
5483           else if (STRCASEEQ('l','L',"large",cur->value)) {
5484             attr_size = apr_pstrdup(doc->pool, cur->value);
5485           }
5486           else if (STRCASEEQ('x','X',"x-large",cur->value)) {
5487             attr_size = apr_pstrdup(doc->pool, cur->value);
5488           }
5489           else if (STRCASEEQ('x','X',"xx-large",cur->value)) {
5490             attr_size = apr_pstrdup(doc->pool, cur->value);
5491           }
5492         }
5493       }
5494     }
5495   }
5496   W_L("<dd");
5497   if (attr_color || attr_size) {
5498     W_L(" style=\"");
5499     if (attr_color) {
5500       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
5501       W_L("color:");
5502       W_V(attr_color);
5503       W_L(";");
5504     }
5505     if (attr_size) {
5506       W_L("font-size:");
5507       W_V(attr_size);
5508       W_L(";");
5509     }
5510     W_L("\"");
5511   }
5512   W_L(">");
5513   return android->out;
5514 }
5515
5516
5517 /**
5518  * It is a handler who processes the DD tag.
5519  *
5520  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5521  *                     destination is specified.
5522  * @param node   [i]   The DD tag node is specified.
5523  * @return The conversion result is returned.
5524  */
5525 static char *
5526 s_android_end_dd_tag(void *pdoc, Node *UNUSED(child))
5527 {
5528   android_t *android = GET_ANDROID(pdoc);
5529   Doc      *doc = android->doc;
5530   W_L("</dd>");
5531   if (IS_CSS_ON(android->entryp)) {
5532     chxj_css_pop_prop_list(android->css_prop_stack);
5533   }
5534   return android->out;
5535 }
5536
5537
5538 /**
5539  * It is a handler who processes the H1 tag.
5540  *
5541  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5542  *                     destination is specified.
5543  * @param node   [i]   The H1 tag node is specified.
5544  * @return The conversion result is returned.
5545  */
5546 static char *
5547 s_android_start_h1_tag(void *pdoc, Node *node)
5548 {
5549   android_t    *android;
5550   Doc         *doc;
5551   request_rec *r;
5552   Attr        *attr;
5553   char        *attr_style = NULL;
5554   char        *attr_align = NULL;
5555   char        *css_clear  = NULL;
5556
5557   android = GET_ANDROID(pdoc);
5558   doc    = android->doc;
5559   r      = doc->r;
5560
5561   for (attr = qs_get_attr(doc,node);
5562        attr;
5563        attr = qs_get_next_attr(doc,attr)) {
5564     char *name  = qs_get_attr_name(doc,attr);
5565     char *value = qs_get_attr_value(doc,attr);
5566     if (STRCASEEQ('a','A',"align", name)) {
5567       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
5568         attr_align = value;
5569       }
5570     }
5571     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
5572       attr_style = value;
5573     }
5574   }
5575   if (IS_CSS_ON(android->entryp)) {
5576     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
5577     if (style) {
5578       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
5579       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
5580       css_property_t *cur;
5581       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
5582         if (STRCASEEQ('l','L',"left", cur->value)) {
5583           attr_align = apr_pstrdup(doc->pool, "left");
5584         }
5585         else if (STRCASEEQ('c','C',"center",cur->value)) {
5586           attr_align = apr_pstrdup(doc->pool, "center");
5587         }
5588         else if (STRCASEEQ('r','R',"right",cur->value)) {
5589           attr_align = apr_pstrdup(doc->pool, "right");
5590         }
5591       }
5592       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
5593         if (STRCASEEQ('b','B',"both", cur->value)) {
5594           css_clear = apr_pstrdup(doc->pool, "both");
5595         }
5596         else if (STRCASEEQ('r','R',"right", cur->value)) {
5597           css_clear = apr_pstrdup(doc->pool, "right");
5598         }
5599         else if (STRCASEEQ('l','L',"left", cur->value)) {
5600           css_clear = apr_pstrdup(doc->pool, "left");
5601         }
5602       }
5603     }
5604   }
5605   W_L("<h1");
5606   if (attr_align || css_clear ) {
5607     W_L(" style=\"");
5608     if(attr_align){
5609       W_L("text-align:");
5610       W_V(attr_align);
5611       W_L(";");
5612     }
5613     if(css_clear){
5614       W_L("clear:");
5615       W_V(css_clear);
5616       W_L(";");
5617     }
5618     W_L("\"");
5619   }
5620   W_L(">");
5621
5622   return android->out;
5623 }
5624
5625
5626 /**
5627  * It is a handler who processes the H1 tag.
5628  *
5629  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5630  *                     destination is specified.
5631  * @param node   [i]   The H1 tag node is specified.
5632  * @return The conversion result is returned.
5633  */
5634 static char *
5635 s_android_end_h1_tag(void *pdoc, Node *UNUSED(child)) 
5636 {
5637   android_t*    android;
5638   Doc*          doc;
5639   request_rec*  r;
5640
5641   android = GET_ANDROID(pdoc);
5642   doc     = android->doc;
5643   r       = doc->r;
5644   
5645   W_L("</h1>");
5646   if (IS_CSS_ON(android->entryp)) {
5647     chxj_css_pop_prop_list(android->css_prop_stack);
5648   }
5649
5650   return android->out;
5651 }
5652
5653
5654 /**
5655  * It is a handler who processes the H2 tag.
5656  *
5657  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5658  *                     destination is specified.
5659  * @param node   [i]   The H1 tag node is specified.
5660  * @return The conversion result is returned.
5661  */
5662 static char *
5663 s_android_start_h2_tag(void *pdoc, Node *node)
5664 {
5665   android_t    *android;
5666   Doc         *doc;
5667   request_rec *r;
5668   Attr        *attr;
5669   char        *attr_style = NULL;
5670   char        *attr_align = NULL;
5671   char        *css_clear  = NULL;
5672
5673   android   = GET_ANDROID(pdoc);
5674   doc     = android->doc;
5675   r       = doc->r;
5676
5677   for (attr = qs_get_attr(doc,node);
5678        attr;
5679        attr = qs_get_next_attr(doc,attr)) {
5680     char *name  = qs_get_attr_name(doc,attr);
5681     char *value = qs_get_attr_value(doc,attr);
5682     if (STRCASEEQ('a','A',"align", name)) {
5683       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
5684         attr_align = value;
5685       }
5686     }
5687     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
5688       attr_style = value;
5689     }
5690   }
5691   if (IS_CSS_ON(android->entryp)) {
5692     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
5693     if (style) {
5694       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
5695       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
5696       css_property_t *cur;
5697       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
5698         if (STRCASEEQ('l','L',"left", cur->value)) {
5699           attr_align = apr_pstrdup(doc->pool, "left");
5700         }
5701         else if (STRCASEEQ('c','C',"center",cur->value)) {
5702           attr_align = apr_pstrdup(doc->pool, "center");
5703         }
5704         else if (STRCASEEQ('r','R',"right",cur->value)) {
5705           attr_align = apr_pstrdup(doc->pool, "right");
5706         }
5707       }
5708       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
5709         if (STRCASEEQ('b','B',"both", cur->value)) {
5710           css_clear = apr_pstrdup(doc->pool, "both");
5711         }
5712         else if (STRCASEEQ('r','R',"right", cur->value)) {
5713           css_clear = apr_pstrdup(doc->pool, "right");
5714         }
5715         else if (STRCASEEQ('l','L',"left", cur->value)) {
5716           css_clear = apr_pstrdup(doc->pool, "left");
5717         }
5718       }
5719     }
5720   }
5721   W_L("<h2");
5722   if (attr_align || css_clear ) {
5723     W_L(" style=\"");
5724     if(attr_align){
5725       W_L("text-align:");
5726       W_V(attr_align);
5727       W_L(";");
5728     }
5729     if(css_clear){
5730       W_L("clear:");
5731       W_V(css_clear);
5732       W_L(";");
5733     }
5734     W_L("\"");
5735   }
5736   W_L(">");
5737
5738   return android->out;
5739 }
5740
5741
5742 /**
5743  * It is a handler who processes the H2 tag.
5744  *
5745  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5746  *                     destination is specified.
5747  * @param node   [i]   The H1 tag node is specified.
5748  * @return The conversion result is returned.
5749  */
5750 static char *
5751 s_android_end_h2_tag(void *pdoc, Node *UNUSED(child)) 
5752 {
5753   android_t*    android;
5754   Doc*          doc;
5755   request_rec*  r;
5756
5757   android = GET_ANDROID(pdoc);
5758   doc     = android->doc;
5759   r       = doc->r;
5760   
5761   W_L("</h2>");
5762   if (IS_CSS_ON(android->entryp)) {
5763     chxj_css_pop_prop_list(android->css_prop_stack);
5764   }
5765   return android->out;
5766 }
5767
5768
5769 /**
5770  * It is a handler who processes the H3 tag.
5771  *
5772  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5773  *                     destination is specified.
5774  * @param node   [i]   The H1 tag node is specified.
5775  * @return The conversion result is returned.
5776  */
5777 static char *
5778 s_android_start_h3_tag(void *pdoc, Node *node)
5779 {
5780   android_t    *android;
5781   Doc         *doc;
5782   request_rec *r;
5783   Attr        *attr;
5784   char        *attr_style = NULL;
5785   char        *attr_align = NULL;
5786   char        *css_clear  = NULL;
5787
5788   android   = GET_ANDROID(pdoc);
5789   doc     = android->doc;
5790   r       = doc->r;
5791
5792   for (attr = qs_get_attr(doc,node);
5793        attr;
5794        attr = qs_get_next_attr(doc,attr)) {
5795     char *name  = qs_get_attr_name(doc,attr);
5796     char *value = qs_get_attr_value(doc,attr);
5797     if (STRCASEEQ('a','A',"align", name)) {
5798       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
5799         attr_align = value;
5800       }
5801     }
5802     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
5803       attr_style = value;
5804     }
5805   }
5806   if (IS_CSS_ON(android->entryp)) {
5807     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
5808     if (style) {
5809       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
5810       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
5811       css_property_t *cur;
5812       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
5813         if (STRCASEEQ('l','L',"left", cur->value)) {
5814           attr_align = apr_pstrdup(doc->pool, "left");
5815         }
5816         else if (STRCASEEQ('c','C',"center",cur->value)) {
5817           attr_align = apr_pstrdup(doc->pool, "center");
5818         }
5819         else if (STRCASEEQ('r','R',"right",cur->value)) {
5820           attr_align = apr_pstrdup(doc->pool, "right");
5821         }
5822       }
5823       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
5824         if (STRCASEEQ('b','B',"both", cur->value)) {
5825           css_clear = apr_pstrdup(doc->pool, "both");
5826         }
5827         else if (STRCASEEQ('r','R',"right", cur->value)) {
5828           css_clear = apr_pstrdup(doc->pool, "right");
5829         }
5830         else if (STRCASEEQ('l','L',"left", cur->value)) {
5831           css_clear = apr_pstrdup(doc->pool, "left");
5832         }
5833       }
5834     }
5835   }
5836   W_L("<h3");
5837   if (attr_align || css_clear ) {
5838     W_L(" style=\"");
5839     if(attr_align){
5840       W_L("text-align:");
5841       W_V(attr_align);
5842       W_L(";");
5843     }
5844     if(css_clear){
5845       W_L("clear:");
5846       W_V(css_clear);
5847       W_L(";");
5848     }
5849     W_L("\"");
5850   }
5851   W_L(">");
5852
5853   return android->out;
5854 }
5855
5856
5857 /**
5858  * It is a handler who processes the H3 tag.
5859  *
5860  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5861  *                     destination is specified.
5862  * @param node   [i]   The H1 tag node is specified.
5863  * @return The conversion result is returned.
5864  */
5865 static char *
5866 s_android_end_h3_tag(void *pdoc, Node *UNUSED(child)) 
5867 {
5868   android_t*    android;
5869   Doc*          doc;
5870   request_rec*  r;
5871
5872   android = GET_ANDROID(pdoc);
5873   doc     = android->doc;
5874   r       = doc->r;
5875
5876   W_L("</h3>");
5877   if (IS_CSS_ON(android->entryp)) {
5878     chxj_css_pop_prop_list(android->css_prop_stack);
5879   }
5880   return android->out;
5881 }
5882
5883
5884 /**
5885  * It is a handler who processes the H4 tag.
5886  *
5887  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5888  *                     destination is specified.
5889  * @param node   [i]   The H1 tag node is specified.
5890  * @return The conversion result is returned.
5891  */
5892 static char *
5893 s_android_start_h4_tag(void *pdoc, Node *node)
5894 {
5895   android_t    *android;
5896   Doc         *doc;
5897   request_rec *r;
5898   Attr        *attr;
5899   char        *attr_style = NULL;
5900   char        *attr_align = NULL;
5901   char        *css_clear  = NULL;
5902
5903   android   = GET_ANDROID(pdoc);
5904   doc     = android->doc;
5905   r       = doc->r;
5906
5907   for (attr = qs_get_attr(doc,node);
5908        attr;
5909        attr = qs_get_next_attr(doc,attr)) {
5910     char *name  = qs_get_attr_name(doc,attr);
5911     char *value = qs_get_attr_value(doc,attr);
5912     if (STRCASEEQ('a','A',"align", name)) {
5913       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
5914         attr_align = value;
5915       }
5916     }
5917     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
5918       attr_style = value;
5919     }
5920   }
5921   if (IS_CSS_ON(android->entryp)) {
5922     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
5923     if (style) {
5924       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
5925       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
5926       css_property_t *cur;
5927       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
5928         if (STRCASEEQ('l','L',"left", cur->value)) {
5929           attr_align = apr_pstrdup(doc->pool, "left");
5930         }
5931         else if (STRCASEEQ('c','C',"center",cur->value)) {
5932           attr_align = apr_pstrdup(doc->pool, "center");
5933         }
5934         else if (STRCASEEQ('r','R',"right",cur->value)) {
5935           attr_align = apr_pstrdup(doc->pool, "right");
5936         }
5937       }
5938       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
5939         if (STRCASEEQ('b','B',"both", cur->value)) {
5940           css_clear = apr_pstrdup(doc->pool, "both");
5941         }
5942         else if (STRCASEEQ('r','R',"right", cur->value)) {
5943           css_clear = apr_pstrdup(doc->pool, "right");
5944         }
5945         else if (STRCASEEQ('l','L',"left", cur->value)) {
5946           css_clear = apr_pstrdup(doc->pool, "left");
5947         }
5948       }
5949     }
5950   }
5951   W_L("<h4");
5952   if (attr_align || css_clear ) {
5953     W_L(" style=\"");
5954     if(attr_align){
5955       W_L("text-align:");
5956       W_V(attr_align);
5957       W_L(";");
5958     }
5959     if(css_clear){
5960       W_L("clear:");
5961       W_V(css_clear);
5962       W_L(";");
5963     }
5964     W_L("\"");
5965   }
5966   W_L(">");
5967
5968   return android->out;
5969 }
5970
5971
5972 /**
5973  * It is a handler who processes the H4 tag.
5974  *
5975  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
5976  *                     destination is specified.
5977  * @param node   [i]   The H1 tag node is specified.
5978  * @return The conversion result is returned.
5979  */
5980 static char *
5981 s_android_end_h4_tag(void *pdoc, Node *UNUSED(child)) 
5982 {
5983   android_t      *android;
5984   Doc           *doc;
5985   request_rec   *r;
5986
5987   android = GET_ANDROID(pdoc);
5988   doc     = android->doc;
5989   r       = doc->r;
5990   
5991   W_L("</h4>");
5992   if (IS_CSS_ON(android->entryp)) {
5993     chxj_css_pop_prop_list(android->css_prop_stack);
5994   }
5995
5996   return android->out;
5997 }
5998
5999
6000 /**
6001  * It is a handler who processes the H5 tag.
6002  *
6003  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6004  *                     destination is specified.
6005  * @param node   [i]   The H1 tag node is specified.
6006  * @return The conversion result is returned.
6007  */
6008 static char *
6009 s_android_start_h5_tag(void *pdoc, Node *node)
6010 {
6011   android_t    *android;
6012   Doc         *doc;
6013   request_rec *r;
6014   Attr        *attr;
6015   char        *attr_style = NULL;
6016   char        *attr_align = NULL;
6017   char        *css_clear  = NULL;
6018
6019   android   = GET_ANDROID(pdoc);
6020   doc     = android->doc;
6021   r       = doc->r;
6022
6023   for (attr = qs_get_attr(doc,node);
6024        attr;
6025        attr = qs_get_next_attr(doc,attr)) {
6026     char *name  = qs_get_attr_name(doc,attr);
6027     char *value = qs_get_attr_value(doc,attr);
6028     if (STRCASEEQ('a','A',"align", name)) {
6029       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
6030         attr_align = value;
6031       }
6032     }
6033     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
6034       attr_style = value;
6035     }
6036   }
6037   if (IS_CSS_ON(android->entryp)) {
6038     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
6039     if (style) {
6040       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
6041       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
6042       css_property_t *cur;
6043       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
6044         if (STRCASEEQ('l','L',"left", cur->value)) {
6045           attr_align = apr_pstrdup(doc->pool, "left");
6046         }
6047         else if (STRCASEEQ('c','C',"center",cur->value)) {
6048           attr_align = apr_pstrdup(doc->pool, "center");
6049         }
6050         else if (STRCASEEQ('r','R',"right",cur->value)) {
6051           attr_align = apr_pstrdup(doc->pool, "right");
6052         }
6053       }
6054       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
6055         if (STRCASEEQ('b','B',"both", cur->value)) {
6056           css_clear = apr_pstrdup(doc->pool, "both");
6057         }
6058         else if (STRCASEEQ('r','R',"right", cur->value)) {
6059           css_clear = apr_pstrdup(doc->pool, "right");
6060         }
6061         else if (STRCASEEQ('l','L',"left", cur->value)) {
6062           css_clear = apr_pstrdup(doc->pool, "left");
6063         }
6064       }
6065     }
6066   }
6067   W_L("<h5");
6068   if (attr_align || css_clear ) {
6069     W_L(" style=\"");
6070     if(attr_align){
6071       W_L("text-align:");
6072       W_V(attr_align);
6073       W_L(";");
6074     }
6075     if(css_clear){
6076       W_L("clear:");
6077       W_V(css_clear);
6078       W_L(";");
6079     }
6080     W_L("\"");
6081   }
6082   W_L(">");
6083
6084   return android->out;
6085 }
6086
6087
6088 /**
6089  * It is a handler who processes the H5 tag.
6090  *
6091  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6092  *                     destination is specified.
6093  * @param node   [i]   The H1 tag node is specified.
6094  * @return The conversion result is returned.
6095  */
6096 static char *
6097 s_android_end_h5_tag(void *pdoc, Node *UNUSED(child)) 
6098 {
6099   android_t    *android;
6100   Doc         *doc;
6101   request_rec *r;
6102
6103   android = GET_ANDROID(pdoc);
6104   doc     = android->doc;
6105   r       = doc->r;
6106   
6107   W_L("</h5>");
6108   if (IS_CSS_ON(android->entryp)) {
6109     chxj_css_pop_prop_list(android->css_prop_stack);
6110   }
6111
6112   return android->out;
6113 }
6114
6115
6116 /**
6117  * It is a handler who processes the H6 tag.
6118  *
6119  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6120  *                     destination is specified.
6121  * @param node   [i]   The H1 tag node is specified.
6122  * @return The conversion result is returned.
6123  */
6124 static char *
6125 s_android_start_h6_tag(void *pdoc, Node *node)
6126 {
6127   android_t    *android;
6128   Doc         *doc;
6129   request_rec *r;
6130   Attr        *attr;
6131   char        *attr_style = NULL;
6132   char        *attr_align = NULL;
6133   char        *css_clear  = NULL;
6134
6135   android   = GET_ANDROID(pdoc);
6136   doc     = android->doc;
6137   r       = doc->r;
6138
6139   for (attr = qs_get_attr(doc,node);
6140        attr;
6141        attr = qs_get_next_attr(doc,attr)) {
6142     char *name  = qs_get_attr_name(doc,attr);
6143     char *value = qs_get_attr_value(doc,attr);
6144     if (STRCASEEQ('a','A',"align", name)) {
6145       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
6146         attr_align = value;
6147       }
6148     }
6149     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
6150       attr_style = value;
6151     }
6152   }
6153   if (IS_CSS_ON(android->entryp)) {
6154     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
6155     if (style) {
6156       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
6157       css_property_t *clear_prop           = chxj_css_get_property_value(doc, style, "clear");
6158       css_property_t *cur;
6159       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
6160         if (STRCASEEQ('l','L',"left", cur->value)) {
6161           attr_align = apr_pstrdup(doc->pool, "left");
6162         }
6163         else if (STRCASEEQ('c','C',"center",cur->value)) {
6164           attr_align = apr_pstrdup(doc->pool, "center");
6165         }
6166         else if (STRCASEEQ('r','R',"right",cur->value)) {
6167           attr_align = apr_pstrdup(doc->pool, "right");
6168         }
6169       }
6170       for (cur = clear_prop->next; cur != clear_prop; cur = cur->next) {
6171         if (STRCASEEQ('b','B',"both", cur->value)) {
6172           css_clear = apr_pstrdup(doc->pool, "both");
6173         }
6174         else if (STRCASEEQ('r','R',"right", cur->value)) {
6175           css_clear = apr_pstrdup(doc->pool, "right");
6176         }
6177         else if (STRCASEEQ('l','L',"left", cur->value)) {
6178           css_clear = apr_pstrdup(doc->pool, "left");
6179         }
6180       }
6181     }
6182   }
6183   W_L("<h6");
6184   if (attr_align || css_clear ) {
6185     W_L(" style=\"");
6186     if(attr_align){
6187       W_L("text-align:");
6188       W_V(attr_align);
6189       W_L(";");
6190     }
6191     if(css_clear){
6192       W_L("clear:");
6193       W_V(css_clear);
6194       W_L(";");
6195     }
6196     W_L("\"");
6197   }
6198   W_L(">");
6199
6200   return android->out;
6201 }
6202
6203
6204 /**
6205  * It is a handler who processes the H6 tag.
6206  *
6207  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6208  *                     destination is specified.
6209  * @param node   [i]   The H1 tag node is specified.
6210  * @return The conversion result is returned.
6211  */
6212 static char *
6213 s_android_end_h6_tag(void *pdoc, Node *UNUSED(child)) 
6214 {
6215   android_t    *android;
6216   Doc         *doc;
6217   request_rec *r;
6218
6219   android = GET_ANDROID(pdoc);
6220   doc     = android->doc;
6221   r       = doc->r;
6222   
6223   W_L("</h6>");
6224   if (IS_CSS_ON(android->entryp)) {
6225     chxj_css_pop_prop_list(android->css_prop_stack);
6226   }
6227
6228   return android->out;
6229 }
6230
6231
6232 /**
6233  * It is a handler who processes the MENU tag.
6234  *
6235  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6236  *                     destination is specified.
6237  * @param node   [i]   The MENU tag node is specified.
6238  * @return The conversion result is returned.
6239  */
6240 static char *
6241 s_android_start_menu_tag(void *pdoc, Node *node)
6242 {
6243   android_t *android      = GET_ANDROID(pdoc);
6244   Doc       *doc        = android->doc;
6245   Attr      *attr;
6246   char      *attr_style = NULL;
6247   char      *attr_color = NULL;
6248   char      *attr_type  = NULL;
6249   char      *attr_size  = NULL;
6250   for (attr = qs_get_attr(doc,node);
6251        attr;
6252        attr = qs_get_next_attr(doc,attr)) {
6253     char *name   = qs_get_attr_name(doc,attr);
6254     char *value  = qs_get_attr_value(doc,attr);
6255     if (STRCASEEQ('t','T',"type",name)) {
6256       if (value && (STRCASEEQ('d','D',"disc",value) || STRCASEEQ('c','C',"circle",value) || STRCASEEQ('s','S',"square",value))) {
6257         attr_type = value;
6258       }
6259     }
6260     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
6261       attr_style = value;
6262     }
6263   }
6264   if (IS_CSS_ON(android->entryp)) {
6265     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
6266     if (style) {
6267       css_property_t *color_prop           = chxj_css_get_property_value(doc, style, "color");
6268       css_property_t *size_prop            = chxj_css_get_property_value(doc, style, "font-size");
6269       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type");
6270       css_property_t *cur;
6271       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
6272         if (cur->value && *cur->value) {
6273           attr_color = apr_pstrdup(doc->pool, cur->value);
6274         }
6275       }
6276       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
6277         if (cur->value && *cur->value) {
6278           attr_type = apr_pstrdup(doc->pool, cur->value);
6279         }
6280       }
6281       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
6282         if (cur->value && *cur->value) {
6283           if (STRCASEEQ('x','X',"xx-small",cur->value)) {
6284             attr_size = apr_pstrdup(doc->pool, cur->value);
6285           }
6286           else if (STRCASEEQ('x','X',"x-small",cur->value)) {
6287             attr_size = apr_pstrdup(doc->pool, cur->value);
6288           }
6289           else if (STRCASEEQ('s','S',"small",cur->value)) {
6290             attr_size = apr_pstrdup(doc->pool, cur->value);
6291           }
6292           else if (STRCASEEQ('m','M',"medium",cur->value)) {
6293             attr_size = apr_pstrdup(doc->pool, cur->value);
6294           }
6295           else if (STRCASEEQ('l','L',"large",cur->value)) {
6296             attr_size = apr_pstrdup(doc->pool, cur->value);
6297           }
6298           else if (STRCASEEQ('x','X',"x-large",cur->value)) {
6299             attr_size = apr_pstrdup(doc->pool, cur->value);
6300           }
6301           else if (STRCASEEQ('x','X',"xx-large",cur->value)) {
6302             attr_size = apr_pstrdup(doc->pool, cur->value);
6303           }
6304         }
6305       }
6306     }
6307   }
6308   W_L("<menu");
6309   if (attr_type || attr_color || attr_size) {
6310     W_L(" style=\"");
6311     if (attr_type) {
6312       W_L("list-style-type:");
6313       W_V(attr_type);
6314       W_L(";");
6315     }
6316     if (attr_color) {
6317       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
6318       W_L("color:");
6319       W_V(attr_color);
6320       W_L(";");
6321     }
6322     if (attr_size) {
6323       W_L("font-size:");
6324       W_V(attr_size);
6325       W_L(";");
6326     }
6327     W_L("\"");
6328   }
6329   W_L(">");
6330   return android->out;
6331 }
6332
6333
6334 /**
6335  * It is a handler who processes the MENU tag.
6336  *
6337  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6338  *                     destination is specified.
6339  * @param node   [i]   The MENU tag node is specified.
6340  * @return The conversion result is returned.
6341  */
6342 static char *
6343 s_android_end_menu_tag(void *pdoc, Node *UNUSED(child))
6344 {
6345   android_t *android = GET_ANDROID(pdoc);
6346   Doc *doc = android->doc;
6347   W_L("</menu>");
6348   if (IS_CSS_ON(android->entryp)) {
6349     chxj_css_pop_prop_list(android->css_prop_stack);
6350   }
6351   return android->out;
6352 }
6353
6354
6355 /**
6356  * It is a handler who processes the PLAINTEXT tag.
6357  *
6358  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6359  *                     destination is specified.
6360  * @param node   [i]   The PLAINTEXT tag node is specified.
6361  * @return The conversion result is returned.
6362  */
6363 static char *
6364 s_android_start_plaintext_tag(void *pdoc, Node *node)
6365 {
6366   android_t *android;
6367   Doc *doc;
6368
6369   android = GET_ANDROID(pdoc);
6370   doc     = android->doc;
6371   W_L("<plaintext>");
6372   s_android_start_plaintext_tag_inner(pdoc,node);
6373   return android->out;
6374 }
6375
6376 static char *
6377 s_android_start_plaintext_tag_inner(void *pdoc, Node *node)
6378 {
6379   android_t *android;
6380   Doc *doc;
6381   Node *child;
6382   android = GET_ANDROID(pdoc);
6383   doc     = android->doc;
6384   for (child = qs_get_child_node(doc, node);
6385        child;
6386        child = qs_get_next_node(doc, child)) {
6387     W_V(child->otext);
6388     s_android_start_plaintext_tag_inner(pdoc, child);
6389   }
6390   return android->out;
6391 }
6392
6393
6394 /**
6395  * It is a handler who processes the PLAINTEXT tag.
6396  *
6397  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6398  *                     destination is specified.
6399  * @param node   [i]   The PLAINTEXT tag node is specified.
6400  * @return The conversion result is returned.
6401  */
6402 static char *
6403 s_android_end_plaintext_tag(void *pdoc, Node *UNUSED(child))
6404 {
6405   android_t *android = GET_ANDROID(pdoc);
6406   return android->out;
6407 }
6408
6409
6410 /**
6411  * It is a handler who processes the BLINK tag.
6412  *
6413  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6414  *                     destination is specified.
6415  * @param node   [i]   The BLINK tag node is specified.
6416  * @return The conversion result is returned.
6417  */
6418 static char *
6419 s_android_start_blink_tag(void *pdoc, Node *node)
6420 {
6421   android_t *android      = GET_ANDROID(pdoc);
6422   Doc       *doc        = android->doc;
6423   Attr      *attr;
6424   char      *attr_style = NULL;
6425   char      *attr_color = NULL;
6426   char      *attr_size  = NULL;
6427   for (attr = qs_get_attr(doc,node);
6428        attr;
6429        attr = qs_get_next_attr(doc,attr)) {
6430     char *name   = qs_get_attr_name(doc,attr);
6431     char *value  = qs_get_attr_value(doc,attr);
6432     if (STRCASEEQ('s','S',"style", name) && value && *value) {
6433       attr_style = value;
6434     }
6435   }
6436   if (IS_CSS_ON(android->entryp)) {
6437     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
6438     if (style) {
6439       css_property_t *color_prop           = chxj_css_get_property_value(doc, style, "color");
6440       css_property_t *size_prop            = chxj_css_get_property_value(doc, style, "font-size");
6441       css_property_t *cur;
6442       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
6443         if (cur->value && *cur->value) {
6444           attr_color = apr_pstrdup(doc->pool, cur->value);
6445         }
6446       }
6447       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
6448         if (cur->value && *cur->value) {
6449           if (STRCASEEQ('x','X',"xx-small",cur->value)) {
6450             attr_size = apr_pstrdup(doc->pool, cur->value);
6451           }
6452           else if (STRCASEEQ('x','X',"x-small",cur->value)) {
6453             attr_size = apr_pstrdup(doc->pool, cur->value);
6454           }
6455           else if (STRCASEEQ('s','S',"small",cur->value)) {
6456             attr_size = apr_pstrdup(doc->pool, cur->value);
6457           }
6458           else if (STRCASEEQ('m','M',"medium",cur->value)) {
6459             attr_size = apr_pstrdup(doc->pool, cur->value);
6460           }
6461           else if (STRCASEEQ('l','L',"large",cur->value)) {
6462             attr_size = apr_pstrdup(doc->pool, cur->value);
6463           }
6464           else if (STRCASEEQ('x','X',"x-large",cur->value)) {
6465             attr_size = apr_pstrdup(doc->pool, cur->value);
6466           }
6467           else if (STRCASEEQ('x','X',"xx-large",cur->value)) {
6468             attr_size = apr_pstrdup(doc->pool, cur->value);
6469           }
6470         }
6471       }
6472     }
6473   }
6474
6475   W_L("<span");
6476   W_L(" style=\"");
6477   W_L(STYLE_BLINK);
6478   if (android->blink_keyframe_out == 0) {
6479     android->style_data = apr_pstrcat(doc->pool, (android->style_data) ? android->style_data : "",
6480                                                 BLINK_KEYFRAME,
6481                                                 NULL);
6482     android->blink_keyframe_out = 1;
6483   }
6484   if (attr_color) {
6485     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
6486     W_L("color:");
6487     W_V(attr_color);
6488     W_L(";");
6489   }
6490   if (attr_size) {
6491     W_L("font-size:");
6492     W_V(attr_size);
6493     W_L(";");
6494   }
6495   W_L("\"");
6496   W_L(">");
6497   
6498   return android->out;
6499 }
6500
6501
6502 /**
6503  * It is a handler who processes the BLINK tag.
6504  *
6505  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6506  *                     destination is specified.
6507  * @param node   [i]   The BLINK tag node is specified.
6508  * @return The conversion result is returned.
6509  */
6510 static char *
6511 s_android_end_blink_tag(void *pdoc, Node *UNUSED(child))
6512 {
6513   android_t *android = GET_ANDROID(pdoc);
6514   Doc      *doc = android->doc;
6515   W_L("</span>");
6516   if (IS_CSS_ON(android->entryp)) {
6517     chxj_css_pop_prop_list(android->css_prop_stack);
6518   }
6519   return android->out;
6520 }
6521
6522
6523 /**
6524  * It is a handler who processes the MARQUEE tag.
6525  *
6526  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6527  *                     destination is specified.
6528  * @param node   [i]   The MARQUEE tag node is specified.
6529  * @return The conversion result is returned.
6530  */
6531 static char *
6532 s_android_start_marquee_tag(void *pdoc, Node *node)
6533 {
6534   android_t *android = GET_ANDROID(pdoc);
6535   Doc       *doc = android->doc;
6536   Attr      *attr;
6537   char      *attr_style     = NULL;
6538   char      *attr_color     = NULL;
6539   char      *attr_size      = NULL;
6540   char      *attr_wap_marquee_loop  = NULL;
6541   char      *attr_wap_marquee_style = NULL;
6542   char      *attr_wap_marquee_dir   = NULL;
6543   char      *attr_wap_marquee_speed = NULL;
6544   char      *attr_bgcolor   = NULL;
6545   /*--------------------------------------------------------------------------*/
6546   /* Get Attributes                                                           */
6547   /*--------------------------------------------------------------------------*/
6548   for (attr = qs_get_attr(doc,node);
6549        attr;
6550        attr = qs_get_next_attr(doc,attr)) {
6551     char *name   = qs_get_attr_name(doc,attr);
6552     char *value  = qs_get_attr_value(doc,attr);
6553     if (STRCASEEQ('d','D',"direction", name)) {
6554       if (value) {
6555         if (STRCASEEQ('l','L',"left",value)) {
6556           attr_wap_marquee_dir = "rtl";
6557         }
6558         else if (STRCASEEQ('r','R',"right",value)) {
6559           attr_wap_marquee_dir = "ltr";
6560         }
6561       }
6562     }
6563     else if (STRCASEEQ('b','B',"behavior",name)) {
6564       if (value && *value) {
6565         attr_wap_marquee_style = value;
6566       }
6567     }
6568     else if (STRCASEEQ('l','L',"loop",name)) {
6569       if (value && *value) {
6570         if(strcmp(value,"0") == 0 || strcmp(value,"-1") == 0){
6571           attr_wap_marquee_loop = "infinite";
6572         }
6573         else{
6574           attr_wap_marquee_loop = value;
6575         }
6576       }
6577     }
6578     else if (STRCASEEQ('b','B',"bgcolor",name)) {
6579       if (value && *value) {
6580         attr_bgcolor = value;
6581       }
6582     }
6583     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
6584       attr_style = value;
6585     }
6586   }
6587   if (IS_CSS_ON(android->entryp)) {
6588     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
6589     if (style) {
6590       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
6591       css_property_t *size_prop  = chxj_css_get_property_value(doc, style, "font-size");
6592       css_property_t *bgcolor_prop  = chxj_css_get_property_value(doc, style, "background-color");
6593       css_property_t *wap_marquee_style_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-style");
6594       css_property_t *wap_marquee_dir_prop   = chxj_css_get_property_value(doc, style, "-wap-marquee-dir");
6595       css_property_t *wap_marquee_loop_prop  = chxj_css_get_property_value(doc, style, "-wap-marquee-loop");
6596       css_property_t *wap_marquee_speed_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-speed");
6597       css_property_t *cur;
6598       if (!attr_wap_marquee_style) {
6599         for (cur = wap_marquee_style_prop->next; cur != wap_marquee_style_prop; cur = cur->next) {
6600           if (STRCASEEQ('s','S',"scroll", cur->value) || STRCASEEQ('s','S',"slide",cur->value) || STRCASEEQ('a','A',"alternate",cur->value)) {
6601             attr_wap_marquee_style = apr_pstrdup(doc->pool, cur->value);
6602           }
6603         }
6604       }
6605       if (!attr_wap_marquee_dir) {
6606         for (cur = wap_marquee_dir_prop->next; cur != wap_marquee_dir_prop; cur = cur->next) {
6607           if (STRCASEEQ('l','L',"ltr",cur->value)) {
6608             attr_wap_marquee_dir = apr_pstrdup(doc->pool, cur->value);
6609           }
6610           else if (STRCASEEQ('r','R',"rtl",cur->value)) {
6611             attr_wap_marquee_dir = apr_pstrdup(doc->pool, cur->value);
6612           }
6613         }
6614       }
6615       if (!attr_wap_marquee_loop) {
6616         for (cur = wap_marquee_loop_prop->next; cur != wap_marquee_loop_prop; cur = cur->next) {
6617           if(strcmp(cur->value,"0") == 0 || strcmp(cur->value,"-1") == 0){
6618             attr_wap_marquee_loop = "infinite";
6619           }
6620           else{
6621             attr_wap_marquee_loop = apr_pstrdup(doc->pool, cur->value);
6622           }
6623         }
6624       }
6625       if (!attr_wap_marquee_speed) {
6626         for (cur = wap_marquee_speed_prop->next; cur != wap_marquee_speed_prop; cur = cur->next) {
6627           attr_wap_marquee_speed = apr_pstrdup(doc->pool, cur->value);
6628         }
6629       }
6630       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
6631         if (cur->value && *cur->value) {
6632           attr_color = apr_pstrdup(doc->pool, cur->value);
6633         }
6634       }
6635       for (cur = bgcolor_prop->next; cur != bgcolor_prop; cur = cur->next) {
6636         if (cur->value && *cur->value) {
6637           attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
6638         }
6639       }
6640       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
6641         if (cur->value && *cur->value) {
6642           if ( STRCASEEQ('x','X',"xx-small",cur->value)
6643             || STRCASEEQ('x','X',"x-small", cur->value)
6644             || STRCASEEQ('s','S',"small",   cur->value)
6645             || STRCASEEQ('m','M',"medium",  cur->value)
6646             || STRCASEEQ('l','L',"large",   cur->value)
6647             || STRCASEEQ('x','X',"x-large", cur->value)
6648             || STRCASEEQ('x','X',"xx-large",cur->value)) {
6649             attr_size = apr_pstrdup(doc->pool, cur->value);
6650           }
6651         }
6652       }
6653     }
6654   }
6655
6656   W_L("<div style=\"");
6657   W_L("overflow:-webkit-marquee;");
6658   if (attr_wap_marquee_dir) {
6659     W_L("-webkit-marquee-direction:");
6660     if (STRCASEEQ('r','R',"rtl",attr_wap_marquee_dir)) {
6661       W_L("left");
6662     }
6663     else if (STRCASEEQ('l','L',"ltr",attr_wap_marquee_dir)) {
6664       W_L("right");
6665     }
6666     W_L(";");
6667   }
6668   if (attr_wap_marquee_style) {
6669     W_L("-webkit-marquee-style:");
6670     W_V(attr_wap_marquee_style);
6671     W_L(";");
6672   }
6673   if (attr_wap_marquee_loop) {
6674     W_L("-webkit-marquee-repetition:");
6675     W_V(attr_wap_marquee_loop);
6676     W_L(";");
6677   }
6678   if (attr_wap_marquee_speed) {
6679     W_L("-webkit-marquee-speed:");
6680     W_V(attr_wap_marquee_speed);
6681     W_L(";");
6682   }
6683   if (attr_bgcolor) {
6684     attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
6685     W_L("background-color:");
6686     W_V(attr_bgcolor);
6687     W_L(";");
6688   }
6689   if (attr_color) {
6690     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
6691     W_L("color:");
6692     W_V(attr_color);
6693     W_L(";");
6694   }
6695   if (attr_size) {
6696     W_L("font-size:");
6697     W_V(attr_size);
6698     W_L(";");
6699   }
6700   W_L("\"");
6701   W_L(">");
6702
6703   return android->out;
6704 }
6705
6706
6707 /**
6708  * It is a handler who processes the MARQUEE tag.
6709  *
6710  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6711  *                     destination is specified.
6712  * @param node   [i]   The MARQUEE tag node is specified.
6713  * @return The conversion result is returned.
6714  */
6715 static char *
6716 s_android_end_marquee_tag(void *pdoc, Node *UNUSED(node))
6717 {
6718   android_t *android = GET_ANDROID(pdoc);
6719   Doc      *doc     = android->doc;
6720   W_L("</div>");
6721   if (IS_CSS_ON(android->entryp)) {
6722     chxj_css_pop_prop_list(android->css_prop_stack);
6723   }
6724   return android->out;
6725 }
6726
6727
6728 /**
6729  * It is handler who processes the New Line Code.
6730  */
6731 static char *
6732 s_android_newline_mark(void *pdoc, Node *UNUSED(node))
6733 {
6734   android_t *android = GET_ANDROID(pdoc);
6735   if (android->start_html_flag) {
6736     Doc *doc = android->doc;
6737     W_NLCODE();
6738   }
6739   return android->out;
6740 }
6741
6742
6743 /**
6744  * It is a handler who processes the LINK tag.
6745  *
6746  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
6747  *                     destination is specified.
6748  * @param node   [i]   The LINK tag node is specified.
6749  * @return The conversion result is returned.
6750  */
6751 static char *
6752 s_android_link_tag(void *pdoc, Node *node)
6753 {
6754   android_t      *android;
6755   Doc           *doc;
6756   Attr          *attr;
6757   char          *rel  = NULL;
6758   char          *href = NULL;
6759   char          *type = NULL;
6760
6761   android = GET_ANDROID(pdoc);
6762   doc    = android->doc;
6763
6764   if (! IS_CSS_ON(android->entryp)) {
6765     return android->out;
6766   }
6767
6768   for (attr = qs_get_attr(doc,node);
6769        attr;
6770        attr = qs_get_next_attr(doc,attr)) {
6771     char *name  = qs_get_attr_name(doc,attr);
6772     char *value = qs_get_attr_value(doc,attr);
6773     if (STRCASEEQ('r','R',"rel", name)) {
6774       if (value && *value && STRCASEEQ('s','S',"stylesheet", value)) {
6775         rel = value;
6776       }
6777     }
6778     else if (STRCASEEQ('h','H',"href", name)) {
6779       if (value && *value) {
6780         href = value;
6781       }
6782     }
6783     else if (STRCASEEQ('t','T',"type", name)) {
6784       if (value && *value && STRCASEEQ('t','T',"text/css",value)) {
6785         type = value;
6786       }
6787     }
6788   }
6789
6790   if (rel && href && type) {
6791     DBG(doc->r,"REQ[%X] start load CSS. url:[%s]", TO_ADDR(doc->r),href);
6792     android->style = chxj_css_parse_from_uri(doc->r, doc->pool, android->style, href);
6793     DBG(doc->r,"REQ[%X] end load CSS. url:[%s]", TO_ADDR(doc->r),href);
6794   }
6795
6796   return android->out;
6797 }
6798
6799
6800 static css_prop_list_t *
6801 s_android_push_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value)
6802 {
6803   android_t *android = GET_ANDROID(pdoc);
6804   Doc *doc = android->doc;
6805   css_prop_list_t *last_css = NULL;
6806   if (IS_CSS_ON(android->entryp)) {
6807     css_prop_list_t *dup_css;
6808     css_selector_t  *selector;
6809
6810     last_css = chxj_css_get_last_prop_list(android->css_prop_stack);
6811     dup_css  = chxj_dup_css_prop_list(doc, last_css);
6812     selector = chxj_css_find_selector(doc, android->style, node);
6813     if (selector) {
6814       chxj_css_prop_list_merge_property(doc, dup_css, selector);
6815     }
6816     chxj_css_push_prop_list(android->css_prop_stack, dup_css);
6817     last_css = chxj_css_get_last_prop_list(android->css_prop_stack);
6818
6819     if (style_attr_value) {
6820       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));
6821       if (ssheet) {
6822         chxj_css_prop_list_merge_property(doc, last_css, ssheet->selector_head.next);
6823       }
6824     }
6825   }
6826   return last_css;
6827 }
6828
6829
6830 static css_prop_list_t *
6831 s_android_nopush_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value)
6832 {
6833   android_t *android = GET_ANDROID(pdoc);
6834   Doc *doc = android->doc;
6835   css_prop_list_t *last_css = NULL;
6836   if (IS_CSS_ON(android->entryp)) {
6837     css_prop_list_t *dup_css;
6838     css_selector_t  *selector;
6839
6840     last_css = chxj_css_get_last_prop_list(android->css_prop_stack);
6841     dup_css  = chxj_dup_css_prop_list(doc, last_css);
6842     selector = chxj_css_find_selector(doc, android->style, node);
6843     if (selector) {
6844       chxj_css_prop_list_merge_property(doc, dup_css, selector);
6845     }
6846     last_css = dup_css;
6847
6848     if (style_attr_value) {
6849       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));
6850       if (ssheet) {
6851         chxj_css_prop_list_merge_property(doc, last_css, ssheet->selector_head.next);
6852       }
6853     }
6854   }
6855   return last_css;
6856 }
6857
6858
6859 /**
6860  * It is a handler who processes the SPAN tag.
6861  *
6862  * @param pdoc  [i/o] The pointer to the JHTML structure at the output
6863  *                     destination is specified.
6864  * @param node   [i]   The SPAN tag node is specified.
6865  * @return The conversion result is returned.
6866  */
6867 static char *
6868 s_android_start_span_tag(void *pdoc, Node *node)
6869 {
6870   android_t *android;
6871   Doc *doc;
6872   Attr *attr;
6873   char *attr_style = NULL;
6874   char *attr_color = NULL;
6875   char *attr_size = NULL;
6876   char *attr_align = NULL;
6877   char *attr_blink = NULL;
6878   char *attr_marquee = NULL;
6879   char *attr_marquee_dir = NULL;
6880   char *attr_marquee_style = NULL;
6881   char *attr_marquee_loop = NULL;
6882   char *attr_marquee_speed = NULL;
6883   char *css_bgcolor        = NULL;
6884
6885   android = GET_ANDROID(pdoc);
6886   doc     = android->doc;
6887
6888   for (attr = qs_get_attr(doc,node);
6889        attr;
6890        attr = qs_get_next_attr(doc,attr)) {
6891     char *nm  = qs_get_attr_name(doc,attr);
6892     char *val = qs_get_attr_value(doc,attr);
6893     if (val && STRCASEEQ('s','S',"style", nm)) {
6894       attr_style = val;
6895     }
6896   }
6897   if (IS_CSS_ON(android->entryp)) {
6898     css_prop_list_t *style = s_android_nopush_and_get_now_style(pdoc, node, attr_style);
6899     if (style) {
6900       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
6901       css_property_t *size_prop = chxj_css_get_property_value(doc, style, "font-size");
6902       css_property_t *text_align_prop = chxj_css_get_property_value(doc, style, "text-align");
6903       css_property_t *decoration_prop = chxj_css_get_property_value(doc, style, "text-decoration");
6904       css_property_t *display_prop = chxj_css_get_property_value(doc, style, "display");
6905       css_property_t *marquee_dir_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-dir");
6906       css_property_t *marquee_style_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-style");
6907       css_property_t *marquee_loop_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-loop");
6908       css_property_t *marquee_speed_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-speed");
6909       css_property_t *bgcolor_prop = chxj_css_get_property_value(doc, style, "background-color");
6910       
6911       css_property_t *cur;
6912       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
6913         attr_color = apr_pstrdup(doc->pool, cur->value);
6914       }
6915       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
6916         if (cur->value && *cur->value) {
6917           if ( STRCASEEQ('x','X',"xx-small",cur->value)
6918             || STRCASEEQ('x','X',"x-small", cur->value)
6919             || STRCASEEQ('s','S',"small",   cur->value)
6920             || STRCASEEQ('m','M',"medium",  cur->value)
6921             || STRCASEEQ('l','L',"large",   cur->value)
6922             || STRCASEEQ('x','X',"x-large", cur->value)
6923             || STRCASEEQ('x','X',"xx-large",cur->value)) {
6924             attr_size = apr_pstrdup(doc->pool, cur->value);
6925           }
6926         }
6927       }
6928       for (cur = decoration_prop->next; cur != decoration_prop; cur = cur->next) {
6929         if (cur->value && STRCASEEQ('b','B',"blink",cur->value)) {
6930           attr_blink = apr_pstrdup(doc->pool, cur->value);
6931         }
6932       }
6933       for (cur = display_prop->next; cur != display_prop; cur = cur->next) {
6934         if (cur->value && strcasecmp("-wap-marquee",cur->value) == 0) {
6935           attr_marquee = apr_pstrdup(doc->pool, cur->value);
6936         }
6937       }
6938       for (cur = marquee_dir_prop->next; cur != marquee_dir_prop; cur = cur->next) {
6939         if (cur->value && *cur->value) {
6940           if ( STRCASEEQ('l','L',"ltr",cur->value)
6941             || STRCASEEQ('r','R',"rtl",cur->value)) {
6942             attr_marquee_dir = apr_pstrdup(doc->pool, cur->value);
6943           }
6944         }
6945       }
6946       for (cur = marquee_style_prop->next; cur != marquee_style_prop; cur = cur->next) {
6947         if (cur->value && *cur->value) {
6948           if ( STRCASEEQ('s','S',"scroll",cur->value)
6949             || STRCASEEQ('s','S',"slide",cur->value)
6950             || STRCASEEQ('a','A',"alternate",cur->value)) {
6951             attr_marquee_style = apr_pstrdup(doc->pool, cur->value);
6952           }
6953         }
6954       }
6955       for (cur = marquee_loop_prop->next; cur != marquee_loop_prop; cur = cur->next) {
6956         if (cur->value && *cur->value) {
6957           if(strcmp(cur->value,"0") == 0 || strcmp(cur->value,"-1") == 0){
6958             attr_marquee_loop = "infinite";
6959           }
6960           else{
6961             attr_marquee_loop = apr_pstrdup(doc->pool, cur->value);
6962           }
6963         }
6964       }
6965       for (cur = marquee_speed_prop->next; cur != marquee_speed_prop; cur = cur->next) {
6966         if (cur->value && *cur->value) {
6967           attr_marquee_speed = apr_pstrdup(doc->pool, cur->value);
6968         }
6969       }
6970       for (cur = text_align_prop->next; cur != text_align_prop; cur = cur->next) {
6971         if (STRCASEEQ('l','L',"left", cur->value)) {
6972           attr_align = apr_pstrdup(doc->pool, "left");
6973         }
6974         else if (STRCASEEQ('c','C',"center",cur->value)) {
6975           attr_align = apr_pstrdup(doc->pool, "center");
6976         }
6977         else if (STRCASEEQ('r','R',"right",cur->value)) {
6978           attr_align = apr_pstrdup(doc->pool, "right");
6979         }
6980       }
6981       for (cur = bgcolor_prop->next; cur != bgcolor_prop; cur = cur->next) {
6982         if (cur->value && *cur->value) {
6983           css_bgcolor = apr_pstrdup(doc->pool, cur->value);
6984         }
6985       }
6986     }
6987   }
6988
6989   W_L("<div");
6990   if (attr_marquee) {
6991     W_L(" style=\"");
6992     W_L("overflow:-webkit-marquee;");
6993     if (attr_marquee_style) {
6994       W_L("-webkit-marquee-style:");
6995       W_V(attr_marquee_style);
6996       W_L(";");
6997     }
6998     if (attr_marquee_dir) {
6999       W_L("-webkit-marquee-direction:");
7000       if (STRCASEEQ('r','R',"rtl",attr_marquee_dir)) {
7001         W_L("left");
7002       }
7003       else if (STRCASEEQ('l','L',"ltr",attr_marquee_dir)) {
7004         W_L("right");
7005       }
7006       W_L(";");
7007     }
7008     if (attr_marquee_loop) {
7009       W_L("-webkit-marquee-repetition:");
7010       W_V(attr_marquee_loop);
7011       W_L(";");
7012     }
7013     if (attr_marquee_speed) {
7014       W_L("-webkit-marquee-speed:");
7015       W_V(attr_marquee_speed);
7016       W_L(";");
7017     }
7018     W_L("\"");
7019   }
7020   W_L(">");
7021   W_L("<span");
7022   if (attr_color || attr_size || attr_align || attr_blink || attr_marquee || css_bgcolor) {
7023     W_L(" style=\"");
7024     if (attr_color) {
7025       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
7026       W_L("color:");
7027       W_V(attr_color);
7028       W_L(";");
7029     }
7030     if (attr_size) {
7031       W_L("font-size:");
7032       W_V(attr_size);
7033       W_L(";");
7034     }
7035     if (attr_align) {
7036       W_L("text-align:");
7037       W_V(attr_align);
7038       W_L(";");
7039     }
7040     if (attr_blink) {
7041       W_L(STYLE_BLINK);
7042       if (android->blink_keyframe_out == 0) {
7043         android->style_data = apr_pstrcat(doc->pool, (android->style_data) ? android->style_data : "",
7044                                                     BLINK_KEYFRAME,
7045                                                     NULL);
7046         android->blink_keyframe_out = 1;
7047       }
7048     }
7049     if(css_bgcolor){
7050       W_L("background-color:");
7051       W_V(css_bgcolor);
7052       W_L(";");
7053     }
7054     W_L("\"");
7055   }
7056   W_L(">");
7057   return android->out;
7058 }
7059
7060
7061 /**
7062  * It is a handler who processes the SPAN tag.
7063  *
7064  * @param pdoc  [i/o] The pointer to the JHTML structure at the output
7065  *                     destination is specified.
7066  * @param node   [i]   The SPAN tag node is specified.
7067  * @return The conversion result is returned.
7068  */
7069 static char *
7070 s_android_end_span_tag(void *pdoc, Node *UNUSED(node))
7071 {
7072   android_t *android = GET_ANDROID(pdoc);
7073   Doc *doc = android->doc;
7074
7075   W_L("</span>");
7076   W_L("</div>");
7077   if (IS_CSS_ON(android->entryp)) {
7078     chxj_css_pop_prop_list(android->css_prop_stack);
7079   }
7080   return android->out;
7081 }
7082
7083
7084 /**
7085  * It is a handler who processes the STYLE tag.
7086  *
7087  * @param pdoc  [i/o] The pointer to the XHTML structure at the output
7088  *                     destination is specified.
7089  * @param node   [i]   The STYLE tag node is specified.
7090  * @return The conversion result is returned.
7091  */
7092 static char *
7093 s_android_style_tag(void *pdoc, Node *node)
7094 {
7095   android_t     *android;
7096   Doc           *doc;
7097   Attr          *attr;
7098   char          *type = NULL;
7099   Node          *child   = NULL;
7100   char          *style;
7101
7102   android = GET_ANDROID(pdoc);
7103   doc     = android->doc;
7104
7105   if (! IS_CSS_ON(android->entryp)) {
7106     return android->out;
7107   }
7108
7109   for (attr = qs_get_attr(doc,node);
7110        attr;
7111        attr = qs_get_next_attr(doc,attr)) {
7112     char *name  = qs_get_attr_name(doc,attr);
7113     char *value = qs_get_attr_value(doc,attr);
7114     if (STRCASEEQ('t','T',"type", name)) {
7115       if (value && *value && STRCASEEQ('t','T',"text/css",value)) {
7116         type = value;
7117       }
7118     }
7119   }
7120   if (type) {
7121     style = "";
7122     for (child = qs_get_child_node(doc, node);
7123          child;
7124          child = qs_get_next_node(doc, child)) {
7125       char *name = qs_get_node_name(doc, child);
7126       if (STRCASEEQ('t','T',"text", name)) {
7127         char *value = qs_get_node_value(doc, child);
7128         if (value && *value) {
7129           style = apr_pstrcat(doc->r->pool, style, value, NULL);
7130         }
7131       }
7132     }
7133     if (strlen(style) > 0) {
7134       DBG(doc->r,"REQ[%X] start load CSS. buf:[%s]", TO_ADDR(doc->r),style);
7135       android->style = chxj_css_parse_style_value(doc, android->style, style);
7136       DBG(doc->r,"REQ[%X] end load CSS. value:[%s]", TO_ADDR(doc->r),style);
7137     }
7138   }
7139   return android->out;
7140 }
7141
7142
7143 static char *
7144 s_android_create_style_data(apr_pool_t *pool, const char *style_data)
7145 {
7146   if (! style_data) {
7147     return "";
7148   }
7149   return apr_pstrcat(pool, "<style type=\"text/css\"><![CDATA[",style_data, "]]></style>", NULL);
7150 }
7151
7152 /**
7153  * It is a handler who processes the OBJECT tag.
7154  *
7155  * @param pdoc  [i/o] The pointer to the JHTML structure at the output
7156  *                     destination is specified.
7157  * @param node   [i]   The OBJECT tag node is specified.
7158  * @return The conversion result is returned.
7159  */
7160 static char *
7161 s_android_start_object_tag(void *pdoc, Node *node)
7162 {
7163   android_t *android = GET_ANDROID(pdoc);
7164   Doc *doc = android->doc;
7165   Attr *attr;
7166   
7167   char *attr_id            = NULL;
7168   char *attr_width         = NULL;
7169   char *attr_height        = NULL;
7170   char *attr_data          = NULL;
7171   char *attr_type          = NULL;
7172   char *attr_declare       = NULL;
7173   char *attr_classid       = NULL;
7174   char *attr_codebase      = NULL;
7175   
7176   /*--------------------------------------------------------------------------*/
7177   /* Get Attributes                                                           */
7178   /*--------------------------------------------------------------------------*/
7179   for (attr = qs_get_attr(doc,node);
7180        attr;
7181        attr = qs_get_next_attr(doc,attr)) {
7182     char *name   = qs_get_attr_name(doc,attr);
7183     char *value  = qs_get_attr_value(doc,attr);
7184     if (STRCASEEQ('i','I',"id",name)) {
7185       attr_id = apr_pstrdup(doc->pool, value);
7186     }
7187     else if (STRCASEEQ('w','W',"width",name)) {
7188       attr_width = apr_pstrdup(doc->pool, value);
7189     }
7190     else if (STRCASEEQ('h','H',"height",name)) {
7191       attr_height = apr_pstrdup(doc->pool, value);
7192     }
7193     else if (STRCASEEQ('d','D',"data",name)) {
7194       attr_data = apr_pstrdup(doc->pool, value);
7195     }
7196     else if  (STRCASEEQ('t','T',"type",name)) {
7197       attr_type = apr_pstrdup(doc->pool, value);
7198     }
7199     else if  (STRCASEEQ('d','D',"declare",name)) {
7200       attr_declare = apr_pstrdup(doc->pool, value);
7201     }
7202     else if (STRCASEEQ('c','C',"classid",name)) {
7203       attr_classid = apr_pstrdup(doc->pool, value);
7204     }
7205     else if (STRCASEEQ('c','C',"codebase",name)) {
7206       attr_codebase = apr_pstrdup(doc->pool, value);
7207     }
7208     
7209   }
7210   W_L("<object");
7211   
7212   if(attr_id){
7213     W_L(" id=\"");
7214     W_V(attr_id);
7215     W_L("\"");
7216   }
7217   if(attr_width){
7218     W_L(" width=\"");
7219     W_V(attr_width);
7220     W_L("\"");
7221   }
7222   if(attr_height){
7223     W_L(" height=\"");
7224     W_V(attr_height);
7225     W_L("\"");
7226   }
7227   if(attr_data){
7228     W_L(" data=\"");
7229     W_V(attr_data);
7230     W_L("\"");
7231   }
7232   if(attr_type){
7233     W_L(" type=\"");
7234     W_V(attr_type);
7235     W_L("\"");
7236   }
7237   if(attr_declare){
7238     W_L(" declare=\"declare\"");
7239   }
7240   if(attr_classid){
7241     W_L(" classid=\"");
7242     W_V(attr_classid);
7243     W_L("\"");
7244   }
7245   if(attr_codebase){
7246     W_L(" codebase=\"");
7247     W_V(attr_codebase);
7248     W_L("\"");
7249   }
7250   
7251   W_L(">");
7252   return android->out;
7253 }
7254 /**
7255  * It is a handler who processes the OBJECT tag.
7256  *
7257  * @param pdoc  [i/o] The pointer to the JHTML structure at the output
7258  *                     destination is specified.
7259  * @param node   [i]   The OBJECT tag node is specified.
7260  * @return The conversion result is returned.
7261  */
7262 static char *
7263 s_android_end_object_tag(void *pdoc, Node *UNUSED(node))
7264 {
7265   android_t *android = GET_ANDROID(pdoc);
7266   Doc *doc = android->doc;
7267
7268   W_L("</object>");
7269   return android->out;
7270 }
7271 /**
7272  * It is a handler who processes the OBJECT tag.
7273  *
7274  * @param pdoc  [i/o] The pointer to the JHTML structure at the output
7275  *                     destination is specified.
7276  * @param node   [i]   The OBJECT tag node is specified.
7277  * @return The conversion result is returned.
7278  */
7279 static char *
7280 s_android_start_param_tag(void *pdoc, Node *node)
7281 {
7282   android_t *android = GET_ANDROID(pdoc);
7283   Doc *doc = android->doc;
7284
7285   Attr *attr;
7286   char *attr_name          = NULL;
7287   char *attr_value         = NULL;
7288   char *attr_valuetype     = NULL;
7289   
7290   /*--------------------------------------------------------------------------*/
7291   /* Get Attributes                                                           */
7292   /*--------------------------------------------------------------------------*/
7293   for (attr = qs_get_attr(doc,node);
7294        attr;
7295        attr = qs_get_next_attr(doc,attr)) {
7296     char *name   = qs_get_attr_name(doc,attr);
7297     char *value  = qs_get_attr_value(doc,attr);
7298     if (STRCASEEQ('n','N',"name",name)) {
7299       attr_name = apr_pstrdup(doc->pool, value);
7300     }
7301     else if (STRCASEEQ('v','V',"value",name)) {
7302       attr_value = apr_pstrdup(doc->pool, value);
7303     }
7304     else if (STRCASEEQ('v','V',"valuetype",name)) {
7305       attr_valuetype = apr_pstrdup(doc->pool, value);
7306     }
7307   }
7308   W_L("<param");
7309   
7310   if(attr_name){
7311     W_L(" name=\"");
7312     W_V(attr_name);
7313     W_L("\"");
7314   }
7315   if(attr_value){
7316     W_L(" value=\"");
7317     W_V(attr_value);
7318     W_L("\"");
7319   }
7320   if(attr_valuetype){
7321     W_L(" valuetype=\"");
7322     W_V(attr_valuetype);
7323     W_L("\"");
7324   }
7325   W_L(" />");
7326   return android->out;
7327 }
7328 /**
7329  * It is a handler who processes the CAPTION tag.
7330  *
7331  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
7332  *                     destination is specified.
7333  * @param node   [i]   The CAPTION tag node is specified.
7334  * @return The conversion result is returned.
7335  */
7336 static char *
7337 s_android_start_caption_tag(void *pdoc, Node *node)
7338 {
7339   android_t    *android;
7340   Doc         *doc;
7341   request_rec *r;
7342   Attr        *attr;
7343   char        *attr_style = NULL;
7344   char        *attr_align = NULL;
7345
7346   android = GET_ANDROID(pdoc);
7347   doc    = android->doc;
7348   r      = doc->r;
7349
7350   for (attr = qs_get_attr(doc,node);
7351        attr;
7352        attr = qs_get_next_attr(doc,attr)) {
7353     char *name  = qs_get_attr_name(doc,attr);
7354     char *value = qs_get_attr_value(doc,attr);
7355     if (STRCASEEQ('a','A',"align", name)) {
7356       if (value && 
7357           (STRCASEEQ('l','L',"left",value) 
7358         || STRCASEEQ('r','R',"right",value) 
7359         || STRCASEEQ('t','T',"top",value)
7360         || STRCASEEQ('b','B',"bottom",value) 
7361         )) {
7362         attr_align = value;
7363       }
7364     }
7365     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
7366       attr_style = value;
7367     }
7368   }
7369   
7370   W_L("<caption");
7371   if(attr_align){
7372     W_L(" align=\"");
7373     W_V(attr_align);
7374     W_L("\"");
7375   }
7376   W_L(">");
7377
7378   return android->out;
7379 }
7380
7381
7382 /**
7383  * It is a handler who processes the CAPTION tag.
7384  *
7385  * @param pdoc  [i/o] The pointer to the ANDROID structure at the output
7386  *                     destination is specified.
7387  * @param node   [i]   The CAPTION tag node is specified.
7388  * @return The conversion result is returned.
7389  */
7390 static char *
7391 s_android_end_caption_tag(void *pdoc, Node *UNUSED(child)) 
7392 {
7393   android_t*    android = GET_ANDROID(pdoc);
7394   Doc*          doc     = android->doc;
7395   
7396   W_L("</caption>");
7397   
7398   return android->out;
7399 }
7400
7401
7402 /*
7403  * vim:ts=2 et
7404  */