OSDN Git Service

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