OSDN Git Service

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