OSDN Git Service

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