OSDN Git Service

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