OSDN Git Service

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