OSDN Git Service

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