OSDN Git Service

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