OSDN Git Service

* copy from old-trunk
[modchxj/mod_chxj.git] / src / chxj_chtml50.c
1 /*
2  * Copyright (C) 2005-2008 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
27 #define GET_CHTML50(X) ((chtml50_t *)(X))
28 #undef W_L
29 #undef W_V
30 #define W_L(X)          do { chtml50->out = BUFFERED_WRITE_LITERAL(chtml50->out, &doc->buf, (X)); } while(0)
31 #define W_V(X)          do { chtml50->out = (X) ? BUFFERED_WRITE_VALUE(chtml50->out, &doc->buf, (X))  \
32                                                 : BUFFERED_WRITE_LITERAL(chtml50->out, &doc->buf, ""); } while(0)
33 #undef W_NLCODE
34 #define W_NLCODE()     do { char *nlcode = TO_NLCODE(chtml50->conf); W_V(nlcode); } while (0)
35
36 static char *s_chtml50_start_html_tag     (void *pdoc, Node *node);
37 static char *s_chtml50_end_html_tag       (void *pdoc, Node *node);
38 static char *s_chtml50_start_meta_tag     (void *pdoc, Node *node);
39 static char *s_chtml50_end_meta_tag       (void *pdoc, Node *node);
40 static char *s_chtml50_start_textarea_tag (void *pdoc, Node *node);
41 static char *s_chtml50_end_textarea_tag   (void *pdoc, Node *node);
42 static char *s_chtml50_start_p_tag        (void *pdoc, Node *node);
43 static char *s_chtml50_end_p_tag          (void *pdoc, Node *node);
44 static char *s_chtml50_start_pre_tag      (void *pdoc, Node *node);
45 static char *s_chtml50_end_pre_tag        (void *pdoc, Node *node);
46 static char *s_chtml50_start_h1_tag       (void *pdoc, Node *node);
47 static char *s_chtml50_end_h1_tag         (void *pdoc, Node *node);
48 static char *s_chtml50_start_h2_tag       (void *pdoc, Node *node);
49 static char *s_chtml50_end_h2_tag         (void *pdoc, Node *node);
50 static char *s_chtml50_start_h3_tag       (void *pdoc, Node *node);
51 static char *s_chtml50_end_h3_tag         (void *pdoc, Node *node);
52 static char *s_chtml50_start_h4_tag       (void *pdoc, Node *node);
53 static char *s_chtml50_end_h4_tag         (void *pdoc, Node *node);
54 static char *s_chtml50_start_h5_tag       (void *pdoc, Node *node);
55 static char *s_chtml50_end_h5_tag         (void *pdoc, Node *node);
56 static char *s_chtml50_start_h6_tag       (void *pdoc, Node *node);
57 static char *s_chtml50_end_h6_tag         (void *pdoc, Node *node);
58 static char *s_chtml50_start_ul_tag       (void *pdoc, Node *node);
59 static char *s_chtml50_end_ul_tag         (void *pdoc, Node *node);
60 static char *s_chtml50_start_ol_tag       (void *pdoc, Node *node);
61 static char *s_chtml50_end_ol_tag         (void *pdoc, Node *node);
62 static char *s_chtml50_start_li_tag       (void *pdoc, Node *node);
63 static char *s_chtml50_end_li_tag         (void *pdoc, Node *node);
64 static char *s_chtml50_start_head_tag     (void *pdoc, Node *node);
65 static char *s_chtml50_end_head_tag       (void *pdoc, Node *node);
66 static char *s_chtml50_start_title_tag    (void *pdoc, Node *node);
67 static char *s_chtml50_end_title_tag      (void *pdoc, Node *node);
68 static char *s_chtml50_start_base_tag     (void *pdoc, Node *node);
69 static char *s_chtml50_end_base_tag       (void *pdoc, Node *node);
70 static char *s_chtml50_start_body_tag     (void *pdoc, Node *node);
71 static char *s_chtml50_end_body_tag       (void *pdoc, Node *node);
72 static char *s_chtml50_start_a_tag        (void *pdoc, Node *node);
73 static char *s_chtml50_end_a_tag          (void *pdoc, Node *node);
74 static char *s_chtml50_start_br_tag       (void *pdoc, Node *node);
75 static char *s_chtml50_end_br_tag         (void *pdoc, Node *node);
76 static char *s_chtml50_start_tr_tag       (void *pdoc, Node *node);
77 static char *s_chtml50_end_tr_tag         (void *pdoc, Node *node);
78 static char *s_chtml50_start_font_tag     (void *pdoc, Node *node);
79 static char *s_chtml50_end_font_tag       (void *pdoc, Node *node);
80 static char *s_chtml50_start_form_tag     (void *pdoc, Node *node);
81 static char *s_chtml50_end_form_tag       (void *pdoc, Node *node);
82 static char *s_chtml50_start_input_tag    (void *pdoc, Node *node);
83 static char *s_chtml50_end_input_tag      (void *pdoc, Node *node);
84 static char *s_chtml50_start_center_tag   (void *pdoc, Node *node);
85 static char *s_chtml50_end_center_tag     (void *pdoc, Node *node);
86 static char *s_chtml50_start_hr_tag       (void *pdoc, Node *node);
87 static char *s_chtml50_end_hr_tag         (void *pdoc, Node *node);
88 static char *s_chtml50_start_img_tag      (void *pdoc, Node *node);
89 static char *s_chtml50_end_img_tag        (void *pdoc, Node *node);
90 static char *s_chtml50_start_select_tag   (void *pdoc, Node *node);
91 static char *s_chtml50_end_select_tag     (void *pdoc, Node *node);
92 static char *s_chtml50_start_option_tag   (void *pdoc, Node *node);
93 static char *s_chtml50_end_option_tag     (void *pdoc, Node *node);
94 static char *s_chtml50_start_div_tag      (void *pdoc, Node *node);
95 static char *s_chtml50_end_div_tag        (void *pdoc, Node *node);
96 static char *s_chtml50_chxjif_tag         (void *pdoc, Node *node); 
97 static char *s_chtml50_text_tag           (void *pdoc, Node *node);
98 static char *s_chtml50_start_blockquote_tag(void *pdoc, Node *node);
99 static char *s_chtml50_end_blockquote_tag  (void *pdoc, Node *node);
100 static char *s_chtml50_start_dir_tag      (void *pdoc, Node *node);
101 static char *s_chtml50_end_dir_tag        (void *pdoc, Node *node);
102 static char *s_chtml50_start_dl_tag       (void *pdoc, Node *node);
103 static char *s_chtml50_end_dl_tag         (void *pdoc, Node *node);
104 static char *s_chtml50_start_dt_tag       (void *pdoc, Node *node);
105 static char *s_chtml50_end_dt_tag         (void *pdoc, Node *node);
106 static char *s_chtml50_start_dd_tag       (void *pdoc, Node *node);
107 static char *s_chtml50_end_dd_tag         (void *pdoc, Node *node);
108 static char *s_chtml50_start_marquee_tag  (void *pdoc, Node *node);
109 static char *s_chtml50_end_marquee_tag    (void *pdoc, Node *node);
110 static char *s_chtml50_start_blink_tag    (void *pdoc, Node *node);
111 static char *s_chtml50_end_blink_tag      (void *pdoc, Node *node);
112 static char *s_chtml50_start_menu_tag     (void *pdoc, Node *node);
113 static char *s_chtml50_end_menu_tag       (void *pdoc, Node *node);
114 static char *s_chtml50_start_plaintext_tag       (void *pdoc, Node *node);
115 static char *s_chtml50_start_plaintext_tag_inner (void *pdoc, Node *node);
116 static char *s_chtml50_end_plaintext_tag         (void *pdoc, Node *node);
117 static char *s_chtml50_newline_mark       (void *pdoc, Node *node);
118
119 static void  s_init_chtml50(chtml50_t *chtml, Doc *doc, request_rec *r, device_table *spec);
120
121 static int   s_chtml50_search_emoji(chtml50_t *chtml, char *txt, char **rslt);
122
123
124 tag_handler chtml50_handler[] = {
125   /* tagHTML */
126   {
127     s_chtml50_start_html_tag,
128     s_chtml50_end_html_tag,
129   },
130   /* tagMETA */
131   {
132     s_chtml50_start_meta_tag,
133     s_chtml50_end_meta_tag,
134   },
135   /* tagTEXTAREA */
136   {
137     s_chtml50_start_textarea_tag,
138     s_chtml50_end_textarea_tag,
139   },
140   /* tagP */
141   {
142     s_chtml50_start_p_tag,
143     s_chtml50_end_p_tag,
144   },
145   /* tagPRE */
146   {
147     s_chtml50_start_pre_tag,
148     s_chtml50_end_pre_tag,
149   },
150   /* tagUL */
151   {
152     s_chtml50_start_ul_tag,
153     s_chtml50_end_ul_tag,
154   },
155   /* tagLI */
156   {
157     s_chtml50_start_li_tag,
158     s_chtml50_end_li_tag,
159   },
160   /* tagOL */
161   {
162     s_chtml50_start_ol_tag,
163     s_chtml50_end_ol_tag,
164   },
165   /* tagH1 */
166   {
167     s_chtml50_start_h1_tag,
168     s_chtml50_end_h1_tag,
169   },
170   /* tagH2 */
171   {
172     s_chtml50_start_h2_tag,
173     s_chtml50_end_h2_tag,
174   },
175   /* tagH3 */
176   {
177     s_chtml50_start_h3_tag,
178     s_chtml50_end_h3_tag,
179   },
180   /* tagH4 */
181   {
182     s_chtml50_start_h4_tag,
183     s_chtml50_end_h4_tag,
184   },
185   /* tagH5 */
186   {
187     s_chtml50_start_h5_tag,
188     s_chtml50_end_h5_tag,
189   },
190   /* tagH6 */
191   {
192     s_chtml50_start_h6_tag,
193     s_chtml50_end_h6_tag,
194   },
195   /* tagHEAD */
196   {
197     s_chtml50_start_head_tag,
198     s_chtml50_end_head_tag,
199   },
200   /* tagTITLE */
201   {
202     s_chtml50_start_title_tag,
203     s_chtml50_end_title_tag,
204   },
205   /* tagBASE */
206   {
207     s_chtml50_start_base_tag,
208     s_chtml50_end_base_tag,
209   },
210   /* tagBODY */
211   {
212     s_chtml50_start_body_tag,
213     s_chtml50_end_body_tag,
214   },
215   /* tagA */
216   {
217     s_chtml50_start_a_tag,
218     s_chtml50_end_a_tag,
219   },
220   /* tagBR */
221   {
222     s_chtml50_start_br_tag,
223     s_chtml50_end_br_tag,
224   },
225   /* tagTABLE */
226   {
227     NULL,
228     NULL,
229   },
230   /* tagTR */
231   {
232     s_chtml50_start_tr_tag,
233     s_chtml50_end_tr_tag,
234   },
235   /* tagTD */
236   {
237     NULL,
238     NULL,
239   },
240   /* tagTBODY */
241   {
242     NULL,
243     NULL,
244   },
245   /* tagFONT */
246   {
247     s_chtml50_start_font_tag,
248     s_chtml50_end_font_tag,
249   },
250   /* tagFORM */
251   {
252     s_chtml50_start_form_tag,
253     s_chtml50_end_form_tag,
254   },
255   /* tagINPUT */
256   {
257     s_chtml50_start_input_tag,
258     s_chtml50_end_input_tag,
259   },
260   /* tagCENTER */
261   {
262     s_chtml50_start_center_tag,
263     s_chtml50_end_center_tag,
264   },
265   /* tagHR */
266   {
267     s_chtml50_start_hr_tag,
268     s_chtml50_end_hr_tag,
269   },
270   /* tagIMG */
271   {
272     s_chtml50_start_img_tag,
273     s_chtml50_end_img_tag,
274   },
275   /* tagSELECT */
276   {
277     s_chtml50_start_select_tag,
278     s_chtml50_end_select_tag,
279   },
280   /* tagOPTION */
281   {
282     s_chtml50_start_option_tag,
283     s_chtml50_end_option_tag,
284   },
285   /* tagDIV */
286   {
287     s_chtml50_start_div_tag,
288     s_chtml50_end_div_tag,
289   },
290   /* tagCHXJIF */
291   {
292     s_chtml50_chxjif_tag,
293     NULL,
294   },
295   /* tagNOBR */
296   {
297     NULL,
298     NULL,
299   },
300   /* tagSMALL */
301   {
302     NULL,
303     NULL,
304   },
305   /* tagSTYLE */
306   {
307     NULL,
308     NULL,
309   },
310   /* tagSPAN */
311   {
312     NULL,
313     NULL,
314   },
315   /* tagTEXT */
316   {
317     s_chtml50_text_tag,
318     NULL,
319   },
320   /* tagTH */
321   {
322     NULL,
323     NULL,
324   },
325   /* tagB */
326   {
327     NULL,
328     NULL,
329   },
330   /* tagFIELDSET */
331   {
332     NULL,
333     NULL,
334   },
335   /* tagDT */
336   {
337     s_chtml50_start_dt_tag,
338     s_chtml50_end_dt_tag,
339   },
340   /* tagLEGEND */
341   {
342     NULL,
343     NULL,
344   },
345   /* tagLABEL */
346   {
347     NULL,
348     NULL,
349   },
350   /* tagBLOCKQUOTE */
351   {
352     s_chtml50_start_blockquote_tag,
353     s_chtml50_end_blockquote_tag,
354   },
355   /* tagDIR */
356   {
357     s_chtml50_start_dir_tag,
358     s_chtml50_end_dir_tag,
359   },
360   /* tagDL */
361   {
362     s_chtml50_start_dl_tag,
363     s_chtml50_end_dl_tag,
364   },
365   /* tagDD */
366   {
367     s_chtml50_start_dd_tag,
368     s_chtml50_end_dd_tag,
369   },
370   /* tagMENU */
371   {
372     s_chtml50_start_menu_tag,
373     s_chtml50_end_menu_tag,
374   },
375   /* tagPLAINTEXT */
376   {
377     s_chtml50_start_plaintext_tag,
378     s_chtml50_end_plaintext_tag,
379   },
380   /* tagBLINK */
381   {
382     s_chtml50_start_blink_tag,
383     s_chtml50_end_blink_tag,
384   },
385   /* tagMARQUEE */
386   {
387     s_chtml50_start_marquee_tag,
388     s_chtml50_end_marquee_tag,
389   },
390   /* tagNLMARK */
391   {
392     s_chtml50_newline_mark,
393     NULL,
394   },
395 };
396
397
398 /**
399  * converts from CHTML5.0 to CHTML3.0.
400  *
401  * @param r     [i]   Requet_rec is appointed.
402  * @param spec  [i]   The result of the device specification processing which 
403  *                    was done in advance is appointed.
404  * @param src   [i]   The character string before the converting is appointed.
405  * @return The character string after the converting is returned.
406  */
407 char*
408 chxj_convert_chtml50(
409   request_rec         *r,
410   device_table        *spec,
411   const char          *src,
412   apr_size_t          srclen,
413   apr_size_t          *dstlen,
414   chxjconvrule_entry  *entryp,
415   cookie_t            *cookie
416 )
417 {
418   char      *dst = NULL;
419   char      *ss;
420   chtml50_t chtml50;
421   Doc       doc;
422
423   DBG(r, "start chxj_convert_chtml50()");
424
425   /*--------------------------------------------------------------------------*/
426   /* If qrcode xml                                                            */
427   /*--------------------------------------------------------------------------*/
428   *dstlen = srclen;
429   dst = chxj_qr_code_blob_handler(r, src, (size_t*)dstlen);
430   if (dst) {
431     DBG(r,"i found qrcode xml");
432     DBG(r, "end chxj_convert_chtml50()");
433     return dst;
434   }
435   DBG(r,"not found qrcode xml");
436
437   /*--------------------------------------------------------------------------*/
438   /* The CHTML structure is initialized.                                      */
439   /*--------------------------------------------------------------------------*/
440   s_init_chtml50(&chtml50, &doc, r, spec);
441
442   chtml50.entryp = entryp;
443   chtml50.cookie = cookie;
444
445   chxj_set_content_type(r, chxj_header_inf_set_content_type(r, "text/html; charset=Windows-31J"));
446
447   /*--------------------------------------------------------------------------*/
448   /* The character string of the input is analyzed.                           */
449   /*--------------------------------------------------------------------------*/
450   qs_init_malloc(&doc);
451   qs_init_root_node(&doc);
452
453   ss = apr_pcalloc(r->pool, srclen + 1);
454   memset(ss, 0, srclen + 1);
455   memcpy(ss, src, srclen);
456
457 #ifdef DUMP_LOG
458   chxj_dump_out("[src] CHTML -> CHTML4.0", ss, srclen);
459 #endif
460   chxj_buffered_write_init(r->pool, &doc.buf);
461
462   qs_parse_string(&doc,ss, strlen(ss));
463
464   /*--------------------------------------------------------------------------*/
465   /* It converts it from CHTML to CHTML.                                      */
466   /*--------------------------------------------------------------------------*/
467   chxj_node_convert(spec,r,(void*)&chtml50, &doc, qs_get_root(&doc), 0);
468   chtml50.out = chxj_buffered_write_flush(chtml50.out, &doc.buf);
469   dst = apr_pstrdup(r->pool, chtml50.out);
470   chxj_buffered_write_terminate(&doc.buf);
471
472   qs_all_free(&doc,QX_LOGMARK);
473
474   if (dst == NULL) {
475     dst = apr_pstrdup(r->pool,ss);
476   }
477   if (strlen(dst) == 0) {
478     dst = apr_psprintf(r->pool, "\n");
479   }
480
481   *dstlen = strlen(dst);
482
483 #ifdef DUMP_LOG
484   chxj_dump_out("[src] CHTML -> CHTML4.0", dst, *dstlen);
485 #endif
486
487   DBG(r, "end chxj_convert_chtml50()");
488   return dst;
489 }
490
491
492 /**
493  * The CHTML structure is initialized.
494  *
495  * @param chtml50 [i/o] The pointer to the HDML structure that wants to be
496  *                   initialized is specified.
497  * @param doc   [i]   The Doc structure that should be set to the initialized
498  *                   HDML structure is specified.
499  * @param r     [i]   To use POOL, the pointer to request_rec is specified.
500  * @param spec  [i]   The pointer to the device_table
501  */
502 static void
503 s_init_chtml50(chtml50_t *chtml50, Doc *doc, request_rec *r, device_table *spec)
504 {
505   memset(doc,     0, sizeof(Doc));
506   memset(chtml50, 0, sizeof(chtml50_t));
507
508   doc->r        = r;
509   chtml50->doc  = doc;
510   chtml50->spec = spec;
511   chtml50->out  = qs_alloc_zero_byte_string(r->pool);
512   chtml50->conf = chxj_get_module_config(r->per_dir_config, &chxj_module);
513   chtml50->doc->parse_mode = PARSE_MODE_CHTML;
514 }
515
516
517 /**
518  * Corresponding EMOJI to a current character-code is retrieved. 
519  * The substitution character string is stored in the rslt pointer if agreeing.
520  *
521  * @param chtml50   [i]   The pointer to the CHTML structure is specified. 
522  * @param txt     [i]   The character string to want to examine whether it is 
523  *                      EMOJI is specified. 
524  * @param rslt    [o]   The pointer to the pointer that stores the result is 
525  *                      specified. 
526  * @return When corresponding EMOJI exists, it returns it excluding 0. 
527  */
528 static int
529 s_chtml50_search_emoji(chtml50_t *chtml50, char *txt, char **rslt)
530 {
531   emoji_t       *ee;
532   request_rec   *r;
533   device_table  *spec;
534   int           len;
535
536   spec = chtml50->spec;
537
538   len = strlen(txt);
539   r   = chtml50->doc->r;
540
541   if (!spec) {
542     DBG(r,"spec is NULL");
543   }
544
545   for (ee = chtml50->conf->emoji;
546        ee;
547        ee = ee->next) {
548     if (ee->imode == NULL) {
549       DBG(r, "emoji->imode is NULL");
550       continue;
551     }
552
553     if (ee->imode->string != NULL
554     &&  strlen(ee->imode->string) > 0
555     &&  strncasecmp(ee->imode->string, txt, strlen(ee->imode->string)) == 0) {
556
557       if (spec == NULL || spec->emoji_type == NULL) {
558         *rslt = apr_palloc(r->pool, 3);
559         (*rslt)[0] = ee->imode->hex1byte & 0xff;
560         (*rslt)[1] = ee->imode->hex2byte & 0xff;
561         (*rslt)[2] = 0;
562         return strlen(ee->imode->string);
563       }
564
565       return 0;
566     }
567   }
568
569   return 0;
570 }
571
572
573 /**
574  * It is a handler who processes the HTML tag.
575  *
576  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
577  *                     destination is specified.
578  * @param node   [i]   The HTML tag node is specified.
579  * @return The conversion result is returned.
580  */
581 static char *
582 s_chtml50_start_html_tag(void *pdoc, Node *UNUSED(node)) 
583 {
584   chtml50_t *chtml50 = GET_CHTML50(pdoc);
585   Doc       *doc     = chtml50->doc;
586
587   /*--------------------------------------------------------------------------*/
588   /* start HTML tag                                                           */
589   /*--------------------------------------------------------------------------*/
590   W_L("<html>");
591
592   return chtml50->out;
593 }
594
595
596 /**
597  * It is a handler who processes the HTML tag.
598  *
599  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
600  *                     destination is specified.
601  * @param node   [i]   The HTML tag node is specified.
602  * @return The conversion result is returned.
603  */
604 static char *
605 s_chtml50_end_html_tag(void *pdoc, Node *UNUSED(child)) 
606 {
607   chtml50_t   *chtml50 = GET_CHTML50(pdoc);
608   Doc         *doc     = chtml50->doc;
609
610   W_L("</html>");
611
612   return chtml50->out;
613 }
614
615
616 /**
617  * It is a handler who processes the META tag.
618  *
619  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
620  *                     destination is specified.
621  * @param node   [i]   The META tag node is specified.
622  * @return The conversion result is returned.
623  */
624 static char *
625 s_chtml50_start_meta_tag(void *pdoc, Node *node) 
626 {
627   chtml50_t     *chtml50;
628   Doc           *doc;
629   request_rec   *r;
630   Attr          *attr;
631   int           content_type_flag;
632   int           refresh_flag;
633
634   chtml50 = GET_CHTML50(pdoc);
635   doc     = chtml50->doc;
636   r       = doc->r;
637
638   content_type_flag = 0;
639   refresh_flag      = 0;
640
641   W_L("<meta");
642   /*--------------------------------------------------------------------------*/
643   /* Get Attributes                                                           */
644   /*--------------------------------------------------------------------------*/
645   for (attr = qs_get_attr(doc,node);
646        attr;
647        attr = qs_get_next_attr(doc,attr)) {
648     char *name   = qs_get_attr_name(doc,attr);
649     char *value  = qs_get_attr_value(doc,attr);
650     switch(*name) {
651     case 'h':
652     case 'H':
653       if (strcasecmp(name, "http-equiv") == 0 && value && *value) {
654         /*----------------------------------------------------------------------*/
655         /* CHTML 2.0                                                            */
656         /*----------------------------------------------------------------------*/
657         W_L(" http-equiv=\"");
658         W_V(value);
659         W_L("\"");
660         if (STRCASEEQ('c','C',"content-type", value))
661           content_type_flag = 1;
662   
663         if (STRCASEEQ('r','R',"refresh", value))
664           refresh_flag = 1;
665       }
666       break;
667
668     case 'c':
669     case 'C':
670       if (strcasecmp(name, "content") == 0 && value && *value) {
671         if (content_type_flag) {
672           W_L(" ");
673           W_V(name);
674           W_L("=\"");
675           W_V(chxj_header_inf_set_content_type(r, "text/html; charset=SHIFT_JIS"));
676           W_L("\"");
677         }
678         else
679         if (refresh_flag) {
680           char *buf;
681           char *sec;
682           char *url;
683           buf = apr_pstrdup(r->pool, value);
684           url = strchr(buf, ';');
685           if (url) {
686             sec = apr_pstrdup(r->pool, buf);
687             sec[url-buf] = 0;
688             url++;
689             url = chxj_encoding_parameter(r, url);
690             url = chxj_add_cookie_parameter(r, url, chtml50->cookie);
691             W_L(" ");
692             W_V(name);
693             W_L("=\"");
694             W_V(sec);
695             W_L(";");
696             W_V(url);
697             W_L("\"");
698           }
699         }
700         else {
701           W_L(" ");
702           W_V(name);
703           W_L("=\"");
704           W_V(value);
705           W_L("\"");
706         }
707       }
708       break;
709
710     default:
711       break;
712     }
713   }
714   W_L(">");
715
716   return chtml50->out;
717 }
718
719
720 /**
721  * It is a handler who processes the META tag.
722  *
723  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
724  *                     destination is specified.
725  * @param node   [i]   The META tag node is specified.
726  * @return The conversion result is returned.
727  */
728 static char*
729 s_chtml50_end_meta_tag(void* pdoc, Node* UNUSED(child)) 
730 {
731   chtml50_t *chtml50 = GET_CHTML50(pdoc);
732
733   return chtml50->out;
734 }
735
736
737 /**
738  * It is a handler who processes the HEAD tag.
739  *
740  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
741  *                     destination is specified.
742  * @param node   [i]   The HEAD tag node is specified.
743  * @return The conversion result is returned.
744  */
745 static char*
746 s_chtml50_start_head_tag(void* pdoc, Node* UNUSED(node)) 
747 {
748   chtml50_t   *chtml50 = GET_CHTML50(pdoc);
749   Doc         *doc     = chtml50->doc;
750
751   W_L("<head>");
752
753   return chtml50->out;
754 }
755
756
757 /**
758  * It is a handler who processes the HEAD tag.
759  *
760  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
761  *                     destination is specified.
762  * @param node   [i]   The HEAD tag node is specified.
763  * @return The conversion result is returned.
764  */
765 static char *
766 s_chtml50_end_head_tag(void *pdoc, Node *UNUSED(node)) 
767 {
768   chtml50_t *chtml50 = GET_CHTML50(pdoc);
769   Doc       *doc     = chtml50->doc;
770
771   W_L("</head>");
772
773   return chtml50->out;
774 }
775
776
777 /**
778  * It is a handler who processes the TITLE tag.
779  *
780  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
781  *                     destination is specified.
782  * @param node   [i]   The TITLE tag node is specified.
783  * @return The conversion result is returned.
784  */
785 static char *
786 s_chtml50_start_title_tag(void *pdoc, Node *UNUSED(node)) 
787 {
788   chtml50_t     *chtml50 = GET_CHTML50(pdoc);
789   Doc           *doc     = chtml50->doc;
790
791   W_L("<title>");
792
793   return chtml50->out;
794 }
795
796
797 /**
798  * It is a handler who processes the TITLE tag.
799  *
800  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
801  *                     destination is specified.
802  * @param node   [i]   The TITLE tag node is specified.
803  * @return The conversion result is returned.
804  */
805 static char *
806 s_chtml50_end_title_tag(void *pdoc, Node *UNUSED(child)) 
807 {
808   chtml50_t    *chtml50 = GET_CHTML50(pdoc);
809   Doc          *doc     = chtml50->doc;
810
811   W_L("</title>");
812
813   return chtml50->out;
814 }
815
816
817 /**
818  * It is a handler who processes the BASE tag.
819  *
820  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
821  *                     destination is specified.
822  * @param node   [i]   The BASE tag node is specified.
823  * @return The conversion result is returned.
824  */
825 static char *
826 s_chtml50_start_base_tag(void *pdoc, Node *node) 
827 {
828   Attr        *attr;
829   chtml50_t   *chtml50;
830   Doc         *doc;
831   request_rec *r;
832
833   chtml50 = GET_CHTML50(pdoc);
834   doc     = chtml50->doc;
835   r       = doc->r;
836
837   W_L("<base");
838   /*--------------------------------------------------------------------------*/
839   /* Get Attributes                                                           */
840   /*--------------------------------------------------------------------------*/
841   for (attr = qs_get_attr(doc,node);
842        attr;
843        attr = qs_get_next_attr(doc,attr)) {
844     char *name = qs_get_attr_name(doc,attr);
845     char *value = qs_get_attr_value(doc,attr);
846     if (STRCASEEQ('h','H',"href", name)) {
847       W_L(" href=\"");
848       W_V(value);
849       W_L("\"");
850     }
851   }
852   W_L(">");
853
854   return chtml50->out;
855 }
856
857
858 /**
859  * It is a handler who processes the BASE tag.
860  *
861  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
862  *                     destination is specified.
863  * @param node   [i]   The BASE tag node is specified.
864  * @return The conversion result is returned.
865  */
866 static char *
867 s_chtml50_end_base_tag(void *pdoc, Node *UNUSED(child)) 
868 {
869   chtml50_t *chtml50 = GET_CHTML50(pdoc);
870
871   return chtml50->out;
872 }
873
874
875 /**
876  * It is a handler who processes the BODY tag.
877  *
878  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
879  *                     destination is specified.
880  * @param node   [i]   The BODY tag node is specified.
881  * @return The conversion result is returned.
882  */
883 static char *
884 s_chtml50_start_body_tag(void *pdoc, Node *node) 
885 {
886   chtml50_t   *chtml50;
887   Doc         *doc;
888   request_rec *r;
889   Attr        *attr;
890
891   chtml50 = GET_CHTML50(pdoc);
892   doc     = chtml50->doc;
893   r       = doc->r;
894
895   W_L("<body");
896   /*--------------------------------------------------------------------------*/
897   /* Get Attributes                                                           */
898   /*--------------------------------------------------------------------------*/
899   for (attr = qs_get_attr(doc,node);
900        attr;
901        attr = qs_get_next_attr(doc,attr)) {
902     char *name   = qs_get_attr_name(doc,attr);
903     char *value  = qs_get_attr_value(doc,attr);
904     if (STRCASEEQ('b','B', "bgcolor", name) && value && *value) {
905       /*----------------------------------------------------------------------*/
906       /* CHTML 2.0                                                            */
907       /*----------------------------------------------------------------------*/
908       W_L(" bgcolor=\"");
909       W_V(value);
910       W_L("\"");
911     }
912     else if (STRCASEEQ('t','T', "text", name) && value && *value) {
913       /*----------------------------------------------------------------------*/
914       /* CHTML 2.0                                                            */
915       /*----------------------------------------------------------------------*/
916       W_L(" text=\"");
917       W_V(value);
918       W_L("\"");
919     }
920     else if (STRCASEEQ('l','L',"link", name) && value && *value) {
921       /*----------------------------------------------------------------------*/
922       /* CHTML 2.0                                                            */
923       /*----------------------------------------------------------------------*/
924       W_L(" link=\"");
925       W_V(value);
926       W_L("\"");
927     }
928     else if (STRCASEEQ('a','A',"alink", name) && value && *value) {
929       /*----------------------------------------------------------------------*/
930       /* CHTML 4.0                                                            */
931       /*----------------------------------------------------------------------*/
932       W_L(" alink=\"");
933       W_V(value);
934       W_L("\"");
935     }
936     else if (STRCASEEQ('v','V',"vlink", name) && value && *value) {
937       /*----------------------------------------------------------------------*/
938       /* CHTML 4.0                                                            */
939       /*----------------------------------------------------------------------*/
940       W_L(" vlink=\"");
941       W_V(value);
942       W_L("\"");
943     }
944   }
945   W_L(">");
946
947   return chtml50->out;
948 }
949
950
951 /**
952  * It is a handler who processes the BODY tag.
953  *
954  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
955  *                     destination is specified.
956  * @param node   [i]   The BODY tag node is specified.
957  * @return The conversion result is returned.
958  */
959 static char *
960 s_chtml50_end_body_tag(void *pdoc, Node *UNUSED(child)) 
961 {
962   chtml50_t   *chtml50;
963   Doc         *doc;
964
965   chtml50 = GET_CHTML50(pdoc);
966   doc     = chtml50->doc;
967
968   W_L("</body>");
969
970   return chtml50->out;
971 }
972
973
974 /**
975  * It is a handler who processes the A tag.
976  *
977  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
978  *                     destination is specified.
979  * @param node   [i]   The A tag node is specified.
980  * @return The conversion result is returned.
981  */
982 static char *
983 s_chtml50_start_a_tag(void *pdoc, Node *node) 
984 {
985   chtml50_t     *chtml50;
986   Doc           *doc;
987   request_rec   *r;
988   Attr          *attr;
989
990   chtml50 = GET_CHTML50(pdoc);
991   doc     = chtml50->doc;
992   r       = doc->r;
993
994   W_L("<a");
995   /*--------------------------------------------------------------------------*/
996   /* Get Attributes                                                           */
997   /*--------------------------------------------------------------------------*/
998   for (attr = qs_get_attr(doc,node);
999        attr; 
1000        attr = qs_get_next_attr(doc,attr)) {
1001     char *name  = qs_get_attr_name(doc,attr);
1002     char *value = qs_get_attr_value(doc,attr);
1003     if (STRCASEEQ('n','N',"name", name)) {
1004       /*----------------------------------------------------------------------*/
1005       /* CHTML1.0                                                             */
1006       /*----------------------------------------------------------------------*/
1007       W_L(" name=\"");
1008       W_V(value);
1009       W_L("\"");
1010     }
1011     else if (STRCASEEQ('h','H',"href", name)) {
1012       /*----------------------------------------------------------------------*/
1013       /* CHTML1.0                                                             */
1014       /*----------------------------------------------------------------------*/
1015       value = chxj_encoding_parameter(r, value);
1016       if (! chxj_starts_with(value, "mailto:") && ! chxj_starts_with(value, "telto:")) {
1017         value = chxj_add_cookie_parameter(r, value, chtml50->cookie);
1018       }
1019       W_L(" href=\"");
1020       W_V(value);
1021       W_L("\"");
1022     }
1023     else if (STRCASEEQ('a','A',"accesskey", name)) {
1024       /*----------------------------------------------------------------------*/
1025       /* CHTML1.0                                                             */
1026       /*----------------------------------------------------------------------*/
1027       W_L(" accesskey=\"");
1028       W_V(value);
1029       W_L("\"");
1030     }
1031     else if (STRCASEEQ('c','C',"cti", name)) {
1032       /*----------------------------------------------------------------------*/
1033       /* CHTML 2.0                                                            */
1034       /*----------------------------------------------------------------------*/
1035       W_L(" cti=\"");
1036       W_V(value);
1037       W_L("\"");
1038     }
1039     else if (STRCASEEQ('i','I',"ijam", name)) {
1040       /*----------------------------------------------------------------------*/
1041       /* CHTML 3.0                                                            */
1042       /*----------------------------------------------------------------------*/
1043       /* ignore */
1044     }
1045     else if (STRCASEEQ('u','U',"utn", name)) {
1046       /*----------------------------------------------------------------------*/
1047       /* CHTML 3.0                                                            */
1048       /* It is special only for CHTML.                                        */
1049       /*----------------------------------------------------------------------*/
1050       W_L(" utn ");
1051     }
1052     else if (STRCASEEQ('t','T',"telbook", name)) {
1053       /*----------------------------------------------------------------------*/
1054       /* CHTML 3.0                                                            */
1055       /*----------------------------------------------------------------------*/
1056       /* not support */
1057     }
1058     else if (STRCASEEQ('k','K',"kana", name)) {
1059       /*----------------------------------------------------------------------*/
1060       /* CHTML 3.0                                                            */
1061       /*----------------------------------------------------------------------*/
1062       /* not support */
1063     }
1064     else if (STRCASEEQ('e','E',"email", name)) {
1065       /*----------------------------------------------------------------------*/
1066       /* CHTML 3.0                                                            */
1067       /*----------------------------------------------------------------------*/
1068       /* not support */
1069     }
1070     else if (STRCASEEQ('i','I',"ista", name)) {
1071       /*----------------------------------------------------------------------*/
1072       /* CHTML 4.0                                                            */
1073       /*----------------------------------------------------------------------*/
1074       /* ignore */
1075     }
1076     else if (STRCASEEQ('i','I',"ilet", name)) {
1077       /*----------------------------------------------------------------------*/
1078       /* CHTML 5.0                                                            */
1079       /*----------------------------------------------------------------------*/
1080       /* ignore */
1081     }
1082     else if (STRCASEEQ('i','I',"iswf", name)) {
1083       /*----------------------------------------------------------------------*/
1084       /* CHTML 5.0                                                            */
1085       /*----------------------------------------------------------------------*/
1086       /* ignore */
1087     }
1088     else if (STRCASEEQ('i','I',"irst", name)) {
1089       /*----------------------------------------------------------------------*/
1090       /* CHTML 5.0                                                            */
1091       /*----------------------------------------------------------------------*/
1092       /* ignore */
1093     }
1094   }
1095   W_L(">");
1096   return chtml50->out;
1097 }
1098
1099
1100 /**
1101  * It is a handler who processes the A tag.
1102  *
1103  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1104  *                     destination is specified.
1105  * @param node   [i]   The A tag node is specified.
1106  * @return The conversion result is returned.
1107  */
1108 static char *
1109 s_chtml50_end_a_tag(void *pdoc, Node *UNUSED(child)) 
1110 {
1111   chtml50_t   *chtml50;
1112   Doc         *doc;
1113
1114   chtml50 = GET_CHTML50(pdoc);
1115   doc     = chtml50->doc;
1116
1117   W_L("</a>");
1118
1119   return chtml50->out;
1120 }
1121
1122
1123 /**
1124  * It is a handler who processes the BR tag.
1125  *
1126  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1127  *                     destination is specified.
1128  * @param node   [i]   The BR tag node is specified.
1129  * @return The conversion result is returned.
1130  */
1131 static char *
1132 s_chtml50_start_br_tag(void *pdoc, Node *node)
1133 {
1134   chtml50_t   *chtml50;
1135   Doc         *doc;
1136   request_rec *r;
1137   Attr        *attr;
1138
1139   chtml50 = GET_CHTML50(pdoc);
1140   doc     = chtml50->doc;
1141   r       = doc->r;
1142   W_L("<br");
1143   /*--------------------------------------------------------------------------*/
1144   /* Get Attributes                                                           */
1145   /*--------------------------------------------------------------------------*/
1146   for (attr = qs_get_attr(doc,node);
1147        attr;
1148        attr = qs_get_next_attr(doc,attr)) {
1149     char *name  = qs_get_attr_name(doc,attr);
1150     char *value = qs_get_attr_value(doc,attr);
1151     if (STRCASEEQ('c','C',"clear",name)) {
1152       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('a','A',"all",value))) {
1153         W_L(" clear=\"");
1154         W_V(value);
1155         W_L("\"");
1156       }
1157     }
1158   }
1159   W_L(">");
1160   return chtml50->out;
1161 }
1162
1163
1164 /**
1165  * It is a handler who processes the BR tag.
1166  *
1167  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1168  *                     destination is specified.
1169  * @param node   [i]   The BR tag node is specified.
1170  * @return The conversion result is returned.
1171  */
1172 static char *
1173 s_chtml50_end_br_tag(void *pdoc, Node *UNUSED(child)) 
1174 {
1175   chtml50_t *chtml50 = GET_CHTML50(pdoc);
1176
1177   return chtml50->out;
1178 }
1179
1180
1181 /**
1182  * It is a handler who processes the TR tag.
1183  *
1184  * @param chtml50  [i/o] The pointer to the CHTML structure at the output
1185  *                     destination is specified.
1186  * @param node   [i]   The TR tag node is specified.
1187  * @return The conversion result is returned.
1188  */
1189 static char *
1190 s_chtml50_start_tr_tag(void *pdoc, Node *UNUSED(node)) 
1191 {
1192   chtml50_t *chtml50 = GET_CHTML50(pdoc);
1193
1194   return chtml50->out;
1195 }
1196
1197
1198 /**
1199  * It is a handler who processes the TR tag.
1200  *
1201  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1202  *                     destination is specified.
1203  * @param node   [i]   The TR tag node is specified.
1204  * @return The conversion result is returned.
1205  */
1206 static char *
1207 s_chtml50_end_tr_tag(void *pdoc, Node *UNUSED(child)) 
1208 {
1209   chtml50_t   *chtml50;
1210   Doc         *doc;
1211   request_rec *r;
1212
1213   chtml50 = GET_CHTML50(pdoc);
1214   doc     = chtml50->doc;
1215   r       = doc->r;
1216
1217   W_L("<br>");
1218
1219   return chtml50->out;
1220 }
1221
1222
1223 /**
1224  * It is a handler who processes the FONT tag.
1225  *
1226  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1227  *                     destination is specified.
1228  * @param node   [i]   The FONT tag node is specified.
1229  * @return The conversion result is returned.
1230  */
1231 static char *
1232 s_chtml50_start_font_tag(void *pdoc, Node *node) 
1233 {
1234   Attr          *attr;
1235   chtml50_t     *chtml50;
1236   Doc           *doc;
1237   request_rec   *r;
1238   char          *color = NULL;
1239   char          *size = NULL;
1240
1241   chtml50 = GET_CHTML50(pdoc);
1242   doc     = chtml50->doc;
1243   r       = doc->r;
1244
1245   /*--------------------------------------------------------------------------*/
1246   /* Get Attributes                                                           */
1247   /*--------------------------------------------------------------------------*/
1248   for (attr = qs_get_attr(doc,node);
1249        attr && (color == NULL || size == NULL); 
1250        attr = qs_get_next_attr(doc,attr)) {
1251     char *name  = qs_get_attr_name(doc,attr);
1252     char *value = qs_get_attr_value(doc,attr);
1253     if (STRCASEEQ('c','C',"color", name) && value && *value) {
1254       color = apr_pstrdup(doc->buf.pool, value);
1255     }
1256     else if (STRCASEEQ('s','S',"size", name) && value && *value) {
1257       /*----------------------------------------------------------------------*/
1258       /* CHTML 5.0                                                            */
1259       /*----------------------------------------------------------------------*/
1260       size = apr_pstrdup(doc->buf.pool, value);
1261       switch (*size) {
1262       case '1':
1263       case '2':
1264       case '3':
1265       case '4':
1266       case '5':
1267       case '6':
1268       case '7':
1269         if (*(size + 1) == 0) {
1270           break;
1271         }
1272         size = NULL;
1273         break;
1274
1275       case '+':
1276       case '-':
1277         {
1278           char ch = *(size + 1);
1279           if (ch == '1' || ch == '2' || ch == '3') {
1280             if (*(size + 2) == 0) {
1281               break;
1282             }
1283           }
1284         }
1285         size = NULL;
1286         break;
1287
1288       default:
1289         size = NULL;
1290       }
1291     }
1292     if (color && size) break;
1293   }
1294   if (color || size) {
1295     W_L("<font");
1296     if (color) {
1297       W_L(" color=\"");
1298       W_V(color);
1299       W_L("\"");
1300     }
1301     if (size) {
1302       W_L(" size=\"");
1303       W_V(size);
1304       W_L("\"");
1305     }
1306     W_L(">");
1307     chtml50->font_flag++;
1308   }
1309   return chtml50->out;
1310 }
1311
1312
1313 /**
1314  * It is a handler who processes the FONT tag.
1315  *
1316  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1317  *                     destination is specified.
1318  * @param node   [i]   The FONT tag node is specified.
1319  * @return The conversion result is returned.
1320  */
1321 static char *
1322 s_chtml50_end_font_tag(void *pdoc, Node *UNUSED(child)) 
1323 {
1324   chtml50_t     *chtml50;
1325   Doc           *doc;
1326   request_rec   *r;
1327
1328   chtml50 = GET_CHTML50(pdoc);
1329   doc     = chtml50->doc;
1330   r       = doc->r;
1331
1332   if (chtml50->font_flag) {
1333     W_L("</font>");
1334     chtml50->font_flag--;
1335   }
1336
1337   return chtml50->out;
1338 }
1339
1340
1341 /**
1342  * It is a handler who processes the FORM tag.
1343  *
1344  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1345  *                     destination is specified.
1346  * @param node   [i]   The FORM tag node is specified.
1347  * @return The conversion result is returned.
1348  */
1349 static char *
1350 s_chtml50_start_form_tag(void *pdoc, Node *node) 
1351 {
1352   chtml50_t     *chtml50;
1353   Doc           *doc;
1354   request_rec   *r;
1355   Attr          *attr;
1356   char          *new_hidden_tag = NULL;
1357   char          *attr_method = NULL;
1358   char          *attr_action = NULL;
1359   char          *attr_utn    = NULL;
1360
1361   chtml50 = GET_CHTML50(pdoc);
1362   doc     = chtml50->doc;
1363   r       = doc->r;
1364
1365   /*--------------------------------------------------------------------------*/
1366   /* Get Attributes                                                           */
1367   /*--------------------------------------------------------------------------*/
1368   for (attr = qs_get_attr(doc,node);
1369        attr;
1370        attr = qs_get_next_attr(doc,attr)) {
1371     char *name  = qs_get_attr_name(doc,attr);
1372     char *value = qs_get_attr_value(doc,attr);
1373     if (STRCASEEQ('a','A',"action", name)) {
1374       /*----------------------------------------------------------------------*/
1375       /* CHTML 1.0                                                            */
1376       /*----------------------------------------------------------------------*/
1377       attr_action = chxj_encoding_parameter(r, value);
1378       attr_action = chxj_add_cookie_parameter(r, attr_action, chtml50->cookie);
1379     }
1380     else if (STRCASEEQ('m','M',"method", name)) {
1381       /*----------------------------------------------------------------------*/
1382       /* CHTML 1.0                                                            */
1383       /*----------------------------------------------------------------------*/
1384       attr_method = apr_pstrdup(doc->pool, value);
1385     }
1386     else if (STRCASEEQ('u','U',"utn", name)) {
1387       /*----------------------------------------------------------------------*/
1388       /* CHTML 3.0                                                            */
1389       /* It is special only for CHTML.                                        */
1390       /*----------------------------------------------------------------------*/
1391       attr_utn = value;
1392     }
1393   }
1394
1395   int post_flag = (attr_method && strcasecmp(attr_method, "post") == 0) ? 1 : 0;
1396
1397   W_L("<form");
1398   if (attr_action) {
1399     char *q;
1400     char *new_query_string = NULL;
1401     q = strchr(attr_action, '?');
1402     if (q) {
1403       new_hidden_tag = chxj_form_action_to_hidden_tag(r, doc->pool, attr_action, 0, post_flag, &new_query_string, CHXJ_TRUE);
1404       if (new_hidden_tag) {
1405         *q = 0;
1406       }
1407     }
1408     W_L(" action=\"");
1409     W_V(attr_action);
1410     if (new_query_string) {
1411       W_L("?");
1412       W_V(new_query_string);
1413     }
1414     W_L("\"");
1415   }
1416   if (attr_method) {
1417     W_L(" method=\"");
1418     W_V(attr_method);
1419     W_L("\"");
1420   }
1421   if (attr_utn) {
1422     W_L(" utn");
1423   }
1424   W_L(">");
1425   if (new_hidden_tag) {
1426     W_V(new_hidden_tag);
1427   }
1428   return chtml50->out;
1429 }
1430
1431
1432 /**
1433  * It is a handler who processes the FORM tag.
1434  *
1435  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1436  *                     destination is specified.
1437  * @param node   [i]   The FORM tag node is specified.
1438  * @return The conversion result is returned.
1439  */
1440 static char *
1441 s_chtml50_end_form_tag(void *pdoc, Node *UNUSED(child)) 
1442 {
1443   chtml50_t    *chtml50;
1444   Doc          *doc;
1445
1446   chtml50 = GET_CHTML50(pdoc);
1447   doc     = chtml50->doc;
1448
1449   W_L("</form>");
1450
1451   return chtml50->out;
1452 }
1453
1454
1455 /**
1456  * It is a handler who processes the INPUT tag.
1457  *
1458  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1459  *                     destination is specified.
1460  * @param node   [i]   The INPUT tag node is specified.
1461  * @return The conversion result is returned.
1462  */
1463 static char *
1464 s_chtml50_start_input_tag(void *pdoc, Node *node) 
1465 {
1466   chtml50_t   *chtml50;
1467   Doc         *doc;
1468   request_rec *r;
1469   char        *max_length  = NULL;
1470   char        *type        = NULL;
1471   char        *name        = NULL;
1472   char        *value       = NULL;
1473   char        *istyle      = NULL;
1474   char        *size        = NULL;
1475   char        *checked     = NULL;
1476   char        *accesskey   = NULL;
1477
1478   chtml50   = GET_CHTML50(pdoc);
1479   doc       = chtml50->doc;
1480   r         = doc->r;
1481   W_L("<input");
1482   /*--------------------------------------------------------------------------*/
1483   /* Get Attributes                                                           */
1484   /*--------------------------------------------------------------------------*/
1485   type       = qs_get_type_attr(doc, node, doc->buf.pool);
1486   name       = qs_get_name_attr(doc, node, doc->buf.pool);
1487   value      = qs_get_value_attr(doc,node, doc->buf.pool);
1488   istyle     = qs_get_istyle_attr(doc,node,doc->buf.pool);
1489   max_length = qs_get_maxlength_attr(doc,node,doc->buf.pool);
1490   checked    = qs_get_checked_attr(doc,node,doc->buf.pool);
1491   accesskey  = qs_get_accesskey_attr(doc, node, doc->buf.pool);
1492   size       = qs_get_size_attr(doc, node, doc->buf.pool);
1493
1494   if (type) {
1495     type = qs_trim_string(doc->buf.pool, type);
1496     if (type && (STRCASEEQ('t','T',"text",    type) ||
1497                  STRCASEEQ('p','P',"password",type) ||
1498                  STRCASEEQ('c','C',"checkbox",type) ||
1499                  STRCASEEQ('r','R',"radio",   type) ||
1500                  STRCASEEQ('h','H',"hidden",  type) ||
1501                  STRCASEEQ('s','S',"submit",  type) ||
1502                  STRCASEEQ('r','R',"reset",   type))) {
1503       W_L(" type=\"");
1504       W_V(type);
1505       W_L("\"");
1506     }
1507   }
1508   if (size && *size) {
1509     W_L(" size=\"");
1510     W_V(size);
1511     W_L("\"");
1512   }
1513   if (name && *name) {
1514     W_L(" name=\"");
1515     W_V(name);
1516     W_L("\"");
1517   }
1518   if (value && *value) {
1519     W_L(" value=\"");
1520     W_V(chxj_add_slash_to_doublequote(doc->pool, value));
1521     W_L("\"");
1522   }
1523   if (accesskey && *accesskey) {
1524     W_L(" accesskey=\"");
1525     W_V(accesskey);
1526     W_L("\"");
1527   }
1528   if (istyle) {
1529     /*------------------------------------------------------------------------*/
1530     /* CHTML 2.0                                                              */
1531     /*------------------------------------------------------------------------*/
1532     if (*istyle == '1' || *istyle == '2' || *istyle == '3' || *istyle == '4') {
1533       W_L(" istyle=\"");
1534       W_V(istyle);
1535       W_L("\"");
1536     }
1537   }
1538
1539   /*--------------------------------------------------------------------------*/
1540   /* The figure is default for the password.                                  */
1541   /*--------------------------------------------------------------------------*/
1542   if (max_length && *max_length) {
1543     if (chxj_chk_numeric(max_length) != 0) {
1544       max_length = apr_psprintf(r->pool, "0");
1545     }
1546     if (istyle != NULL && *istyle == '1') {
1547       char *vv = apr_psprintf(doc->buf.pool, " maxlength=\"%d\"", chxj_atoi(max_length) * 2);
1548       W_V(vv);
1549     }
1550     else  {
1551       char *vv = apr_psprintf(doc->buf.pool, " maxlength=\"%d\"", chxj_atoi(max_length));
1552       W_V(vv);
1553     }
1554   }
1555   if (checked) {
1556     W_L(" checked");
1557   }
1558   W_L(">");
1559
1560   return chtml50->out;
1561 }
1562
1563
1564 /**
1565  * It is a handler who processes the INPUT tag.
1566  *
1567  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1568  *                     destination is specified.
1569  * @param node   [i]   The INPUT tag node is specified.
1570  * @return The conversion result is returned.
1571  */
1572 static char *
1573 s_chtml50_end_input_tag(void *pdoc, Node *UNUSED(child)) 
1574 {
1575   chtml50_t *chtml50 = GET_CHTML50(pdoc);
1576
1577   return chtml50->out;
1578 }
1579
1580
1581 /**
1582  * It is a handler who processes the CENTER tag.
1583  *
1584  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1585  *                     destination is specified.
1586  * @param node   [i]   The CENTER tag node is specified.
1587  * @return The conversion result is returned.
1588  */
1589 static char *
1590 s_chtml50_start_center_tag(void *pdoc, Node *UNUSED(node)) 
1591 {
1592   chtml50_t     *chtml50;
1593   Doc           *doc;
1594
1595   chtml50 = GET_CHTML50(pdoc);
1596   doc     = chtml50->doc;
1597
1598   W_L("<center>");
1599
1600   return chtml50->out;
1601 }
1602
1603
1604 /**
1605  * It is a handler who processes the CENTER tag.
1606  *
1607  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1608  *                     destination is specified.
1609  * @param node   [i]   The CENTER tag node is specified.
1610  * @return The conversion result is returned.
1611  */
1612 static char *
1613 s_chtml50_end_center_tag(void *pdoc, Node *UNUSED(child)) 
1614 {
1615   chtml50_t     *chtml50;
1616   Doc           *doc;
1617
1618   chtml50 = GET_CHTML50(pdoc);
1619   doc     = chtml50->doc;
1620
1621   W_L("</center>");
1622
1623   return chtml50->out;
1624 }
1625
1626
1627 /**
1628  * It is a handler who processes the HR tag.
1629  *
1630  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1631  *                     destination is specified.
1632  * @param node   [i]   The HR tag node is specified.
1633  * @return The conversion result is returned.
1634  */
1635 static char *
1636 s_chtml50_start_hr_tag(void *pdoc, Node *node) 
1637 {
1638   Attr        *attr;
1639   chtml50_t   *chtml50;
1640   Doc         *doc;
1641   request_rec *r;
1642
1643   chtml50 = GET_CHTML50(pdoc);
1644   doc     = chtml50->doc;
1645   r       = doc->r;
1646
1647   W_L("<hr");
1648  
1649   for (attr = qs_get_attr(doc,node);
1650        attr; 
1651        attr = qs_get_next_attr(doc,attr)) {
1652     char *name = qs_get_attr_name(doc,attr);
1653     char *value = qs_get_attr_value(doc,attr);
1654     if (STRCASEEQ('a','A',"align", name)) {
1655       /*----------------------------------------------------------------------*/
1656       /* CHTML 1.0                                                            */
1657       /*----------------------------------------------------------------------*/
1658       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
1659         W_L(" align=\"");
1660         W_V(value);
1661         W_L("\"");
1662       }
1663     }
1664     else if (STRCASEEQ('s','S',"size", name)) {
1665       /*----------------------------------------------------------------------*/
1666       /* CHTML 1.0                                                            */
1667       /*----------------------------------------------------------------------*/
1668       if (value && *value) {
1669         W_L(" size=\"");
1670         W_V(value);
1671         W_L("\"");
1672       }
1673     }
1674     else if (STRCASEEQ('w','W',"width", name)) {
1675       /*----------------------------------------------------------------------*/
1676       /* CHTML 1.0                                                            */
1677       /*----------------------------------------------------------------------*/
1678       if (value && *value) {
1679         W_L(" width=\"");
1680         W_V(value);
1681         W_L("\"");
1682       }
1683     }
1684     else if (STRCASEEQ('n','N',"noshade", name)) {
1685       /*----------------------------------------------------------------------*/
1686       /* CHTML 1.0                                                            */
1687       /*----------------------------------------------------------------------*/
1688       W_L(" noshade");
1689     }
1690     else if (STRCASEEQ('c','C',"color", name) && value && *value) {
1691       /*----------------------------------------------------------------------*/
1692       /* CHTML 4.0                                                            */
1693       /*----------------------------------------------------------------------*/
1694       W_L(" color=\"");
1695       W_V(value);
1696       W_L("\"");
1697     }
1698   }
1699   W_L(">");
1700
1701   return chtml50->out;
1702 }
1703
1704
1705 /**
1706  * It is a handler who processes the HR tag.
1707  *
1708  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1709  *                     destination is specified.
1710  * @param node   [i]   The HR tag node is specified.
1711  * @return The conversion result is returned.
1712  */
1713 static char *
1714 s_chtml50_end_hr_tag(void *pdoc, Node *UNUSED(child)) 
1715 {
1716   chtml50_t *chtml50 = GET_CHTML50(pdoc);
1717
1718   return chtml50->out;
1719 }
1720
1721
1722 /**
1723  * It is a handler who processes the IMG tag.
1724  *
1725  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1726  *                     destination is specified.
1727  * @param node   [i]   The IMG tag node is specified.
1728  * @return The conversion result is returned.
1729  */
1730 static char *
1731 s_chtml50_start_img_tag(void *pdoc, Node *node) 
1732 {
1733 #ifndef IMG_NOT_CONVERT_FILENAME
1734   device_table *spec;
1735 #endif
1736   chtml50_t    *chtml50;
1737   Doc          *doc;
1738   request_rec  *r;
1739   Attr         *attr;
1740
1741   chtml50 = GET_CHTML50(pdoc);
1742   doc     = chtml50->doc;
1743   r       = doc->r;
1744 #ifndef IMG_NOT_CONVERT_FILENAME
1745   spec    = chtml50->spec;
1746 #endif
1747
1748   W_L("<img");
1749   /*--------------------------------------------------------------------------*/
1750   /* Get Attributes                                                           */
1751   /*--------------------------------------------------------------------------*/
1752   for (attr = qs_get_attr(doc,node);
1753        attr;
1754        attr = qs_get_next_attr(doc,attr)) {
1755     char *name  = qs_get_attr_name(doc,attr);
1756     char *value = qs_get_attr_value(doc,attr);
1757     if (STRCASEEQ('s','S',"src", name)) {
1758       /*----------------------------------------------------------------------*/
1759       /* CHTML 1.0                                                            */
1760       /*----------------------------------------------------------------------*/
1761 #ifdef IMG_NOT_CONVERT_FILENAME
1762       value = chxj_encoding_parameter(r, value);
1763       value = chxj_add_cookie_parameter(r, value, chtml50->cookie);
1764       value = chxj_add_cookie_no_update_parameter(r, value);
1765       W_L(" src=\"");
1766       W_V(value);
1767       W_L("\"");
1768 #else
1769       value = chxj_img_conv(r,spec,value);
1770       value = chxj_encoding_parameter(r, value);
1771       value = chxj_add_cookie_parameter(r, value, chtml50->cookie);
1772       value = chxj_add_cookie_no_update_parameter(r, value);
1773       W_L(" src=\"");
1774       W_V(value);
1775       W_L("\"");
1776 #endif
1777     }
1778     else if (STRCASEEQ('a','A',"align", name)) {
1779       /*----------------------------------------------------------------------*/
1780       /* CHTML 1.0                                                            */
1781       /*----------------------------------------------------------------------*/
1782       if (value) {
1783         if (STRCASEEQ('t','T',"top",   value) ||
1784             STRCASEEQ('m','M',"middle",value) ||
1785             STRCASEEQ('b','B',"bottom",value) ||
1786             STRCASEEQ('l','L',"left",  value) ||
1787             STRCASEEQ('c','C',"center",  value) ||
1788             STRCASEEQ('r','R',"right", value)) {
1789           W_L(" align=\"");
1790           W_V(value);
1791           W_L("\"");
1792         }
1793       }
1794     }
1795     else if (STRCASEEQ('w','W',"width", name) && value && *value) {
1796       /*----------------------------------------------------------------------*/
1797       /* CHTML 1.0                                                            */
1798       /*----------------------------------------------------------------------*/
1799       W_L(" width=\"");
1800       W_V(value);
1801       W_L("\"");
1802     }
1803     else if (STRCASEEQ('h','H', "height", name) && value && *value) {
1804       /*----------------------------------------------------------------------*/
1805       /* CHTML 1.0                                                            */
1806       /*----------------------------------------------------------------------*/
1807       W_L(" height=\"");
1808       W_V(value);
1809       W_L("\"");
1810     }
1811     else if (STRCASEEQ('h','H',"hspace", name) && value && *value) {
1812       /*----------------------------------------------------------------------*/
1813       /* CHTML 1.0                                                            */
1814       /*----------------------------------------------------------------------*/
1815       W_L(" hspace=\"");
1816       W_V(value);
1817       W_L("\"");
1818     }
1819     else if (STRCASEEQ('v','V',"vspace", name) && value && *value) {
1820       /*----------------------------------------------------------------------*/
1821       /* CHTML 1.0                                                            */
1822       /*----------------------------------------------------------------------*/
1823       W_L(" vspace=\"");
1824       W_V(value);
1825       W_L("\"");
1826     }
1827     else if (STRCASEEQ('a','A',"alt",name) && value && *value) {
1828       /*----------------------------------------------------------------------*/
1829       /* CHTML 1.0                                                            */
1830       /*----------------------------------------------------------------------*/
1831       W_L(" alt=\"");
1832       W_V(value);
1833       W_L("\"");
1834     }
1835   }
1836   W_L(">");
1837
1838   return chtml50->out;
1839 }
1840
1841
1842 /**
1843  * It is a handler who processes the IMG tag.
1844  *
1845  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1846  *                     destination is specified.
1847  * @param node   [i]   The IMG tag node is specified.
1848  * @return The conversion result is returned.
1849  */
1850 static char *
1851 s_chtml50_end_img_tag(void *pdoc, Node *UNUSED(child)) 
1852 {
1853   chtml50_t *chtml50 = GET_CHTML50(pdoc);
1854
1855   return chtml50->out;
1856 }
1857
1858
1859 /**
1860  * It is a handler who processes the SELECT tag.
1861  *
1862  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1863  *                     destination is specified.
1864  * @param node   [i]   The SELECT tag node is specified.
1865  * @return The conversion result is returned.
1866  */
1867 static char *
1868 s_chtml50_start_select_tag(void *pdoc, Node *child)
1869 {
1870   chtml50_t   *chtml50  = GET_CHTML50(pdoc);
1871   Doc         *doc      = chtml50->doc;
1872   char        *size     = NULL;
1873   char        *name     = NULL;
1874   char        *multiple = NULL;
1875   Attr        *attr;
1876
1877   W_L("<select");
1878   for (attr = qs_get_attr(doc,child);
1879        attr;
1880        attr = qs_get_next_attr(doc,attr)) {
1881     char *nm  = qs_get_attr_name(doc,attr);
1882     char *val = qs_get_attr_value(doc,attr);
1883     if (STRCASEEQ('s','S',"size", nm)) {
1884       /*----------------------------------------------------------------------*/
1885       /* CHTML 1.0 version 2.0                                                */
1886       /*----------------------------------------------------------------------*/
1887       size = apr_pstrdup(doc->buf.pool, val);
1888     }
1889     else if (STRCASEEQ('n','N',"name", nm)) {
1890       /*----------------------------------------------------------------------*/
1891       /* CHTML 1.0 version 2.0                                                */
1892       /*----------------------------------------------------------------------*/
1893       name = apr_pstrdup(doc->buf.pool, val);
1894     }
1895     else if (STRCASEEQ('m','M',"multiple", nm)) {
1896       /*----------------------------------------------------------------------*/
1897       /* CHTML 1.0 version 2.0                                                */
1898       /*----------------------------------------------------------------------*/
1899       multiple = apr_pstrdup(doc->buf.pool, val);
1900     }
1901   }
1902   if (size && *size) {
1903     W_L(" size=\"");
1904     W_V(size);
1905     W_L("\"");
1906   }
1907   if (name && *name) {
1908     W_L(" name=\"");
1909     W_V(name);
1910     W_L("\"");
1911   }
1912   if (multiple) {
1913     W_L(" multiple");
1914   }
1915   W_L(">");
1916
1917   return chtml50->out;
1918 }
1919
1920
1921 /**
1922  * It is a handler who processes the SELECT tag.
1923  *
1924  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1925  *                     destination is specified.
1926  * @param node   [i]   The SELECT tag node is specified.
1927  * @return The conversion result is returned.
1928  */
1929 static char *
1930 s_chtml50_end_select_tag(void *pdoc, Node *UNUSED(child))
1931 {
1932   chtml50_t    *chtml50 = GET_CHTML50(pdoc);
1933   Doc          *doc   = chtml50->doc;
1934
1935   W_L("</select>");
1936
1937   return chtml50->out;
1938 }
1939
1940
1941 /**
1942  * It is a handler who processes the OPTION tag.
1943  *
1944  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1945  *                     destination is specified.
1946  * @param node   [i]   The OPTION tag node is specified.
1947  * @return The conversion result is returned.
1948  */
1949 static char *
1950 s_chtml50_start_option_tag(void *pdoc, Node *child)
1951 {
1952   Attr        *attr;
1953   chtml50_t   *chtml50;
1954   Doc         *doc;
1955   request_rec *r;
1956   char        *selected;
1957   char        *value;
1958
1959   chtml50    = GET_CHTML50(pdoc);
1960   doc        = chtml50->doc;
1961   r          = doc->r;
1962   selected   = NULL;
1963   value      = NULL;
1964
1965   W_L("<option");
1966   for (attr = qs_get_attr(doc,child);
1967        attr;
1968        attr = qs_get_next_attr(doc,attr)) {
1969     char *nm  = qs_get_attr_name(doc,attr);
1970     char *val = qs_get_attr_value(doc,attr);
1971     if (STRCASEEQ('s','S',"selected", nm)) {
1972       /*----------------------------------------------------------------------*/
1973       /* CHTML 1.0 version 2.0                                                */
1974       /*----------------------------------------------------------------------*/
1975       selected = apr_pstrdup(doc->buf.pool, val);
1976     }
1977     else if (STRCASEEQ('v','V',"value", nm)) {
1978       /*----------------------------------------------------------------------*/
1979       /* CHTML 1.0 version 2.0                                                */
1980       /*----------------------------------------------------------------------*/
1981       value = apr_pstrdup(doc->buf.pool, val);
1982     }
1983   }
1984   if (value && *value) {
1985     W_L(" value=\"");
1986     W_V(value);
1987     W_L("\"");
1988   }
1989   if (selected) {
1990     W_L(" selected");
1991   }
1992   W_L(">");
1993   return chtml50->out;
1994 }
1995
1996
1997 /**
1998  * It is a handler who processes the OPTION tag.
1999  *
2000  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2001  *                     destination is specified.
2002  * @param node   [i]   The OPTION tag node is specified.
2003  * @return The conversion result is returned.
2004  */
2005 static char *
2006 s_chtml50_end_option_tag(void *pdoc, Node *UNUSED(child))
2007 {
2008   chtml50_t *chtml50 = GET_CHTML50(pdoc);
2009
2010   /* Don't close */
2011
2012   return chtml50->out;
2013 }
2014
2015
2016 /**
2017  * It is a handler who processes the DIV tag.
2018  *
2019  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2020  *                     destination is specified.
2021  * @param node   [i]   The DIV tag node is specified.
2022  * @return The conversion result is returned.
2023  */
2024 static char *
2025 s_chtml50_start_div_tag(void *pdoc, Node *child)
2026 {
2027   Attr          *attr;
2028   chtml50_t     *chtml50;
2029   Doc           *doc;
2030   request_rec   *r;
2031   char          *align;
2032
2033   chtml50 = GET_CHTML50(pdoc);
2034   doc     = chtml50->doc;
2035   r       = doc->r;
2036   align   = NULL;
2037
2038   W_L("<div");
2039   for (attr = qs_get_attr(doc,child);
2040        attr;
2041        attr = qs_get_next_attr(doc,attr)) {
2042     char *nm  = qs_get_attr_name(doc,attr);
2043     char *val = qs_get_attr_value(doc,attr);
2044     if (STRCASEEQ('a','A',"align", nm)) {
2045       /*----------------------------------------------------------------------*/
2046       /* CHTML 1.0 (W3C version 3.2)                                          */
2047       /*----------------------------------------------------------------------*/
2048       if (val && (STRCASEEQ('l','L',"left",val) || STRCASEEQ('r','R',"right",val) || STRCASEEQ('c','C',"center",val))) {
2049         align = apr_pstrdup(doc->buf.pool, val);
2050       }
2051     }
2052   }
2053   if (align) {
2054     W_L(" align=\"");
2055     W_V(align);
2056     W_L("\"");
2057   }
2058   W_L(">");
2059
2060   return chtml50->out;
2061 }
2062
2063
2064 /**
2065  * It is a handler who processes the DIV tag.
2066  *
2067  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2068  *                     destination is specified.
2069  * @param node   [i]   The DIV tag node is specified.
2070  * @return The conversion result is returned.
2071  */
2072 static char *
2073 s_chtml50_end_div_tag(void *pdoc, Node *UNUSED(node))
2074 {
2075   chtml50_t    *chtml50 = GET_CHTML50(pdoc);
2076   Doc          *doc     = chtml50->doc;
2077
2078   W_L("</div>");
2079
2080   return chtml50->out;
2081 }
2082
2083
2084 /**
2085  * It is a handler who processes the UL tag.
2086  *
2087  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2088  *                     destination is specified.
2089  * @param node   [i]   The UL tag node is specified.
2090  * @return The conversion result is returned.
2091  */
2092 static char *
2093 s_chtml50_start_ul_tag(void *pdoc, Node *node)
2094 {
2095   chtml50_t   *chtml50 = GET_CHTML50(pdoc);
2096   Doc         *doc     = chtml50->doc;
2097   Attr        *attr;
2098   W_L("<ul");
2099   /*--------------------------------------------------------------------------*/
2100   /* Get Attributes                                                           */
2101   /*--------------------------------------------------------------------------*/
2102   for (attr = qs_get_attr(doc,node);
2103        attr;
2104        attr = qs_get_next_attr(doc,attr)) {
2105     char *name   = qs_get_attr_name(doc,attr);
2106     char *value  = qs_get_attr_value(doc,attr);
2107     if (STRCASEEQ('t','T',"type",name)) {
2108       if (value && (STRCASEEQ('d','D',"disc",value) || STRCASEEQ('c','C',"circle",value) || STRCASEEQ('s','S',"square",value))) {
2109         W_L(" type=\"");
2110         W_V(value);
2111         W_L("\"");
2112       }
2113     }
2114   }
2115   W_L(">");
2116   return chtml50->out;
2117 }
2118
2119
2120 /**
2121  * It is a handler who processes the UL tag.
2122  *
2123  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2124  *                     destination is specified.
2125  * @param node   [i]   The UL tag node is specified.
2126  * @return The conversion result is returned.
2127  */
2128 static char *
2129 s_chtml50_end_ul_tag(void *pdoc, Node *UNUSED(child)) 
2130 {
2131   chtml50_t     *chtml50 = GET_CHTML50(pdoc);
2132   Doc           *doc     = chtml50->doc;
2133
2134   W_L("</ul>");
2135
2136   return chtml50->out;
2137 }
2138
2139
2140 /**
2141  * It is a handler who processes the PRE tag.
2142  *
2143  * @param pdoc  [i/o] The pointer to the XHTML structure at the output
2144  *                     destination is specified.
2145  * @param node   [i]   The PRE tag node is specified.
2146  * @return The conversion result is returned.
2147  */
2148 static char *
2149 s_chtml50_start_pre_tag(void *pdoc, Node *UNUSED(node)) 
2150 {
2151   chtml50_t *chtml50 = GET_CHTML50(pdoc);
2152   Doc       *doc     = chtml50->doc;
2153
2154   chtml50->pre_flag++;
2155   W_L("<pre>");
2156
2157   return chtml50->out;
2158 }
2159
2160
2161 /**
2162  * It is a handler who processes the PRE tag.
2163  *
2164  * @param pdoc  [i/o] The pointer to the XHTML structure at the output
2165  *                     destination is specified.
2166  * @param node   [i]   The PRE tag node is specified.
2167  * @return The conversion result is returned.
2168  */
2169 static char *
2170 s_chtml50_end_pre_tag(void *pdoc, Node *UNUSED(child)) 
2171 {
2172   chtml50_t     *chtml50 = GET_CHTML50(pdoc);
2173   Doc           *doc     = chtml50->doc;
2174
2175   W_L("</pre>");
2176   chtml50->pre_flag--;
2177
2178   return chtml50->out;
2179 }
2180
2181
2182 /**
2183  * It is a handler who processes the P tag.
2184  *
2185  * @param pdoc  [i/o] The pointer to the XHTML structure at the output
2186  *                     destination is specified.
2187  * @param node   [i]   The P tag node is specified.
2188  * @return The conversion result is returned.
2189  */
2190 static char *
2191 s_chtml50_start_p_tag(void *pdoc, Node *node) 
2192 {
2193   chtml50_t     *chtml50;
2194   Doc           *doc;
2195   request_rec   *r;
2196   Attr          *attr;
2197   char          *align = NULL;
2198
2199   chtml50 = GET_CHTML50(pdoc);
2200   doc     = chtml50->doc;
2201   r       = doc->r;
2202
2203   W_L("<p");
2204   for (attr = qs_get_attr(doc,node);
2205        attr;
2206        attr = qs_get_next_attr(doc,attr)) {
2207     char *nm  = qs_get_attr_name(doc,attr);
2208     char *val = qs_get_attr_value(doc,attr);
2209     if (STRCASEEQ('a','A',"align", nm)) {
2210       /*----------------------------------------------------------------------*/
2211       /* CHTML 1.0 (W3C version 3.2)                                          */
2212       /*----------------------------------------------------------------------*/
2213       if (val && (STRCASEEQ('l','L',"left",val) || STRCASEEQ('r','R',"right",val) || STRCASEEQ('c','C',"center",val))) {
2214         align = apr_pstrdup(doc->buf.pool, val);
2215         break;
2216       }
2217     }
2218   }
2219   if (align) {
2220     W_L(" align=\"");
2221     W_V(align);
2222     W_L("\"");
2223   }
2224   W_L(">");
2225   return chtml50->out;
2226 }
2227
2228
2229 /**
2230  * It is a handler who processes the P tag.
2231  *
2232  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2233  *                     destination is specified.
2234  * @param node   [i]   The P tag node is specified.
2235  * @return The conversion result is returned.
2236  */
2237 static char *
2238 s_chtml50_end_p_tag(void *pdoc, Node *UNUSED(child)) 
2239 {
2240   chtml50_t   *chtml50;
2241   Doc         *doc;
2242
2243   chtml50 = GET_CHTML50(pdoc);
2244   doc     = chtml50->doc;
2245
2246   W_L("</p>");
2247
2248   return chtml50->out;
2249 }
2250
2251
2252 /**
2253  * It is a handler who processes the OL tag.
2254  *
2255  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2256  *                     destination is specified.
2257  * @param node   [i]   The OL tag node is specified.
2258  * @return The conversion result is returned.
2259  */
2260 static char *
2261 s_chtml50_start_ol_tag(void *pdoc, Node *node)
2262 {
2263   chtml50_t     *chtml50;
2264   Doc           *doc;
2265   request_rec   *r;
2266   Attr          *attr;
2267
2268   chtml50 = GET_CHTML50(pdoc);
2269   doc     = chtml50->doc;
2270   r       = doc->r;
2271
2272   W_L("<ol");
2273   /*--------------------------------------------------------------------------*/
2274   /* Get Attributes                                                           */
2275   /*--------------------------------------------------------------------------*/
2276   for (attr = qs_get_attr(doc,node);
2277        attr;
2278        attr = qs_get_next_attr(doc,attr)) {
2279     char *name = qs_get_attr_name(doc,attr);
2280     char *value = qs_get_attr_value(doc,attr);
2281     if (STRCASEEQ('t','T',"type",name) && value && (*value == '1' || *value == 'a' || *value == 'A')) {
2282       W_L(" type=\"");
2283       W_V(value);
2284       W_L("\"");
2285     }
2286     else if (STRCASEEQ('s','S',"start",name) && value && *value) {
2287       W_L(" start=\"");
2288       W_V(value);
2289       W_L("\"");
2290     }
2291   }
2292   W_L(">");
2293
2294   return chtml50->out;
2295 }
2296
2297
2298 /**
2299  * It is a handler who processes the OL tag.
2300  *
2301  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2302  *                     destination is specified.
2303  * @param node   [i]   The OL tag node is specified.
2304  * @return The conversion result is returned.
2305  */
2306 static char *
2307 s_chtml50_end_ol_tag(void *pdoc, Node *UNUSED(node)) 
2308 {
2309   chtml50_t *chtml50 = GET_CHTML50(pdoc);
2310   Doc       *doc     = chtml50->doc;
2311
2312   W_L("</ol>");
2313
2314   return chtml50->out;
2315 }
2316
2317
2318 /**
2319  * It is a handler who processes the LI tag.
2320  *
2321  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2322  *                     destination is specified.
2323  * @param node   [i]   The LI tag node is specified.
2324  * @return The conversion result is returned.
2325  */
2326 static char *
2327 s_chtml50_start_li_tag(void *pdoc, Node *node) 
2328 {
2329   chtml50_t   *chtml50 = GET_CHTML50(pdoc);
2330   Doc         *doc     = chtml50->doc;
2331   Attr        *attr;
2332
2333   W_L("<li");
2334   /*--------------------------------------------------------------------------*/
2335   /* Get Attributes                                                           */
2336   /*--------------------------------------------------------------------------*/
2337   for (attr = qs_get_attr(doc,node);
2338        attr;
2339        attr = qs_get_next_attr(doc,attr)) {
2340     char *name = qs_get_attr_name(doc,attr);
2341     char *value = qs_get_attr_value(doc,attr);
2342     if (STRCASEEQ('t','T',"type",name)) {
2343       if (value && (*value == '1' || *value == 'a' || *value == 'A' || STRCASEEQ('d','D',"disc",value) || STRCASEEQ('s','S',"square",value) || STRCASEEQ('c','C',"circle",value))) {
2344         W_L(" type=\"");
2345         W_V(value);
2346         W_L("\"");
2347       }
2348     }
2349     else if (STRCASEEQ('v','V',"value", name) && value && *value) {
2350       W_L(" value=\"");
2351       W_V(value);
2352       W_L("\"");
2353     }
2354   }
2355   W_L(">");
2356   return chtml50->out;
2357 }
2358
2359
2360 /**
2361  * It is a handler who processes the LI tag.
2362  *
2363  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2364  *                     destination is specified.
2365  * @param node   [i]   The LI tag node is specified.
2366  * @return The conversion result is returned.
2367  */
2368 static char *
2369 s_chtml50_end_li_tag(void *pdoc, Node *UNUSED(child)) 
2370 {
2371   chtml50_t *chtml50 = GET_CHTML50(pdoc);
2372
2373   return chtml50->out;
2374 }
2375
2376
2377 /**
2378  * It is a handler who processes the H1 tag.
2379  *
2380  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2381  *                     destination is specified.
2382  * @param node   [i]   The H1 tag node is specified.
2383  * @return The conversion result is returned.
2384  */
2385 static char *
2386 s_chtml50_start_h1_tag(void *pdoc, Node *node)
2387 {
2388   chtml50_t     *chtml50;
2389   Doc           *doc;
2390   request_rec   *r;
2391   Attr          *attr;
2392
2393   chtml50 = GET_CHTML50(pdoc);
2394   doc     = chtml50->doc;
2395   r       = doc->r;
2396
2397   W_L("<h1");
2398   for (attr = qs_get_attr(doc,node);
2399        attr;
2400        attr = qs_get_next_attr(doc,attr)) {
2401     char *name = qs_get_attr_name(doc,attr);
2402     char *value = qs_get_attr_value(doc,attr);
2403     if (STRCASEEQ('a','A',"align", name)) {
2404       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
2405         W_L(" align=\"");
2406         W_V(value);
2407         W_L("\"");
2408         break;
2409       }
2410     }
2411   }
2412   W_L(">");
2413
2414   return chtml50->out;
2415 }
2416
2417
2418 /**
2419  * It is a handler who processes the H1 tag.
2420  *
2421  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2422  *                     destination is specified.
2423  * @param node   [i]   The H1 tag node is specified.
2424  * @return The conversion result is returned.
2425  */
2426 static char *
2427 s_chtml50_end_h1_tag(void *pdoc, Node *UNUSED(child)) 
2428 {
2429   chtml50_t   *chtml50;
2430   Doc         *doc;
2431
2432   chtml50 = GET_CHTML50(pdoc);
2433   doc     = chtml50->doc;
2434
2435   W_L("</h1>");
2436
2437   return chtml50->out;
2438 }
2439
2440
2441 /**
2442  * It is a handler who processes the H2 tag.
2443  *
2444  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2445  *                     destination is specified.
2446  * @param node   [i]   The H2 tag node is specified.
2447  * @return The conversion result is returned.
2448  */
2449 static char *
2450 s_chtml50_start_h2_tag(void *pdoc, Node *node)
2451 {
2452   chtml50_t     *chtml50;
2453   Doc           *doc;
2454   request_rec   *r;
2455   Attr          *attr;
2456
2457   chtml50 = GET_CHTML50(pdoc);
2458   doc     = chtml50->doc;
2459   r       = doc->r;
2460
2461   W_L("<h2");
2462   for (attr = qs_get_attr(doc,node);
2463        attr;
2464        attr = qs_get_next_attr(doc,attr)) {
2465     char *name  = qs_get_attr_name(doc,attr);
2466     char *value = qs_get_attr_value(doc,attr);
2467     if (STRCASEEQ('a','A',"align", name)) {
2468       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
2469         W_L(" align=\"");
2470         W_V(value);
2471         W_L("\"");
2472         break;
2473       }
2474     }
2475   }
2476   W_L(">");
2477   return chtml50->out;
2478 }
2479
2480
2481 /**
2482  * It is a handler who processes the H2 tag.
2483  *
2484  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2485  *                     destination is specified.
2486  * @param node   [i]   The H2 tag node is specified.
2487  * @return The conversion result is returned.
2488  */
2489 static char *
2490 s_chtml50_end_h2_tag(void *pdoc, Node *UNUSED(child)) 
2491 {
2492   chtml50_t   *chtml50 = GET_CHTML50(pdoc);
2493   Doc         *doc     = chtml50->doc;
2494
2495   W_L("</h2>");
2496
2497   return chtml50->out;
2498 }
2499
2500
2501 /**
2502  * It is a handler who processes the H3 tag.
2503  *
2504  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2505  *                     destination is specified.
2506  * @param node   [i]   The H3 tag node is specified.
2507  * @return The conversion result is returned.
2508  */
2509 static char *
2510 s_chtml50_start_h3_tag(void *pdoc, Node *node)
2511 {
2512   chtml50_t   *chtml50;
2513   Doc         *doc;
2514   request_rec *r;
2515   Attr        *attr;
2516
2517   chtml50 = GET_CHTML50(pdoc);
2518   doc     = chtml50->doc;
2519   r       = doc->r;
2520
2521   W_L("<h3");
2522   for (attr = qs_get_attr(doc,node);
2523        attr;
2524        attr = qs_get_next_attr(doc,attr)) {
2525     char *name  = qs_get_attr_name(doc,attr);
2526     char *value = qs_get_attr_value(doc,attr);
2527     if (STRCASEEQ('a','A',"align", name)) {
2528       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
2529         W_L(" align=\"");
2530         W_V(value);
2531         W_L("\"");
2532         break;
2533       }
2534     }
2535   }
2536   W_L(">");
2537
2538   return chtml50->out;
2539 }
2540
2541
2542 /**
2543  * It is a handler who processes the H3 tag.
2544  *
2545  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2546  *                     destination is specified.
2547  * @param node   [i]   The H3 tag node is specified.
2548  * @return The conversion result is returned.
2549  */
2550 static char *
2551 s_chtml50_end_h3_tag(void *pdoc, Node *UNUSED(child))
2552 {
2553   chtml50_t *chtml50 = GET_CHTML50(pdoc);
2554   Doc       *doc   = chtml50->doc;
2555
2556   W_L("</h3>");
2557
2558   return chtml50->out;
2559 }
2560
2561
2562 /**
2563  * It is a handler who processes the H4 tag.
2564  *
2565  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2566  *                     destination is specified.
2567  * @param node   [i]   The H4 tag node is specified.
2568  * @return The conversion result is returned.
2569  */
2570 static char *
2571 s_chtml50_start_h4_tag(void *pdoc, Node *node)
2572 {
2573   chtml50_t   *chtml50;
2574   Doc         *doc;
2575   request_rec *r;
2576   Attr        *attr;
2577
2578   chtml50 = GET_CHTML50(pdoc);
2579   doc     = chtml50->doc;
2580   r       = doc->r;
2581
2582   W_L("<h4");
2583   for (attr = qs_get_attr(doc,node);
2584        attr;
2585        attr = qs_get_next_attr(doc,attr)) {
2586     char *name  = qs_get_attr_name(doc,attr);
2587     char *value = qs_get_attr_value(doc,attr);
2588     if (STRCASEEQ('a','A',"align", name)) {
2589       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
2590         W_L(" align=\"");
2591         W_V(value);
2592         W_L("\"");
2593         break;
2594       }
2595     }
2596   }
2597   W_L(">");
2598   return chtml50->out;
2599 }
2600
2601
2602 /**
2603  * It is a handler who processes the H4 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 H4 tag node is specified.
2608  * @return The conversion result is returned.
2609  */
2610 static char *
2611 s_chtml50_end_h4_tag(void *pdoc, Node *UNUSED(child)) 
2612 {
2613   chtml50_t *chtml50 = GET_CHTML50(pdoc);
2614   Doc       *doc     = chtml50->doc;
2615
2616   W_L("</h4>");
2617
2618   return chtml50->out;
2619 }
2620
2621
2622 /**
2623  * It is a handler who processes the H5 tag.
2624  *
2625  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2626  *                     destination is specified.
2627  * @param node   [i]   The H5 tag node is specified.
2628  * @return The conversion result is returned.
2629  */
2630 static char *
2631 s_chtml50_start_h5_tag(void *pdoc, Node *node)
2632 {
2633   chtml50_t   *chtml50;
2634   Doc         *doc;
2635   request_rec *r;
2636   Attr        *attr;
2637
2638   chtml50 = GET_CHTML50(pdoc);
2639   doc     = chtml50->doc;
2640   r       = doc->r;
2641
2642   W_L("<h5");
2643   for (attr = qs_get_attr(doc,node);
2644        attr;
2645        attr = qs_get_next_attr(doc,attr)) {
2646     char *name  = qs_get_attr_name(doc,attr);
2647     char *value = qs_get_attr_value(doc,attr);
2648     if (STRCASEEQ('a','A',"align", name)) {
2649       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
2650         W_L(" align=\"");
2651         W_V(value);
2652         W_L("\"");
2653         break;
2654       }
2655     }
2656   }
2657   W_L(">");
2658   return chtml50->out;
2659 }
2660
2661
2662 /**
2663  * It is a handler who processes the H5 tag.
2664  *
2665  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2666  *                     destination is specified.
2667  * @param node   [i]   The H5 tag node is specified.
2668  * @return The conversion result is returned.
2669  */
2670 static char *
2671 s_chtml50_end_h5_tag(void *pdoc, Node *UNUSED(child)) 
2672 {
2673   chtml50_t *chtml50 = GET_CHTML50(pdoc);
2674   Doc       *doc     = chtml50->doc;
2675
2676   W_L("</h5>");
2677
2678   return chtml50->out;
2679 }
2680
2681
2682 /**
2683  * It is a handler who processes the H6 tag.
2684  *
2685  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2686  *                     destination is specified.
2687  * @param node   [i]   The H6 tag node is specified.
2688  * @return The conversion result is returned.
2689  */
2690 static char *
2691 s_chtml50_start_h6_tag(void *pdoc, Node *node)
2692 {
2693   chtml50_t   *chtml50;
2694   Doc         *doc;
2695   request_rec *r;
2696   Attr        *attr;
2697
2698   chtml50 = GET_CHTML50(pdoc);
2699   doc     = chtml50->doc;
2700   r       = doc->r;
2701
2702   W_L("<h6");
2703   for (attr = qs_get_attr(doc,node);
2704        attr;
2705        attr = qs_get_next_attr(doc,attr)) {
2706     char *name  = qs_get_attr_name(doc,attr);
2707     char *value = qs_get_attr_value(doc,attr);
2708     if (STRCASEEQ('a','A',"align", name)) {
2709       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
2710         W_L(" align=\"");
2711         W_V(value);
2712         W_L("\"");
2713         break;
2714       }
2715     }
2716   }
2717   W_L(">");
2718   return chtml50->out;
2719 }
2720
2721
2722 /**
2723  * It is a handler who processes the H6 tag.
2724  *
2725  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2726  *                     destination is specified.
2727  * @param node   [i]   The H6 tag node is specified.
2728  * @return The conversion result is returned.
2729  */
2730 static char *
2731 s_chtml50_end_h6_tag(void *pdoc, Node *UNUSED(child)) 
2732 {
2733   chtml50_t *chtml50 = GET_CHTML50(pdoc);
2734   Doc       *doc     = chtml50->doc;
2735
2736   W_L("</h6>");
2737
2738   return chtml50->out;
2739 }
2740
2741
2742 /**
2743  * It is a handler who processes the TEXTARE tag.
2744  *
2745  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2746  *                     destination is specified.
2747  * @param node   [i]   The TEXTAREA tag node is specified.
2748  * @return The conversion result is returned.
2749  */
2750 static char *
2751 s_chtml50_start_textarea_tag(void *pdoc, Node *node) 
2752 {
2753   chtml50_t     *chtml50;
2754   Doc           *doc;
2755   request_rec   *r;
2756   Attr          *attr;
2757
2758   chtml50 = GET_CHTML50(pdoc);
2759   doc     = chtml50->doc;
2760   r       = doc->r;
2761
2762   chtml50->textarea_flag++;
2763
2764   W_L("<textarea");
2765   for (attr = qs_get_attr(doc,node);
2766        attr;
2767        attr = qs_get_next_attr(doc,attr)) {
2768     char *name  = qs_get_attr_name(doc,attr);
2769     char *value = qs_get_attr_value(doc,attr);
2770     if (STRCASEEQ('a','A',"accesskey",name) && value && *value != 0) {
2771       W_L(" accesskey=\"");
2772       W_V(value);
2773       W_L("\"");
2774     }
2775     else if (STRCASEEQ('i','I',"istyle", name) && value && (*value == '1' || *value == '2' || *value == '3' || *value == '4')) {
2776       W_L(" istyle=\"");
2777       W_V(value);
2778       W_L("\"");
2779     }
2780     else if (STRCASEEQ('n','N',"name", name) && value && *value) {
2781       W_L(" name=\"");
2782       W_V(value);
2783       W_L("\"");
2784     }
2785     else if (STRCASEEQ('r','R',"rows", name) && value && *value) {
2786       W_L(" rows=\"");
2787       W_V(value);
2788       W_L("\"");
2789     }
2790     else if (STRCASEEQ('c','C',"cols", name) && value && *value) {
2791       W_L(" cols=\"");
2792       W_V(value);
2793       W_L("\"");
2794     }
2795   }
2796   W_L(">");
2797   return chtml50->out;
2798 }
2799
2800
2801 /**
2802  * It is a handler who processes the TEXTAREA tag.
2803  *
2804  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2805  *                     destination is specified.
2806  * @param node   [i]   The TEXTAREA tag node is specified.
2807  * @return The conversion result is returned.
2808  */
2809 static char *
2810 s_chtml50_end_textarea_tag(void *pdoc, Node *UNUSED(child)) 
2811 {
2812   chtml50_t *chtml50 = GET_CHTML50(pdoc);
2813   Doc       *doc     = chtml50->doc;
2814
2815   W_L("</textarea>");
2816   chtml50->textarea_flag--;
2817
2818   return chtml50->out;
2819 }
2820
2821
2822 static char *
2823 s_chtml50_chxjif_tag(void *pdoc, Node *node)
2824 {
2825   Node        *child;
2826   chtml50_t   *chtml50;
2827   Doc         *doc;
2828   request_rec *r;
2829
2830   chtml50 = GET_CHTML50(pdoc);
2831   doc     = chtml50->doc;
2832   r       = doc->r;
2833
2834   for (child = qs_get_child_node(doc, node);
2835        child;
2836        child = qs_get_next_node(doc, child)) {
2837     W_V(child->otext);
2838     s_chtml50_chxjif_tag(chtml50, child);
2839   }
2840
2841   return NULL;
2842 }
2843
2844
2845 static char *
2846 s_chtml50_text_tag(void *pdoc, Node *child)
2847 {
2848   chtml50_t   *chtml50;
2849   Doc         *doc;
2850   request_rec *r;
2851
2852   char        *textval;
2853   char        *tmp;
2854   char        *tdst;
2855   char        one_byte[2];
2856   int         ii;
2857   int         tdst_len;
2858
2859   chtml50 = GET_CHTML50(pdoc);
2860   doc     = chtml50->doc;
2861   r       = doc->r;
2862   
2863   textval = qs_get_node_value(doc,child);
2864   if (strlen(textval) == 0) {
2865     return chtml50->out;
2866   }
2867   
2868   tmp = apr_palloc(r->pool, qs_get_node_size(doc,child)+1);
2869   memset(tmp, 0, qs_get_node_size(doc,child)+1);
2870   
2871   tdst     = qs_alloc_zero_byte_string(doc->buf.pool);
2872   memset(one_byte, 0, sizeof(one_byte));
2873   tdst_len = 0;
2874   
2875   for (ii=0; ii<qs_get_node_size(doc,child); ii++) {
2876     char* out;
2877     int rtn = s_chtml50_search_emoji(chtml50, &textval[ii], &out);
2878     if (rtn) {
2879       tdst = qs_out_apr_pstrcat(r, tdst, out, &tdst_len);
2880       ii+=(rtn - 1);
2881       continue;
2882     }
2883   
2884     if (is_sjis_kanji(textval[ii])) {
2885       one_byte[0] = textval[ii+0];
2886       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
2887       one_byte[0] = textval[ii+1];
2888       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
2889       ii++;
2890     }
2891     else if (chtml50->pre_flag) {
2892       one_byte[0] = textval[ii+0];
2893       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
2894     }
2895     else if (chtml50->textarea_flag) {
2896       one_byte[0] = textval[ii+0];
2897       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
2898     }
2899     else if (textval[ii] != '\r' && textval[ii] != '\n') {
2900       one_byte[0] = textval[ii+0];
2901       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
2902     }
2903   }
2904   W_V(tdst);
2905   return chtml50->out;
2906 }
2907
2908
2909 /**
2910  * It is a handler who processes the BLOCKQUOTE tag.
2911  *
2912  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2913  *                     destination is specified.
2914  * @param node   [i]   The BLOCKQUOTE tag node is specified.
2915  * @return The conversion result is returned.
2916  */
2917 static char *
2918 s_chtml50_start_blockquote_tag(void *pdoc, Node *UNUSED(child))
2919 {
2920   chtml50_t *chtml50 = GET_CHTML50(pdoc);
2921   Doc       *doc     = chtml50->doc;
2922   W_L("<blockquote>");
2923   return chtml50->out;
2924 }
2925
2926
2927 /**
2928  * It is a handler who processes the BLOCKQUOTE tag.
2929  *
2930  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2931  *                     destination is specified.
2932  * @param node   [i]   The BLOCKQUOTE tag node is specified.
2933  * @return The conversion result is returned.
2934  */
2935 static char *
2936 s_chtml50_end_blockquote_tag(void *pdoc, Node *UNUSED(child))
2937 {
2938   chtml50_t *chtml50 = GET_CHTML50(pdoc);
2939   Doc       *doc     = chtml50->doc;
2940   W_L("</blockquote>");
2941   return chtml50->out;
2942 }
2943
2944
2945 /**
2946  * It is a handler who processes the DIR tag.
2947  *
2948  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2949  *                     destination is specified.
2950  * @param node   [i]   The DIR tag node is specified.
2951  * @return The conversion result is returned.
2952  */
2953 static char *
2954 s_chtml50_start_dir_tag(void *pdoc, Node *node)
2955 {
2956   chtml50_t *chtml50 = GET_CHTML50(pdoc);
2957   Doc       *doc     = chtml50->doc;
2958   Attr      *attr;
2959   W_L("<dir");
2960   for (attr = qs_get_attr(doc,node);
2961        attr;
2962        attr = qs_get_next_attr(doc,attr)) {
2963     char *name   = qs_get_attr_name(doc,attr);
2964     char *value  = qs_get_attr_value(doc,attr);
2965     if (STRCASEEQ('t','T',"type",name)) {
2966       if (value && (STRCASEEQ('d','D',"disc",value) || STRCASEEQ('c','C',"circle",value) || STRCASEEQ('s','S',"square",value))) {
2967         W_L(" type=\"");
2968         W_V(value);
2969         W_L("\"");
2970       }
2971     }
2972   }
2973   W_L(">");
2974   return chtml50->out;
2975 }
2976
2977
2978 /**
2979  * It is a handler who processes the DIR tag.
2980  *
2981  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2982  *                     destination is specified.
2983  * @param node   [i]   The DIR tag node is specified.
2984  * @return The conversion result is returned.
2985  */
2986 static char *
2987 s_chtml50_end_dir_tag(void *pdoc, Node *UNUSED(child))
2988 {
2989   chtml50_t *chtml50 = GET_CHTML50(pdoc);
2990   Doc       *doc = chtml50->doc;
2991   W_L("</dir>");
2992   return chtml50->out;
2993 }
2994
2995
2996 /**
2997  * It is a handler who processes the DL tag.
2998  *
2999  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3000  *                     destination is specified.
3001  * @param node   [i]   The DL tag node is specified.
3002  * @return The conversion result is returned.
3003  */
3004 static char *
3005 s_chtml50_start_dl_tag(void *pdoc, Node *UNUSED(child))
3006 {
3007   chtml50_t *chtml50 = GET_CHTML50(pdoc);
3008   Doc       *doc     = chtml50->doc;
3009   W_L("<dl>");
3010   return chtml50->out;
3011 }
3012
3013
3014 /**
3015  * It is a handler who processes the DL tag.
3016  *
3017  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3018  *                     destination is specified.
3019  * @param node   [i]   The DL tag node is specified.
3020  * @return The conversion result is returned.
3021  */
3022 static char *
3023 s_chtml50_end_dl_tag(void *pdoc, Node *UNUSED(child))
3024 {
3025   chtml50_t *chtml50 = GET_CHTML50(pdoc);
3026   Doc       *doc     = chtml50->doc;
3027   W_L("</dl>");
3028   return chtml50->out;
3029 }
3030
3031
3032 /**
3033  * It is a handler who processes the DT tag.
3034  *
3035  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3036  *                     destination is specified.
3037  * @param node   [i]   The DT tag node is specified.
3038  * @return The conversion result is returned.
3039  */
3040 static char *
3041 s_chtml50_start_dt_tag(void *pdoc, Node *UNUSED(child))
3042 {
3043   chtml50_t *chtml50 = GET_CHTML50(pdoc);
3044   Doc       *doc     = chtml50->doc;
3045   W_L("<dt>");
3046   return chtml50->out;
3047 }
3048
3049
3050 /**
3051  * It is a handler who processes the DT tag.
3052  *
3053  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3054  *                     destination is specified.
3055  * @param node   [i]   The DT tag node is specified.
3056  * @return The conversion result is returned.
3057  */
3058 static char *
3059 s_chtml50_end_dt_tag(void *pdoc, Node *UNUSED(child))
3060 {
3061   chtml50_t *chtml50 = GET_CHTML50(pdoc);
3062
3063   return chtml50->out;
3064 }
3065
3066
3067 /**
3068  * It is a handler who processes the DD tag.
3069  *
3070  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3071  *                     destination is specified.
3072  * @param node   [i]   The DD tag node is specified.
3073  * @return The conversion result is returned.
3074  */
3075 static char *
3076 s_chtml50_start_dd_tag(void *pdoc, Node *UNUSED(child))
3077 {
3078   chtml50_t *chtml50 = GET_CHTML50(pdoc);
3079   Doc       *doc     = chtml50->doc;
3080
3081   W_L("<dd>");
3082
3083   return chtml50->out;
3084 }
3085
3086
3087 /**
3088  * It is a handler who processes the DD tag.
3089  *
3090  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3091  *                     destination is specified.
3092  * @param node   [i]   The DD tag node is specified.
3093  * @return The conversion result is returned.
3094  */
3095 static char *
3096 s_chtml50_end_dd_tag(void *pdoc, Node *UNUSED(child))
3097 {
3098   chtml50_t *chtml50 = GET_CHTML50(pdoc);
3099
3100   return chtml50->out;
3101 }
3102
3103
3104 /**
3105  * It is a handler who processes the MARQUEE tag.
3106  *
3107  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3108  *                     destination is specified.
3109  * @param node   [i]   The MARQUEE tag node is specified.
3110  * @return The conversion result is returned.
3111  */
3112 static char *
3113 s_chtml50_start_marquee_tag(void *pdoc, Node *node)
3114 {
3115   chtml50_t *chtml50 = GET_CHTML50(pdoc);
3116   Doc       *doc = chtml50->doc;
3117   Attr      *attr;
3118   W_L("<marquee");
3119   /*--------------------------------------------------------------------------*/
3120   /* Get Attributes                                                           */
3121   /*--------------------------------------------------------------------------*/
3122   for (attr = qs_get_attr(doc,node);
3123        attr;
3124        attr = qs_get_next_attr(doc,attr)) {
3125     char *name   = qs_get_attr_name(doc,attr);
3126     char *value  = qs_get_attr_value(doc,attr);
3127     if (STRCASEEQ('d','D',"direction", name)) {
3128       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value))) {
3129         W_L(" direction=\"");
3130         W_V(value);
3131         W_L("\"");
3132       }
3133     }
3134     else if (STRCASEEQ('b','B',"behavior",name)) {
3135       if (value && (STRCASEEQ('s','S',"scroll",value) || STRCASEEQ('s','S',"slide",value) || STRCASEEQ('a','A',"alternate",value))) {
3136         W_L(" behavior=\""); 
3137         W_V(value);
3138         W_L("\"");
3139       }
3140     }
3141     else if (STRCASEEQ('l','L',"loop",name)) {
3142       if (value && *value) {
3143         W_L(" loop=\"");
3144         W_V(value);
3145         W_L("\"");
3146       }
3147     }
3148     else if (STRCASEEQ('b','B',"bgcolor",name)) {
3149       if (value && *value) {
3150         W_L(" bgcolor=\"");
3151         W_V(value);
3152         W_L("\"");
3153       }
3154     }
3155   }
3156   W_L(">");
3157   return chtml50->out;
3158 }
3159
3160
3161 /**
3162  * It is a handler who processes the MARQUEE tag.
3163  *
3164  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3165  *                     destination is specified.
3166  * @param node   [i]   The MARQUEE tag node is specified.
3167  * @return The conversion result is returned.
3168  */
3169 static char *
3170 s_chtml50_end_marquee_tag(void *pdoc, Node *UNUSED(child))
3171 {
3172   chtml50_t *chtml50 = GET_CHTML50(pdoc);
3173   Doc       *doc = chtml50->doc;
3174   W_L("</marquee>");
3175   return chtml50->out;
3176 }
3177
3178
3179 /**
3180  * It is a handler who processes the BLINK tag.
3181  *
3182  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3183  *                     destination is specified.
3184  * @param node   [i]   The BLINK tag node is specified.
3185  * @return The conversion result is returned.
3186  */
3187 static char *
3188 s_chtml50_start_blink_tag(void *pdoc, Node *UNUSED(child))
3189 {
3190   chtml50_t *chtml50 = GET_CHTML50(pdoc);
3191   Doc       *doc = chtml50->doc;
3192   W_L("<blink>");
3193   return chtml50->out;
3194 }
3195
3196
3197 /**
3198  * It is a handler who processes the BLINK tag.
3199  *
3200  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3201  *                     destination is specified.
3202  * @param node   [i]   The BLINK tag node is specified.
3203  * @return The conversion result is returned.
3204  */
3205 static char *
3206 s_chtml50_end_blink_tag(void *pdoc, Node *UNUSED(child))
3207 {
3208   chtml50_t *chtml50 = GET_CHTML50(pdoc);
3209   Doc       *doc = chtml50->doc;
3210   W_L("</blink>");
3211   return chtml50->out;
3212 }
3213
3214
3215 /**
3216  * It is a handler who processes the MENU tag.
3217  *
3218  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3219  *                     destination is specified.
3220  * @param node   [i]   The MENU tag node is specified.
3221  * @return The conversion result is returned.
3222  */
3223 static char *
3224 s_chtml50_start_menu_tag(void *pdoc, Node *node)
3225 {
3226   chtml50_t *chtml50 = GET_CHTML50(pdoc);
3227   Doc       *doc     = chtml50->doc;
3228   Attr      *attr;
3229   W_L("<menu");
3230   /*--------------------------------------------------------------------------*/
3231   /* Get Attributes                                                           */
3232   /*--------------------------------------------------------------------------*/
3233   for (attr = qs_get_attr(doc,node);
3234        attr;
3235        attr = qs_get_next_attr(doc,attr)) {
3236     char *name   = qs_get_attr_name(doc,attr);
3237     char *value  = qs_get_attr_value(doc,attr);
3238     if (STRCASEEQ('t','T',"type",name)) {
3239       if (value && (STRCASEEQ('d','D',"disc",value) || STRCASEEQ('c','C',"circle",value) || STRCASEEQ('s','S',"square",value))) {
3240         W_L(" type=\"");
3241         W_V(value);
3242         W_L("\"");
3243       }
3244     }
3245   }
3246   W_L(">");
3247   return chtml50->out;
3248 }
3249
3250
3251 /**
3252  * It is a handler who processes the MENU tag.
3253  *
3254  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3255  *                     destination is specified.
3256  * @param node   [i]   The MENU tag node is specified.
3257  * @return The conversion result is returned.
3258  */
3259 static char *
3260 s_chtml50_end_menu_tag(void *pdoc, Node *UNUSED(child))
3261 {
3262   chtml50_t *chtml50 = GET_CHTML50(pdoc);
3263   Doc       *doc = chtml50->doc;
3264   W_L("</menu>");
3265   return chtml50->out;
3266 }
3267
3268
3269 /**
3270  * It is a handler who processes the PLAINTEXT tag.
3271  *
3272  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3273  *                     destination is specified.
3274  * @param node   [i]   The PLAINTEXT tag node is specified.
3275  * @return The conversion result is returned.
3276  */
3277 static char *
3278 s_chtml50_start_plaintext_tag(void *pdoc, Node *node)
3279 {
3280   chtml50_t *chtml50 = GET_CHTML50(pdoc);
3281   Doc       *doc     = chtml50->doc;
3282   W_L("<plaintext>");
3283   s_chtml50_start_plaintext_tag_inner(pdoc,node);
3284   return chtml50->out;
3285 }
3286
3287 static char *
3288 s_chtml50_start_plaintext_tag_inner(void *pdoc, Node *node)
3289 {
3290   chtml50_t *chtml50 = GET_CHTML50(pdoc);
3291   Doc       *doc     = chtml50->doc;
3292   Node      *child;
3293   for (child = qs_get_child_node(doc, node);
3294        child;
3295        child = qs_get_next_node(doc, child)) {
3296     W_V(child->otext);
3297     s_chtml50_start_plaintext_tag_inner(pdoc, child);
3298   }
3299   return chtml50->out;
3300 }
3301
3302
3303 /**
3304  * It is a handler who processes the PLAINTEXT tag.
3305  *
3306  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3307  *                     destination is specified.
3308  * @param node   [i]   The PLAINTEXT tag node is specified.
3309  * @return The conversion result is returned.
3310  */
3311 static char *
3312 s_chtml50_end_plaintext_tag(void *pdoc, Node *UNUSED(child))
3313 {
3314   chtml50_t *chtml50 = GET_CHTML50(pdoc);
3315   return chtml50->out;
3316 }
3317
3318
3319 /**
3320  * It is handler who processes the New Line Code.
3321  */
3322 static char *
3323 s_chtml50_newline_mark(void *pdoc, Node *UNUSED(node))
3324 {
3325   chtml50_t *chtml50 = GET_CHTML50(pdoc);
3326   Doc *doc = chtml50->doc;
3327   W_NLCODE();
3328   return chtml50->out;
3329 }
3330 /*
3331  * vim:ts=2 et
3332  */