OSDN Git Service

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