OSDN Git Service

* updated ChangeLog
[modchxj/mod_chxj.git] / src / chxj_chtml30.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 <apr_time.h>
18 #include "chxj_chtml30.h"
19 #include "chxj_hdml.h"
20 #include "chxj_str_util.h"
21 #include "chxj_dump.h"
22 #include "chxj_img_conv.h"
23 #include "chxj_qr_code.h"
24 #include "chxj_encoding.h"
25 #include "chxj_header_inf.h"
26 #include "chxj_conv_z2h.h"
27 #include "chxj_google.h"
28
29 #define GET_CHTML30(X) ((chtml30_t *)(X))
30 #undef W_L
31 #undef W_V
32 #define W_L(X)          do { chtml30->out = BUFFERED_WRITE_LITERAL(chtml30->out, &doc->buf, (X)); } while(0)
33 #define W_V(X)          do { chtml30->out = (X) ? BUFFERED_WRITE_VALUE(chtml30->out, &doc->buf, (X))  \
34                                                 : BUFFERED_WRITE_LITERAL(chtml30->out, &doc->buf, ""); } while(0)
35 #undef W_NLCODE
36 #define W_NLCODE()     do { char *nlcode = TO_NLCODE(chtml30->conf); W_V(nlcode); } while (0)
37
38
39
40 #define CHTML30_START_OF_TAG_WITH_CSS_FONT_COLOR(tagname) \
41   do { \
42     chtml30_t *chtml30; \
43     Doc       *doc; \
44     Attr      *attr; \
45     char      *attr_style = NULL; \
46     char      *attr_color = NULL; \
47    \
48     chtml30 = GET_CHTML30(pdoc); \
49     doc     = chtml30->doc; \
50     for (attr = qs_get_attr(doc,node); \
51          attr; \
52          attr = qs_get_next_attr(doc,attr)) { \
53       char *nm  = qs_get_attr_name(doc,attr); \
54       char *val = qs_get_attr_value(doc,attr); \
55       if (val && STRCASEEQ('s','S',"style", nm)) { \
56         attr_style = val; \
57       } \
58     } \
59     if (IS_CSS_ON(chtml30->entryp)) { \
60       css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style); \
61       if (style) { \
62         css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color"); \
63         css_property_t *cur; \
64         for (cur = color_prop->next; cur != color_prop; cur = cur->next) { \
65           if (cur->value && *cur->value) { \
66             attr_color = apr_pstrdup(doc->pool, cur->value); \
67           } \
68         } \
69       } \
70     } \
71     W_L(tagname); \
72     chtml30_flags_t *flg = (chtml30_flags_t *)apr_palloc(doc->pool, sizeof(chtml30_flags_t)); \
73     memset(flg, 0, sizeof(*flg)); \
74     if (attr_color) { \
75       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color); \
76       W_L("<font color=\""); \
77       W_V(attr_color); \
78       W_L("\">"); \
79       flg->with_font_flag = 1; \
80     } \
81     node->userData = (void *)flg; \
82     return chtml30->out; \
83   } while(0) \
84
85 #define CHTML30_END_OF_NO_CLOSE_TAG_WITH_FONT_TAG() \
86   do {                                                        \
87     chtml30_t *chtml30 = GET_CHTML30(pdoc);                   \
88     Doc       *doc     = chtml30->doc;                        \
89     chtml30_flags_t *flg = (chtml30_flags_t *)node->userData; \
90     if (flg && flg->with_font_flag) {                         \
91       W_L("</font>");                                         \
92     }                                                         \
93     if (IS_CSS_ON(chtml30->entryp)) {                         \
94       chxj_css_pop_prop_list(chtml30->css_prop_stack);        \
95     }                                                         \
96     return chtml30->out;                                      \
97   } while(0)
98
99 #define CHTML30_END_OF_CLOSE_TAG_WITH_FONT_TAG(tagname) \
100   do {                                                        \
101     chtml30_t *chtml30 = GET_CHTML30(pdoc);                   \
102     Doc       *doc     = chtml30->doc;                        \
103     chtml30_flags_t *flg = (chtml30_flags_t *)node->userData; \
104     if (flg && flg->with_font_flag) {                         \
105       W_L("</font>");                                         \
106     }                                                         \
107     W_L(tagname);                                             \
108     if (IS_CSS_ON(chtml30->entryp)) {                         \
109       chxj_css_pop_prop_list(chtml30->css_prop_stack);        \
110     }                                                         \
111     return chtml30->out;                                      \
112   } while(0)
113
114
115 static char *s_chtml30_start_html_tag     (void *pdoc, Node *node);
116 static char *s_chtml30_end_html_tag       (void *pdoc, Node *node);
117 static char *s_chtml30_start_meta_tag     (void *pdoc, Node *node);
118 static char *s_chtml30_end_meta_tag       (void *pdoc, Node *node);
119 static char *s_chtml30_start_textarea_tag (void *pdoc, Node *node);
120 static char *s_chtml30_end_textarea_tag   (void *pdoc, Node *node);
121 static char *s_chtml30_start_p_tag        (void *pdoc, Node *node);
122 static char *s_chtml30_end_p_tag          (void *pdoc, Node *node);
123 static char *s_chtml30_start_pre_tag      (void *pdoc, Node *node);
124 static char *s_chtml30_end_pre_tag        (void *pdoc, Node *node);
125 static char *s_chtml30_start_h1_tag       (void *pdoc, Node *node);
126 static char *s_chtml30_end_h1_tag         (void *pdoc, Node *node);
127 static char *s_chtml30_start_h2_tag       (void *pdoc, Node *node);
128 static char *s_chtml30_end_h2_tag         (void *pdoc, Node *node);
129 static char *s_chtml30_start_h3_tag       (void *pdoc, Node *node);
130 static char *s_chtml30_end_h3_tag         (void *pdoc, Node *node);
131 static char *s_chtml30_start_h4_tag       (void *pdoc, Node *node);
132 static char *s_chtml30_end_h4_tag         (void *pdoc, Node *node);
133 static char *s_chtml30_start_h5_tag       (void *pdoc, Node *node);
134 static char *s_chtml30_end_h5_tag         (void *pdoc, Node *node);
135 static char *s_chtml30_start_h6_tag       (void *pdoc, Node *node);
136 static char *s_chtml30_end_h6_tag         (void *pdoc, Node *node);
137 static char *s_chtml30_start_ul_tag       (void *pdoc, Node *node);
138 static char *s_chtml30_end_ul_tag         (void *pdoc, Node *node);
139 static char *s_chtml30_start_ol_tag       (void *pdoc, Node *node);
140 static char *s_chtml30_end_ol_tag         (void *pdoc, Node *node);
141 static char *s_chtml30_start_li_tag       (void *pdoc, Node *node);
142 static char *s_chtml30_end_li_tag         (void *pdoc, Node *node);
143 static char *s_chtml30_start_head_tag     (void *pdoc, Node *node);
144 static char *s_chtml30_end_head_tag       (void *pdoc, Node *node);
145 static char *s_chtml30_start_title_tag    (void *pdoc, Node *node);
146 static char *s_chtml30_end_title_tag      (void *pdoc, Node *node);
147 static char *s_chtml30_start_base_tag     (void *pdoc, Node *node);
148 static char *s_chtml30_end_base_tag       (void *pdoc, Node *node);
149 static char *s_chtml30_start_body_tag     (void *pdoc, Node *node);
150 static char *s_chtml30_end_body_tag       (void *pdoc, Node *node);
151 static char *s_chtml30_start_a_tag        (void *pdoc, Node *node);
152 static char *s_chtml30_end_a_tag          (void *pdoc, Node *node);
153 static char *s_chtml30_start_br_tag       (void *pdoc, Node *node);
154 static char *s_chtml30_end_br_tag         (void *pdoc, Node *node);
155 static char *s_chtml30_start_tr_tag       (void *pdoc, Node *node);
156 static char *s_chtml30_end_tr_tag         (void *pdoc, Node *node);
157 static char *s_chtml30_start_font_tag     (void *pdoc, Node *node);
158 static char *s_chtml30_end_font_tag       (void *pdoc, Node *node);
159 static char *s_chtml30_start_form_tag     (void *pdoc, Node *node);
160 static char *s_chtml30_end_form_tag       (void *pdoc, Node *node);
161 static char *s_chtml30_start_input_tag    (void *pdoc, Node *node);
162 static char *s_chtml30_end_input_tag      (void *pdoc, Node *node);
163 static char *s_chtml30_start_center_tag   (void *pdoc, Node *node);
164 static char *s_chtml30_end_center_tag     (void *pdoc, Node *node);
165 static char *s_chtml30_start_hr_tag       (void *pdoc, Node *node);
166 static char *s_chtml30_end_hr_tag         (void *pdoc, Node *node);
167 static char *s_chtml30_start_img_tag      (void *pdoc, Node *node);
168 static char *s_chtml30_end_img_tag        (void *pdoc, Node *node);
169 static char *s_chtml30_start_select_tag   (void *pdoc, Node *node);
170 static char *s_chtml30_end_select_tag     (void *pdoc, Node *node);
171 static char *s_chtml30_start_option_tag   (void *pdoc, Node *node);
172 static char *s_chtml30_end_option_tag     (void *pdoc, Node *node);
173 static char *s_chtml30_start_div_tag      (void *pdoc, Node *node);
174 static char *s_chtml30_end_div_tag        (void *pdoc, Node *node);
175 static char *s_chtml30_chxjif_tag         (void *pdoc, Node *node); 
176 static char *s_chtml30_text_tag           (void *pdoc, Node *node);
177 static char *s_chtml30_start_blockquote_tag (void *pdoc, Node *node);
178 static char *s_chtml30_end_blockquote_tag  (void *pdoc, Node *node);
179 static char *s_chtml30_start_dir_tag      (void *pdoc, Node *node);
180 static char *s_chtml30_end_dir_tag        (void *pdoc, Node *node);
181 static char *s_chtml30_start_dl_tag       (void *pdoc, Node *node);
182 static char *s_chtml30_end_dl_tag         (void *pdoc, Node *node);
183 static char *s_chtml30_start_dt_tag       (void *pdoc, Node *node);
184 static char *s_chtml30_end_dt_tag         (void *pdoc, Node *node);
185 static char *s_chtml30_start_dd_tag       (void *pdoc, Node *node);
186 static char *s_chtml30_end_dd_tag         (void *pdoc, Node *node);
187 static char *s_chtml30_start_marquee_tag  (void *pdoc, Node *node);
188 static char *s_chtml30_end_marquee_tag    (void *pdoc, Node *node);
189 static char *s_chtml30_start_blink_tag    (void *pdoc, Node *node);
190 static char *s_chtml30_end_blink_tag      (void *pdoc, Node *node);
191 static char *s_chtml30_start_menu_tag     (void *pdoc, Node *node);
192 static char *s_chtml30_end_menu_tag       (void *pdoc, Node *node);
193 static char *s_chtml30_start_plaintext_tag       (void *pdoc, Node *node);
194 static char *s_chtml30_start_plaintext_tag_inner (void *pdoc, Node *node);
195 static char *s_chtml30_end_plaintext_tag         (void *pdoc, Node *node);
196 static char *s_chtml30_style_tag       (void *pdoc, Node *node);
197 static char *s_chtml30_newline_mark       (void *pdoc, Node *node);
198 static char *s_chtml30_link_tag           (void *pdoc, Node *node);
199 static char *s_chtml30_start_span_tag     (void *pdoc, Node *node);
200 static char *s_chtml30_end_span_tag       (void *pdoc, Node *node);
201
202 static void  s_init_chtml30(chtml30_t *chtml, Doc *doc, request_rec *r, device_table *spec);
203
204 static int   s_chtml30_search_emoji(chtml30_t *chtml, char *txt, char **rslt, Node *node);
205 static css_prop_list_t *s_chtml30_push_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value);
206 static css_prop_list_t *s_chtml30_nopush_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value);
207
208
209 tag_handler chtml30_handler[] = {
210   /* tagHTML */
211   {
212     s_chtml30_start_html_tag,
213     s_chtml30_end_html_tag,
214   },
215   /* tagMETA */
216   {
217     s_chtml30_start_meta_tag,
218     s_chtml30_end_meta_tag,
219   },
220   /* tagTEXTAREA */
221   {
222     s_chtml30_start_textarea_tag,
223     s_chtml30_end_textarea_tag,
224   },
225   /* tagP */
226   {
227     s_chtml30_start_p_tag,
228     s_chtml30_end_p_tag,
229   },
230   /* tagPRE */
231   {
232     s_chtml30_start_pre_tag,
233     s_chtml30_end_pre_tag,
234   },
235   /* tagUL */
236   {
237     s_chtml30_start_ul_tag,
238     s_chtml30_end_ul_tag,
239   },
240   /* tagLI */
241   {
242     s_chtml30_start_li_tag,
243     s_chtml30_end_li_tag,
244   },
245   /* tagOL */
246   {
247     s_chtml30_start_ol_tag,
248     s_chtml30_end_ol_tag,
249   },
250   /* tagH1 */
251   {
252     s_chtml30_start_h1_tag,
253     s_chtml30_end_h1_tag,
254   },
255   /* tagH2 */
256   {
257     s_chtml30_start_h2_tag,
258     s_chtml30_end_h2_tag,
259   },
260   /* tagH3 */
261   {
262     s_chtml30_start_h3_tag,
263     s_chtml30_end_h3_tag,
264   },
265   /* tagH4 */
266   {
267     s_chtml30_start_h4_tag,
268     s_chtml30_end_h4_tag,
269   },
270   /* tagH5 */
271   {
272     s_chtml30_start_h5_tag,
273     s_chtml30_end_h5_tag,
274   },
275   /* tagH6 */
276   {
277     s_chtml30_start_h6_tag,
278     s_chtml30_end_h6_tag,
279   },
280   /* tagHEAD */
281   {
282     s_chtml30_start_head_tag,
283     s_chtml30_end_head_tag,
284   },
285   /* tagTITLE */
286   {
287     s_chtml30_start_title_tag,
288     s_chtml30_end_title_tag,
289   },
290   /* tagBASE */
291   {
292     s_chtml30_start_base_tag,
293     s_chtml30_end_base_tag,
294   },
295   /* tagBODY */
296   {
297     s_chtml30_start_body_tag,
298     s_chtml30_end_body_tag,
299   },
300   /* tagA */
301   {
302     s_chtml30_start_a_tag,
303     s_chtml30_end_a_tag,
304   },
305   /* tagBR */
306   {
307     s_chtml30_start_br_tag,
308     s_chtml30_end_br_tag,
309   },
310   /* tagTABLE */
311   {
312     NULL,
313     NULL,
314   },
315   /* tagTR */
316   {
317     s_chtml30_start_tr_tag,
318     s_chtml30_end_tr_tag,
319   },
320   /* tagTD */
321   {
322     NULL,
323     NULL,
324   },
325   /* tagTBODY */
326   {
327     NULL,
328     NULL,
329   },
330   /* tagFONT */
331   {
332     s_chtml30_start_font_tag,
333     s_chtml30_end_font_tag,
334   },
335   /* tagFORM */
336   {
337     s_chtml30_start_form_tag,
338     s_chtml30_end_form_tag,
339   },
340   /* tagINPUT */
341   {
342     s_chtml30_start_input_tag,
343     s_chtml30_end_input_tag,
344   },
345   /* tagCENTER */
346   {
347     s_chtml30_start_center_tag,
348     s_chtml30_end_center_tag,
349   },
350   /* tagHR */
351   {
352     s_chtml30_start_hr_tag,
353     s_chtml30_end_hr_tag,
354   },
355   /* tagIMG */
356   {
357     s_chtml30_start_img_tag,
358     s_chtml30_end_img_tag,
359   },
360   /* tagSELECT */
361   {
362     s_chtml30_start_select_tag,
363     s_chtml30_end_select_tag,
364   },
365   /* tagOPTION */
366   {
367     s_chtml30_start_option_tag,
368     s_chtml30_end_option_tag,
369   },
370   /* tagDIV */
371   {
372     s_chtml30_start_div_tag,
373     s_chtml30_end_div_tag,
374   },
375   /* tagCHXJIF */
376   {
377     s_chtml30_chxjif_tag,
378     NULL,
379   },
380   /* tagCHXJRAW */
381   {
382     s_chtml30_chxjif_tag,
383     NULL,
384   },
385   /* tagNOBR */
386   {
387     NULL,
388     NULL,
389   },
390   /* tagSMALL */
391   {
392     NULL,
393     NULL,
394   },
395   /* tagSTYLE */
396   {
397     s_chtml30_style_tag,
398     NULL,
399   },
400   /* tagSPAN */
401   {
402     s_chtml30_start_span_tag,
403     s_chtml30_end_span_tag,
404   },
405   /* tagTEXT */
406   {
407     s_chtml30_text_tag,
408     NULL,
409   },
410   /* tagTH */
411   {
412     NULL,
413     NULL,
414   },
415   /* tagB */
416   {
417     NULL,
418     NULL,
419   },
420   /* tagFIELDSET */
421   {
422     NULL,
423     NULL,
424   },
425   /* tagDT */
426   {
427     s_chtml30_start_dt_tag,
428     s_chtml30_end_dt_tag,
429   },
430   /* tagLEGEND */
431   {
432     NULL,
433     NULL,
434   },
435   /* tagLABEL */
436   {
437     NULL,
438     NULL,
439   },
440   /* tagBLOCKQUOTE */
441   {
442     s_chtml30_start_blockquote_tag,
443     s_chtml30_end_blockquote_tag,
444   },
445   /* tagDIR */
446   {
447     s_chtml30_start_dir_tag,
448     s_chtml30_end_dir_tag,
449   },
450   /* tagDL */
451   {
452     s_chtml30_start_dl_tag,
453     s_chtml30_end_dl_tag,
454   },
455   /* tagDD */
456   {
457     s_chtml30_start_dd_tag,
458     s_chtml30_end_dd_tag,
459   },
460   /* tagMENU */
461   {
462     s_chtml30_start_menu_tag,
463     s_chtml30_end_menu_tag,
464   },
465   /* tagPLAINTEXT */
466   {
467     s_chtml30_start_plaintext_tag,
468     s_chtml30_end_plaintext_tag,
469   },
470   /* tagBLINK */
471   {
472     s_chtml30_start_blink_tag,
473     s_chtml30_end_blink_tag,
474   },
475   /* tagMARQUEE */
476   {
477     s_chtml30_start_marquee_tag,
478     s_chtml30_end_marquee_tag,
479   },
480   /* tagLINK */
481   {
482     s_chtml30_link_tag,
483     NULL,
484   },
485   /* tagNLMARK */
486   {
487     s_chtml30_newline_mark,
488     NULL,
489   },
490   /* tagObject */
491   {
492     NULL,
493     NULL,
494   },
495   /* tagParam */
496   {
497     NULL,
498     NULL,
499   },
500   /* tagCAPTION */
501   {
502     NULL,
503     NULL,
504   },
505 };
506
507
508 /**
509  * converts from CHTML5.0 to CHTML3.0.
510  *
511  * @param r     [i]   Requet_rec is appointed.
512  * @param spec  [i]   The result of the device specification processing which 
513  *                    was done in advance is appointed.
514  * @param src   [i]   The character string before the converting is appointed.
515  * @return The character string after the converting is returned.
516  */
517 char*
518 chxj_convert_chtml30(
519   request_rec         *r,
520   device_table        *spec,
521   const char          *src,
522   apr_size_t          srclen,
523   apr_size_t          *dstlen,
524   chxjconvrule_entry  *entryp,
525   cookie_t            *cookie
526 )
527 {
528   char      *dst = NULL;
529   char      *ss;
530   chtml30_t chtml30;
531   Doc       doc;
532
533   DBG(r,"REQ[%X] start %s()",TO_ADDR(r),__func__);
534
535   /*--------------------------------------------------------------------------*/
536   /* If qrcode xml                                                            */
537   /*--------------------------------------------------------------------------*/
538   *dstlen = srclen;
539   dst = chxj_qr_code_blob_handler(r, src, (size_t*)dstlen);
540   if (dst) {
541     DBG(r,"REQ[%X] found qrcode xml",TO_ADDR(r));
542     DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
543     return dst;
544   }
545   DBG(r,"not found qrcode xml");
546
547   /*--------------------------------------------------------------------------*/
548   /* The CHTML structure is initialized.                                      */
549   /*--------------------------------------------------------------------------*/
550   s_init_chtml30(&chtml30, &doc, r, spec);
551
552   chtml30.entryp = entryp;
553   chtml30.cookie = cookie;
554
555   chxj_set_content_type(r, chxj_header_inf_set_content_type(r, "text/html; charset=Windows-31J"));
556
557   /*--------------------------------------------------------------------------*/
558   /* The character string of the input is analyzed.                           */
559   /*--------------------------------------------------------------------------*/
560   qs_init_malloc(&doc);
561   qs_init_root_node(&doc);
562
563   ss = apr_pcalloc(r->pool, srclen + 1);
564   memset(ss, 0, srclen + 1);
565   memcpy(ss, src, srclen);
566
567 #ifdef DUMP_LOG
568   chxj_dump_out("[src] CHTML -> CHTML3.0", ss, srclen);
569 #endif
570   if (IS_CSS_ON(chtml30.entryp)) {
571     /* current property list */
572     chtml30.css_prop_stack = chxj_new_prop_list_stack(&doc);
573   }
574
575   chxj_buffered_write_init(r->pool, &doc.buf);
576
577   qs_parse_string(&doc,ss, strlen(ss));
578
579   /*--------------------------------------------------------------------------*/
580   /* It converts it from CHTML to CHTML.                                      */
581   /*--------------------------------------------------------------------------*/
582   chxj_node_convert(spec,r,(void*)&chtml30, &doc, qs_get_root(&doc), 0);
583   chtml30.out = chxj_buffered_write_flush(chtml30.out, &doc.buf);
584   dst = apr_pstrdup(r->pool, chtml30.out);
585   chxj_buffered_write_terminate(&doc.buf);
586
587   qs_all_free(&doc,QX_LOGMARK);
588
589   if (dst == NULL) {
590     dst = apr_pstrdup(r->pool,ss);
591   }
592   if (strlen(dst) == 0) {
593     dst = apr_psprintf(r->pool, "\n");
594   }
595
596   *dstlen = strlen(dst);
597
598 #ifdef DUMP_LOG
599   chxj_dump_out("[src] CHTML -> CHTML3.0", dst, *dstlen);
600 #endif
601
602   DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
603   return dst;
604 }
605
606
607 /**
608  * The CHTML structure is initialized.
609  *
610  * @param chtml30 [i/o] The pointer to the HDML structure that wants to be
611  *                   initialized is specified.
612  * @param doc   [i]   The Doc structure that should be set to the initialized
613  *                   HDML structure is specified.
614  * @param r     [i]   To use POOL, the pointer to request_rec is specified.
615  * @param spec  [i]   The pointer to the device_table
616  */
617 static void
618 s_init_chtml30(chtml30_t *chtml30, Doc *doc, request_rec *r, device_table *spec)
619 {
620   memset(doc,     0, sizeof(Doc));
621   memset(chtml30, 0, sizeof(chtml30_t));
622
623   doc->r        = r;
624   chtml30->doc  = doc;
625   chtml30->spec = spec;
626   chtml30->out  = qs_alloc_zero_byte_string(r->pool);
627   chtml30->conf = chxj_get_module_config(r->per_dir_config, &chxj_module);
628   chtml30->doc->parse_mode = PARSE_MODE_CHTML;
629 }
630
631
632 /**
633  * Corresponding EMOJI to a current character-code is retrieved. 
634  * The substitution character string is stored in the rslt pointer if agreeing.
635  *
636  * @param chtml30   [i]   The pointer to the CHTML structure is specified. 
637  * @param txt     [i]   The character string to want to examine whether it is 
638  *                      EMOJI is specified. 
639  * @param rslt    [o]   The pointer to the pointer that stores the result is 
640  *                      specified. 
641  * @param node    [i]   The current node to check whether tag is span/font for CHXJ_IMODE_EMOJI_COLOR_AUTO
642  * @return When corresponding EMOJI exists, it returns it excluding 0. 
643  */
644 static int
645 s_chtml30_search_emoji(chtml30_t *chtml30, char *txt, char **rslt, Node *node)
646 {
647   emoji_t       *ee;
648   request_rec   *r;
649   device_table  *spec;
650   int           len;
651
652   spec = chtml30->spec;
653
654   len = strlen(txt);
655   r   = chtml30->doc->r;
656
657   if (!spec) {
658     DBG(r,"REQ[%X] spec is NULL", TO_ADDR(r));
659   }
660
661   for (ee = chtml30->conf->emoji;
662        ee;
663        ee = ee->next) {
664     if (ee->imode == NULL) {
665       DBG(r, "REQ[%X] emoji->imode is NULL", TO_ADDR(r));
666       continue;
667     }
668
669     if (ee->imode->string != NULL
670     &&  strlen(ee->imode->string) > 0
671     &&  strncasecmp(ee->imode->string, txt, strlen(ee->imode->string)) == 0) {
672
673       if (spec == NULL || spec->emoji_type == NULL) {
674         *rslt = apr_palloc(r->pool, 3);
675         (*rslt)[0] = ee->imode->hex1byte & 0xff;
676         (*rslt)[1] = ee->imode->hex2byte & 0xff;
677         (*rslt)[2] = 0;
678         
679         if(chtml30->conf->imode_emoji_color >= CHXJ_IMODE_EMOJI_COLOR_AUTO ){
680           if(ee->imode->color != NULL){
681             if(chtml30->conf->imode_emoji_color == CHXJ_IMODE_EMOJI_COLOR_AUTO && node != NULL ){
682               if(strcasecmp(node->parent->name, "span") == 0 ||
683                  strcasecmp(node->parent->name, "font")  == 0 ){
684                 return strlen(ee->imode->string);
685               }
686             }
687             char *tmp = apr_pstrdup(r->pool,*rslt);
688             *rslt = apr_psprintf(r->pool,
689                         "<font color=\"%s\">%s</font>",ee->imode->color,tmp);
690           }
691         }
692         return strlen(ee->imode->string);
693         
694         return strlen(ee->imode->string);
695       }
696
697       return 0;
698     }
699   }
700
701   return 0;
702 }
703
704
705 char *
706 chxj_chtml30_emoji_only_converter(request_rec *r, device_table *spec, const char *src, apr_size_t len)
707 {
708   apr_size_t ii;
709   Doc __doc;
710   Doc *doc;
711   chtml30_t __chtml30;
712   chtml30_t *chtml30;
713   char one_byte[2];
714   char two_byte[3];
715   apr_pool_t *pool;
716
717   chtml30 = &__chtml30;
718   doc     = &__doc;
719
720   DBG(r,"REQ[%X] start %s()",TO_ADDR(r),__func__);
721   memset(doc,     0, sizeof(Doc));
722   memset(chtml30, 0, sizeof(chtml30_t));
723
724   doc->r        = r;
725   chtml30->doc  = doc;
726   chtml30->spec = spec;
727   chtml30->out  = qs_alloc_zero_byte_string(r->pool);
728   chtml30->conf = chxj_get_module_config(r->per_dir_config, &chxj_module);
729   chtml30->doc->parse_mode = PARSE_MODE_CHTML;
730
731   apr_pool_create(&pool, r->pool);
732
733   chxj_buffered_write_init(pool, &doc->buf);
734
735   for (ii=0; ii<len; ii++) {
736     char *out;
737     int   rtn;
738
739     rtn = s_chtml30_search_emoji(chtml30, (char *)&src[ii], &out, NULL);
740     if (rtn) {
741       W_V(out);
742       ii+=(rtn - 1);
743       continue;
744     }
745
746     if (is_sjis_kanji(src[ii])) {
747       two_byte[0] = src[ii+0];
748       two_byte[1] = src[ii+1];
749       two_byte[2] = 0;
750       W_V(two_byte);
751       ii++;
752     }
753     else {
754       one_byte[0] = src[ii+0];
755       one_byte[1] = 0;
756       W_V(one_byte);
757     }
758   }
759   chtml30->out = chxj_buffered_write_flush(chtml30->out, &doc->buf);
760
761   DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
762   return chtml30->out;
763 }
764
765
766 /**
767  * It is a handler who processes the HTML tag.
768  *
769  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
770  *                     destination is specified.
771  * @param node   [i]   The HTML tag node is specified.
772  * @return The conversion result is returned.
773  */
774 static char *
775 s_chtml30_start_html_tag(void *pdoc, Node *UNUSED(node)) 
776 {
777   chtml30_t *chtml30 = GET_CHTML30(pdoc);
778   Doc       *doc     = chtml30->doc;
779
780   /*--------------------------------------------------------------------------*/
781   /* start HTML tag                                                           */
782   /*--------------------------------------------------------------------------*/
783   W_L("<html>");
784
785   return chtml30->out;
786 }
787
788
789 /**
790  * It is a handler who processes the HTML tag.
791  *
792  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
793  *                     destination is specified.
794  * @param node   [i]   The HTML tag node is specified.
795  * @return The conversion result is returned.
796  */
797 static char *
798 s_chtml30_end_html_tag(void *pdoc, Node *UNUSED(child)) 
799 {
800   chtml30_t   *chtml30 = GET_CHTML30(pdoc);
801   Doc         *doc     = chtml30->doc;
802
803   W_L("</html>");
804
805   return chtml30->out;
806 }
807
808
809 /**
810  * It is a handler who processes the META tag.
811  *
812  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
813  *                     destination is specified.
814  * @param node   [i]   The META tag node is specified.
815  * @return The conversion result is returned.
816  */
817 static char *
818 s_chtml30_start_meta_tag(void *pdoc, Node *node) 
819 {
820   chtml30_t     *chtml30;
821   Doc           *doc;
822   request_rec   *r;
823   Attr          *attr;
824   int           content_type_flag;
825   int           refresh_flag;
826
827   chtml30 = GET_CHTML30(pdoc);
828   doc     = chtml30->doc;
829   r       = doc->r;
830
831   content_type_flag = 0;
832   refresh_flag      = 0;
833
834   W_L("<meta");
835   /*--------------------------------------------------------------------------*/
836   /* Get Attributes                                                           */
837   /*--------------------------------------------------------------------------*/
838   for (attr = qs_get_attr(doc,node);
839        attr;
840        attr = qs_get_next_attr(doc,attr)) {
841     char *name   = qs_get_attr_name(doc,attr);
842     char *value  = qs_get_attr_value(doc,attr);
843     switch(*name) {
844     case 'h':
845     case 'H':
846       if (strcasecmp(name, "http-equiv") == 0 && value && *value) {
847         /*----------------------------------------------------------------------*/
848         /* CHTML 2.0                                                            */
849         /*----------------------------------------------------------------------*/
850         W_L(" http-equiv=\"");
851         W_V(value);
852         W_L("\"");
853         if (STRCASEEQ('c','C',"content-type", value))
854           content_type_flag = 1;
855   
856         if (STRCASEEQ('r','R',"refresh", value))
857           refresh_flag = 1;
858       }
859       break;
860
861     case 'c':
862     case 'C':
863       if (strcasecmp(name, "content") == 0 && value && *value) {
864         if (content_type_flag) {
865           W_L(" ");
866           W_V(name);
867           W_L("=\"");
868           W_V(chxj_header_inf_set_content_type(r, "text/html; charset=SHIFT_JIS"));
869           W_L("\"");
870         }
871         else
872         if (refresh_flag) {
873           char *buf;
874           char *sec;
875           char *url;
876           buf = apr_pstrdup(r->pool, value);
877           url = strchr(buf, ';');
878           if (url) {
879             sec = apr_pstrdup(r->pool, buf);
880             sec[url-buf] = 0;
881             url++;
882             url = chxj_encoding_parameter(r, url, 0);
883             url = chxj_add_cookie_parameter(r, url, chtml30->cookie);
884             W_L(" ");
885             W_V(name);
886             W_L("=\"");
887             W_V(sec);
888             W_L(";");
889             W_V(url);
890             W_L("\"");
891           }
892         }
893         else {
894           W_L(" ");
895           W_V(name);
896           W_L("=\"");
897           W_V(value);
898           W_L("\"");
899         }
900       }
901       break;
902
903     default:
904       break;
905     }
906   }
907   W_L(">");
908   return chtml30->out;
909 }
910
911
912 /**
913  * It is a handler who processes the META tag.
914  *
915  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
916  *                     destination is specified.
917  * @param node   [i]   The META tag node is specified.
918  * @return The conversion result is returned.
919  */
920 static char*
921 s_chtml30_end_meta_tag(void* pdoc, Node* UNUSED(child)) 
922 {
923   chtml30_t *chtml30 = GET_CHTML30(pdoc);
924
925   return chtml30->out;
926 }
927
928
929 /**
930  * It is a handler who processes the HEAD tag.
931  *
932  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
933  *                     destination is specified.
934  * @param node   [i]   The HEAD tag node is specified.
935  * @return The conversion result is returned.
936  */
937 static char*
938 s_chtml30_start_head_tag(void* pdoc, Node* UNUSED(node)) 
939 {
940   chtml30_t   *chtml30 = GET_CHTML30(pdoc);
941   Doc         *doc     = chtml30->doc;
942
943   W_L("<head>");
944
945   return chtml30->out;
946 }
947
948
949 /**
950  * It is a handler who processes the HEAD tag.
951  *
952  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
953  *                     destination is specified.
954  * @param node   [i]   The HEAD tag node is specified.
955  * @return The conversion result is returned.
956  */
957 static char *
958 s_chtml30_end_head_tag(void *pdoc, Node *UNUSED(node)) 
959 {
960   chtml30_t *chtml30 = GET_CHTML30(pdoc);
961   Doc       *doc     = chtml30->doc;
962
963   W_L("</head>");
964
965   return chtml30->out;
966 }
967
968
969 /**
970  * It is a handler who processes the TITLE tag.
971  *
972  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
973  *                     destination is specified.
974  * @param node   [i]   The TITLE tag node is specified.
975  * @return The conversion result is returned.
976  */
977 static char *
978 s_chtml30_start_title_tag(void *pdoc, Node *node) 
979 {
980   chtml30_t     *chtml30 = GET_CHTML30(pdoc);
981   Doc           *doc     = chtml30->doc;
982
983   W_L("<title>");
984
985   if (chtml30->conf->use_google_analytics) {
986     chtml30->pagetitle = "";
987     Node         *child;
988     for (child = qs_get_child_node(doc,node);
989          child;
990          child = qs_get_next_node(doc,child)) {
991       char *textval = qs_get_node_value(doc,child);
992       chtml30->pagetitle = apr_pstrcat(doc->r->pool, chtml30->pagetitle, textval, NULL);
993     }
994   }
995
996   return chtml30->out;
997 }
998
999
1000 /**
1001  * It is a handler who processes the TITLE tag.
1002  *
1003  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1004  *                     destination is specified.
1005  * @param node   [i]   The TITLE tag node is specified.
1006  * @return The conversion result is returned.
1007  */
1008 static char *
1009 s_chtml30_end_title_tag(void *pdoc, Node *UNUSED(child)) 
1010 {
1011   chtml30_t    *chtml30 = GET_CHTML30(pdoc);
1012   Doc          *doc     = chtml30->doc;
1013
1014   W_L("</title>");
1015
1016   return chtml30->out;
1017 }
1018
1019
1020 /**
1021  * It is a handler who processes the BASE tag.
1022  *
1023  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1024  *                     destination is specified.
1025  * @param node   [i]   The BASE tag node is specified.
1026  * @return The conversion result is returned.
1027  */
1028 static char *
1029 s_chtml30_start_base_tag(void *pdoc, Node *node) 
1030 {
1031   Attr        *attr;
1032   chtml30_t   *chtml30;
1033   Doc         *doc;
1034   request_rec *r;
1035
1036   chtml30 = GET_CHTML30(pdoc);
1037   doc     = chtml30->doc;
1038   r       = doc->r;
1039
1040   W_L("<base");
1041   /*--------------------------------------------------------------------------*/
1042   /* Get Attributes                                                           */
1043   /*--------------------------------------------------------------------------*/
1044   for (attr = qs_get_attr(doc,node);
1045        attr;
1046        attr = qs_get_next_attr(doc,attr)) {
1047     char *name = qs_get_attr_name(doc,attr);
1048     char *value = qs_get_attr_value(doc,attr);
1049     if (STRCASEEQ('h','H',"href", name)) {
1050       W_L(" href=\"");
1051       W_V(value);
1052       W_L("\"");
1053     }
1054   }
1055   W_L(">");
1056   return chtml30->out;
1057 }
1058
1059
1060 /**
1061  * It is a handler who processes the BASE tag.
1062  *
1063  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1064  *                     destination is specified.
1065  * @param node   [i]   The BASE tag node is specified.
1066  * @return The conversion result is returned.
1067  */
1068 static char *
1069 s_chtml30_end_base_tag(void *pdoc, Node *UNUSED(child)) 
1070 {
1071   chtml30_t *chtml30 = GET_CHTML30(pdoc);
1072
1073   return chtml30->out;
1074 }
1075
1076
1077 /**
1078  * It is a handler who processes the BODY tag.
1079  *
1080  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1081  *                     destination is specified.
1082  * @param node   [i]   The BODY tag node is specified.
1083  * @return The conversion result is returned.
1084  */
1085 static char *
1086 s_chtml30_start_body_tag(void *pdoc, Node *node) 
1087 {
1088   chtml30_t   *chtml30;
1089   Doc         *doc;
1090   request_rec *r;
1091   Attr        *attr;
1092   char        *attr_bgcolor = NULL;
1093   char        *attr_text    = NULL;
1094   char        *attr_link    = NULL;
1095   char        *attr_style   = NULL;
1096
1097   chtml30 = GET_CHTML30(pdoc);
1098   doc     = chtml30->doc;
1099   r       = doc->r;
1100
1101   /*--------------------------------------------------------------------------*/
1102   /* Get Attributes                                                           */
1103   /*--------------------------------------------------------------------------*/
1104   for (attr = qs_get_attr(doc,node);
1105        attr;
1106        attr = qs_get_next_attr(doc,attr)) {
1107     char *name = qs_get_attr_name(doc,attr);
1108     char *value = qs_get_attr_value(doc,attr);
1109     switch(*name) {
1110     case 'b':
1111     case 'B':
1112       if (strcasecmp(name, "bgcolor") == 0 && value && *value != 0) {
1113         /*----------------------------------------------------------------------*/
1114         /* CHTML 2.0                                                            */
1115         /*----------------------------------------------------------------------*/
1116         attr_bgcolor = value;
1117       }
1118       break;
1119
1120     case 't':
1121     case 'T':
1122       if (strcasecmp(name, "text") == 0 && value && *value != 0) {
1123         /*----------------------------------------------------------------------*/
1124         /* CHTML 2.0                                                            */
1125         /*----------------------------------------------------------------------*/
1126         attr_text = value;
1127       }
1128       break;
1129
1130     case 's':
1131     case 'S':
1132       if (strcasecmp(name, "style") == 0 && value && *value != 0) {
1133         attr_style = value;
1134       }
1135       break;
1136
1137     case 'l':
1138     case 'L':
1139       if (strcasecmp(name, "link") == 0 && value && *value != 0) {
1140         /*----------------------------------------------------------------------*/
1141         /* CHTML 2.0                                                            */
1142         /*----------------------------------------------------------------------*/
1143         attr_link = value;
1144       }
1145       break;
1146
1147     case 'a':
1148     case 'A':
1149       if (strcasecmp(name, "alink") == 0) {
1150         /*----------------------------------------------------------------------*/
1151         /* CHTML 4.0                                                            */
1152         /*----------------------------------------------------------------------*/
1153         /* ignore */
1154       }
1155       break;
1156
1157     case 'v':
1158     case 'V':
1159       if (strcasecmp(name, "vlink") == 0) {
1160         /*----------------------------------------------------------------------*/
1161         /* CHTML 4.0                                                            */
1162         /*----------------------------------------------------------------------*/
1163         /* ignore */
1164       }
1165       break;
1166
1167     default:
1168       break;
1169     }
1170   }
1171   if (IS_CSS_ON(chtml30->entryp)) {
1172     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
1173     if (style) {
1174       css_property_t *color_prop      = chxj_css_get_property_value(doc, style, "color");
1175       css_property_t *bgcolor_prop    = chxj_css_get_property_value(doc, style, "background-color");
1176       css_property_t *cur;
1177       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
1178         if (cur->value && *cur->value) {
1179           attr_text = apr_pstrdup(doc->pool, cur->value);
1180         }
1181       }
1182       for (cur = bgcolor_prop->next; cur != bgcolor_prop; cur = cur->next) {
1183         if (cur->value && *cur->value) {
1184           attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
1185         }
1186       }
1187     }
1188     if (chtml30->style) {
1189       css_stylesheet_t *pseudos = chxj_find_pseudo_selectors(doc, chtml30->style);
1190       css_selector_t *cur_sel;
1191       for (cur_sel = pseudos->selector_head.next; cur_sel != &pseudos->selector_head; cur_sel = cur_sel->next) {
1192         if (cur_sel->name && strcasecmp(cur_sel->name, "a:link") == 0) {
1193           css_property_t *cur;
1194           for (cur = cur_sel->property_head.next; cur != &cur_sel->property_head; cur = cur->next) {
1195             if (cur->name && strcasecmp(cur->name, "color") == 0) {
1196               attr_link = apr_pstrdup(doc->pool, cur->value);
1197             }
1198           }
1199         }
1200       }
1201     }
1202   }
1203   W_L("<body");
1204   if (attr_bgcolor) {
1205     attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
1206     W_L(" bgcolor=\"");
1207     W_V(attr_bgcolor);
1208     W_L("\"");
1209   }
1210   if (attr_text) {
1211     attr_text = chxj_css_rgb_func_to_value(doc->pool, attr_text);
1212     W_L(" text=\"");
1213     W_V(attr_text);
1214     W_L("\"");
1215   }
1216   if (attr_link) {
1217     attr_link = chxj_css_rgb_func_to_value(doc->pool, attr_link);
1218     W_L(" link=\"");
1219     W_V(attr_link);
1220     W_L("\"");
1221   }
1222   W_L(">");
1223
1224   return chtml30->out;
1225 }
1226
1227
1228 /**
1229  * It is a handler who processes the BODY tag.
1230  *
1231  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1232  *                     destination is specified.
1233  * @param node   [i]   The BODY tag node is specified.
1234  * @return The conversion result is returned.
1235  */
1236 static char *
1237 s_chtml30_end_body_tag(void *pdoc, Node *UNUSED(child)) 
1238 {
1239   chtml30_t   *chtml30;
1240   Doc         *doc;
1241
1242   chtml30 = GET_CHTML30(pdoc);
1243   doc     = chtml30->doc;
1244
1245   if (chtml30->conf->use_google_analytics) {
1246     char *src = chxj_google_analytics_get_image_url(doc->r, chtml30->pagetitle);
1247     W_L("<img src=\"");
1248     W_V(src);
1249     W_L("\" />");
1250   }
1251
1252   W_L("</body>");
1253   if (IS_CSS_ON(chtml30->entryp)) {
1254     chxj_css_pop_prop_list(chtml30->css_prop_stack);
1255   }
1256
1257   return chtml30->out;
1258 }
1259
1260
1261 /**
1262  * It is a handler who processes the A tag.
1263  *
1264  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1265  *                     destination is specified.
1266  * @param node   [i]   The A tag node is specified.
1267  * @return The conversion result is returned.
1268  */
1269 static char *
1270 s_chtml30_start_a_tag(void *pdoc, Node *node) 
1271 {
1272   chtml30_t     *chtml30;
1273   Doc           *doc;
1274   request_rec   *r;
1275   Attr          *attr;
1276   char          *attr_style = NULL;
1277
1278   chtml30 = GET_CHTML30(pdoc);
1279   doc     = chtml30->doc;
1280   r       = doc->r;
1281
1282   W_L("<a");
1283   /*--------------------------------------------------------------------------*/
1284   /* Get Attributes                                                           */
1285   /*--------------------------------------------------------------------------*/
1286   for (attr = qs_get_attr(doc,node);
1287        attr; 
1288        attr = qs_get_next_attr(doc,attr)) {
1289     char *name  = qs_get_attr_name(doc,attr);
1290     char *value = qs_get_attr_value(doc,attr);
1291     if (STRCASEEQ('n','N',"name", name)) {
1292       /*----------------------------------------------------------------------*/
1293       /* CHTML1.0                                                             */
1294       /*----------------------------------------------------------------------*/
1295       W_L(" name=\"");
1296       W_V(value);
1297       W_L("\"");
1298     }
1299     else if (STRCASEEQ('h','H',"href", name)) {
1300       /*----------------------------------------------------------------------*/
1301       /* CHTML1.0                                                             */
1302       /*----------------------------------------------------------------------*/
1303       value = chxj_encoding_parameter(r, value, 0);
1304       if (! chxj_starts_with(value, "mailto:") && ! chxj_starts_with(value, "tel:")) {
1305         value = chxj_add_cookie_parameter(r, value, chtml30->cookie);
1306       }
1307       W_L(" href=\"");
1308       W_V(value);
1309       W_L("\"");
1310     }
1311     else if (STRCASEEQ('a','A',"accesskey", name)) {
1312       /*----------------------------------------------------------------------*/
1313       /* CHTML1.0                                                             */
1314       /*----------------------------------------------------------------------*/
1315       W_L(" accesskey=\"");
1316       W_V(value);
1317       W_L("\"");
1318     }
1319     else if (STRCASEEQ('c','C',"cti", name)) {
1320       /*----------------------------------------------------------------------*/
1321       /* CHTML 2.0                                                            */
1322       /*----------------------------------------------------------------------*/
1323       W_L(" cti=\"");
1324       W_V(value);
1325       W_L("\"");
1326     }
1327     else if (STRCASEEQ('i','I',"ijam", name)) {
1328       /*----------------------------------------------------------------------*/
1329       /* CHTML 3.0                                                            */
1330       /*----------------------------------------------------------------------*/
1331       /* ignore */
1332     }
1333     else if (STRCASEEQ('u','U',"utn", name)) {
1334       /*----------------------------------------------------------------------*/
1335       /* CHTML 3.0                                                            */
1336       /* It is special only for CHTML.                                        */
1337       /*----------------------------------------------------------------------*/
1338       W_L(" utn ");
1339     }
1340     else if (STRCASEEQ('t','T',"telbook", name)) {
1341       /*----------------------------------------------------------------------*/
1342       /* CHTML 3.0                                                            */
1343       /*----------------------------------------------------------------------*/
1344       /* not support */
1345     }
1346     else if (STRCASEEQ('k','K',"kana", name)) {
1347       /*----------------------------------------------------------------------*/
1348       /* CHTML 3.0                                                            */
1349       /*----------------------------------------------------------------------*/
1350       /* not support */
1351     }
1352     else if (STRCASEEQ('e','E',"email", name)) {
1353       /*----------------------------------------------------------------------*/
1354       /* CHTML 3.0                                                            */
1355       /*----------------------------------------------------------------------*/
1356       /* not support */
1357     }
1358     else if (STRCASEEQ('i','I',"ista", name)) {
1359       /*----------------------------------------------------------------------*/
1360       /* CHTML 4.0                                                            */
1361       /*----------------------------------------------------------------------*/
1362       /* ignore */
1363     }
1364     else if (STRCASEEQ('i','I',"ilet", name)) {
1365       /*----------------------------------------------------------------------*/
1366       /* CHTML 5.0                                                            */
1367       /*----------------------------------------------------------------------*/
1368       /* ignore */
1369     }
1370     else if (STRCASEEQ('i','I',"iswf", name)) {
1371       /*----------------------------------------------------------------------*/
1372       /* CHTML 5.0                                                            */
1373       /*----------------------------------------------------------------------*/
1374       /* ignore */
1375     }
1376     else if (STRCASEEQ('i','I',"irst", name)) {
1377       /*----------------------------------------------------------------------*/
1378       /* CHTML 5.0                                                            */
1379       /*----------------------------------------------------------------------*/
1380       /* ignore */
1381     }
1382     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
1383       attr_style = value;
1384     }
1385   }
1386   W_L(">");
1387
1388   if (IS_CSS_ON(chtml30->entryp)) {
1389     s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
1390   }
1391
1392   return chtml30->out;
1393 }
1394
1395
1396 /**
1397  * It is a handler who processes the A tag.
1398  *
1399  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1400  *                     destination is specified.
1401  * @param node   [i]   The A tag node is specified.
1402  * @return The conversion result is returned.
1403  */
1404 static char *
1405 s_chtml30_end_a_tag(void *pdoc, Node *UNUSED(child)) 
1406 {
1407   chtml30_t   *chtml30;
1408   Doc         *doc;
1409
1410   chtml30 = GET_CHTML30(pdoc);
1411   doc     = chtml30->doc;
1412
1413   W_L("</a>");
1414   if (IS_CSS_ON(chtml30->entryp)) {
1415     chxj_css_pop_prop_list(chtml30->css_prop_stack);
1416   }
1417
1418   return chtml30->out;
1419 }
1420
1421
1422 /**
1423  * It is a handler who processes the BR tag.
1424  *
1425  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1426  *                     destination is specified.
1427  * @param node   [i]   The BR tag node is specified.
1428  * @return The conversion result is returned.
1429  */
1430 static char *
1431 s_chtml30_start_br_tag(void *pdoc, Node *node)
1432 {
1433   chtml30_t   *chtml30;
1434   Doc         *doc;
1435   request_rec *r;
1436   Attr        *attr;
1437
1438   chtml30 = GET_CHTML30(pdoc);
1439   doc     = chtml30->doc;
1440   r       = doc->r;
1441   W_L("<br");
1442   /*--------------------------------------------------------------------------*/
1443   /* Get Attributes                                                           */
1444   /*--------------------------------------------------------------------------*/
1445   for (attr = qs_get_attr(doc,node);
1446        attr;
1447        attr = qs_get_next_attr(doc,attr)) {
1448     char *name  = qs_get_attr_name(doc,attr);
1449     char *value = qs_get_attr_value(doc,attr);
1450     if (STRCASEEQ('c','C',"clear",name)) {
1451       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('a','A',"all",value))) {
1452         W_L(" clear=\"");
1453         W_V(value);
1454         W_L("\"");
1455       }
1456     }
1457   }
1458   W_L(">");
1459   return chtml30->out;
1460 }
1461
1462
1463 /**
1464  * It is a handler who processes the BR tag.
1465  *
1466  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1467  *                     destination is specified.
1468  * @param node   [i]   The BR tag node is specified.
1469  * @return The conversion result is returned.
1470  */
1471 static char *
1472 s_chtml30_end_br_tag(void *pdoc, Node *UNUSED(child)) 
1473 {
1474   chtml30_t *chtml30 = GET_CHTML30(pdoc);
1475
1476   return chtml30->out;
1477 }
1478
1479
1480 /**
1481  * It is a handler who processes the TR tag.
1482  *
1483  * @param chtml30  [i/o] The pointer to the CHTML structure at the output
1484  *                     destination is specified.
1485  * @param node   [i]   The TR tag node is specified.
1486  * @return The conversion result is returned.
1487  */
1488 static char *
1489 s_chtml30_start_tr_tag(void *pdoc, Node *UNUSED(node)) 
1490 {
1491   chtml30_t *chtml30 = GET_CHTML30(pdoc);
1492
1493   return chtml30->out;
1494 }
1495
1496
1497 /**
1498  * It is a handler who processes the TR tag.
1499  *
1500  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1501  *                     destination is specified.
1502  * @param node   [i]   The TR tag node is specified.
1503  * @return The conversion result is returned.
1504  */
1505 static char *
1506 s_chtml30_end_tr_tag(void *pdoc, Node *UNUSED(child)) 
1507 {
1508   chtml30_t   *chtml30;
1509   Doc         *doc;
1510   request_rec *r;
1511
1512   chtml30 = GET_CHTML30(pdoc);
1513   doc     = chtml30->doc;
1514   r       = doc->r;
1515
1516   W_L("<br>");
1517
1518   return chtml30->out;
1519 }
1520
1521
1522 /**
1523  * It is a handler who processes the FONT tag.
1524  *
1525  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1526  *                     destination is specified.
1527  * @param node   [i]   The FONT tag node is specified.
1528  * @return The conversion result is returned.
1529  */
1530 static char *
1531 s_chtml30_start_font_tag(void *pdoc, Node *node) 
1532 {
1533   Attr        *attr;
1534   chtml30_t   *chtml30;
1535   Doc         *doc;
1536   request_rec *r;
1537   char        *attr_color = NULL;
1538   char        *attr_style = NULL;
1539
1540   chtml30 = GET_CHTML30(pdoc);
1541   doc     = chtml30->doc;
1542   r       = doc->r;
1543
1544   /*--------------------------------------------------------------------------*/
1545   /* Get Attributes                                                           */
1546   /*--------------------------------------------------------------------------*/
1547   for (attr = qs_get_attr(doc,node);
1548        attr; 
1549        attr = qs_get_next_attr(doc,attr)) {
1550     char *name  = qs_get_attr_name(doc,attr);
1551     char *value = qs_get_attr_value(doc,attr);
1552     if (STRCASEEQ('c','C',"color", name) && value && *value) {
1553       attr_color = apr_pstrdup(doc->buf.pool, value);
1554     }
1555     else if (STRCASEEQ('s','S',"size", name)) {
1556       /*----------------------------------------------------------------------*/
1557       /* CHTML 5.0                                                            */
1558       /*----------------------------------------------------------------------*/
1559       /* ignore */
1560     }
1561     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
1562       attr_style = value;
1563     }
1564   }
1565   if (IS_CSS_ON(chtml30->entryp)) {
1566     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
1567     if (style) {
1568       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
1569       css_property_t *cur;
1570       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
1571         if (cur->value && *cur->value) {
1572           attr_color = apr_pstrdup(doc->pool, cur->value);
1573         }
1574       }
1575     }
1576   }
1577   if (attr_color) {
1578     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
1579     W_L("<font color=\"");
1580     W_V(attr_color);
1581     W_L("\">");
1582
1583     chtml30_flags_t *flg = (chtml30_flags_t *)apr_palloc(doc->pool, sizeof(*flg));
1584     flg->with_font_flag = 1;
1585     node->userData = flg;
1586   }
1587   else {
1588     node->userData = NULL;
1589   }
1590   return chtml30->out;
1591 }
1592
1593
1594 /**
1595  * It is a handler who processes the FONT tag.
1596  *
1597  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1598  *                     destination is specified.
1599  * @param node   [i]   The FONT tag node is specified.
1600  * @return The conversion result is returned.
1601  */
1602 static char *
1603 s_chtml30_end_font_tag(void *pdoc, Node *node)
1604 {
1605   chtml30_t     *chtml30;
1606   Doc           *doc;
1607   request_rec   *r;
1608
1609   chtml30 = GET_CHTML30(pdoc);
1610   doc     = chtml30->doc;
1611   r       = doc->r;
1612
1613   chtml30_flags_t *flg = (chtml30_flags_t *)node->userData;
1614   if (flg && flg->with_font_flag) {
1615     W_L("</font>");
1616   }
1617   if (IS_CSS_ON(chtml30->entryp)) {
1618     chxj_css_pop_prop_list(chtml30->css_prop_stack);
1619   }
1620
1621   return chtml30->out;
1622 }
1623
1624
1625 /**
1626  * It is a handler who processes the FORM tag.
1627  *
1628  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1629  *                     destination is specified.
1630  * @param node   [i]   The FORM tag node is specified.
1631  * @return The conversion result is returned.
1632  */
1633 static char *
1634 s_chtml30_start_form_tag(void *pdoc, Node *node) 
1635 {
1636   chtml30_t   *chtml30;
1637   Doc         *doc;
1638   request_rec *r;
1639   Attr        *attr;
1640   char        *attr_style  = NULL;
1641   char        *attr_color  = NULL;
1642   char        *attr_align  = NULL;
1643   char        *new_hidden_tag = NULL;
1644   char        *attr_method = NULL;
1645   char        *attr_action = NULL;
1646   char        *attr_utn    = NULL;
1647
1648   chtml30 = GET_CHTML30(pdoc);
1649   doc     = chtml30->doc;
1650   r       = doc->r;
1651
1652   /*--------------------------------------------------------------------------*/
1653   /* Get Attributes                                                           */
1654   /*--------------------------------------------------------------------------*/
1655   for (attr = qs_get_attr(doc,node);
1656        attr;
1657        attr = qs_get_next_attr(doc,attr)) {
1658     char *name  = qs_get_attr_name(doc,attr);
1659     char *value = qs_get_attr_value(doc,attr);
1660     switch(*name) {
1661     case 'a':
1662     case 'A':
1663       if (strcasecmp(name, "action") == 0) {
1664         /*--------------------------------------------------------------------*/
1665         /* CHTML 1.0                                                          */
1666         /*--------------------------------------------------------------------*/
1667         attr_action = value;
1668       }
1669       break;
1670
1671     case 'm':
1672     case 'M':
1673       if (strcasecmp(name, "method") == 0) {
1674         /*--------------------------------------------------------------------*/
1675         /* CHTML 1.0                                                          */
1676         /*--------------------------------------------------------------------*/
1677         attr_method = value;
1678       }
1679       break;
1680
1681     case 'u':
1682     case 'U':
1683       if (strcasecmp(name, "utn") == 0) {
1684         /*--------------------------------------------------------------------*/
1685         /* CHTML 3.0                                                          */
1686         /*--------------------------------------------------------------------*/
1687         attr_utn = "";
1688       }
1689       break;
1690
1691     case 's':
1692     case 'S':
1693       if (strcasecmp(name, "style") == 0) {
1694         attr_style = value;
1695       }
1696       break;
1697
1698     default:
1699       break;
1700     }
1701   }
1702   if (IS_CSS_ON(chtml30->entryp)) {
1703     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
1704     if (style) {
1705       css_property_t *text_align_prop = chxj_css_get_property_value(doc, style, "text-align");
1706       css_property_t *color_prop      = chxj_css_get_property_value(doc, style, "color");
1707       css_property_t *cur;
1708       for (cur = text_align_prop->next; cur != text_align_prop; cur = cur->next) {
1709         if (STRCASEEQ('l','L',"left", cur->value)) {
1710           attr_align = apr_pstrdup(doc->pool, "left");
1711         }
1712         else if (STRCASEEQ('c','C',"center",cur->value)) {
1713           attr_align = apr_pstrdup(doc->pool, "center");
1714         }
1715         else if (STRCASEEQ('r','R',"right",cur->value)) {
1716           attr_align = apr_pstrdup(doc->pool, "right");
1717         }
1718       }
1719       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
1720         attr_color = apr_pstrdup(doc->pool, cur->value);
1721       }
1722     }
1723   }
1724
1725   int post_flag = (attr_method && strcasecmp(attr_method, "post") == 0) ? 1 : 0;
1726
1727   W_L("<form");
1728   if (attr_action) {
1729     attr_action = chxj_encoding_parameter(r, attr_action, 0);
1730     attr_action = chxj_add_cookie_parameter(r, attr_action, chtml30->cookie);
1731     char *q;
1732     char *new_query_string = NULL;
1733     q = strchr(attr_action, '?');
1734     if (q) {
1735       new_hidden_tag = chxj_form_action_to_hidden_tag(r, doc->pool, attr_action, 0, post_flag, &new_query_string, CHXJ_TRUE, CHXJ_FALSE, chtml30->entryp);
1736       if (new_hidden_tag || new_query_string) {
1737         *q = 0;
1738       }
1739     }
1740     W_L(" action=\"");
1741     W_V(attr_action);
1742     if (new_query_string) {
1743       W_L("?");
1744       W_V(new_query_string);
1745     }
1746     W_L("\"");
1747   }
1748   if (attr_method) {
1749     W_L(" method=\"");
1750     W_V(attr_method);
1751     W_L("\"");
1752   }
1753   if (attr_utn) {
1754     W_L(" utn");
1755   }
1756   W_L(">");
1757
1758   chtml30_flags_t *flg = (chtml30_flags_t *)apr_palloc(doc->pool, sizeof(chtml30_flags_t));
1759   memset(flg, 0, sizeof(*flg));
1760   if (attr_color) {
1761     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
1762     W_L("<font color=\"");
1763     W_V(attr_color);
1764     W_L("\">");
1765     flg->with_font_flag = 1;
1766   }
1767   if (attr_align) {
1768     W_L("<div align=\"");
1769     W_V(attr_align);
1770     W_L("\">");
1771     flg->with_div_flag = 1;
1772   }
1773   node->userData = flg;
1774
1775   if (new_hidden_tag) {
1776     W_V(new_hidden_tag);
1777   }
1778   return chtml30->out;
1779 }
1780
1781
1782 /**
1783  * It is a handler who processes the FORM tag.
1784  *
1785  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1786  *                     destination is specified.
1787  * @param node   [i]   The FORM tag node is specified.
1788  * @return The conversion result is returned.
1789  */
1790 static char *
1791 s_chtml30_end_form_tag(void *pdoc, Node *node)
1792 {
1793   chtml30_t    *chtml30;
1794   Doc          *doc;
1795
1796   chtml30 = GET_CHTML30(pdoc);
1797   doc     = chtml30->doc;
1798
1799   chtml30_flags_t *flg = (chtml30_flags_t *)node->userData;
1800   if (flg && flg->with_div_flag) {
1801     W_L("</div>");
1802   }
1803   if (flg && flg->with_font_flag) {
1804     W_L("</font>");
1805   }
1806   W_L("</form>");
1807   if (IS_CSS_ON(chtml30->entryp)) {
1808     chxj_css_pop_prop_list(chtml30->css_prop_stack);
1809   }
1810
1811   return chtml30->out;
1812 }
1813
1814
1815 /**
1816  * It is a handler who processes the INPUT tag.
1817  *
1818  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1819  *                     destination is specified.
1820  * @param node   [i]   The INPUT tag node is specified.
1821  * @return The conversion result is returned.
1822  */
1823 static char *
1824 s_chtml30_start_input_tag(void *pdoc, Node *node) 
1825 {
1826   chtml30_t   *chtml30;
1827   Doc         *doc;
1828   request_rec *r;
1829   Attr        *attr;
1830   char        *attr_accesskey  = NULL;
1831   char        *attr_max_length = NULL;
1832   char        *attr_type       = NULL;
1833   char        *attr_name       = NULL;
1834   char        *attr_value      = NULL;
1835   char        *attr_istyle     = NULL;
1836   char        *attr_size       = NULL;
1837   char        *attr_checked    = NULL;
1838   char        *attr_style      = NULL;
1839
1840   chtml30 = GET_CHTML30(pdoc);
1841   doc     = chtml30->doc;
1842   r       = doc->r;
1843
1844   /*--------------------------------------------------------------------------*/
1845   /* Get Attributes                                                           */
1846   /*--------------------------------------------------------------------------*/
1847   for (attr = qs_get_attr(doc,node);
1848        attr;
1849        attr = qs_get_next_attr(doc,attr)) {
1850     char *name  = qs_get_attr_name(doc,attr);
1851     char *value = qs_get_attr_value(doc,attr);
1852     if (STRCASEEQ('t','T',"type",name) && value && *value) {
1853       char *tmp_type = qs_trim_string(doc->buf.pool, value);
1854       if (tmp_type && (STRCASEEQ('t','T',"text",    tmp_type) ||
1855                        STRCASEEQ('p','P',"password",tmp_type) ||
1856                        STRCASEEQ('c','C',"checkbox",tmp_type) ||
1857                        STRCASEEQ('r','R',"radio",   tmp_type) ||
1858                        STRCASEEQ('h','H',"hidden",  tmp_type) ||
1859                        STRCASEEQ('s','S',"submit",  tmp_type) ||
1860                        STRCASEEQ('r','R',"reset",   tmp_type))) {
1861         attr_type = tmp_type;
1862       }
1863     }
1864     else if (STRCASEEQ('n','N',"name",name) && value && *value) {
1865       attr_name = value;
1866     }
1867     else if (STRCASEEQ('v','V',"value",name) && value && *value) {
1868       attr_value = value;
1869     }
1870     else if (STRCASEEQ('i','I',"istyle",name) && value && *value) {
1871       attr_istyle = value;
1872     }
1873     else if (STRCASEEQ('m','M',"maxlength",name) && value && *value) {
1874       attr_max_length = value;
1875     }
1876     else if (STRCASEEQ('c','C',"checked", name)) {
1877       attr_checked = value;
1878     }
1879     else if (STRCASEEQ('a','A',"accesskey", name) && value && *value) {
1880       attr_accesskey = value;
1881     }
1882     else if (STRCASEEQ('s','S',"size", name) && value && *value) {
1883       attr_size = value;
1884     }
1885     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
1886       attr_style = value;
1887     }
1888   }
1889
1890   if (IS_CSS_ON(chtml30->entryp)) {
1891     css_prop_list_t *style = s_chtml30_nopush_and_get_now_style(pdoc, node, attr_style);
1892     if (style) {
1893       css_property_t *wap_input_format = chxj_css_get_property_value(doc, style, "-wap-input-format");
1894       css_property_t *cur;
1895       for (cur = wap_input_format->next; cur != wap_input_format; cur = cur->next) {
1896         if (strcasestr(cur->value, "<ja:n>")) {
1897           attr_istyle = "4";
1898         }
1899         else if (strcasestr(cur->value, "<ja:en>")) {
1900           attr_istyle = "3";
1901         }
1902         else if (strcasestr(cur->value, "<ja:hk>")) {
1903           attr_istyle = "2";
1904         }
1905         else if (strcasestr(cur->value, "<ja:h>")) {
1906           attr_istyle = "1";
1907         }
1908       }
1909     }
1910   }
1911
1912   W_L("<input");
1913   if (attr_type) {
1914     W_L(" type=\"");
1915     W_V(attr_type);
1916     W_L("\"");
1917   }
1918   if (attr_size) {
1919     W_L(" size=\"");
1920     W_V(attr_size);
1921     W_L("\"");
1922   }
1923   if (attr_name) {
1924     W_L(" name=\"");
1925     W_V(attr_name);
1926     W_L("\"");
1927   }
1928   if (attr_value) {
1929     if (attr_type && (STRCASEEQ('s','S',"submit",attr_type) || STRCASEEQ('r','R',"reset",attr_type))) {
1930       apr_size_t value_len = strlen(attr_value);
1931       attr_value = chxj_conv_z2h(r, attr_value, &value_len, chtml30->entryp);
1932     }
1933
1934     W_L(" value=\"");
1935     W_V(chxj_add_slash_to_doublequote(doc->pool, attr_value));
1936     W_L("\"");
1937   }
1938   if (attr_accesskey) {
1939     W_L(" accesskey=\"");
1940     W_V(attr_accesskey);
1941     W_L("\"");
1942   }
1943   if (attr_istyle) {
1944     if (*attr_istyle == '1' || *attr_istyle == '2' || *attr_istyle == '3' || *attr_istyle == '4') {
1945       W_L(" istyle=\"");
1946       W_V(attr_istyle);
1947       W_L("\"");
1948     }
1949   }
1950   /*--------------------------------------------------------------------------*/
1951   /* The figure is default for the password.                                  */
1952   /*--------------------------------------------------------------------------*/
1953   if (attr_max_length) {
1954     if (chxj_chk_numeric(attr_max_length) != 0) {
1955       attr_max_length = apr_psprintf(doc->buf.pool, "0");
1956     }
1957     if (attr_istyle && *attr_istyle == '1') {
1958       char *vv = apr_psprintf(doc->buf.pool, " maxlength=\"%d\"", chxj_atoi(attr_max_length) * 2);
1959       W_V(vv);
1960     }
1961     else {
1962       char *vv = apr_psprintf(doc->buf.pool, " maxlength=\"%d\"", chxj_atoi(attr_max_length));
1963       W_V(vv);
1964     }
1965   }
1966   if (attr_checked) {
1967     W_L(" checked");
1968   }
1969   W_L(">");
1970
1971   return chtml30->out;
1972 }
1973
1974
1975 /**
1976  * It is a handler who processes the INPUT tag.
1977  *
1978  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1979  *                     destination is specified.
1980  * @param node   [i]   The INPUT tag node is specified.
1981  * @return The conversion result is returned.
1982  */
1983 static char *
1984 s_chtml30_end_input_tag(void *pdoc, Node *UNUSED(node))
1985 {
1986   chtml30_t   *chtml30;
1987   Doc         *doc;
1988   request_rec *r;
1989
1990   chtml30 = GET_CHTML30(pdoc);
1991   doc     = chtml30->doc;
1992   r       = doc->r;
1993
1994   return chtml30->out;
1995 }
1996
1997
1998 /**
1999  * It is a handler who processes the CENTER tag.
2000  *
2001  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2002  *                     destination is specified.
2003  * @param node   [i]   The CENTER tag node is specified.
2004  * @return The conversion result is returned.
2005  */
2006 static char *
2007 s_chtml30_start_center_tag(void *pdoc, Node *node)
2008 {
2009   chtml30_t   *chtml30;
2010   Doc         *doc;
2011   Attr        *attr;
2012   char        *attr_style = NULL;
2013   char        *attr_color = NULL;
2014
2015   chtml30 = GET_CHTML30(pdoc);
2016   doc     = chtml30->doc;
2017
2018   for (attr = qs_get_attr(doc,node);
2019        attr;
2020        attr = qs_get_next_attr(doc,attr)) {
2021     char *name  = qs_get_attr_name(doc,attr);
2022     char *value = qs_get_attr_value(doc,attr);
2023     if (STRCASEEQ('s','S',"style",name) && value && *value) {
2024       attr_style = value;
2025     }
2026   }
2027
2028   if (IS_CSS_ON(chtml30->entryp)) {
2029     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
2030     if (style) {
2031       css_property_t *color_prop      = chxj_css_get_property_value(doc, style, "color");
2032       css_property_t *cur;
2033       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
2034         if (cur->value && *cur->value) {
2035           attr_color = apr_pstrdup(doc->pool, cur->value);
2036         }
2037       }
2038     }
2039   }
2040
2041   W_L("<center>");
2042   chtml30_flags_t *flg = (chtml30_flags_t *)apr_palloc(doc->pool, sizeof(chtml30_flags_t));
2043   memset(flg, 0, sizeof(*flg));
2044   if (attr_color) {
2045     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
2046     W_L("<font color=\"");
2047     W_V(attr_color);
2048     W_L("\">");
2049     flg->with_font_flag = 1;
2050   }
2051   node->userData = flg;
2052
2053   return chtml30->out;
2054 }
2055
2056
2057 /**
2058  * It is a handler who processes the CENTER tag.
2059  *
2060  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2061  *                     destination is specified.
2062  * @param node   [i]   The CENTER tag node is specified.
2063  * @return The conversion result is returned.
2064  */
2065 static char *
2066 s_chtml30_end_center_tag(void *pdoc, Node *node)
2067 {
2068   chtml30_t     *chtml30;
2069   Doc           *doc;
2070
2071   chtml30 = GET_CHTML30(pdoc);
2072   doc     = chtml30->doc;
2073
2074   if (IS_CSS_ON(chtml30->entryp)) {
2075     chxj_css_pop_prop_list(chtml30->css_prop_stack);
2076   }
2077   chtml30_flags_t *flg = (chtml30_flags_t *)node->userData;
2078   if (flg && flg->with_font_flag) {
2079     W_L("</font>");
2080   }
2081   W_L("</center>");
2082
2083   return chtml30->out;
2084 }
2085
2086
2087 /**
2088  * It is a handler who processes the HR tag.
2089  *
2090  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2091  *                     destination is specified.
2092  * @param node   [i]   The HR tag node is specified.
2093  * @return The conversion result is returned.
2094  */
2095 static char *
2096 s_chtml30_start_hr_tag(void *pdoc, Node *node) 
2097 {
2098   chtml30_t   *chtml30;
2099   Doc         *doc;
2100   request_rec *r;
2101   Attr        *attr;
2102   char        *attr_align   = NULL;
2103   char        *attr_size    = NULL;
2104   char        *attr_width   = NULL;
2105   char        *attr_noshade = NULL;
2106   char        *attr_style   = NULL;
2107
2108   chtml30 = GET_CHTML30(pdoc);
2109   doc     = chtml30->doc;
2110   r       = doc->r;
2111
2112   for (attr = qs_get_attr(doc,node);
2113        attr; 
2114        attr = qs_get_next_attr(doc,attr)) {
2115     char *name  = qs_get_attr_name (doc,attr);
2116     char *value = qs_get_attr_value(doc,attr);
2117     switch(*name) {
2118     case 'a':
2119     case 'A':
2120       if (strcasecmp(name, "align") == 0) {
2121         /*--------------------------------------------------------------------*/
2122         /* CHTML 1.0                                                          */
2123         /*--------------------------------------------------------------------*/
2124         if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
2125           attr_align = value;
2126         }
2127       }
2128       break;
2129
2130     case 's':
2131     case 'S':
2132       if (strcasecmp(name, "size") == 0) {
2133         /*--------------------------------------------------------------------*/
2134         /* CHTML 1.0                                                          */
2135         /*--------------------------------------------------------------------*/
2136         if (value && *value) {
2137           attr_size = value;
2138         }
2139       }
2140       else if (strcasecmp(name, "style") == 0) {
2141         if (value && *value) {
2142           attr_style = value;
2143         }
2144       }
2145       break;
2146
2147     case 'w':
2148     case 'W':
2149       if (strcasecmp(name, "width") == 0) {
2150         /*--------------------------------------------------------------------*/
2151         /* CHTML 1.0                                                          */
2152         /*--------------------------------------------------------------------*/
2153         if (value && *value) {
2154           attr_width = value;
2155         }
2156       }
2157       break;
2158
2159     case 'n':
2160     case 'N':
2161       if (strcasecmp(name, "noshade") == 0) {
2162         /*--------------------------------------------------------------------*/
2163         /* CHTML 1.0                                                          */
2164         /*--------------------------------------------------------------------*/
2165         attr_noshade = apr_pstrdup(doc->pool, "noshade");
2166       }
2167       break;
2168
2169     case 'c':
2170     case 'C':
2171       if (strcasecmp(name, "color") == 0) {
2172         /*--------------------------------------------------------------------*/
2173         /* CHTML 4.0                                                          */
2174         /*--------------------------------------------------------------------*/
2175         /* ignore */
2176       }
2177       break;
2178
2179     default:
2180       break;
2181     }
2182   }
2183   if (IS_CSS_ON(chtml30->entryp)) {
2184     css_prop_list_t *style = s_chtml30_nopush_and_get_now_style(pdoc, node, attr_style);
2185     if (style) {
2186       css_property_t *border_style_prop = chxj_css_get_property_value(doc, style, "border-style");
2187       css_property_t *height_prop       = chxj_css_get_property_value(doc, style, "height");
2188       css_property_t *width_prop        = chxj_css_get_property_value(doc, style, "width");
2189       css_property_t *cur;
2190       for (cur = border_style_prop->next; cur != border_style_prop; cur = cur->next) {
2191         if (STRCASEEQ('s','S',"solid",cur->value)) {
2192           attr_noshade = "noshade";
2193         }
2194       }
2195       for (cur = height_prop->next; cur != height_prop; cur = cur->next) {
2196         char *tmp = apr_pstrdup(doc->pool, cur->value);
2197         char *tmpp = strstr(tmp, "px");
2198         if (tmpp) { 
2199           *tmpp = 0;
2200           attr_size = apr_pstrdup(doc->pool, tmp);
2201         }
2202       }
2203       for (cur = width_prop->next; cur != width_prop; cur = cur->next) {
2204         char *tmp = apr_pstrdup(doc->pool, cur->value);
2205         char *tmpp = strstr(tmp, "px");
2206         if (tmpp) {
2207           *tmpp = 0;
2208           attr_width = apr_pstrdup(doc->pool, tmp);
2209         }
2210         else {
2211           tmpp = strstr(tmp, "%");
2212           if (tmpp) {
2213             attr_width = apr_pstrdup(doc->pool, tmp);
2214           }
2215         }
2216       }
2217     }
2218   }
2219   W_L("<hr");
2220   if (attr_align) {
2221     W_L(" align=\"");
2222     W_V(attr_align);
2223     W_L("\"");
2224   }
2225   if (attr_size) {
2226     W_L(" size=\"");
2227     W_V(attr_size);
2228     W_L("\"");
2229   }
2230   if (attr_width) {
2231     W_L(" width=\"");
2232     W_V(attr_width);
2233     W_L("\"");
2234   }
2235   if (attr_noshade) {
2236     W_L(" noshade");
2237   }
2238   W_L(">");
2239   return chtml30->out;
2240 }
2241
2242
2243 /**
2244  * It is a handler who processes the HR tag.
2245  *
2246  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2247  *                     destination is specified.
2248  * @param node   [i]   The HR tag node is specified.
2249  * @return The conversion result is returned.
2250  */
2251 static char *
2252 s_chtml30_end_hr_tag(void *pdoc, Node *UNUSED(child)) 
2253 {
2254   chtml30_t *chtml30 = GET_CHTML30(pdoc);
2255   return chtml30->out;
2256 }
2257
2258
2259 /**
2260  * It is a handler who processes the IMG tag.
2261  *
2262  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2263  *                     destination is specified.
2264  * @param node   [i]   The IMG tag node is specified.
2265  * @return The conversion result is returned.
2266  */
2267 static char *
2268 s_chtml30_start_img_tag(void *pdoc, Node *node) 
2269 {
2270   chtml30_t   *chtml30;
2271   Doc         *doc;
2272   request_rec *r;
2273   Attr        *attr;
2274   char        *attr_src    = NULL;
2275   char        *attr_align  = NULL;
2276   char        *attr_style  = NULL;
2277   char        *attr_alt    = NULL;
2278   char        *attr_width  = NULL;
2279   char        *attr_height = NULL;
2280   char        *attr_hspace = NULL;
2281   char        *attr_vspace = NULL;
2282 #ifndef IMG_NOT_CONVERT_FILENAME
2283   device_table *spec;
2284 #endif
2285
2286   chtml30 = GET_CHTML30(pdoc);
2287 #ifndef IMG_NOT_CONVERT_FILENAME
2288   spec    = chtml30->spec;
2289 #endif
2290   doc     = chtml30->doc;
2291   r       = doc->r;
2292
2293   /*--------------------------------------------------------------------------*/
2294   /* Get Attributes                                                           */
2295   /*--------------------------------------------------------------------------*/
2296   for (attr = qs_get_attr(doc,node);
2297        attr;
2298        attr = qs_get_next_attr(doc,attr)) {
2299     char *name  = qs_get_attr_name (doc,attr);
2300     char *value = qs_get_attr_value(doc,attr);
2301     switch(*name) {
2302     case 's':
2303     case 'S':
2304       if (strcasecmp(name, "src") == 0) {
2305         /*--------------------------------------------------------------------*/
2306         /* CHTML 1.0                                                          */
2307         /*--------------------------------------------------------------------*/
2308 #ifdef IMG_NOT_CONVERT_FILENAME
2309       value = chxj_encoding_parameter(r, value, 0);
2310       value = chxj_add_cookie_parameter(r, value, chtml30->cookie);
2311       value = chxj_add_cookie_no_update_parameter(r, value, 0);
2312       value = chxj_img_rewrite_parameter(r,chtml30->conf,value);
2313       attr_src = value;
2314 #else
2315       value = chxj_img_conv(r,spec,value);
2316       value = chxj_encoding_parameter(r, value, 0);
2317       value = chxj_add_cookie_parameter(r, value, chtml30->cookie);
2318       value = chxj_add_cookie_no_update_parameter(r, value, 0);
2319       value = chxj_img_rewrite_parameter(r,chtml30->conf,value);
2320       attr_src = value;
2321 #endif
2322       }
2323       else if (strcasecmp(name,"style") == 0 && value && *value) {
2324         attr_style = value;
2325       }
2326       break;
2327
2328     case 'a':
2329     case 'A':
2330       if (strcasecmp(name, "align" ) == 0) {
2331         /*--------------------------------------------------------------------*/
2332         /* CHTML 1.0                                                          */
2333         /*--------------------------------------------------------------------*/
2334         /*--------------------------------------------------------------------*/
2335         /* CHTML 4.0                                                          */
2336         /*--------------------------------------------------------------------*/
2337         if (value) {
2338           if (STRCASEEQ('t','T',"top",   value) ||
2339               STRCASEEQ('m','M',"middle",value) ||
2340               STRCASEEQ('b','B',"bottom",value) ||
2341               STRCASEEQ('l','L',"left",  value) ||
2342               STRCASEEQ('r','R',"right", value)) {
2343             attr_align = value;
2344           }
2345           else if (STRCASEEQ('c','C',"center",  value)) {
2346             attr_align = apr_pstrdup(doc->pool, "middle");
2347           }
2348         }
2349       }
2350       else if (strcasecmp(name, "alt"   ) == 0 && value && *value) {
2351         /*--------------------------------------------------------------------*/
2352         /* CHTML 1.0                                                          */
2353         /*--------------------------------------------------------------------*/
2354         attr_alt = value;
2355       }
2356       break;
2357
2358     case 'w':
2359     case 'W':
2360       if (strcasecmp(name, "width" ) == 0 && value && *value) {
2361         /*--------------------------------------------------------------------*/
2362         /* CHTML 1.0                                                          */
2363         /*--------------------------------------------------------------------*/
2364         attr_width = value;
2365       }
2366       break;
2367
2368     case 'h':
2369     case 'H':
2370       if (strcasecmp(name, "height") == 0 && value && *value) {
2371         /*--------------------------------------------------------------------*/
2372         /* CHTML 1.0                                                          */
2373         /*--------------------------------------------------------------------*/
2374         attr_height = value;
2375       }
2376       else
2377       if (strcasecmp(name, "hspace") == 0 && value && *value) {
2378         /*--------------------------------------------------------------------*/
2379         /* CHTML 1.0                                                          */
2380         /*--------------------------------------------------------------------*/
2381         attr_hspace = value;
2382       }
2383       break;
2384
2385     case 'v':
2386     case 'V':
2387       if (strcasecmp(name, "vspace") == 0 && value && *value) {
2388         /*--------------------------------------------------------------------*/
2389         /* CHTML 1.0                                                          */
2390         /*--------------------------------------------------------------------*/
2391         attr_vspace = value;
2392       }
2393       break;
2394
2395     default:
2396       break;
2397     }
2398   }
2399
2400   if (IS_CSS_ON(chtml30->entryp)) {
2401     css_prop_list_t *style = s_chtml30_nopush_and_get_now_style(pdoc, node, attr_style);
2402     if (style) {
2403       css_property_t *height_prop = chxj_css_get_property_value(doc, style, "height");
2404       css_property_t *width_prop  = chxj_css_get_property_value(doc, style, "width");
2405       css_property_t *valign_prop = chxj_css_get_property_value(doc, style, "vertical-align");
2406       css_property_t *cur;
2407       for (cur = height_prop->next; cur != height_prop; cur = cur->next) {
2408         attr_height = apr_pstrdup(doc->pool, cur->value);
2409       }
2410       for (cur = width_prop->next; cur != width_prop; cur = cur->next) {
2411         attr_width = apr_pstrdup(doc->pool, cur->value);
2412       }
2413       for (cur = valign_prop->next; cur != valign_prop; cur = cur->next) {
2414         attr_align = apr_pstrdup(doc->pool, cur->value);
2415       }
2416     }
2417   }
2418
2419   W_L("<img");
2420   if (attr_src) {
2421     W_L(" src=\"");
2422     W_V(attr_src);
2423     W_L("\"");
2424   }
2425   if (attr_align) {
2426     W_L(" align=\"");
2427     W_V(attr_align);
2428     W_L("\"");
2429   }
2430   if (attr_alt) {
2431     W_L(" alt=\"");
2432     W_V(attr_alt);
2433     W_L("\"");
2434   }
2435   if (attr_width) {
2436     W_L(" width=\"");
2437     W_V(attr_width);
2438     W_L("\"");
2439   }
2440   if (attr_height) {
2441     W_L(" height=\"");
2442     W_V(attr_height);
2443     W_L("\"");
2444   }
2445   if (attr_hspace) {
2446     W_L(" hspace=\"");
2447     W_V(attr_hspace);
2448     W_L("\"");
2449   }
2450   if (attr_vspace) {
2451     W_L(" vspace=\"");
2452     W_V(attr_vspace);
2453     W_L("\"");
2454   }
2455   W_L(">");
2456   return chtml30->out;
2457 }
2458
2459
2460 /**
2461  * It is a handler who processes the IMG tag.
2462  *
2463  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2464  *                     destination is specified.
2465  * @param node   [i]   The IMG tag node is specified.
2466  * @return The conversion result is returned.
2467  */
2468 static char *
2469 s_chtml30_end_img_tag(void *pdoc, Node *UNUSED(child)) 
2470 {
2471   chtml30_t *chtml30 = GET_CHTML30(pdoc);
2472
2473   return chtml30->out;
2474 }
2475
2476
2477 /**
2478  * It is a handler who processes the SELECT tag.
2479  *
2480  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2481  *                     destination is specified.
2482  * @param node   [i]   The SELECT tag node is specified.
2483  * @return The conversion result is returned.
2484  */
2485 static char *
2486 s_chtml30_start_select_tag(void *pdoc, Node *node)
2487 {
2488   chtml30_t   *chtml30  = GET_CHTML30(pdoc);
2489   Doc         *doc      = chtml30->doc;
2490   char        *size     = NULL;
2491   char        *name     = NULL;
2492   char        *multiple = NULL;
2493   Attr        *attr;
2494   char        *attr_style = NULL;
2495
2496   W_L("<select");
2497   for (attr = qs_get_attr(doc,node);
2498        attr;
2499        attr = qs_get_next_attr(doc,attr)) {
2500     char *nm  = qs_get_attr_name(doc,attr);
2501     char *val = qs_get_attr_value(doc,attr);
2502     if (STRCASEEQ('s','S',"size", nm)) {
2503       /*----------------------------------------------------------------------*/
2504       /* CHTML 1.0 version 2.0                                                */
2505       /*----------------------------------------------------------------------*/
2506       size = apr_pstrdup(doc->buf.pool, val);
2507     }
2508     else if (STRCASEEQ('s','S',"style", nm) && val && *val) {
2509       /*----------------------------------------------------------------------*/
2510       /* CHTML 1.0 version 2.0                                                */
2511       /*----------------------------------------------------------------------*/
2512       attr_style = apr_pstrdup(doc->buf.pool, val);
2513     }
2514     else if (STRCASEEQ('n','N',"name", nm)) {
2515       /*----------------------------------------------------------------------*/
2516       /* CHTML 1.0 version 2.0                                                */
2517       /*----------------------------------------------------------------------*/
2518       name = apr_pstrdup(doc->buf.pool, val);
2519     }
2520     else if (STRCASEEQ('m','M',"multiple", nm)) {
2521       /*----------------------------------------------------------------------*/
2522       /* CHTML 1.0 version 2.0                                                */
2523       /*----------------------------------------------------------------------*/
2524       multiple = apr_pstrdup(doc->buf.pool, val);
2525     }
2526   }
2527   if (size && *size) {
2528     W_L(" size=\"");
2529     W_V(size);
2530     W_L("\"");
2531   }
2532   if (name && *name) {
2533     W_L(" name=\"");
2534     W_V(name);
2535     W_L("\"");
2536   }
2537   if (multiple) {
2538     W_L(" multiple");
2539   }
2540   W_L(">");
2541   if (IS_CSS_ON(chtml30->entryp)) {
2542     s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
2543   }
2544   return chtml30->out;
2545 }
2546
2547
2548 /**
2549  * It is a handler who processes the SELECT tag.
2550  *
2551  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2552  *                     destination is specified.
2553  * @param node   [i]   The SELECT tag node is specified.
2554  * @return The conversion result is returned.
2555  */
2556 static char *
2557 s_chtml30_end_select_tag(void *pdoc, Node *UNUSED(child))
2558 {
2559   chtml30_t    *chtml30 = GET_CHTML30(pdoc);
2560   Doc          *doc   = chtml30->doc;
2561
2562   W_L("</select>");
2563   if (IS_CSS_ON(chtml30->entryp)) {
2564     chxj_css_pop_prop_list(chtml30->css_prop_stack);
2565   }
2566
2567   return chtml30->out;
2568 }
2569
2570
2571 /**
2572  * It is a handler who processes the OPTION tag.
2573  *
2574  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2575  *                     destination is specified.
2576  * @param node   [i]   The OPTION tag node is specified.
2577  * @return The conversion result is returned.
2578  */
2579 static char *
2580 s_chtml30_start_option_tag(void *pdoc, Node *node)
2581 {
2582   Attr        *attr;
2583   chtml30_t   *chtml30;
2584   Doc         *doc;
2585   request_rec *r;
2586   char        *selected;
2587   char        *value;
2588   char        *attr_style = NULL;
2589
2590   chtml30    = GET_CHTML30(pdoc);
2591   doc        = chtml30->doc;
2592   r          = doc->r;
2593   selected   = NULL;
2594   value      = NULL;
2595
2596   W_L("<option");
2597   for (attr = qs_get_attr(doc,node);
2598        attr;
2599        attr = qs_get_next_attr(doc,attr)) {
2600     char *nm  = qs_get_attr_name(doc,attr);
2601     char *val = qs_get_attr_value(doc,attr);
2602     if (STRCASEEQ('s','S',"selected", nm)) {
2603       /*----------------------------------------------------------------------*/
2604       /* CHTML 1.0 version 2.0                                                */
2605       /*----------------------------------------------------------------------*/
2606       selected = apr_pstrdup(doc->buf.pool, val);
2607     }
2608     else if (STRCASEEQ('s','S',"style", nm) && val && *val) {
2609       /*----------------------------------------------------------------------*/
2610       /* CHTML 1.0 version 2.0                                                */
2611       /*----------------------------------------------------------------------*/
2612       attr_style = apr_pstrdup(doc->buf.pool, val);
2613     }
2614     else if (STRCASEEQ('v','V',"value", nm)) {
2615       /*----------------------------------------------------------------------*/
2616       /* CHTML 1.0 version 2.0                                                */
2617       /*----------------------------------------------------------------------*/
2618       value = apr_pstrdup(doc->buf.pool, val);
2619     }
2620   }
2621   if (value) {
2622     W_L(" value=\"");
2623     W_V(value);
2624     W_L("\"");
2625   }
2626   if (selected) {
2627     W_L(" selected");
2628   }
2629   W_L(">");
2630   if (IS_CSS_ON(chtml30->entryp)) {
2631     s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
2632   }
2633   return chtml30->out;
2634 }
2635
2636
2637 /**
2638  * It is a handler who processes the OPTION tag.
2639  *
2640  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2641  *                     destination is specified.
2642  * @param node   [i]   The OPTION tag node is specified.
2643  * @return The conversion result is returned.
2644  */
2645 static char *
2646 s_chtml30_end_option_tag(void *pdoc, Node *UNUSED(child))
2647 {
2648   chtml30_t *chtml30 = GET_CHTML30(pdoc);
2649
2650   /* Don't close */
2651   if (IS_CSS_ON(chtml30->entryp)) {
2652     chxj_css_pop_prop_list(chtml30->css_prop_stack);
2653   }
2654
2655   return chtml30->out;
2656 }
2657
2658
2659 /**
2660  * It is a handler who processes the DIV tag.
2661  *
2662  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2663  *                     destination is specified.
2664  * @param node   [i]   The DIV tag node is specified.
2665  * @return The conversion result is returned.
2666  */
2667 static char *
2668 s_chtml30_start_div_tag(void *pdoc, Node *node)
2669 {
2670   chtml30_t   *chtml30;
2671   Doc         *doc;
2672   request_rec *r;
2673   Attr        *attr;
2674   char        *attr_style             = NULL;
2675   char        *attr_align             = NULL;
2676   char        *attr_display           = NULL;
2677   char        *attr_decoration        = NULL;
2678   char        *attr_wap_marquee_style = NULL;
2679   char        *attr_wap_marquee_dir   = NULL;
2680   char        *attr_wap_marquee_loop  = NULL;
2681   char        *attr_color             = NULL;
2682   char        *attr_bgcolor           = NULL;
2683
2684   chtml30 = GET_CHTML30(pdoc);
2685   doc     = chtml30->doc;
2686   r       = doc->r;
2687
2688   for (attr = qs_get_attr(doc,node);
2689        attr;
2690        attr = qs_get_next_attr(doc,attr)) {
2691     char *nm  = qs_get_attr_name(doc,attr);
2692     char *val = qs_get_attr_value(doc,attr);
2693     if (STRCASEEQ('a','A', "align", nm)) {
2694       /*----------------------------------------------------------------------*/
2695       /* CHTML 1.0 (W3C version 3.2)                                          */
2696       /*----------------------------------------------------------------------*/
2697       if (val && (STRCASEEQ('l','L',"left",val) || STRCASEEQ('r','R',"right",val) || STRCASEEQ('c','C',"center",val))) {
2698         attr_align = apr_pstrdup(doc->buf.pool, val);
2699       }
2700     }
2701     else if (STRCASEEQ('s','S',"style",nm) && val && *val) {
2702       attr_style = apr_pstrdup(doc->buf.pool, val);
2703     }
2704   }
2705
2706   if (IS_CSS_ON(chtml30->entryp)) {
2707     css_prop_list_t *style = s_chtml30_nopush_and_get_now_style(pdoc, node, attr_style);
2708     if (style) {
2709       css_property_t *display_prop           = chxj_css_get_property_value(doc, style, "display");
2710       css_property_t *text_decoration_prop   = chxj_css_get_property_value(doc, style, "text-decoration");
2711       css_property_t *color_prop             = chxj_css_get_property_value(doc, style, "color");
2712       css_property_t *text_align_prop        = chxj_css_get_property_value(doc, style, "text-align");
2713       css_property_t *background_color_prop  = chxj_css_get_property_value(doc, style, "background-color");
2714       css_property_t *background_prop        = chxj_css_get_property_value(doc, style, "background");
2715
2716       css_property_t *cur;
2717       for (cur = display_prop->next; cur != display_prop; cur = cur->next) {
2718         if (strcasecmp("-wap-marquee", cur->value) == 0) {
2719           attr_display = apr_pstrdup(doc->pool, cur->value);
2720         }
2721       }
2722       for (cur = text_decoration_prop->next; cur != text_decoration_prop; cur = cur->next) {
2723         if (STRCASEEQ('b','B',"blink", cur->value)) {
2724           attr_decoration = apr_pstrdup(doc->pool, cur->value);
2725         }
2726       }
2727       for (cur = background_color_prop->next; cur != background_color_prop; cur = cur->next) {
2728         attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
2729         attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
2730       }
2731       for (cur = background_prop->next; cur != background_prop; cur = cur->next) {
2732         char *ss = strchr(cur->value, '#');
2733         if (!ss) {
2734           ss = strstr(cur->value, "rgb");
2735         }
2736         if (ss) {
2737           attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
2738           attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
2739         }
2740       }
2741       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
2742         attr_color = apr_pstrdup(doc->pool, cur->value);
2743         attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
2744       }
2745       for (cur = text_align_prop->next; cur != text_align_prop; cur = cur->next) {
2746         attr_align = apr_pstrdup(doc->pool, cur->value);
2747       }
2748       if (attr_display) {
2749         css_property_t *wap_marquee_style_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-style");
2750         css_property_t *wap_marquee_dir_prop   = chxj_css_get_property_value(doc, style, "-wap-marquee-dir");
2751         css_property_t *wap_marquee_loop_prop  = chxj_css_get_property_value(doc, style, "-wap-marquee-loop");
2752         for (cur = wap_marquee_style_prop->next; cur != wap_marquee_style_prop; cur = cur->next) {
2753           if (STRCASEEQ('s','S',"scroll", cur->value) || STRCASEEQ('s','S',"slide",cur->value) || STRCASEEQ('a','A',"alternate",cur->value)) {
2754             attr_wap_marquee_style = apr_pstrdup(doc->pool, cur->value);
2755           }
2756         }
2757         for (cur = wap_marquee_dir_prop->next; cur != wap_marquee_dir_prop; cur = cur->next) {
2758           if (STRCASEEQ('l','L',"ltr",cur->value)) {
2759             attr_wap_marquee_dir = apr_pstrdup(doc->pool, "right");
2760           }
2761           else if (STRCASEEQ('r','R',"rtl",cur->value)) {
2762             attr_wap_marquee_dir = apr_pstrdup(doc->pool, "left");
2763           }
2764         }
2765         for (cur = wap_marquee_loop_prop->next; cur != wap_marquee_loop_prop; cur = cur->next) {
2766           if (STRCASEEQ('i','I',"infinite",cur->value)) {
2767             attr_wap_marquee_loop = apr_pstrdup(doc->pool, "16");
2768           }
2769           else {
2770             attr_wap_marquee_loop = apr_pstrdup(doc->pool, cur->value);
2771           }
2772         }
2773       }
2774     }
2775   }  
2776   chtml30_flags_t *flg = (chtml30_flags_t *)apr_palloc(doc->pool, sizeof(chtml30_flags_t));
2777   memset(flg, 0, sizeof(*flg));
2778   if (attr_align) {
2779     W_L("<div");
2780     W_L(" align=\"");
2781     W_V(attr_align);
2782     W_L("\"");
2783     W_L(">");
2784     flg->with_div_flag = 1;
2785   }
2786   else {
2787     W_L("<div>");
2788     flg->with_div_flag = 1;
2789   }
2790   if (attr_color) {
2791     if (attr_bgcolor && (STRCASEEQ('w','W',"white",attr_color) || STRCASEEQ('#','#',"#ffffff",attr_color))) {
2792       /* nothing */
2793     }
2794     else {
2795       W_L("<font color=\"");
2796       W_V(attr_color);
2797       W_L("\">");
2798       flg->with_font_flag = 1;
2799     }
2800   }
2801   if (attr_decoration) {
2802     W_L("<blink>");
2803     flg->with_blink_flag = 1;
2804   }
2805   if (attr_display) {
2806     W_L("<marquee");
2807     if (attr_wap_marquee_style) {
2808       W_L(" behavior=\"");
2809       W_V(attr_wap_marquee_style);
2810       W_L("\"");
2811     }
2812     if (attr_wap_marquee_dir) {
2813       W_L(" direction=\"");
2814       W_V(attr_wap_marquee_dir);
2815       W_L("\"");
2816     }
2817     if (attr_wap_marquee_loop) {
2818       W_L(" loop=\"");
2819       W_V(attr_wap_marquee_loop);
2820       W_L("\"");
2821     }
2822     W_L(">");
2823     flg->with_marquee_flag = 1;
2824   }
2825   node->userData = flg;
2826
2827   return chtml30->out;
2828 }
2829
2830
2831 /**
2832  * It is a handler who processes the DIV tag.
2833  *
2834  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2835  *                     destination is specified.
2836  * @param node   [i]   The DIV tag node is specified.
2837  * @return The conversion result is returned.
2838  */
2839 static char *
2840 s_chtml30_end_div_tag(void *pdoc, Node *node)
2841 {
2842   chtml30_t    *chtml30 = GET_CHTML30(pdoc);
2843   Doc          *doc     = chtml30->doc;
2844
2845   chtml30_flags_t *flg = node->userData;
2846   if (flg && flg->with_marquee_flag) {
2847     W_L("</marquee>");
2848   }
2849   if (flg && flg->with_blink_flag) {
2850     W_L("</blink>");
2851   }
2852   if (flg && flg->with_font_flag) {
2853     W_L("</font>");
2854   }
2855   if (flg && flg->with_div_flag) {
2856     W_L("</div>");
2857   }
2858   if (IS_CSS_ON(chtml30->entryp)) {
2859     chxj_css_pop_prop_list(chtml30->css_prop_stack);
2860   }
2861   node->userData = NULL;
2862
2863   return chtml30->out;
2864 }
2865
2866
2867 /**
2868  * It is a handler who processes the UL tag.
2869  *
2870  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2871  *                     destination is specified.
2872  * @param node   [i]   The UL tag node is specified.
2873  * @return The conversion result is returned.
2874  */
2875 static char *
2876 s_chtml30_start_ul_tag(void *pdoc, Node *node)
2877 {
2878   chtml30_t   *chtml30 = GET_CHTML30(pdoc);
2879   Doc         *doc     = chtml30->doc;
2880   Attr        *attr;
2881   char        *attr_style = NULL;
2882
2883   for (attr = qs_get_attr(doc,node);
2884        attr;
2885        attr = qs_get_next_attr(doc,attr)) {
2886     char *nm  = qs_get_attr_name(doc,attr);
2887     char *val = qs_get_attr_value(doc,attr);
2888     if (val && STRCASEEQ('s','S',"style", nm)) {
2889       attr_style = val;
2890     }
2891   }
2892
2893   if (IS_CSS_ON(chtml30->entryp)) {
2894     s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
2895   }
2896
2897   W_L("<ul>");
2898
2899   return chtml30->out;
2900 }
2901
2902
2903 /**
2904  * It is a handler who processes the UL tag.
2905  *
2906  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2907  *                     destination is specified.
2908  * @param node   [i]   The UL tag node is specified.
2909  * @return The conversion result is returned.
2910  */
2911 static char *
2912 s_chtml30_end_ul_tag(void *pdoc, Node *UNUSED(child)) 
2913 {
2914   chtml30_t     *chtml30 = GET_CHTML30(pdoc);
2915   Doc           *doc     = chtml30->doc;
2916
2917   if (IS_CSS_ON(chtml30->entryp)) {
2918     chxj_css_pop_prop_list(chtml30->css_prop_stack);
2919   }
2920   W_L("</ul>");
2921
2922   return chtml30->out;
2923 }
2924
2925
2926 /**
2927  * It is a handler who processes the PRE tag.
2928  *
2929  * @param pdoc  [i/o] The pointer to the XHTML structure at the output
2930  *                     destination is specified.
2931  * @param node   [i]   The PRE tag node is specified.
2932  * @return The conversion result is returned.
2933  */
2934 static char *
2935 s_chtml30_start_pre_tag(void *pdoc, Node *node)
2936 {
2937   chtml30_t *chtml30 = GET_CHTML30(pdoc);
2938   Doc       *doc     = chtml30->doc;
2939   Attr        *attr;
2940   char        *attr_style = NULL;
2941
2942   for (attr = qs_get_attr(doc,node);
2943        attr;
2944        attr = qs_get_next_attr(doc,attr)) {
2945     char *nm  = qs_get_attr_name(doc,attr);
2946     char *val = qs_get_attr_value(doc,attr);
2947     if (val && STRCASEEQ('s','S',"style", nm)) {
2948       attr_style = val;
2949     }
2950   }
2951
2952   if (IS_CSS_ON(chtml30->entryp)) {
2953     s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
2954   }
2955
2956   chtml30->pre_flag++;
2957   W_L("<pre>");
2958
2959   return chtml30->out;
2960 }
2961
2962
2963 /**
2964  * It is a handler who processes the PRE tag.
2965  *
2966  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2967  *                     destination is specified.
2968  * @param node   [i]   The PRE tag node is specified.
2969  * @return The conversion result is returned.
2970  */
2971 static char *
2972 s_chtml30_end_pre_tag(void *pdoc, Node *UNUSED(child)) 
2973 {
2974   chtml30_t     *chtml30 = GET_CHTML30(pdoc);
2975   Doc           *doc     = chtml30->doc;
2976
2977   W_L("</pre>");
2978   chtml30->pre_flag--;
2979   if (IS_CSS_ON(chtml30->entryp)) {
2980     chxj_css_pop_prop_list(chtml30->css_prop_stack);
2981   }
2982
2983   return chtml30->out;
2984 }
2985
2986
2987 /**
2988  * It is a handler who processes the P tag.
2989  *
2990  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2991  *                     destination is specified.
2992  * @param node   [i]   The P tag node is specified.
2993  * @return The conversion result is returned.
2994  */
2995 static char *
2996 s_chtml30_start_p_tag(void *pdoc, Node *node) 
2997 {
2998   chtml30_t   *chtml30;
2999   Doc         *doc;
3000   request_rec *r;
3001   Attr        *attr;
3002   char        *attr_align = NULL;
3003   char        *attr_style = NULL;
3004   char        *attr_color = NULL;
3005   char        *attr_blink = NULL;
3006
3007   chtml30 = GET_CHTML30(pdoc);
3008   doc     = chtml30->doc;
3009   r       = doc->r;
3010
3011   for (attr = qs_get_attr(doc,node);
3012        attr;
3013        attr = qs_get_next_attr(doc,attr)) {
3014     char *nm  = qs_get_attr_name(doc,attr);
3015     char *val = qs_get_attr_value(doc,attr);
3016     if (STRCASEEQ('a','A',"align", nm)) {
3017       /*----------------------------------------------------------------------*/
3018       /* CHTML 1.0 (W3C version 3.2)                                          */
3019       /*----------------------------------------------------------------------*/
3020       if (val && (STRCASEEQ('l','L',"left",val) || STRCASEEQ('r','R',"right",val) || STRCASEEQ('c','C',"center",val))) {
3021         attr_align = apr_pstrdup(doc->buf.pool, val);
3022         break;
3023       }
3024     }
3025     else if (STRCASEEQ('s','S',"style", nm) && val && *val) {
3026       attr_style = apr_pstrdup(doc->buf.pool, val);
3027     }
3028   }
3029   if (IS_CSS_ON(chtml30->entryp)) {
3030     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
3031     if (style) {
3032       css_property_t *text_align_prop = chxj_css_get_property_value(doc, style, "text-align");
3033       css_property_t *color_prop      = chxj_css_get_property_value(doc, style, "color");
3034       css_property_t *text_deco_prop  = chxj_css_get_property_value(doc, style, "text-decoration");
3035       css_property_t *cur;
3036       for (cur = text_align_prop->next; cur != text_align_prop; cur = cur->next) {
3037         if (STRCASEEQ('l','L',"left",cur->value)) {
3038           attr_align = apr_pstrdup(doc->pool, "left");
3039         }
3040         else if (STRCASEEQ('c','C',"center",cur->value)) {
3041           attr_align = apr_pstrdup(doc->pool, "center");
3042         }
3043         else if (STRCASEEQ('r','R',"right",cur->value)) {
3044           attr_align = apr_pstrdup(doc->pool, "right");
3045         }
3046       }
3047       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
3048         if (cur->value && *cur->value) {
3049           attr_color = apr_pstrdup(doc->pool, cur->value);
3050         }
3051       }
3052       for (cur = text_deco_prop->next; cur != text_deco_prop; cur = cur->next) {
3053         if (cur->value && *cur->value && STRCASEEQ('b','B',"blink",cur->value)) {
3054           attr_blink = apr_pstrdup(doc->pool, cur->value);
3055         }
3056       }
3057     }
3058   }
3059   W_L("<p");
3060   if (attr_align) {
3061     W_L(" align=\"");
3062     W_V(attr_align);
3063     W_L("\"");
3064   }
3065   W_L(">");
3066
3067   chtml30_flags_t *flg = (chtml30_flags_t *)apr_palloc(doc->pool, sizeof(chtml30_flags_t));
3068   memset(flg, 0, sizeof(*flg));
3069   if (attr_color) {
3070     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
3071     W_L("<font color=\"");
3072     W_V(attr_color);
3073     W_L("\">");
3074     flg->with_font_flag = 1;
3075   }
3076   if (attr_blink) {
3077     W_L("<blink>");
3078     flg->with_blink_flag = 1;
3079   }
3080   node->userData = (void *)flg;
3081
3082   return chtml30->out;
3083 }
3084
3085
3086 /**
3087  * It is a handler who processes the P tag.
3088  *
3089  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3090  *                     destination is specified.
3091  * @param node   [i]   The P tag node is specified.
3092  * @return The conversion result is returned.
3093  */
3094 static char *
3095 s_chtml30_end_p_tag(void *pdoc, Node *node)
3096 {
3097   chtml30_t   *chtml30;
3098   Doc         *doc;
3099
3100   chtml30 = GET_CHTML30(pdoc);
3101   doc     = chtml30->doc;
3102
3103   chtml30_flags_t *flg = (chtml30_flags_t *)node->userData;
3104   if (flg->with_font_flag) {
3105     W_L("</font>");
3106   }
3107   if (flg->with_blink_flag) {
3108     W_L("</blink>");
3109   }
3110   W_L("</p>");
3111   if (IS_CSS_ON(chtml30->entryp)) {
3112     chxj_css_pop_prop_list(chtml30->css_prop_stack);
3113   }
3114
3115   return chtml30->out;
3116 }
3117
3118
3119 /**
3120  * It is a handler who processes the OL tag.
3121  *
3122  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3123  *                     destination is specified.
3124  * @param node   [i]   The OL tag node is specified.
3125  * @return The conversion result is returned.
3126  */
3127 static char *
3128 s_chtml30_start_ol_tag(void *pdoc, Node *node)
3129 {
3130   chtml30_t   *chtml30;
3131   Doc         *doc;
3132   request_rec *r;
3133   Attr        *attr;
3134   char        *attr_style = NULL;
3135   char        *attr_start = NULL;
3136   char        *attr_type = NULL;
3137
3138   chtml30 = GET_CHTML30(pdoc);
3139   doc     = chtml30->doc;
3140   r       = doc->r;
3141
3142   /*--------------------------------------------------------------------------*/
3143   /* Get Attributes                                                           */
3144   /*--------------------------------------------------------------------------*/
3145   for (attr = qs_get_attr(doc,node);
3146        attr;
3147        attr = qs_get_next_attr(doc,attr)) {
3148     char *name = qs_get_attr_name(doc,attr);
3149     char *value = qs_get_attr_value(doc,attr);
3150     if (STRCASEEQ('t','T',"type",name) && value && (*value == '1' || *value == 'a' || *value == 'A')) {
3151       attr_type = value;
3152     }
3153     else if (STRCASEEQ('s','S',"start",name) && value && *value) {
3154       attr_start = value;
3155     }
3156     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
3157       attr_style = value;
3158     }
3159   }
3160   if (IS_CSS_ON(chtml30->entryp)) {
3161     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
3162     if (style) {
3163       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type");
3164       css_property_t *cur;
3165       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3166         if (STRCASEEQ('d','D',"decimal", cur->value)) {
3167           attr_type = apr_pstrdup(doc->pool, "1");
3168         }
3169         else if (STRCASEEQ('u','U',"upper-alpha", cur->value)) {
3170           attr_type = apr_pstrdup(doc->pool, "A");
3171         }
3172         else if (STRCASEEQ('l','L',"lower-alpha", cur->value)) {
3173           attr_type = apr_pstrdup(doc->pool, "a");
3174         }
3175       }
3176     }
3177   }
3178   W_L("<ol");
3179   if (attr_type) {
3180     W_L(" type=\"");
3181     W_V(attr_type);
3182     W_L("\"");
3183   }
3184   if (attr_start) {
3185     W_L(" start=\"");
3186     W_V(attr_start);
3187     W_L("\"");
3188   }
3189   W_L(">");
3190
3191   return chtml30->out;
3192 }
3193
3194
3195 /**
3196  * It is a handler who processes the OL tag.
3197  *
3198  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3199  *                     destination is specified.
3200  * @param node   [i]   The OL tag node is specified.
3201  * @return The conversion result is returned.
3202  */
3203 static char *
3204 s_chtml30_end_ol_tag(void *pdoc, Node *UNUSED(node)) 
3205 {
3206   chtml30_t *chtml30 = GET_CHTML30(pdoc);
3207   Doc       *doc     = chtml30->doc;
3208
3209   W_L("</ol>");
3210   if (IS_CSS_ON(chtml30->entryp)) {
3211     chxj_css_pop_prop_list(chtml30->css_prop_stack);
3212   }
3213
3214   return chtml30->out;
3215 }
3216
3217
3218 /**
3219  * It is a handler who processes the LI tag.
3220  *
3221  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3222  *                     destination is specified.
3223  * @param node   [i]   The LI tag node is specified.
3224  * @return The conversion result is returned.
3225  */
3226 static char *
3227 s_chtml30_start_li_tag(void *pdoc, Node *node) 
3228 {
3229   chtml30_t   *chtml30 = GET_CHTML30(pdoc);
3230   Doc         *doc     = chtml30->doc;
3231   Attr        *attr;
3232   char        *attr_type = NULL;
3233   char        *attr_value = NULL;
3234   char        *attr_style = NULL;
3235   /*--------------------------------------------------------------------------*/
3236   /* Get Attributes                                                           */
3237   /*--------------------------------------------------------------------------*/
3238   for (attr = qs_get_attr(doc,node);
3239        attr;
3240        attr = qs_get_next_attr(doc,attr)) {
3241     char *name = qs_get_attr_name(doc,attr);
3242     char *value = qs_get_attr_value(doc,attr);
3243     if (STRCASEEQ('t','T',"type",name) && value && (*value == '1' || *value == 'a' || *value == 'A')) {
3244       attr_type = value;
3245     }
3246     else if (STRCASEEQ('v','V',"value", name) && value && *value) {
3247       attr_value = value;
3248     }
3249     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
3250       attr_style = value;
3251     }
3252   }
3253   if (IS_CSS_ON(chtml30->entryp)) {
3254     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
3255     if (style) {
3256       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type");
3257       css_property_t *cur;
3258       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3259         if (STRCASEEQ('d','D',"decimal", cur->value)) {
3260           attr_type = apr_pstrdup(doc->pool, "1");
3261         }
3262         else if (STRCASEEQ('u','U',"upper-alpha", cur->value)) {
3263           attr_type = apr_pstrdup(doc->pool, "A");
3264         }
3265         else if (STRCASEEQ('l','L',"lower-alpha", cur->value)) {
3266           attr_type = apr_pstrdup(doc->pool, "a");
3267         }
3268       }
3269     }
3270   }
3271
3272   W_L("<li");
3273   if (attr_type) {
3274     W_L(" type=\"");
3275     W_V(attr_type);
3276     W_L("\"");
3277   }
3278   if (attr_value) {
3279     W_L(" value=\"");
3280     W_V(attr_value);
3281     W_L("\"");
3282   }
3283   W_L(">");
3284   return chtml30->out;
3285 }
3286
3287
3288 /**
3289  * It is a handler who processes the LI tag.
3290  *
3291  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3292  *                     destination is specified.
3293  * @param node   [i]   The LI tag node is specified.
3294  * @return The conversion result is returned.
3295  */
3296 static char *
3297 s_chtml30_end_li_tag(void *pdoc, Node *UNUSED(child)) 
3298 {
3299   chtml30_t *chtml30 = GET_CHTML30(pdoc);
3300
3301   if (IS_CSS_ON(chtml30->entryp)) {
3302     chxj_css_pop_prop_list(chtml30->css_prop_stack);
3303   }
3304   return chtml30->out;
3305 }
3306
3307
3308 /**
3309  * It is a handler who processes the H1 tag.
3310  *
3311  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3312  *                     destination is specified.
3313  * @param node   [i]   The H1 tag node is specified.
3314  * @return The conversion result is returned.
3315  */
3316 static char *
3317 s_chtml30_start_h1_tag(void *pdoc, Node *node)
3318 {
3319   chtml30_t   *chtml30;
3320   Doc         *doc;
3321   request_rec *r;
3322   Attr        *attr;
3323   char        *attr_style = NULL;
3324   char        *attr_align = NULL;
3325
3326
3327   chtml30 = GET_CHTML30(pdoc);
3328   doc     = chtml30->doc;
3329   r       = doc->r;
3330
3331   for (attr = qs_get_attr(doc,node);
3332        attr;
3333        attr = qs_get_next_attr(doc,attr)) {
3334     char *name  = qs_get_attr_name(doc,attr);
3335     char *value = qs_get_attr_value(doc,attr);
3336     if (STRCASEEQ('a','A',"align", name)) {
3337       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3338         attr_align = value;
3339       }
3340     }
3341     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3342       attr_style = value;
3343     }
3344   }
3345   if (IS_CSS_ON(chtml30->entryp)) {
3346     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
3347     if (style) {
3348       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3349       css_property_t *cur;
3350       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3351         if (STRCASEEQ('l','L',"left", cur->value)) {
3352           attr_align = apr_pstrdup(doc->pool, "left");
3353         }
3354         else if (STRCASEEQ('c','C',"center",cur->value)) {
3355           attr_align = apr_pstrdup(doc->pool, "center");
3356         }
3357         else if (STRCASEEQ('r','R',"right",cur->value)) {
3358           attr_align = apr_pstrdup(doc->pool, "right");
3359         }
3360       }
3361     }
3362   }
3363   W_L("<h1");
3364   if (attr_align) {
3365     W_L(" align=\"");
3366     W_V(attr_align);
3367     W_L("\"");
3368   }
3369   W_L(">");
3370
3371   return chtml30->out;
3372 }
3373
3374
3375 /**
3376  * It is a handler who processes the H1 tag.
3377  *
3378  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3379  *                     destination is specified.
3380  * @param node   [i]   The H1 tag node is specified.
3381  * @return The conversion result is returned.
3382  */
3383 static char *
3384 s_chtml30_end_h1_tag(void *pdoc, Node *UNUSED(child)) 
3385 {
3386   chtml30_t   *chtml30;
3387   Doc         *doc;
3388
3389   chtml30 = GET_CHTML30(pdoc);
3390   doc     = chtml30->doc;
3391
3392   W_L("</h1>");
3393   if (IS_CSS_ON(chtml30->entryp)) {
3394     chxj_css_pop_prop_list(chtml30->css_prop_stack);
3395   }
3396
3397   return chtml30->out;
3398 }
3399
3400
3401 /**
3402  * It is a handler who processes the H2 tag.
3403  *
3404  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3405  *                     destination is specified.
3406  * @param node   [i]   The H2 tag node is specified.
3407  * @return The conversion result is returned.
3408  */
3409 static char *
3410 s_chtml30_start_h2_tag(void *pdoc, Node *node)
3411 {
3412   chtml30_t   *chtml30;
3413   Doc         *doc;
3414   request_rec *r;
3415   Attr        *attr;
3416   char        *attr_style = NULL;
3417   char        *attr_align = NULL;
3418
3419   chtml30 = GET_CHTML30(pdoc);
3420   doc     = chtml30->doc;
3421   r       = doc->r;
3422
3423   for (attr = qs_get_attr(doc,node);
3424        attr;
3425        attr = qs_get_next_attr(doc,attr)) {
3426     char *name  = qs_get_attr_name(doc,attr);
3427     char *value = qs_get_attr_value(doc,attr);
3428     if (STRCASEEQ('a','A',"align", name)) {
3429       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3430         attr_align = value;
3431       }
3432     }
3433     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3434       attr_style = value;
3435     }
3436   }
3437   if (IS_CSS_ON(chtml30->entryp)) {
3438     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
3439     if (style) {
3440       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3441       css_property_t *cur;
3442       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3443         if (STRCASEEQ('l','L',"left", cur->value)) {
3444           attr_align = apr_pstrdup(doc->pool, "left");
3445         }
3446         else if (STRCASEEQ('c','C',"center",cur->value)) {
3447           attr_align = apr_pstrdup(doc->pool, "center");
3448         }
3449         else if (STRCASEEQ('r','R',"right",cur->value)) {
3450           attr_align = apr_pstrdup(doc->pool, "right");
3451         }
3452       }
3453     }
3454   }
3455   W_L("<h2");
3456   if (attr_align) {
3457     W_L(" align=\"");
3458     W_V(attr_align);
3459     W_L("\"");
3460   }
3461   W_L(">");
3462
3463   return chtml30->out;
3464 }
3465
3466
3467 /**
3468  * It is a handler who processes the H2 tag.
3469  *
3470  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3471  *                     destination is specified.
3472  * @param node   [i]   The H2 tag node is specified.
3473  * @return The conversion result is returned.
3474  */
3475 static char *
3476 s_chtml30_end_h2_tag(void *pdoc, Node *UNUSED(child)) 
3477 {
3478   chtml30_t   *chtml30 = GET_CHTML30(pdoc);
3479   Doc         *doc     = chtml30->doc;
3480
3481   W_L("</h2>");
3482   if (IS_CSS_ON(chtml30->entryp)) {
3483     chxj_css_pop_prop_list(chtml30->css_prop_stack);
3484   }
3485
3486   return chtml30->out;
3487 }
3488
3489
3490 /**
3491  * It is a handler who processes the H3 tag.
3492  *
3493  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3494  *                     destination is specified.
3495  * @param node   [i]   The H3 tag node is specified.
3496  * @return The conversion result is returned.
3497  */
3498 static char *
3499 s_chtml30_start_h3_tag(void *pdoc, Node *node)
3500 {
3501   chtml30_t   *chtml30;
3502   Doc         *doc;
3503   request_rec *r;
3504   Attr        *attr;
3505   char        *attr_style = NULL;
3506   char        *attr_align = NULL;
3507
3508   chtml30 = GET_CHTML30(pdoc);
3509   doc     = chtml30->doc;
3510   r       = doc->r;
3511
3512   for (attr = qs_get_attr(doc,node);
3513        attr;
3514        attr = qs_get_next_attr(doc,attr)) {
3515     char *name  = qs_get_attr_name(doc,attr);
3516     char *value = qs_get_attr_value(doc,attr);
3517     if (STRCASEEQ('a','A',"align", name)) {
3518       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3519         attr_align = value;
3520       }
3521     }
3522     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3523       attr_style = value;
3524     }
3525   }
3526   if (IS_CSS_ON(chtml30->entryp)) {
3527     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
3528     if (style) {
3529       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3530       css_property_t *cur;
3531       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3532         if (STRCASEEQ('l','L',"left", cur->value)) {
3533           attr_align = apr_pstrdup(doc->pool, "left");
3534         }
3535         else if (STRCASEEQ('c','C',"center",cur->value)) {
3536           attr_align = apr_pstrdup(doc->pool, "center");
3537         }
3538         else if (STRCASEEQ('r','R',"right",cur->value)) {
3539           attr_align = apr_pstrdup(doc->pool, "right");
3540         }
3541       }
3542     }
3543   }
3544   W_L("<h3");
3545   if (attr_align) {
3546     W_L(" align=\"");
3547     W_V(attr_align);
3548     W_L("\"");
3549   }
3550   W_L(">");
3551
3552   return chtml30->out;
3553 }
3554
3555
3556 /**
3557  * It is a handler who processes the H3 tag.
3558  *
3559  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3560  *                     destination is specified.
3561  * @param node   [i]   The H3 tag node is specified.
3562  * @return The conversion result is returned.
3563  */
3564 static char *
3565 s_chtml30_end_h3_tag(void *pdoc, Node *UNUSED(child))
3566 {
3567   chtml30_t *chtml30 = GET_CHTML30(pdoc);
3568   Doc       *doc   = chtml30->doc;
3569
3570   W_L("</h3>");
3571   if (IS_CSS_ON(chtml30->entryp)) {
3572     chxj_css_pop_prop_list(chtml30->css_prop_stack);
3573   }
3574
3575   return chtml30->out;
3576 }
3577
3578
3579 /**
3580  * It is a handler who processes the H4 tag.
3581  *
3582  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3583  *                     destination is specified.
3584  * @param node   [i]   The H4 tag node is specified.
3585  * @return The conversion result is returned.
3586  */
3587 static char *
3588 s_chtml30_start_h4_tag(void *pdoc, Node *node)
3589 {
3590   chtml30_t   *chtml30;
3591   Doc         *doc;
3592   request_rec *r;
3593   Attr        *attr;
3594   char        *attr_style = NULL;
3595   char        *attr_align = NULL;
3596
3597   chtml30 = GET_CHTML30(pdoc);
3598   doc     = chtml30->doc;
3599   r       = doc->r;
3600
3601   for (attr = qs_get_attr(doc,node);
3602        attr;
3603        attr = qs_get_next_attr(doc,attr)) {
3604     char *name  = qs_get_attr_name(doc,attr);
3605     char *value = qs_get_attr_value(doc,attr);
3606     if (STRCASEEQ('a','A',"align", name)) {
3607       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3608         attr_align = value;
3609       }
3610     }
3611     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3612       attr_style = value;
3613     }
3614   }
3615   if (IS_CSS_ON(chtml30->entryp)) {
3616     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
3617     if (style) {
3618       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3619       css_property_t *cur;
3620       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3621         if (STRCASEEQ('l','L',"left", cur->value)) {
3622           attr_align = apr_pstrdup(doc->pool, "left");
3623         }
3624         else if (STRCASEEQ('c','C',"center",cur->value)) {
3625           attr_align = apr_pstrdup(doc->pool, "center");
3626         }
3627         else if (STRCASEEQ('r','R',"right",cur->value)) {
3628           attr_align = apr_pstrdup(doc->pool, "right");
3629         }
3630       }
3631     }
3632   }
3633   W_L("<h4");
3634   if (attr_align) {
3635     W_L(" align=\"");
3636     W_V(attr_align);
3637     W_L("\"");
3638   }
3639   W_L(">");
3640
3641   return chtml30->out;
3642 }
3643
3644
3645 /**
3646  * It is a handler who processes the H4 tag.
3647  *
3648  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3649  *                     destination is specified.
3650  * @param node   [i]   The H4 tag node is specified.
3651  * @return The conversion result is returned.
3652  */
3653 static char *
3654 s_chtml30_end_h4_tag(void *pdoc, Node *UNUSED(child)) 
3655 {
3656   chtml30_t *chtml30 = GET_CHTML30(pdoc);
3657   Doc       *doc     = chtml30->doc;
3658
3659   W_L("</h4>");
3660   if (IS_CSS_ON(chtml30->entryp)) {
3661     chxj_css_pop_prop_list(chtml30->css_prop_stack);
3662   }
3663
3664   return chtml30->out;
3665 }
3666
3667
3668 /**
3669  * It is a handler who processes the H5 tag.
3670  *
3671  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3672  *                     destination is specified.
3673  * @param node   [i]   The H5 tag node is specified.
3674  * @return The conversion result is returned.
3675  */
3676 static char *
3677 s_chtml30_start_h5_tag(void *pdoc, Node *node)
3678 {
3679   chtml30_t   *chtml30;
3680   Doc         *doc;
3681   request_rec *r;
3682   Attr        *attr;
3683   char        *attr_style = NULL;
3684   char        *attr_align = NULL;
3685
3686   chtml30 = GET_CHTML30(pdoc);
3687   doc     = chtml30->doc;
3688   r       = doc->r;
3689
3690   for (attr = qs_get_attr(doc,node);
3691        attr;
3692        attr = qs_get_next_attr(doc,attr)) {
3693     char *name  = qs_get_attr_name(doc,attr);
3694     char *value = qs_get_attr_value(doc,attr);
3695     if (STRCASEEQ('a','A',"align", name)) {
3696       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3697         attr_align = value;
3698       }
3699     }
3700     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3701       attr_style = value;
3702     }
3703   }
3704   if (IS_CSS_ON(chtml30->entryp)) {
3705     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
3706     if (style) {
3707       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3708       css_property_t *cur;
3709       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3710         if (STRCASEEQ('l','L',"left", cur->value)) {
3711           attr_align = apr_pstrdup(doc->pool, "left");
3712         }
3713         else if (STRCASEEQ('c','C',"center",cur->value)) {
3714           attr_align = apr_pstrdup(doc->pool, "center");
3715         }
3716         else if (STRCASEEQ('r','R',"right",cur->value)) {
3717           attr_align = apr_pstrdup(doc->pool, "right");
3718         }
3719       }
3720     }
3721   }
3722   W_L("<h5");
3723   if (attr_align) {
3724     W_L(" align=\"");
3725     W_V(attr_align);
3726     W_L("\"");
3727   }
3728   W_L(">");
3729
3730   return chtml30->out;
3731 }
3732
3733
3734 /**
3735  * It is a handler who processes the H5 tag.
3736  *
3737  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3738  *                     destination is specified.
3739  * @param node   [i]   The H5 tag node is specified.
3740  * @return The conversion result is returned.
3741  */
3742 static char *
3743 s_chtml30_end_h5_tag(void *pdoc, Node *UNUSED(child)) 
3744 {
3745   chtml30_t *chtml30 = GET_CHTML30(pdoc);
3746   Doc       *doc     = chtml30->doc;
3747
3748   W_L("</h5>");
3749   if (IS_CSS_ON(chtml30->entryp)) {
3750     chxj_css_pop_prop_list(chtml30->css_prop_stack);
3751   }
3752
3753   return chtml30->out;
3754 }
3755
3756
3757 /**
3758  * It is a handler who processes the H6 tag.
3759  *
3760  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3761  *                     destination is specified.
3762  * @param node   [i]   The H6 tag node is specified.
3763  * @return The conversion result is returned.
3764  */
3765 static char *
3766 s_chtml30_start_h6_tag(void *pdoc, Node *node)
3767 {
3768   chtml30_t   *chtml30;
3769   Doc         *doc;
3770   request_rec *r;
3771   Attr        *attr;
3772   char        *attr_style = NULL;
3773   char        *attr_align = NULL;
3774
3775   chtml30 = GET_CHTML30(pdoc);
3776   doc     = chtml30->doc;
3777   r       = doc->r;
3778
3779   for (attr = qs_get_attr(doc,node);
3780        attr;
3781        attr = qs_get_next_attr(doc,attr)) {
3782     char *name  = qs_get_attr_name(doc,attr);
3783     char *value = qs_get_attr_value(doc,attr);
3784     if (STRCASEEQ('a','A',"align", name)) {
3785       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3786         attr_align = value;
3787       }
3788     }
3789     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3790       attr_style = value;
3791     }
3792   }
3793   if (IS_CSS_ON(chtml30->entryp)) {
3794     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
3795     if (style) {
3796       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3797       css_property_t *cur;
3798       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3799         if (STRCASEEQ('l','L',"left", cur->value)) {
3800           attr_align = apr_pstrdup(doc->pool, "left");
3801         }
3802         else if (STRCASEEQ('c','C',"center",cur->value)) {
3803           attr_align = apr_pstrdup(doc->pool, "center");
3804         }
3805         else if (STRCASEEQ('r','R',"right",cur->value)) {
3806           attr_align = apr_pstrdup(doc->pool, "right");
3807         }
3808       }
3809     }
3810   }
3811   W_L("<h6");
3812   if (attr_align) {
3813     W_L(" align=\"");
3814     W_V(attr_align);
3815     W_L("\"");
3816   }
3817   W_L(">");
3818
3819   return chtml30->out;
3820 }
3821
3822
3823 /**
3824  * It is a handler who processes the H6 tag.
3825  *
3826  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3827  *                     destination is specified.
3828  * @param node   [i]   The H6 tag node is specified.
3829  * @return The conversion result is returned.
3830  */
3831 static char *
3832 s_chtml30_end_h6_tag(void *pdoc, Node *UNUSED(child)) 
3833 {
3834   chtml30_t *chtml30 = GET_CHTML30(pdoc);
3835   Doc       *doc     = chtml30->doc;
3836
3837   W_L("</h6>");
3838   if (IS_CSS_ON(chtml30->entryp)) {
3839     chxj_css_pop_prop_list(chtml30->css_prop_stack);
3840   }
3841
3842   return chtml30->out;
3843 }
3844
3845
3846 /**
3847  * It is a handler who processes the TEXTARE tag.
3848  *
3849  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3850  *                     destination is specified.
3851  * @param node   [i]   The TEXTAREA tag node is specified.
3852  * @return The conversion result is returned.
3853  */
3854 static char *
3855 s_chtml30_start_textarea_tag(void *pdoc, Node *node) 
3856 {
3857   chtml30_t   *chtml30;
3858   Doc         *doc;
3859   request_rec *r;
3860   Attr        *attr;
3861   char        *attr_accesskey = NULL;
3862   char        *attr_name      = NULL;
3863   char        *attr_rows      = NULL;
3864   char        *attr_cols      = NULL;
3865   char        *attr_istyle    = NULL;
3866   char        *attr_style     = NULL;
3867
3868   chtml30 = GET_CHTML30(pdoc);
3869   doc     = chtml30->doc;
3870   r       = doc->r;
3871
3872   chtml30->textarea_flag++;
3873
3874   for (attr = qs_get_attr(doc,node);
3875        attr;
3876        attr = qs_get_next_attr(doc,attr)) {
3877     char *name  = qs_get_attr_name(doc,attr);
3878     char *value = qs_get_attr_value(doc,attr);
3879     if (STRCASEEQ('a','A',"accesskey",name) && value && *value != 0) {
3880       attr_accesskey = value;
3881     }
3882     else if (STRCASEEQ('i','I',"istyle", name) && value && (*value == '1' || *value == '2' || *value == '3' || *value == '4')) {
3883       attr_istyle = value;
3884     }
3885     else if (STRCASEEQ('n','N',"name", name) && value && *value) {
3886       attr_name = value;
3887     }
3888     else if (STRCASEEQ('r','R',"rows", name) && value && *value) {
3889       attr_rows = value;
3890     }
3891     else if (STRCASEEQ('c','C',"cols", name) && value && *value) {
3892       attr_cols = value;
3893     }
3894     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
3895       attr_style = value;
3896     }
3897   }
3898
3899   if (IS_CSS_ON(chtml30->entryp)) {
3900     css_prop_list_t *style = s_chtml30_nopush_and_get_now_style(pdoc, node, attr_style);
3901     if (style) {
3902       css_property_t *wap_input_format = chxj_css_get_property_value(doc, style, "-wap-input-format");
3903       css_property_t *cur;
3904       for (cur = wap_input_format->next; cur != wap_input_format; cur = cur->next) {
3905         if (strcasestr(cur->value, "<ja:n>")) {
3906           attr_istyle = "4";
3907         }
3908         else if (strcasestr(cur->value, "<ja:en>")) {
3909           attr_istyle = "3";
3910         }
3911         else if (strcasestr(cur->value, "<ja:hk>")) {
3912           attr_istyle = "2";
3913         }
3914         else if (strcasestr(cur->value, "<ja:h>")) {
3915           attr_istyle = "1";
3916         }
3917       }
3918     }
3919   }  
3920
3921   W_L("<textarea");
3922   if (attr_accesskey) {
3923     W_L(" accesskey=\"");
3924     W_V(attr_accesskey);
3925     W_L("\"");
3926   }
3927   if (attr_name) {
3928     W_L(" name=\"");
3929     W_V(attr_name);
3930     W_L("\"");
3931   }
3932   if (attr_rows) {
3933     W_L(" rows=\"");
3934     W_V(attr_rows);
3935     W_L("\"");
3936   }
3937   if (attr_cols) {
3938     W_L(" cols=\"");
3939     W_V(attr_cols);
3940     W_L("\"");
3941   }
3942   if (attr_istyle) {
3943     W_L(" istyle=\"");
3944     W_V(attr_istyle);
3945     W_L("\"");
3946   }
3947   W_L(">");
3948   return chtml30->out;
3949 }
3950
3951
3952 /**
3953  * It is a handler who processes the TEXTAREA tag.
3954  *
3955  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3956  *                     destination is specified.
3957  * @param node   [i]   The TEXTAREA tag node is specified.
3958  * @return The conversion result is returned.
3959  */
3960 static char *
3961 s_chtml30_end_textarea_tag(void *pdoc, Node *UNUSED(child)) 
3962 {
3963   chtml30_t *chtml30 = GET_CHTML30(pdoc);
3964   Doc       *doc     = chtml30->doc;
3965
3966   W_L("</textarea>");
3967   chtml30->textarea_flag--;
3968
3969   return chtml30->out;
3970 }
3971
3972
3973 static char *
3974 s_chtml30_chxjif_tag(void *pdoc, Node *node)
3975 {
3976   Node        *child;
3977   chtml30_t   *chtml30;
3978   Doc         *doc;
3979   request_rec *r;
3980
3981   chtml30 = GET_CHTML30(pdoc);
3982   doc     = chtml30->doc;
3983   r       = doc->r;
3984
3985   for (child = qs_get_child_node(doc, node);
3986        child;
3987        child = qs_get_next_node(doc, child)) {
3988     W_V(child->otext);
3989     s_chtml30_chxjif_tag(chtml30, child);
3990   }
3991
3992   return NULL;
3993 }
3994
3995
3996 static char *
3997 s_chtml30_text_tag(void *pdoc, Node *child)
3998 {
3999   chtml30_t   *chtml30;
4000   Doc         *doc;
4001   request_rec *r;
4002
4003   char        *textval;
4004   char        *tmp;
4005   char        *tdst;
4006   char        one_byte[2];
4007   int         ii;
4008   int         tdst_len;
4009   apr_size_t  z2h_input_len;
4010
4011   chtml30 = GET_CHTML30(pdoc);
4012   doc     = chtml30->doc;
4013   r       = doc->r;
4014   
4015   textval = qs_get_node_value(doc,child);
4016   if (strlen(textval) == 0) {
4017     return chtml30->out;
4018   }
4019   
4020   tmp = apr_palloc(r->pool, qs_get_node_size(doc,child)+1);
4021   memset(tmp, 0, qs_get_node_size(doc,child)+1);
4022   
4023   tdst     = qs_alloc_zero_byte_string(doc->buf.pool);
4024   memset(one_byte, 0, sizeof(one_byte));
4025   tdst_len = 0;
4026   
4027   for (ii=0; ii<qs_get_node_size(doc,child); ii++) {
4028     char* out;
4029     int rtn = s_chtml30_search_emoji(chtml30, &textval[ii], &out, child);
4030     if (rtn) {
4031       tdst = qs_out_apr_pstrcat(r, tdst, out, &tdst_len);
4032       ii+=(rtn - 1);
4033       continue;
4034     }
4035   
4036     if (is_sjis_kanji(textval[ii])) {
4037       one_byte[0] = textval[ii+0];
4038       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
4039       one_byte[0] = textval[ii+1];
4040       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
4041       ii++;
4042     }
4043     else if (chtml30->pre_flag) {
4044       one_byte[0] = textval[ii+0];
4045       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
4046     }
4047     else if (chtml30->textarea_flag) {
4048       one_byte[0] = textval[ii+0];
4049       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
4050     }
4051     else if (textval[ii] != '\r' && textval[ii] != '\n') {
4052       one_byte[0] = textval[ii+0];
4053       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
4054     }
4055   }
4056   z2h_input_len = strlen(tdst);
4057   tdst = chxj_conv_z2h(r, tdst, &z2h_input_len, chtml30->entryp);
4058
4059   W_V(tdst);
4060   return chtml30->out;
4061 }
4062
4063
4064 /**
4065  * It is a handler who processes the BLOCKQUOTE tag.
4066  *
4067  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4068  *                     destination is specified.
4069  * @param node   [i]   The BLOCKQUOTE tag node is specified.
4070  * @return The conversion result is returned.
4071  */
4072 static char *
4073 s_chtml30_start_blockquote_tag(void *pdoc, Node *node)
4074 {
4075   chtml30_t *chtml30;
4076   Doc       *doc;
4077   Attr      *attr;
4078   char      *attr_style = NULL;
4079   char      *attr_color = NULL;
4080
4081   chtml30 = GET_CHTML30(pdoc);
4082   doc     = chtml30->doc;
4083   for (attr = qs_get_attr(doc,node);
4084        attr;
4085        attr = qs_get_next_attr(doc,attr)) {
4086     char *nm  = qs_get_attr_name(doc,attr);
4087     char *val = qs_get_attr_value(doc,attr);
4088     if (val && STRCASEEQ('s','S',"style", nm)) {
4089       attr_style = val;
4090     }
4091   }
4092   if (IS_CSS_ON(chtml30->entryp)) {
4093     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
4094     if (style) {
4095       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
4096       css_property_t *cur;
4097       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
4098         if (cur->value && *cur->value) {
4099           attr_color = apr_pstrdup(doc->pool, cur->value);
4100         }
4101       }
4102     }
4103   }
4104   W_L("<blockquote>");
4105   chtml30_flags_t *flg = (chtml30_flags_t *)apr_palloc(doc->pool, sizeof(chtml30_flags_t));
4106   memset(flg, 0, sizeof(*flg));
4107   if (attr_color) {
4108     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
4109     W_L("<font color=\"");
4110     W_V(attr_color);
4111     W_L("\">");
4112     flg->with_font_flag = 1;
4113   }
4114   node->userData = (void *)flg;
4115   return chtml30->out;
4116 }
4117
4118
4119 /**
4120  * It is a handler who processes the BLOCKQUOTE tag.
4121  *
4122  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4123  *                     destination is specified.
4124  * @param node   [i]   The BLOCKQUOTE tag node is specified.
4125  * @return The conversion result is returned.
4126  */
4127 static char *
4128 s_chtml30_end_blockquote_tag(void *pdoc, Node *node)
4129 {
4130   chtml30_t *chtml30 = GET_CHTML30(pdoc);
4131   Doc       *doc     = chtml30->doc;
4132   chtml30_flags_t *flg = (chtml30_flags_t *)node->userData;
4133   if (flg && flg->with_font_flag) {
4134     W_L("</font>");
4135   }
4136   W_L("</blockquote>");
4137   if (IS_CSS_ON(chtml30->entryp)) {
4138     chxj_css_pop_prop_list(chtml30->css_prop_stack);
4139   }
4140   return chtml30->out;
4141 }
4142
4143
4144 /**
4145  * It is a handler who processes the DIR tag.
4146  *
4147  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4148  *                     destination is specified.
4149  * @param node   [i]   The DIR tag node is specified.
4150  * @return The conversion result is returned.
4151  */
4152 static char *
4153 s_chtml30_start_dir_tag(void *pdoc, Node *node)
4154 {
4155   chtml30_t *chtml30;
4156   Doc       *doc;
4157   Attr      *attr;
4158   char      *attr_style = NULL;
4159   char      *attr_color = NULL;
4160
4161   chtml30 = GET_CHTML30(pdoc);
4162   doc     = chtml30->doc;
4163   for (attr = qs_get_attr(doc,node);
4164        attr;
4165        attr = qs_get_next_attr(doc,attr)) {
4166     char *nm  = qs_get_attr_name(doc,attr);
4167     char *val = qs_get_attr_value(doc,attr);
4168     if (val && STRCASEEQ('s','S',"style", nm)) {
4169       attr_style = val;
4170     }
4171   }
4172   if (IS_CSS_ON(chtml30->entryp)) {
4173     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
4174     if (style) {
4175       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
4176       css_property_t *cur;
4177       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
4178         if (cur->value && *cur->value) {
4179           attr_color = apr_pstrdup(doc->pool, cur->value);
4180         }
4181       }
4182     }
4183   }
4184   W_L("<dir>");
4185   chtml30_flags_t *flg = (chtml30_flags_t *)apr_palloc(doc->pool, sizeof(chtml30_flags_t));
4186   memset(flg, 0, sizeof(*flg));
4187   if (attr_color) {
4188     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
4189     W_L("<font color=\"");
4190     W_V(attr_color);
4191     W_L("\">");
4192     flg->with_font_flag = 1;
4193   }
4194   node->userData = (void *)flg;
4195   return chtml30->out;
4196 }
4197
4198
4199 /**
4200  * It is a handler who processes the DIR tag.
4201  *
4202  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4203  *                     destination is specified.
4204  * @param node   [i]   The DIR tag node is specified.
4205  * @return The conversion result is returned.
4206  */
4207 static char *
4208 s_chtml30_end_dir_tag(void *pdoc, Node *node)
4209 {
4210   CHTML30_END_OF_CLOSE_TAG_WITH_FONT_TAG("</dir>");
4211 }
4212
4213
4214 /**
4215  * It is a handler who processes the DL tag.
4216  *
4217  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4218  *                     destination is specified.
4219  * @param node   [i]   The DL tag node is specified.
4220  * @return The conversion result is returned.
4221  */
4222 static char *
4223 s_chtml30_start_dl_tag(void *pdoc, Node *node)
4224 {
4225   CHTML30_START_OF_TAG_WITH_CSS_FONT_COLOR("<dl>");
4226 }
4227
4228
4229 /**
4230  * It is a handler who processes the DL tag.
4231  *
4232  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4233  *                     destination is specified.
4234  * @param node   [i]   The DL tag node is specified.
4235  * @return The conversion result is returned.
4236  */
4237 static char *
4238 s_chtml30_end_dl_tag(void *pdoc, Node *node)
4239 {
4240   CHTML30_END_OF_CLOSE_TAG_WITH_FONT_TAG("</dl>");
4241 }
4242
4243
4244 /**
4245  * It is a handler who processes the DT tag.
4246  *
4247  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4248  *                     destination is specified.
4249  * @param node   [i]   The DT tag node is specified.
4250  * @return The conversion result is returned.
4251  */
4252 static char *
4253 s_chtml30_start_dt_tag(void *pdoc, Node *node)
4254 {
4255   CHTML30_START_OF_TAG_WITH_CSS_FONT_COLOR("<dt>");
4256 }
4257
4258
4259 /**
4260  * It is a handler who processes the DT tag.
4261  *
4262  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4263  *                     destination is specified.
4264  * @param node   [i]   The DT tag node is specified.
4265  * @return The conversion result is returned.
4266  */
4267 static char *
4268 s_chtml30_end_dt_tag(void *pdoc, Node *node)
4269 {
4270   CHTML30_END_OF_NO_CLOSE_TAG_WITH_FONT_TAG();
4271 }
4272
4273
4274 /**
4275  * It is a handler who processes the DD tag.
4276  *
4277  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4278  *                     destination is specified.
4279  * @param node   [i]   The DD tag node is specified.
4280  * @return The conversion result is returned.
4281  */
4282 static char *
4283 s_chtml30_start_dd_tag(void *pdoc, Node *node)
4284 {
4285   CHTML30_START_OF_TAG_WITH_CSS_FONT_COLOR("<dd>");
4286 }
4287
4288
4289 /**
4290  * It is a handler who processes the DD tag.
4291  *
4292  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4293  *                     destination is specified.
4294  * @param node   [i]   The DD tag node is specified.
4295  * @return The conversion result is returned.
4296  */
4297 static char *
4298 s_chtml30_end_dd_tag(void *pdoc, Node *node)
4299 {
4300   CHTML30_END_OF_NO_CLOSE_TAG_WITH_FONT_TAG();
4301 }
4302
4303
4304 /**
4305  * It is a handler who processes the MARQUEE tag.
4306  *
4307  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4308  *                     destination is specified.
4309  * @param node   [i]   The MARQUEE tag node is specified.
4310  * @return The conversion result is returned.
4311  */
4312 static char *
4313 s_chtml30_start_marquee_tag(void *pdoc, Node *node)
4314 {
4315   chtml30_t *chtml30 = GET_CHTML30(pdoc);
4316   Doc       *doc = chtml30->doc;
4317   Attr      *attr;
4318   char      *attr_direction = NULL;
4319   char      *attr_behavior  = NULL;
4320   char      *attr_loop      = NULL;
4321   char      *attr_style     = NULL;
4322   char      *attr_color     = NULL;
4323   /*--------------------------------------------------------------------------*/
4324   /* Get Attributes                                                           */
4325   /*--------------------------------------------------------------------------*/
4326   for (attr = qs_get_attr(doc,node);
4327        attr;
4328        attr = qs_get_next_attr(doc,attr)) {
4329     char *name   = qs_get_attr_name(doc,attr);
4330     char *value  = qs_get_attr_value(doc,attr);
4331     if (STRCASEEQ('d','D',"direction", name)) {
4332       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value))) {
4333         attr_direction = value;
4334       }
4335     }
4336     else if (STRCASEEQ('b','B',"behavior",name)) {
4337       if (value && (STRCASEEQ('s','S',"scroll",value) || STRCASEEQ('s','S',"slide",value) || STRCASEEQ('a','A',"alternate",value))) {
4338         attr_behavior = value;
4339       }
4340     }
4341     else if (STRCASEEQ('l','L',"loop",name)) {
4342       if (value && *value) {
4343         attr_loop = value;
4344       }
4345     }
4346     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
4347       attr_style = value;
4348     }
4349   }
4350   if (IS_CSS_ON(chtml30->entryp)) {
4351     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
4352     if (style) {
4353       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
4354       css_property_t *direction_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-dir");
4355       css_property_t *style_prop     = chxj_css_get_property_value(doc, style, "-wap-marquee-style");
4356       css_property_t *loop_prop      = chxj_css_get_property_value(doc, style, "-wap-marquee-loop");
4357       css_property_t *cur;
4358       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
4359         if (cur->value && *cur->value) {
4360           attr_color = apr_pstrdup(doc->pool, cur->value);
4361         }
4362       }
4363       for (cur = style_prop->next; cur != style_prop; cur = cur->next) {
4364         if (cur->value && *cur->value) {
4365           attr_behavior = apr_pstrdup(doc->pool, cur->value);
4366         }
4367       }
4368       for (cur = loop_prop->next; cur != loop_prop; cur = cur->next) {
4369         if (cur->value && *cur->value) {
4370           attr_loop = apr_pstrdup(doc->pool, cur->value);
4371           if (STRCASEEQ('i','I',"infinite",attr_loop)) {
4372             attr_loop = "16";
4373           }
4374         }
4375       }
4376       for (cur = direction_prop->next; cur != direction_prop; cur = cur->next) {
4377         if (cur->value && *cur->value) {
4378           if (STRCASEEQ('l','L',"ltr",cur->value)) {
4379             attr_direction = "right";
4380           }
4381           else if (STRCASEEQ('r','R',"rtl",cur->value)) {
4382             attr_direction = "left";
4383           }
4384         }
4385       }
4386     }
4387   }
4388   W_L("<marquee");
4389   if (attr_direction) {
4390     W_L(" direction=\"");
4391     W_V(attr_direction);
4392     W_L("\"");
4393   }
4394   if (attr_behavior) {
4395     W_L(" behavior=\"");
4396     W_V(attr_behavior);
4397     W_L("\"");
4398   }
4399   if (attr_loop) {
4400     W_L(" loop=\"");
4401     W_V(attr_loop);
4402     W_L("\"");
4403   }
4404   W_L(">");
4405
4406   chtml30_flags_t *flg = (chtml30_flags_t *)apr_palloc(doc->pool, sizeof(chtml30_flags_t));
4407   memset(flg, 0, sizeof(*flg));
4408   if (attr_color) {
4409     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
4410     W_L("<font color=\"");
4411     W_V(attr_color);
4412     W_L("\">");
4413     flg->with_font_flag = 1;
4414   }
4415   node->userData = (void *)flg;
4416   return chtml30->out;
4417 }
4418
4419
4420 /**
4421  * It is a handler who processes the MARQUEE tag.
4422  *
4423  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4424  *                     destination is specified.
4425  * @param node   [i]   The MARQUEE tag node is specified.
4426  * @return The conversion result is returned.
4427  */
4428 static char *
4429 s_chtml30_end_marquee_tag(void *pdoc, Node *node)
4430 {
4431   chtml30_t *chtml30 = GET_CHTML30(pdoc);
4432   Doc       *doc     = chtml30->doc;
4433   chtml30_flags_t *flg = (chtml30_flags_t *)node->userData;
4434   if (flg && flg->with_font_flag) {
4435     W_L("</font>");
4436   }
4437   W_L("</marquee>");
4438   if (IS_CSS_ON(chtml30->entryp)) {
4439     chxj_css_pop_prop_list(chtml30->css_prop_stack);
4440   }
4441   return chtml30->out;
4442 }
4443
4444
4445 /**
4446  * It is a handler who processes the BLINK tag.
4447  *
4448  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4449  *                     destination is specified.
4450  * @param node   [i]   The BLINK tag node is specified.
4451  * @return The conversion result is returned.
4452  */
4453 static char *
4454 s_chtml30_start_blink_tag(void *pdoc, Node *node)
4455 {
4456   CHTML30_START_OF_TAG_WITH_CSS_FONT_COLOR("<blink>");
4457 }
4458
4459
4460 /**
4461  * It is a handler who processes the BLINK tag.
4462  *
4463  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4464  *                     destination is specified.
4465  * @param node   [i]   The BLINK tag node is specified.
4466  * @return The conversion result is returned.
4467  */
4468 static char *
4469 s_chtml30_end_blink_tag(void *pdoc, Node *node)
4470 {
4471   CHTML30_END_OF_CLOSE_TAG_WITH_FONT_TAG("</blink>");
4472 }
4473
4474
4475 /**
4476  * It is a handler who processes the MENU tag.
4477  *
4478  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4479  *                     destination is specified.
4480  * @param node   [i]   The MENU tag node is specified.
4481  * @return The conversion result is returned.
4482  */
4483 static char *
4484 s_chtml30_start_menu_tag(void *pdoc, Node *node)
4485 {
4486   CHTML30_START_OF_TAG_WITH_CSS_FONT_COLOR("<menu>");
4487 }
4488
4489
4490 /**
4491  * It is a handler who processes the MENU tag.
4492  *
4493  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4494  *                     destination is specified.
4495  * @param node   [i]   The MENU tag node is specified.
4496  * @return The conversion result is returned.
4497  */
4498 static char *
4499 s_chtml30_end_menu_tag(void *pdoc, Node *node)
4500 {
4501   CHTML30_END_OF_CLOSE_TAG_WITH_FONT_TAG("</menu>");
4502 }
4503
4504
4505 /**
4506  * It is a handler who processes the PLAINTEXT tag.
4507  *
4508  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4509  *                     destination is specified.
4510  * @param node   [i]   The PLAINTEXT tag node is specified.
4511  * @return The conversion result is returned.
4512  */
4513 static char *
4514 s_chtml30_start_plaintext_tag(void *pdoc, Node *node)
4515 {
4516   chtml30_t *chtml30 = GET_CHTML30(pdoc);
4517   Doc       *doc     = chtml30->doc;
4518   W_L("<plaintext>");
4519   s_chtml30_start_plaintext_tag_inner(pdoc,node);
4520   return chtml30->out;
4521 }
4522
4523 static char *
4524 s_chtml30_start_plaintext_tag_inner(void *pdoc, Node *node)
4525 {
4526   chtml30_t *chtml30 = GET_CHTML30(pdoc);
4527   Doc       *doc     = chtml30->doc;
4528   Node      *child;
4529   for (child = qs_get_child_node(doc, node);
4530        child;
4531        child = qs_get_next_node(doc, child)) {
4532     W_V(child->otext);
4533     s_chtml30_start_plaintext_tag_inner(pdoc, child);
4534   }
4535   return chtml30->out;
4536 }
4537
4538
4539 /**
4540  * It is a handler who processes the PLAINTEXT tag.
4541  *
4542  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4543  *                     destination is specified.
4544  * @param node   [i]   The PLAINTEXT tag node is specified.
4545  * @return The conversion result is returned.
4546  */
4547 static char *
4548 s_chtml30_end_plaintext_tag(void *pdoc, Node *UNUSED(child))
4549 {
4550   chtml30_t *chtml30 = GET_CHTML30(pdoc);
4551   return chtml30->out;
4552 }
4553
4554
4555 /**
4556  *  * It is handler who processes the New Line Code.
4557  *   */
4558 static char *
4559 s_chtml30_newline_mark(void *pdoc, Node *UNUSED(node))
4560 {
4561   chtml30_t *chtml30 = GET_CHTML30(pdoc);
4562   Doc *doc = chtml30->doc;
4563   W_NLCODE();
4564   return chtml30->out;
4565 }
4566
4567
4568 /**
4569  * It is a handler who processes the LINK tag.
4570  *
4571  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4572  *                     destination is specified.
4573  * @param node   [i]   The LINK tag node is specified.
4574  * @return The conversion result is returned.
4575  */
4576 static char *
4577 s_chtml30_link_tag(void *pdoc, Node *node)
4578 {
4579   chtml30_t     *chtml30;
4580   Doc           *doc;
4581   Attr          *attr;
4582   char          *rel  = NULL;
4583   char          *href = NULL;
4584   char          *type = NULL;
4585
4586   chtml30 = GET_CHTML30(pdoc);
4587   doc     = chtml30->doc;
4588
4589   if (! IS_CSS_ON(chtml30->entryp)) {
4590     return chtml30->out;
4591   }
4592
4593   for (attr = qs_get_attr(doc,node);
4594        attr;
4595        attr = qs_get_next_attr(doc,attr)) {
4596     char *name  = qs_get_attr_name(doc,attr);
4597     char *value = qs_get_attr_value(doc,attr);
4598     if (STRCASEEQ('r','R',"rel", name)) {
4599       if (value && *value && STRCASEEQ('s','S',"stylesheet", value)) {
4600         rel = value;
4601       }
4602     }
4603     else if (STRCASEEQ('h','H',"href", name)) {
4604       if (value && *value) {
4605         href = value;
4606       }
4607     }
4608     else if (STRCASEEQ('t','T',"type", name)) {
4609       if (value && *value && STRCASEEQ('t','T',"text/css",value)) {
4610         type = value;
4611       }
4612     }
4613   }
4614
4615   if (rel && href && type) {
4616     DBG(doc->r, "REQ[%X] start load CSS. url:[%s]", TO_ADDR(doc->r),href);
4617     chtml30->style = chxj_css_parse_from_uri(doc->r, doc->pool, chtml30->style, href);
4618     DBG(doc->r, "REQ[%X] end load CSS. url:[%s]", TO_ADDR(doc->r),href);
4619   }
4620
4621   return chtml30->out;
4622 }
4623
4624
4625 static css_prop_list_t *
4626 s_chtml30_push_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value)
4627 {
4628   chtml30_t *chtml30 = GET_CHTML30(pdoc);
4629   Doc *doc = chtml30->doc;
4630   css_prop_list_t *last_css = NULL;
4631   if (IS_CSS_ON(chtml30->entryp)) {
4632     css_prop_list_t *dup_css;
4633     css_selector_t  *selector;
4634
4635     last_css = chxj_css_get_last_prop_list(chtml30->css_prop_stack);
4636     dup_css  = chxj_dup_css_prop_list(doc, last_css);
4637     selector = chxj_css_find_selector(doc, chtml30->style, node);
4638     if (selector) {
4639       chxj_css_prop_list_merge_property(doc, dup_css, selector);
4640     }
4641     chxj_css_push_prop_list(chtml30->css_prop_stack, dup_css);
4642     last_css = chxj_css_get_last_prop_list(chtml30->css_prop_stack);
4643
4644     if (style_attr_value) {
4645       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));
4646       if (ssheet) {
4647         chxj_css_prop_list_merge_property(doc, last_css, ssheet->selector_head.next);
4648       }
4649     }
4650   }
4651   return last_css;
4652 }
4653
4654
4655 static css_prop_list_t *
4656 s_chtml30_nopush_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value)
4657 {
4658   chtml30_t *chtml30 = GET_CHTML30(pdoc);
4659   Doc *doc = chtml30->doc;
4660   css_prop_list_t *last_css = NULL;
4661   if (IS_CSS_ON(chtml30->entryp)) {
4662     css_prop_list_t *dup_css;
4663     css_selector_t  *selector;
4664
4665     last_css = chxj_css_get_last_prop_list(chtml30->css_prop_stack);
4666     dup_css  = chxj_dup_css_prop_list(doc, last_css);
4667     selector = chxj_css_find_selector(doc, chtml30->style, node);
4668     if (selector) {
4669       chxj_css_prop_list_merge_property(doc, dup_css, selector);
4670     }
4671     last_css = dup_css;
4672
4673     if (style_attr_value) {
4674       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));
4675       if (ssheet) {
4676         chxj_css_prop_list_merge_property(doc, last_css, ssheet->selector_head.next);
4677       }
4678     }
4679   }
4680   return last_css;
4681 }
4682
4683
4684
4685 /**
4686  * It is a handler who processes the SPAN tag.
4687  *
4688  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4689  *                     destination is specified.
4690  * @param node   [i]   The SPAN tag node is specified.
4691  * @return The conversion result is returned.
4692  */
4693 static char *
4694 s_chtml30_start_span_tag(void *pdoc, Node *node)
4695 {
4696   chtml30_t *chtml30;
4697   Doc *doc;
4698   Attr *attr;
4699   char *attr_style = NULL;
4700   char *attr_color = NULL;
4701   char *attr_align = NULL;
4702   char *attr_blink = NULL;
4703   char *attr_marquee = NULL;
4704   char *attr_marquee_dir = NULL;
4705   char *attr_marquee_style = NULL;
4706   char *attr_marquee_loop = NULL;
4707
4708   chtml30 = GET_CHTML30(pdoc);
4709   doc     = chtml30->doc;
4710
4711   for (attr = qs_get_attr(doc,node);
4712        attr;
4713        attr = qs_get_next_attr(doc,attr)) {
4714     char *nm  = qs_get_attr_name(doc,attr);
4715     char *val = qs_get_attr_value(doc,attr);
4716     if (val && STRCASEEQ('s','S',"style", nm)) {
4717       attr_style = val;
4718     }
4719   }
4720   if (IS_CSS_ON(chtml30->entryp)) {
4721     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
4722     if (style) {
4723       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
4724       css_property_t *text_align_prop = chxj_css_get_property_value(doc, style, "text-align");
4725       css_property_t *decoration_prop = chxj_css_get_property_value(doc, style, "text-decoration");
4726       css_property_t *display_prop = chxj_css_get_property_value(doc, style, "display");
4727       css_property_t *marquee_dir_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-dir");
4728       css_property_t *marquee_style_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-style");
4729       css_property_t *marquee_loop_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-loop");
4730       css_property_t *cur;
4731       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
4732         attr_color = apr_pstrdup(doc->pool, cur->value);
4733       }
4734       for (cur = decoration_prop->next; cur != decoration_prop; cur = cur->next) {
4735         if (cur->value && STRCASEEQ('b','B',"blink",cur->value)) {
4736           attr_blink = apr_pstrdup(doc->pool, cur->value);
4737         }
4738       }
4739       for (cur = display_prop->next; cur != display_prop; cur = cur->next) {
4740         if (cur->value && strcasecmp("-wap-marquee",cur->value) == 0) {
4741           attr_marquee = apr_pstrdup(doc->pool, cur->value);
4742         }
4743       }
4744       for (cur = marquee_dir_prop->next; cur != marquee_dir_prop; cur = cur->next) {
4745         if (cur->value && *cur->value) {
4746           if (STRCASEEQ('l','L',"ltr",cur->value)) {
4747             attr_marquee_dir = "right";
4748           }
4749           else if (STRCASEEQ('r','R',"rtl",cur->value)) {
4750             attr_marquee_dir = "left";
4751           }
4752         }
4753       }
4754       for (cur = marquee_style_prop->next; cur != marquee_style_prop; cur = cur->next) {
4755         if (cur->value && *cur->value) {
4756           if ( STRCASEEQ('s','S',"scroll",cur->value)
4757             || STRCASEEQ('s','S',"slide",cur->value)
4758             || STRCASEEQ('a','A',"alternate",cur->value)) {
4759             attr_marquee_style = apr_pstrdup(doc->pool, cur->value);
4760           }
4761         }
4762       }
4763       for (cur = marquee_loop_prop->next; cur != marquee_loop_prop; cur = cur->next) {
4764         if (cur->value && *cur->value) {
4765           if (STRCASEEQ('i','I',"infinite",cur->value)) {
4766             attr_marquee_loop = "16";
4767           }
4768           else {
4769             attr_marquee_loop = apr_pstrdup(doc->pool, cur->value);
4770           }
4771         }
4772       }
4773       for (cur = text_align_prop->next; cur != text_align_prop; cur = cur->next) {
4774         if (STRCASEEQ('l','L',"left", cur->value)) {
4775           attr_align = apr_pstrdup(doc->pool, "left");
4776         }
4777         else if (STRCASEEQ('c','C',"center",cur->value)) {
4778           attr_align = apr_pstrdup(doc->pool, "center");
4779         }
4780         else if (STRCASEEQ('r','R',"right",cur->value)) {
4781           attr_align = apr_pstrdup(doc->pool, "right");
4782         }
4783       }
4784     }
4785   }
4786   if (attr_color || attr_align || attr_blink || attr_marquee) {
4787     chtml30_flags_t *flg = apr_palloc(doc->pool, sizeof(*flg));
4788     memset(flg, 0, sizeof(*flg));
4789     if (attr_blink) {
4790       W_L("<blink>");
4791       flg->with_blink_flag = 1;
4792     }
4793     if (attr_marquee) {
4794       W_L("<marquee");
4795       if (attr_marquee_dir) {
4796         W_L(" direction=\"");
4797         W_V(attr_marquee_dir);
4798         W_L("\"");
4799       }
4800       if (attr_marquee_style) {
4801         W_L(" behavior=\"");
4802         W_V(attr_marquee_style);
4803         W_L("\"");
4804       }
4805       if (attr_marquee_loop) {
4806         W_L(" loop=\"");
4807         W_V(attr_marquee_loop);
4808         W_L("\"");
4809       }
4810       W_L(">");
4811       flg->with_marquee_flag = 1;
4812     }
4813     if (attr_color) {
4814       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
4815       W_L("<font color=\"");
4816       W_V(attr_color);
4817       W_L("\">");
4818       flg->with_font_flag = 1;
4819     }
4820     if (attr_align) {
4821       W_L("<div align=\"");
4822       W_V(attr_align);
4823       W_L("\">");
4824       flg->with_div_flag = 1;
4825     }
4826     node->userData = flg;
4827   }
4828   else {
4829     node->userData = NULL;
4830   }
4831   return chtml30->out;
4832 }
4833
4834
4835 /**
4836  * It is a handler who processes the SPAN tag.
4837  *
4838  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4839  *                     destination is specified.
4840  * @param node   [i]   The SPAN tag node is specified.
4841  * @return The conversion result is returned.
4842  */
4843 static char *
4844 s_chtml30_end_span_tag(void *pdoc, Node *node)
4845 {
4846   chtml30_t *chtml30 = GET_CHTML30(pdoc);
4847   Doc *doc = chtml30->doc;
4848
4849   chtml30_flags_t *flg = (chtml30_flags_t *)node->userData;
4850   if (flg && flg->with_div_flag) {
4851     W_L("</div>");
4852   }
4853   if (flg && flg->with_font_flag) {
4854     W_L("</font>");
4855   }
4856   if (flg && flg->with_marquee_flag) {
4857     W_L("</marquee>");
4858   }
4859   if (flg && flg->with_blink_flag) {
4860     W_L("</blink>");
4861   }
4862   if (IS_CSS_ON(chtml30->entryp)) {
4863     chxj_css_pop_prop_list(chtml30->css_prop_stack);
4864   }
4865   return chtml30->out;
4866 }
4867
4868
4869
4870 /**
4871  * It is a handler who processes the STYLE tag.
4872  *
4873  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4874  *                     destination is specified.
4875  * @param node   [i]   The STYLE tag node is specified.
4876  * @return The conversion result is returned.
4877  */
4878 static char *
4879 s_chtml30_style_tag(void *pdoc, Node *node)
4880 {
4881   chtml30_t     *chtml30;
4882   Doc           *doc;
4883   Attr          *attr;
4884   char          *type = NULL;
4885
4886   chtml30 = GET_CHTML30(pdoc);
4887   doc     = chtml30->doc;
4888
4889   if (! IS_CSS_ON(chtml30->entryp)) {
4890     return chtml30->out;
4891   }
4892
4893   for (attr = qs_get_attr(doc,node);
4894        attr;
4895        attr = qs_get_next_attr(doc,attr)) {
4896     char *name  = qs_get_attr_name(doc,attr);
4897     char *value = qs_get_attr_value(doc,attr);
4898     if (STRCASEEQ('t','T',"type", name)) {
4899       if (value && *value && STRCASEEQ('t','T',"text/css",value)) {
4900         type = value;
4901       }
4902     }
4903   }
4904
4905   Node *child = qs_get_child_node(doc, node);
4906   if (type && child) {
4907     char *name  = qs_get_node_name(doc, child);
4908     if (STRCASEEQ('t','T',"text", name)) {
4909       char *value = qs_get_node_value(doc, child);
4910       DBG(doc->r, "REQ[%X] start load CSS. buf:[%s]", TO_ADDR(doc->r),value);
4911       chtml30->style = chxj_css_parse_style_value(doc, chtml30->style, value);
4912       DBG(doc->r, "REQ[%X] end load CSS. value:[%s]", TO_ADDR(doc->r),value);
4913     }
4914   }
4915   return chtml30->out;
4916 }
4917 /*
4918  * vim:ts=2 et
4919  */