OSDN Git Service

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