OSDN Git Service

* 2005/3/25
[modchxj/mod_chxj.git] / src / chxj_chtml20.c
1 /*
2  * Copyright (C) 2005 QSDN,Inc. All rights reserved.
3  * Copyright (C) 2005 Atsushi Konno All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #include "chxj_chtml20.h"
18 #include "chxj_hdml.h"
19 #include "chxj_str_util.h"
20 #include "chxj_dump.h"
21 #include "chxj_img_conv.h"
22
23 static char* chtml20_node_exchange    (Chtml20* chtml, Node* node, int indent);
24 static char* chtml20_start_html_tag   (Chtml20* chtml, Node* child);
25 static char* chtml20_end_html_tag     (Chtml20* chtml, Node* child);
26 static char* chtml20_start_meta_tag   (Chtml20* chtml, Node* node);
27 static char* chtml20_end_meta_tag     (Chtml20* chtml, Node* node);
28 static char* chtml20_start_head_tag   (Chtml20* chtml, Node* node);
29 static char* chtml20_end_head_tag     (Chtml20* chtml, Node* node);
30 static char* chtml20_start_title_tag  (Chtml20* chtml, Node* node);
31 static char* chtml20_end_title_tag    (Chtml20* chtml, Node* node);
32 static char* chtml20_start_base_tag   (Chtml20* chtml, Node* node);
33 static char* chtml20_end_base_tag     (Chtml20* chtml, Node* node);
34 static char* chtml20_start_body_tag   (Chtml20* chtml, Node* node);
35 static char* chtml20_end_body_tag     (Chtml20* chtml, Node* node);
36 static char* chtml20_start_a_tag      (Chtml20* chtml, Node* node);
37 static char* chtml20_end_a_tag        (Chtml20* chtml, Node* node);
38 static char* chtml20_start_br_tag     (Chtml20* chtml, Node* node);
39 static char* chtml20_end_br_tag       (Chtml20* chtml, Node* node);
40 static char* chtml20_start_font_tag   (Chtml20* chtml, Node* node);
41 static char* chtml20_end_font_tag     (Chtml20* chtml, Node* node);
42 static char* chtml20_start_form_tag   (Chtml20* chtml, Node* node);
43 static char* chtml20_end_form_tag     (Chtml20* chtml, Node* node);
44 static char* chtml20_start_input_tag  (Chtml20* chtml, Node* node);
45 static char* chtml20_end_input_tag    (Chtml20* chtml, Node* node);
46 static char* chtml20_start_center_tag (Chtml20* chtml, Node* node);
47 static char* chtml20_end_center_tag   (Chtml20* chtml, Node* node);
48 static char* chtml20_start_hr_tag     (Chtml20* chtml, Node* node);
49 static char* chtml20_end_hr_tag       (Chtml20* chtml, Node* node);
50 static char* chtml20_start_img_tag    (Chtml20* chtml, Node* node);
51 static char* chtml20_end_img_tag      (Chtml20* chtml, Node* node);
52 static char* chtml20_start_select_tag (Chtml20* chtml, Node* node);
53 static char* chtml20_end_select_tag   (Chtml20* chtml, Node* node);
54 static char* chtml20_start_option_tag (Chtml20* chtml, Node* node);
55 static char* chtml20_end_option_tag   (Chtml20* chtml, Node* node);
56 static char* chtml20_start_div_tag    (Chtml20* chtml, Node* node);
57 static char* chtml20_end_div_tag      (Chtml20* chtml, Node* node);
58 static void chxj_init_chtml20(Chtml20* chtml, Doc* doc, request_rec* r, device_table* spec);
59 static int chtml20_search_emoji(Chtml20* chtml, char* txt, char** rslt);
60 static void chtml20_chxjif_tag(Chtml20* chtml, Node* node); 
61
62 /**
63  * converts from CHTML5.0 to CHTML2.0.
64  *
65  * @param r     [i]   Requet_rec is appointed.
66  * @param spec  [i]   The result of the device specification processing which 
67  *                    was done in advance is appointed.
68  * @param src   [i]   The character string before the converting is appointed.
69  * @return The character string after the converting is returned.
70  */
71 char*
72 chxj_exchange_chtml20(
73   request_rec* r,
74   device_table *spec,
75   const char* src,
76   apr_size_t srclen,
77   apr_size_t *dstlen)
78 {
79   char*     dst = NULL;
80   char*     ss;
81   Chtml20   chtml20;
82   Doc       doc;
83
84   /*--------------------------------------------------------------------------*/
85   /* The CHTML structure is initialized.                                      */
86   /*--------------------------------------------------------------------------*/
87   chxj_init_chtml20(&chtml20, &doc, r, spec);
88
89   /*--------------------------------------------------------------------------*/
90   /* The character string of the input is analyzed.                           */
91   /*--------------------------------------------------------------------------*/
92   qs_init_malloc(&doc);
93   qs_init_root_node(&doc);
94
95   ss = apr_pcalloc(r->pool, srclen + 1);
96   memset(ss, 0, srclen + 1);
97   memcpy(ss, src, srclen);
98 #ifdef DUMP_LOG
99   chxj_dump_out("[src] CHTML -> CHTML2.0", ss, srclen);
100 #endif
101
102   qs_parse_string(&doc,ss, strlen(ss));
103
104   /*--------------------------------------------------------------------------*/
105   /* It converts it from CHTML to CHTML.                                      */
106   /*--------------------------------------------------------------------------*/
107   dst = chtml20_node_exchange(&chtml20, qs_get_root(&doc), 0);
108   qs_all_free(&doc,QX_LOGMARK);
109
110   if (dst == NULL) 
111   {
112     return apr_pstrdup(r->pool,ss);
113   }
114
115   if (strlen(dst) == 0)
116   {
117     dst = apr_psprintf(r->pool, "\n");
118   }
119   *dstlen = strlen(dst);
120 #ifdef DUMP_LOG
121   chxj_dump_out("[dst] CHTML -> CHTML2.0", dst, *dstlen);
122 #endif
123   return dst;
124 }
125
126 /**
127  * The CHTML structure is initialized.
128  *
129  * @param chtml20 [i/o] The pointer to the HDML structure that wants to be
130  *                   initialized is specified.
131  * @param doc   [i]   The Doc structure that should be set to the initialized
132  *                   HDML structure is specified.
133  * @param r     [i]   To use POOL, the pointer to request_rec is specified.
134  * @param spec  [i]   The pointer to the device_table
135  */
136 static void
137 chxj_init_chtml20(Chtml20* chtml20, Doc* doc, request_rec* r, device_table* spec)
138 {
139   memset(doc,   0, sizeof(Doc));
140   memset(chtml20, 0, sizeof(Chtml20));
141
142   doc->r      = r;
143   chtml20->doc  = doc;
144   chtml20->spec = spec;
145   chtml20->out  = qs_alloc_zero_byte_string(r);
146   chtml20->conf = ap_get_module_config(r->per_dir_config, &chxj_module);
147   chtml20->doc->parse_mode = PARSE_MODE_CHTML;
148 }
149
150 /**
151  * It is main processing of conversion from CHTML to CHTML. 
152  *
153  * @param chtml20   [i/o] The pointer to the CHTML structure is specified. 
154  * @param node    [i]   The pointer to a current node is specified. 
155  * @param indent  [i]   The depth of the node processing it now is specified. 
156  *
157  * @return The character string after it converts it is returned. 
158  */
159 static char*
160 chtml20_node_exchange(Chtml20* chtml20, Node* node, int indent) 
161 {
162   Node*         child;
163   Doc*          doc   = chtml20->doc;
164   request_rec*  r     = doc->r;
165
166   /*--------------------------------------------------------------------------*/
167   /* It is the main loop of the conversion processing.                        */
168   /*--------------------------------------------------------------------------*/
169   for (child = qs_get_child_node(doc,node);
170        child ;
171        child = qs_get_next_node(doc,child)) 
172   {
173     char* name = qs_get_node_name(doc,child);
174
175     /*------------------------------------------------------------------------*/
176     /* <HTML>                                                                 */
177     /*------------------------------------------------------------------------*/
178     if (strcasecmp(name, "html") == 0) 
179     {
180       chtml20_start_html_tag(chtml20, child);
181       chtml20_node_exchange (chtml20, child,indent+1);
182       chtml20_end_html_tag  (chtml20, child);
183     }
184     /*------------------------------------------------------------------------*/
185     /* <META>                                                                 */
186     /*------------------------------------------------------------------------*/
187     else
188     if (strcasecmp(name, "meta") == 0) 
189     {
190       chtml20_start_meta_tag(chtml20, child);
191       chtml20_end_meta_tag  (chtml20, child);
192     }
193     /*------------------------------------------------------------------------*/
194     /* <HEAD>                                                                 */
195     /*------------------------------------------------------------------------*/
196     else
197     if (strcasecmp(name, "head") == 0) 
198     {
199       chtml20_start_head_tag(chtml20, child);
200       chtml20_node_exchange (chtml20, child,indent+1);
201       chtml20_end_head_tag  (chtml20, child);
202     }
203     /*------------------------------------------------------------------------*/
204     /* <TITLE>                                                                */
205     /*------------------------------------------------------------------------*/
206     else
207     if (strcasecmp(name, "title") == 0) 
208     {
209       chtml20_start_title_tag (chtml20, child);
210       chtml20_node_exchange   (chtml20, child,indent+1);
211       chtml20_end_title_tag   (chtml20, child);
212     }
213     /*------------------------------------------------------------------------*/
214     /* <BASE>                                                                 */
215     /*------------------------------------------------------------------------*/
216     else
217     if (strcasecmp(name, "base") == 0) 
218     {
219       chtml20_start_base_tag(chtml20, child);
220       chtml20_end_base_tag  (chtml20, child);
221     }
222     /*------------------------------------------------------------------------*/
223     /* <BODY>                                                                 */
224     /*------------------------------------------------------------------------*/
225     else
226     if (strcasecmp(name, "body") == 0) 
227     {
228       chtml20_start_body_tag(chtml20, child);
229       chtml20_node_exchange (chtml20, child,indent+1);
230       chtml20_end_body_tag  (chtml20, child);
231     }
232     /*------------------------------------------------------------------------*/
233     /* <A>                                                                    */
234     /*------------------------------------------------------------------------*/
235     else
236     if (strcasecmp(name, "a") == 0) 
237     {
238       chtml20_start_a_tag   (chtml20, child);
239       chtml20_node_exchange (chtml20, child,indent+1);
240       chtml20_end_a_tag     (chtml20, child);
241     }
242     /*------------------------------------------------------------------------*/
243     /* <BR>                                                                   */
244     /*------------------------------------------------------------------------*/
245     else
246     if (strcasecmp(name, "br") == 0) 
247     {
248       chtml20_start_br_tag  (chtml20, child);
249       chtml20_node_exchange (chtml20, child,indent+1);
250       chtml20_end_br_tag    (chtml20, child);
251     }
252     /*------------------------------------------------------------------------*/
253     /* <FONT>                                                                 */
254     /*------------------------------------------------------------------------*/
255     else
256     if (strcasecmp(name, "font") == 0) 
257     {
258       chtml20_start_font_tag(chtml20, child);
259       chtml20_node_exchange (chtml20, child,indent+1);
260       chtml20_end_font_tag  (chtml20, child);
261     }
262     /*------------------------------------------------------------------------*/
263     /* <FORM>                                                                 */
264     /*------------------------------------------------------------------------*/
265     else
266     if (strcasecmp(name, "form") == 0) 
267     {
268       chtml20_start_form_tag(chtml20, child);
269       chtml20_node_exchange (chtml20, child,indent+1);
270       chtml20_end_form_tag  (chtml20, child);
271     }
272     /*------------------------------------------------------------------------*/
273     /* <INPUT>                                                                */
274     /*------------------------------------------------------------------------*/
275     else
276     if (strcasecmp(name, "input") == 0) 
277     {
278       chtml20_start_input_tag (chtml20, child);
279       chtml20_node_exchange   (chtml20, child,indent+1);
280       chtml20_end_input_tag   (chtml20, child);
281     }
282     /*------------------------------------------------------------------------*/
283     /* <HR>                                                                   */
284     /*------------------------------------------------------------------------*/
285     else
286     if (strcasecmp(name, "hr") == 0) 
287     {
288       chtml20_start_hr_tag  (chtml20, child);
289       chtml20_end_hr_tag    (chtml20, child);
290     }
291     /*------------------------------------------------------------------------*/
292     /* <CENTER>                                                               */
293     /*------------------------------------------------------------------------*/
294     else
295     if (strcasecmp(name, "center") == 0) 
296     {
297       chtml20_start_center_tag(chtml20, child);
298       chtml20_node_exchange   (chtml20, child,indent+1);
299       chtml20_end_center_tag  (chtml20, child);
300     }
301     /*------------------------------------------------------------------------*/
302     /* <IMG>                                                                  */
303     /*------------------------------------------------------------------------*/
304     else
305     if (strcasecmp(name, "img") == 0) 
306     {
307       chtml20_start_img_tag (chtml20, child);
308       chtml20_end_img_tag   (chtml20, child);
309     }
310     /*------------------------------------------------------------------------*/
311     /* <SELECT>                                                               */
312     /*------------------------------------------------------------------------*/
313     else
314     if (strcasecmp(name, "select") == 0)
315     {
316       chtml20_start_select_tag(chtml20, child);
317       chtml20_node_exchange   (chtml20, child, indent+1);
318       chtml20_end_select_tag  (chtml20, child);
319     }
320     /*------------------------------------------------------------------------*/
321     /* <OPTION>                                                               */
322     /*------------------------------------------------------------------------*/
323     else
324     if (strcasecmp(name, "option") == 0)
325     {
326       chtml20_start_option_tag(chtml20, child);
327       chtml20_node_exchange   (chtml20, child, indent+1);
328       chtml20_end_option_tag  (chtml20, child);
329     }
330     /*------------------------------------------------------------------------*/
331     /* <DIV>                                                                  */
332     /*------------------------------------------------------------------------*/
333     else
334     if (strcasecmp(name, "div") == 0)
335     {
336       chtml20_start_div_tag (chtml20, child);
337       chtml20_node_exchange (chtml20, child, indent+1);
338       chtml20_end_div_tag   (chtml20, child);
339     }
340     /*------------------------------------------------------------------------*/
341     /* <BLINK>                                                                */
342     /*------------------------------------------------------------------------*/
343     else
344     if (strcasecmp(name, "blink") == 0)
345     {
346       /* ignore */
347     }
348     /*------------------------------------------------------------------------*/
349     /* <CHXJ:IF>                                                              */
350     /*------------------------------------------------------------------------*/
351     else
352     if (strcasecmp(name, "chxj:if") == 0)
353     {
354       ap_log_rerror(APLOG_MARK, APLOG_DEBUG,0,r, "chxj:if tag found");
355       if (chxj_chxjif_is_mine(chtml20->spec, doc, child))
356       {
357         ap_log_rerror(APLOG_MARK, APLOG_DEBUG,0,r, "chxj:if tag is mine");
358         chtml20_chxjif_tag(chtml20, child);
359       }
360     }
361     /*------------------------------------------------------------------------*/
362     /* NORMAL TEXT                                                            */
363     /*------------------------------------------------------------------------*/
364     else
365     if (strcasecmp(name, "text") == 0) 
366     {
367       char*   textval;
368       char*   tmp;
369       char*   tdst;
370       char    one_byte[2];
371       int     ii;
372       int     tdst_len;
373
374       textval = qs_get_node_value(doc,child);
375       textval = qs_trim_string(chtml20->doc->r, textval);
376       if (strlen(textval) == 0)
377       {
378         continue;
379       }
380
381       tmp = apr_palloc(r->pool, qs_get_node_size(doc,child)+1);
382       memset(tmp, 0, qs_get_node_size(doc,child)+1);
383
384       tdst     = qs_alloc_zero_byte_string(r);
385       memset(one_byte, 0, sizeof(one_byte));
386       tdst_len = 0;
387
388       for (ii=0; ii<qs_get_node_size(doc,child); ii++)
389       {
390         char* out;
391         int rtn = chtml20_search_emoji(chtml20, &textval[ii], &out);
392         if (rtn != 0)
393         {
394           tdst = qs_out_apr_pstrcat(r, tdst, out, &tdst_len);
395           ii+=(rtn - 1);
396           continue;
397         }
398         if (is_sjis_kanji(textval[ii]))
399         {
400           one_byte[0] = textval[ii+0];
401           tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
402           one_byte[0] = textval[ii+1];
403           tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
404           ii++;
405         }
406         else if (textval[ii] != '\r' && textval[ii] != '\n')
407         {
408           one_byte[0] = textval[ii+0];
409           tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
410         }
411       }
412       chtml20->out = apr_pstrcat(r->pool, chtml20->out, tdst, NULL);
413     }
414   }
415   return chtml20->out;
416 }
417
418 /**
419  * Corresponding EMOJI to a current character-code is retrieved. 
420  * The substitution character string is stored in the rslt pointer if agreeing.
421  *
422  * @param chtml20   [i]   The pointer to the CHTML structure is specified. 
423  * @param txt     [i]   The character string to want to examine whether it is 
424  *                      EMOJI is specified. 
425  * @param rslt    [o]   The pointer to the pointer that stores the result is 
426  *                      specified. 
427  * @return When corresponding EMOJI exists, it returns it excluding 0. 
428  */
429 static int
430 chtml20_search_emoji(Chtml20* chtml20, char* txt, char** rslt)
431 {
432   emoji_t*      ee;
433   request_rec*  r;
434   device_table* spec;
435   int           len;
436
437   spec = chtml20->spec;
438
439   len = strlen(txt);
440   r = chtml20->doc->r;
441
442   if (spec == NULL)
443   {
444     ap_log_rerror(APLOG_MARK, APLOG_DEBUG,0,r, "spec is NULL");
445   }
446
447   for (ee = chtml20->conf->emoji;
448        ee;
449        ee = ee->next) 
450   {
451     if (ee->imode == NULL)
452     {
453       ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
454                       "emoji->imode is NULL");
455       continue;
456     }
457
458     if (ee->imode->string != NULL
459     &&  strlen(ee->imode->string) > 0
460     &&  strncasecmp(ee->imode->string, txt, strlen(ee->imode->string)) == 0)
461     {
462       if (spec == NULL || spec->emoji_type == NULL)
463       {
464         *rslt = apr_palloc(r->pool, 3);
465         (*rslt)[0] = ee->imode->hex1byte & 0xff;
466         (*rslt)[1] = ee->imode->hex2byte & 0xff;
467         (*rslt)[2] = 0;
468         return strlen(ee->imode->string);
469       }
470
471       return 0;
472     }
473   }
474   return 0;
475 }
476
477 /**
478  * It is a handler who processes the HTML tag.
479  *
480  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
481  *                     destination is specified.
482  * @param node   [i]   The HTML tag node is specified.
483  * @return The conversion result is returned.
484  */
485 static char*
486 chtml20_start_html_tag(Chtml20* chtml20, Node* node) 
487 {
488   Doc*          doc   = chtml20->doc;
489   request_rec*  r     = doc->r;
490
491   /*--------------------------------------------------------------------------*/
492   /* start HTML tag                                                           */
493   /*--------------------------------------------------------------------------*/
494   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "<html>\n", NULL);
495
496   return chtml20->out;
497 }
498
499 /**
500  * It is a handler who processes the HTML tag.
501  *
502  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
503  *                     destination is specified.
504  * @param node   [i]   The HTML tag node is specified.
505  * @return The conversion result is returned.
506  */
507 static char*
508 chtml20_end_html_tag(Chtml20* chtml20, Node* child) 
509 {
510   Doc*          doc = chtml20->doc;
511   request_rec*  r   = doc->r;
512
513   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "</html>\n", NULL);
514
515   return chtml20->out;
516 }
517
518 /**
519  * It is a handler who processes the META tag.
520  *
521  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
522  *                     destination is specified.
523  * @param node   [i]   The META tag node is specified.
524  * @return The conversion result is returned.
525  */
526 static char*
527 chtml20_start_meta_tag(Chtml20* chtml20, Node* node) 
528 {
529   Doc* doc = chtml20->doc;
530   request_rec* r = doc->r;
531   Attr* attr;
532
533   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "<meta", NULL);
534
535   /*--------------------------------------------------------------------------*/
536   /* Get Attributes                                                           */
537   /*--------------------------------------------------------------------------*/
538   for (attr = qs_get_attr(doc,node);
539        attr;
540        attr = qs_get_next_attr(doc,attr)) 
541   {
542     char* name   = qs_get_attr_name(doc,attr);
543     char* value  = qs_get_attr_value(doc,attr);
544
545     if (strcasecmp(name, "http-equiv") == 0) 
546     {
547       /*----------------------------------------------------------------------*/
548       /* CHTML 2.0                                                            */
549       /*----------------------------------------------------------------------*/
550       chtml20->out = apr_pstrcat(r->pool, 
551                       chtml20->out, 
552                       " http-equiv=\"", 
553                       value,
554                       "\"",
555                       NULL);
556     }
557     else
558     if (strcasecmp(name, "content") == 0)
559     {
560       /*----------------------------------------------------------------------*/
561       /* CHTML 2.0                                                            */
562       /*----------------------------------------------------------------------*/
563       chtml20->out = apr_pstrcat(r->pool, 
564                       chtml20->out, 
565                       " content=\"", 
566                       value,
567                       "\"",
568                       NULL);
569     }
570   }
571   chtml20->out = apr_pstrcat(r->pool, chtml20->out, ">", NULL);
572   return chtml20->out;
573 }
574
575 /**
576  * It is a handler who processes the META tag.
577  *
578  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
579  *                     destination is specified.
580  * @param node   [i]   The META tag node is specified.
581  * @return The conversion result is returned.
582  */
583 static char*
584 chtml20_end_meta_tag(Chtml20* chtml20, Node* child) 
585 {
586   return chtml20->out;
587 }
588
589 /**
590  * It is a handler who processes the HEAD tag.
591  *
592  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
593  *                     destination is specified.
594  * @param node   [i]   The HEAD tag node is specified.
595  * @return The conversion result is returned.
596  */
597 static char*
598 chtml20_start_head_tag(Chtml20* chtml20, Node* node) 
599 {
600   Doc*          doc = chtml20->doc;
601   request_rec*  r   = doc->r;
602   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "<head>\r\n", NULL);
603
604   return chtml20->out;
605 }
606
607 /**
608  * It is a handler who processes the HEAD tag.
609  *
610  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
611  *                     destination is specified.
612  * @param node   [i]   The HEAD tag node is specified.
613  * @return The conversion result is returned.
614  */
615 static char*
616 chtml20_end_head_tag(Chtml20* chtml20, Node* child) 
617 {
618   Doc*          doc = chtml20->doc;
619   request_rec*  r   = doc->r;
620
621   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "</head>\r\n", NULL);
622   return chtml20->out;
623 }
624
625 /**
626  * It is a handler who processes the TITLE tag.
627  *
628  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
629  *                     destination is specified.
630  * @param node   [i]   The TITLE tag node is specified.
631  * @return The conversion result is returned.
632  */
633 static char*
634 chtml20_start_title_tag(Chtml20* chtml20, Node* node) 
635 {
636   Doc* doc = chtml20->doc;
637   request_rec* r = doc->r;
638
639   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "<title>", NULL);
640   return chtml20->out;
641 }
642
643 /**
644  * It is a handler who processes the TITLE tag.
645  *
646  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
647  *                     destination is specified.
648  * @param node   [i]   The TITLE tag node is specified.
649  * @return The conversion result is returned.
650  */
651 static char*
652 chtml20_end_title_tag(Chtml20* chtml20, Node* child) 
653 {
654   Doc*          doc = chtml20->doc;
655   request_rec*  r   = doc->r;
656
657   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "</title>\r\n", NULL);
658
659   return chtml20->out;
660 }
661
662 /**
663  * It is a handler who processes the BASE tag.
664  *
665  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
666  *                     destination is specified.
667  * @param node   [i]   The BASE tag node is specified.
668  * @return The conversion result is returned.
669  */
670 static char*
671 chtml20_start_base_tag(Chtml20* chtml20, Node* node) 
672 {
673   Attr*         attr;
674   Doc*          doc   = chtml20->doc;
675   request_rec*  r     = doc->r;
676
677   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "<base", NULL);
678
679   /*--------------------------------------------------------------------------*/
680   /* Get Attributes                                                           */
681   /*--------------------------------------------------------------------------*/
682   for (attr = qs_get_attr(doc,node);
683        attr;
684        attr = qs_get_next_attr(doc,attr)) 
685   {
686     char* name = qs_get_attr_name(doc,attr);
687     char* value = qs_get_attr_value(doc,attr);
688     if (strcasecmp(name, "href") == 0) 
689     {
690       chtml20->out = apr_pstrcat(r->pool, 
691                       chtml20->out, 
692                       " href=\"", 
693                       value, 
694                       "\"", 
695                       NULL);
696     }
697   }
698   chtml20->out = apr_pstrcat(r->pool, chtml20->out, " >\r\n", NULL);
699   return chtml20->out;
700 }
701
702 /**
703  * It is a handler who processes the BASE tag.
704  *
705  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
706  *                     destination is specified.
707  * @param node   [i]   The BASE tag node is specified.
708  * @return The conversion result is returned.
709  */
710 static char*
711 chtml20_end_base_tag(Chtml20* chtml20, Node* child) 
712 {
713   return chtml20->out;
714 }
715
716 /**
717  * It is a handler who processes the BODY tag.
718  *
719  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
720  *                     destination is specified.
721  * @param node   [i]   The BODY tag node is specified.
722  * @return The conversion result is returned.
723  */
724 static char*
725 chtml20_start_body_tag(Chtml20* chtml20, Node* node) 
726 {
727   Doc* doc = chtml20->doc;
728   request_rec* r = doc->r;
729   Attr* attr;
730
731   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "<body", NULL);
732
733   /*--------------------------------------------------------------------------*/
734   /* Get Attributes                                                           */
735   /*--------------------------------------------------------------------------*/
736   for (attr = qs_get_attr(doc,node);
737        attr;
738        attr = qs_get_next_attr(doc,attr)) 
739   {
740     char* name  = qs_get_attr_name(doc,attr);
741     char* value  = qs_get_attr_value(doc,attr);
742
743     if (strcasecmp(name, "bgcolor") == 0) 
744     {
745       /*----------------------------------------------------------------------*/
746       /* CHTML 2.0                                                            */
747       /*----------------------------------------------------------------------*/
748       chtml20->out = apr_pstrcat(r->pool, 
749                       chtml20->out, 
750                       " bgcolor=\"", 
751                       value, 
752                       "\"", 
753                       NULL);
754     }
755     else
756     if (strcasecmp(name, "text") == 0) 
757     {
758       /*----------------------------------------------------------------------*/
759       /* CHTML 2.0                                                            */
760       /*----------------------------------------------------------------------*/
761       chtml20->out = apr_pstrcat(r->pool, 
762                       chtml20->out, 
763                       " text=\"", 
764                       value, 
765                       "\"", 
766                       NULL);
767     }
768     else
769     if (strcasecmp(name, "link") == 0) 
770     {
771       /*----------------------------------------------------------------------*/
772       /* CHTML 2.0                                                            */
773       /*----------------------------------------------------------------------*/
774       chtml20->out = apr_pstrcat(r->pool, 
775                       chtml20->out, 
776                       " link=\"", 
777                       value, 
778                       "\"", 
779                       NULL);
780     }
781     else
782     if (strcasecmp(name, "alink") == 0) 
783     {
784       /*----------------------------------------------------------------------*/
785       /* CHTML 4.0                                                            */
786       /*----------------------------------------------------------------------*/
787       /* ignore */
788     }
789     else
790     if (strcasecmp(name, "vlink") == 0) 
791     {
792       /*----------------------------------------------------------------------*/
793       /* CHTML 4.0                                                            */
794       /*----------------------------------------------------------------------*/
795       /* ignore */
796     }
797   }
798   chtml20->out = apr_pstrcat(r->pool, chtml20->out, ">\r\n", NULL);
799
800   return chtml20->out;
801 }
802
803 /**
804  * It is a handler who processes the BODY tag.
805  *
806  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
807  *                     destination is specified.
808  * @param node   [i]   The BODY tag node is specified.
809  * @return The conversion result is returned.
810  */
811 static char*
812 chtml20_end_body_tag(Chtml20* chtml20, Node* child) 
813 {
814   Doc*          doc = chtml20->doc;
815   request_rec*  r = doc->r;
816
817   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "</body>\r\n", NULL);
818
819   return chtml20->out;
820 }
821
822 /**
823  * It is a handler who processes the A tag.
824  *
825  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
826  *                     destination is specified.
827  * @param node   [i]   The A tag node is specified.
828  * @return The conversion result is returned.
829  */
830 static char*
831 chtml20_start_a_tag(Chtml20* chtml20, Node* node) 
832 {
833   Doc*          doc   = chtml20->doc;
834   request_rec*  r     = doc->r;
835   Attr*         attr;
836
837   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "<a", NULL);
838
839   /*--------------------------------------------------------------------------*/
840   /* Get Attributes                                                           */
841   /*--------------------------------------------------------------------------*/
842   for (attr = qs_get_attr(doc,node);
843        attr; 
844        attr = qs_get_next_attr(doc,attr)) 
845   {
846     char* name  = qs_get_attr_name(doc,attr);
847     char* value = qs_get_attr_value(doc,attr);
848
849     if (strcasecmp(name, "name") == 0) 
850     {
851       /*----------------------------------------------------------------------*/
852       /* CHTML1.0                                                             */
853       /*----------------------------------------------------------------------*/
854       chtml20->out = apr_pstrcat(r->pool, 
855                       chtml20->out, 
856                       " name=\"", 
857                       value, 
858                       "\"", 
859                       NULL);
860     }
861     else
862     if (strcasecmp(name, "href") == 0) 
863     {
864       /*----------------------------------------------------------------------*/
865       /* CHTML1.0                                                             */
866       /*----------------------------------------------------------------------*/
867       chtml20->out = apr_pstrcat(r->pool, 
868                       chtml20->out, 
869                       " href=\"", 
870                       value, 
871                       "\"", 
872                       NULL);
873     }
874     else
875     if (strcasecmp(name, "accesskey") == 0) 
876     {
877       /*----------------------------------------------------------------------*/
878       /* CHTML1.0                                                             */
879       /*----------------------------------------------------------------------*/
880       chtml20->out = apr_pstrcat(r->pool, 
881                       chtml20->out, 
882                       " accesskey=\"", 
883                       value, 
884                       "\"", 
885                       NULL);
886     }
887     else
888     if (strcasecmp(name, "cti") == 0) 
889     {
890       /*----------------------------------------------------------------------*/
891       /* CHTML 2.0                                                            */
892       /*----------------------------------------------------------------------*/
893       chtml20->out = apr_pstrcat(r->pool, 
894                       chtml20->out, 
895                       " cti=\"", 
896                       value, 
897                       "\"", 
898                       NULL);
899     }
900     else
901     if (strcasecmp(name, "ijam") == 0) 
902     {
903       /*----------------------------------------------------------------------*/
904       /* CHTML 3.0                                                            */
905       /*----------------------------------------------------------------------*/
906       /* ignore */
907     }
908     else
909     if (strcasecmp(name, "utn") == 0) 
910     {
911       /*----------------------------------------------------------------------*/
912       /* CHTML 3.0                                                            */
913       /*----------------------------------------------------------------------*/
914       /* ignore */
915     }
916     else
917     if (strcasecmp(name, "telbook") == 0) 
918     {
919       /*----------------------------------------------------------------------*/
920       /* CHTML 3.0                                                            */
921       /*----------------------------------------------------------------------*/
922       /* ignore */
923     }
924     else
925     if (strcasecmp(name, "kana") == 0) 
926     {
927       /*----------------------------------------------------------------------*/
928       /* CHTML 3.0                                                            */
929       /*----------------------------------------------------------------------*/
930       /* ignore */
931     }
932     else
933     if (strcasecmp(name, "email") == 0) 
934     {
935       /*----------------------------------------------------------------------*/
936       /* CHTML 3.0                                                            */
937       /*----------------------------------------------------------------------*/
938       /* ignore */
939     }
940     else
941     if (strcasecmp(name, "ista") == 0) 
942     {
943       /*----------------------------------------------------------------------*/
944       /* CHTML 4.0                                                            */
945       /*----------------------------------------------------------------------*/
946       /* ignore */
947     }
948     else
949     if (strcasecmp(name, "ilet") == 0) 
950     {
951       /*----------------------------------------------------------------------*/
952       /* CHTML 5.0                                                            */
953       /*----------------------------------------------------------------------*/
954       /* ignore */
955     }
956     else
957     if (strcasecmp(name, "iswf") == 0) 
958     {
959       /*----------------------------------------------------------------------*/
960       /* CHTML 5.0                                                            */
961       /*----------------------------------------------------------------------*/
962       /* ignore */
963     }
964     else
965     if (strcasecmp(name, "irst") == 0) 
966     {
967       /*----------------------------------------------------------------------*/
968       /* CHTML 5.0                                                            */
969       /*----------------------------------------------------------------------*/
970       /* ignore */
971     }
972   }
973   chtml20->out = apr_pstrcat(r->pool, chtml20->out, ">", NULL);
974   return chtml20->out;
975 }
976
977 /**
978  * It is a handler who processes the A tag.
979  *
980  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
981  *                     destination is specified.
982  * @param node   [i]   The A tag node is specified.
983  * @return The conversion result is returned.
984  */
985 static char*
986 chtml20_end_a_tag(Chtml20* chtml20, Node* child) 
987 {
988   Doc* doc = chtml20->doc;
989   request_rec* r = doc->r;
990
991   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "</a>", NULL);
992   return chtml20->out;
993 }
994
995 /**
996  * It is a handler who processes the BR tag.
997  *
998  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
999  *                     destination is specified.
1000  * @param node   [i]   The BR tag node is specified.
1001  * @return The conversion result is returned.
1002  */
1003 static char*
1004 chtml20_start_br_tag(Chtml20* chtml20, Node* node) 
1005 {
1006   Doc* doc = chtml20->doc;
1007   request_rec* r = doc->r;
1008   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "<br>\r\n", NULL);
1009   return chtml20->out;
1010 }
1011
1012 /**
1013  * It is a handler who processes the BR tag.
1014  *
1015  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
1016  *                     destination is specified.
1017  * @param node   [i]   The BR tag node is specified.
1018  * @return The conversion result is returned.
1019  */
1020 static char*
1021 chtml20_end_br_tag(Chtml20* chtml20, Node* child) 
1022 {
1023   return chtml20->out;
1024 }
1025
1026 /**
1027  * It is a handler who processes the FONT tag.
1028  *
1029  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
1030  *                     destination is specified.
1031  * @param node   [i]   The FONT tag node is specified.
1032  * @return The conversion result is returned.
1033  */
1034 static char*
1035 chtml20_start_font_tag(Chtml20* chtml20, Node* node) 
1036 {
1037   Doc*          doc   = chtml20->doc;
1038   request_rec*  r     = doc->r;
1039   Attr*         attr;
1040
1041   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "<font", NULL);
1042
1043   /*--------------------------------------------------------------------------*/
1044   /* Get Attributes                                                           */
1045   /*--------------------------------------------------------------------------*/
1046   for (attr = qs_get_attr(doc,node);
1047        attr; 
1048        attr = qs_get_next_attr(doc,attr)) 
1049   {
1050     char* name  = qs_get_attr_name(doc,attr);
1051     char* value = qs_get_attr_value(doc,attr);
1052
1053     if (strcasecmp(name, "color") == 0) 
1054     {
1055       chtml20->out = apr_pstrcat(r->pool, 
1056                       chtml20->out, 
1057                       " color=\"", 
1058                       value, 
1059                       "\"", 
1060                       NULL);
1061     }
1062     else
1063     if (strcasecmp(name, "size") == 0)
1064     {
1065       /*----------------------------------------------------------------------*/
1066       /* CHTML 5.0                                                            */
1067       /*----------------------------------------------------------------------*/
1068       /* ignore */
1069     }
1070   }
1071
1072   chtml20->out = apr_pstrcat(r->pool, chtml20->out, ">", NULL);
1073   return chtml20->out;
1074 }
1075
1076 /**
1077  * It is a handler who processes the FONT tag.
1078  *
1079  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
1080  *                     destination is specified.
1081  * @param node   [i]   The FONT tag node is specified.
1082  * @return The conversion result is returned.
1083  */
1084 static char*
1085 chtml20_end_font_tag(Chtml20* chtml20, Node* child) 
1086 {
1087   request_rec* r = chtml20->doc->r;
1088   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "</font>", NULL);
1089   return chtml20->out;
1090 }
1091
1092 /**
1093  * It is a handler who processes the FORM tag.
1094  *
1095  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
1096  *                     destination is specified.
1097  * @param node   [i]   The FORM tag node is specified.
1098  * @return The conversion result is returned.
1099  */
1100 static char*
1101 chtml20_start_form_tag(Chtml20* chtml20, Node* node) 
1102 {
1103   Doc* doc = chtml20->doc;
1104   request_rec* r = doc->r;
1105   Attr* attr;
1106
1107   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "<form", NULL);
1108
1109   /*--------------------------------------------------------------------------*/
1110   /* Get Attributes                                                           */
1111   /*--------------------------------------------------------------------------*/
1112   for (attr = qs_get_attr(doc,node);
1113        attr;
1114        attr = qs_get_next_attr(doc,attr)) 
1115   {
1116     char* name = qs_get_attr_name(doc,attr);
1117     char* value = qs_get_attr_value(doc,attr);
1118     if (strcasecmp(name, "action") == 0) 
1119     {
1120       /*----------------------------------------------------------------------*/
1121       /* CHTML 1.0                                                            */
1122       /*----------------------------------------------------------------------*/
1123       chtml20->out = apr_pstrcat(r->pool, 
1124                       chtml20->out, 
1125                       " action=\"",
1126                       value,
1127                       "\"", 
1128                       NULL);
1129     }
1130     else
1131     if (strcasecmp(name, "method") == 0) 
1132     {
1133       /*----------------------------------------------------------------------*/
1134       /* CHTML 1.0                                                            */
1135       /*----------------------------------------------------------------------*/
1136       chtml20->out = apr_pstrcat(r->pool, 
1137                       chtml20->out, 
1138                       " method=\"",
1139                       value,
1140                       "\"", 
1141                       NULL);
1142     }
1143     else
1144     if (strcasecmp(name, "utn") == 0) 
1145     {
1146       /*----------------------------------------------------------------------*/
1147       /* CHTML 3.0                                                            */
1148       /*----------------------------------------------------------------------*/
1149       /* ignore */
1150     }
1151   }
1152   chtml20->out = apr_pstrcat(r->pool, chtml20->out, ">", NULL);
1153   return chtml20->out;
1154 }
1155
1156 /**
1157  * It is a handler who processes the FORM tag.
1158  *
1159  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
1160  *                     destination is specified.
1161  * @param node   [i]   The FORM tag node is specified.
1162  * @return The conversion result is returned.
1163  */
1164 static char*
1165 chtml20_end_form_tag(Chtml20* chtml20, Node* child) 
1166 {
1167   Doc* doc = chtml20->doc;
1168   request_rec* r = doc->r;
1169
1170   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "</form>", NULL);
1171   return chtml20->out;
1172 }
1173
1174 /**
1175  * It is a handler who processes the INPUT tag.
1176  *
1177  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
1178  *                     destination is specified.
1179  * @param node   [i]   The INPUT tag node is specified.
1180  * @return The conversion result is returned.
1181  */
1182 static char*
1183 chtml20_start_input_tag(Chtml20* chtml20, Node* node) 
1184 {
1185   Doc*          doc         = chtml20->doc;
1186   request_rec*  r           = doc->r;
1187   char*         max_length  = NULL;
1188   char*         type        = NULL;
1189   char*         name        = NULL;
1190   char*         value       = NULL;
1191   char*         istyle      = NULL;
1192   char*         size        = NULL;
1193   char*         checked     = NULL;
1194   char*         accesskey   = NULL;
1195
1196   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "<input", NULL);
1197
1198   /*--------------------------------------------------------------------------*/
1199   /* Get Attributes                                                           */
1200   /*--------------------------------------------------------------------------*/
1201
1202   type       = qs_get_type_attr(doc, node, r);
1203   name       = qs_get_name_attr(doc, node, r);
1204   value      = qs_get_value_attr(doc,node,r);
1205   istyle     = qs_get_istyle_attr(doc,node,r);
1206   max_length = qs_get_maxlength_attr(doc,node,r);
1207   checked    = qs_get_checked_attr(doc,node,r);
1208   accesskey  = qs_get_accesskey_attr(doc, node, r);
1209   size       = qs_get_size_attr(doc, node, r);
1210
1211   if (type != NULL)
1212   {
1213     chtml20->out = apr_pstrcat(r->pool,
1214                     chtml20->out, 
1215                     " type=\"", 
1216                     type, 
1217                     "\" ", 
1218                     NULL);
1219   }
1220   if (size != NULL)
1221   {
1222     chtml20->out = apr_pstrcat(r->pool, 
1223                     chtml20->out, 
1224                     " size=\"", 
1225                     size, 
1226                     "\" ", 
1227                     NULL);
1228   }
1229   if (name != NULL)
1230   {
1231     chtml20->out = apr_pstrcat(r->pool, 
1232                     chtml20->out, 
1233                     " name=\"", 
1234                     name, 
1235                     "\" ", 
1236                     NULL);
1237   }
1238   if (value != NULL)
1239   {
1240     chtml20->out = apr_pstrcat(r->pool, 
1241                     chtml20->out, 
1242                     " value=\"", 
1243                     value, 
1244                     "\" ", 
1245                     NULL);
1246   }
1247   if (accesskey != NULL)
1248   {
1249     chtml20->out = apr_pstrcat(r->pool, 
1250                     chtml20->out, 
1251                     " accesskey=\"", 
1252                     accesskey, "\" ", 
1253                     NULL);
1254   }
1255   if (istyle != NULL)
1256   {
1257     /*------------------------------------------------------------------------*/
1258     /* CHTML 2.0                                                              */
1259     /*------------------------------------------------------------------------*/
1260     chtml20->out = apr_pstrcat(r->pool, 
1261                     chtml20->out, 
1262                     " istyle=\"", 
1263                     istyle, "\" ", 
1264                     NULL);
1265   }
1266   /*--------------------------------------------------------------------------*/
1267   /* The figure is default for the password.                                  */
1268   /*--------------------------------------------------------------------------*/
1269   if (max_length != NULL)
1270   {
1271     if (chxj_chk_numeric(max_length) != 0)
1272     {
1273       max_length = apr_psprintf(r->pool, "0");
1274     }
1275     if (istyle != NULL && strcasecmp(istyle, "1") == 0)
1276     {
1277       chtml20->out = apr_pstrcat(r->pool, 
1278                       chtml20->out, 
1279                       apr_psprintf(r->pool, " maxlength=\"%d\"", chxj_atoi(max_length)*2) , NULL);
1280     }
1281     else
1282     {
1283       chtml20->out = apr_pstrcat(r->pool, 
1284                       chtml20->out, 
1285                       apr_psprintf(r->pool, " maxlength=\"%d\"", chxj_atoi(max_length)) , NULL);
1286     }
1287   }
1288
1289   if (checked != NULL)
1290   {
1291     chtml20->out = apr_pstrcat(r->pool, 
1292                     chtml20->out, " checked ", NULL);
1293   }
1294
1295   chtml20->out = apr_pstrcat(r->pool, chtml20->out, " >", NULL);
1296   return chtml20->out;
1297 }
1298
1299 /**
1300  * It is a handler who processes the INPUT tag.
1301  *
1302  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
1303  *                     destination is specified.
1304  * @param node   [i]   The INPUT tag node is specified.
1305  * @return The conversion result is returned.
1306  */
1307 static char*
1308 chtml20_end_input_tag(Chtml20* chtml20, Node* child) 
1309 {
1310   return chtml20->out;
1311 }
1312
1313 /**
1314  * It is a handler who processes the CENTER tag.
1315  *
1316  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
1317  *                     destination is specified.
1318  * @param node   [i]   The CENTER tag node is specified.
1319  * @return The conversion result is returned.
1320  */
1321 static char*
1322 chtml20_start_center_tag(Chtml20* chtml20, Node* node) 
1323 {
1324   Doc*          doc = chtml20->doc;
1325   request_rec*  r   = doc->r;
1326
1327   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "<center>", NULL);
1328
1329   return chtml20->out;
1330 }
1331
1332 /**
1333  * It is a handler who processes the CENTER tag.
1334  *
1335  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
1336  *                     destination is specified.
1337  * @param node   [i]   The CENTER tag node is specified.
1338  * @return The conversion result is returned.
1339  */
1340 static char*
1341 chtml20_end_center_tag(Chtml20* chtml20, Node* child) 
1342 {
1343   Doc*          doc = chtml20->doc;
1344   request_rec*  r   = doc->r;
1345
1346   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "</center>", NULL);
1347
1348   return chtml20->out;
1349 }
1350
1351 /**
1352  * It is a handler who processes the HR tag.
1353  *
1354  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
1355  *                     destination is specified.
1356  * @param node   [i]   The HR tag node is specified.
1357  * @return The conversion result is returned.
1358  */
1359 static char*
1360 chtml20_start_hr_tag(Chtml20* chtml20, Node* node) 
1361 {
1362   Doc* doc = chtml20->doc;
1363   request_rec* r = doc->r;
1364   Attr* attr;
1365
1366   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "<hr ", NULL);
1367  
1368   for (attr = qs_get_attr(doc,node);
1369        attr; 
1370        attr = qs_get_next_attr(doc,attr)) 
1371   {
1372     char* name = qs_get_attr_name(doc,attr);
1373     char* value = qs_get_attr_value(doc,attr);
1374     if (strcasecmp(name, "align") == 0) 
1375     {
1376       /*----------------------------------------------------------------------*/
1377       /* CHTML 1.0                                                            */
1378       /*----------------------------------------------------------------------*/
1379       chtml20->out = apr_pstrcat(r->pool,
1380                         chtml20->out, 
1381                         " align=\"", value, "\" ", NULL);
1382     }
1383     else
1384     if (strcasecmp(name, "size") == 0)
1385     {
1386       /*----------------------------------------------------------------------*/
1387       /* CHTML 1.0                                                            */
1388       /*----------------------------------------------------------------------*/
1389       chtml20->out = apr_pstrcat(r->pool,
1390                         chtml20->out, 
1391                         " size=\"", value, "\" ", NULL);
1392     }
1393     else
1394     if (strcasecmp(name, "width") == 0)
1395     {
1396       /*----------------------------------------------------------------------*/
1397       /* CHTML 1.0                                                            */
1398       /*----------------------------------------------------------------------*/
1399       chtml20->out = apr_pstrcat(r->pool,
1400                         chtml20->out, 
1401                         " width=\"", value, "\" ", NULL);
1402     }
1403     else
1404     if (strcasecmp(name, "noshade") == 0)
1405     {
1406       /*----------------------------------------------------------------------*/
1407       /* CHTML 1.0                                                            */
1408       /*----------------------------------------------------------------------*/
1409       chtml20->out = apr_pstrcat(r->pool,
1410                         chtml20->out, 
1411                         " noshade ", NULL);
1412     }
1413     else
1414     if (strcasecmp(name, "color") == 0)
1415     {
1416       /*----------------------------------------------------------------------*/
1417       /* CHTML 4.0                                                            */
1418       /*----------------------------------------------------------------------*/
1419       /* ignore */
1420     }
1421   }
1422   chtml20->out = apr_pstrcat(r->pool, chtml20->out, " >", NULL);
1423
1424   return chtml20->out;
1425 }
1426
1427 /**
1428  * It is a handler who processes the HR tag.
1429  *
1430  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
1431  *                     destination is specified.
1432  * @param node   [i]   The HR tag node is specified.
1433  * @return The conversion result is returned.
1434  */
1435 static char*
1436 chtml20_end_hr_tag(Chtml20* chtml20, Node* child) 
1437 {
1438   return chtml20->out;
1439 }
1440
1441 /**
1442  * It is a handler who processes the IMG tag.
1443  *
1444  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
1445  *                     destination is specified.
1446  * @param node   [i]   The IMG tag node is specified.
1447  * @return The conversion result is returned.
1448  */
1449 static char*
1450 chtml20_start_img_tag(Chtml20* chtml20, Node* node) 
1451 {
1452   Doc*          doc = chtml20->doc;
1453   request_rec*  r   = doc->r;
1454   Attr* attr;
1455 #ifndef IMG_NOT_CONVERT_FILENAME
1456   device_table* spec = chtml20->spec;
1457 #endif
1458
1459   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "<img", NULL);
1460  
1461
1462   /*--------------------------------------------------------------------------*/
1463   /* Get Attributes                                                           */
1464   /*--------------------------------------------------------------------------*/
1465   for (attr = qs_get_attr(doc,node);
1466        attr;
1467        attr = qs_get_next_attr(doc,attr)) 
1468   {
1469     char* name  = qs_get_attr_name(doc,attr);
1470     char* value = qs_get_attr_value(doc,attr);
1471
1472     if (strcasecmp(name, "src") == 0) 
1473     {
1474       /*----------------------------------------------------------------------*/
1475       /* CHTML 1.0                                                            */
1476       /*----------------------------------------------------------------------*/
1477 #ifdef IMG_NOT_CONVERT_FILENAME
1478       chtml20->out = apr_pstrcat(r->pool, 
1479                       chtml20->out, " src=\"",value,"\"", NULL);
1480 #else
1481       chtml20->out = apr_pstrcat(r->pool, 
1482                       chtml20->out, " src=\"", 
1483                       chxj_img_conv(r, spec,value), NULL);
1484       chtml20->out = apr_pstrcat(r->pool, chtml20->out, "\"", NULL);
1485 #endif
1486     }
1487     else
1488     if (strcasecmp(name, "align" ) == 0) 
1489     {
1490       /*----------------------------------------------------------------------*/
1491       /* CHTML 1.0                                                            */
1492       /*----------------------------------------------------------------------*/
1493       chtml20->out = apr_pstrcat(r->pool, 
1494                       chtml20->out, " align=\"",value,"\"", NULL);
1495     }
1496     else
1497     if (strcasecmp(name, "width" ) == 0) 
1498     {
1499       /*----------------------------------------------------------------------*/
1500       /* CHTML 1.0                                                            */
1501       /*----------------------------------------------------------------------*/
1502       chtml20->out = apr_pstrcat(r->pool, 
1503                       chtml20->out, " width=\"",value,"\"", NULL);
1504     }
1505     else
1506     if (strcasecmp(name, "height") == 0) 
1507     {
1508       /*----------------------------------------------------------------------*/
1509       /* CHTML 1.0                                                            */
1510       /*----------------------------------------------------------------------*/
1511       chtml20->out = apr_pstrcat(r->pool, 
1512                       chtml20->out, " height=\"",value,"\"", NULL);
1513     }
1514     else
1515     if (strcasecmp(name, "hspace") == 0) 
1516     {
1517       /*----------------------------------------------------------------------*/
1518       /* CHTML 1.0                                                            */
1519       /*----------------------------------------------------------------------*/
1520       chtml20->out = apr_pstrcat(r->pool, 
1521                       chtml20->out, " hspace=\"",value,"\"", NULL);
1522     }
1523     else
1524     if (strcasecmp(name, "vspace") == 0) 
1525     {
1526       /*----------------------------------------------------------------------*/
1527       /* CHTML 1.0                                                            */
1528       /*----------------------------------------------------------------------*/
1529       chtml20->out = apr_pstrcat(r->pool, 
1530                       chtml20->out, " vspace=\"",value,"\"", NULL);
1531     }
1532     else
1533     if (strcasecmp(name, "alt"   ) == 0) 
1534     {
1535       /*----------------------------------------------------------------------*/
1536       /* CHTML 1.0                                                            */
1537       /*----------------------------------------------------------------------*/
1538       chtml20->out = apr_pstrcat(r->pool, 
1539                       chtml20->out, " alt=\"",value,"\"", NULL);
1540     }
1541     else
1542     if (strcasecmp(name, "align" ) == 0) 
1543     {
1544       /*----------------------------------------------------------------------*/
1545       /* CHTML 4.0                                                            */
1546       /*----------------------------------------------------------------------*/
1547       /* ignore */
1548     }
1549   }
1550
1551   chtml20->out = apr_pstrcat(r->pool, chtml20->out, ">", NULL);
1552
1553   return chtml20->out;
1554 }
1555
1556 /**
1557  * It is a handler who processes the IMG tag.
1558  *
1559  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
1560  *                     destination is specified.
1561  * @param node   [i]   The IMG tag node is specified.
1562  * @return The conversion result is returned.
1563  */
1564 static char*
1565 chtml20_end_img_tag(Chtml20* chtml20, Node* child) 
1566 {
1567   return chtml20->out;
1568 }
1569
1570 /**
1571  * It is a handler who processes the SELECT tag.
1572  *
1573  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
1574  *                     destination is specified.
1575  * @param node   [i]   The SELECT tag node is specified.
1576  * @return The conversion result is returned.
1577  */
1578 static char*
1579 chtml20_start_select_tag(Chtml20* chtml20, Node* child)
1580 {
1581   Doc* doc = chtml20->doc;
1582   request_rec* r = doc->r;
1583   Attr* attr;
1584
1585   char* size      = NULL;
1586   char* name      = NULL;
1587
1588   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "<select", NULL);
1589   for (attr = qs_get_attr(doc,child);
1590        attr;
1591        attr = qs_get_next_attr(doc,attr)) 
1592   {
1593     char* nm  = qs_get_attr_name(doc,attr);
1594     char* val = qs_get_attr_value(doc,attr);
1595
1596     if (strcasecmp(nm, "size") == 0)
1597     {
1598       /*----------------------------------------------------------------------*/
1599       /* CHTML 1.0 version 2.0                                                */
1600       /*----------------------------------------------------------------------*/
1601       size = apr_pstrdup(r->pool, val);
1602     }
1603     else
1604     if (strcasecmp(nm, "name") == 0)
1605     {
1606       /*----------------------------------------------------------------------*/
1607       /* CHTML 1.0 version 2.0                                                */
1608       /*----------------------------------------------------------------------*/
1609       name = apr_pstrdup(r->pool, val);
1610     }
1611     else
1612     if (strcasecmp(nm, "multiple") == 0)
1613     {
1614       /*----------------------------------------------------------------------*/
1615       /* CHTML 1.0 version 2.0                                                */
1616       /*----------------------------------------------------------------------*/
1617       /* not support */
1618     }
1619   }
1620
1621   if (size != NULL)
1622   {
1623     chtml20->out = apr_pstrcat(r->pool, chtml20->out, " size=\"",size,"\"", NULL);
1624   }
1625   if (name != NULL)
1626   {
1627     chtml20->out = apr_pstrcat(r->pool, chtml20->out, " name=\"",name,"\"", NULL);
1628   }
1629   chtml20->out = apr_pstrcat(r->pool, chtml20->out, ">\n", NULL);
1630   return chtml20->out;
1631 }
1632
1633 /**
1634  * It is a handler who processes the SELECT tag.
1635  *
1636  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
1637  *                     destination is specified.
1638  * @param node   [i]   The SELECT tag node is specified.
1639  * @return The conversion result is returned.
1640  */
1641 static char*
1642 chtml20_end_select_tag(Chtml20* chtml20, Node* child)
1643 {
1644   Doc* doc = chtml20->doc;
1645   request_rec* r = doc->r;
1646
1647   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "</select>\n", NULL);
1648   return chtml20->out;
1649 }
1650
1651 /**
1652  * It is a handler who processes the OPTION tag.
1653  *
1654  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
1655  *                     destination is specified.
1656  * @param node   [i]   The OPTION tag node is specified.
1657  * @return The conversion result is returned.
1658  */
1659 static char*
1660 chtml20_start_option_tag(Chtml20* chtml20, Node* child)
1661 {
1662   Doc* doc = chtml20->doc;
1663   request_rec* r = doc->r;
1664   Attr* attr;
1665
1666   char* selected   = NULL;
1667   char* value      = NULL;
1668
1669   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "<option", NULL);
1670   for (attr = qs_get_attr(doc,child);
1671        attr;
1672        attr = qs_get_next_attr(doc,attr)) 
1673   {
1674     char* nm  = qs_get_attr_name(doc,attr);
1675     char* val = qs_get_attr_value(doc,attr);
1676
1677     if (strcasecmp(nm, "selected") == 0)
1678     {
1679       /*----------------------------------------------------------------------*/
1680       /* CHTML 1.0 version 2.0                                                */
1681       /*----------------------------------------------------------------------*/
1682       selected = apr_pstrdup(r->pool, val);
1683     }
1684     else
1685     if (strcasecmp(nm, "value") == 0)
1686     {
1687       /*----------------------------------------------------------------------*/
1688       /* CHTML 1.0 version 2.0                                                */
1689       /*----------------------------------------------------------------------*/
1690       value = apr_pstrdup(r->pool, val);
1691     }
1692   }
1693
1694   if (value != NULL)
1695   {
1696     chtml20->out = apr_pstrcat(r->pool, chtml20->out, " value=\"",value,"\"", NULL);
1697   }
1698   else
1699   {
1700     chtml20->out = apr_pstrcat(r->pool, chtml20->out, " value=\"\"", NULL);
1701   }
1702
1703   if (selected != NULL)
1704   {
1705     chtml20->out = apr_pstrcat(r->pool, chtml20->out, " selected ", NULL);
1706   }
1707
1708   chtml20->out = apr_pstrcat(r->pool, chtml20->out, ">", NULL);
1709   return chtml20->out;
1710 }
1711
1712 /**
1713  * It is a handler who processes the OPTION tag.
1714  *
1715  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
1716  *                     destination is specified.
1717  * @param node   [i]   The OPTION tag node is specified.
1718  * @return The conversion result is returned.
1719  */
1720 static char*
1721 chtml20_end_option_tag(Chtml20* chtml20, Node* child)
1722 {
1723   /* Don't close */
1724   return chtml20->out;
1725 }
1726
1727 /**
1728  * It is a handler who processes the DIV tag.
1729  *
1730  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
1731  *                     destination is specified.
1732  * @param node   [i]   The DIV tag node is specified.
1733  * @return The conversion result is returned.
1734  */
1735 static char*
1736 chtml20_start_div_tag(Chtml20* chtml20, Node* child)
1737 {
1738   Doc* doc = chtml20->doc;
1739   request_rec* r = doc->r;
1740   Attr* attr;
1741
1742   char* align   = NULL;
1743
1744   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "<div", NULL);
1745   for (attr = qs_get_attr(doc,child);
1746        attr;
1747        attr = qs_get_next_attr(doc,attr)) 
1748   {
1749     char* nm  = qs_get_attr_name(doc,attr);
1750     char* val = qs_get_attr_value(doc,attr);
1751
1752     if (strcasecmp(nm, "align") == 0)
1753     {
1754       /*----------------------------------------------------------------------*/
1755       /* CHTML 1.0 (W3C version 3.2)                                          */
1756       /*----------------------------------------------------------------------*/
1757       align = apr_pstrdup(r->pool, val);
1758     }
1759   }
1760
1761   if (align != NULL)
1762   {
1763     chtml20->out = apr_pstrcat(r->pool, 
1764                     chtml20->out, " align=\"", align, "\"", NULL);
1765   }
1766
1767   chtml20->out = apr_pstrcat(r->pool, chtml20->out, ">", NULL);
1768   return chtml20->out;
1769 }
1770
1771 /**
1772  * It is a handler who processes the DIV tag.
1773  *
1774  * @param chtml20  [i/o] The pointer to the CHTML structure at the output
1775  *                     destination is specified.
1776  * @param node   [i]   The DIV tag node is specified.
1777  * @return The conversion result is returned.
1778  */
1779 static char*
1780 chtml20_end_div_tag(Chtml20* chtml20, Node* child)
1781 {
1782   Doc* doc = chtml20->doc;
1783   request_rec* r = doc->r;
1784
1785   chtml20->out = apr_pstrcat(r->pool, chtml20->out, "</div>\n", NULL);
1786
1787   return chtml20->out;
1788 }
1789
1790
1791 static void
1792 chtml20_chxjif_tag(Chtml20* chtml20, Node* node)
1793 {
1794   Doc*         doc   = chtml20->doc;
1795   Node*        child;
1796   request_rec* r     = doc->r;
1797
1798   for (child = qs_get_child_node(doc, node);
1799        child;
1800        child = qs_get_next_node(doc, child))
1801   {
1802     chtml20->out = apr_pstrcat(r->pool, chtml20->out, child->otext, NULL);
1803     chtml20_chxjif_tag(chtml20, child);
1804   }
1805 }
1806 /*
1807  * vim:ts=2 et
1808  */