OSDN Git Service

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