OSDN Git Service

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