OSDN Git Service

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