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