OSDN Git Service

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