OSDN Git Service

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