OSDN Git Service

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