OSDN Git Service

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