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