OSDN Git Service

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