OSDN Git Service

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