OSDN Git Service

Merge branch 'branch_0.13.0' into branch_0.13.0-svn
[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",attr_type) || STRCASEEQ('r','R',"reset",attr_type)) {
1874       apr_size_t value_len = strlen(attr_value);
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
3226   W_L("<li");
3227   if (attr_type) {
3228     W_L(" type=\"");
3229     W_V(attr_type);
3230     W_L("\"");
3231   }
3232   if (attr_value) {
3233     W_L(" value=\"");
3234     W_V(attr_value);
3235     W_L("\"");
3236   }
3237   W_L(">");
3238   return chtml30->out;
3239 }
3240
3241
3242 /**
3243  * It is a handler who processes the LI tag.
3244  *
3245  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3246  *                     destination is specified.
3247  * @param node   [i]   The LI tag node is specified.
3248  * @return The conversion result is returned.
3249  */
3250 static char *
3251 s_chtml30_end_li_tag(void *pdoc, Node *UNUSED(child)) 
3252 {
3253   chtml30_t *chtml30 = GET_CHTML30(pdoc);
3254
3255   if (IS_CSS_ON(chtml30->entryp)) {
3256     chxj_css_pop_prop_list(chtml30->css_prop_stack);
3257   }
3258   return chtml30->out;
3259 }
3260
3261
3262 /**
3263  * It is a handler who processes the H1 tag.
3264  *
3265  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3266  *                     destination is specified.
3267  * @param node   [i]   The H1 tag node is specified.
3268  * @return The conversion result is returned.
3269  */
3270 static char *
3271 s_chtml30_start_h1_tag(void *pdoc, Node *node)
3272 {
3273   chtml30_t   *chtml30;
3274   Doc         *doc;
3275   request_rec *r;
3276   Attr        *attr;
3277   char        *attr_style = NULL;
3278   char        *attr_align = NULL;
3279
3280
3281   chtml30 = GET_CHTML30(pdoc);
3282   doc     = chtml30->doc;
3283   r       = doc->r;
3284
3285   for (attr = qs_get_attr(doc,node);
3286        attr;
3287        attr = qs_get_next_attr(doc,attr)) {
3288     char *name  = qs_get_attr_name(doc,attr);
3289     char *value = qs_get_attr_value(doc,attr);
3290     if (STRCASEEQ('a','A',"align", name)) {
3291       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3292         attr_align = value;
3293       }
3294     }
3295     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3296       attr_style = value;
3297     }
3298   }
3299   if (IS_CSS_ON(chtml30->entryp)) {
3300     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
3301     if (style) {
3302       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3303       css_property_t *cur;
3304       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3305         if (STRCASEEQ('l','L',"left", cur->value)) {
3306           attr_align = apr_pstrdup(doc->pool, "left");
3307         }
3308         else if (STRCASEEQ('c','C',"center",cur->value)) {
3309           attr_align = apr_pstrdup(doc->pool, "center");
3310         }
3311         else if (STRCASEEQ('r','R',"right",cur->value)) {
3312           attr_align = apr_pstrdup(doc->pool, "right");
3313         }
3314       }
3315     }
3316   }
3317   W_L("<h1");
3318   if (attr_align) {
3319     W_L(" align=\"");
3320     W_V(attr_align);
3321     W_L("\"");
3322   }
3323   W_L(">");
3324
3325   return chtml30->out;
3326 }
3327
3328
3329 /**
3330  * It is a handler who processes the H1 tag.
3331  *
3332  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3333  *                     destination is specified.
3334  * @param node   [i]   The H1 tag node is specified.
3335  * @return The conversion result is returned.
3336  */
3337 static char *
3338 s_chtml30_end_h1_tag(void *pdoc, Node *UNUSED(child)) 
3339 {
3340   chtml30_t   *chtml30;
3341   Doc         *doc;
3342
3343   chtml30 = GET_CHTML30(pdoc);
3344   doc     = chtml30->doc;
3345
3346   W_L("</h1>");
3347   if (IS_CSS_ON(chtml30->entryp)) {
3348     chxj_css_pop_prop_list(chtml30->css_prop_stack);
3349   }
3350
3351   return chtml30->out;
3352 }
3353
3354
3355 /**
3356  * It is a handler who processes the H2 tag.
3357  *
3358  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3359  *                     destination is specified.
3360  * @param node   [i]   The H2 tag node is specified.
3361  * @return The conversion result is returned.
3362  */
3363 static char *
3364 s_chtml30_start_h2_tag(void *pdoc, Node *node)
3365 {
3366   chtml30_t   *chtml30;
3367   Doc         *doc;
3368   request_rec *r;
3369   Attr        *attr;
3370   char        *attr_style = NULL;
3371   char        *attr_align = NULL;
3372
3373   chtml30 = GET_CHTML30(pdoc);
3374   doc     = chtml30->doc;
3375   r       = doc->r;
3376
3377   for (attr = qs_get_attr(doc,node);
3378        attr;
3379        attr = qs_get_next_attr(doc,attr)) {
3380     char *name  = qs_get_attr_name(doc,attr);
3381     char *value = qs_get_attr_value(doc,attr);
3382     if (STRCASEEQ('a','A',"align", name)) {
3383       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3384         attr_align = value;
3385       }
3386     }
3387     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3388       attr_style = value;
3389     }
3390   }
3391   if (IS_CSS_ON(chtml30->entryp)) {
3392     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
3393     if (style) {
3394       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3395       css_property_t *cur;
3396       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3397         if (STRCASEEQ('l','L',"left", cur->value)) {
3398           attr_align = apr_pstrdup(doc->pool, "left");
3399         }
3400         else if (STRCASEEQ('c','C',"center",cur->value)) {
3401           attr_align = apr_pstrdup(doc->pool, "center");
3402         }
3403         else if (STRCASEEQ('r','R',"right",cur->value)) {
3404           attr_align = apr_pstrdup(doc->pool, "right");
3405         }
3406       }
3407     }
3408   }
3409   W_L("<h2");
3410   if (attr_align) {
3411     W_L(" align=\"");
3412     W_V(attr_align);
3413     W_L("\"");
3414   }
3415   W_L(">");
3416
3417   return chtml30->out;
3418 }
3419
3420
3421 /**
3422  * It is a handler who processes the H2 tag.
3423  *
3424  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3425  *                     destination is specified.
3426  * @param node   [i]   The H2 tag node is specified.
3427  * @return The conversion result is returned.
3428  */
3429 static char *
3430 s_chtml30_end_h2_tag(void *pdoc, Node *UNUSED(child)) 
3431 {
3432   chtml30_t   *chtml30 = GET_CHTML30(pdoc);
3433   Doc         *doc     = chtml30->doc;
3434
3435   W_L("</h2>");
3436   if (IS_CSS_ON(chtml30->entryp)) {
3437     chxj_css_pop_prop_list(chtml30->css_prop_stack);
3438   }
3439
3440   return chtml30->out;
3441 }
3442
3443
3444 /**
3445  * It is a handler who processes the H3 tag.
3446  *
3447  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3448  *                     destination is specified.
3449  * @param node   [i]   The H3 tag node is specified.
3450  * @return The conversion result is returned.
3451  */
3452 static char *
3453 s_chtml30_start_h3_tag(void *pdoc, Node *node)
3454 {
3455   chtml30_t   *chtml30;
3456   Doc         *doc;
3457   request_rec *r;
3458   Attr        *attr;
3459   char        *attr_style = NULL;
3460   char        *attr_align = NULL;
3461
3462   chtml30 = GET_CHTML30(pdoc);
3463   doc     = chtml30->doc;
3464   r       = doc->r;
3465
3466   for (attr = qs_get_attr(doc,node);
3467        attr;
3468        attr = qs_get_next_attr(doc,attr)) {
3469     char *name  = qs_get_attr_name(doc,attr);
3470     char *value = qs_get_attr_value(doc,attr);
3471     if (STRCASEEQ('a','A',"align", name)) {
3472       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3473         attr_align = value;
3474       }
3475     }
3476     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3477       attr_style = value;
3478     }
3479   }
3480   if (IS_CSS_ON(chtml30->entryp)) {
3481     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
3482     if (style) {
3483       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3484       css_property_t *cur;
3485       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3486         if (STRCASEEQ('l','L',"left", cur->value)) {
3487           attr_align = apr_pstrdup(doc->pool, "left");
3488         }
3489         else if (STRCASEEQ('c','C',"center",cur->value)) {
3490           attr_align = apr_pstrdup(doc->pool, "center");
3491         }
3492         else if (STRCASEEQ('r','R',"right",cur->value)) {
3493           attr_align = apr_pstrdup(doc->pool, "right");
3494         }
3495       }
3496     }
3497   }
3498   W_L("<h3");
3499   if (attr_align) {
3500     W_L(" align=\"");
3501     W_V(attr_align);
3502     W_L("\"");
3503   }
3504   W_L(">");
3505
3506   return chtml30->out;
3507 }
3508
3509
3510 /**
3511  * It is a handler who processes the H3 tag.
3512  *
3513  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3514  *                     destination is specified.
3515  * @param node   [i]   The H3 tag node is specified.
3516  * @return The conversion result is returned.
3517  */
3518 static char *
3519 s_chtml30_end_h3_tag(void *pdoc, Node *UNUSED(child))
3520 {
3521   chtml30_t *chtml30 = GET_CHTML30(pdoc);
3522   Doc       *doc   = chtml30->doc;
3523
3524   W_L("</h3>");
3525   if (IS_CSS_ON(chtml30->entryp)) {
3526     chxj_css_pop_prop_list(chtml30->css_prop_stack);
3527   }
3528
3529   return chtml30->out;
3530 }
3531
3532
3533 /**
3534  * It is a handler who processes the H4 tag.
3535  *
3536  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3537  *                     destination is specified.
3538  * @param node   [i]   The H4 tag node is specified.
3539  * @return The conversion result is returned.
3540  */
3541 static char *
3542 s_chtml30_start_h4_tag(void *pdoc, Node *node)
3543 {
3544   chtml30_t   *chtml30;
3545   Doc         *doc;
3546   request_rec *r;
3547   Attr        *attr;
3548   char        *attr_style = NULL;
3549   char        *attr_align = NULL;
3550
3551   chtml30 = GET_CHTML30(pdoc);
3552   doc     = chtml30->doc;
3553   r       = doc->r;
3554
3555   for (attr = qs_get_attr(doc,node);
3556        attr;
3557        attr = qs_get_next_attr(doc,attr)) {
3558     char *name  = qs_get_attr_name(doc,attr);
3559     char *value = qs_get_attr_value(doc,attr);
3560     if (STRCASEEQ('a','A',"align", name)) {
3561       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3562         attr_align = value;
3563       }
3564     }
3565     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3566       attr_style = value;
3567     }
3568   }
3569   if (IS_CSS_ON(chtml30->entryp)) {
3570     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
3571     if (style) {
3572       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3573       css_property_t *cur;
3574       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3575         if (STRCASEEQ('l','L',"left", cur->value)) {
3576           attr_align = apr_pstrdup(doc->pool, "left");
3577         }
3578         else if (STRCASEEQ('c','C',"center",cur->value)) {
3579           attr_align = apr_pstrdup(doc->pool, "center");
3580         }
3581         else if (STRCASEEQ('r','R',"right",cur->value)) {
3582           attr_align = apr_pstrdup(doc->pool, "right");
3583         }
3584       }
3585     }
3586   }
3587   W_L("<h4");
3588   if (attr_align) {
3589     W_L(" align=\"");
3590     W_V(attr_align);
3591     W_L("\"");
3592   }
3593   W_L(">");
3594
3595   return chtml30->out;
3596 }
3597
3598
3599 /**
3600  * It is a handler who processes the H4 tag.
3601  *
3602  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3603  *                     destination is specified.
3604  * @param node   [i]   The H4 tag node is specified.
3605  * @return The conversion result is returned.
3606  */
3607 static char *
3608 s_chtml30_end_h4_tag(void *pdoc, Node *UNUSED(child)) 
3609 {
3610   chtml30_t *chtml30 = GET_CHTML30(pdoc);
3611   Doc       *doc     = chtml30->doc;
3612
3613   W_L("</h4>");
3614   if (IS_CSS_ON(chtml30->entryp)) {
3615     chxj_css_pop_prop_list(chtml30->css_prop_stack);
3616   }
3617
3618   return chtml30->out;
3619 }
3620
3621
3622 /**
3623  * It is a handler who processes the H5 tag.
3624  *
3625  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3626  *                     destination is specified.
3627  * @param node   [i]   The H5 tag node is specified.
3628  * @return The conversion result is returned.
3629  */
3630 static char *
3631 s_chtml30_start_h5_tag(void *pdoc, Node *node)
3632 {
3633   chtml30_t   *chtml30;
3634   Doc         *doc;
3635   request_rec *r;
3636   Attr        *attr;
3637   char        *attr_style = NULL;
3638   char        *attr_align = NULL;
3639
3640   chtml30 = GET_CHTML30(pdoc);
3641   doc     = chtml30->doc;
3642   r       = doc->r;
3643
3644   for (attr = qs_get_attr(doc,node);
3645        attr;
3646        attr = qs_get_next_attr(doc,attr)) {
3647     char *name  = qs_get_attr_name(doc,attr);
3648     char *value = qs_get_attr_value(doc,attr);
3649     if (STRCASEEQ('a','A',"align", name)) {
3650       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3651         attr_align = value;
3652       }
3653     }
3654     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3655       attr_style = value;
3656     }
3657   }
3658   if (IS_CSS_ON(chtml30->entryp)) {
3659     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
3660     if (style) {
3661       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3662       css_property_t *cur;
3663       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3664         if (STRCASEEQ('l','L',"left", cur->value)) {
3665           attr_align = apr_pstrdup(doc->pool, "left");
3666         }
3667         else if (STRCASEEQ('c','C',"center",cur->value)) {
3668           attr_align = apr_pstrdup(doc->pool, "center");
3669         }
3670         else if (STRCASEEQ('r','R',"right",cur->value)) {
3671           attr_align = apr_pstrdup(doc->pool, "right");
3672         }
3673       }
3674     }
3675   }
3676   W_L("<h5");
3677   if (attr_align) {
3678     W_L(" align=\"");
3679     W_V(attr_align);
3680     W_L("\"");
3681   }
3682   W_L("<h5");
3683   if (attr_align) {
3684     W_L(" align=\"");
3685     W_V(attr_align);
3686     W_L("\"");
3687   }
3688   W_L(">");
3689
3690   return chtml30->out;
3691 }
3692
3693
3694 /**
3695  * It is a handler who processes the H5 tag.
3696  *
3697  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3698  *                     destination is specified.
3699  * @param node   [i]   The H5 tag node is specified.
3700  * @return The conversion result is returned.
3701  */
3702 static char *
3703 s_chtml30_end_h5_tag(void *pdoc, Node *UNUSED(child)) 
3704 {
3705   chtml30_t *chtml30 = GET_CHTML30(pdoc);
3706   Doc       *doc     = chtml30->doc;
3707
3708   W_L("</h5>");
3709   if (IS_CSS_ON(chtml30->entryp)) {
3710     chxj_css_pop_prop_list(chtml30->css_prop_stack);
3711   }
3712
3713   return chtml30->out;
3714 }
3715
3716
3717 /**
3718  * It is a handler who processes the H6 tag.
3719  *
3720  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3721  *                     destination is specified.
3722  * @param node   [i]   The H6 tag node is specified.
3723  * @return The conversion result is returned.
3724  */
3725 static char *
3726 s_chtml30_start_h6_tag(void *pdoc, Node *node)
3727 {
3728   chtml30_t   *chtml30;
3729   Doc         *doc;
3730   request_rec *r;
3731   Attr        *attr;
3732   char        *attr_style = NULL;
3733   char        *attr_align = NULL;
3734
3735   chtml30 = GET_CHTML30(pdoc);
3736   doc     = chtml30->doc;
3737   r       = doc->r;
3738
3739   for (attr = qs_get_attr(doc,node);
3740        attr;
3741        attr = qs_get_next_attr(doc,attr)) {
3742     char *name  = qs_get_attr_name(doc,attr);
3743     char *value = qs_get_attr_value(doc,attr);
3744     if (STRCASEEQ('a','A',"align", name)) {
3745       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3746         attr_align = value;
3747       }
3748     }
3749     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3750       attr_style = value;
3751     }
3752   }
3753   if (IS_CSS_ON(chtml30->entryp)) {
3754     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
3755     if (style) {
3756       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3757       css_property_t *cur;
3758       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3759         if (STRCASEEQ('l','L',"left", cur->value)) {
3760           attr_align = apr_pstrdup(doc->pool, "left");
3761         }
3762         else if (STRCASEEQ('c','C',"center",cur->value)) {
3763           attr_align = apr_pstrdup(doc->pool, "center");
3764         }
3765         else if (STRCASEEQ('r','R',"right",cur->value)) {
3766           attr_align = apr_pstrdup(doc->pool, "right");
3767         }
3768       }
3769     }
3770   }
3771   W_L("<h6");
3772   if (attr_align) {
3773     W_L(" align=\"");
3774     W_V(attr_align);
3775     W_L("\"");
3776   }
3777   W_L(">");
3778
3779   return chtml30->out;
3780 }
3781
3782
3783 /**
3784  * It is a handler who processes the H6 tag.
3785  *
3786  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3787  *                     destination is specified.
3788  * @param node   [i]   The H6 tag node is specified.
3789  * @return The conversion result is returned.
3790  */
3791 static char *
3792 s_chtml30_end_h6_tag(void *pdoc, Node *UNUSED(child)) 
3793 {
3794   chtml30_t *chtml30 = GET_CHTML30(pdoc);
3795   Doc       *doc     = chtml30->doc;
3796
3797   W_L("</h6>");
3798   if (IS_CSS_ON(chtml30->entryp)) {
3799     chxj_css_pop_prop_list(chtml30->css_prop_stack);
3800   }
3801
3802   return chtml30->out;
3803 }
3804
3805
3806 /**
3807  * It is a handler who processes the TEXTARE tag.
3808  *
3809  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3810  *                     destination is specified.
3811  * @param node   [i]   The TEXTAREA tag node is specified.
3812  * @return The conversion result is returned.
3813  */
3814 static char *
3815 s_chtml30_start_textarea_tag(void *pdoc, Node *node) 
3816 {
3817   chtml30_t   *chtml30;
3818   Doc         *doc;
3819   request_rec *r;
3820   Attr        *attr;
3821   char        *attr_accesskey = NULL;
3822   char        *attr_name      = NULL;
3823   char        *attr_rows      = NULL;
3824   char        *attr_cols      = NULL;
3825   char        *attr_istyle    = NULL;
3826   char        *attr_style     = NULL;
3827
3828   chtml30 = GET_CHTML30(pdoc);
3829   doc     = chtml30->doc;
3830   r       = doc->r;
3831
3832   chtml30->textarea_flag++;
3833
3834   for (attr = qs_get_attr(doc,node);
3835        attr;
3836        attr = qs_get_next_attr(doc,attr)) {
3837     char *name  = qs_get_attr_name(doc,attr);
3838     char *value = qs_get_attr_value(doc,attr);
3839     if (STRCASEEQ('a','A',"accesskey",name) && value && *value != 0) {
3840       attr_accesskey = value;
3841     }
3842     else if (STRCASEEQ('i','I',"istyle", name) && value && (*value == '1' || *value == '2' || *value == '3' || *value == '4')) {
3843       attr_istyle = value;
3844     }
3845     else if (STRCASEEQ('n','N',"name", name) && value && *value) {
3846       attr_name = value;
3847     }
3848     else if (STRCASEEQ('r','R',"rows", name) && value && *value) {
3849       attr_rows = value;
3850     }
3851     else if (STRCASEEQ('c','C',"cols", name) && value && *value) {
3852       attr_cols = value;
3853     }
3854     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
3855       attr_style = value;
3856     }
3857   }  
3858
3859   W_L("<textarea");
3860   if (attr_accesskey) {
3861     W_L(" accesskey=\"");
3862     W_V(attr_accesskey);
3863     W_L("\"");
3864   }
3865   if (attr_name) {
3866     W_L(" name=\"");
3867     W_V(attr_name);
3868     W_L("\"");
3869   }
3870   if (attr_rows) {
3871     W_L(" rows=\"");
3872     W_V(attr_rows);
3873     W_L("\"");
3874   }
3875   if (attr_cols) {
3876     W_L(" cols=\"");
3877     W_V(attr_cols);
3878     W_L("\"");
3879   }
3880   if (attr_istyle) {
3881     W_L(" istyle=\"");
3882     W_V(attr_istyle);
3883     W_L("\"");
3884   }
3885
3886   if (IS_CSS_ON(chtml30->entryp)) {
3887     css_prop_list_t *style = s_chtml30_nopush_and_get_now_style(pdoc, node, attr_style);
3888     if (style) {
3889       css_property_t *wap_input_format = chxj_css_get_property_value(doc, style, "-wap-input-format");
3890       css_property_t *cur;
3891       for (cur = wap_input_format->next; cur != wap_input_format; cur = cur->next) {
3892         if (strcasestr(cur->value, "<ja:n>")) {
3893           attr_istyle = "4";
3894         }
3895         else if (strcasestr(cur->value, "<ja:en>")) {
3896           attr_istyle = "3";
3897         }
3898         else if (strcasestr(cur->value, "<ja:hk>")) {
3899           attr_istyle = "2";
3900         }
3901         else if (strcasestr(cur->value, "<ja:h>")) {
3902           attr_istyle = "1";
3903         }
3904       }
3905     }
3906   }  
3907
3908   W_L("<textarea");
3909   if (attr_accesskey) {
3910     W_L(" accesskey=\"");
3911     W_V(attr_accesskey);
3912     W_L("\"");
3913   }
3914   if (attr_name) {
3915     W_L(" name=\"");
3916     W_V(attr_name);
3917     W_L("\"");
3918   }
3919   if (attr_rows) {
3920     W_L(" rows=\"");
3921     W_V(attr_rows);
3922     W_L("\"");
3923   }
3924   if (attr_cols) {
3925     W_L(" cols=\"");
3926     W_V(attr_cols);
3927     W_L("\"");
3928   }
3929   if (attr_istyle) {
3930     W_L(" istyle=\"");
3931     W_V(attr_istyle);
3932     W_L("\"");
3933   }
3934   W_L(">");
3935   return chtml30->out;
3936 }
3937
3938
3939 /**
3940  * It is a handler who processes the TEXTAREA tag.
3941  *
3942  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3943  *                     destination is specified.
3944  * @param node   [i]   The TEXTAREA tag node is specified.
3945  * @return The conversion result is returned.
3946  */
3947 static char *
3948 s_chtml30_end_textarea_tag(void *pdoc, Node *UNUSED(child)) 
3949 {
3950   chtml30_t *chtml30 = GET_CHTML30(pdoc);
3951   Doc       *doc     = chtml30->doc;
3952
3953   W_L("</textarea>");
3954   chtml30->textarea_flag--;
3955
3956   return chtml30->out;
3957 }
3958
3959
3960 static char *
3961 s_chtml30_chxjif_tag(void *pdoc, Node *node)
3962 {
3963   Node        *child;
3964   chtml30_t   *chtml30;
3965   Doc         *doc;
3966   request_rec *r;
3967
3968   chtml30 = GET_CHTML30(pdoc);
3969   doc     = chtml30->doc;
3970   r       = doc->r;
3971
3972   for (child = qs_get_child_node(doc, node);
3973        child;
3974        child = qs_get_next_node(doc, child)) {
3975     W_V(child->otext);
3976     s_chtml30_chxjif_tag(chtml30, child);
3977   }
3978
3979   return NULL;
3980 }
3981
3982
3983 static char *
3984 s_chtml30_text_tag(void *pdoc, Node *child)
3985 {
3986   chtml30_t   *chtml30;
3987   Doc         *doc;
3988   request_rec *r;
3989
3990   char        *textval;
3991   char        *tmp;
3992   char        *tdst;
3993   char        one_byte[2];
3994   int         ii;
3995   int         tdst_len;
3996   apr_size_t  z2h_input_len;
3997
3998   chtml30 = GET_CHTML30(pdoc);
3999   doc     = chtml30->doc;
4000   r       = doc->r;
4001   
4002   textval = qs_get_node_value(doc,child);
4003   if (strlen(textval) == 0) {
4004     return chtml30->out;
4005   }
4006   
4007   tmp = apr_palloc(r->pool, qs_get_node_size(doc,child)+1);
4008   memset(tmp, 0, qs_get_node_size(doc,child)+1);
4009   
4010   tdst     = qs_alloc_zero_byte_string(doc->buf.pool);
4011   memset(one_byte, 0, sizeof(one_byte));
4012   tdst_len = 0;
4013   
4014   for (ii=0; ii<qs_get_node_size(doc,child); ii++) {
4015     char* out;
4016     int rtn = s_chtml30_search_emoji(chtml30, &textval[ii], &out);
4017     if (rtn) {
4018       tdst = qs_out_apr_pstrcat(r, tdst, out, &tdst_len);
4019       ii+=(rtn - 1);
4020       continue;
4021     }
4022   
4023     if (is_sjis_kanji(textval[ii])) {
4024       one_byte[0] = textval[ii+0];
4025       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
4026       one_byte[0] = textval[ii+1];
4027       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
4028       ii++;
4029     }
4030     else if (chtml30->pre_flag) {
4031       one_byte[0] = textval[ii+0];
4032       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
4033     }
4034     else if (chtml30->textarea_flag) {
4035       one_byte[0] = textval[ii+0];
4036       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
4037     }
4038     else if (textval[ii] != '\r' && textval[ii] != '\n') {
4039       one_byte[0] = textval[ii+0];
4040       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
4041     }
4042   }
4043   z2h_input_len = strlen(tdst);
4044   tdst = chxj_conv_z2h(r, tdst, &z2h_input_len, chtml30->entryp);
4045
4046   W_V(tdst);
4047   return chtml30->out;
4048 }
4049
4050
4051 /**
4052  * It is a handler who processes the BLOCKQUOTE tag.
4053  *
4054  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4055  *                     destination is specified.
4056  * @param node   [i]   The BLOCKQUOTE tag node is specified.
4057  * @return The conversion result is returned.
4058  */
4059 static char *
4060 s_chtml30_start_blockquote_tag(void *pdoc, Node *node)
4061 {
4062   chtml30_t *chtml30;
4063   Doc       *doc;
4064   Attr      *attr;
4065   char      *attr_style = NULL;
4066   char      *attr_color = NULL;
4067
4068   chtml30 = GET_CHTML30(pdoc);
4069   doc     = chtml30->doc;
4070   for (attr = qs_get_attr(doc,node);
4071        attr;
4072        attr = qs_get_next_attr(doc,attr)) {
4073     char *nm  = qs_get_attr_name(doc,attr);
4074     char *val = qs_get_attr_value(doc,attr);
4075     if (val && STRCASEEQ('s','S',"style", nm)) {
4076       attr_style = val;
4077     }
4078   }
4079   if (IS_CSS_ON(chtml30->entryp)) {
4080     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
4081     if (style) {
4082       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
4083       css_property_t *cur;
4084       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
4085         if (cur->value && *cur->value) {
4086           attr_color = apr_pstrdup(doc->pool, cur->value);
4087         }
4088       }
4089     }
4090   }
4091   W_L("<blockquote>");
4092   chtml30_flags_t *flg = (chtml30_flags_t *)apr_palloc(doc->pool, sizeof(chtml30_flags_t));
4093   memset(flg, 0, sizeof(*flg));
4094   if (attr_color) {
4095     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
4096     W_L("<font color=\"");
4097     W_V(attr_color);
4098     W_L("\">");
4099     flg->with_font_flag = 1;
4100   }
4101   node->userData = (void *)flg;
4102   return chtml30->out;
4103 }
4104
4105
4106 /**
4107  * It is a handler who processes the BLOCKQUOTE tag.
4108  *
4109  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4110  *                     destination is specified.
4111  * @param node   [i]   The BLOCKQUOTE tag node is specified.
4112  * @return The conversion result is returned.
4113  */
4114 static char *
4115 s_chtml30_end_blockquote_tag(void *pdoc, Node *node)
4116 {
4117   chtml30_t *chtml30 = GET_CHTML30(pdoc);
4118   Doc       *doc     = chtml30->doc;
4119   chtml30_flags_t *flg = (chtml30_flags_t *)node->userData;
4120   if (flg && flg->with_font_flag) {
4121     W_L("</font>");
4122   }
4123   W_L("</blockquote>");
4124   if (IS_CSS_ON(chtml30->entryp)) {
4125     chxj_css_pop_prop_list(chtml30->css_prop_stack);
4126   }
4127   return chtml30->out;
4128 }
4129
4130
4131 /**
4132  * It is a handler who processes the DIR tag.
4133  *
4134  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4135  *                     destination is specified.
4136  * @param node   [i]   The DIR tag node is specified.
4137  * @return The conversion result is returned.
4138  */
4139 static char *
4140 s_chtml30_start_dir_tag(void *pdoc, Node *node)
4141 {
4142   chtml30_t *chtml30;
4143   Doc       *doc;
4144   Attr      *attr;
4145   char      *attr_style = NULL;
4146   char      *attr_color = NULL;
4147
4148   chtml30 = GET_CHTML30(pdoc);
4149   doc     = chtml30->doc;
4150   for (attr = qs_get_attr(doc,node);
4151        attr;
4152        attr = qs_get_next_attr(doc,attr)) {
4153     char *nm  = qs_get_attr_name(doc,attr);
4154     char *val = qs_get_attr_value(doc,attr);
4155     if (val && STRCASEEQ('s','S',"style", nm)) {
4156       attr_style = val;
4157     }
4158   }
4159   if (IS_CSS_ON(chtml30->entryp)) {
4160     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
4161     if (style) {
4162       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
4163       css_property_t *cur;
4164       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
4165         if (cur->value && *cur->value) {
4166           attr_color = apr_pstrdup(doc->pool, cur->value);
4167         }
4168       }
4169     }
4170   }
4171   W_L("<dir>");
4172   chtml30_flags_t *flg = (chtml30_flags_t *)apr_palloc(doc->pool, sizeof(chtml30_flags_t));
4173   memset(flg, 0, sizeof(*flg));
4174   if (attr_color) {
4175     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
4176     W_L("<font color=\"");
4177     W_V(attr_color);
4178     W_L("\">");
4179     flg->with_font_flag = 1;
4180   }
4181   node->userData = (void *)flg;
4182   return chtml30->out;
4183 }
4184
4185
4186 /**
4187  * It is a handler who processes the DIR 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 DIR tag node is specified.
4192  * @return The conversion result is returned.
4193  */
4194 static char *
4195 s_chtml30_end_dir_tag(void *pdoc, Node *node)
4196 {
4197   CHTML30_END_OF_CLOSE_TAG_WITH_FONT_TAG("</dir>");
4198 }
4199
4200
4201 /**
4202  * It is a handler who processes the DL 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 DL tag node is specified.
4207  * @return The conversion result is returned.
4208  */
4209 static char *
4210 s_chtml30_start_dl_tag(void *pdoc, Node *node)
4211 {
4212   CHTML30_START_OF_TAG_WITH_CSS_FONT_COLOR("<dl>");
4213 }
4214
4215
4216 /**
4217  * It is a handler who processes the DL 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 DL tag node is specified.
4222  * @return The conversion result is returned.
4223  */
4224 static char *
4225 s_chtml30_end_dl_tag(void *pdoc, Node *node)
4226 {
4227   CHTML30_END_OF_CLOSE_TAG_WITH_FONT_TAG("</dl>");
4228 }
4229
4230
4231 /**
4232  * It is a handler who processes the DT 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 DT tag node is specified.
4237  * @return The conversion result is returned.
4238  */
4239 static char *
4240 s_chtml30_start_dt_tag(void *pdoc, Node *node)
4241 {
4242   CHTML30_START_OF_TAG_WITH_CSS_FONT_COLOR("<dt>");
4243 }
4244
4245
4246 /**
4247  * It is a handler who processes the DT 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 DT tag node is specified.
4252  * @return The conversion result is returned.
4253  */
4254 static char *
4255 s_chtml30_end_dt_tag(void *pdoc, Node *node)
4256 {
4257   CHTML30_END_OF_NO_CLOSE_TAG_WITH_FONT_TAG();
4258 }
4259
4260
4261 /**
4262  * It is a handler who processes the DD tag.
4263  *
4264  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4265  *                     destination is specified.
4266  * @param node   [i]   The DD tag node is specified.
4267  * @return The conversion result is returned.
4268  */
4269 static char *
4270 s_chtml30_start_dd_tag(void *pdoc, Node *node)
4271 {
4272   CHTML30_START_OF_TAG_WITH_CSS_FONT_COLOR("<dd>");
4273 }
4274
4275
4276 /**
4277  * It is a handler who processes the DD tag.
4278  *
4279  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4280  *                     destination is specified.
4281  * @param node   [i]   The DD tag node is specified.
4282  * @return The conversion result is returned.
4283  */
4284 static char *
4285 s_chtml30_end_dd_tag(void *pdoc, Node *node)
4286 {
4287   CHTML30_END_OF_NO_CLOSE_TAG_WITH_FONT_TAG();
4288 }
4289
4290
4291 /**
4292  * It is a handler who processes the MARQUEE tag.
4293  *
4294  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4295  *                     destination is specified.
4296  * @param node   [i]   The MARQUEE tag node is specified.
4297  * @return The conversion result is returned.
4298  */
4299 static char *
4300 s_chtml30_start_marquee_tag(void *pdoc, Node *node)
4301 {
4302   chtml30_t *chtml30 = GET_CHTML30(pdoc);
4303   Doc       *doc = chtml30->doc;
4304   Attr      *attr;
4305   char      *attr_direction = NULL;
4306   char      *attr_behavior  = NULL;
4307   char      *attr_loop      = NULL;
4308   char      *attr_style     = NULL;
4309   char      *attr_color     = NULL;
4310   /*--------------------------------------------------------------------------*/
4311   /* Get Attributes                                                           */
4312   /*--------------------------------------------------------------------------*/
4313   for (attr = qs_get_attr(doc,node);
4314        attr;
4315        attr = qs_get_next_attr(doc,attr)) {
4316     char *name   = qs_get_attr_name(doc,attr);
4317     char *value  = qs_get_attr_value(doc,attr);
4318     if (STRCASEEQ('d','D',"direction", name)) {
4319       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value))) {
4320         attr_direction = value;
4321       }
4322     }
4323     else if (STRCASEEQ('b','B',"behavior",name)) {
4324       if (value && (STRCASEEQ('s','S',"scroll",value) || STRCASEEQ('s','S',"slide",value) || STRCASEEQ('a','A',"alternate",value))) {
4325         attr_behavior = value;
4326       }
4327     }
4328     else if (STRCASEEQ('l','L',"loop",name)) {
4329       if (value && *value) {
4330         attr_loop = value;
4331       }
4332     }
4333     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
4334       attr_style = value;
4335     }
4336   }
4337   if (IS_CSS_ON(chtml30->entryp)) {
4338     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
4339     if (style) {
4340       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
4341       css_property_t *direction_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-dir");
4342       css_property_t *style_prop     = chxj_css_get_property_value(doc, style, "-wap-marquee-style");
4343       css_property_t *loop_prop      = chxj_css_get_property_value(doc, style, "-wap-marquee-loop");
4344       css_property_t *cur;
4345       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
4346         if (cur->value && *cur->value) {
4347           attr_color = apr_pstrdup(doc->pool, cur->value);
4348         }
4349       }
4350       for (cur = style_prop->next; cur != style_prop; cur = cur->next) {
4351         if (cur->value && *cur->value) {
4352           attr_behavior = apr_pstrdup(doc->pool, cur->value);
4353         }
4354       }
4355       for (cur = loop_prop->next; cur != loop_prop; cur = cur->next) {
4356         if (cur->value && *cur->value) {
4357           attr_loop = apr_pstrdup(doc->pool, cur->value);
4358           if (STRCASEEQ('i','I',"infinite",attr_loop)) {
4359             attr_loop = "16";
4360           }
4361         }
4362       }
4363       for (cur = direction_prop->next; cur != direction_prop; cur = cur->next) {
4364         if (cur->value && *cur->value) {
4365           if (STRCASEEQ('l','L',"ltr",cur->value)) {
4366             attr_direction = "right";
4367           }
4368           else if (STRCASEEQ('r','R',"rtl",cur->value)) {
4369             attr_direction = "left";
4370           }
4371         }
4372       }
4373     }
4374   }
4375   W_L("<marquee");
4376   if (attr_direction) {
4377     W_L(" direction=\"");
4378     W_V(attr_direction);
4379     W_L("\"");
4380   }
4381   if (attr_behavior) {
4382     W_L(" behavior=\"");
4383     W_V(attr_behavior);
4384     W_L("\"");
4385   }
4386   if (attr_loop) {
4387     W_L(" loop=\"");
4388     W_V(attr_loop);
4389     W_L("\"");
4390   }
4391   W_L("<marquee");
4392   if (attr_direction) {
4393     W_L(" direction=\"");
4394     W_V(attr_direction);
4395     W_L("\"");
4396   }
4397   if (attr_behavior) {
4398     W_L(" behavior=\"");
4399     W_V(attr_behavior);
4400     W_L("\"");
4401   }
4402   if (attr_loop) {
4403     W_L(" loop=\"");
4404     W_V(attr_loop);
4405     W_L("\"");
4406   }
4407   W_L(">");
4408
4409   chtml30_flags_t *flg = (chtml30_flags_t *)apr_palloc(doc->pool, sizeof(chtml30_flags_t));
4410   memset(flg, 0, sizeof(*flg));
4411   if (attr_color) {
4412     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
4413     W_L("<font color=\"");
4414     W_V(attr_color);
4415     W_L("\">");
4416     flg->with_font_flag = 1;
4417   }
4418   node->userData = (void *)flg;
4419   return chtml30->out;
4420 }
4421
4422
4423 /**
4424  * It is a handler who processes the MARQUEE tag.
4425  *
4426  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4427  *                     destination is specified.
4428  * @param node   [i]   The MARQUEE tag node is specified.
4429  * @return The conversion result is returned.
4430  */
4431 static char *
4432 s_chtml30_end_marquee_tag(void *pdoc, Node *node)
4433 {
4434   chtml30_t *chtml30 = GET_CHTML30(pdoc);
4435   Doc       *doc     = chtml30->doc;
4436   chtml30_flags_t *flg = (chtml30_flags_t *)node->userData;
4437   if (flg && flg->with_font_flag) {
4438     W_L("</font>");
4439   }
4440   W_L("</marquee>");
4441   if (IS_CSS_ON(chtml30->entryp)) {
4442     chxj_css_pop_prop_list(chtml30->css_prop_stack);
4443   }
4444   return chtml30->out;
4445 }
4446
4447
4448 /**
4449  * It is a handler who processes the BLINK tag.
4450  *
4451  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4452  *                     destination is specified.
4453  * @param node   [i]   The BLINK tag node is specified.
4454  * @return The conversion result is returned.
4455  */
4456 static char *
4457 s_chtml30_start_blink_tag(void *pdoc, Node *node)
4458 {
4459   CHTML30_START_OF_TAG_WITH_CSS_FONT_COLOR("<blink>");
4460 }
4461
4462
4463 /**
4464  * It is a handler who processes the BLINK tag.
4465  *
4466  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4467  *                     destination is specified.
4468  * @param node   [i]   The BLINK tag node is specified.
4469  * @return The conversion result is returned.
4470  */
4471 static char *
4472 s_chtml30_end_blink_tag(void *pdoc, Node *node)
4473 {
4474   CHTML30_END_OF_CLOSE_TAG_WITH_FONT_TAG("</blink>");
4475 }
4476
4477
4478 /**
4479  * It is a handler who processes the MENU tag.
4480  *
4481  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4482  *                     destination is specified.
4483  * @param node   [i]   The MENU tag node is specified.
4484  * @return The conversion result is returned.
4485  */
4486 static char *
4487 s_chtml30_start_menu_tag(void *pdoc, Node *node)
4488 {
4489   CHTML30_START_OF_TAG_WITH_CSS_FONT_COLOR("<menu>");
4490 }
4491
4492
4493 /**
4494  * It is a handler who processes the MENU tag.
4495  *
4496  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4497  *                     destination is specified.
4498  * @param node   [i]   The MENU tag node is specified.
4499  * @return The conversion result is returned.
4500  */
4501 static char *
4502 s_chtml30_end_menu_tag(void *pdoc, Node *node)
4503 {
4504   CHTML30_END_OF_CLOSE_TAG_WITH_FONT_TAG("</menu>");
4505 }
4506
4507
4508 /**
4509  * It is a handler who processes the PLAINTEXT tag.
4510  *
4511  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4512  *                     destination is specified.
4513  * @param node   [i]   The PLAINTEXT tag node is specified.
4514  * @return The conversion result is returned.
4515  */
4516 static char *
4517 s_chtml30_start_plaintext_tag(void *pdoc, Node *node)
4518 {
4519   chtml30_t *chtml30 = GET_CHTML30(pdoc);
4520   Doc       *doc     = chtml30->doc;
4521   W_L("<plaintext>");
4522   s_chtml30_start_plaintext_tag_inner(pdoc,node);
4523   return chtml30->out;
4524 }
4525
4526 static char *
4527 s_chtml30_start_plaintext_tag_inner(void *pdoc, Node *node)
4528 {
4529   chtml30_t *chtml30 = GET_CHTML30(pdoc);
4530   Doc       *doc     = chtml30->doc;
4531   Node      *child;
4532   for (child = qs_get_child_node(doc, node);
4533        child;
4534        child = qs_get_next_node(doc, child)) {
4535     W_V(child->otext);
4536     s_chtml30_start_plaintext_tag_inner(pdoc, child);
4537   }
4538   return chtml30->out;
4539 }
4540
4541
4542 /**
4543  * It is a handler who processes the PLAINTEXT tag.
4544  *
4545  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4546  *                     destination is specified.
4547  * @param node   [i]   The PLAINTEXT tag node is specified.
4548  * @return The conversion result is returned.
4549  */
4550 static char *
4551 s_chtml30_end_plaintext_tag(void *pdoc, Node *UNUSED(child))
4552 {
4553   chtml30_t *chtml30 = GET_CHTML30(pdoc);
4554   return chtml30->out;
4555 }
4556
4557
4558 /**
4559  *  * It is handler who processes the New Line Code.
4560  *   */
4561 static char *
4562 s_chtml30_newline_mark(void *pdoc, Node *UNUSED(node))
4563 {
4564   chtml30_t *chtml30 = GET_CHTML30(pdoc);
4565   Doc *doc = chtml30->doc;
4566   W_NLCODE();
4567   return chtml30->out;
4568 }
4569
4570
4571 /**
4572  * It is a handler who processes the LINK tag.
4573  *
4574  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4575  *                     destination is specified.
4576  * @param node   [i]   The LINK tag node is specified.
4577  * @return The conversion result is returned.
4578  */
4579 static char *
4580 s_chtml30_link_tag(void *pdoc, Node *node)
4581 {
4582   chtml30_t     *chtml30;
4583   Doc           *doc;
4584   Attr          *attr;
4585   char          *rel  = NULL;
4586   char          *href = NULL;
4587   char          *type = NULL;
4588
4589   chtml30 = GET_CHTML30(pdoc);
4590   doc     = chtml30->doc;
4591
4592   if (! IS_CSS_ON(chtml30->entryp)) {
4593     return chtml30->out;
4594   }
4595
4596   for (attr = qs_get_attr(doc,node);
4597        attr;
4598        attr = qs_get_next_attr(doc,attr)) {
4599     char *name  = qs_get_attr_name(doc,attr);
4600     char *value = qs_get_attr_value(doc,attr);
4601     if (STRCASEEQ('r','R',"rel", name)) {
4602       if (value && *value && STRCASEEQ('s','S',"stylesheet", value)) {
4603         rel = value;
4604       }
4605     }
4606     else if (STRCASEEQ('h','H',"href", name)) {
4607       if (value && *value) {
4608         href = value;
4609       }
4610     }
4611     else if (STRCASEEQ('t','T',"type", name)) {
4612       if (value && *value && STRCASEEQ('t','T',"text/css",value)) {
4613         type = value;
4614       }
4615     }
4616   }
4617
4618   if (rel && href && type) {
4619     DBG(doc->r, "start load CSS. url:[%s]", href);
4620     chtml30->style = chxj_css_parse_from_uri(doc->r, doc->pool, chtml30->style, href);
4621     DBG(doc->r, "end load CSS. url:[%s]", href);
4622   }
4623
4624   return chtml30->out;
4625 }
4626
4627
4628 static css_prop_list_t *
4629 s_chtml30_push_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value)
4630 {
4631   chtml30_t *chtml30 = GET_CHTML30(pdoc);
4632   Doc *doc = chtml30->doc;
4633   css_prop_list_t *last_css = NULL;
4634   if (IS_CSS_ON(chtml30->entryp)) {
4635     css_prop_list_t *dup_css;
4636     css_selector_t  *selector;
4637
4638     last_css = chxj_css_get_last_prop_list(chtml30->css_prop_stack);
4639     dup_css  = chxj_dup_css_prop_list(doc, last_css);
4640     selector = chxj_css_find_selector(doc, chtml30->style, node);
4641     if (selector) {
4642       chxj_css_prop_list_merge_property(doc, dup_css, selector);
4643     }
4644     chxj_css_push_prop_list(chtml30->css_prop_stack, dup_css);
4645     last_css = chxj_css_get_last_prop_list(chtml30->css_prop_stack);
4646
4647     if (style_attr_value) {
4648       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));
4649       if (ssheet) {
4650         chxj_css_prop_list_merge_property(doc, last_css, ssheet->selector_head.next);
4651       }
4652     }
4653   }
4654   return last_css;
4655 }
4656
4657
4658 static css_prop_list_t *
4659 s_chtml30_nopush_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value)
4660 {
4661   chtml30_t *chtml30 = GET_CHTML30(pdoc);
4662   Doc *doc = chtml30->doc;
4663   css_prop_list_t *last_css = NULL;
4664   if (IS_CSS_ON(chtml30->entryp)) {
4665     css_prop_list_t *dup_css;
4666     css_selector_t  *selector;
4667
4668     last_css = chxj_css_get_last_prop_list(chtml30->css_prop_stack);
4669     dup_css  = chxj_dup_css_prop_list(doc, last_css);
4670     selector = chxj_css_find_selector(doc, chtml30->style, node);
4671     if (selector) {
4672       chxj_css_prop_list_merge_property(doc, dup_css, selector);
4673     }
4674     last_css = dup_css;
4675
4676     if (style_attr_value) {
4677       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));
4678       if (ssheet) {
4679         chxj_css_prop_list_merge_property(doc, last_css, ssheet->selector_head.next);
4680       }
4681     }
4682   }
4683   return last_css;
4684 }
4685
4686
4687
4688 /**
4689  * It is a handler who processes the SPAN tag.
4690  *
4691  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4692  *                     destination is specified.
4693  * @param node   [i]   The SPAN tag node is specified.
4694  * @return The conversion result is returned.
4695  */
4696 static char *
4697 s_chtml30_start_span_tag(void *pdoc, Node *node)
4698 {
4699   chtml30_t *chtml30;
4700   Doc *doc;
4701   Attr *attr;
4702   char *attr_style = NULL;
4703   char *attr_color = NULL;
4704   char *attr_align = NULL;
4705   char *attr_blink = NULL;
4706   char *attr_marquee = NULL;
4707   char *attr_marquee_dir = NULL;
4708   char *attr_marquee_style = NULL;
4709   char *attr_marquee_loop = NULL;
4710
4711   chtml30 = GET_CHTML30(pdoc);
4712   doc     = chtml30->doc;
4713
4714   for (attr = qs_get_attr(doc,node);
4715        attr;
4716        attr = qs_get_next_attr(doc,attr)) {
4717     char *nm  = qs_get_attr_name(doc,attr);
4718     char *val = qs_get_attr_value(doc,attr);
4719     if (val && STRCASEEQ('s','S',"style", nm)) {
4720       attr_style = val;
4721     }
4722   }
4723   if (IS_CSS_ON(chtml30->entryp)) {
4724     css_prop_list_t *style = s_chtml30_push_and_get_now_style(pdoc, node, attr_style);
4725     if (style) {
4726       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
4727       css_property_t *text_align_prop = chxj_css_get_property_value(doc, style, "text-align");
4728       css_property_t *decoration_prop = chxj_css_get_property_value(doc, style, "text-decoration");
4729       css_property_t *display_prop = chxj_css_get_property_value(doc, style, "display");
4730       css_property_t *marquee_dir_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-dir");
4731       css_property_t *marquee_style_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-style");
4732       css_property_t *marquee_loop_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-loop");
4733       css_property_t *cur;
4734       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
4735         attr_color = apr_pstrdup(doc->pool, cur->value);
4736       }
4737       for (cur = decoration_prop->next; cur != decoration_prop; cur = cur->next) {
4738         if (cur->value && STRCASEEQ('b','B',"blink",cur->value)) {
4739           attr_blink = apr_pstrdup(doc->pool, cur->value);
4740         }
4741       }
4742       for (cur = display_prop->next; cur != display_prop; cur = cur->next) {
4743         if (cur->value && strcasecmp("-wap-marquee",cur->value) == 0) {
4744           attr_marquee = apr_pstrdup(doc->pool, cur->value);
4745         }
4746       }
4747       for (cur = marquee_dir_prop->next; cur != marquee_dir_prop; cur = cur->next) {
4748         if (cur->value && *cur->value) {
4749           if (STRCASEEQ('l','L',"ltr",cur->value)) {
4750             attr_marquee_dir = "right";
4751           }
4752           else if (STRCASEEQ('r','R',"rtl",cur->value)) {
4753             attr_marquee_dir = "left";
4754           }
4755         }
4756       }
4757       for (cur = marquee_style_prop->next; cur != marquee_style_prop; cur = cur->next) {
4758         if (cur->value && *cur->value) {
4759           if ( STRCASEEQ('s','S',"scroll",cur->value)
4760             || STRCASEEQ('s','S',"slide",cur->value)
4761             || STRCASEEQ('a','A',"alternate",cur->value)) {
4762             attr_marquee_style = apr_pstrdup(doc->pool, cur->value);
4763           }
4764         }
4765       }
4766       for (cur = marquee_loop_prop->next; cur != marquee_loop_prop; cur = cur->next) {
4767         if (cur->value && *cur->value) {
4768           if (STRCASEEQ('i','I',"infinite",cur->value)) {
4769             attr_marquee_loop = "16";
4770           }
4771           else {
4772             attr_marquee_loop = apr_pstrdup(doc->pool, cur->value);
4773           }
4774         }
4775       }
4776       for (cur = text_align_prop->next; cur != text_align_prop; cur = cur->next) {
4777         if (STRCASEEQ('l','L',"left", cur->value)) {
4778           attr_align = apr_pstrdup(doc->pool, "left");
4779         }
4780         else if (STRCASEEQ('c','C',"center",cur->value)) {
4781           attr_align = apr_pstrdup(doc->pool, "center");
4782         }
4783         else if (STRCASEEQ('r','R',"right",cur->value)) {
4784           attr_align = apr_pstrdup(doc->pool, "right");
4785         }
4786       }
4787     }
4788   }
4789   if (attr_color || attr_align || attr_blink || attr_marquee) {
4790     chtml30_flags_t *flg = apr_palloc(doc->pool, sizeof(*flg));
4791     memset(flg, 0, sizeof(*flg));
4792     if (attr_blink) {
4793       W_L("<blink>");
4794       flg->with_blink_flag = 1;
4795     }
4796     if (attr_marquee) {
4797       W_L("<marquee");
4798       if (attr_marquee_dir) {
4799         W_L(" direction=\"");
4800         W_V(attr_marquee_dir);
4801         W_L("\"");
4802       }
4803       if (attr_marquee_style) {
4804         W_L(" behavior=\"");
4805         W_V(attr_marquee_style);
4806         W_L("\"");
4807       }
4808       if (attr_marquee_loop) {
4809         W_L(" loop=\"");
4810         W_V(attr_marquee_loop);
4811         W_L("\"");
4812       }
4813       W_L(">");
4814       flg->with_marquee_flag = 1;
4815     }
4816     if (attr_color) {
4817       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
4818       W_L("<font color=\"");
4819       W_V(attr_color);
4820       W_L("\">");
4821       flg->with_font_flag = 1;
4822     }
4823     if (attr_align) {
4824       W_L("<div align=\"");
4825       W_V(attr_align);
4826       W_L("\">");
4827       flg->with_div_flag = 1;
4828     }
4829     node->userData = flg;
4830   }
4831   else {
4832     node->userData = NULL;
4833   }
4834   return chtml30->out;
4835 }
4836
4837
4838 /**
4839  * It is a handler who processes the SPAN tag.
4840  *
4841  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4842  *                     destination is specified.
4843  * @param node   [i]   The SPAN tag node is specified.
4844  * @return The conversion result is returned.
4845  */
4846 static char *
4847 s_chtml30_end_span_tag(void *pdoc, Node *node)
4848 {
4849   chtml30_t *chtml30 = GET_CHTML30(pdoc);
4850   Doc *doc = chtml30->doc;
4851
4852   chtml30_flags_t *flg = (chtml30_flags_t *)node->userData;
4853   if (flg && flg->with_div_flag) {
4854     W_L("</div>");
4855   }
4856   if (flg && flg->with_font_flag) {
4857     W_L("</font>");
4858   }
4859   if (flg && flg->with_marquee_flag) {
4860     W_L("</marquee>");
4861   }
4862   if (flg && flg->with_blink_flag) {
4863     W_L("</blink>");
4864   }
4865   if (IS_CSS_ON(chtml30->entryp)) {
4866     chxj_css_pop_prop_list(chtml30->css_prop_stack);
4867   }
4868   return chtml30->out;
4869 }
4870
4871
4872
4873 /**
4874  * It is a handler who processes the STYLE tag.
4875  *
4876  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4877  *                     destination is specified.
4878  * @param node   [i]   The STYLE tag node is specified.
4879  * @return The conversion result is returned.
4880  */
4881 static char *
4882 s_chtml30_style_tag(void *pdoc, Node *node)
4883 {
4884   chtml30_t     *chtml30;
4885   Doc           *doc;
4886   Attr          *attr;
4887   char          *type = NULL;
4888
4889   chtml30 = GET_CHTML30(pdoc);
4890   doc     = chtml30->doc;
4891
4892   if (! IS_CSS_ON(chtml30->entryp)) {
4893     return chtml30->out;
4894   }
4895
4896   for (attr = qs_get_attr(doc,node);
4897        attr;
4898        attr = qs_get_next_attr(doc,attr)) {
4899     char *name  = qs_get_attr_name(doc,attr);
4900     char *value = qs_get_attr_value(doc,attr);
4901     if (STRCASEEQ('t','T',"type", name)) {
4902       if (value && *value && STRCASEEQ('t','T',"text/css",value)) {
4903         type = value;
4904       }
4905     }
4906   }
4907
4908   Node *child = qs_get_child_node(doc, node);
4909   if (type && child) {
4910     char *name  = qs_get_node_name(doc, child);
4911     if (STRCASEEQ('t','T',"text", name)) {
4912       char *value = qs_get_node_value(doc, child);
4913       DBG(doc->r, "start load CSS. buf:[%s]", value);
4914       chtml30->style = chxj_css_parse_style_value(doc, chtml30->style, value);
4915       DBG(doc->r, "end load CSS. value:[%s]", value);
4916     }
4917   }
4918   return chtml30->out;
4919 }
4920 /*
4921  * vim:ts=2 et
4922  */