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, "tel:")) {
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     char *new_query_string = NULL;
1500     q = strchr(attr_action, '?');
1501     if (q) {
1502       new_hidden_tag = chxj_form_action_to_hidden_tag(r, doc->pool, attr_action, 0, post_flag, &new_query_string, CHXJ_TRUE, CHXJ_FALSE);
1503       if (new_hidden_tag || new_query_string) {
1504         *q = 0;
1505       }
1506     }
1507     W_L(" action=\"");
1508     W_V(attr_action);
1509     if (new_query_string) {
1510       W_L("?");
1511       W_V(new_query_string);
1512     }
1513     W_L("\"");
1514   }
1515   if (attr_method) {
1516     W_L(" method=\"");
1517     W_V(attr_method);
1518     W_L("\"");
1519   }
1520   W_L(">");
1521   if (new_hidden_tag) {
1522     W_V(new_hidden_tag);
1523   }
1524   return chtml20->out;
1525 }
1526
1527
1528 /**
1529  * It is a handler who processes the FORM tag.
1530  *
1531  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1532  *                     destination is specified.
1533  * @param node   [i]   The FORM tag node is specified.
1534  * @return The conversion result is returned.
1535  */
1536 static char *
1537 s_chtml20_end_form_tag(void *pdoc, Node *UNUSED(child)) 
1538 {
1539   chtml20_t   *chtml20;
1540   Doc         *doc;
1541   request_rec *r;
1542
1543   chtml20 = GET_CHTML20(pdoc);
1544   doc     = chtml20->doc;
1545   r       = doc->r;
1546
1547   W_L("</form>");
1548
1549   return chtml20->out;
1550 }
1551
1552
1553 /**
1554  * It is a handler who processes the INPUT tag.
1555  *
1556  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1557  *                     destination is specified.
1558  * @param node   [i]   The INPUT tag node is specified.
1559  * @return The conversion result is returned.
1560  */
1561 static char *
1562 s_chtml20_start_input_tag(void *pdoc, Node *node) 
1563 {
1564   chtml20_t   *chtml20;
1565   Doc         *doc;
1566   request_rec *r;
1567   char        *max_length  = NULL;
1568   char        *type        = NULL;
1569   char        *name        = NULL;
1570   char        *value       = NULL;
1571   char        *istyle      = NULL;
1572   char        *size        = NULL;
1573   char        *checked     = NULL;
1574   char        *accesskey   = NULL;
1575
1576   chtml20 = GET_CHTML20(pdoc);
1577   doc     = chtml20->doc;
1578   r       = doc->r;
1579
1580
1581   W_L("<input");
1582   /*--------------------------------------------------------------------------*/
1583   /* Get Attributes                                                           */
1584   /*--------------------------------------------------------------------------*/
1585   type       = qs_get_type_attr(doc, node, doc->buf.pool);
1586   name       = qs_get_name_attr(doc, node, doc->buf.pool);
1587   value      = qs_get_value_attr(doc,node,doc->buf.pool);
1588   istyle     = qs_get_istyle_attr(doc,node,doc->buf.pool);
1589   max_length = qs_get_maxlength_attr(doc,node,doc->buf.pool);
1590   checked    = qs_get_checked_attr(doc,node,doc->buf.pool);
1591   accesskey  = qs_get_accesskey_attr(doc, node, doc->buf.pool);
1592   size       = qs_get_size_attr(doc, node, doc->buf.pool);
1593
1594   if (type) {
1595     type = qs_trim_string(doc->buf.pool, type);
1596     if (type && (STRCASEEQ('t','T',"text",    type) ||
1597                  STRCASEEQ('p','P',"password",type) ||
1598                  STRCASEEQ('c','C',"checkbox",type) ||
1599                  STRCASEEQ('r','R',"radio",   type) ||
1600                  STRCASEEQ('h','H',"hidden",  type) ||
1601                  STRCASEEQ('s','S',"submit",  type) ||
1602                  STRCASEEQ('r','R',"reset",   type))) {
1603       W_L(" type=\"");
1604       W_V(type);
1605       W_L("\"");
1606     }
1607   }
1608   if (size && *size) {
1609     W_L(" size=\"");
1610     W_V(size);
1611     W_L("\"");
1612   }
1613   if (name && *name) {
1614     W_L(" name=\"");
1615     W_V(name);
1616     W_L("\"");
1617   }
1618   if (value && *value) {
1619     W_L(" value=\"");
1620     W_V(chxj_add_slash_to_doublequote(doc->pool, value));
1621     W_L("\"");
1622   }
1623   if (accesskey && *accesskey) {
1624     W_L(" accesskey=\"");
1625     W_V(accesskey);
1626     W_L("\"");
1627   }
1628   if (istyle) {
1629     /*------------------------------------------------------------------------*/
1630     /* CHTML 2.0                                                              */
1631     /*------------------------------------------------------------------------*/
1632     if (*istyle == '1' || *istyle == '2' || *istyle == '3' || *istyle == '4') {
1633       W_L(" istyle=\"");
1634       W_V(istyle);
1635       W_L("\"");
1636     }
1637   }
1638   /*--------------------------------------------------------------------------*/
1639   /* The figure is default for the password.                                  */
1640   /*--------------------------------------------------------------------------*/
1641   if (max_length && *max_length) {
1642     if (chxj_chk_numeric(max_length) != 0) {
1643       max_length = apr_psprintf(doc->buf.pool, "0");
1644     }
1645     if (istyle && *istyle == '1') {
1646       char *vv = apr_psprintf(doc->buf.pool, " maxlength=\"%d\"", chxj_atoi(max_length) * 2);
1647       W_V(vv);
1648     }
1649     else {
1650       char *vv = apr_psprintf(doc->buf.pool, " maxlength=\"%d\"", chxj_atoi(max_length));
1651       W_V(vv);
1652     }
1653   }
1654   if (checked) {
1655     W_L(" checked");
1656   }
1657   W_L(">");
1658
1659   return chtml20->out;
1660 }
1661
1662
1663 /**
1664  * It is a handler who processes the INPUT tag.
1665  *
1666  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1667  *                     destination is specified.
1668  * @param node   [i]   The INPUT tag node is specified.
1669  * @return The conversion result is returned.
1670  */
1671 static char *
1672 s_chtml20_end_input_tag(void *pdoc, Node *UNUSED(child)) 
1673 {
1674   chtml20_t   *chtml20;
1675   Doc         *doc;
1676   request_rec *r;
1677
1678   chtml20 = GET_CHTML20(pdoc);
1679   doc     = chtml20->doc;
1680   r       = doc->r;
1681
1682   return chtml20->out;
1683 }
1684
1685
1686 /**
1687  * It is a handler who processes the CENTER tag.
1688  *
1689  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1690  *                     destination is specified.
1691  * @param node   [i]   The CENTER tag node is specified.
1692  * @return The conversion result is returned.
1693  */
1694 static char *
1695 s_chtml20_start_center_tag(void *pdoc, Node *UNUSED(node)) 
1696 {
1697   chtml20_t   *chtml20;
1698   Doc         *doc;
1699   request_rec *r;
1700
1701   chtml20 = GET_CHTML20(pdoc);
1702   doc     = chtml20->doc;
1703   r       = doc->r;
1704
1705   W_L("<center>");
1706   return chtml20->out;
1707 }
1708
1709
1710 /**
1711  * It is a handler who processes the CENTER tag.
1712  *
1713  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1714  *                     destination is specified.
1715  * @param node   [i]   The CENTER tag node is specified.
1716  * @return The conversion result is returned.
1717  */
1718 static char *
1719 s_chtml20_end_center_tag(void *pdoc, Node *UNUSED(child)) 
1720 {
1721   chtml20_t   *chtml20;
1722   Doc         *doc;
1723   request_rec *r;
1724
1725   chtml20 = GET_CHTML20(pdoc);
1726   doc     = chtml20->doc;
1727   r       = doc->r;
1728
1729   W_L("</center>");
1730
1731   return chtml20->out;
1732 }
1733
1734
1735 /**
1736  * It is a handler who processes the UL tag.
1737  *
1738  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1739  *                     destination is specified.
1740  * @param node   [i]   The UL tag node is specified.
1741  * @return The conversion result is returned.
1742  */
1743 static char *
1744 s_chtml20_start_ul_tag(void *pdoc, Node *UNUSED(node)) 
1745 {
1746   chtml20_t   *chtml20;
1747   Doc         *doc;
1748   request_rec *r;
1749
1750   chtml20 = GET_CHTML20(pdoc);
1751   doc     = chtml20->doc;
1752   r       = doc->r;
1753
1754   W_L("<ul>");
1755
1756   return chtml20->out;
1757 }
1758
1759
1760 /**
1761  * It is a handler who processes the UL tag.
1762  *
1763  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1764  *                     destination is specified.
1765  * @param node   [i]   The UL tag node is specified.
1766  * @return The conversion result is returned.
1767  */
1768 static char *
1769 s_chtml20_end_ul_tag(void *pdoc, Node *UNUSED(child)) 
1770 {
1771   chtml20_t     *chtml20;
1772   Doc           *doc;
1773   request_rec   *r;
1774
1775   chtml20 = GET_CHTML20(pdoc);
1776   doc     = chtml20->doc;
1777   r       = doc->r;
1778
1779   W_L("</ul>");
1780
1781   return chtml20->out;
1782 }
1783
1784
1785 /**
1786  * It is a handler who processes the OL tag.
1787  *
1788  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1789  *                     destination is specified.
1790  * @param node   [i]   The OL tag node is specified.
1791  * @return The conversion result is returned.
1792  */
1793 static char *
1794 s_chtml20_start_ol_tag(void *pdoc, Node *node) 
1795 {
1796   chtml20_t   *chtml20;
1797   Doc         *doc;
1798   request_rec *r;
1799   Attr        *attr;
1800
1801   chtml20 = GET_CHTML20(pdoc);
1802   doc     = chtml20->doc;
1803   r       = doc->r;
1804
1805   W_L("<ol");
1806   /*--------------------------------------------------------------------------*/
1807   /* Get Attributes                                                           */
1808   /*--------------------------------------------------------------------------*/
1809   for (attr = qs_get_attr(doc,node);
1810        attr;
1811        attr = qs_get_next_attr(doc,attr)) {
1812     char *name = qs_get_attr_name(doc,attr);
1813     char *value = qs_get_attr_value(doc,attr);
1814     if (STRCASEEQ('t','T',"type",name) && value && (*value == '1' || *value == 'a' || *value == 'A')) {
1815       W_L(" type=\"");
1816       W_V(value);
1817       W_L("\"");
1818     }
1819     else if (STRCASEEQ('s','S',"start",name) && value && *value) {
1820       W_L(" start=\"");
1821       W_V(value);
1822       W_L("\"");
1823     }
1824   }
1825   W_L(">");
1826
1827   return chtml20->out;
1828 }
1829
1830
1831 /**
1832  * It is a handler who processes the OL tag.
1833  *
1834  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1835  *                     destination is specified.
1836  * @param node   [i]   The OL tag node is specified.
1837  * @return The conversion result is returned.
1838  */
1839 static char *
1840 s_chtml20_end_ol_tag(void *pdoc, Node *UNUSED(child)) 
1841 {
1842   chtml20_t   *chtml20;
1843   Doc         *doc;
1844   request_rec *r;
1845
1846   chtml20 = GET_CHTML20(pdoc);
1847   doc     = chtml20->doc;
1848   r       = doc->r;
1849
1850   W_L("</ol>");
1851
1852   return chtml20->out;
1853 }
1854
1855
1856 /**
1857  * It is a handler who processes the LI tag.
1858  *
1859  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1860  *                     destination is specified.
1861  * @param node   [i]   The LI tag node is specified.
1862  * @return The conversion result is returned.
1863  */
1864 static char *
1865 s_chtml20_start_li_tag(void *pdoc, Node *node) 
1866 {
1867   chtml20_t   *chtml20;
1868   Doc         *doc;
1869   request_rec *r;
1870   Attr        *attr;
1871
1872   chtml20 = GET_CHTML20(pdoc);
1873   doc     = chtml20->doc;
1874   r       = doc->r;
1875
1876   W_L("<li");
1877   /*--------------------------------------------------------------------------*/
1878   /* Get Attributes                                                           */
1879   /*--------------------------------------------------------------------------*/
1880   for (attr = qs_get_attr(doc,node);
1881        attr;
1882        attr = qs_get_next_attr(doc,attr)) {
1883     char *name = qs_get_attr_name(doc,attr);
1884     char *value = qs_get_attr_value(doc,attr);
1885     if (STRCASEEQ('t','T',"type",name) && value && (*value == '1' || *value == 'a' || *value == 'A')) {
1886       W_L(" type=\"");
1887       W_V(value);
1888       W_L("\"");
1889     }
1890     else if (STRCASEEQ('v','V',"value", name) && value && *value) {
1891       W_L(" value=\"");
1892       W_V(value);
1893       W_L("\"");
1894     }
1895   }
1896   W_L(">");
1897   return chtml20->out;
1898 }
1899
1900
1901 /**
1902  * It is a handler who processes the LI tag.
1903  *
1904  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1905  *                     destination is specified.
1906  * @param node   [i]   The LI tag node is specified.
1907  * @return The conversion result is returned.
1908  */
1909 static char *
1910 s_chtml20_end_li_tag(void *pdoc, Node *UNUSED(child)) 
1911 {
1912   chtml20_t *chtml20 = GET_CHTML20(pdoc);
1913   return chtml20->out;
1914 }
1915
1916
1917 /**
1918  * It is a handler who processes the HR tag.
1919  *
1920  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1921  *                     destination is specified.
1922  * @param node   [i]   The HR tag node is specified.
1923  * @return The conversion result is returned.
1924  */
1925 static char *
1926 s_chtml20_start_hr_tag(void *pdoc, Node *node) 
1927 {
1928   chtml20_t   *chtml20;
1929   Doc         *doc;
1930   request_rec *r;
1931   Attr        *attr;
1932
1933   chtml20 = GET_CHTML20(pdoc);
1934   doc     = chtml20->doc;
1935   r       = doc->r;
1936
1937
1938   W_L("<hr");
1939   for (attr = qs_get_attr(doc,node);
1940        attr; 
1941        attr = qs_get_next_attr(doc,attr)) {
1942     char *name  = qs_get_attr_name(doc,attr);
1943     char *value = qs_get_attr_value(doc,attr);
1944     switch(*name) {
1945     case 'a':
1946     case 'A':
1947       if (strcasecmp(name, "align") == 0) {
1948         /*--------------------------------------------------------------------*/
1949         /* CHTML 1.0                                                          */
1950         /*--------------------------------------------------------------------*/
1951         if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
1952           W_L(" align=\"");
1953           W_V(value);
1954           W_L("\"");
1955         }
1956       }
1957       break;
1958
1959     case 's':
1960     case 'S':
1961       if (strcasecmp(name, "size") == 0) {
1962         /*--------------------------------------------------------------------*/
1963         /* CHTML 1.0                                                          */
1964         /*--------------------------------------------------------------------*/
1965         if (value && value[0] != '\0') {
1966           W_L(" size=\"");
1967           W_V(value);
1968           W_L("\"");
1969         }
1970       }
1971       break;
1972
1973     case 'w':
1974     case 'W':
1975       if (strcasecmp(name, "width") == 0) {
1976         /*--------------------------------------------------------------------*/
1977         /* CHTML 1.0                                                          */
1978         /*--------------------------------------------------------------------*/
1979         if (value && value[0] != '\0') {
1980           W_L(" width=\"");
1981           W_V(value);
1982           W_L("\"");
1983         }
1984       }
1985       break;
1986
1987     case 'n':
1988     case 'N':
1989       if (strcasecmp(name, "noshade") == 0) {
1990         /*--------------------------------------------------------------------*/
1991         /* CHTML 1.0                                                          */
1992         /*--------------------------------------------------------------------*/
1993         W_L(" noshade");
1994       }
1995       break;
1996
1997     case 'c':
1998     case 'C':
1999       if (strcasecmp(name, "color") == 0) {
2000         /*--------------------------------------------------------------------*/
2001         /* CHTML 4.0                                                          */
2002         /*--------------------------------------------------------------------*/
2003         /* ignore */
2004       }
2005       break;
2006
2007     default:
2008       break;
2009     }
2010   }
2011   W_L(">");
2012   return chtml20->out;
2013 }
2014
2015
2016 /**
2017  * It is a handler who processes the HR tag.
2018  *
2019  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2020  *                     destination is specified.
2021  * @param node   [i]   The HR tag node is specified.
2022  * @return The conversion result is returned.
2023  */
2024 static char *
2025 s_chtml20_end_hr_tag(void *pdoc, Node *UNUSED(child)) 
2026 {
2027   chtml20_t *chtml20 = GET_CHTML20(pdoc);
2028   return chtml20->out;
2029 }
2030
2031
2032 /**
2033  * It is a handler who processes the IMG tag.
2034  *
2035  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2036  *                     destination is specified.
2037  * @param node   [i]   The IMG tag node is specified.
2038  * @return The conversion result is returned.
2039  */
2040 static char *
2041 s_chtml20_start_img_tag(void *pdoc, Node *node) 
2042 {
2043   chtml20_t    *chtml20;
2044   Doc          *doc;
2045   request_rec  *r;
2046   Attr         *attr;
2047 #ifndef IMG_NOT_CONVERT_FILENAME
2048   device_table *spec;
2049 #endif
2050
2051   chtml20 = GET_CHTML20(pdoc);
2052   doc     = chtml20->doc;
2053   r       = doc->r;
2054
2055 #ifndef IMG_NOT_CONVERT_FILENAME
2056   spec = chtml20->spec;
2057 #endif
2058
2059   W_L("<img");
2060   /*-------------------------------------------------------------------------*/
2061   /* Get Attributes                                                          */
2062   /*-------------------------------------------------------------------------*/
2063   for (attr = qs_get_attr(doc,node);
2064        attr;
2065        attr = qs_get_next_attr(doc,attr)) {
2066     char *name  = qs_get_attr_name(doc,attr);
2067     char *value = qs_get_attr_value(doc,attr);
2068     switch(*name) {
2069     case 's':
2070     case 'S':
2071       if (strcasecmp(name, "src") == 0) {
2072         /*-------------------------------------------------------------------*/
2073         /* CHTML 1.0                                                         */
2074         /*-------------------------------------------------------------------*/
2075 #ifdef IMG_NOT_CONVERT_FILENAME
2076         value = chxj_encoding_parameter(r, value);
2077         value = chxj_add_cookie_parameter(r, value, chtml20->cookie);
2078         value = chxj_add_cookie_no_update_parameter(r, value);
2079         W_L(" src=\"");
2080         W_V(value);
2081         W_L("\"");
2082 #else
2083         value = chxj_img_conv(r, spec, value);
2084         value = chxj_encoding_parameter(r, value);
2085         value = chxj_add_cookie_parameter(r, value, chtml20->cookie);
2086         value = chxj_add_cookie_no_update_parameter(r, value);
2087         W_L(" src=\"");
2088         W_V(value);
2089         W_L("\"");
2090 #endif
2091       }
2092       break;
2093
2094     case 'a':
2095     case 'A':
2096       if (strcasecmp(name, "align" ) == 0) {
2097         /*--------------------------------------------------------------------*/
2098         /* CHTML 1.0                                                          */
2099         /*--------------------------------------------------------------------*/
2100         if (value) {
2101           if (STRCASEEQ('t','T',"top",   value) ||
2102               STRCASEEQ('m','M',"middle",value) ||
2103               STRCASEEQ('b','B',"bottom",value) ||
2104               STRCASEEQ('l','L',"left",  value) ||
2105               STRCASEEQ('r','R',"right", value)) {
2106             W_L(" align=\"");
2107             W_V(value);
2108             W_L("\"");
2109           }
2110           else if (STRCASEEQ('c','C',"center",  value)) {
2111             W_L(" align=\"");
2112             W_L("middle");
2113             W_L("\"");
2114           }
2115         }
2116       }
2117       else if (strcasecmp(name, "alt"   ) == 0 && value && *value) {
2118         /*--------------------------------------------------------------------*/
2119         /* CHTML 1.0                                                          */
2120         /*--------------------------------------------------------------------*/
2121         W_L(" alt=\"");
2122         W_V(value);
2123         W_L("\"");
2124       }
2125       break;
2126
2127     case 'w':
2128     case 'W':
2129       if (strcasecmp(name, "width" ) == 0 && value && *value) {
2130         /*--------------------------------------------------------------------*/
2131         /* CHTML 1.0                                                          */
2132         /*--------------------------------------------------------------------*/
2133         W_L(" width=\"");
2134         W_V(value);
2135         W_L("\"");
2136       }
2137       break;
2138
2139     case 'h':
2140     case 'H':
2141       if (strcasecmp(name, "height") == 0 && value && *value) {
2142         /*--------------------------------------------------------------------*/
2143         /* CHTML 1.0                                                          */
2144         /*--------------------------------------------------------------------*/
2145         W_L(" height=\"");
2146         W_V(value);
2147         W_L("\"");
2148       }
2149       else if (strcasecmp(name, "hspace") == 0 && value && *value) {
2150         /*--------------------------------------------------------------------*/
2151         /* CHTML 1.0                                                          */
2152         /*--------------------------------------------------------------------*/
2153         W_L(" hspace=\"");
2154         W_V(value);
2155         W_L("\"");
2156       }
2157       break;
2158
2159     case 'v':
2160     case 'V':
2161       if (strcasecmp(name, "vspace") == 0 && value && *value) {
2162         /*--------------------------------------------------------------------*/
2163         /* CHTML 1.0                                                          */
2164         /*--------------------------------------------------------------------*/
2165         W_L(" vspace=\"");
2166         W_V(value);
2167         W_L("\"");
2168       }
2169       break;
2170
2171     default:
2172       break;
2173     }
2174   }
2175   W_L(">");
2176   return chtml20->out;
2177 }
2178
2179
2180 /**
2181  * It is a handler who processes the IMG tag.
2182  *
2183  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2184  *                     destination is specified.
2185  * @param node   [i]   The IMG tag node is specified.
2186  * @return The conversion result is returned.
2187  */
2188 static char *
2189 s_chtml20_end_img_tag(void *pdoc, Node *UNUSED(child)) 
2190 {
2191   chtml20_t *chtml20 = GET_CHTML20(pdoc);
2192
2193   return chtml20->out;
2194 }
2195
2196
2197 /**
2198  * It is a handler who processes the SELECT tag.
2199  *
2200  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2201  *                     destination is specified.
2202  * @param node   [i]   The SELECT tag node is specified.
2203  * @return The conversion result is returned.
2204  */
2205 static char *
2206 s_chtml20_start_select_tag(void *pdoc, Node *child)
2207 {
2208   chtml20_t   *chtml20;
2209   Doc         *doc;
2210   request_rec *r;
2211   Attr        *attr;
2212
2213   chtml20 = GET_CHTML20(pdoc);
2214   doc     = chtml20->doc;
2215   r       = doc->r;
2216
2217   char *size      = NULL;
2218   char *name      = NULL;
2219   char *multiple  = NULL;
2220
2221   W_L("<select");
2222   for (attr = qs_get_attr(doc,child);
2223        attr;
2224        attr = qs_get_next_attr(doc,attr)) {
2225     char *nm = qs_get_attr_name(doc,attr);
2226     char *val = qs_get_attr_value(doc,attr);
2227     switch(*nm) {
2228     case 's':
2229     case 'S':
2230       if (strcasecmp(nm, "size") == 0) {
2231         /*--------------------------------------------------------------------*/
2232         /* CHTML 1.0 version 2.0                                              */
2233         /*--------------------------------------------------------------------*/
2234         size = apr_pstrdup(doc->buf.pool, val);
2235       }
2236       break;
2237
2238     case 'n':
2239     case 'N':
2240       if (strcasecmp(nm, "name") == 0) {
2241         /*--------------------------------------------------------------------*/
2242         /* CHTML 1.0 version 2.0                                              */
2243         /*--------------------------------------------------------------------*/
2244         name = apr_pstrdup(doc->buf.pool, val);
2245       }
2246       break;
2247
2248     case 'm':
2249     case 'M':
2250       if (strcasecmp(nm, "multiple") == 0) {
2251         /*--------------------------------------------------------------------*/
2252         /* CHTML 1.0 version 2.0                                              */
2253         /*--------------------------------------------------------------------*/
2254         multiple = apr_pstrdup(doc->buf.pool, val);
2255       }
2256       break;
2257
2258     default:
2259       break;
2260     }
2261   }
2262   if (size && *size) {
2263     W_L(" size=\"");
2264     W_V(size);
2265     W_L("\"");
2266   }
2267   if (name && *name) {
2268     W_L(" name=\"");
2269     W_V(name);
2270     W_L("\"");
2271   }
2272   if (multiple) {
2273     W_L(" multiple");
2274   }
2275   W_L(">");
2276   return chtml20->out;
2277 }
2278
2279
2280 /**
2281  * It is a handler who processes the SELECT tag.
2282  *
2283  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2284  *                     destination is specified.
2285  * @param node   [i]   The SELECT tag node is specified.
2286  * @return The conversion result is returned.
2287  */
2288 static char *
2289 s_chtml20_end_select_tag(void *pdoc, Node *UNUSED(child))
2290 {
2291   chtml20_t   *chtml20;
2292   Doc         *doc;
2293
2294   chtml20 = GET_CHTML20(pdoc);
2295   doc     = chtml20->doc;
2296
2297   W_L("</select>");
2298   return chtml20->out;
2299 }
2300
2301
2302 /**
2303  * It is a handler who processes the OPTION tag.
2304  *
2305  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2306  *                     destination is specified.
2307  * @param node   [i]   The OPTION tag node is specified.
2308  * @return The conversion result is returned.
2309  */
2310 static char *
2311 s_chtml20_start_option_tag(void *pdoc, Node *child)
2312 {
2313   chtml20_t   *chtml20;
2314   Doc         *doc;
2315   request_rec *r;
2316   Attr        *attr;
2317
2318   chtml20 = GET_CHTML20(pdoc);
2319   doc     = chtml20->doc;
2320   r       = doc->r;
2321
2322   char *selected   = NULL;
2323   char *value      = NULL;
2324
2325   W_L("<option");
2326   for (attr = qs_get_attr(doc,child);
2327        attr;
2328        attr = qs_get_next_attr(doc,attr)) {
2329     char *nm  = qs_get_attr_name(doc,attr);
2330     char *val = qs_get_attr_value(doc,attr);
2331     switch(*nm) {
2332     case 's':
2333     case 'S':
2334       if (strcasecmp(nm, "selected") == 0) {
2335         /*--------------------------------------------------------------------*/
2336         /* CHTML 1.0 version 2.0                                              */
2337         /*--------------------------------------------------------------------*/
2338         selected = apr_pstrdup(doc->buf.pool, val);
2339       }
2340       break;
2341
2342     case 'v':
2343     case 'V':
2344       if (strcasecmp(nm, "value") == 0) {
2345         /*--------------------------------------------------------------------*/
2346         /* CHTML 1.0 version 2.0                                              */
2347         /*--------------------------------------------------------------------*/
2348         value = apr_pstrdup(doc->buf.pool, val);
2349       }
2350       break;
2351
2352     default:
2353       break;
2354     }
2355   }
2356
2357   if (value) {
2358     W_L(" value=\"");
2359     W_V(value);
2360     W_L("\"");
2361   }
2362
2363   if (selected) {
2364     W_L(" selected");
2365   }
2366   W_L(">");
2367   return chtml20->out;
2368 }
2369
2370
2371 /**
2372  * It is a handler who processes the OPTION tag.
2373  *
2374  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2375  *                     destination is specified.
2376  * @param node   [i]   The OPTION tag node is specified.
2377  * @return The conversion result is returned.
2378  */
2379 static char *
2380 s_chtml20_end_option_tag(void *pdoc, Node *UNUSED(child))
2381 {
2382   chtml20_t   *chtml20 = GET_CHTML20(pdoc);
2383
2384   /* Don't close */
2385
2386   return chtml20->out;
2387 }
2388
2389
2390 /**
2391  * It is a handler who processes the DIV tag.
2392  *
2393  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2394  *                     destination is specified.
2395  * @param node   [i]   The DIV tag node is specified.
2396  * @return The conversion result is returned.
2397  */
2398 static char *
2399 s_chtml20_start_div_tag(void *pdoc, Node *child)
2400 {
2401   chtml20_t   *chtml20;
2402   Doc         *doc;
2403   request_rec *r;
2404   Attr        *attr;
2405
2406   chtml20 = GET_CHTML20(pdoc);
2407   doc     = chtml20->doc;
2408   r       = doc->r;
2409
2410
2411   char *align   = NULL;
2412
2413   W_L("<div");
2414   for (attr = qs_get_attr(doc,child);
2415        attr;
2416        attr = qs_get_next_attr(doc,attr)) {
2417     char *nm  = qs_get_attr_name(doc,attr);
2418     char *val = qs_get_attr_value(doc,attr);
2419     if (STRCASEEQ('a','A', "align", nm)) {
2420       /*----------------------------------------------------------------------*/
2421       /* CHTML 1.0 (W3C version 3.2)                                          */
2422       /*----------------------------------------------------------------------*/
2423       if (val && (STRCASEEQ('l','L',"left",val) || STRCASEEQ('r','R',"right",val) || STRCASEEQ('c','C',"center",val))) {
2424         align = apr_pstrdup(doc->buf.pool, val);
2425       }
2426     }
2427   }
2428   if (align) {
2429     W_L(" align=\"");
2430     W_V(align);
2431     W_L("\"");
2432   }
2433   W_L(">");
2434   return chtml20->out;
2435 }
2436
2437
2438 /**
2439  * It is a handler who processes the DIV tag.
2440  *
2441  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2442  *                     destination is specified.
2443  * @param node   [i]   The DIV tag node is specified.
2444  * @return The conversion result is returned.
2445  */
2446 static char *
2447 s_chtml20_end_div_tag(void *pdoc, Node *UNUSED(child))
2448 {
2449   chtml20_t   *chtml20 = GET_CHTML20(pdoc);
2450   Doc         *doc     = chtml20->doc;
2451
2452   W_L("</div>");
2453   return chtml20->out;
2454 }
2455
2456
2457 /**
2458  * It is a handler who processes the H1 tag.
2459  *
2460  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2461  *                     destination is specified.
2462  * @param node   [i]   The H1 tag node is specified.
2463  * @return The conversion result is returned.
2464  */
2465 static char *
2466 s_chtml20_start_h1_tag(void *pdoc, Node *node) 
2467 {
2468   chtml20_t   *chtml20;
2469   Doc         *doc;
2470   request_rec *r;
2471   Attr        *attr;
2472
2473   chtml20 = GET_CHTML20(pdoc);
2474   doc     = chtml20->doc;
2475   r       = doc->r;
2476
2477   W_L("<h1");
2478   for (attr = qs_get_attr(doc,node);
2479        attr;
2480        attr = qs_get_next_attr(doc,attr)) {
2481     char *name  = qs_get_attr_name(doc,attr);
2482     char *value = qs_get_attr_value(doc,attr);
2483     if (STRCASEEQ('a','A',"align", name)) {
2484       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
2485         W_L(" align=\"");
2486         W_V(value);
2487         W_L("\"");
2488         break;
2489       }
2490     }
2491   }
2492   W_L(">");
2493   return chtml20->out;
2494 }
2495
2496
2497 /**
2498  * It is a handler who processes the H1 tag.
2499  *
2500  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2501  *                     destination is specified.
2502  * @param node   [i]   The H1 tag node is specified.
2503  * @return The conversion result is returned.
2504  */
2505 static char *
2506 s_chtml20_end_h1_tag(void *pdoc, Node *UNUSED(child)) 
2507 {
2508   chtml20_t   *chtml20;
2509   Doc         *doc;
2510
2511   chtml20 = GET_CHTML20(pdoc);
2512   doc     = chtml20->doc;
2513
2514   W_L("</h1>");
2515   return chtml20->out;
2516 }
2517
2518
2519 /**
2520  * It is a handler who processes the H2 tag.
2521  *
2522  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2523  *                     destination is specified.
2524  * @param node   [i]   The H2 tag node is specified.
2525  * @return The conversion result is returned.
2526  */
2527 static char *
2528 s_chtml20_start_h2_tag(void *pdoc, Node *node) 
2529 {
2530   chtml20_t   *chtml20;
2531   Doc         *doc;
2532   request_rec *r;
2533   Attr        *attr;
2534
2535   chtml20 = GET_CHTML20(pdoc);
2536   doc     = chtml20->doc;
2537   r       = doc->r;
2538
2539   W_L("<h2");
2540   for (attr = qs_get_attr(doc,node);
2541        attr;
2542        attr = qs_get_next_attr(doc,attr)) {
2543     char *name  = qs_get_attr_name(doc,attr);
2544     char *value = qs_get_attr_value(doc,attr);
2545     if (STRCASEEQ('a','A',"align", name)) {
2546       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
2547         W_L(" align=\"");
2548         W_V(value);
2549         W_L("\"");
2550         break;
2551       }
2552     }
2553   }
2554   W_L(">");
2555   return chtml20->out;
2556 }
2557
2558
2559 /**
2560  * It is a handler who processes the H2 tag.
2561  *
2562  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2563  *                     destination is specified.
2564  * @param node   [i]   The H2 tag node is specified.
2565  * @return The conversion result is returned.
2566  */
2567 static char *
2568 s_chtml20_end_h2_tag(void *pdoc, Node *UNUSED(child)) 
2569
2570   chtml20_t   *chtml20 = GET_CHTML20(pdoc);
2571   Doc         *doc     = chtml20->doc;
2572
2573   W_L("</h2>");
2574
2575   return chtml20->out;
2576 }
2577
2578
2579 /**
2580  * It is a handler who processes the H3 tag.
2581  *
2582  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2583  *                     destination is specified.
2584  * @param node   [i]   The H3 tag node is specified.
2585  * @return The conversion result is returned.
2586  */
2587 static char *
2588 s_chtml20_start_h3_tag(void *pdoc, Node *node) 
2589 {
2590   chtml20_t   *chtml20;
2591   Doc         *doc;
2592   request_rec *r;
2593   Attr        *attr;
2594
2595   chtml20 = GET_CHTML20(pdoc);
2596   doc     = chtml20->doc;
2597   r       = doc->r;
2598
2599   W_L("<h3");
2600   for (attr = qs_get_attr(doc,node);
2601        attr;
2602        attr = qs_get_next_attr(doc,attr)) {
2603     char *name  = qs_get_attr_name(doc,attr);
2604     char *value = qs_get_attr_value(doc,attr);
2605     if (STRCASEEQ('a','A',"align", name)) {
2606       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
2607         W_L(" align=\"");
2608         W_V(value);
2609         W_L("\"");
2610         break;
2611       }
2612     }
2613   }
2614   W_L(">");
2615   return chtml20->out;
2616 }
2617
2618
2619 /**
2620  * It is a handler who processes the H3 tag.
2621  *
2622  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2623  *                     destination is specified.
2624  * @param node   [i]   The H3 tag node is specified.
2625  * @return The conversion result is returned.
2626  */
2627 static char *
2628 s_chtml20_end_h3_tag(void *pdoc, Node *UNUSED(child)) 
2629 {
2630   chtml20_t   *chtml20 = GET_CHTML20(pdoc);
2631   Doc         *doc     = chtml20->doc;
2632
2633   W_L("</h3>");
2634   return chtml20->out;
2635 }
2636
2637
2638 /**
2639  * It is a handler who processes the H4 tag.
2640  *
2641  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2642  *                     destination is specified.
2643  * @param node   [i]   The H4 tag node is specified.
2644  * @return The conversion result is returned.
2645  */
2646 static char *
2647 s_chtml20_start_h4_tag(void *pdoc, Node *node)
2648 {
2649   chtml20_t   *chtml20;
2650   Doc         *doc;
2651   request_rec *r;
2652   Attr        *attr;
2653
2654   chtml20 = GET_CHTML20(pdoc);
2655   doc     = chtml20->doc;
2656   r       = doc->r;
2657
2658   W_L("<h4");
2659   for (attr = qs_get_attr(doc,node);
2660        attr;
2661        attr = qs_get_next_attr(doc,attr)) {
2662     char *name  = qs_get_attr_name(doc,attr);
2663     char *value = qs_get_attr_value(doc,attr);
2664     if (STRCASEEQ('a','A',"align", name)) {
2665       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
2666         W_L(" align=\"");
2667         W_V(value);
2668         W_L("\"");
2669         break;
2670       }
2671     }
2672   }
2673   W_L(">");
2674   return chtml20->out;
2675 }
2676
2677
2678 /**
2679  * It is a handler who processes the H4 tag.
2680  *
2681  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2682  *                     destination is specified.
2683  * @param node   [i]   The H4 tag node is specified.
2684  * @return The conversion result is returned.
2685  */
2686 static char *
2687 s_chtml20_end_h4_tag(void *pdoc, Node *UNUSED(child)) 
2688 {
2689   chtml20_t   *chtml20 = GET_CHTML20(pdoc);
2690   Doc         *doc     = chtml20->doc;
2691
2692   W_L("</h4>");
2693   return chtml20->out;
2694 }
2695
2696
2697 /**
2698  * It is a handler who processes the H5 tag.
2699  *
2700  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2701  *                     destination is specified.
2702  * @param node   [i]   The H5 tag node is specified.
2703  * @return The conversion result is returned.
2704  */
2705 static char *
2706 s_chtml20_start_h5_tag(void *pdoc, Node *node)
2707 {
2708   chtml20_t   *chtml20;
2709   Doc         *doc;
2710   request_rec *r;
2711   Attr        *attr;
2712
2713   chtml20 = GET_CHTML20(pdoc);
2714   doc     = chtml20->doc;
2715   r       = doc->r;
2716
2717   W_L("<h5");
2718   for (attr = qs_get_attr(doc,node);
2719        attr;
2720        attr = qs_get_next_attr(doc,attr)) {
2721     char *name  = qs_get_attr_name(doc,attr);
2722     char *value = qs_get_attr_value(doc,attr);
2723     if (STRCASEEQ('a','A',"align", name)) {
2724       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
2725         W_L(" align=\"");
2726         W_V(value);
2727         W_L("\"");
2728         break;
2729       }
2730     }
2731   }
2732   W_L(">");
2733   return chtml20->out;
2734 }
2735
2736
2737 /**
2738  * It is a handler who processes the H5 tag.
2739  *
2740  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2741  *                     destination is specified.
2742  * @param node   [i]   The H5 tag node is specified.
2743  * @return The conversion result is returned.
2744  */
2745 static char *
2746 s_chtml20_end_h5_tag(void *pdoc, Node *UNUSED(child)) 
2747 {
2748   chtml20_t   *chtml20 = GET_CHTML20(pdoc);
2749   Doc         *doc     = chtml20->doc;
2750
2751   W_L("</h5>");
2752   return chtml20->out;
2753 }
2754
2755
2756 /**
2757  * It is a handler who processes the H6 tag.
2758  *
2759  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2760  *                     destination is specified.
2761  * @param node   [i]   The H6 tag node is specified.
2762  * @return The conversion result is returned.
2763  */
2764 static char *
2765 s_chtml20_start_h6_tag(void *pdoc, Node *node)
2766 {
2767   chtml20_t   *chtml20;
2768   Doc         *doc;
2769   request_rec *r;
2770   Attr        *attr;
2771
2772   chtml20 = GET_CHTML20(pdoc);
2773   doc     = chtml20->doc;
2774   r       = doc->r;
2775
2776   W_L("<h6");
2777   for (attr = qs_get_attr(doc,node);
2778        attr;
2779        attr = qs_get_next_attr(doc,attr)) {
2780     char *name  = qs_get_attr_name(doc,attr);
2781     char *value = qs_get_attr_value(doc,attr);
2782     if (STRCASEEQ('a','A',"align", name)) {
2783       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
2784         W_L(" align=\"");
2785         W_V(value);
2786         W_L("\"");
2787         break;
2788       }
2789     }
2790   }
2791   W_L(">");
2792   return chtml20->out;
2793 }
2794
2795
2796 /**
2797  * It is a handler who processes the H6 tag.
2798  *
2799  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2800  *                     destination is specified.
2801  * @param node   [i]   The H6 tag node is specified.
2802  * @return The conversion result is returned.
2803  */
2804 static char *
2805 s_chtml20_end_h6_tag(void *pdoc, Node *UNUSED(child)) 
2806 {
2807   chtml20_t   *chtml20 = GET_CHTML20(pdoc);
2808   Doc         *doc     = chtml20->doc;
2809
2810   W_L("</h6>");
2811   return chtml20->out;
2812 }
2813
2814
2815 /**
2816  * It is a handler who processes the PRE tag.
2817  *
2818  * @param pdoc  [i/o] The pointer to the XHTML structure at the output
2819  *                     destination is specified.
2820  * @param node   [i]   The PRE tag node is specified.
2821  * @return The conversion result is returned.
2822  */
2823 static char *
2824 s_chtml20_start_pre_tag(void *pdoc, Node *UNUSED(node)) 
2825 {
2826   chtml20_t   *chtml20 = GET_CHTML20(pdoc);
2827   Doc         *doc     = chtml20->doc;
2828
2829   chtml20->pre_flag++;
2830   W_L("<pre>");
2831   return chtml20->out;
2832 }
2833
2834
2835 /**
2836  * It is a handler who processes the PRE tag.
2837  *
2838  * @param pdoc  [i/o] The pointer to the XHTML structure at the output
2839  *                     destination is specified.
2840  * @param node   [i]   The PRE tag node is specified.
2841  * @return The conversion result is returned.
2842  */
2843 static char *
2844 s_chtml20_end_pre_tag(void *pdoc, Node *UNUSED(child)) 
2845 {
2846   chtml20_t   *chtml20 = GET_CHTML20(pdoc);
2847   Doc         *doc     = chtml20->doc;
2848
2849   W_L("</pre>");
2850   chtml20->pre_flag--;
2851
2852   return chtml20->out;
2853 }
2854
2855
2856 /**
2857  * It is a handler who processes the P tag.
2858  *
2859  * @param pdoc  [i/o] The pointer to the XHTML structure at the output
2860  *                     destination is specified.
2861  * @param node   [i]   The P tag node is specified.
2862  * @return The conversion result is returned.
2863  */
2864 static char *
2865 s_chtml20_start_p_tag(void *pdoc, Node *node)
2866 {
2867   chtml20_t   *chtml20;
2868   Doc         *doc;
2869   request_rec *r;
2870   Attr        *attr;
2871   char        *align = NULL;
2872
2873   chtml20 = GET_CHTML20(pdoc);
2874   doc     = chtml20->doc;
2875   r       = doc->r;
2876
2877   W_L("<p");
2878   for (attr = qs_get_attr(doc,node);
2879        attr;
2880        attr = qs_get_next_attr(doc,attr)) {
2881     char *nm  = qs_get_attr_name(doc,attr);
2882     char *val = qs_get_attr_value(doc,attr);
2883     if (STRCASEEQ('a','A',"align", nm)) {
2884       /*----------------------------------------------------------------------*/
2885       /* CHTML 1.0 (W3C version 3.2)                                          */
2886       /*----------------------------------------------------------------------*/
2887       if (val && (STRCASEEQ('l','L',"left",val) || STRCASEEQ('r','R',"right",val) || STRCASEEQ('c','C',"center",val))) {
2888         align = apr_pstrdup(doc->buf.pool, val);
2889         break;
2890       }
2891     }
2892   }
2893   if (align) {
2894     W_L(" align=\"");
2895     W_V(align);
2896     W_L("\"");
2897   }
2898   W_L(">");
2899   return chtml20->out;
2900 }
2901
2902
2903 /**
2904  * It is a handler who processes the P tag.
2905  *
2906  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2907  *                     destination is specified.
2908  * @param node   [i]   The P tag node is specified.
2909  * @return The conversion result is returned.
2910  */
2911 static char *
2912 s_chtml20_end_p_tag(void *pdoc, Node *UNUSED(child)) 
2913 {
2914   chtml20_t   *chtml20;
2915   Doc         *doc;
2916   request_rec *r;
2917
2918   chtml20 = GET_CHTML20(pdoc);
2919   doc     = chtml20->doc;
2920   r       = doc->r;
2921
2922   W_L("</p>");
2923   return chtml20->out;
2924 }
2925
2926
2927 static char *
2928 s_chtml20_chxjif_tag(void *pdoc, Node *node)
2929 {
2930   chtml20_t   *chtml20;
2931   Doc         *doc;
2932   Node        *child;
2933   request_rec *r;
2934
2935   chtml20 = GET_CHTML20(pdoc);
2936   doc     = chtml20->doc;
2937   r       = doc->r;
2938
2939   for (child = qs_get_child_node(doc, node);
2940        child;
2941        child = qs_get_next_node(doc, child)) {
2942
2943     W_V(child->otext);
2944     s_chtml20_chxjif_tag(pdoc, child);
2945   }
2946
2947   return NULL;
2948 }
2949
2950
2951 /**
2952  * It is a handler who processes the TEXTARE tag.
2953  *
2954  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2955  *                     destination is specified.
2956  * @param node   [i]   The TEXTAREA tag node is specified.
2957  * @return The conversion result is returned.
2958  */
2959 static char *
2960 s_chtml20_start_textarea_tag(void *pdoc, Node *node) 
2961 {
2962   chtml20_t   *chtml20;
2963   Doc         *doc;
2964   request_rec *r;
2965   Attr        *attr;
2966
2967   chtml20 = GET_CHTML20(pdoc);
2968   doc     = chtml20->doc;
2969   r       = doc->r;
2970
2971   chtml20->textarea_flag++;
2972   W_L("<textarea");
2973   for (attr = qs_get_attr(doc,node);
2974        attr;
2975        attr = qs_get_next_attr(doc,attr)) {
2976     char *name = qs_get_attr_name(doc,attr);
2977     char *value = qs_get_attr_value(doc,attr);
2978     switch(*name) {
2979     case 'a':
2980     case 'A':
2981       if (strcasecmp(name, "accesskey") == 0 && value && *value != 0) {
2982         W_L(" accesskey=\"");
2983         W_V(value);
2984         W_L("\"");
2985       }
2986       break;
2987
2988     case 'n':
2989     case 'N':
2990       if (strcasecmp(name, "name") == 0 && value && *value != 0) {
2991         W_L(" name=\"");
2992         W_V(value);
2993         W_L("\"");
2994       }
2995       break;
2996
2997     case 'r':
2998     case 'R':
2999       if (strcasecmp(name, "rows") == 0 && value && *value != 0) {
3000         W_L(" rows=\"");
3001         W_V(value);
3002         W_L("\"");
3003       }
3004       break;
3005
3006     case 'c':
3007     case 'C':
3008       if (strcasecmp(name, "cols") == 0 && value && *value != 0) {
3009         W_L(" cols=\"");
3010         W_V(value);
3011         W_L("\"");
3012       }
3013       break;
3014
3015     case 'i':
3016     case 'I':
3017       if (strcasecmp(name, "istyle") == 0 && value && (*value == '1' || *value == '2' || *value == '3' || *value == '4')) {
3018         W_L(" istyle=\"");
3019         W_V(value);
3020         W_L("\"");
3021       }
3022       break;
3023
3024     default:
3025       break;
3026     }
3027   }
3028   W_L(">");
3029   return chtml20->out;
3030 }
3031
3032
3033 /**
3034  * It is a handler who processes the TEXTAREA tag.
3035  *
3036  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3037  *                     destination is specified.
3038  * @param node   [i]   The TEXTAREA tag node is specified.
3039  * @return The conversion result is returned.
3040  */
3041 static char *
3042 s_chtml20_end_textarea_tag(void *pdoc, Node *UNUSED(child)) 
3043 {
3044   chtml20_t   *chtml20 = GET_CHTML20(pdoc);
3045   Doc         *doc     = chtml20->doc;
3046
3047   W_L("</textarea>");
3048   chtml20->textarea_flag--;
3049
3050   return chtml20->out;
3051 }
3052
3053
3054 static char *
3055 s_chtml20_text_tag(void *pdoc, Node *child)
3056 {       
3057   chtml20_t   *chtml20;
3058   Doc         *doc;
3059   request_rec *r;
3060   char        *textval;
3061   char        *tmp;
3062   char        *tdst;
3063   char        one_byte[2];
3064   int         ii;
3065   int         tdst_len;
3066
3067   chtml20 = GET_CHTML20(pdoc);
3068   doc     = chtml20->doc;
3069   r       = doc->r;
3070   
3071   textval = qs_get_node_value(doc,child);
3072   if (strlen(textval) == 0) {
3073     return chtml20->out;
3074   }
3075   
3076   tmp = apr_palloc(r->pool, qs_get_node_size(doc,child)+1);
3077   memset(tmp, 0, qs_get_node_size(doc,child)+1);
3078   
3079   tdst     = qs_alloc_zero_byte_string(doc->buf.pool);
3080   memset(one_byte, 0, sizeof(one_byte));
3081   tdst_len = 0;
3082   
3083   for (ii=0; ii<qs_get_node_size(doc,child); ii++) {
3084     char *out;
3085     int rtn = s_chtml20_search_emoji(chtml20, &textval[ii], &out);
3086     if (rtn != 0) {
3087       tdst = qs_out_apr_pstrcat(r, tdst, out, &tdst_len);
3088       ii+=(rtn - 1);
3089       continue;
3090     }
3091     if (is_sjis_kanji(textval[ii])) {
3092       one_byte[0] = textval[ii+0];
3093       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
3094       one_byte[0] = textval[ii+1];
3095       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
3096       ii++;
3097     }
3098     else 
3099     if (chtml20->pre_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 (chtml20->textarea_flag) {
3105       one_byte[0] = textval[ii+0];
3106       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
3107     }
3108     else 
3109     if (textval[ii] != '\r' && textval[ii] != '\n') {
3110       one_byte[0] = textval[ii+0];
3111       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
3112     }
3113   }
3114   W_V(tdst);
3115   return chtml20->out;
3116 }
3117
3118
3119 /**
3120  * It is a handler who processes the BLOCKQUOTE tag.
3121  *
3122  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3123  *                     destination is specified.
3124  * @param node   [i]   The BLOCKQUOTE tag node is specified.
3125  * @return The conversion result is returned.
3126  */
3127 static char *
3128 s_chtml20_start_blockquote_tag(void *pdoc, Node *UNUSED(child))
3129 {
3130   chtml20_t *chtml20 = GET_CHTML20(pdoc);
3131   Doc       *doc     = chtml20->doc;
3132   W_L("<blockquote>");
3133   return chtml20->out;
3134 }
3135
3136
3137 /**
3138  * It is a handler who processes the BLOCKQUOTE tag.
3139  *
3140  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3141  *                     destination is specified.
3142  * @param node   [i]   The BLOCKQUOTE tag node is specified.
3143  * @return The conversion result is returned.
3144  */
3145 static char *
3146 s_chtml20_end_blockquote_tag(void *pdoc, Node *UNUSED(child))
3147 {
3148   chtml20_t *chtml20 = GET_CHTML20(pdoc);
3149   Doc       *doc     = chtml20->doc;
3150   W_L("</blockquote>");
3151   return chtml20->out;
3152 }
3153
3154
3155 /**
3156  * It is a handler who processes the DIR tag.
3157  *
3158  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3159  *                     destination is specified.
3160  * @param node   [i]   The DIR tag node is specified.
3161  * @return The conversion result is returned.
3162  */
3163 static char *
3164 s_chtml20_start_dir_tag(void *pdoc, Node *UNUSED(child))
3165 {
3166   chtml20_t *chtml20 = GET_CHTML20(pdoc);
3167   Doc       *doc     = chtml20->doc;
3168   W_L("<dir>");
3169   return chtml20->out;
3170 }
3171
3172
3173 /**
3174  * It is a handler who processes the DIR tag.
3175  *
3176  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3177  *                     destination is specified.
3178  * @param node   [i]   The DIR tag node is specified.
3179  * @return The conversion result is returned.
3180  */
3181 static char *
3182 s_chtml20_end_dir_tag(void *pdoc, Node *UNUSED(child))
3183 {
3184   chtml20_t *chtml20 = GET_CHTML20(pdoc);
3185   Doc       *doc     = chtml20->doc;
3186
3187   W_L("</dir>");
3188   return chtml20->out;
3189 }
3190
3191
3192 /**
3193  * It is a handler who processes the DL tag.
3194  *
3195  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3196  *                     destination is specified.
3197  * @param node   [i]   The DL tag node is specified.
3198  * @return The conversion result is returned.
3199  */
3200 static char *
3201 s_chtml20_start_dl_tag(void *pdoc, Node *UNUSED(child))
3202 {
3203   chtml20_t *chtml20 = GET_CHTML20(pdoc);
3204   Doc       *doc     = chtml20->doc;
3205   W_L("<dl>");
3206   return chtml20->out;
3207 }
3208
3209
3210 /**
3211  * It is a handler who processes the DL tag.
3212  *
3213  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3214  *                     destination is specified.
3215  * @param node   [i]   The DL tag node is specified.
3216  * @return The conversion result is returned.
3217  */
3218 static char *
3219 s_chtml20_end_dl_tag(void *pdoc, Node *UNUSED(child))
3220 {
3221   chtml20_t *chtml20 = GET_CHTML20(pdoc);
3222   Doc       *doc     = chtml20->doc;
3223   W_L("</dl>");
3224   return chtml20->out;
3225 }
3226
3227
3228 /**
3229  * It is a handter who processes the DT tag.
3230  *
3231  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3232  *                     destination is specified.
3233  * @param node   [i]   The DT tag node is specified.
3234  * @return The conversion result is returned.
3235  */
3236 static char *
3237 s_chtml20_start_dt_tag(void *pdoc, Node *UNUSED(child))
3238 {
3239   chtml20_t *chtml20 = GET_CHTML20(pdoc);
3240   Doc       *doc     = chtml20->doc;
3241   W_L("<dt>");
3242   return chtml20->out;
3243 }
3244
3245
3246 /**
3247  * It is a handter who processes the DT tag.
3248  *
3249  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3250  *                     destination is specified.
3251  * @param node   [i]   The DT tag node is specified.
3252  * @return The conversion result is returned.
3253  */
3254 static char *
3255 s_chtml20_end_dt_tag(void *pdoc, Node *UNUSED(child))
3256 {
3257   chtml20_t *chtml20 = GET_CHTML20(pdoc);
3258
3259   return chtml20->out;
3260 }
3261
3262
3263 /**
3264  * It is a handder who processes the DD tag.
3265  *
3266  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3267  *                     destination is specified.
3268  * @param node   [i]   The DD tag node is specified.
3269  * @return The conversion result is returned.
3270  */
3271 static char *
3272 s_chtml20_start_dd_tag(void *pdoc, Node *UNUSED(child))
3273 {
3274   chtml20_t *chtml20 = GET_CHTML20(pdoc);
3275   Doc       *doc     = chtml20->doc;
3276   W_L("<dd>");
3277   return chtml20->out;
3278 }
3279
3280
3281 /**
3282  * It is a handder who processes the DD tag.
3283  *
3284  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3285  *                     destination is specified.
3286  * @param node   [i]   The DD tag node is specified.
3287  * @return The conversion result is returned.
3288  */
3289 static char *
3290 s_chtml20_end_dd_tag(void *pdoc, Node *UNUSED(child))
3291 {
3292   chtml20_t *chtml20 = GET_CHTML20(pdoc);
3293
3294   return chtml20->out;
3295 }
3296
3297
3298 /**
3299  * It is a hanmenuer who processes the MENU tag.
3300  *
3301  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3302  *                     destination is specified.
3303  * @param node   [i]   The MENU tag node is specified.
3304  * @return The conversion result is returned.
3305  */
3306 static char *
3307 s_chtml20_start_menu_tag(void *pdoc, Node *UNUSED(child))
3308 {
3309   chtml20_t *chtml20 = GET_CHTML20(pdoc);
3310   Doc       *doc     = chtml20->doc;
3311
3312   W_L("<menu>");
3313   return chtml20->out;
3314 }
3315
3316
3317 /**
3318  * It is a hanmenuer who processes the MENU tag.
3319  *
3320  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3321  *                     destination is specified.
3322  * @param node   [i]   The MENU tag node is specified.
3323  * @return The conversion result is returned.
3324  */
3325 static char *
3326 s_chtml20_end_menu_tag(void *pdoc, Node *UNUSED(child))
3327 {
3328   chtml20_t *chtml20 = GET_CHTML20(pdoc);
3329   Doc       *doc = chtml20->doc;
3330
3331   W_L("</menu>");
3332   return chtml20->out;
3333 }
3334
3335
3336 /**
3337  * It is a hanplaintexter who processes the PLAINTEXT tag.
3338  *
3339  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3340  *                     destination is specified.
3341  * @param node   [i]   The PLAINTEXT tag node is specified.
3342  * @return The conversion result is returned.
3343  */
3344 static char *
3345 s_chtml20_start_plaintext_tag(void *pdoc, Node *node)
3346 {
3347   chtml20_t *chtml20 = GET_CHTML20(pdoc);
3348   Doc       *doc     = chtml20->doc;
3349
3350   W_L("<plaintext>");
3351   s_chtml20_start_plaintext_tag_inner(pdoc,node);
3352   return chtml20->out;
3353 }
3354
3355 static char *
3356 s_chtml20_start_plaintext_tag_inner(void *pdoc, Node *node)
3357 {
3358   chtml20_t *chtml20 = GET_CHTML20(pdoc);
3359   Doc       *doc     = chtml20->doc;
3360   Node      *child;
3361
3362   for (child = qs_get_child_node(doc, node);
3363        child;
3364        child = qs_get_next_node(doc, child)) {
3365     W_V(child->otext);
3366     s_chtml20_start_plaintext_tag_inner(pdoc, child);
3367   }
3368   return chtml20->out;
3369 }
3370
3371
3372 /**
3373  * It is a hanplaintexter who processes the PLAINTEXT tag.
3374  *
3375  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3376  *                     destination is specified.
3377  * @param node   [i]   The PLAINTEXT tag node is specified.
3378  * @return The conversion result is returned.
3379  */
3380 static char *
3381 s_chtml20_end_plaintext_tag(void *pdoc, Node *UNUSED(child))
3382 {
3383   chtml20_t *chtml20 = GET_CHTML20(pdoc);
3384   return chtml20->out;
3385 }
3386
3387 /**
3388  * It is a hanblinker who processes the BLINK tag.
3389  *
3390  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3391  *                     destination is specified.
3392  * @param node   [i]   The BLINK tag node is specified.
3393  * @return The conversion result is returned.
3394  */
3395 static char *
3396 s_chtml20_start_blink_tag(void *pdoc, Node *UNUSED(child))
3397 {
3398   chtml20_t *chtml20 = GET_CHTML20(pdoc);
3399   Doc       *doc = chtml20->doc;
3400   W_L("<blink>");
3401   return chtml20->out;
3402 }
3403
3404
3405 /**
3406  * It is a hanblinker who processes the BLINK tag.
3407  *
3408  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3409  *                     destination is specified.
3410  * @param node   [i]   The BLINK tag node is specified.
3411  * @return The conversion result is returned.
3412  */
3413 static char *
3414 s_chtml20_end_blink_tag(void *pdoc, Node *UNUSED(child))
3415 {
3416   chtml20_t *chtml20 = GET_CHTML20(pdoc);
3417   Doc       *doc = chtml20->doc;
3418   W_L("</blink>");
3419   return chtml20->out;
3420 }
3421
3422
3423 /**
3424  * It is a hanmarqueeer who processes the MARQUEE tag.
3425  *
3426  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3427  *                     destination is specified.
3428  * @param node   [i]   The MARQUEE tag node is specified.
3429  * @return The conversion result is returned.
3430  */
3431 static char *
3432 s_chtml20_start_marquee_tag(void *pdoc, Node *node)
3433 {
3434   chtml20_t *chtml20 = GET_CHTML20(pdoc);
3435   Doc       *doc = chtml20->doc;
3436   Attr      *attr;
3437   W_L("<marquee");
3438   /*--------------------------------------------------------------------------*/
3439   /* Get Attributes                                                           */
3440   /*--------------------------------------------------------------------------*/
3441   for (attr = qs_get_attr(doc,node);
3442        attr;
3443        attr = qs_get_next_attr(doc,attr)) {
3444     char *name   = qs_get_attr_name(doc,attr);
3445     char *value  = qs_get_attr_value(doc,attr);
3446     if (STRCASEEQ('d','D',"direction", name)) {
3447       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value))) {
3448         W_L(" direction=\"");
3449         W_V(value);
3450         W_L("\"");
3451       }
3452     }
3453     else if (STRCASEEQ('b','B',"behavior",name)) {
3454       if (value && (STRCASEEQ('s','S',"scroll",value) || STRCASEEQ('s','S',"slide",value) || STRCASEEQ('a','A',"alternate",value))) {
3455         W_L(" behavior=\""); 
3456         W_V(value);
3457         W_L("\"");
3458       }
3459     }
3460     else if (STRCASEEQ('l','L',"loop",name)) {
3461       if (value && *value) {
3462         W_L(" loop=\"");
3463         W_V(value);
3464         W_L("\"");
3465       }
3466     }
3467   }
3468   W_L(">");
3469   return chtml20->out;
3470 }
3471
3472
3473 /**
3474  * It is a hanmarqueeer who processes the MARQUEE tag.
3475  *
3476  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3477  *                     destination is specified.
3478  * @param node   [i]   The MARQUEE tag node is specified.
3479  * @return The conversion result is returned.
3480  */
3481 static char *
3482 s_chtml20_end_marquee_tag(void *pdoc, Node *UNUSED(child))
3483 {
3484   chtml20_t *chtml20 = GET_CHTML20(pdoc);
3485   Doc       *doc = chtml20->doc;
3486   W_L("</marquee>");
3487   return chtml20->out;
3488 }
3489
3490
3491 /**
3492  *  * It is handler who processes the New Line Code.
3493  *   */
3494 static char *
3495 s_chtml20_newline_mark(void *pdoc, Node *UNUSED(node))
3496 {
3497   chtml20_t *chtml20 = GET_CHTML20(pdoc);
3498   Doc *doc = chtml20->doc;
3499   W_NLCODE();
3500   return chtml20->out;
3501 }
3502 /*
3503  * vim:ts=2 et
3504  */