OSDN Git Service

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