OSDN Git Service

Merge branch 'branch_0.12.0'
[modchxj/mod_chxj.git] / src / chxj_jxhtml.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_jxhtml.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_encoding.h"
23 #include "chxj_url_encode.h"
24 #include "chxj_str_util.h"
25 #include "chxj_header_inf.h"
26 #include "chxj_jreserved_tag.h"
27 #include "chxj_conv_z2h.h"
28
29
30 #define GET_JXHTML(X) ((jxhtml_t *)(X))
31 #undef W_L
32 #undef W_V
33 #define W_L(X)          do { jxhtml->out = BUFFERED_WRITE_LITERAL(jxhtml->out, &doc->buf, (X)); } while(0)
34 #define W_V(X)          do { jxhtml->out = (X) ? BUFFERED_WRITE_VALUE(jxhtml->out, &doc->buf, (X))  \
35                                                : BUFFERED_WRITE_LITERAL(jxhtml->out, &doc->buf, ""); } while(0)
36 #undef W_NLCODE
37 #define W_NLCODE()     do { char *nlcode = TO_NLCODE(jxhtml->conf); W_V(nlcode); } while (0)
38
39 static char *s_jxhtml_start_html_tag     (void *pdoc, Node *node);
40 static char *s_jxhtml_end_html_tag       (void *pdoc, Node *node);
41 static char *s_jxhtml_start_meta_tag     (void *pdoc, Node *node);
42 static char *s_jxhtml_end_meta_tag       (void *pdoc, Node *node);
43 static char *s_jxhtml_start_head_tag     (void *pdoc, Node *node);
44 static char *s_jxhtml_end_head_tag       (void *pdoc, Node *node);
45 static char *s_jxhtml_start_title_tag    (void *pdoc, Node *node);
46 static char *s_jxhtml_end_title_tag      (void *pdoc, Node *node);
47 static char *s_jxhtml_start_base_tag     (void *pdoc, Node *node);
48 static char *s_jxhtml_end_base_tag       (void *pdoc, Node *node);
49 static char *s_jxhtml_start_body_tag     (void *pdoc, Node *node);
50 static char *s_jxhtml_end_body_tag       (void *pdoc, Node *node);
51 static char *s_jxhtml_start_a_tag        (void *pdoc, Node *node);
52 static char *s_jxhtml_end_a_tag          (void *pdoc, Node *node);
53 static char *s_jxhtml_start_pre_tag      (void *pdoc, Node *node);
54 static char *s_jxhtml_end_pre_tag        (void *pdoc, Node *node);
55 static char *s_jxhtml_start_p_tag        (void *pdoc, Node *node);
56 static char *s_jxhtml_end_p_tag          (void *pdoc, Node *node);
57 static char *s_jxhtml_start_ul_tag       (void *pdoc, Node *node);
58 static char *s_jxhtml_end_ul_tag         (void *pdoc, Node *node);
59 static char *s_jxhtml_start_ol_tag       (void *pdoc, Node *node);
60 static char *s_jxhtml_end_ol_tag         (void *pdoc, Node *node);
61 static char *s_jxhtml_start_li_tag       (void *pdoc, Node *node);
62 static char *s_jxhtml_end_li_tag         (void *pdoc, Node *node);
63 static char *s_jxhtml_start_br_tag       (void *pdoc, Node *node);
64 static char *s_jxhtml_end_br_tag         (void *pdoc, Node *node);
65 static char *s_jxhtml_start_tr_tag       (void *pdoc, Node *node);
66 static char *s_jxhtml_end_tr_tag         (void *pdoc, Node *node);
67 static char *s_jxhtml_start_font_tag     (void *pdoc, Node *node);
68 static char *s_jxhtml_end_font_tag       (void *pdoc, Node *node);
69 static char *s_jxhtml_start_form_tag     (void *pdoc, Node *node);
70 static char *s_jxhtml_end_form_tag       (void *pdoc, Node *node);
71 static char *s_jxhtml_start_input_tag    (void *pdoc, Node *node);
72 static char *s_jxhtml_end_input_tag      (void *pdoc, Node *node);
73 static char *s_jxhtml_start_center_tag   (void *pdoc, Node *node);
74 static char *s_jxhtml_end_center_tag     (void *pdoc, Node *node);
75 static char *s_jxhtml_start_hr_tag       (void *pdoc, Node *node);
76 static char *s_jxhtml_end_hr_tag         (void *pdoc, Node *node);
77 static char *s_jxhtml_start_img_tag      (void *pdoc, Node *node);
78 static char *s_jxhtml_end_img_tag        (void *pdoc, Node *node);
79 static char *s_jxhtml_start_select_tag   (void *pdoc, Node *node);
80 static char *s_jxhtml_end_select_tag     (void *pdoc, Node *node);
81 static char *s_jxhtml_start_option_tag   (void *pdoc, Node *node);
82 static char *s_jxhtml_end_option_tag     (void *pdoc, Node *node);
83 static char *s_jxhtml_start_div_tag      (void *pdoc, Node *node);
84 static char *s_jxhtml_end_div_tag        (void *pdoc, Node *node);
85 static char *s_jxhtml_start_textarea_tag (void *pdoc, Node *node);
86 static char *s_jxhtml_end_textarea_tag   (void *pdoc, Node *node);
87 static char *s_jxhtml_start_b_tag        (void *pdoc, Node *node);
88 static char *s_jxhtml_end_b_tag          (void *pdoc, Node *node);
89 static char *s_jxhtml_chxjif_tag         (void *pdoc, Node *node); 
90 static char *s_jxhtml_text_tag           (void *pdoc, Node *node);
91 static char *s_jxhtml_start_blockquote_tag (void *pdoc, Node *node);
92 static char *s_jxhtml_end_blockquote_tag  (void *pdoc, Node *node);
93 static char *s_jxhtml_start_dir_tag      (void *pdoc, Node *node);
94 static char *s_jxhtml_end_dir_tag        (void *pdoc, Node *node);
95 static char *s_jxhtml_start_dl_tag       (void *pdoc, Node *node);
96 static char *s_jxhtml_end_dl_tag         (void *pdoc, Node *node);
97 static char *s_jxhtml_start_dt_tag       (void *pdoc, Node *node);
98 static char *s_jxhtml_end_dt_tag         (void *pdoc, Node *node);
99 static char *s_jxhtml_start_dd_tag       (void *pdoc, Node *node);
100 static char *s_jxhtml_end_dd_tag         (void *pdoc, Node *node);
101 static char *s_jxhtml_start_h1_tag       (void *pdoc, Node *node);
102 static char *s_jxhtml_end_h1_tag         (void *pdoc, Node *node);
103 static char *s_jxhtml_start_h2_tag       (void *pdoc, Node *node);
104 static char *s_jxhtml_end_h2_tag         (void *pdoc, Node *node);
105 static char *s_jxhtml_start_h3_tag       (void *pdoc, Node *node);
106 static char *s_jxhtml_end_h3_tag         (void *pdoc, Node *node);
107 static char *s_jxhtml_start_h4_tag       (void *pdoc, Node *node);
108 static char *s_jxhtml_end_h4_tag         (void *pdoc, Node *node);
109 static char *s_jxhtml_start_h5_tag       (void *pdoc, Node *node);
110 static char *s_jxhtml_end_h5_tag         (void *pdoc, Node *node);
111 static char *s_jxhtml_start_h6_tag       (void *pdoc, Node *node);
112 static char *s_jxhtml_end_h6_tag         (void *pdoc, Node *node);
113 static char *s_jxhtml_start_menu_tag     (void *pdoc, Node *node);
114 static char *s_jxhtml_end_menu_tag       (void *pdoc, Node *node);
115 static char *s_jxhtml_start_plaintext_tag       (void *pdoc, Node *node);
116 static char *s_jxhtml_start_plaintext_tag_inner (void *pdoc, Node *node);
117 static char *s_jxhtml_end_plaintext_tag         (void *pdoc, Node *node);
118 static char *s_jxhtml_start_blink_tag  (void *pdoc, Node *node);
119 static char *s_jxhtml_end_blink_tag    (void *pdoc, Node *node);
120 static char *s_jxhtml_start_marquee_tag (void *pdoc, Node *node);
121 static char *s_jxhtml_end_marquee_tag  (void *pdoc, Node *node);
122 static char *s_jxhtml_newline_mark       (void *pdoc, Node *node);
123 static char *s_jxhtml_link_tag           (void *pdoc, Node *node);
124 static char *s_jxhtml_start_span_tag     (void *pdoc, Node *node);
125 static char *s_jxhtml_end_span_tag       (void *pdoc, Node *node);
126 static char *s_jxhtml_style_tag       (void *pdoc, Node *node);
127
128 static void  s_init_jxhtml(jxhtml_t *jxhtml, Doc *doc, request_rec *r, device_table *spec);
129
130 static int   s_jxhtml_search_emoji(jxhtml_t *jxhtml, char *txt, char **rslt);
131
132 static css_prop_list_t *s_jxhtml_nopush_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value);
133 static css_prop_list_t *s_jxhtml_push_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value);
134
135
136
137 tag_handler jxhtml_handler[] = {
138   /* tagHTML */
139   {
140     s_jxhtml_start_html_tag,
141     s_jxhtml_end_html_tag,
142   },
143   /* tagMETA */
144   {
145     s_jxhtml_start_meta_tag,
146     s_jxhtml_end_meta_tag,
147   },
148   /* tagTEXTAREA */
149   {
150     s_jxhtml_start_textarea_tag,
151     s_jxhtml_end_textarea_tag,
152   },
153   /* tagP */
154   {
155     s_jxhtml_start_p_tag,
156     s_jxhtml_end_p_tag,
157   },
158   /* tagPRE */
159   {
160     s_jxhtml_start_pre_tag,
161     s_jxhtml_end_pre_tag,
162   },
163   /* tagUL */
164   {
165     s_jxhtml_start_ul_tag,
166     s_jxhtml_end_ul_tag,
167   },
168   /* tagLI */
169   {
170     s_jxhtml_start_li_tag,
171     s_jxhtml_end_li_tag,
172   },
173   /* tagOL */
174   {
175     s_jxhtml_start_ol_tag,
176     s_jxhtml_end_ol_tag,
177   },
178   /* tagH1 */
179   {
180     s_jxhtml_start_h1_tag,
181     s_jxhtml_end_h1_tag,
182   },
183   /* tagH2 */
184   {
185     s_jxhtml_start_h2_tag,
186     s_jxhtml_end_h2_tag,
187   },
188   /* tagH3 */
189   {
190     s_jxhtml_start_h3_tag,
191     s_jxhtml_end_h3_tag,
192   },
193   /* tagH4 */
194   {
195     s_jxhtml_start_h4_tag,
196     s_jxhtml_end_h4_tag,
197   },
198   /* tagH5 */
199   {
200     s_jxhtml_start_h5_tag,
201     s_jxhtml_end_h5_tag,
202   },
203   /* tagH6 */
204   {
205     s_jxhtml_start_h6_tag,
206     s_jxhtml_end_h6_tag,
207   },
208   /* tagHEAD */
209   {
210     s_jxhtml_start_head_tag,
211     s_jxhtml_end_head_tag,
212   },
213   /* tagTITLE */
214   {
215     s_jxhtml_start_title_tag,
216     s_jxhtml_end_title_tag,
217   },
218   /* tagBASE */
219   {
220     s_jxhtml_start_base_tag,
221     s_jxhtml_end_base_tag,
222   },
223   /* tagBODY */
224   {
225     s_jxhtml_start_body_tag,
226     s_jxhtml_end_body_tag,
227   },
228   /* tagA */
229   {
230     s_jxhtml_start_a_tag,
231     s_jxhtml_end_a_tag,
232   },
233   /* tagBR */
234   {
235     s_jxhtml_start_br_tag,
236     s_jxhtml_end_br_tag,
237   },
238   /* tagTABLE */
239   {
240     NULL,
241     NULL,
242   },
243   /* tagTR */
244   {
245     s_jxhtml_start_tr_tag,
246     s_jxhtml_end_tr_tag,
247   },
248   /* tagTD */
249   {
250     NULL,
251     NULL,
252   },
253   /* tagTBODY */
254   {
255     NULL,
256     NULL,
257   },
258   /* tagFONT */
259   {
260     s_jxhtml_start_font_tag,
261     s_jxhtml_end_font_tag,
262   },
263   /* tagFORM */
264   {
265     s_jxhtml_start_form_tag,
266     s_jxhtml_end_form_tag,
267   },
268   /* tagINPUT */
269   {
270     s_jxhtml_start_input_tag,
271     s_jxhtml_end_input_tag,
272   },
273   /* tagCENTER */
274   {
275     s_jxhtml_start_center_tag,
276     s_jxhtml_end_center_tag,
277   },
278   /* tagHR */
279   {
280     s_jxhtml_start_hr_tag,
281     s_jxhtml_end_hr_tag,
282   },
283   /* tagIMG */
284   {
285     s_jxhtml_start_img_tag,
286     s_jxhtml_end_img_tag,
287   },
288   /* tagSELECT */
289   {
290     s_jxhtml_start_select_tag,
291     s_jxhtml_end_select_tag,
292   },
293   /* tagOPTION */
294   {
295     s_jxhtml_start_option_tag,
296     s_jxhtml_end_option_tag,
297   },
298   /* tagDIV */
299   {
300     s_jxhtml_start_div_tag,
301     s_jxhtml_end_div_tag,
302   },
303   /* tagCHXJIF */
304   {
305     s_jxhtml_chxjif_tag,
306     NULL,
307   },
308   /* tagCHXJRAW */
309   {
310     s_jxhtml_chxjif_tag,
311     NULL,
312   },
313   /* tagNOBR */
314   {
315     NULL,
316     NULL,
317   },
318   /* tagSMALL */
319   {
320     NULL,
321     NULL,
322   },
323   /* tagSTYLE */
324   {
325     s_jxhtml_style_tag,
326     NULL,
327   },
328   /* tagSPAN */
329   {
330     s_jxhtml_start_span_tag,
331     s_jxhtml_end_span_tag,
332   },
333   /* tagTEXT */
334   {
335     s_jxhtml_text_tag,
336     NULL,
337   },
338   /* tagTH */
339   {
340     NULL,
341     NULL,
342   },
343   /* tagB */
344   {
345     s_jxhtml_start_b_tag,
346     s_jxhtml_end_b_tag,
347   },
348   /* tagFIELDSET */
349   {
350     NULL,
351     NULL,
352   },
353   /* tagDT */
354   {
355     s_jxhtml_start_dt_tag,
356     s_jxhtml_end_dt_tag,
357   },
358   /* tagLEGEND */
359   {
360     NULL,
361     NULL,
362   },
363   /* tagLABEL */
364   {
365     NULL,
366     NULL,
367   },
368   /* tagBLOCKQUOTE */
369   {
370     s_jxhtml_start_blockquote_tag,
371     s_jxhtml_end_blockquote_tag,
372   },
373   /* tagDIR */
374   {
375     s_jxhtml_start_dir_tag,
376     s_jxhtml_end_dir_tag,
377   },
378   /* tagDL */
379   {
380     s_jxhtml_start_dl_tag,
381     s_jxhtml_end_dl_tag,
382   },
383   /* tagDD */
384   {
385     s_jxhtml_start_dd_tag,
386     s_jxhtml_end_dd_tag,
387   },
388   /* tagMENU */
389   {
390     s_jxhtml_start_menu_tag,
391     s_jxhtml_end_menu_tag,
392   },
393   /* tagPLAINTEXT */
394   {
395     s_jxhtml_start_plaintext_tag,
396     s_jxhtml_end_plaintext_tag,
397   },
398   /* tagBLINK */
399   {
400     s_jxhtml_start_blink_tag,
401     s_jxhtml_end_blink_tag,
402   },
403   /* tagMARQUEE */
404   {
405     s_jxhtml_start_marquee_tag,
406     s_jxhtml_end_marquee_tag,
407   },
408   /* tagLINK */
409   {
410     s_jxhtml_link_tag,
411     NULL,
412   },
413   /* tagNLMARK */
414   {
415     s_jxhtml_newline_mark,
416     NULL,
417   },
418 };
419
420
421 /**
422  * converts from CHTML5.0 to JXHTML.
423  *
424  * @param r     [i]   Requet_rec is appointed.
425  * @param spec  [i]   The result of the device specification processing which 
426  *                    was done in advance is appointed.
427  * @param src   [i]   The character string before the converting is appointed.
428  * @return The character string after the converting is returned.
429  */
430 char *
431 chxj_convert_jxhtml(
432   request_rec         *r,
433   device_table        *spec,
434   const char          *src,
435   apr_size_t          srclen,
436   apr_size_t          *dstlen,
437   chxjconvrule_entry  *entryp,
438   cookie_t            *cookie
439 )
440 {
441   char      *dst;
442   char      *ss;
443   jxhtml_t   jxhtml;
444   Doc       doc;
445
446   dst = NULL;
447
448   /*--------------------------------------------------------------------------*/
449   /* If qrcode xml                                                            */
450   /*--------------------------------------------------------------------------*/
451   *dstlen = srclen;
452   dst = chxj_qr_code_blob_handler(r, src, (size_t*)dstlen);
453   if (dst) {
454     DBG(r,"I found qrcode xml");
455     return dst;
456   }
457   DBG(r,"not found qrcode xml");
458
459   /*--------------------------------------------------------------------------*/
460   /* The CHTML structure is initialized.                                      */
461   /*--------------------------------------------------------------------------*/
462   s_init_jxhtml(&jxhtml, &doc, r, spec);
463
464   jxhtml.entryp = entryp;
465   jxhtml.cookie = cookie;
466
467   chxj_set_content_type(r, chxj_header_inf_set_content_type(r, "application/xhtml+xml; charset=Windows-31J"));
468
469   /*--------------------------------------------------------------------------*/
470   /* The character string of the input is analyzed.                           */
471   /*--------------------------------------------------------------------------*/
472   qs_init_malloc(&doc);
473   qs_init_root_node(&doc);
474
475   ss = apr_pcalloc(r->pool, srclen + 1);
476
477   memset(ss,   0, srclen + 1);
478   memcpy(ss, src, srclen);
479
480   if (IS_CSS_ON(jxhtml.entryp)) {
481     /* current property list */
482     jxhtml.css_prop_stack = chxj_new_prop_list_stack(&doc);
483   }
484 #ifdef DUMP_LOG
485   chxj_dump_out("[src] CHTML -> JXHTML", ss, srclen);
486 #endif
487
488   qs_parse_string(&doc,ss,strlen(ss));
489
490   chxj_buffered_write_init(r->pool, &doc.buf);
491   /*--------------------------------------------------------------------------*/
492   /* It converts it from CHTML to JXHTML.                                     */
493   /*--------------------------------------------------------------------------*/
494   chxj_node_convert(spec,r,(void*)&jxhtml, &doc, qs_get_root(&doc), 0);
495   jxhtml.out = chxj_buffered_write_flush(jxhtml.out, &doc.buf);
496   dst = apr_pstrdup(r->pool, jxhtml.out);
497   chxj_buffered_write_terminate(&doc.buf);
498
499
500   qs_all_free(&doc,QX_LOGMARK);
501
502   if (! dst) 
503     return apr_pstrdup(r->pool,ss);
504
505   if (! strlen(dst)) 
506     dst = apr_psprintf(r->pool, "\n");
507
508   *dstlen = strlen(dst);
509
510 #ifdef DUMP_LOG
511   chxj_dump_out("[dst] CHTML -> JXHTML", dst, *dstlen);
512 #endif
513
514   return dst;
515 }
516
517
518 /**
519  * The JXHTML structure is initialized.
520  *
521  * @param jxhtml [i/o] The pointer to the JXHTML structure that wants to be
522  *                   initialized is specified.
523  * @param doc   [i]   The Doc structure that should be set to the initialized
524  *                   JXHTML structure is specified.
525  * @param r     [i]   To use POOL, the pointer to request_rec is specified.
526  * @param spec  [i]   The pointer to the device_table
527  */
528 static void
529 s_init_jxhtml(jxhtml_t *jxhtml, Doc *doc, request_rec *r, device_table *spec)
530 {
531   memset(doc,   0, sizeof(Doc));
532   memset(jxhtml, 0, sizeof(jxhtml_t));
533
534   doc->r      = r;
535   jxhtml->doc  = doc;
536   jxhtml->spec = spec;
537   jxhtml->out  = qs_alloc_zero_byte_string(r->pool);
538   jxhtml->conf = chxj_get_module_config(r->per_dir_config, &chxj_module);
539   jxhtml->doc->parse_mode = PARSE_MODE_CHTML;
540 }
541
542
543 /**
544  * Corresponding EMOJI to a current character-code is retrieved. 
545  * The substitution character string is stored in the rslt pointer if agreeing.
546  *
547  * @param jxhtml   [i]   The pointer to the JXHTML structure is specified. 
548  * @param txt     [i]   The character string to want to examine whether it is 
549  *                      EMOJI is specified. 
550  * @param rslt    [o]   The pointer to the pointer that stores the result is 
551  *                      specified. 
552  * @return When corresponding EMOJI exists, it returns it excluding 0. 
553  */
554 static int
555 s_jxhtml_search_emoji(jxhtml_t *jxhtml, char *txt, char **rslt)
556 {
557   emoji_t       *ee;
558   request_rec   *r;
559   device_table  *spec;
560   int           len;
561
562   spec = jxhtml->spec;
563
564   len = strlen(txt);
565   r = jxhtml->doc->r;
566
567   if (! spec) DBG(r,"spec is NULL");
568
569   for (ee = jxhtml->conf->emoji;
570        ee;
571        ee = ee->next) {
572
573     unsigned char hex1byte;
574     unsigned char hex2byte;
575
576     if (! ee->imode) { 
577       DBG(r,"emoji->imode is NULL");
578       continue;
579     }
580
581     hex1byte = ee->imode->hex1byte & 0xff;
582     hex2byte = ee->imode->hex2byte & 0xff;
583
584     if (ee->imode->string
585     &&  strlen(ee->imode->string) > 0
586     &&  strncasecmp(ee->imode->string, txt, strlen(ee->imode->string)) == 0) {
587       if (spec == NULL || spec->emoji_type == NULL) {
588         *rslt = apr_psprintf(r->pool,"\e%s\ f", ee->jphone->string);
589         return strlen(ee->imode->string);
590       }
591
592       return 0;
593     }
594
595     if (len >= 2
596     && ((unsigned char)txt[0] & 0xff) == ((unsigned char)hex1byte)
597     && ((unsigned char)txt[1] & 0xff) == ((unsigned char)hex2byte)) {
598       if (spec == NULL || spec->emoji_type == NULL) {
599         *rslt = apr_psprintf(r->pool,"\e%s\ f", ee->jphone->string);
600         return 2;
601       }
602
603       return 0;
604     }
605   }
606
607   return 0;
608 }
609
610
611 char *
612 chxj_jxhtml_emoji_only_converter(request_rec *r, device_table *spec, const char *src, apr_size_t len)
613 {
614   apr_size_t ii;
615   Doc __doc;
616   Doc *doc;
617   jxhtml_t __jxhtml;
618   jxhtml_t *jxhtml;
619   char one_byte[2];
620   char two_byte[3];
621   apr_pool_t *pool;
622
623   jxhtml = &__jxhtml;
624   doc    = &__doc;
625
626   DBG(r, "REQ[%X] start chxj_jxhtml_emoji_eonly_converter()", (unsigned int)(apr_size_t)r);
627   memset(doc,    0, sizeof(Doc));
628   memset(jxhtml, 0, sizeof(jxhtml_t));
629
630   doc->r       = r;
631   jxhtml->doc  = doc;
632   jxhtml->spec = spec;
633   jxhtml->out  = qs_alloc_zero_byte_string(r->pool);
634   jxhtml->conf = chxj_get_module_config(r->per_dir_config, &chxj_module);
635   jxhtml->doc->parse_mode = PARSE_MODE_CHTML;
636
637   apr_pool_create(&pool, r->pool);
638
639   chxj_buffered_write_init(pool, &doc->buf);
640
641   for (ii=0; ii<len; ii++) {
642     char *out;
643     int   rtn;
644
645     rtn = s_jxhtml_search_emoji(jxhtml, (char *)&src[ii], &out);
646     if (rtn) {
647       W_V(out);
648       ii+=(rtn - 1);
649       continue;
650     }
651
652     if (is_sjis_kanji(src[ii])) {
653       two_byte[0] = src[ii+0];
654       two_byte[1] = src[ii+1];
655       two_byte[2] = 0;
656       W_V(two_byte);
657       ii++;
658     }
659     else {
660       one_byte[0] = src[ii+0];
661       one_byte[1] = 0;
662       W_V(one_byte);
663     }
664   }
665   jxhtml->out = chxj_buffered_write_flush(jxhtml->out, &doc->buf);
666
667   DBG(r, "REQ[%X] end chxj_jxhtml_emoji_eonly_converter()", (unsigned int)(apr_size_t)r);
668   return jxhtml->out;
669 }
670
671
672 /**
673  * It is a handler who processes the HTML tag.
674  *
675  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
676  *                     destination is specified.
677  * @param node   [i]   The HTML tag node is specified.
678  * @return The conversion result is returned.
679  */
680 static char *
681 s_jxhtml_start_html_tag(void *pdoc, Node *UNUSED(node)) 
682 {
683   jxhtml_t       *jxhtml;
684   Doc           *doc;
685   request_rec   *r;
686
687
688   jxhtml  = GET_JXHTML(pdoc);
689   doc    = jxhtml->doc;
690   r      = doc->r;
691   DBG(r, "REQ[%X] start s_jxhtml_start_html_tag()", TO_ADDR(r));
692
693   W_L("<?xml version=\"1.0\" encoding=\"Shift_JIS\" ?>");
694   W_NLCODE();
695   W_L("<!DOCTYPE html PUBLIC \"-//J-PHONE//DTD XHTML Basic 1.0 Plus//EN\" \"xhtml-basic10-plus.dtd\">");
696   W_NLCODE();
697
698   /*--------------------------------------------------------------------------*/
699   /* start HTML tag                                                           */
700   /*--------------------------------------------------------------------------*/
701   W_L("<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"ja\" xml:lang=\"ja\">");
702
703   jxhtml->start_html_flag = 1;
704
705   DBG(r, "REQ[%X] end s_jxhtml_start_html_tag()", TO_ADDR(r));
706
707   return jxhtml->out;
708 }
709
710
711 /**
712  * It is a handler who processes the HTML tag.
713  *
714  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
715  *                     destination is specified.
716  * @param node   [i]   The HTML tag node is specified.
717  * @return The conversion result is returned.
718  */
719 static char *
720 s_jxhtml_end_html_tag(void *pdoc, Node *UNUSED(child)) 
721 {
722   jxhtml_t      *jxhtml = GET_JXHTML(pdoc);
723   Doc           *doc = jxhtml->doc;
724
725   W_L("</html>");
726
727   return jxhtml->out;
728 }
729
730
731 /**
732  * It is a handler who processes the META tag.
733  *
734  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
735  *                     destination is specified.
736  * @param node   [i]   The META tag node is specified.
737  * @return The conversion result is returned.
738  */
739 static char *
740 s_jxhtml_start_meta_tag(void *pdoc, Node *node) 
741 {
742   jxhtml_t     *jxhtml;
743   Doc          *doc;
744   request_rec  *r;
745   Attr         *attr;
746   int          content_type_flag;
747   int          refresh_flag;
748
749   jxhtml             = GET_JXHTML(pdoc);
750   doc               = jxhtml->doc;
751   r                 = doc->r;
752   refresh_flag      = 0;
753   content_type_flag = 0;
754
755   W_L("<meta");
756   /*--------------------------------------------------------------------------*/
757   /* Get Attributes                                                           */
758   /*--------------------------------------------------------------------------*/
759   for (attr = qs_get_attr(doc,node);
760        attr;
761        attr = qs_get_next_attr(doc,attr)) {
762     char *name   = qs_get_attr_name(doc,attr);
763     char *value  = qs_get_attr_value(doc,attr);
764     switch(*name) {
765     case 'h':
766     case 'H':
767       if (strcasecmp(name, "http-equiv") == 0 && value && *value) {
768         /*----------------------------------------------------------------------*/
769         /* CHTML 2.0                                                            */
770         /*----------------------------------------------------------------------*/
771         W_L(" http-equiv=\"");
772         W_V(value);
773         W_L("\"");
774         if (STRCASEEQ('c','C',"content-type",value)) {
775           content_type_flag = 1;
776         }
777         if (STRCASEEQ('r','R',"refresh",value)) {
778           refresh_flag = 1;
779         }
780       }
781       break;
782
783     case 'c':
784     case 'C':
785       if (strcasecmp(name, "content") == 0 && value && *value) {
786         /*----------------------------------------------------------------------*/
787         /* CHTML 2.0                                                            */
788         /*----------------------------------------------------------------------*/
789         if (content_type_flag)  {
790           W_L(" ");
791           W_V(name);
792           W_L("=\"");
793           W_V(chxj_header_inf_set_content_type(r, "application/xhtml+xml; charset=SHIFT_JIS"));
794           W_L("\"");
795         }
796         else
797         if (refresh_flag) {
798           char *buf;
799           char *sec;
800           char *url;
801   
802           buf = apr_pstrdup(r->pool, value);
803   
804           url = strchr(buf, ';');
805           if (url) {
806             sec = apr_pstrdup(r->pool, buf);
807             sec[url-buf] = 0;
808             url++;
809             url = chxj_encoding_parameter(r, url, 1);
810             W_L(" ");
811             W_V(name);
812             W_L("=\"");
813             W_V(sec);
814             W_L(";");
815             W_V(url);
816             W_L("\"");
817           }
818         }
819         else {
820           W_L(" ");
821           W_V(name);
822           W_L("=\"");
823           W_V(value);
824           W_L("\"");
825         }
826       }
827       break;
828     
829     default:
830       break;
831     }
832   }
833   W_L(" />");
834   return jxhtml->out;
835 }
836
837
838 /**
839  * It is a handler who processes the META tag.
840  *
841  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
842  *                     destination is specified.
843  * @param node   [i]   The META tag node is specified.
844  * @return The conversion result is returned.
845  */
846 static char *
847 s_jxhtml_end_meta_tag(void *pdoc, Node *UNUSED(child)) 
848 {
849   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
850
851   return jxhtml->out;
852 }
853
854
855 /**
856  * It is a handler who processes the HEAD tag.
857  *
858  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
859  *                     destination is specified.
860  * @param node   [i]   The HEAD tag node is specified.
861  * @return The conversion result is returned.
862  */
863 static char *
864 s_jxhtml_start_head_tag(void *pdoc, Node *UNUSED(node)) 
865 {
866   jxhtml_t      *jxhtml;
867   Doc           *doc;
868   request_rec   *r;
869
870   jxhtml = GET_JXHTML(pdoc);
871   doc   = jxhtml->doc;
872   r     = doc->r;
873
874   W_L("<head>");
875   return jxhtml->out;
876 }
877
878
879 /**
880  * It is a handler who processes the HEAD tag.
881  *
882  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
883  *                     destination is specified.
884  * @param node   [i]   The HEAD tag node is specified.
885  * @return The conversion result is returned.
886  */
887 static char *
888 s_jxhtml_end_head_tag(void *pdoc, Node *UNUSED(child)) 
889 {
890   jxhtml_t       *jxhtml;
891   Doc           *doc;
892   request_rec   *r;
893
894   jxhtml = GET_JXHTML(pdoc);
895   doc   = jxhtml->doc;
896   r     = doc->r;
897
898   W_L("</head>");
899   return jxhtml->out;
900 }
901
902
903 /**
904  * It is a handler who processes the TITLE tag.
905  *
906  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
907  *                     destination is specified.
908  * @param node   [i]   The TITLE tag node is specified.
909  * @return The conversion result is returned.
910  */
911 static char *
912 s_jxhtml_start_title_tag(void *pdoc, Node *UNUSED(node)) 
913 {
914   jxhtml_t      *jxhtml;
915   Doc          *doc;
916   request_rec  *r;
917
918   jxhtml = GET_JXHTML(pdoc);
919   doc   = jxhtml->doc;
920   r     = doc->r;
921
922   W_L("<title>");
923   return jxhtml->out;
924 }
925
926
927 /**
928  * It is a handler who processes the TITLE tag.
929  *
930  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
931  *                     destination is specified.
932  * @param node   [i]   The TITLE tag node is specified.
933  * @return The conversion result is returned.
934  */
935 static char *
936 s_jxhtml_end_title_tag(void *pdoc, Node *UNUSED(child)) 
937 {
938   jxhtml_t      *jxhtml;
939   Doc           *doc;
940   request_rec   *r;
941
942   jxhtml = GET_JXHTML(pdoc);
943   doc   = jxhtml->doc;
944   r     = doc->r;
945
946   W_L("</title>");
947   return jxhtml->out;
948 }
949
950
951 /**
952  * It is a handler who processes the BASE tag.
953  *
954  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
955  *                     destination is specified.
956  * @param node   [i]   The BASE tag node is specified.
957  * @return The conversion result is returned.
958  */
959 static char *
960 s_jxhtml_start_base_tag(void *pdoc, Node *node) 
961 {
962   jxhtml_t      *jxhtml;
963   Attr          *attr;
964   Doc           *doc;
965   request_rec   *r;
966
967   jxhtml = GET_JXHTML(pdoc);
968   doc   = jxhtml->doc;
969   r     = doc->r;
970
971   W_L("<base");
972   /*--------------------------------------------------------------------------*/
973   /* Get Attributes                                                           */
974   /*--------------------------------------------------------------------------*/
975   for (attr = qs_get_attr(doc,node);
976        attr;
977        attr = qs_get_next_attr(doc,attr)) {
978     char *name  = qs_get_attr_name(doc,attr);
979     char *value = qs_get_attr_value(doc,attr);
980     if (STRCASEEQ('h','H',"href",name)) {
981       W_L(" href=\"");
982       W_V(value);
983       W_L("\"");
984     }
985   }
986   W_L(" />");
987   return jxhtml->out;
988 }
989
990
991 /**
992  * It is a handler who processes the BASE tag.
993  *
994  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
995  *                     destination is specified.
996  * @param node   [i]   The BASE tag node is specified.
997  * @return The conversion result is returned.
998  */
999 static char *
1000 s_jxhtml_end_base_tag(void *pdoc, Node *UNUSED(child)) 
1001 {
1002   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
1003   return jxhtml->out;
1004 }
1005
1006
1007 /**
1008  * It is a handler who processes the BODY tag.
1009  *
1010  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
1011  *                     destination is specified.
1012  * @param node   [i]   The BODY tag node is specified.
1013  * @return The conversion result is returned.
1014  */
1015 static char *
1016 s_jxhtml_start_body_tag(void *pdoc, Node *node) 
1017 {
1018   jxhtml_t    *jxhtml;
1019   Doc         *doc;
1020   request_rec *r;
1021   Attr        *attr;
1022   char        *attr_bgcolor = NULL;
1023   char        *attr_text    = NULL;
1024   char        *attr_link    = NULL;
1025   char        *attr_style   = NULL;
1026
1027   jxhtml = GET_JXHTML(pdoc);
1028   doc   = jxhtml->doc;
1029   r     = doc->r;
1030
1031   /*--------------------------------------------------------------------------*/
1032   /* Get Attributes                                                           */
1033   /*--------------------------------------------------------------------------*/
1034   for (attr = qs_get_attr(doc,node);
1035        attr;
1036        attr = qs_get_next_attr(doc,attr)) {
1037     char *name   = qs_get_attr_name(doc,attr);
1038     char *value  = qs_get_attr_value(doc,attr);
1039     if (STRCASEEQ('b','B',"bgcolor",name) && value && *value) {
1040       /*----------------------------------------------------------------------*/
1041       /* CHTML 2.0                                                            */
1042       /*----------------------------------------------------------------------*/
1043       attr_bgcolor = value;
1044     }
1045     else if (STRCASEEQ('t','T',"text",name) && value && *value) {
1046       /*----------------------------------------------------------------------*/
1047       /* CHTML 2.0                                                            */
1048       /*----------------------------------------------------------------------*/
1049       attr_text = value;
1050     }
1051     else if (STRCASEEQ('l','L',"link",name) && value && *value) {
1052       /*----------------------------------------------------------------------*/
1053       /* CHTML 2.0                                                            */
1054       /*----------------------------------------------------------------------*/
1055       attr_link = value;
1056     }
1057     else if (STRCASEEQ('a','A',"alink",name)) {
1058       /*----------------------------------------------------------------------*/
1059       /* CHTML 4.0                                                            */
1060       /*----------------------------------------------------------------------*/
1061       /* ignore */
1062     }
1063     else if (STRCASEEQ('v','V',"vlink",name)) {
1064       /*----------------------------------------------------------------------*/
1065       /* CHTML 4.0                                                            */
1066       /*----------------------------------------------------------------------*/
1067       /* ignore */
1068     }
1069     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
1070       attr_style = value;
1071     }
1072   }
1073
1074   if (IS_CSS_ON(jxhtml->entryp)) {
1075     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
1076     if (style) {
1077       css_property_t *color_prop      = chxj_css_get_property_value(doc, style, "color");
1078       css_property_t *bgcolor_prop    = chxj_css_get_property_value(doc, style, "background-color");
1079       css_property_t *cur;
1080       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
1081         if (cur->value && *cur->value) {
1082           attr_text = apr_pstrdup(doc->pool, cur->value);
1083         }
1084       }
1085       for (cur = bgcolor_prop->next; cur != bgcolor_prop; cur = cur->next) {
1086         if (cur->value && *cur->value) {
1087           attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
1088         }
1089       }
1090     }
1091     if (jxhtml->style) {
1092       css_stylesheet_t *pseudos = chxj_find_pseudo_selectors(doc, jxhtml->style);
1093       css_selector_t *cur_sel;
1094       for (cur_sel = pseudos->selector_head.next; cur_sel != &pseudos->selector_head; cur_sel = cur_sel->next) {
1095         if (cur_sel->name && strcasecmp(cur_sel->name, "a:link") == 0) {
1096           css_property_t *cur;
1097           for (cur = cur_sel->property_head.next; cur != &cur_sel->property_head; cur = cur->next) {
1098             if (cur->name && strcasecmp(cur->name, "color") == 0) {
1099               attr_link = apr_pstrdup(doc->pool, cur->value);
1100             }
1101           }
1102         }
1103       }
1104     }
1105   }
1106
1107
1108   W_L("<body");
1109   if (attr_bgcolor || attr_text) {
1110     W_L(" style=\"");
1111     if (attr_bgcolor) {
1112       attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
1113       W_L("background-color:");
1114       W_V(attr_bgcolor);
1115       W_L(";");
1116     }
1117     if (attr_text) {
1118       attr_text = chxj_css_rgb_func_to_value(doc->pool, attr_text);
1119       W_L("color:");
1120       W_V(attr_text);
1121       W_L(";");
1122     }
1123     W_L("\"");
1124   }
1125   if (attr_link) {
1126     attr_link = chxj_css_rgb_func_to_value(doc->pool, attr_link);
1127     W_L(" link=\"");
1128     W_V(attr_link);
1129     W_L("\"");
1130   }
1131   W_L("><div>");
1132   return jxhtml->out;
1133 }
1134
1135
1136 /**
1137  * It is a handler who processes the BODY tag.
1138  *
1139  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
1140  *                     destination is specified.
1141  * @param node   [i]   The BODY tag node is specified.
1142  * @return The conversion result is returned.
1143  */
1144 static char *
1145 s_jxhtml_end_body_tag(void *pdoc, Node *UNUSED(child)) 
1146 {
1147   jxhtml_t       *jxhtml;
1148   Doc           *doc;
1149   request_rec   *r;
1150
1151   jxhtml = GET_JXHTML(pdoc);
1152   doc   = jxhtml->doc;
1153   r     = doc->r;
1154
1155   W_L("</div></body>");
1156   if (IS_CSS_ON(jxhtml->entryp)) {
1157     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
1158   }
1159   return jxhtml->out;
1160 }
1161
1162
1163 /**
1164  * It is a handler who processes the A tag.
1165  *
1166  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
1167  *                     destination is specified.
1168  * @param node   [i]   The A tag node is specified.
1169  * @return The conversion result is returned.
1170  */
1171 static char *
1172 s_jxhtml_start_a_tag(void *pdoc, Node *node) 
1173 {
1174   jxhtml_t    *jxhtml;
1175   Doc         *doc;
1176   request_rec *r;
1177   Attr        *attr;
1178   char        *attr_style = NULL;
1179
1180   jxhtml = GET_JXHTML(pdoc);
1181   doc   = jxhtml->doc;
1182   r     = doc->r;
1183
1184   W_L("<a");
1185   /*--------------------------------------------------------------------------*/
1186   /* Get Attributes                                                           */
1187   /*--------------------------------------------------------------------------*/
1188   for (attr = qs_get_attr(doc,node);
1189        attr; 
1190        attr = qs_get_next_attr(doc,attr)) {
1191     char *name  = qs_get_attr_name(doc,attr);
1192     char *value = qs_get_attr_value(doc,attr);
1193     if (STRCASEEQ('n','N',"name",name)) {
1194       /*----------------------------------------------------------------------*/
1195       /* CHTML1.0                                                             */
1196       /*----------------------------------------------------------------------*/
1197       W_L(" name=\"");
1198       W_V(chxj_jreserved_to_safe_tag(r, value, jxhtml->entryp));
1199       W_L("\"");
1200     }
1201     else if (STRCASEEQ('h','H',"href",name)) {
1202       /*----------------------------------------------------------------------*/
1203       /* CHTML1.0                                                             */
1204       /*----------------------------------------------------------------------*/
1205       value = chxj_encoding_parameter(r, value, 1);
1206       if (! chxj_starts_with(value, "mailto:") && ! chxj_starts_with(value, "tel:")) {
1207         value = chxj_jreserved_tag_to_safe_for_query_string(r, value, jxhtml->entryp, 1);
1208       }
1209       W_L(" href=\"");
1210       W_V(value);
1211       W_L("\"");
1212     }
1213     else if (STRCASEEQ('a','A',"accesskey",name)) {
1214       /*----------------------------------------------------------------------*/
1215       /* CHTML1.0                                                             */
1216       /*----------------------------------------------------------------------*/
1217       W_L(" accesskey=\"");
1218       W_V(value);
1219       W_L("\"");
1220     }
1221     else if (STRCASEEQ('c','C',"cti",name)) {
1222       /*----------------------------------------------------------------------*/
1223       /* CHTML 2.0                                                            */
1224       /*----------------------------------------------------------------------*/
1225       W_L(" cti=\"");
1226       W_V(value);
1227       W_L("\"");
1228     }
1229     else if (STRCASEEQ('i','I',"ijam",name)) {
1230       /*----------------------------------------------------------------------*/
1231       /* CHTML 3.0                                                            */
1232       /*----------------------------------------------------------------------*/
1233       /* ignore */
1234     }
1235     else if (STRCASEEQ('u','U',"utn",name)) {
1236       /*----------------------------------------------------------------------*/
1237       /* CHTML 3.0                                                            */
1238       /* It is special only for CHTML.                                        */
1239       /*----------------------------------------------------------------------*/
1240       W_L(" utn ");
1241     }
1242     else if (STRCASEEQ('t','T',"telbook",name)) {
1243       /*----------------------------------------------------------------------*/
1244       /* CHTML 3.0                                                            */
1245       /*----------------------------------------------------------------------*/
1246       /* not support */
1247     }
1248     else if (STRCASEEQ('k','K',"kana",name)) {
1249       /*----------------------------------------------------------------------*/
1250       /* CHTML 3.0                                                            */
1251       /*----------------------------------------------------------------------*/
1252       /* not support */
1253     }
1254     else if (STRCASEEQ('e','E',"email",name)) {
1255       /*----------------------------------------------------------------------*/
1256       /* CHTML 3.0                                                            */
1257       /*----------------------------------------------------------------------*/
1258       /* not support */
1259     }
1260     else if (STRCASEEQ('i','I',"ista",name)) {
1261       /*----------------------------------------------------------------------*/
1262       /* CHTML 4.0                                                            */
1263       /*----------------------------------------------------------------------*/
1264       /* ignore */
1265     }
1266     else if (STRCASEEQ('i','I',"ilet",name)) {
1267       /*----------------------------------------------------------------------*/
1268       /* CHTML 5.0                                                            */
1269       /*----------------------------------------------------------------------*/
1270       /* ignore */
1271     }
1272     else if (STRCASEEQ('i','I',"iswf",name)) {
1273       /*----------------------------------------------------------------------*/
1274       /* CHTML 5.0                                                            */
1275       /*----------------------------------------------------------------------*/
1276       /* ignore */
1277     }
1278     else if (STRCASEEQ('i','I',"irst",name)) {
1279       /*----------------------------------------------------------------------*/
1280       /* CHTML 5.0                                                            */
1281       /*----------------------------------------------------------------------*/
1282       /* ignore */
1283     }
1284     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
1285       /*----------------------------------------------------------------------*/
1286       /* CHTML 5.0                                                            */
1287       /*----------------------------------------------------------------------*/
1288       attr_style = value;
1289     }
1290   }
1291   W_L(">");
1292
1293   if (IS_CSS_ON(jxhtml->entryp)) {
1294     s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
1295   }
1296
1297   return jxhtml->out;
1298 }
1299
1300
1301 /**
1302  * It is a handler who processes the A tag.
1303  *
1304  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
1305  *                     destination is specified.
1306  * @param node   [i]   The A tag node is specified.
1307  * @return The conversion result is returned.
1308  */
1309 static char *
1310 s_jxhtml_end_a_tag(void *pdoc, Node *UNUSED(child)) 
1311 {
1312   jxhtml_t      *jxhtml;
1313   Doc          *doc;
1314   request_rec  *r;
1315
1316   jxhtml = GET_JXHTML(pdoc);
1317   doc   = jxhtml->doc;
1318   r     = doc->r;
1319
1320   W_L("</a>");
1321
1322   if (IS_CSS_ON(jxhtml->entryp)) {
1323     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
1324   }
1325
1326   return jxhtml->out;
1327 }
1328
1329
1330 /**
1331  * It is a handler who processes the BR tag.
1332  *
1333  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
1334  *                     destination is specified.
1335  * @param node   [i]   The BR tag node is specified.
1336  * @return The conversion result is returned.
1337  */
1338 static char *
1339 s_jxhtml_start_br_tag(void *pdoc, Node *node)
1340 {
1341   jxhtml_t     *jxhtml;
1342   Doc          *doc;
1343   request_rec  *r;
1344   Attr         *attr;
1345
1346   jxhtml = GET_JXHTML(pdoc);
1347   doc   = jxhtml->doc;
1348   r     = doc->r;
1349
1350   W_L("<br");
1351   /*--------------------------------------------------------------------------*/
1352   /* Get Attributes                                                           */
1353   /*--------------------------------------------------------------------------*/
1354   for (attr = qs_get_attr(doc,node);
1355        attr;
1356        attr = qs_get_next_attr(doc,attr)) {
1357     char *name  = qs_get_attr_name(doc,attr);
1358     char *value = qs_get_attr_value(doc,attr);
1359     if (STRCASEEQ('c','C',"clear",name)) {
1360       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('a','A',"all",value))) {
1361         W_L(" clear=\"");
1362         W_V(value);
1363         W_L("\"");
1364       }
1365     }
1366   }
1367   W_L(" />");
1368   return jxhtml->out;
1369 }
1370
1371
1372 /**
1373  * It is a handler who processes the BR tag.
1374  *
1375  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
1376  *                     destination is specified.
1377  * @param node   [i]   The BR tag node is specified.
1378  * @return The conversion result is returned.
1379  */
1380 static char *
1381 s_jxhtml_end_br_tag(void *pdoc, Node *UNUSED(child)) 
1382 {
1383   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
1384   return jxhtml->out;
1385 }
1386
1387
1388 /**
1389  * It is a handler who processes the TR tag.
1390  *
1391  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
1392  *                     destination is specified.
1393  * @param node   [i]   The TR tag node is specified.
1394  * @return The conversion result is returned.
1395  */
1396 static char *
1397 s_jxhtml_start_tr_tag(void *pdoc, Node *UNUSED(node)) 
1398 {
1399   jxhtml_t      *jxhtml;
1400   Doc          *doc;
1401   request_rec  *r;
1402
1403   jxhtml = GET_JXHTML(pdoc);
1404   doc   = jxhtml->doc;
1405   r     = doc->r;
1406
1407   W_L("<br />");
1408   return jxhtml->out;
1409 }
1410
1411
1412 /**
1413  * It is a handler who processes the TR tag.
1414  *
1415  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
1416  *                     destination is specified.
1417  * @param node   [i]   The TR tag node is specified.
1418  * @return The conversion result is returned.
1419  */
1420 static char *
1421 s_jxhtml_end_tr_tag(void *pdoc, Node *UNUSED(child)) 
1422 {
1423   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
1424   return jxhtml->out;
1425 }
1426
1427
1428 /**
1429  * It is a handler who processes the FONT tag.
1430  *
1431  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
1432  *                     destination is specified.
1433  * @param node   [i]   The FONT tag node is specified.
1434  * @return The conversion result is returned.
1435  */
1436 static char *
1437 s_jxhtml_start_font_tag(void *pdoc, Node *node) 
1438 {
1439   jxhtml_t      *jxhtml;
1440   Doc           *doc;
1441   request_rec   *r;
1442   Attr          *attr;
1443   char          *attr_color = NULL;
1444   char          *attr_size  = NULL;
1445   char          *attr_style = NULL;
1446
1447   jxhtml = GET_JXHTML(pdoc);
1448   doc   = jxhtml->doc;
1449   r     = doc->r;
1450
1451   /*--------------------------------------------------------------------------*/
1452   /* Get Attributes                                                           */
1453   /*--------------------------------------------------------------------------*/
1454   for (attr = qs_get_attr(doc,node);
1455        attr; 
1456        attr = qs_get_next_attr(doc,attr)) {
1457     char *name  = qs_get_attr_name(doc,attr);
1458     char *value = qs_get_attr_value(doc,attr);
1459     if (STRCASEEQ('c','C',"color",name) && value && *value) {
1460       attr_color = apr_pstrdup(doc->buf.pool, value);
1461     }
1462     else if (STRCASEEQ('s','S',"size",name) && value && *value) {
1463       /*----------------------------------------------------------------------*/
1464       /* CHTML 5.0                                                            */
1465       /*----------------------------------------------------------------------*/
1466       attr_size = apr_pstrdup(doc->buf.pool, value);
1467     }
1468     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
1469       attr_style = apr_pstrdup(doc->buf.pool, value);
1470     }
1471   }
1472   if (IS_CSS_ON(jxhtml->entryp)) {
1473     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
1474     if (style) {
1475       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
1476       css_property_t *size_prop  = chxj_css_get_property_value(doc, style, "font-size");
1477       css_property_t *cur;
1478       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
1479         if (cur->value && *cur->value) {
1480           attr_color = apr_pstrdup(doc->pool, cur->value);
1481         }
1482       }
1483       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
1484         if (cur->value && *cur->value) {
1485           attr_size = apr_pstrdup(doc->pool, cur->value);
1486           if (STRCASEEQ('x','X',"xx-small",attr_size)) {
1487             attr_size = apr_pstrdup(doc->pool, "1");
1488           }
1489           else if (STRCASEEQ('x','X',"x-small",attr_size)) {
1490             attr_size = apr_pstrdup(doc->pool, "2");
1491           }
1492           else if (STRCASEEQ('s','S',"small",attr_size)) {
1493             attr_size = apr_pstrdup(doc->pool, "3");
1494           }
1495           else if (STRCASEEQ('m','M',"medium",attr_size)) {
1496             attr_size = apr_pstrdup(doc->pool, "4");
1497           }
1498           else if (STRCASEEQ('l','L',"large",attr_size)) {
1499             attr_size = apr_pstrdup(doc->pool, "5");
1500           }
1501           else if (STRCASEEQ('x','X',"x-large",attr_size)) {
1502             attr_size = apr_pstrdup(doc->pool, "6");
1503           }
1504           else if (STRCASEEQ('x','X',"xx-large",attr_size)) {
1505             attr_size = apr_pstrdup(doc->pool, "7");
1506           }
1507         }
1508       }
1509     }
1510   }
1511   jxhtml_flags_t *flg = (jxhtml_flags_t *)apr_palloc(doc->pool, sizeof(*flg));
1512   memset(flg, 0, sizeof(*flg));
1513   if (attr_color) {
1514     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
1515     W_L("<font color=\"");
1516     W_V(attr_color);
1517     W_L("\">");
1518     flg->font_color_flag = 1;
1519   }
1520   if (attr_size) {
1521     flg->font_size_flag = 1;
1522     switch(*attr_size) {
1523     case '1': W_L("<span style=\"font-size: xx-small\">"); break;
1524     case '2': W_L("<span style=\"font-size: x-small\">");  break;
1525     case '3': W_L("<span style=\"font-size: small\">");    break;
1526     case '4': W_L("<span style=\"font-size: medium\">");   break;
1527     case '5': W_L("<span style=\"font-size: large\">");    break;
1528     case '6': W_L("<span style=\"font-size: x-large\">");  break;
1529     case '7': W_L("<span style=\"font-size: xx-large\">"); break;
1530     case '-':
1531       if (*(attr_size + 1) == '1') {
1532         W_L("<span style=\"font-size: small\">");
1533         break;
1534       }
1535       if (*(attr_size + 1) == '2') {
1536         W_L("<span style=\"font-size: x-small\">");
1537         break;
1538       }
1539       if (*(attr_size + 1) == '3') {
1540         W_L("<span style=\"font-size: xx-small\">");
1541         break;
1542       }
1543       flg->font_size_flag = 0;
1544       break;
1545
1546     case '+':
1547       if (*(attr_size + 1) == '1') {
1548         W_L("<span style=\"font-size: large\">");
1549         break;
1550       }
1551       if (*(attr_size + 1) == '2') {
1552         W_L("<span style=\"font-size: x-large\">");
1553         break;
1554       }
1555       if (*(attr_size + 1) == '3') {
1556         W_L("<span style=\"font-size: xx-large\">");
1557         break;
1558       }
1559       flg->font_size_flag = 0;
1560       break;
1561
1562     default:
1563       WRN(doc->r, "invlalid font size. [%s] != (1|2|3|4|5|6|7|+1|+2|+3|-1|-2|-3)", attr_size);
1564       flg->font_size_flag = 0;
1565     }
1566   }
1567   node->userData = flg;
1568   return jxhtml->out;
1569 }
1570
1571
1572 /**
1573  * It is a handler who processes the FONT tag.
1574  *
1575  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
1576  *                     destination is specified.
1577  * @param node   [i]   The FONT tag node is specified.
1578  * @return The conversion result is returned.
1579  */
1580 static char *
1581 s_jxhtml_end_font_tag(void *pdoc, Node *node)
1582 {
1583   jxhtml_t      *jxhtml;
1584   request_rec  *r;
1585   Doc          *doc;
1586
1587   jxhtml = GET_JXHTML(pdoc);
1588   doc   = jxhtml->doc;
1589   r     = jxhtml->doc->r;
1590
1591   jxhtml_flags_t *flg = (jxhtml_flags_t *)node->userData;
1592   if (flg && flg->font_size_flag) {
1593     W_L("</span>");
1594   }
1595   if (flg && flg->font_color_flag) {
1596     W_L("</font>");
1597   }
1598   if (IS_CSS_ON(jxhtml->entryp)) {
1599     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
1600   }
1601
1602   return jxhtml->out;
1603 }
1604
1605
1606 /**
1607  * It is a handler who processes the FORM tag.
1608  *
1609  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
1610  *                     destination is specified.
1611  * @param node   [i]   The FORM tag node is specified.
1612  * @return The conversion result is returned.
1613  */
1614 static char *
1615 s_jxhtml_start_form_tag(void *pdoc, Node *node) 
1616 {
1617   jxhtml_t    *jxhtml;
1618   Doc         *doc;
1619   request_rec *r;
1620   Attr        *attr;
1621   char        *attr_action = NULL;
1622   char        *attr_method = NULL;
1623   char        *attr_style  = NULL;
1624   char        *attr_color  = NULL;
1625   char        *attr_align  = NULL;
1626   char        *attr_name   = NULL;
1627   char        *new_hidden_tag = NULL;
1628
1629   jxhtml  = GET_JXHTML(pdoc);
1630   doc     = jxhtml->doc;
1631   r       = doc->r;
1632
1633   /*--------------------------------------------------------------------------*/
1634   /* Get Attributes                                                           */
1635   /*--------------------------------------------------------------------------*/
1636   for (attr = qs_get_attr(doc,node);
1637        attr;
1638        attr = qs_get_next_attr(doc,attr)) {
1639     char *name  = qs_get_attr_name(doc,attr);
1640     char *value = qs_get_attr_value(doc,attr);
1641     switch(*name) {
1642     case 'a':
1643     case 'A':
1644       if (strcasecmp(name, "action") == 0) {
1645         /*--------------------------------------------------------------------*/
1646         /* CHTML 1.0                                                          */
1647         /*--------------------------------------------------------------------*/
1648         attr_action = value;
1649       }
1650       break;
1651
1652     case 'm':
1653     case 'M':
1654       if (strcasecmp(name, "method") == 0) {
1655         /*--------------------------------------------------------------------*/
1656         /* CHTML 1.0                                                          */
1657         /*--------------------------------------------------------------------*/
1658         attr_method = value;
1659       }
1660       break;
1661
1662     case 'n':
1663     case 'N':
1664       if (strcasecmp(name, "name") == 0) {
1665         /*--------------------------------------------------------------------*/
1666         /* CHTML 1.0                                                          */
1667         /*--------------------------------------------------------------------*/
1668         attr_name = value;
1669       }
1670       break;
1671
1672     case 's':
1673     case 'S':
1674       if (strcasecmp(name, "style") == 0) {
1675         attr_style = value;
1676       }
1677       break;
1678
1679     default:
1680       break;
1681     }
1682   }
1683   if (IS_CSS_ON(jxhtml->entryp)) {
1684     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
1685     if (style) {
1686       css_property_t *text_align_prop = chxj_css_get_property_value(doc, style, "text-align");
1687       css_property_t *color_prop      = chxj_css_get_property_value(doc, style, "color");
1688       css_property_t *cur;
1689       for (cur = text_align_prop->next; cur != text_align_prop; cur = cur->next) {
1690         if (STRCASEEQ('l','L',"left", cur->value)) {
1691           attr_align = apr_pstrdup(doc->pool, "left");
1692         }
1693         else if (STRCASEEQ('c','C',"center",cur->value)) {
1694           attr_align = apr_pstrdup(doc->pool, "center");
1695         }
1696         else if (STRCASEEQ('r','R',"right",cur->value)) {
1697           attr_align = apr_pstrdup(doc->pool, "right");
1698         }
1699       }
1700       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
1701         attr_color = apr_pstrdup(doc->pool, cur->value);
1702       }
1703     }
1704   }
1705
1706   int post_flag = (attr_method && strcasecmp(attr_method, "post") == 0) ? 1 : 0;
1707
1708   W_L("<form");
1709   if (attr_action) {
1710     attr_action = chxj_encoding_parameter(r, attr_action, 1);
1711     attr_action = chxj_add_cookie_parameter(r, attr_action, jxhtml->cookie);
1712     char *q;
1713     char *old_qs = NULL;
1714     q = strchr(attr_action, '?');
1715     if (q) {
1716       new_hidden_tag = chxj_form_action_to_hidden_tag(r, doc->pool, attr_action, 1, post_flag, &old_qs, CHXJ_FALSE, CHXJ_TRUE, jxhtml->entryp);
1717       if (new_hidden_tag || old_qs) {
1718         *q = 0;
1719       }
1720     }
1721     W_L(" action=\"");
1722     W_V(attr_action);
1723     if (old_qs) {
1724       W_L("?");
1725       W_V(old_qs);
1726     }
1727     W_L("\"");
1728   }
1729   if (attr_method) {
1730     W_L(" method=\"");
1731     W_V(attr_method);
1732     W_L("\"");
1733   }
1734   if (attr_name) {
1735     W_L(" name=\"");
1736     W_V(attr_name);
1737     W_L("\"");
1738   }
1739   W_L(">");
1740
1741   jxhtml_flags_t *flg = (jxhtml_flags_t *)apr_palloc(doc->pool, sizeof(jxhtml_flags_t));
1742   memset(flg, 0, sizeof(*flg));
1743   if (attr_color) {
1744     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
1745     W_L("<font color=\"");
1746     W_V(attr_color);
1747     W_L("\">");
1748     flg->with_font_flag = 1;
1749   }
1750   if (attr_align) {
1751     W_L("<div align=\"");
1752     W_V(attr_align);
1753     W_L("\">");
1754     flg->with_div_flag = 1;
1755   }
1756   node->userData = flg;
1757   if (new_hidden_tag) {
1758     W_V(new_hidden_tag);
1759   }
1760   return jxhtml->out;
1761 }
1762
1763
1764 /**
1765  * It is a handler who processes the FORM tag.
1766  *
1767  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
1768  *                     destination is specified.
1769  * @param node   [i]   The FORM tag node is specified.
1770  * @return The conversion result is returned.
1771  */
1772 static char *
1773 s_jxhtml_end_form_tag(void *pdoc, Node *node)
1774 {
1775   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
1776   Doc      *doc    = jxhtml->doc;
1777
1778   jxhtml_flags_t *flg = (jxhtml_flags_t *)node->userData;
1779   if (flg && flg->with_div_flag) {
1780     W_L("</div>");
1781   }
1782   if (flg && flg->with_font_flag) {
1783     W_L("</font>");
1784   }
1785   W_L("</form>");
1786   if (IS_CSS_ON(jxhtml->entryp)) {
1787     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
1788   }
1789
1790   return jxhtml->out;
1791 }
1792
1793
1794 /**
1795  * It is a handler who processes the INPUT tag.
1796  *
1797  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
1798  *                     destination is specified.
1799  * @param node   [i]   The INPUT tag node is specified.
1800  * @return The conversion result is returned.
1801  */
1802 static char *
1803 s_jxhtml_start_input_tag(void *pdoc, Node *node) 
1804 {
1805   jxhtml_t    *jxhtml;
1806   Doc         *doc;
1807   request_rec *r;
1808   Attr        *attr;
1809   char        *attr_accesskey  = NULL;
1810   char        *attr_max_length = NULL;
1811   char        *attr_type       = NULL;
1812   char        *attr_name       = NULL;
1813   char        *attr_value      = NULL;
1814   char        *attr_istyle     = NULL;
1815   char        *attr_size       = NULL;
1816   char        *attr_checked    = NULL;
1817   char        *attr_style      = NULL;
1818
1819   jxhtml  = GET_JXHTML(pdoc);
1820   doc     = jxhtml->doc;
1821   r       = doc->r;
1822
1823   /*--------------------------------------------------------------------------*/
1824   /* Get Attributes                                                           */
1825   /*--------------------------------------------------------------------------*/
1826   for (attr = qs_get_attr(doc,node);
1827        attr;
1828        attr = qs_get_next_attr(doc,attr)) {
1829     char *name  = qs_get_attr_name(doc,attr);
1830     char *value = qs_get_attr_value(doc,attr);
1831     if (STRCASEEQ('t','T',"type",name) && value && *value) {
1832       char *tmp_type = qs_trim_string(doc->buf.pool, value);
1833       if (tmp_type && (STRCASEEQ('t','T',"text",    tmp_type) ||
1834                        STRCASEEQ('p','P',"password",tmp_type) ||
1835                        STRCASEEQ('c','C',"checkbox",tmp_type) ||
1836                        STRCASEEQ('r','R',"radio",   tmp_type) ||
1837                        STRCASEEQ('h','H',"hidden",  tmp_type) ||
1838                        STRCASEEQ('s','S',"submit",  tmp_type) ||
1839                        STRCASEEQ('r','R',"reset",   tmp_type))) {
1840         attr_type = tmp_type;
1841       }
1842     }
1843     else if (STRCASEEQ('n','N',"name",name) && value && *value) {
1844       attr_name = value;
1845     }
1846     else if (STRCASEEQ('v','V',"value",name) && value && *value) {
1847       attr_value = value;
1848     }
1849     else if (STRCASEEQ('i','I',"istyle",name) && value && *value) {
1850       attr_istyle = value;
1851     }
1852     else if (STRCASEEQ('m','M',"maxlength",name) && value && *value) {
1853       attr_max_length = value;
1854     }
1855     else if (STRCASEEQ('c','C',"checked", name)) {
1856       attr_checked = value;
1857     }
1858     else if (STRCASEEQ('a','A',"accesskey", name) && value && *value) {
1859       attr_accesskey = value;
1860     }
1861     else if (STRCASEEQ('s','S',"size", name) && value && *value) {
1862       attr_size = value;
1863     }
1864     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
1865       attr_style = value;
1866     }
1867   }
1868
1869   if (IS_CSS_ON(jxhtml->entryp)) {
1870     css_prop_list_t *style = s_jxhtml_nopush_and_get_now_style(pdoc, node, attr_style);
1871     if (style) {
1872       css_property_t *wap_input_format = chxj_css_get_property_value(doc, style, "-wap-input-format");
1873       css_property_t *cur;
1874       for (cur = wap_input_format->next; cur != wap_input_format; cur = cur->next) {
1875         if (strcasestr(cur->value, "<ja:n>")) {
1876           attr_istyle = "4";
1877         }
1878         else if (strcasestr(cur->value, "<ja:en>")) {
1879           attr_istyle = "3";
1880         }
1881         else if (strcasestr(cur->value, "<ja:hk>")) {
1882           attr_istyle = "2";
1883         }
1884         else if (strcasestr(cur->value, "<ja:h>")) {
1885           attr_istyle = "1";
1886         }
1887       }
1888     }
1889   }
1890
1891   W_L("<input");
1892   if (attr_type) {
1893     W_L(" type=\"");
1894     W_V(attr_type);
1895     W_L("\"");
1896   }
1897   if (attr_size) {
1898     W_L(" size=\"");
1899     W_V(attr_size);
1900     W_L("\"");
1901   }
1902   if (attr_name) {
1903     W_L(" name=\"");
1904     W_V(chxj_jreserved_to_safe_tag(r, attr_name, jxhtml->entryp));
1905     W_L("\"");
1906   }
1907   if (attr_value) {
1908     W_L(" value=\"");
1909     W_V(chxj_add_slash_to_doublequote(doc->pool, attr_value));
1910     W_L("\"");
1911   }
1912   if (attr_accesskey) {
1913     W_L(" accesskey=\"");
1914     W_V(attr_accesskey);
1915     W_L("\"");
1916   }
1917   if (attr_istyle && (*attr_istyle == '1' || *attr_istyle == '2' || *attr_istyle == '3' || *attr_istyle == '4')) {
1918     /*------------------------------------------------------------------------*/
1919     /* CHTML 2.0                                                              */
1920     /*------------------------------------------------------------------------*/
1921     if (attr_type && STRCASEEQ('p','P',"password", attr_type) && ! jxhtml->entryp->pc_flag ) {
1922       char *vv = qs_conv_istyle_to_format(doc->buf.pool, "4");
1923       W_L(" style=\"-wap-input-format:&quot;*");
1924       W_V(vv);
1925       W_L("&quot;;\"");
1926     }
1927     else {
1928       char *vv = qs_conv_istyle_to_format(doc->buf.pool, attr_istyle);
1929       W_L(" style=\"");
1930       W_L("-wap-input-format:&quot;*");
1931       W_V(vv);
1932       W_L("&quot;;");
1933       W_L("\"");
1934     }
1935   }
1936   else if (attr_type && STRCASEEQ('p','P',"password",attr_type)) {
1937     char *vv = qs_conv_istyle_to_format(doc->buf.pool, "4");
1938     W_L(" style=\"-wap-input-format:&quot;*");
1939     W_V(vv);
1940     W_L("&quot;;\"");
1941   }
1942   /*--------------------------------------------------------------------------*/
1943   /* The figure is default for the password.                                  */
1944   /*--------------------------------------------------------------------------*/
1945   if (attr_max_length && *attr_max_length) {
1946     if (chxj_chk_numeric(attr_max_length) == 0) {
1947       W_L(" maxlength=\"");
1948       W_V(attr_max_length);
1949       W_L("\"");
1950     }
1951   }
1952   if (attr_checked) {
1953     W_L(" checked=\"checked\"");
1954   }
1955   W_L(" />");
1956 #if 0
1957   jxhtml_t       *jxhtml;
1958   Doc           *doc;
1959   request_rec   *r;
1960   char          *max_length;
1961   char          *type;
1962   char          *name;
1963   char          *value;
1964   char          *istyle;
1965   char          *size;
1966   char          *checked;
1967   char          *accesskey;
1968
1969   jxhtml       = GET_JXHTML(pdoc);
1970   doc         = jxhtml->doc;
1971   r           = doc->r;
1972   max_length  = NULL;
1973   type        = NULL;
1974   name        = NULL;
1975   value       = NULL;
1976   istyle      = NULL;
1977   size        = NULL;
1978   checked     = NULL;
1979   accesskey   = NULL;
1980
1981   W_L("<input");
1982   /*--------------------------------------------------------------------------*/
1983   /* Get Attributes                                                           */
1984   /*--------------------------------------------------------------------------*/
1985   type       = qs_get_type_attr(doc, node, doc->buf.pool);
1986   name       = qs_get_name_attr(doc, node, doc->buf.pool);
1987   value      = qs_get_value_attr(doc,node, doc->buf.pool);
1988   istyle     = qs_get_istyle_attr(doc,node,doc->buf.pool);
1989   max_length = qs_get_maxlength_attr(doc,node,doc->buf.pool);
1990   checked    = qs_get_checked_attr(doc,node,doc->buf.pool);
1991   accesskey  = qs_get_accesskey_attr(doc, node, doc->buf.pool);
1992   size       = qs_get_size_attr(doc, node, doc->buf.pool);
1993
1994   if (type) {
1995     if (type && (STRCASEEQ('t','T',"text",    type) ||
1996                  STRCASEEQ('p','P',"password",type) ||
1997                  STRCASEEQ('c','C',"checkbox",type) ||
1998                  STRCASEEQ('r','R',"radio",   type) ||
1999                  STRCASEEQ('h','H',"hidden",  type) ||
2000                  STRCASEEQ('s','S',"submit",  type) ||
2001                  STRCASEEQ('r','R',"reset",   type))) {
2002       W_L(" type=\"");
2003       W_V(type);
2004       W_L("\"");
2005     }
2006   }
2007   if (size && *size) {
2008     W_L(" size=\"");
2009     W_V(size);
2010     W_L("\"");
2011   }
2012   if (name && *name) {
2013     W_L(" name=\"");
2014     W_V(chxj_jreserved_to_safe_tag(r, name, jxhtml->entryp));
2015     W_L("\"");
2016   }
2017   if (value && *value) {
2018     if (type && (STRCASEEQ('s','S',"submit",type) || STRCASEEQ('r','R',"reset",type))) {
2019       apr_size_t value_len = strlen(value);
2020       value = chxj_conv_z2h(r, value, &value_len, jxhtml->entryp);
2021     }
2022
2023     W_L(" value=\"");
2024     W_V(chxj_add_slash_to_doublequote(doc->pool, value));
2025     W_L("\"");
2026   }
2027   if (accesskey && *accesskey) {
2028     W_L(" accesskey=\"");
2029     W_V(accesskey);
2030     W_L("\"");
2031   }
2032   if (istyle && (*istyle == '1' || *istyle == '2' || *istyle == '3' || *istyle == '4')) {
2033     /*------------------------------------------------------------------------*/
2034     /* CHTML 2.0                                                              */
2035     /*------------------------------------------------------------------------*/
2036     if (type && STRCASEEQ('p','P',"password", type) && ! jxhtml->entryp->pc_flag ) {
2037       W_L(" style=\"-wap-input-format: &quot;*&lt;ja:n&gt;&quot;;\"");
2038     }
2039     else {
2040       char *vv = qs_conv_istyle_to_format(doc->buf.pool, istyle);
2041       W_L(" style=\"");
2042       W_L("-wap-input-format:'*");
2043       W_V(vv);
2044       W_L("';");
2045       W_L("\"");
2046     }
2047   }
2048   else if (type && STRCASEEQ('p','P',"password",type)) {
2049     W_L(" style=\"-wap-input-format: &quot;*&lt;ja:n&gt;&quot;;\"");
2050   }
2051   /*--------------------------------------------------------------------------*/
2052   /* The figure is default for the password.                                  */
2053   /*--------------------------------------------------------------------------*/
2054   if (max_length && *max_length) {
2055     if (chxj_chk_numeric(max_length) == 0) {
2056       W_L(" maxlength=\"");
2057       W_V(max_length);
2058       W_L("\"");
2059     }
2060   }
2061
2062   if (checked) {
2063     W_L(" checked=\"checked\"");
2064   }
2065   W_L(" />");
2066 #endif
2067   return jxhtml->out;
2068 }
2069
2070
2071 /**
2072  * It is a handler who processes the INPUT tag.
2073  *
2074  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
2075  *                     destination is specified.
2076  * @param node   [i]   The INPUT tag node is specified.
2077  * @return The conversion result is returned.
2078  */
2079 static char *
2080 s_jxhtml_end_input_tag(void *pdoc, Node *UNUSED(child)) 
2081 {
2082   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
2083   return jxhtml->out;
2084 }
2085
2086
2087 /**
2088  * It is a handler who processes the CENTER tag.
2089  *
2090  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
2091  *                     destination is specified.
2092  * @param node   [i]   The CENTER tag node is specified.
2093  * @return The conversion result is returned.
2094  */
2095 static char *
2096 s_jxhtml_start_center_tag(void *pdoc, Node *node)
2097 {
2098   jxhtml_t *jxhtml;
2099   Doc       *doc;
2100   Attr      *attr;
2101   char      *attr_style = NULL;
2102   char      *attr_color = NULL;
2103   char      *attr_size  = NULL;
2104
2105   jxhtml = GET_JXHTML(pdoc);
2106   doc    = jxhtml->doc;
2107
2108   for (attr = qs_get_attr(doc,node);
2109        attr;
2110        attr = qs_get_next_attr(doc,attr)) {
2111     char *name  = qs_get_attr_name(doc,attr);
2112     char *value = qs_get_attr_value(doc,attr);
2113     if (STRCASEEQ('s','S',"style",name) && value && *value) {
2114       attr_style = value;
2115     }
2116   }
2117   if (IS_CSS_ON(jxhtml->entryp)) {
2118     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
2119     if (style) {
2120       css_property_t *color_prop      = chxj_css_get_property_value(doc, style, "color");
2121       css_property_t *size_prop       = chxj_css_get_property_value(doc, style, "font-size");
2122       css_property_t *cur;
2123       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
2124         if (cur->value && *cur->value) {
2125           attr_color = apr_pstrdup(doc->pool, cur->value);
2126         }
2127       }
2128       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
2129         if (cur->value && *cur->value) {
2130           attr_size = apr_pstrdup(doc->pool, cur->value);
2131         }
2132       }
2133     }
2134   }
2135
2136   W_L("<center");
2137   if (attr_size || attr_color) {
2138     W_L(" style=\"");
2139     if (attr_size) {
2140       W_L("font-size:");
2141       W_V(attr_size);
2142       W_L(";");
2143     }
2144     if (attr_color) {
2145       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
2146       W_L("color:");
2147       W_V(attr_color);
2148       W_L(";");
2149     }
2150     W_L("\"");
2151   }
2152   W_L(">");
2153   
2154   return jxhtml->out;
2155 }
2156
2157
2158 /**
2159  * It is a handler who processes the CENTER tag.
2160  *
2161  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
2162  *                     destination is specified.
2163  * @param node   [i]   The CENTER tag node is specified.
2164  * @return The conversion result is returned.
2165  */
2166 static char *
2167 s_jxhtml_end_center_tag(void *pdoc, Node *UNUSED(node))
2168 {
2169   jxhtml_t    *jxhtml;
2170   Doc         *doc;
2171   request_rec *r;
2172
2173   jxhtml = GET_JXHTML(pdoc);
2174   doc    = jxhtml->doc;
2175   r      = doc->r;
2176
2177   W_L("</center>");
2178   if (IS_CSS_ON(jxhtml->entryp)) {
2179     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
2180   }
2181   return jxhtml->out;
2182 }
2183
2184
2185 /**
2186  * It is a handler who processes the li tag.
2187  *
2188  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
2189  *                     destination is specified.
2190  * @param node   [i]   The li tag node is specified.
2191  * @return The conversion result is returned.
2192  */
2193 static char *
2194 s_jxhtml_start_li_tag(void *pdoc, Node *node)
2195 {
2196   jxhtml_t    *jxhtml;
2197   Doc         *doc;
2198   request_rec *r;
2199   Attr        *attr;
2200   char        *attr_type  = NULL;
2201   char        *attr_value = NULL;
2202   char        *attr_style = NULL;
2203
2204   jxhtml = GET_JXHTML(pdoc);
2205   doc   = jxhtml->doc;
2206   r     = doc->r;
2207
2208   for (attr = qs_get_attr(doc,node);
2209        attr;
2210        attr = qs_get_next_attr(doc,attr)) {
2211     char *name  = qs_get_attr_name(doc,attr);
2212     char *value = qs_get_attr_value(doc,attr);
2213     if (STRCASEEQ('t','T',"type",name)) {
2214       if (value && (*value == '1' || *value == 'a' || *value == 'A' || STRCASEEQ('d','D',"disc",value) || STRCASEEQ('s','S',"square",value) || STRCASEEQ('c','C',"circle",value))) {
2215         if (*value == '1') {
2216           attr_type = apr_pstrdup(doc->pool, "decimal");
2217         }
2218         else if (*value == 'a') {
2219           attr_type = apr_pstrdup(doc->pool, "lower-alpha");
2220         }
2221         else if (*value == 'A') {
2222           attr_type = apr_pstrdup(doc->pool, "upper-alpha");
2223         }
2224         else {
2225           attr_type = value;
2226         }
2227       }
2228     }
2229     else if (STRCASEEQ('v','V',"value", name) && value && *value) {
2230       attr_value = value;
2231     }
2232     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
2233       attr_style = value;
2234     }
2235   }
2236   if (IS_CSS_ON(jxhtml->entryp)) {
2237     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
2238     if (style) {
2239       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type");
2240       css_property_t *cur;
2241       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
2242         if (STRCASEEQ('d','D',"decimal", cur->value)) {
2243           attr_type = apr_pstrdup(doc->pool, "decimal");
2244         }
2245         else if (STRCASEEQ('u','U',"upper-alpha", cur->value)) {
2246           attr_type = apr_pstrdup(doc->pool, "upper-alpha");
2247         }
2248         else if (STRCASEEQ('l','L',"lower-alpha", cur->value)) {
2249           attr_type = apr_pstrdup(doc->pool, "lower-alpha");
2250         }
2251         else if (STRCASEEQ('d','D',"disc", cur->value)) {
2252           attr_type = apr_pstrdup(doc->pool, "disc");
2253         }
2254         else if (STRCASEEQ('s','S',"square", cur->value)) {
2255           attr_type = apr_pstrdup(doc->pool, "square");
2256         }
2257         else if (STRCASEEQ('c','C',"circle", cur->value)) {
2258           attr_type = apr_pstrdup(doc->pool, "circle");
2259         }
2260       }
2261     }
2262   }
2263
2264
2265   W_L("<li");
2266   if (attr_type) {
2267     W_L(" style=\"");
2268     W_L("list-style-type:");
2269     W_V(attr_type);
2270     W_L(";");
2271     W_L("\"");
2272   }
2273   if (attr_value) {
2274     W_L(" value=\"");
2275     W_V(attr_value);
2276     W_L("\"");
2277   }
2278   W_L(">");
2279   return jxhtml->out;
2280 }
2281
2282
2283 /**
2284  * It is a handler who processes the li tag.
2285  *
2286  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
2287  *                     destination is specified.
2288  * @param node   [i]   The li tag node is specified.
2289  * @return The conversion result is returned.
2290  */
2291 static char *
2292 s_jxhtml_end_li_tag(void *pdoc, Node *UNUSED(child)) 
2293 {
2294   jxhtml_t     *jxhtml;
2295   Doc         *doc;
2296   request_rec *r;
2297
2298   jxhtml = GET_JXHTML(pdoc);
2299   doc   = jxhtml->doc;
2300   r     = doc->r;
2301
2302   if (IS_CSS_ON(jxhtml->entryp)) {
2303     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
2304   }
2305   W_L("</li>");
2306   return jxhtml->out;
2307 }
2308
2309
2310 /**
2311  * It is a handler who processes the OL tag.
2312  *
2313  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
2314  *                     destination is specified.
2315  * @param node   [i]   The OL tag node is specified.
2316  * @return The conversion result is returned.
2317  */
2318 static char *
2319 s_jxhtml_start_ol_tag(void *pdoc, Node *node)
2320 {
2321   jxhtml_t    *jxhtml;
2322   Doc         *doc;
2323   request_rec *r;
2324   Attr        *attr;
2325   char        *attr_style = NULL;
2326   char        *attr_start = NULL;
2327   char        *attr_type  = NULL;
2328
2329   jxhtml = GET_JXHTML(pdoc);
2330   doc   = jxhtml->doc;
2331   r     = doc->r;
2332
2333   /*--------------------------------------------------------------------------*/
2334   /* Get Attributes                                                           */
2335   /*--------------------------------------------------------------------------*/
2336   for (attr = qs_get_attr(doc,node);
2337        attr;
2338        attr = qs_get_next_attr(doc,attr)) {
2339     char *name = qs_get_attr_name(doc,attr);
2340     char *value = qs_get_attr_value(doc,attr);
2341     if (STRCASEEQ('t','T',"type",name) && value) {
2342       if (*value == '1') {
2343         attr_type = apr_pstrdup(doc->pool, "decimal");
2344       }
2345       else if (*value == 'a') {
2346         attr_type = apr_pstrdup(doc->pool, "lower-alpha");
2347       }
2348       else if (*value == 'A') {
2349         attr_type = apr_pstrdup(doc->pool, "upper-alpha");
2350       }
2351     }
2352     else if (STRCASEEQ('s','S',"start",name) && value && *value) {
2353       attr_start = value;
2354     }
2355     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
2356       attr_style = value;
2357     }
2358   }
2359   if (IS_CSS_ON(jxhtml->entryp)) {
2360     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
2361     if (style) {
2362       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type");
2363       css_property_t *cur;
2364       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
2365         if (STRCASEEQ('d','D',"decimal", cur->value)) {
2366           attr_type = apr_pstrdup(doc->pool, "decimal");
2367         }
2368         else if (STRCASEEQ('u','U',"upper-alpha", cur->value)) {
2369           attr_type = apr_pstrdup(doc->pool, "upper-alpha");
2370         }
2371         else if (STRCASEEQ('l','L',"lower-alpha", cur->value)) {
2372           attr_type = apr_pstrdup(doc->pool, "lower-alpha");
2373         }
2374       }
2375     }
2376   }
2377   W_L("<ol");
2378   if (attr_type) {
2379     W_L(" style=\"");
2380     W_L("list-style-type:");
2381     W_V(attr_type);
2382     W_L(";");
2383     W_L("\"");
2384   }
2385   if (attr_start) {
2386     W_L(" start=\"");
2387     W_V(attr_start);
2388     W_L("\"");
2389   }
2390   W_L(">");
2391
2392   return jxhtml->out;
2393 }
2394
2395
2396 /**
2397  * It is a handler who processes the OL tag.
2398  *
2399  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
2400  *                     destination is specified.
2401  * @param node   [i]   The OL tag node is specified.
2402  * @return The conversion result is returned.
2403  */
2404 static char *
2405 s_jxhtml_end_ol_tag(void *pdoc, Node *UNUSED(child)) 
2406 {
2407   jxhtml_t     *jxhtml;
2408   Doc         *doc;
2409   request_rec *r;
2410
2411   jxhtml = GET_JXHTML(pdoc);
2412   doc   = jxhtml->doc;
2413   r     = doc->r;
2414
2415   W_L("</ol>");
2416   if (IS_CSS_ON(jxhtml->entryp)) {
2417     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
2418   }
2419   return jxhtml->out;
2420 }
2421
2422
2423 /**
2424  * It is a handler who processes the P tag.
2425  *
2426  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
2427  *                     destination is specified.
2428  * @param node   [i]   The P tag node is specified.
2429  * @return The conversion result is returned.
2430  */
2431 static char *
2432 s_jxhtml_start_p_tag(void *pdoc, Node *node)
2433 {
2434   jxhtml_t    *jxhtml;
2435   Doc         *doc;
2436   request_rec *r;
2437   Attr        *attr;
2438   char        *attr_align = NULL;
2439   char        *attr_style = NULL;
2440   char        *attr_color = NULL;
2441   char        *attr_blink = NULL;
2442
2443   jxhtml = GET_JXHTML(pdoc);
2444   doc   = jxhtml->doc;
2445   r     = doc->r;
2446
2447   for (attr = qs_get_attr(doc,node);
2448        attr;
2449        attr = qs_get_next_attr(doc,attr)) {
2450     char *nm  = qs_get_attr_name(doc,attr);
2451     char *val = qs_get_attr_value(doc,attr);
2452     if (STRCASEEQ('a','A',"align", nm)) {
2453       /*----------------------------------------------------------------------*/
2454       /* CHTML 1.0 (W3C version 3.2)                                          */
2455       /*----------------------------------------------------------------------*/
2456       if (val && (STRCASEEQ('l','L',"left",val) || STRCASEEQ('r','R',"right",val) || STRCASEEQ('c','C',"center",val))) {
2457         attr_align = apr_pstrdup(doc->buf.pool, val);
2458         break;
2459       }
2460     }
2461     else if (STRCASEEQ('s','S',"style", nm) && val && *val) {
2462       attr_style = apr_pstrdup(doc->buf.pool, val);
2463     }
2464   }
2465   if (IS_CSS_ON(jxhtml->entryp)) {
2466     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
2467     if (style) {
2468       css_property_t *text_align_prop = chxj_css_get_property_value(doc, style, "text-align");
2469       css_property_t *color_prop      = chxj_css_get_property_value(doc, style, "color");
2470       css_property_t *text_deco_prop  = chxj_css_get_property_value(doc, style, "text-decoration");
2471       css_property_t *cur;
2472       for (cur = text_align_prop->next; cur != text_align_prop; cur = cur->next) {
2473         if (STRCASEEQ('l','L',"left",cur->value)) {
2474           attr_align = apr_pstrdup(doc->pool, "left");
2475         }
2476         else if (STRCASEEQ('c','C',"center",cur->value)) {
2477           attr_align = apr_pstrdup(doc->pool, "center");
2478         }
2479         else if (STRCASEEQ('r','R',"right",cur->value)) {
2480           attr_align = apr_pstrdup(doc->pool, "right");
2481         }
2482       }
2483       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
2484         if (cur->value && *cur->value) {
2485           attr_color = apr_pstrdup(doc->pool, cur->value);
2486         }
2487       }
2488       for (cur = text_deco_prop->next; cur != text_deco_prop; cur = cur->next) {
2489         if (cur->value && *cur->value && STRCASEEQ('b','B',"blink",cur->value)) {
2490           attr_blink = apr_pstrdup(doc->pool, cur->value);
2491         }
2492       }
2493     }
2494   }
2495   W_L("<p");
2496   if ((attr_align && *attr_align) || (attr_color && *attr_color) || (attr_blink && *attr_blink)) {
2497     W_L(" style=\"");
2498     if (attr_align) {
2499       W_L("text-align:");
2500       W_V(attr_align);
2501       W_L(";");
2502     }
2503     if (attr_color) {
2504       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
2505       W_L("color:");
2506       W_V(attr_color);
2507       W_L(";");
2508     }
2509     if (attr_blink) {
2510       W_L("text-decoration:");
2511       W_V(attr_blink);
2512       W_L(";");
2513     }
2514     W_L("\"");
2515   }
2516   W_L(">");
2517   return jxhtml->out;
2518 }
2519
2520
2521 /**
2522  * It is a handler who processes the P tag.
2523  *
2524  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
2525  *                     destination is specified.
2526  * @param node   [i]   The P tag node is specified.
2527  * @return The conversion result is returned.
2528  */
2529 static char *
2530 s_jxhtml_end_p_tag(void *pdoc, Node *UNUSED(child)) 
2531 {
2532   jxhtml_t  *jxhtml = GET_JXHTML(pdoc);
2533   Doc       *doc    = jxhtml->doc;
2534
2535   W_L("</p>");
2536   if (IS_CSS_ON(jxhtml->entryp)) {
2537     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
2538   }
2539   return jxhtml->out;
2540 }
2541
2542
2543 /**
2544  * It is a handler who processes the PRE tag.
2545  *
2546  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
2547  *                     destination is specified.
2548  * @param node   [i]   The PRE tag node is specified.
2549  * @return The conversion result is returned.
2550  */
2551 static char *
2552 s_jxhtml_start_pre_tag(void *pdoc, Node *node)
2553 {
2554   jxhtml_t  *jxhtml = GET_JXHTML(pdoc);
2555   Doc       *doc   = jxhtml->doc;
2556   Attr      *attr;
2557   char      *attr_style = NULL;
2558
2559   for (attr = qs_get_attr(doc,node);
2560        attr;
2561        attr = qs_get_next_attr(doc,attr)) {
2562     char *nm  = qs_get_attr_name(doc,attr);
2563     char *val = qs_get_attr_value(doc,attr);
2564     if (val && STRCASEEQ('s','S',"style", nm)) {
2565       attr_style = val;
2566     }
2567   }
2568
2569   if (IS_CSS_ON(jxhtml->entryp)) {
2570     s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
2571   }
2572
2573   jxhtml->pre_flag++;
2574   W_L("<pre>");
2575   return jxhtml->out;
2576 }
2577
2578
2579 /**
2580  * It is a handler who processes the PRE tag.
2581  *
2582  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
2583  *                     destination is specified.
2584  * @param node   [i]   The PRE tag node is specified.
2585  * @return The conversion result is returned.
2586  */
2587 static char *
2588 s_jxhtml_end_pre_tag(void *pdoc, Node *UNUSED(child)) 
2589 {
2590   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
2591   Doc     *doc   = jxhtml->doc;
2592
2593   W_L("</pre>");
2594   jxhtml->pre_flag--;
2595   if (IS_CSS_ON(jxhtml->entryp)) {
2596     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
2597   }
2598
2599   return jxhtml->out;
2600 }
2601
2602
2603 /**
2604  * It is a handler who processes the UL tag.
2605  *
2606  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
2607  *                     destination is specified.
2608  * @param node   [i]   The UL tag node is specified.
2609  * @return The conversion result is returned.
2610  */
2611 static char *
2612 s_jxhtml_start_ul_tag(void *pdoc, Node *node)
2613 {
2614   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
2615   Doc      *doc    = jxhtml->doc;
2616   Attr     *attr;
2617   char     *attr_type = NULL;
2618   char     *attr_style = NULL;
2619   /*--------------------------------------------------------------------------*/
2620   /* Get Attributes                                                           */
2621   /*--------------------------------------------------------------------------*/
2622   for (attr = qs_get_attr(doc,node);
2623        attr;
2624        attr = qs_get_next_attr(doc,attr)) {
2625     char *name   = qs_get_attr_name(doc,attr);
2626     char *value  = qs_get_attr_value(doc,attr);
2627     if (STRCASEEQ('t','T',"type",name)) {
2628       if (value && (STRCASEEQ('d','D',"disc",value) || STRCASEEQ('c','C',"circle",value) || STRCASEEQ('s','S',"square",value))) {
2629         attr_type = value;
2630       }
2631     }
2632     else if (value && *value && STRCASEEQ('s','S',"style", name)) {
2633       attr_style = value;
2634     }
2635   }
2636   if (IS_CSS_ON(jxhtml->entryp)) {
2637     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
2638     if (style) {
2639       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type");
2640       css_property_t *cur;
2641       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
2642         if (STRCASEEQ('d','D',"disc",cur->value)) {
2643           attr_type = apr_pstrdup(doc->pool, "disc");
2644         }
2645         else if (STRCASEEQ('c','C',"circle",cur->value)) {
2646           attr_type = apr_pstrdup(doc->pool, "circle");
2647         }
2648         else if (STRCASEEQ('s','S',"square",cur->value)) {
2649           attr_type = apr_pstrdup(doc->pool, "square");
2650         }
2651       }
2652     }
2653   }
2654   W_L("<ul");
2655   if (attr_type) {
2656     W_L(" style=\"");
2657     W_L("list-style-type:");
2658     W_V(attr_type);
2659     W_L(";");
2660     W_L("\"");
2661   }
2662   W_L(">");
2663   return jxhtml->out;
2664 }
2665
2666
2667 /**
2668  * It is a handler who processes the UL tag.
2669  *
2670  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
2671  *                     destination is specified.
2672  * @param node   [i]   The UL tag node is specified.
2673  * @return The conversion result is returned.
2674  */
2675 static char *
2676 s_jxhtml_end_ul_tag(void *pdoc, Node *UNUSED(child)) 
2677 {
2678   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
2679   Doc     *doc   = jxhtml->doc;
2680
2681   W_L("</ul>");
2682   if (IS_CSS_ON(jxhtml->entryp)) {
2683     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
2684   }
2685   return jxhtml->out;
2686 }
2687
2688
2689 /**
2690  * It is a handler who processes the HR tag.
2691  *
2692  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
2693  *                     destination is specified.
2694  * @param node   [i]   The HR tag node is specified.
2695  * @return The conversion result is returned.
2696  */
2697 static char *
2698 s_jxhtml_start_hr_tag(void *pdoc, Node *node) 
2699 {
2700   Attr        *attr;
2701   jxhtml_t     *jxhtml;
2702   Doc         *doc;
2703   request_rec *r;
2704   char        *attr_align   = NULL;
2705   char        *attr_size    = NULL;
2706   char        *attr_width   = NULL;
2707   char        *attr_noshade = NULL;
2708   char        *attr_style   = NULL;
2709   char        *attr_color   = NULL;
2710
2711   jxhtml   = GET_JXHTML(pdoc);
2712   doc     = jxhtml->doc;
2713   r       = doc->r;
2714
2715   for (attr = qs_get_attr(doc,node);
2716        attr; 
2717        attr = qs_get_next_attr(doc,attr)) {
2718     char *name  = qs_get_attr_name (doc,attr);
2719     char *value = qs_get_attr_value(doc,attr);
2720     switch(*name) {
2721     case 'a':
2722     case 'A':
2723       if (strcasecmp(name, "align") == 0) {
2724         /*--------------------------------------------------------------------*/
2725         /* CHTML 1.0                                                          */
2726         /*--------------------------------------------------------------------*/
2727         if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
2728           attr_align = value;
2729         }
2730       }
2731       break;
2732
2733     case 's':
2734     case 'S':
2735       if (strcasecmp(name, "size") == 0) {
2736         /*--------------------------------------------------------------------*/
2737         /* CHTML 1.0                                                          */
2738         /*--------------------------------------------------------------------*/
2739         if (value && *value) {
2740           attr_size = value;
2741         }
2742       }
2743       else if (strcasecmp(name, "style") == 0) {
2744         if (value && *value) {
2745           attr_style = value;
2746         }
2747       }
2748       break;
2749
2750     case 'w':
2751     case 'W':
2752       if (strcasecmp(name, "width") == 0) {
2753         /*--------------------------------------------------------------------*/
2754         /* CHTML 1.0                                                          */
2755         /*--------------------------------------------------------------------*/
2756         if (value && *value) {
2757           attr_width = value;
2758         }
2759       }
2760       break;
2761
2762     case 'n':
2763     case 'N':
2764       if (strcasecmp(name, "noshade") == 0) {
2765         /*--------------------------------------------------------------------*/
2766         /* CHTML 1.0                                                          */
2767         /*--------------------------------------------------------------------*/
2768         attr_noshade = apr_pstrdup(doc->pool, "noshade");
2769       }
2770       break;
2771
2772     case 'c':
2773     case 'C':
2774       if (strcasecmp(name, "color") == 0 && value && *value) {
2775         /*--------------------------------------------------------------------*/
2776         /* CHTML 4.0                                                          */
2777         /*--------------------------------------------------------------------*/
2778         attr_color = value;
2779       }
2780       break;
2781
2782     default:
2783       break;
2784     }
2785   }
2786   if (IS_CSS_ON(jxhtml->entryp)) {
2787     css_prop_list_t *style = s_jxhtml_nopush_and_get_now_style(pdoc, node, attr_style);
2788     if (style) {
2789       css_property_t *border_style_prop = chxj_css_get_property_value(doc, style, "border-style");
2790       css_property_t *height_prop       = chxj_css_get_property_value(doc, style, "height");
2791       css_property_t *width_prop        = chxj_css_get_property_value(doc, style, "width");
2792       css_property_t *cur;
2793       for (cur = border_style_prop->next; cur != border_style_prop; cur = cur->next) {
2794         if (STRCASEEQ('s','S',"solid",cur->value)) {
2795           attr_noshade = "noshade";
2796         }
2797       }
2798       for (cur = height_prop->next; cur != height_prop; cur = cur->next) {
2799         char *tmp = apr_pstrdup(doc->pool, cur->value);
2800         char *tmpp = strstr(tmp, "px");
2801         if (tmpp) { 
2802           attr_size = apr_pstrdup(doc->pool, tmp);
2803         }
2804       }
2805       for (cur = width_prop->next; cur != width_prop; cur = cur->next) {
2806         char *tmp = apr_pstrdup(doc->pool, cur->value);
2807         char *tmpp = strstr(tmp, "px");
2808         if (tmpp) {
2809           attr_width = apr_pstrdup(doc->pool, tmp);
2810         }
2811         else {
2812           tmpp = strstr(tmp, "%");
2813           if (tmpp) {
2814             attr_width = apr_pstrdup(doc->pool, tmp);
2815           }
2816         }
2817       }
2818     }
2819   }
2820   W_L("<hr");
2821   if (attr_align) {
2822     W_L(" align=\"");
2823     W_V(attr_align);
2824     W_L("\"");
2825   }
2826   if (attr_size || attr_width || attr_noshade) {
2827     W_L(" style=\"");
2828     if (attr_size) {
2829       W_L("height:");
2830       W_V(attr_size);
2831       if (!strstr(attr_size, "px")) {
2832         W_L("px");
2833       }
2834       W_L(";");
2835     }
2836     if (attr_width) {
2837       W_L("width:");
2838       W_V(attr_width);
2839       if (!strstr(attr_width, "px") && !strstr(attr_width, "%")) {
2840         W_L("px");
2841       }
2842       W_L(";");
2843     }
2844     if (attr_noshade) {
2845       W_L("border-style:solid;");
2846     }
2847     W_L("\"");
2848   }
2849   if (attr_color) {
2850     W_L(" color=\"");
2851     W_V(attr_color);
2852     W_L("\"");
2853   }
2854   W_L(" />");
2855
2856   return jxhtml->out;
2857 }
2858
2859
2860 /**
2861  * It is a handler who processes the HR tag.
2862  *
2863  * @param jxhtml  [i/o] The pointer to the JXHTML structure at the output
2864  *                     destination is specified.
2865  * @param node   [i]   The HR tag node is specified.
2866  * @return The conversion result is returned.
2867  */
2868 static char *
2869 s_jxhtml_end_hr_tag(void *pdoc, Node *UNUSED(child)) 
2870 {
2871   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
2872   return jxhtml->out;
2873 }
2874
2875
2876 /**
2877  * It is a handler who processes the IMG tag.
2878  *
2879  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
2880  *                     destination is specified.
2881  * @param node   [i]   The IMG tag node is specified.
2882  * @return The conversion result is returned.
2883  */
2884 static char *
2885 s_jxhtml_start_img_tag(void *pdoc, Node *node) 
2886 {
2887   jxhtml_t    *jxhtml = GET_JXHTML(pdoc);
2888   Doc         *doc   = jxhtml->doc;
2889   request_rec *r     = doc->r;
2890   Attr        *attr;
2891   char        *attr_src    = NULL;
2892   char        *attr_height = NULL;
2893   char        *attr_width  = NULL;
2894   char        *attr_align  = NULL;
2895   char        *attr_alt    = NULL;
2896   char        *attr_style  = NULL;
2897 #ifndef IMG_NOT_CONVERT_FILENAME
2898   device_table  *spec = jxhtml->spec;
2899 #endif
2900
2901   /*--------------------------------------------------------------------------*/
2902   /* Get Attributes                                                           */
2903   /*--------------------------------------------------------------------------*/
2904   for (attr = qs_get_attr(doc,node);
2905        attr;
2906        attr = qs_get_next_attr(doc,attr)) {
2907     char *name  = qs_get_attr_name(doc,attr);
2908     char *value = qs_get_attr_value(doc,attr);
2909     if (STRCASEEQ('s','S',"src",name)) {
2910       /*----------------------------------------------------------------------*/
2911       /* CHTML 1.0                                                            */
2912       /*----------------------------------------------------------------------*/
2913 #ifdef IMG_NOT_CONVERT_FILENAME
2914       value = chxj_encoding_parameter(r, value, 1);
2915       value = chxj_jreserved_tag_to_safe_for_query_string(r, value, jxhtml->entryp, 1);
2916       value = chxj_add_cookie_no_update_parameter(r, value);
2917       attr_src = value;
2918 #else
2919       value = chxj_img_conv(r, spec, value);
2920       value = chxj_encoding_parameter(r, value, 1);
2921       value = chxj_jreserved_tag_to_safe_for_query_string(r, value, jxhtml->entryp, 1);
2922       value = chxj_add_cookie_no_update_parameter(r, value);
2923       attr_src = value;
2924 #endif
2925     }
2926     else if (STRCASEEQ('a','A',"align",name)) {
2927       /*----------------------------------------------------------------------*/
2928       /* CHTML 1.0                                                            */
2929       /*----------------------------------------------------------------------*/
2930       if (value) {
2931         if (STRCASEEQ('t','T',"top",   value) ||
2932             STRCASEEQ('m','M',"middle",value) ||
2933             STRCASEEQ('b','B',"bottom",value) ||
2934             STRCASEEQ('l','L',"left",  value) ||
2935             STRCASEEQ('r','R',"right", value)) {
2936           attr_align = value;
2937         }
2938         else if (STRCASEEQ('c','C',"center",value)) {
2939           attr_align = apr_pstrdup(doc->pool, "middle");
2940         }
2941       }
2942     }
2943     else if (STRCASEEQ('w','W',"width",name) && value && *value) {
2944       /*----------------------------------------------------------------------*/
2945       /* CHTML 1.0                                                            */
2946       /*----------------------------------------------------------------------*/
2947       attr_width = value;
2948     }
2949     else if (STRCASEEQ('h','H',"height",name) && value && *value) {
2950       /*----------------------------------------------------------------------*/
2951       /* CHTML 1.0                                                            */
2952       /*----------------------------------------------------------------------*/
2953       attr_height = value;
2954     }
2955     else if (STRCASEEQ('h','H',"hspace",name)) {
2956       /*----------------------------------------------------------------------*/
2957       /* CHTML 1.0                                                            */
2958       /*----------------------------------------------------------------------*/
2959       /* ignore */
2960     }
2961     else if (STRCASEEQ('v','V',"vspace",name)) {
2962       /*----------------------------------------------------------------------*/
2963       /* CHTML 1.0                                                            */
2964       /*----------------------------------------------------------------------*/
2965       /* ignore */
2966     }
2967     else if (STRCASEEQ('a','A',"alt",name) && value && *value) {
2968       /*----------------------------------------------------------------------*/
2969       /* CHTML 1.0                                                            */
2970       /*----------------------------------------------------------------------*/
2971       attr_alt = value;
2972     }
2973     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
2974       /*----------------------------------------------------------------------*/
2975       /* CHTML 1.0                                                            */
2976       /*----------------------------------------------------------------------*/
2977       attr_style = value;
2978     }
2979   }
2980
2981   if (IS_CSS_ON(jxhtml->entryp)) {
2982     css_prop_list_t *style = s_jxhtml_nopush_and_get_now_style(pdoc, node, attr_style);
2983     if (style) {
2984       css_property_t *height_prop = chxj_css_get_property_value(doc, style, "height");
2985       css_property_t *width_prop  = chxj_css_get_property_value(doc, style, "width");
2986       css_property_t *valign_prop = chxj_css_get_property_value(doc, style, "vertical-align");
2987       css_property_t *cur;
2988       for (cur = height_prop->next; cur != height_prop; cur = cur->next) {
2989         attr_height = apr_pstrdup(doc->pool, cur->value);
2990       }
2991       for (cur = width_prop->next; cur != width_prop; cur = cur->next) {
2992         attr_width = apr_pstrdup(doc->pool, cur->value);
2993       }
2994       for (cur = valign_prop->next; cur != valign_prop; cur = cur->next) {
2995         attr_align = apr_pstrdup(doc->pool, cur->value);
2996       }
2997     }
2998   }
2999
3000   W_L("<img");
3001   if (attr_src) {
3002     W_L(" src=\"");
3003     W_V(attr_src);
3004     W_L("\"");
3005   }
3006   if (attr_align) {
3007     W_L(" align=\"");
3008     W_V(attr_align); 
3009     W_L("\"");
3010   }
3011   if (attr_width) {
3012     W_L(" width=\"");
3013     W_V(attr_width);
3014     W_L("\"");
3015   }
3016   if (attr_height) {
3017     W_L(" height=\"");
3018     W_V(attr_height);
3019     W_L("\"");
3020   }
3021   if (attr_alt) {
3022     W_L(" alt=\"");
3023     W_V(attr_alt);
3024     W_L("\"");
3025   } 
3026   else {
3027     W_L(" alt=\"\"");
3028   }
3029   W_L(" />");
3030   return jxhtml->out;
3031 }
3032
3033
3034 /**
3035  * It is a handler who processes the IMG tag.
3036  *
3037  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
3038  *                     destination is specified.
3039  * @param node   [i]   The IMG tag node is specified.
3040  * @return The conversion result is returned.
3041  */
3042 static char *
3043 s_jxhtml_end_img_tag(void *pdoc, Node *UNUSED(child)) 
3044 {
3045   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
3046   return jxhtml->out;
3047 }
3048
3049
3050 /**
3051  * It is a handler who processes the SELECT tag.
3052  *
3053  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
3054  *                     destination is specified.
3055  * @param node   [i]   The SELECT tag node is specified.
3056  * @return The conversion result is returned.
3057  */
3058 static char *
3059 s_jxhtml_start_select_tag(void *pdoc, Node *node)
3060 {
3061   jxhtml_t *jxhtml    = GET_JXHTML(pdoc);
3062   Doc     *doc      = jxhtml->doc;
3063   Attr    *attr;
3064   char    *size     = NULL;
3065   char    *name     = NULL;
3066   char    *multiple = NULL;
3067   char    *attr_style = NULL;
3068
3069   W_L("<select");
3070   for (attr = qs_get_attr(doc,node);
3071        attr;
3072        attr = qs_get_next_attr(doc,attr)) {
3073     char *nm  = qs_get_attr_name(doc,attr);
3074     char *val = qs_get_attr_value(doc,attr);
3075     if (STRCASEEQ('s','S',"size",nm)) {
3076       /*----------------------------------------------------------------------*/
3077       /* CHTML 1.0 version 2.0                                                */
3078       /*----------------------------------------------------------------------*/
3079       size = apr_pstrdup(doc->buf.pool, val);
3080     }
3081     else if (STRCASEEQ('s','S',"style",nm) && val && *val) {
3082       /*----------------------------------------------------------------------*/
3083       /* CHTML 1.0 version 2.0                                                */
3084       /*----------------------------------------------------------------------*/
3085       attr_style = apr_pstrdup(doc->buf.pool, val);
3086     }
3087     else if (STRCASEEQ('n','N',"name",nm)) {
3088       /*----------------------------------------------------------------------*/
3089       /* CHTML 1.0 version 2.0                                                */
3090       /*----------------------------------------------------------------------*/
3091       name = apr_pstrdup(doc->buf.pool, val);
3092     }
3093     else if (STRCASEEQ('m','M',"multiple", nm)) {
3094       /*----------------------------------------------------------------------*/
3095       /* CHTML 1.0 version 2.0                                                */
3096       /*----------------------------------------------------------------------*/
3097       multiple = apr_pstrdup(doc->buf.pool, val);
3098     }
3099   }
3100   if (size && *size) {
3101     W_L(" size=\"");
3102     W_V(size);
3103     W_L("\"");
3104   }
3105   if (name && *name) {
3106     W_L(" name=\"");
3107     W_V(name);
3108     W_L("\"");
3109   }
3110   if (multiple) {
3111     W_L(" multiple");
3112   }
3113   W_L(">");
3114
3115   if (IS_CSS_ON(jxhtml->entryp)) {
3116     s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
3117   }
3118
3119   return jxhtml->out;
3120 }
3121
3122
3123 /**
3124  * It is a handler who processes the SELECT tag.
3125  *
3126  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
3127  *                     destination is specified.
3128  * @param node   [i]   The SELECT tag node is specified.
3129  * @return The conversion result is returned.
3130  */
3131 static char *
3132 s_jxhtml_end_select_tag(void *pdoc, Node *UNUSED(child))
3133 {
3134   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
3135   Doc     *doc   = jxhtml->doc;
3136
3137   W_L("</select>");
3138   if (IS_CSS_ON(jxhtml->entryp)) {
3139     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
3140   }
3141
3142   return jxhtml->out;
3143 }
3144
3145 /**
3146  * It is a handler who processes the OPTION tag.
3147  *
3148  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
3149  *                     destination is specified.
3150  * @param node   [i]   The OPTION tag node is specified.
3151  * @return The conversion result is returned.
3152  */
3153 static char *
3154 s_jxhtml_start_option_tag(void *pdoc, Node *node)
3155 {
3156   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
3157   Doc     *doc   = jxhtml->doc;
3158   Attr    *attr;
3159
3160   char *selected   = NULL;
3161   char *value      = NULL;
3162   char *attr_style = NULL;
3163
3164   W_L("<option");
3165   for (attr = qs_get_attr(doc,node);
3166        attr;
3167        attr = qs_get_next_attr(doc,attr)) {
3168     char *nm  = qs_get_attr_name(doc,attr);
3169     char *val = qs_get_attr_value(doc,attr);
3170     if (STRCASEEQ('s','S',"selected",nm)) {
3171       /*----------------------------------------------------------------------*/
3172       /* CHTML 1.0 version 2.0                                                */
3173       /*----------------------------------------------------------------------*/
3174       selected = apr_pstrdup(doc->buf.pool, val);
3175     }
3176     else if (STRCASEEQ('s','S',"style",nm) && val && *val) {
3177       /*----------------------------------------------------------------------*/
3178       /* CHTML 1.0 version 2.0                                                */
3179       /*----------------------------------------------------------------------*/
3180       attr_style = apr_pstrdup(doc->buf.pool, val);
3181     }
3182     else if (STRCASEEQ('v','V',"value",nm)) {
3183       /*----------------------------------------------------------------------*/
3184       /* CHTML 1.0 version 2.0                                                */
3185       /*----------------------------------------------------------------------*/
3186       value = apr_pstrdup(doc->buf.pool, val);
3187     }
3188   }
3189   if (value) {
3190     W_L(" value=\"");
3191     W_V(value);
3192     W_L("\"");
3193   }
3194   if (selected) {
3195     W_L(" selected");
3196   }
3197   W_L(">");
3198
3199   if (IS_CSS_ON(jxhtml->entryp)) {
3200     s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
3201   }
3202
3203   return jxhtml->out;
3204 }
3205
3206
3207 /**
3208  * It is a handler who processes the OPTION tag.
3209  *
3210  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
3211  *                     destination is specified.
3212  * @param node   [i]   The OPTION tag node is specified.
3213  * @return The conversion result is returned.
3214  */
3215 static char *
3216 s_jxhtml_end_option_tag(void *pdoc, Node *UNUSED(child))
3217 {
3218   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
3219   Doc      *doc = jxhtml->doc;
3220
3221   W_L("</option>");
3222   if (IS_CSS_ON(jxhtml->entryp)) {
3223     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
3224   }
3225
3226   return jxhtml->out;
3227 }
3228
3229
3230 /**
3231  * It is a handler who processes the DIV tag.
3232  *
3233  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
3234  *                     destination is specified.
3235  * @param node   [i]   The DIV tag node is specified.
3236  * @return The conversion result is returned.
3237  */
3238 static char *
3239 s_jxhtml_start_div_tag(void *pdoc, Node *node)
3240 {
3241   jxhtml_t    *jxhtml;
3242   Doc         *doc;
3243   request_rec *r;
3244   Attr        *attr;
3245   char        *attr_style             = NULL;
3246   char        *attr_align             = NULL;
3247   char        *attr_display           = NULL;
3248   char        *attr_decoration        = NULL;
3249   char        *attr_wap_marquee_style = NULL;
3250   char        *attr_wap_marquee_dir   = NULL;
3251   char        *attr_wap_marquee_loop  = NULL;
3252   char        *attr_color             = NULL;
3253   char        *attr_bgcolor           = NULL;
3254   char        *attr_font_size         = NULL;
3255
3256   jxhtml = GET_JXHTML(pdoc);
3257   doc   = jxhtml->doc;
3258   r     = doc->r;
3259
3260   for (attr = qs_get_attr(doc,node);
3261        attr;
3262        attr = qs_get_next_attr(doc,attr)) {
3263     char *nm  = qs_get_attr_name(doc,attr);
3264     char *val = qs_get_attr_value(doc,attr);
3265     if (STRCASEEQ('a','A',"align",nm)) {
3266       /*----------------------------------------------------------------------*/
3267       /* CHTML 1.0 (W3C version 3.2)                                          */
3268       /*----------------------------------------------------------------------*/
3269       if (val && (STRCASEEQ('l','L',"left",val) || STRCASEEQ('r','R',"right",val) || STRCASEEQ('c','C',"center",val))) {
3270         attr_align = apr_pstrdup(doc->buf.pool, val);
3271       }
3272     }
3273     else if (STRCASEEQ('s','S',"style",nm) && val && *val) {
3274       attr_style = apr_pstrdup(doc->buf.pool, val);
3275     }
3276   }
3277
3278   if (IS_CSS_ON(jxhtml->entryp)) {
3279     css_prop_list_t *style = s_jxhtml_nopush_and_get_now_style(pdoc, node, attr_style);
3280     if (style) {
3281       css_property_t *display_prop           = chxj_css_get_property_value(doc, style, "display");
3282       css_property_t *text_decoration_prop   = chxj_css_get_property_value(doc, style, "text-decoration");
3283       css_property_t *color_prop             = chxj_css_get_property_value(doc, style, "color");
3284       css_property_t *text_align_prop        = chxj_css_get_property_value(doc, style, "text-align");
3285       css_property_t *font_size_prop         = chxj_css_get_property_value(doc, style, "font-size");
3286       css_property_t *background_color_prop  = chxj_css_get_property_value(doc, style, "background-color");
3287       css_property_t *background_prop        = chxj_css_get_property_value(doc, style, "background");
3288
3289       css_property_t *cur;
3290       for (cur = display_prop->next; cur != display_prop; cur = cur->next) {
3291         if (strcasecmp("-wap-marquee", cur->value) == 0) {
3292           attr_display = apr_pstrdup(doc->pool, cur->value);
3293         }
3294       }
3295       for (cur = text_decoration_prop->next; cur != text_decoration_prop; cur = cur->next) {
3296         if (STRCASEEQ('b','B',"blink", cur->value)) {
3297           attr_decoration = apr_pstrdup(doc->pool, cur->value);
3298         }
3299       }
3300       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
3301         attr_color = apr_pstrdup(doc->pool, cur->value);
3302       }
3303       for (cur = background_color_prop->next; cur != background_color_prop; cur = cur->next) {
3304         attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
3305         attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
3306       }
3307       for (cur = background_prop->next; cur != background_prop; cur = cur->next) {
3308         char *ss = strchr(cur->value, '#');
3309         if (!ss || !*ss) {
3310           ss = strstr(cur->value, "rgb");
3311         }
3312         if (ss && *ss) {
3313           attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
3314           attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
3315         }
3316       }
3317       for (cur = text_align_prop->next; cur != text_align_prop; cur = cur->next) {
3318         attr_align = apr_pstrdup(doc->pool, cur->value);
3319       }
3320       for (cur = font_size_prop->next; cur != font_size_prop; cur = cur->next) {
3321         if (   STRCASEEQ('x','X',"xx-small",cur->value)
3322             || STRCASEEQ('x','X',"x-small",cur->value)
3323             || STRCASEEQ('s','S',"small",cur->value)
3324             || STRCASEEQ('m','M',"medium",cur->value)
3325             || STRCASEEQ('l','L',"large",cur->value)
3326             || STRCASEEQ('x','X',"x-large",cur->value)
3327             || STRCASEEQ('x','X',"xx-large",cur->value)) {
3328           attr_font_size = apr_pstrdup(doc->pool, cur->value);
3329         }
3330       }
3331       if (attr_display) {
3332         css_property_t *wap_marquee_style_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-style");
3333         css_property_t *wap_marquee_dir_prop   = chxj_css_get_property_value(doc, style, "-wap-marquee-dir");
3334         css_property_t *wap_marquee_loop_prop  = chxj_css_get_property_value(doc, style, "-wap-marquee-loop");
3335         for (cur = wap_marquee_style_prop->next; cur != wap_marquee_style_prop; cur = cur->next) {
3336           if (STRCASEEQ('s','S',"scroll", cur->value) || STRCASEEQ('s','S',"slide",cur->value) || STRCASEEQ('a','A',"alternate",cur->value)) {
3337             attr_wap_marquee_style = apr_pstrdup(doc->pool, cur->value);
3338           }
3339         }
3340         for (cur = wap_marquee_dir_prop->next; cur != wap_marquee_dir_prop; cur = cur->next) {
3341           if (STRCASEEQ('l','L',"ltr",cur->value)) {
3342             attr_wap_marquee_dir = apr_pstrdup(doc->pool, cur->value);
3343           }
3344           else if (STRCASEEQ('r','R',"rtl",cur->value)) {
3345             attr_wap_marquee_dir = apr_pstrdup(doc->pool, cur->value);
3346           }
3347         }
3348         for (cur = wap_marquee_loop_prop->next; cur != wap_marquee_loop_prop; cur = cur->next) {
3349           attr_wap_marquee_loop = apr_pstrdup(doc->pool, cur->value);
3350         }
3351       }
3352     }
3353   }  
3354   W_L("<div");
3355   if (attr_align
3356       || attr_display
3357       || attr_decoration
3358       || attr_wap_marquee_style
3359       || attr_wap_marquee_dir
3360       || attr_wap_marquee_loop
3361       || attr_color
3362       || attr_bgcolor
3363       || attr_font_size) {
3364     W_L(" style=\"");
3365     if (attr_align) {
3366       W_L("text-align:");
3367       W_V(attr_align);
3368       W_L(";");
3369     }
3370     if (attr_display) {
3371       W_L("display:");
3372       W_V(attr_display);
3373       W_L(";");
3374     }
3375     if (attr_decoration) {
3376       W_L("text-decoration:");
3377       W_V(attr_decoration);
3378       W_L(";");
3379     }
3380     if (attr_wap_marquee_style) {
3381       W_L("-wap-marquee-style:");
3382       W_V(attr_wap_marquee_style);
3383       W_L(";");
3384     }
3385     if (attr_wap_marquee_dir) {
3386       W_L("-wap-marquee-dir:");
3387       W_V(attr_wap_marquee_dir);
3388       W_L(";");
3389     }
3390     if (attr_wap_marquee_loop) {
3391       W_L("-wap-marquee-loop:");
3392       W_V(attr_wap_marquee_loop);
3393       W_L(";");
3394     }
3395     if (attr_color) {
3396       W_L("color:");
3397       W_V(attr_color);
3398       W_L(";");
3399     }
3400     if (attr_bgcolor) {
3401       W_L("background-color:");
3402       W_V(attr_bgcolor);
3403       W_L(";");
3404     }
3405     if (attr_font_size) {
3406       W_L("font-size:");
3407       W_V(attr_font_size);
3408       W_L(";");
3409     }
3410     W_L("\"");
3411   }
3412   W_L(">");
3413   return jxhtml->out;
3414 }
3415
3416
3417 /**
3418  * It is a handler who processes the DIV tag.
3419  *
3420  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
3421  *                     destination is specified.
3422  * @param node   [i]   The DIV tag node is specified.
3423  * @return The conversion result is returned.
3424  */
3425 static char *
3426 s_jxhtml_end_div_tag(void *pdoc, Node *UNUSED(child))
3427 {
3428   jxhtml_t      *jxhtml;
3429   Doc          *doc;
3430   request_rec  *r;
3431
3432   jxhtml = GET_JXHTML(pdoc);
3433   doc   = jxhtml->doc;
3434   r     = doc->r;
3435
3436   W_L("</div>");
3437   if (IS_CSS_ON(jxhtml->entryp)) {
3438     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
3439   }
3440   return jxhtml->out;
3441 }
3442
3443
3444 static char *
3445 s_jxhtml_chxjif_tag(void *pdoc, Node *node)
3446 {
3447   jxhtml_t *jxhtml;
3448   Doc     *doc;
3449   Node    *child;
3450   request_rec *r;
3451
3452   jxhtml = GET_JXHTML(pdoc);
3453   doc   = jxhtml->doc;
3454   r     = doc->r;
3455
3456   for (child = qs_get_child_node(doc, node);
3457        child;
3458        child = qs_get_next_node(doc, child)) {
3459     W_V(child->otext);
3460     s_jxhtml_chxjif_tag(jxhtml, child);
3461   }
3462   return NULL;
3463 }
3464
3465
3466 /**
3467  * It is a handler who processes the TEXTARE tag.
3468  *
3469  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
3470  *                     destination is specified.
3471  * @param node   [i]   The TEXTAREA tag node is specified.
3472  * @return The conversion result is returned.
3473  */
3474 static char *
3475 s_jxhtml_start_textarea_tag(void *pdoc, Node *node) 
3476 {
3477   jxhtml_t      *jxhtml;
3478   Doc           *doc;
3479   request_rec   *r;
3480   Attr          *attr;
3481   char          *attr_accesskey = NULL;
3482   char          *attr_name      = NULL;
3483   char          *attr_rows      = NULL;
3484   char          *attr_cols      = NULL;
3485   char          *attr_istyle    = NULL;
3486   char          *attr_style     = NULL;
3487
3488
3489   jxhtml = GET_JXHTML(pdoc);
3490   doc   = jxhtml->doc;
3491   r     = doc->r;
3492
3493   jxhtml->textarea_flag++;
3494   for (attr = qs_get_attr(doc,node);
3495        attr;
3496        attr = qs_get_next_attr(doc,attr)) {
3497     char *name  = qs_get_attr_name(doc,attr);
3498     char *value = qs_get_attr_value(doc,attr);
3499     if (STRCASEEQ('a','A',"accesskey",name) && value && *value != 0) {
3500       attr_accesskey = value;
3501     }
3502     else if (STRCASEEQ('i','I',"istyle", name) && value && (*value == '1' || *value == '2' || *value == '3' || *value == '4')) {
3503       attr_istyle = value;
3504     }
3505     else if (STRCASEEQ('n','N',"name", name) && value && *value) {
3506       attr_name = value;
3507     }
3508     else if (STRCASEEQ('r','R',"rows", name) && value && *value) {
3509       attr_rows = value;
3510     }
3511     else if (STRCASEEQ('c','C',"cols", name) && value && *value) {
3512       attr_cols = value;
3513     }
3514     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
3515       attr_style = value;
3516     }
3517   }
3518   if (IS_CSS_ON(jxhtml->entryp)) {
3519     css_prop_list_t *style = s_jxhtml_nopush_and_get_now_style(pdoc, node, attr_style);
3520     if (style) {
3521       css_property_t *wap_input_format = chxj_css_get_property_value(doc, style, "-wap-input-format");
3522       css_property_t *cur;
3523       for (cur = wap_input_format->next; cur != wap_input_format; cur = cur->next) {
3524         if (strcasestr(cur->value, "<ja:n>")) {
3525           attr_istyle = "4";
3526         }
3527         else if (strcasestr(cur->value, "<ja:en>")) {
3528           attr_istyle = "3";
3529         }
3530         else if (strcasestr(cur->value, "<ja:hk>")) {
3531           attr_istyle = "2";
3532         }
3533         else if (strcasestr(cur->value, "<ja:h>")) {
3534           attr_istyle = "1";
3535         }
3536       }
3537     }
3538   }
3539   W_L("<textarea");
3540   if (attr_accesskey) {
3541     W_L(" accesskey=\"");
3542     W_V(attr_accesskey);
3543     W_L("\"");
3544   }
3545   if (attr_name) {
3546     W_L(" name=\"");
3547     W_V(attr_name);
3548     W_L("\"");
3549   }
3550   if (attr_rows) {
3551     W_L(" rows=\"");
3552     W_V(attr_rows);
3553     W_L("\"");
3554   }
3555   if (attr_cols) {
3556     W_L(" cols=\"");
3557     W_V(attr_cols);
3558     W_L("\"");
3559   }
3560   if (attr_istyle) {
3561     char *vv = qs_conv_istyle_to_format(doc->buf.pool, attr_istyle);
3562     W_L(" style=\"");
3563     W_L("-wap-input-format:&quot;*");
3564     W_V(vv);
3565     W_L("&quot;;");
3566     W_L("\"");
3567   }
3568   W_L(">");
3569   return jxhtml->out;
3570 }
3571
3572
3573 /**
3574  * It is a handler who processes the TEXTAREA tag.
3575  *
3576  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
3577  *                     destination is specified.
3578  * @param node   [i]   The TEXTAREA tag node is specified.
3579  * @return The conversion result is returned.
3580  */
3581 static char *
3582 s_jxhtml_end_textarea_tag(void *pdoc, Node *UNUSED(child)) 
3583 {
3584   jxhtml_t       *jxhtml;
3585   Doc           *doc;
3586   request_rec   *r;
3587
3588   jxhtml = GET_JXHTML(pdoc);
3589   doc   = jxhtml->doc;
3590   r     = doc->r;
3591
3592   W_L("</textarea>");
3593   jxhtml->textarea_flag--;
3594
3595   return jxhtml->out;
3596 }
3597
3598
3599 /**
3600  * It is a handler who processes the B tag.
3601  *
3602  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
3603  *                     destination is specified.
3604  * @param node   [i]   The B tag node is specified.
3605  * @return The conversion result is returned.
3606  */
3607 static char*
3608 s_jxhtml_start_b_tag(void* pdoc, Node* UNUSED(node)) 
3609 {
3610   jxhtml_t*      jxhtml;
3611   Doc*          doc;
3612   request_rec*  r;
3613
3614   jxhtml = GET_JXHTML(pdoc);
3615   doc   = jxhtml->doc;
3616   r     = doc->r;
3617
3618   W_L("<b>");
3619   return jxhtml->out;
3620 }
3621
3622
3623 /**
3624  * It is a handler who processes the B tag.
3625  *
3626  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
3627  *                     destination is specified.
3628  * @param node   [i]   The B tag node is specified.
3629  * @return The conversion result is returned.
3630  */
3631 static char*
3632 s_jxhtml_end_b_tag(void* pdoc, Node* UNUSED(child)) 
3633 {
3634   jxhtml_t*      jxhtml = GET_JXHTML(pdoc);
3635   Doc*          doc   = jxhtml->doc;
3636
3637   W_L("</b>");
3638   return jxhtml->out;
3639 }
3640
3641 static char*
3642 s_jxhtml_text_tag(void* pdoc, Node* child)
3643 {
3644   jxhtml_t*     jxhtml;
3645   Doc*         doc;
3646   char*        textval;
3647   char*        tmp;
3648   char*        tdst;
3649   char         one_byte[2];
3650   int          ii;
3651   int          tdst_len;
3652   request_rec* r;
3653   apr_size_t   z2h_input_len;
3654
3655   jxhtml = GET_JXHTML(pdoc);
3656   doc   = jxhtml->doc;
3657   r     = doc->r;
3658
3659   textval = qs_get_node_value(doc,child);
3660   if (strlen(textval) == 0) {
3661     return jxhtml->out;
3662   }
3663
3664   tmp = apr_palloc(r->pool, qs_get_node_size(doc,child)+1);
3665   memset(tmp, 0, qs_get_node_size(doc,child)+1);
3666
3667   tdst     = qs_alloc_zero_byte_string(doc->buf.pool);
3668   memset(one_byte, 0, sizeof(one_byte));
3669   tdst_len = 0;
3670
3671   for (ii=0; ii<qs_get_node_size(doc,child); ii++) {
3672     char* out;
3673     int rtn = s_jxhtml_search_emoji(jxhtml, &textval[ii], &out);
3674     if (rtn) {
3675       tdst = qs_out_apr_pstrcat(r, tdst, out, &tdst_len);
3676       ii+=(rtn - 1);
3677       continue;
3678     }
3679
3680     if (is_sjis_kanji(textval[ii])) {
3681       one_byte[0] = textval[ii+0];
3682       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
3683       one_byte[0] = textval[ii+1];
3684       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
3685       ii++;
3686     }
3687     else 
3688     if (jxhtml->pre_flag) {
3689       one_byte[0] = textval[ii+0];
3690       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
3691     }
3692     else
3693     if (jxhtml->textarea_flag) {
3694       one_byte[0] = textval[ii+0];
3695       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
3696     }
3697     else {
3698       if (textval[ii] != '\r' && textval[ii] != '\n') {
3699         one_byte[0] = textval[ii+0];
3700         tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
3701       }
3702     }
3703   }
3704   z2h_input_len = strlen(tdst);
3705   tdst = chxj_conv_z2h(r, tdst, &z2h_input_len, jxhtml->entryp);
3706
3707   W_V(tdst);
3708   return jxhtml->out;
3709 }
3710
3711
3712 /**
3713  * It is a handler who processes the BLOCKQUOTE tag.
3714  *
3715  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
3716  *                     destination is specified.
3717  * @param node   [i]   The BLOCKQUOTE tag node is specified.
3718  * @return The conversion result is returned.
3719  */
3720 static char *
3721 s_jxhtml_start_blockquote_tag(void *pdoc, Node *node)
3722 {
3723   jxhtml_t *jxhtml;
3724   Doc      *doc;
3725   Attr     *attr;
3726   char     *attr_style = NULL;
3727   char     *attr_color = NULL;
3728   char     *attr_size  = NULL;
3729
3730   jxhtml  = GET_JXHTML(pdoc);
3731   doc     = jxhtml->doc;
3732   for (attr = qs_get_attr(doc,node);
3733        attr;
3734        attr = qs_get_next_attr(doc,attr)) {
3735     char *nm  = qs_get_attr_name(doc,attr);
3736     char *val = qs_get_attr_value(doc,attr);
3737     if (val && STRCASEEQ('s','S',"style", nm)) {
3738       attr_style = val;
3739     }
3740   }
3741   if (IS_CSS_ON(jxhtml->entryp)) {
3742     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
3743     if (style) {
3744       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
3745       css_property_t *font_size_prop = chxj_css_get_property_value(doc, style, "font-size");
3746       css_property_t *cur;
3747       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
3748         if (cur->value && *cur->value) {
3749           attr_color = apr_pstrdup(doc->pool, cur->value);
3750         }
3751       }
3752       for (cur = font_size_prop->next; cur != font_size_prop; cur = cur->next) {
3753         if (cur->value && *cur->value) {
3754           if (STRCASEEQ('x','X',"xx-small",cur->value)) {
3755             attr_size = apr_pstrdup(doc->pool, cur->value);
3756           }
3757           else if (STRCASEEQ('x','X',"x-small",cur->value)) {
3758             attr_size = apr_pstrdup(doc->pool, cur->value);
3759           }
3760           else if (STRCASEEQ('s','S',"small",cur->value)) {
3761             attr_size = apr_pstrdup(doc->pool, cur->value);
3762           }
3763           else if (STRCASEEQ('m','M',"medium",cur->value)) {
3764             attr_size = apr_pstrdup(doc->pool, cur->value);
3765           }
3766           else if (STRCASEEQ('l','L',"large",cur->value)) {
3767             attr_size = apr_pstrdup(doc->pool, cur->value);
3768           }
3769           else if (STRCASEEQ('x','X',"x-large",cur->value)) {
3770             attr_size = apr_pstrdup(doc->pool, cur->value);
3771           }
3772           else if (STRCASEEQ('x','X',"xx-large",cur->value)) {
3773             attr_size = apr_pstrdup(doc->pool, cur->value);
3774           }
3775         }
3776       }
3777     }
3778   }
3779   W_L("<blockquote");
3780   if (attr_color || attr_size) {
3781     W_L(" style=\"");
3782     if (attr_color) {
3783       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
3784       W_L("color:");
3785       W_V(attr_color);
3786       W_L(";");
3787     }
3788     if (attr_size) {
3789       W_L("font-size:");
3790       W_V(attr_size);
3791       W_L(";");
3792     }
3793     W_L("\"");
3794   }
3795   W_L(">");
3796   return jxhtml->out;
3797 }
3798
3799
3800 /**
3801  * It is a handler who processes the BLOCKQUOTE tag.
3802  *
3803  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
3804  *                     destination is specified.
3805  * @param node   [i]   The BLOCKQUOTE tag node is specified.
3806  * @return The conversion result is returned.
3807  */
3808 static char *
3809 s_jxhtml_end_blockquote_tag(void *pdoc, Node *UNUSED(child))
3810 {
3811   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
3812   Doc     *doc   = jxhtml->doc;
3813   W_L("</blockquote>");
3814   if (IS_CSS_ON(jxhtml->entryp)) {
3815     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
3816   }
3817   return jxhtml->out;
3818 }
3819
3820
3821 /**
3822  * It is a handler who processes the DIR tag.
3823  *
3824  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
3825  *                     destination is specified.
3826  * @param node   [i]   The DIR tag node is specified.
3827  * @return The conversion result is returned.
3828  */
3829 static char *
3830 s_jxhtml_start_dir_tag(void *pdoc, Node *node)
3831 {
3832   jxhtml_t *jxhtml      = GET_JXHTML(pdoc);
3833   Doc       *doc        = jxhtml->doc;
3834   Attr      *attr;
3835   char      *attr_style = NULL;
3836   char      *attr_color = NULL;
3837   char      *attr_type  = NULL;
3838   char      *attr_size  = NULL;
3839   for (attr = qs_get_attr(doc,node);
3840        attr;
3841        attr = qs_get_next_attr(doc,attr)) {
3842     char *name   = qs_get_attr_name(doc,attr);
3843     char *value  = qs_get_attr_value(doc,attr);
3844     if (STRCASEEQ('t','T',"type",name)) {
3845       if (value && (STRCASEEQ('d','D',"disc",value) || STRCASEEQ('c','C',"circle",value) || STRCASEEQ('s','S',"square",value))) {
3846         attr_type = value;
3847       }
3848     }
3849     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
3850       attr_style = value;
3851     }
3852   }
3853   if (IS_CSS_ON(jxhtml->entryp)) {
3854     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
3855     if (style) {
3856       css_property_t *color_prop           = chxj_css_get_property_value(doc, style, "color");
3857       css_property_t *size_prop            = chxj_css_get_property_value(doc, style, "font-size");
3858       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type");
3859       css_property_t *cur;
3860       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
3861         if (cur->value && *cur->value) {
3862           attr_color = apr_pstrdup(doc->pool, cur->value);
3863         }
3864       }
3865       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3866         if (cur->value && *cur->value) {
3867           attr_type = apr_pstrdup(doc->pool, cur->value);
3868         }
3869       }
3870       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
3871         if (cur->value && *cur->value) {
3872           if (STRCASEEQ('x','X',"xx-small",cur->value)) {
3873             attr_size = apr_pstrdup(doc->pool, cur->value);
3874           }
3875           else if (STRCASEEQ('x','X',"x-small",cur->value)) {
3876             attr_size = apr_pstrdup(doc->pool, cur->value);
3877           }
3878           else if (STRCASEEQ('s','S',"small",cur->value)) {
3879             attr_size = apr_pstrdup(doc->pool, cur->value);
3880           }
3881           else if (STRCASEEQ('m','M',"medium",cur->value)) {
3882             attr_size = apr_pstrdup(doc->pool, cur->value);
3883           }
3884           else if (STRCASEEQ('l','L',"large",cur->value)) {
3885             attr_size = apr_pstrdup(doc->pool, cur->value);
3886           }
3887           else if (STRCASEEQ('x','X',"x-large",cur->value)) {
3888             attr_size = apr_pstrdup(doc->pool, cur->value);
3889           }
3890           else if (STRCASEEQ('x','X',"xx-large",cur->value)) {
3891             attr_size = apr_pstrdup(doc->pool, cur->value);
3892           }
3893         }
3894       }
3895     }
3896   }
3897   W_L("<dir");
3898   if (attr_type || attr_color || attr_size) {
3899     W_L(" style=\"");
3900     if (attr_type) {
3901       W_L("list-style-type:");
3902       W_V(attr_type);
3903       W_L(";");
3904     }
3905     if (attr_color) {
3906       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
3907       W_L("color:");
3908       W_V(attr_color);
3909       W_L(";");
3910     }
3911     if (attr_size) {
3912       W_L("font-size:");
3913       W_V(attr_size);
3914       W_L(";");
3915     }
3916     W_L("\"");
3917   }
3918   W_L(">");
3919   return jxhtml->out;
3920 }
3921
3922
3923 /**
3924  * It is a handler who processes the DIR tag.
3925  *
3926  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
3927  *                     destination is specified.
3928  * @param node   [i]   The DIR tag node is specified.
3929  * @return The conversion result is returned.
3930  */
3931 static char *
3932 s_jxhtml_end_dir_tag(void *pdoc, Node *UNUSED(child))
3933 {
3934   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
3935   Doc *doc = jxhtml->doc;
3936   W_L("</dir>");
3937   if (IS_CSS_ON(jxhtml->entryp)) {
3938     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
3939   }
3940   return jxhtml->out;
3941 }
3942
3943
3944 /**
3945  * It is a handler who processes the DL tag.
3946  *
3947  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
3948  *                     destination is specified.
3949  * @param node   [i]   The DL tag node is specified.
3950  * @return The conversion result is returned.
3951  */
3952 static char *
3953 s_jxhtml_start_dl_tag(void *pdoc, Node *node)
3954 {
3955   jxhtml_t *jxhtml      = GET_JXHTML(pdoc);
3956   Doc       *doc        = jxhtml->doc;
3957   Attr      *attr;
3958   char      *attr_style = NULL;
3959   char      *attr_color = NULL;
3960   char      *attr_size  = NULL;
3961   for (attr = qs_get_attr(doc,node);
3962        attr;
3963        attr = qs_get_next_attr(doc,attr)) {
3964     char *name   = qs_get_attr_name(doc,attr);
3965     char *value  = qs_get_attr_value(doc,attr);
3966     if (STRCASEEQ('s','S',"style", name) && value && *value) {
3967       attr_style = value;
3968     }
3969   }
3970   if (IS_CSS_ON(jxhtml->entryp)) {
3971     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
3972     if (style) {
3973       css_property_t *color_prop           = chxj_css_get_property_value(doc, style, "color");
3974       css_property_t *size_prop            = chxj_css_get_property_value(doc, style, "font-size");
3975       css_property_t *cur;
3976       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
3977         if (cur->value && *cur->value) {
3978           attr_color = apr_pstrdup(doc->pool, cur->value);
3979         }
3980       }
3981       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
3982         if (cur->value && *cur->value) {
3983           if (STRCASEEQ('x','X',"xx-small",cur->value)) {
3984             attr_size = apr_pstrdup(doc->pool, cur->value);
3985           }
3986           else if (STRCASEEQ('x','X',"x-small",cur->value)) {
3987             attr_size = apr_pstrdup(doc->pool, cur->value);
3988           }
3989           else if (STRCASEEQ('s','S',"small",cur->value)) {
3990             attr_size = apr_pstrdup(doc->pool, cur->value);
3991           }
3992           else if (STRCASEEQ('m','M',"medium",cur->value)) {
3993             attr_size = apr_pstrdup(doc->pool, cur->value);
3994           }
3995           else if (STRCASEEQ('l','L',"large",cur->value)) {
3996             attr_size = apr_pstrdup(doc->pool, cur->value);
3997           }
3998           else if (STRCASEEQ('x','X',"x-large",cur->value)) {
3999             attr_size = apr_pstrdup(doc->pool, cur->value);
4000           }
4001           else if (STRCASEEQ('x','X',"xx-large",cur->value)) {
4002             attr_size = apr_pstrdup(doc->pool, cur->value);
4003           }
4004         }
4005       }
4006     }
4007   }
4008   W_L("<dl");
4009   if (attr_color || attr_size) {
4010     W_L(" style=\"");
4011     if (attr_color) {
4012       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
4013       W_L("color:");
4014       W_V(attr_color);
4015       W_L(";");
4016     }
4017     if (attr_size) {
4018       W_L("font-size:");
4019       W_V(attr_size);
4020       W_L(";");
4021     }
4022     W_L("\"");
4023   }
4024   W_L(">");
4025   return jxhtml->out;
4026 }
4027
4028
4029 /**
4030  * It is a handler who processes the DL tag.
4031  *
4032  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
4033  *                     destination is specified.
4034  * @param node   [i]   The DL tag node is specified.
4035  * @return The conversion result is returned.
4036  */
4037 static char *
4038 s_jxhtml_end_dl_tag(void *pdoc, Node *UNUSED(child))
4039 {
4040   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
4041   Doc *doc = jxhtml->doc;
4042   W_L("</dl>");
4043   if (IS_CSS_ON(jxhtml->entryp)) {
4044     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
4045   }
4046   return jxhtml->out;
4047 }
4048
4049
4050 /**
4051  * It is a handler who processes the DT tag.
4052  *
4053  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
4054  *                     destination is specified.
4055  * @param node   [i]   The DT tag node is specified.
4056  * @return The conversion result is returned.
4057  */
4058 static char *
4059 s_jxhtml_start_dt_tag(void *pdoc, Node *node)
4060 {
4061   jxhtml_t *jxhtml      = GET_JXHTML(pdoc);
4062   Doc       *doc        = jxhtml->doc;
4063   Attr      *attr;
4064   char      *attr_style = NULL;
4065   char      *attr_color = NULL;
4066   char      *attr_size  = NULL;
4067   for (attr = qs_get_attr(doc,node);
4068        attr;
4069        attr = qs_get_next_attr(doc,attr)) {
4070     char *name   = qs_get_attr_name(doc,attr);
4071     char *value  = qs_get_attr_value(doc,attr);
4072     if (STRCASEEQ('s','S',"style", name) && value && *value) {
4073       attr_style = value;
4074     }
4075   }
4076   if (IS_CSS_ON(jxhtml->entryp)) {
4077     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
4078     if (style) {
4079       css_property_t *color_prop           = chxj_css_get_property_value(doc, style, "color");
4080       css_property_t *size_prop            = chxj_css_get_property_value(doc, style, "font-size");
4081       css_property_t *cur;
4082       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
4083         if (cur->value && *cur->value) {
4084           attr_color = apr_pstrdup(doc->pool, cur->value);
4085         }
4086       }
4087       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
4088         if (cur->value && *cur->value) {
4089           if (STRCASEEQ('x','X',"xx-small",cur->value)) {
4090             attr_size = apr_pstrdup(doc->pool, cur->value);
4091           }
4092           else if (STRCASEEQ('x','X',"x-small",cur->value)) {
4093             attr_size = apr_pstrdup(doc->pool, cur->value);
4094           }
4095           else if (STRCASEEQ('s','S',"small",cur->value)) {
4096             attr_size = apr_pstrdup(doc->pool, cur->value);
4097           }
4098           else if (STRCASEEQ('m','M',"medium",cur->value)) {
4099             attr_size = apr_pstrdup(doc->pool, cur->value);
4100           }
4101           else if (STRCASEEQ('l','L',"large",cur->value)) {
4102             attr_size = apr_pstrdup(doc->pool, cur->value);
4103           }
4104           else if (STRCASEEQ('x','X',"x-large",cur->value)) {
4105             attr_size = apr_pstrdup(doc->pool, cur->value);
4106           }
4107           else if (STRCASEEQ('x','X',"xx-large",cur->value)) {
4108             attr_size = apr_pstrdup(doc->pool, cur->value);
4109           }
4110         }
4111       }
4112     }
4113   }
4114   W_L("<dt");
4115   if (attr_color || attr_size) {
4116     W_L(" style=\"");
4117     if (attr_color) {
4118       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
4119       W_L("color:");
4120       W_V(attr_color);
4121       W_L(";");
4122     }
4123     if (attr_size) {
4124       W_L("font-size:");
4125       W_V(attr_size);
4126       W_L(";");
4127     }
4128     W_L("\"");
4129   }
4130   W_L(">");
4131   return jxhtml->out;
4132 }
4133
4134
4135 /**
4136  * It is a handler who processes the DT tag.
4137  *
4138  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
4139  *                     destination is specified.
4140  * @param node   [i]   The DT tag node is specified.
4141  * @return The conversion result is returned.
4142  */
4143 static char *
4144 s_jxhtml_end_dt_tag(void *pdoc, Node *UNUSED(child))
4145 {
4146   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
4147   Doc      *doc    = jxhtml->doc;
4148   W_L("</dt>");
4149   if (IS_CSS_ON(jxhtml->entryp)) {
4150     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
4151   }
4152   return jxhtml->out;
4153 }
4154
4155
4156 /**
4157  * It is a handler who processes the DD tag.
4158  *
4159  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
4160  *                     destination is specified.
4161  * @param node   [i]   The DD tag node is specified.
4162  * @return The conversion result is returned.
4163  */
4164 static char *
4165 s_jxhtml_start_dd_tag(void *pdoc, Node *node)
4166 {
4167   jxhtml_t *jxhtml      = GET_JXHTML(pdoc);
4168   Doc       *doc        = jxhtml->doc;
4169   Attr      *attr;
4170   char      *attr_style = NULL;
4171   char      *attr_color = NULL;
4172   char      *attr_size  = NULL;
4173   for (attr = qs_get_attr(doc,node);
4174        attr;
4175        attr = qs_get_next_attr(doc,attr)) {
4176     char *name   = qs_get_attr_name(doc,attr);
4177     char *value  = qs_get_attr_value(doc,attr);
4178     if (STRCASEEQ('s','S',"style", name) && value && *value) {
4179       attr_style = value;
4180     }
4181   }
4182   if (IS_CSS_ON(jxhtml->entryp)) {
4183     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
4184     if (style) {
4185       css_property_t *color_prop           = chxj_css_get_property_value(doc, style, "color");
4186       css_property_t *size_prop            = chxj_css_get_property_value(doc, style, "font-size");
4187       css_property_t *cur;
4188       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
4189         if (cur->value && *cur->value) {
4190           attr_color = apr_pstrdup(doc->pool, cur->value);
4191         }
4192       }
4193       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
4194         if (cur->value && *cur->value) {
4195           if (STRCASEEQ('x','X',"xx-small",cur->value)) {
4196             attr_size = apr_pstrdup(doc->pool, cur->value);
4197           }
4198           else if (STRCASEEQ('x','X',"x-small",cur->value)) {
4199             attr_size = apr_pstrdup(doc->pool, cur->value);
4200           }
4201           else if (STRCASEEQ('s','S',"small",cur->value)) {
4202             attr_size = apr_pstrdup(doc->pool, cur->value);
4203           }
4204           else if (STRCASEEQ('m','M',"medium",cur->value)) {
4205             attr_size = apr_pstrdup(doc->pool, cur->value);
4206           }
4207           else if (STRCASEEQ('l','L',"large",cur->value)) {
4208             attr_size = apr_pstrdup(doc->pool, cur->value);
4209           }
4210           else if (STRCASEEQ('x','X',"x-large",cur->value)) {
4211             attr_size = apr_pstrdup(doc->pool, cur->value);
4212           }
4213           else if (STRCASEEQ('x','X',"xx-large",cur->value)) {
4214             attr_size = apr_pstrdup(doc->pool, cur->value);
4215           }
4216         }
4217       }
4218     }
4219   }
4220   W_L("<dd");
4221   if (attr_color || attr_size) {
4222     W_L(" style=\"");
4223     if (attr_color) {
4224       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
4225       W_L("color:");
4226       W_V(attr_color);
4227       W_L(";");
4228     }
4229     if (attr_size) {
4230       W_L("font-size:");
4231       W_V(attr_size);
4232       W_L(";");
4233     }
4234     W_L("\"");
4235   }
4236   W_L(">");
4237   return jxhtml->out;
4238 }
4239
4240
4241 /**
4242  * It is a handler who processes the DD tag.
4243  *
4244  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
4245  *                     destination is specified.
4246  * @param node   [i]   The DD tag node is specified.
4247  * @return The conversion result is returned.
4248  */
4249 static char *
4250 s_jxhtml_end_dd_tag(void *pdoc, Node *UNUSED(child))
4251 {
4252   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
4253   Doc      *doc = jxhtml->doc;
4254   W_L("</dd>");
4255   if (IS_CSS_ON(jxhtml->entryp)) {
4256     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
4257   }
4258   return jxhtml->out;
4259 }
4260
4261
4262 /**
4263  * It is a handler who processes the H1 tag.
4264  *
4265  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
4266  *                     destination is specified.
4267  * @param node   [i]   The H1 tag node is specified.
4268  * @return The conversion result is returned.
4269  */
4270 static char *
4271 s_jxhtml_start_h1_tag(void *pdoc, Node *node)
4272 {
4273   jxhtml_t    *jxhtml;
4274   Doc         *doc;
4275   request_rec *r;
4276   Attr        *attr;
4277   char        *attr_style = NULL;
4278   char        *attr_align = NULL;
4279
4280   jxhtml = GET_JXHTML(pdoc);
4281   doc    = jxhtml->doc;
4282   r      = doc->r;
4283
4284   for (attr = qs_get_attr(doc,node);
4285        attr;
4286        attr = qs_get_next_attr(doc,attr)) {
4287     char *name  = qs_get_attr_name(doc,attr);
4288     char *value = qs_get_attr_value(doc,attr);
4289     if (STRCASEEQ('a','A',"align", name)) {
4290       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
4291         attr_align = value;
4292       }
4293     }
4294     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
4295       attr_style = value;
4296     }
4297   }
4298   if (IS_CSS_ON(jxhtml->entryp)) {
4299     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
4300     if (style) {
4301       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
4302       css_property_t *cur;
4303       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
4304         if (STRCASEEQ('l','L',"left", cur->value)) {
4305           attr_align = apr_pstrdup(doc->pool, "left");
4306         }
4307         else if (STRCASEEQ('c','C',"center",cur->value)) {
4308           attr_align = apr_pstrdup(doc->pool, "center");
4309         }
4310         else if (STRCASEEQ('r','R',"right",cur->value)) {
4311           attr_align = apr_pstrdup(doc->pool, "right");
4312         }
4313       }
4314     }
4315   }
4316   W_L("<div");
4317   W_L(" style=\""); 
4318   W_L("font-size:xx-large;");
4319   if (attr_align) {
4320     W_L("text-align:");
4321     W_V(attr_align);
4322     W_L(";");
4323   }
4324   W_L("\">");
4325
4326   return jxhtml->out;
4327 }
4328
4329
4330 /**
4331  * It is a handler who processes the H1 tag.
4332  *
4333  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
4334  *                     destination is specified.
4335  * @param node   [i]   The H1 tag node is specified.
4336  * @return The conversion result is returned.
4337  */
4338 static char *
4339 s_jxhtml_end_h1_tag(void *pdoc, Node *UNUSED(child)) 
4340 {
4341   jxhtml_t*    jxhtml;
4342   Doc*          doc;
4343   request_rec*  r;
4344
4345   jxhtml = GET_JXHTML(pdoc);
4346   doc     = jxhtml->doc;
4347   r       = doc->r;
4348   
4349   W_L("</div>");
4350   if (IS_CSS_ON(jxhtml->entryp)) {
4351     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
4352   }
4353
4354   return jxhtml->out;
4355 }
4356
4357
4358 /**
4359  * It is a handler who processes the H2 tag.
4360  *
4361  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
4362  *                     destination is specified.
4363  * @param node   [i]   The H1 tag node is specified.
4364  * @return The conversion result is returned.
4365  */
4366 static char *
4367 s_jxhtml_start_h2_tag(void *pdoc, Node *node)
4368 {
4369   jxhtml_t    *jxhtml;
4370   Doc         *doc;
4371   request_rec *r;
4372   Attr        *attr;
4373   char        *attr_style = NULL;
4374   char        *attr_align = NULL;
4375
4376   jxhtml   = GET_JXHTML(pdoc);
4377   doc     = jxhtml->doc;
4378   r       = doc->r;
4379
4380   for (attr = qs_get_attr(doc,node);
4381        attr;
4382        attr = qs_get_next_attr(doc,attr)) {
4383     char *name  = qs_get_attr_name(doc,attr);
4384     char *value = qs_get_attr_value(doc,attr);
4385     if (STRCASEEQ('a','A',"align", name)) {
4386       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
4387         attr_align = value;
4388       }
4389     }
4390     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
4391       attr_style = value;
4392     }
4393   }
4394   if (IS_CSS_ON(jxhtml->entryp)) {
4395     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
4396     if (style) {
4397       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
4398       css_property_t *cur;
4399       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
4400         if (STRCASEEQ('l','L',"left", cur->value)) {
4401           attr_align = apr_pstrdup(doc->pool, "left");
4402         }
4403         else if (STRCASEEQ('c','C',"center",cur->value)) {
4404           attr_align = apr_pstrdup(doc->pool, "center");
4405         }
4406         else if (STRCASEEQ('r','R',"right",cur->value)) {
4407           attr_align = apr_pstrdup(doc->pool, "right");
4408         }
4409       }
4410     }
4411   }
4412   W_L("<div");
4413   W_L(" style=\""); 
4414   W_L("font-size:x-large;");
4415   if (attr_align) {
4416     W_L("text-align:");
4417     W_V(attr_align);
4418     W_L(";");
4419   }
4420   W_L("\">");
4421
4422   return jxhtml->out;
4423 }
4424
4425
4426 /**
4427  * It is a handler who processes the H2 tag.
4428  *
4429  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
4430  *                     destination is specified.
4431  * @param node   [i]   The H1 tag node is specified.
4432  * @return The conversion result is returned.
4433  */
4434 static char *
4435 s_jxhtml_end_h2_tag(void *pdoc, Node *UNUSED(child)) 
4436 {
4437   jxhtml_t*    jxhtml;
4438   Doc*          doc;
4439   request_rec*  r;
4440
4441   jxhtml = GET_JXHTML(pdoc);
4442   doc     = jxhtml->doc;
4443   r       = doc->r;
4444   
4445   W_L("</div>");
4446   if (IS_CSS_ON(jxhtml->entryp)) {
4447     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
4448   }
4449   return jxhtml->out;
4450 }
4451
4452
4453 /**
4454  * It is a handler who processes the H3 tag.
4455  *
4456  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
4457  *                     destination is specified.
4458  * @param node   [i]   The H1 tag node is specified.
4459  * @return The conversion result is returned.
4460  */
4461 static char *
4462 s_jxhtml_start_h3_tag(void *pdoc, Node *node)
4463 {
4464   jxhtml_t    *jxhtml;
4465   Doc         *doc;
4466   request_rec *r;
4467   Attr        *attr;
4468   char        *attr_style = NULL;
4469   char        *attr_align = NULL;
4470
4471   jxhtml   = GET_JXHTML(pdoc);
4472   doc     = jxhtml->doc;
4473   r       = doc->r;
4474
4475   for (attr = qs_get_attr(doc,node);
4476        attr;
4477        attr = qs_get_next_attr(doc,attr)) {
4478     char *name  = qs_get_attr_name(doc,attr);
4479     char *value = qs_get_attr_value(doc,attr);
4480     if (STRCASEEQ('a','A',"align", name)) {
4481       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
4482         attr_align = value;
4483       }
4484     }
4485     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
4486       attr_style = value;
4487     }
4488   }
4489   if (IS_CSS_ON(jxhtml->entryp)) {
4490     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
4491     if (style) {
4492       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
4493       css_property_t *cur;
4494       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
4495         if (STRCASEEQ('l','L',"left", cur->value)) {
4496           attr_align = apr_pstrdup(doc->pool, "left");
4497         }
4498         else if (STRCASEEQ('c','C',"center",cur->value)) {
4499           attr_align = apr_pstrdup(doc->pool, "center");
4500         }
4501         else if (STRCASEEQ('r','R',"right",cur->value)) {
4502           attr_align = apr_pstrdup(doc->pool, "right");
4503         }
4504       }
4505     }
4506   }
4507   W_L("<div");
4508   W_L(" style=\""); 
4509   W_L("font-size:large;");
4510   if (attr_align) {
4511     W_L("text-align:");
4512     W_V(attr_align);
4513     W_L(";");
4514   }
4515   W_L("\">");
4516
4517   return jxhtml->out;
4518 }
4519
4520
4521 /**
4522  * It is a handler who processes the H3 tag.
4523  *
4524  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
4525  *                     destination is specified.
4526  * @param node   [i]   The H1 tag node is specified.
4527  * @return The conversion result is returned.
4528  */
4529 static char *
4530 s_jxhtml_end_h3_tag(void *pdoc, Node *UNUSED(child)) 
4531 {
4532   jxhtml_t*    jxhtml;
4533   Doc*          doc;
4534   request_rec*  r;
4535
4536   jxhtml = GET_JXHTML(pdoc);
4537   doc     = jxhtml->doc;
4538   r       = doc->r;
4539
4540   W_L("</div>");
4541   if (IS_CSS_ON(jxhtml->entryp)) {
4542     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
4543   }
4544   return jxhtml->out;
4545 }
4546
4547
4548 /**
4549  * It is a handler who processes the H4 tag.
4550  *
4551  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
4552  *                     destination is specified.
4553  * @param node   [i]   The H1 tag node is specified.
4554  * @return The conversion result is returned.
4555  */
4556 static char *
4557 s_jxhtml_start_h4_tag(void *pdoc, Node *node)
4558 {
4559   jxhtml_t    *jxhtml;
4560   Doc         *doc;
4561   request_rec *r;
4562   Attr        *attr;
4563   char        *attr_style = NULL;
4564   char        *attr_align = NULL;
4565
4566   jxhtml   = GET_JXHTML(pdoc);
4567   doc     = jxhtml->doc;
4568   r       = doc->r;
4569
4570   for (attr = qs_get_attr(doc,node);
4571        attr;
4572        attr = qs_get_next_attr(doc,attr)) {
4573     char *name  = qs_get_attr_name(doc,attr);
4574     char *value = qs_get_attr_value(doc,attr);
4575     if (STRCASEEQ('a','A',"align", name)) {
4576       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
4577         attr_align = value;
4578       }
4579     }
4580     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
4581       attr_style = value;
4582     }
4583   }
4584   if (IS_CSS_ON(jxhtml->entryp)) {
4585     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
4586     if (style) {
4587       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
4588       css_property_t *cur;
4589       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
4590         if (STRCASEEQ('l','L',"left", cur->value)) {
4591           attr_align = apr_pstrdup(doc->pool, "left");
4592         }
4593         else if (STRCASEEQ('c','C',"center",cur->value)) {
4594           attr_align = apr_pstrdup(doc->pool, "center");
4595         }
4596         else if (STRCASEEQ('r','R',"right",cur->value)) {
4597           attr_align = apr_pstrdup(doc->pool, "right");
4598         }
4599       }
4600     }
4601   }
4602   W_L("<div");
4603   W_L(" style=\""); 
4604   W_L("font-size:small;");
4605   if (attr_align) {
4606     W_L("text-align:");
4607     W_V(attr_align);
4608     W_L(";");
4609   }
4610   W_L("\">");
4611
4612   return jxhtml->out;
4613 }
4614
4615
4616 /**
4617  * It is a handler who processes the H4 tag.
4618  *
4619  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
4620  *                     destination is specified.
4621  * @param node   [i]   The H1 tag node is specified.
4622  * @return The conversion result is returned.
4623  */
4624 static char *
4625 s_jxhtml_end_h4_tag(void *pdoc, Node *UNUSED(child)) 
4626 {
4627   jxhtml_t      *jxhtml;
4628   Doc           *doc;
4629   request_rec   *r;
4630
4631   jxhtml = GET_JXHTML(pdoc);
4632   doc     = jxhtml->doc;
4633   r       = doc->r;
4634   
4635   W_L("</div>");
4636   if (IS_CSS_ON(jxhtml->entryp)) {
4637     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
4638   }
4639
4640   return jxhtml->out;
4641 }
4642
4643
4644 /**
4645  * It is a handler who processes the H5 tag.
4646  *
4647  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
4648  *                     destination is specified.
4649  * @param node   [i]   The H1 tag node is specified.
4650  * @return The conversion result is returned.
4651  */
4652 static char *
4653 s_jxhtml_start_h5_tag(void *pdoc, Node *node)
4654 {
4655   jxhtml_t    *jxhtml;
4656   Doc         *doc;
4657   request_rec *r;
4658   Attr        *attr;
4659   char        *attr_style = NULL;
4660   char        *attr_align = NULL;
4661
4662   jxhtml   = GET_JXHTML(pdoc);
4663   doc     = jxhtml->doc;
4664   r       = doc->r;
4665
4666   for (attr = qs_get_attr(doc,node);
4667        attr;
4668        attr = qs_get_next_attr(doc,attr)) {
4669     char *name  = qs_get_attr_name(doc,attr);
4670     char *value = qs_get_attr_value(doc,attr);
4671     if (STRCASEEQ('a','A',"align", name)) {
4672       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
4673         attr_align = value;
4674       }
4675     }
4676     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
4677       attr_style = value;
4678     }
4679   }
4680   if (IS_CSS_ON(jxhtml->entryp)) {
4681     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
4682     if (style) {
4683       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
4684       css_property_t *cur;
4685       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
4686         if (STRCASEEQ('l','L',"left", cur->value)) {
4687           attr_align = apr_pstrdup(doc->pool, "left");
4688         }
4689         else if (STRCASEEQ('c','C',"center",cur->value)) {
4690           attr_align = apr_pstrdup(doc->pool, "center");
4691         }
4692         else if (STRCASEEQ('r','R',"right",cur->value)) {
4693           attr_align = apr_pstrdup(doc->pool, "right");
4694         }
4695       }
4696     }
4697   }
4698   W_L("<div");
4699   W_L(" style=\""); 
4700   W_L("font-size:x-small;");
4701   if (attr_align) {
4702     W_L("text-align:");
4703     W_V(attr_align);
4704     W_L(";");
4705   }
4706   W_L("\">");
4707
4708   return jxhtml->out;
4709 }
4710
4711
4712 /**
4713  * It is a handler who processes the H5 tag.
4714  *
4715  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
4716  *                     destination is specified.
4717  * @param node   [i]   The H1 tag node is specified.
4718  * @return The conversion result is returned.
4719  */
4720 static char *
4721 s_jxhtml_end_h5_tag(void *pdoc, Node *UNUSED(child)) 
4722 {
4723   jxhtml_t    *jxhtml;
4724   Doc         *doc;
4725   request_rec *r;
4726
4727   jxhtml = GET_JXHTML(pdoc);
4728   doc     = jxhtml->doc;
4729   r       = doc->r;
4730   
4731   W_L("</div>");
4732   if (IS_CSS_ON(jxhtml->entryp)) {
4733     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
4734   }
4735
4736   return jxhtml->out;
4737 }
4738
4739
4740 /**
4741  * It is a handler who processes the H6 tag.
4742  *
4743  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
4744  *                     destination is specified.
4745  * @param node   [i]   The H1 tag node is specified.
4746  * @return The conversion result is returned.
4747  */
4748 static char *
4749 s_jxhtml_start_h6_tag(void *pdoc, Node *node)
4750 {
4751   jxhtml_t    *jxhtml;
4752   Doc         *doc;
4753   request_rec *r;
4754   Attr        *attr;
4755   char        *attr_style = NULL;
4756   char        *attr_align = NULL;
4757
4758   jxhtml   = GET_JXHTML(pdoc);
4759   doc     = jxhtml->doc;
4760   r       = doc->r;
4761
4762   for (attr = qs_get_attr(doc,node);
4763        attr;
4764        attr = qs_get_next_attr(doc,attr)) {
4765     char *name  = qs_get_attr_name(doc,attr);
4766     char *value = qs_get_attr_value(doc,attr);
4767     if (STRCASEEQ('a','A',"align", name)) {
4768       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
4769         attr_align = value;
4770       }
4771     }
4772     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
4773       attr_style = value;
4774     }
4775   }
4776   if (IS_CSS_ON(jxhtml->entryp)) {
4777     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
4778     if (style) {
4779       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
4780       css_property_t *cur;
4781       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
4782         if (STRCASEEQ('l','L',"left", cur->value)) {
4783           attr_align = apr_pstrdup(doc->pool, "left");
4784         }
4785         else if (STRCASEEQ('c','C',"center",cur->value)) {
4786           attr_align = apr_pstrdup(doc->pool, "center");
4787         }
4788         else if (STRCASEEQ('r','R',"right",cur->value)) {
4789           attr_align = apr_pstrdup(doc->pool, "right");
4790         }
4791       }
4792     }
4793   }
4794   W_L("<div");
4795   W_L(" style=\""); 
4796   W_L("font-size:xx-small;");
4797   if (attr_align) {
4798     W_L("text-align:");
4799     W_V(attr_align);
4800     W_L(";");
4801   }
4802   W_L("\">");
4803
4804   return jxhtml->out;
4805 }
4806
4807
4808 /**
4809  * It is a handler who processes the H6 tag.
4810  *
4811  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
4812  *                     destination is specified.
4813  * @param node   [i]   The H1 tag node is specified.
4814  * @return The conversion result is returned.
4815  */
4816 static char *
4817 s_jxhtml_end_h6_tag(void *pdoc, Node *UNUSED(child)) 
4818 {
4819   jxhtml_t    *jxhtml;
4820   Doc         *doc;
4821   request_rec *r;
4822
4823   jxhtml = GET_JXHTML(pdoc);
4824   doc     = jxhtml->doc;
4825   r       = doc->r;
4826   
4827   W_L("</div>");
4828   if (IS_CSS_ON(jxhtml->entryp)) {
4829     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
4830   }
4831
4832   return jxhtml->out;
4833 }
4834
4835
4836 /**
4837  * It is a handler who processes the MENU tag.
4838  *
4839  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
4840  *                     destination is specified.
4841  * @param node   [i]   The MENU tag node is specified.
4842  * @return The conversion result is returned.
4843  */
4844 static char *
4845 s_jxhtml_start_menu_tag(void *pdoc, Node *node)
4846 {
4847   jxhtml_t *jxhtml      = GET_JXHTML(pdoc);
4848   Doc       *doc        = jxhtml->doc;
4849   Attr      *attr;
4850   char      *attr_style = NULL;
4851   char      *attr_color = NULL;
4852   char      *attr_type  = NULL;
4853   char      *attr_size  = NULL;
4854   for (attr = qs_get_attr(doc,node);
4855        attr;
4856        attr = qs_get_next_attr(doc,attr)) {
4857     char *name   = qs_get_attr_name(doc,attr);
4858     char *value  = qs_get_attr_value(doc,attr);
4859     if (STRCASEEQ('t','T',"type",name)) {
4860       if (value && (STRCASEEQ('d','D',"disc",value) || STRCASEEQ('c','C',"circle",value) || STRCASEEQ('s','S',"square",value))) {
4861         attr_type = value;
4862       }
4863     }
4864     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
4865       attr_style = value;
4866     }
4867   }
4868   if (IS_CSS_ON(jxhtml->entryp)) {
4869     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
4870     if (style) {
4871       css_property_t *color_prop           = chxj_css_get_property_value(doc, style, "color");
4872       css_property_t *size_prop            = chxj_css_get_property_value(doc, style, "font-size");
4873       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type");
4874       css_property_t *cur;
4875       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
4876         if (cur->value && *cur->value) {
4877           attr_color = apr_pstrdup(doc->pool, cur->value);
4878         }
4879       }
4880       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
4881         if (cur->value && *cur->value) {
4882           attr_type = apr_pstrdup(doc->pool, cur->value);
4883         }
4884       }
4885       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
4886         if (cur->value && *cur->value) {
4887           if (STRCASEEQ('x','X',"xx-small",cur->value)) {
4888             attr_size = apr_pstrdup(doc->pool, cur->value);
4889           }
4890           else if (STRCASEEQ('x','X',"x-small",cur->value)) {
4891             attr_size = apr_pstrdup(doc->pool, cur->value);
4892           }
4893           else if (STRCASEEQ('s','S',"small",cur->value)) {
4894             attr_size = apr_pstrdup(doc->pool, cur->value);
4895           }
4896           else if (STRCASEEQ('m','M',"medium",cur->value)) {
4897             attr_size = apr_pstrdup(doc->pool, cur->value);
4898           }
4899           else if (STRCASEEQ('l','L',"large",cur->value)) {
4900             attr_size = apr_pstrdup(doc->pool, cur->value);
4901           }
4902           else if (STRCASEEQ('x','X',"x-large",cur->value)) {
4903             attr_size = apr_pstrdup(doc->pool, cur->value);
4904           }
4905           else if (STRCASEEQ('x','X',"xx-large",cur->value)) {
4906             attr_size = apr_pstrdup(doc->pool, cur->value);
4907           }
4908         }
4909       }
4910     }
4911   }
4912   W_L("<menu");
4913   if (attr_type || attr_color || attr_size) {
4914     W_L(" style=\"");
4915     if (attr_type) {
4916       W_L("list-style-type:");
4917       W_V(attr_type);
4918       W_L(";");
4919     }
4920     if (attr_color) {
4921       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
4922       W_L("color:");
4923       W_V(attr_color);
4924       W_L(";");
4925     }
4926     if (attr_size) {
4927       W_L("font-size:");
4928       W_V(attr_size);
4929       W_L(";");
4930     }
4931     W_L("\"");
4932   }
4933   W_L(">");
4934   return jxhtml->out;
4935 }
4936
4937
4938 /**
4939  * It is a handler who processes the MENU tag.
4940  *
4941  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
4942  *                     destination is specified.
4943  * @param node   [i]   The MENU tag node is specified.
4944  * @return The conversion result is returned.
4945  */
4946 static char *
4947 s_jxhtml_end_menu_tag(void *pdoc, Node *UNUSED(child))
4948 {
4949   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
4950   Doc *doc = jxhtml->doc;
4951   W_L("</menu>");
4952   if (IS_CSS_ON(jxhtml->entryp)) {
4953     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
4954   }
4955   return jxhtml->out;
4956 }
4957
4958
4959 /**
4960  * It is a handler who processes the PLAINTEXT tag.
4961  *
4962  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
4963  *                     destination is specified.
4964  * @param node   [i]   The PLAINTEXT tag node is specified.
4965  * @return The conversion result is returned.
4966  */
4967 static char *
4968 s_jxhtml_start_plaintext_tag(void *pdoc, Node *node)
4969 {
4970   jxhtml_t *jxhtml;
4971   Doc *doc;
4972
4973   jxhtml = GET_JXHTML(pdoc);
4974   doc     = jxhtml->doc;
4975   W_L("<plaintext>");
4976   s_jxhtml_start_plaintext_tag_inner(pdoc,node);
4977   return jxhtml->out;
4978 }
4979
4980 static char *
4981 s_jxhtml_start_plaintext_tag_inner(void *pdoc, Node *node)
4982 {
4983   jxhtml_t *jxhtml;
4984   Doc *doc;
4985   Node *child;
4986   jxhtml = GET_JXHTML(pdoc);
4987   doc     = jxhtml->doc;
4988   for (child = qs_get_child_node(doc, node);
4989        child;
4990        child = qs_get_next_node(doc, child)) {
4991     W_V(child->otext);
4992     s_jxhtml_start_plaintext_tag_inner(pdoc, child);
4993   }
4994   return jxhtml->out;
4995 }
4996
4997
4998 /**
4999  * It is a handler who processes the PLAINTEXT tag.
5000  *
5001  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
5002  *                     destination is specified.
5003  * @param node   [i]   The PLAINTEXT tag node is specified.
5004  * @return The conversion result is returned.
5005  */
5006 static char *
5007 s_jxhtml_end_plaintext_tag(void *pdoc, Node *UNUSED(child))
5008 {
5009   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
5010   return jxhtml->out;
5011 }
5012
5013
5014 /**
5015  * It is a handler who processes the BLINK tag.
5016  *
5017  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
5018  *                     destination is specified.
5019  * @param node   [i]   The BLINK tag node is specified.
5020  * @return The conversion result is returned.
5021  */
5022 static char *
5023 s_jxhtml_start_blink_tag(void *pdoc, Node *node)
5024 {
5025   jxhtml_t *jxhtml      = GET_JXHTML(pdoc);
5026   Doc       *doc        = jxhtml->doc;
5027   Attr      *attr;
5028   char      *attr_style = NULL;
5029   char      *attr_color = NULL;
5030   char      *attr_size  = NULL;
5031   for (attr = qs_get_attr(doc,node);
5032        attr;
5033        attr = qs_get_next_attr(doc,attr)) {
5034     char *name   = qs_get_attr_name(doc,attr);
5035     char *value  = qs_get_attr_value(doc,attr);
5036     if (STRCASEEQ('s','S',"style", name) && value && *value) {
5037       attr_style = value;
5038     }
5039   }
5040   if (IS_CSS_ON(jxhtml->entryp)) {
5041     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
5042     if (style) {
5043       css_property_t *color_prop           = chxj_css_get_property_value(doc, style, "color");
5044       css_property_t *size_prop            = chxj_css_get_property_value(doc, style, "font-size");
5045       css_property_t *cur;
5046       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
5047         if (cur->value && *cur->value) {
5048           attr_color = apr_pstrdup(doc->pool, cur->value);
5049         }
5050       }
5051       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
5052         if (cur->value && *cur->value) {
5053           if (STRCASEEQ('x','X',"xx-small",cur->value)) {
5054             attr_size = apr_pstrdup(doc->pool, cur->value);
5055           }
5056           else if (STRCASEEQ('x','X',"x-small",cur->value)) {
5057             attr_size = apr_pstrdup(doc->pool, cur->value);
5058           }
5059           else if (STRCASEEQ('s','S',"small",cur->value)) {
5060             attr_size = apr_pstrdup(doc->pool, cur->value);
5061           }
5062           else if (STRCASEEQ('m','M',"medium",cur->value)) {
5063             attr_size = apr_pstrdup(doc->pool, cur->value);
5064           }
5065           else if (STRCASEEQ('l','L',"large",cur->value)) {
5066             attr_size = apr_pstrdup(doc->pool, cur->value);
5067           }
5068           else if (STRCASEEQ('x','X',"x-large",cur->value)) {
5069             attr_size = apr_pstrdup(doc->pool, cur->value);
5070           }
5071           else if (STRCASEEQ('x','X',"xx-large",cur->value)) {
5072             attr_size = apr_pstrdup(doc->pool, cur->value);
5073           }
5074         }
5075       }
5076     }
5077   }
5078   W_L("<blink");
5079   if (attr_color || attr_size) {
5080     W_L(" style=\"");
5081     if (attr_color) {
5082       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
5083       W_L("color:");
5084       W_V(attr_color);
5085       W_L(";");
5086     }
5087     if (attr_size) {
5088       W_L("font-size:");
5089       W_V(attr_size);
5090       W_L(";");
5091     }
5092     W_L("\"");
5093   }
5094   W_L(">");
5095   return jxhtml->out;
5096 }
5097
5098
5099 /**
5100  * It is a handler who processes the BLINK tag.
5101  *
5102  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
5103  *                     destination is specified.
5104  * @param node   [i]   The BLINK tag node is specified.
5105  * @return The conversion result is returned.
5106  */
5107 static char *
5108 s_jxhtml_end_blink_tag(void *pdoc, Node *UNUSED(child))
5109 {
5110   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
5111   Doc      *doc = jxhtml->doc;
5112   W_L("</blink>");
5113   if (IS_CSS_ON(jxhtml->entryp)) {
5114     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
5115   }
5116   return jxhtml->out;
5117 }
5118
5119
5120 /**
5121  * It is a handler who processes the MARQUEE tag.
5122  *
5123  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
5124  *                     destination is specified.
5125  * @param node   [i]   The MARQUEE tag node is specified.
5126  * @return The conversion result is returned.
5127  */
5128 static char *
5129 s_jxhtml_start_marquee_tag(void *pdoc, Node *node)
5130 {
5131   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
5132   Doc       *doc = jxhtml->doc;
5133   Attr      *attr;
5134   char      *attr_direction = NULL;
5135   char      *attr_style     = NULL;
5136   char      *attr_color     = NULL;
5137   char      *attr_size      = NULL;
5138   char      *attr_bgcolor   = NULL;
5139   /*--------------------------------------------------------------------------*/
5140   /* Get Attributes                                                           */
5141   /*--------------------------------------------------------------------------*/
5142   for (attr = qs_get_attr(doc,node);
5143        attr;
5144        attr = qs_get_next_attr(doc,attr)) {
5145     char *name   = qs_get_attr_name(doc,attr);
5146     char *value  = qs_get_attr_value(doc,attr);
5147     if (STRCASEEQ('d','D',"direction", name)) {
5148       if (value) {
5149         if (STRCASEEQ('l','L',"left",value)) {
5150           attr_direction = "rtl";
5151         }
5152         else if (STRCASEEQ('r','R',"right",value)) {
5153           attr_direction = "ltr";
5154         }
5155       }
5156     }
5157     else if (STRCASEEQ('b','B',"behavior",name)) {
5158       /* ignore */
5159     }
5160     else if (STRCASEEQ('l','L',"loop",name)) {
5161       /* ignore */
5162     }
5163     else if (STRCASEEQ('b','B',"bgcolor",name)) {
5164       if (value && *value) {
5165         attr_bgcolor = value;
5166       }
5167     }
5168     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
5169       attr_style = value;
5170     }
5171   }
5172   if (IS_CSS_ON(jxhtml->entryp)) {
5173     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
5174     if (style) {
5175       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
5176       css_property_t *size_prop  = chxj_css_get_property_value(doc, style, "font-size");
5177       css_property_t *bgcolor_prop  = chxj_css_get_property_value(doc, style, "background-color");
5178       css_property_t *direction_prop  = chxj_css_get_property_value(doc, style, "-wap-marquee-dir");
5179       css_property_t *cur;
5180       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
5181         if (cur->value && *cur->value) {
5182           attr_color = apr_pstrdup(doc->pool, cur->value);
5183         }
5184       }
5185       for (cur = bgcolor_prop->next; cur != bgcolor_prop; cur = cur->next) {
5186         if (cur->value && *cur->value) {
5187           attr_bgcolor = apr_pstrdup(doc->pool, cur->value);
5188         }
5189       }
5190       for (cur = direction_prop->next; cur != direction_prop; cur = cur->next) {
5191         if (cur->value && *cur->value) {
5192           attr_direction = apr_pstrdup(doc->pool, cur->value);
5193         }
5194       }
5195       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
5196         if (cur->value && *cur->value) {
5197           if ( STRCASEEQ('x','X',"xx-small",cur->value)
5198             || STRCASEEQ('x','X',"x-small", cur->value)
5199             || STRCASEEQ('s','S',"small",   cur->value)
5200             || STRCASEEQ('m','M',"medium",  cur->value)
5201             || STRCASEEQ('l','L',"large",   cur->value)
5202             || STRCASEEQ('x','X',"x-large", cur->value)
5203             || STRCASEEQ('x','X',"xx-large",cur->value)) {
5204             attr_size = apr_pstrdup(doc->pool, cur->value);
5205           }
5206         }
5207       }
5208     }
5209   }
5210   W_L("<marquee");
5211   if (attr_color || attr_size || attr_direction || attr_bgcolor) {
5212     W_L(" style=\"");
5213     if (attr_direction) {
5214       W_L("-wap-marquee-dir:");
5215       W_V(attr_direction);
5216       W_L(";");
5217     }
5218     if (attr_bgcolor) {
5219       attr_bgcolor = chxj_css_rgb_func_to_value(doc->pool, attr_bgcolor);
5220       W_L("background-color:");
5221       W_V(attr_bgcolor);
5222       W_L(";");
5223     }
5224     if (attr_color) {
5225       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
5226       W_L("color:");
5227       W_V(attr_color);
5228       W_L(";");
5229     }
5230     if (attr_size) {
5231       W_L("font-size:");
5232       W_V(attr_size);
5233       W_L(";");
5234     }
5235     W_L("\"");
5236   }
5237   W_L(">");
5238
5239   return jxhtml->out;
5240 }
5241
5242
5243 /**
5244  * It is a handler who processes the MARQUEE tag.
5245  *
5246  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
5247  *                     destination is specified.
5248  * @param node   [i]   The MARQUEE tag node is specified.
5249  * @return The conversion result is returned.
5250  */
5251 static char *
5252 s_jxhtml_end_marquee_tag(void *pdoc, Node *UNUSED(node))
5253 {
5254   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
5255   Doc      *doc     = jxhtml->doc;
5256   W_L("</marquee>");
5257   if (IS_CSS_ON(jxhtml->entryp)) {
5258     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
5259   }
5260   return jxhtml->out;
5261 }
5262
5263
5264 /**
5265  * It is handler who processes the New Line Code.
5266  */
5267 static char *
5268 s_jxhtml_newline_mark(void *pdoc, Node *UNUSED(node))
5269 {
5270   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
5271   if (jxhtml->start_html_flag) {
5272     Doc *doc = jxhtml->doc;
5273     W_NLCODE();
5274   }
5275   return jxhtml->out;
5276 }
5277
5278
5279 /**
5280  * It is a handler who processes the LINK tag.
5281  *
5282  * @param pdoc  [i/o] The pointer to the JXHTML structure at the output
5283  *                     destination is specified.
5284  * @param node   [i]   The LINK tag node is specified.
5285  * @return The conversion result is returned.
5286  */
5287 static char *
5288 s_jxhtml_link_tag(void *pdoc, Node *node)
5289 {
5290   jxhtml_t      *jxhtml;
5291   Doc           *doc;
5292   Attr          *attr;
5293   char          *rel  = NULL;
5294   char          *href = NULL;
5295   char          *type = NULL;
5296
5297   jxhtml = GET_JXHTML(pdoc);
5298   doc    = jxhtml->doc;
5299
5300   if (! IS_CSS_ON(jxhtml->entryp)) {
5301     return jxhtml->out;
5302   }
5303
5304   for (attr = qs_get_attr(doc,node);
5305        attr;
5306        attr = qs_get_next_attr(doc,attr)) {
5307     char *name  = qs_get_attr_name(doc,attr);
5308     char *value = qs_get_attr_value(doc,attr);
5309     if (STRCASEEQ('r','R',"rel", name)) {
5310       if (value && *value && STRCASEEQ('s','S',"stylesheet", value)) {
5311         rel = value;
5312       }
5313     }
5314     else if (STRCASEEQ('h','H',"href", name)) {
5315       if (value && *value) {
5316         href = value;
5317       }
5318     }
5319     else if (STRCASEEQ('t','T',"type", name)) {
5320       if (value && *value && STRCASEEQ('t','T',"text/css",value)) {
5321         type = value;
5322       }
5323     }
5324   }
5325
5326   if (rel && href && type) {
5327     DBG(doc->r, "start load CSS. url:[%s]", href);
5328     jxhtml->style = chxj_css_parse_from_uri(doc->r, doc->pool, jxhtml->style, href);
5329     DBG(doc->r, "end load CSS. url:[%s]", href);
5330   }
5331
5332   return jxhtml->out;
5333 }
5334
5335
5336 static css_prop_list_t *
5337 s_jxhtml_push_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value)
5338 {
5339   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
5340   Doc *doc = jxhtml->doc;
5341   css_prop_list_t *last_css = NULL;
5342   if (IS_CSS_ON(jxhtml->entryp)) {
5343     css_prop_list_t *dup_css;
5344     css_selector_t  *selector;
5345
5346     last_css = chxj_css_get_last_prop_list(jxhtml->css_prop_stack);
5347     dup_css  = chxj_dup_css_prop_list(doc, last_css);
5348     selector = chxj_css_find_selector(doc, jxhtml->style, node);
5349     if (selector) {
5350       chxj_css_prop_list_merge_property(doc, dup_css, selector);
5351     }
5352     chxj_css_push_prop_list(jxhtml->css_prop_stack, dup_css);
5353     last_css = chxj_css_get_last_prop_list(jxhtml->css_prop_stack);
5354
5355     if (style_attr_value) {
5356       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));
5357       if (ssheet) {
5358         chxj_css_prop_list_merge_property(doc, last_css, ssheet->selector_head.next);
5359       }
5360     }
5361   }
5362   return last_css;
5363 }
5364
5365
5366 static css_prop_list_t *
5367 s_jxhtml_nopush_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value)
5368 {
5369   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
5370   Doc *doc = jxhtml->doc;
5371   css_prop_list_t *last_css = NULL;
5372   if (IS_CSS_ON(jxhtml->entryp)) {
5373     css_prop_list_t *dup_css;
5374     css_selector_t  *selector;
5375
5376     last_css = chxj_css_get_last_prop_list(jxhtml->css_prop_stack);
5377     dup_css  = chxj_dup_css_prop_list(doc, last_css);
5378     selector = chxj_css_find_selector(doc, jxhtml->style, node);
5379     if (selector) {
5380       chxj_css_prop_list_merge_property(doc, dup_css, selector);
5381     }
5382     last_css = dup_css;
5383
5384     if (style_attr_value) {
5385       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));
5386       if (ssheet) {
5387         chxj_css_prop_list_merge_property(doc, last_css, ssheet->selector_head.next);
5388       }
5389     }
5390   }
5391   return last_css;
5392 }
5393
5394
5395 /**
5396  * It is a handler who processes the SPAN tag.
5397  *
5398  * @param pdoc  [i/o] The pointer to the JHTML structure at the output
5399  *                     destination is specified.
5400  * @param node   [i]   The SPAN tag node is specified.
5401  * @return The conversion result is returned.
5402  */
5403 static char *
5404 s_jxhtml_start_span_tag(void *pdoc, Node *node)
5405 {
5406   jxhtml_t *jxhtml;
5407   Doc *doc;
5408   Attr *attr;
5409   char *attr_style = NULL;
5410   char *attr_color = NULL;
5411   char *attr_size = NULL;
5412   char *attr_align = NULL;
5413   char *attr_blink = NULL;
5414   char *attr_marquee = NULL;
5415   char *attr_marquee_dir = NULL;
5416   char *attr_marquee_style = NULL;
5417   char *attr_marquee_loop = NULL;
5418
5419   jxhtml = GET_JXHTML(pdoc);
5420   doc     = jxhtml->doc;
5421
5422   for (attr = qs_get_attr(doc,node);
5423        attr;
5424        attr = qs_get_next_attr(doc,attr)) {
5425     char *nm  = qs_get_attr_name(doc,attr);
5426     char *val = qs_get_attr_value(doc,attr);
5427     if (val && STRCASEEQ('s','S',"style", nm)) {
5428       attr_style = val;
5429     }
5430   }
5431   if (IS_CSS_ON(jxhtml->entryp)) {
5432     css_prop_list_t *style = s_jxhtml_push_and_get_now_style(pdoc, node, attr_style);
5433     if (style) {
5434       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
5435       css_property_t *size_prop = chxj_css_get_property_value(doc, style, "font-size");
5436       css_property_t *text_align_prop = chxj_css_get_property_value(doc, style, "text-align");
5437       css_property_t *decoration_prop = chxj_css_get_property_value(doc, style, "text-decoration");
5438       css_property_t *display_prop = chxj_css_get_property_value(doc, style, "display");
5439       css_property_t *marquee_dir_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-dir");
5440       css_property_t *marquee_style_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-style");
5441       css_property_t *marquee_loop_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-loop");
5442       css_property_t *cur;
5443       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
5444         attr_color = apr_pstrdup(doc->pool, cur->value);
5445       }
5446       for (cur = size_prop->next; cur != size_prop; cur = cur->next) {
5447         if (cur->value && *cur->value) {
5448           if ( STRCASEEQ('x','X',"xx-small",cur->value)
5449             || STRCASEEQ('x','X',"x-small", cur->value)
5450             || STRCASEEQ('s','S',"small",   cur->value)
5451             || STRCASEEQ('m','M',"medium",  cur->value)
5452             || STRCASEEQ('l','L',"large",   cur->value)
5453             || STRCASEEQ('x','X',"x-large", cur->value)
5454             || STRCASEEQ('x','X',"xx-large",cur->value)) {
5455             attr_size = apr_pstrdup(doc->pool, cur->value);
5456           }
5457         }
5458       }
5459       for (cur = decoration_prop->next; cur != decoration_prop; cur = cur->next) {
5460         if (cur->value && STRCASEEQ('b','B',"blink",cur->value)) {
5461           attr_blink = apr_pstrdup(doc->pool, cur->value);
5462         }
5463       }
5464       for (cur = display_prop->next; cur != display_prop; cur = cur->next) {
5465         if (cur->value && strcasecmp("-wap-marquee",cur->value) == 0) {
5466           attr_marquee = apr_pstrdup(doc->pool, cur->value);
5467         }
5468       }
5469       for (cur = marquee_dir_prop->next; cur != marquee_dir_prop; cur = cur->next) {
5470         if (cur->value && *cur->value) {
5471           if ( STRCASEEQ('l','L',"ltr",cur->value)
5472             || STRCASEEQ('r','R',"rtl",cur->value)) {
5473             attr_marquee_dir = apr_pstrdup(doc->pool, cur->value);
5474           }
5475         }
5476       }
5477       for (cur = marquee_style_prop->next; cur != marquee_style_prop; cur = cur->next) {
5478         if (cur->value && *cur->value) {
5479           if ( STRCASEEQ('s','S',"scroll",cur->value)
5480             || STRCASEEQ('s','S',"slide",cur->value)
5481             || STRCASEEQ('a','A',"alternate",cur->value)) {
5482             attr_marquee_style = apr_pstrdup(doc->pool, cur->value);
5483           }
5484         }
5485       }
5486       for (cur = marquee_loop_prop->next; cur != marquee_loop_prop; cur = cur->next) {
5487         if (cur->value && *cur->value) {
5488           attr_marquee_loop = apr_pstrdup(doc->pool, cur->value);
5489         }
5490       }
5491       for (cur = text_align_prop->next; cur != text_align_prop; cur = cur->next) {
5492         if (STRCASEEQ('l','L',"left", cur->value)) {
5493           attr_align = apr_pstrdup(doc->pool, "left");
5494         }
5495         else if (STRCASEEQ('c','C',"center",cur->value)) {
5496           attr_align = apr_pstrdup(doc->pool, "center");
5497         }
5498         else if (STRCASEEQ('r','R',"right",cur->value)) {
5499           attr_align = apr_pstrdup(doc->pool, "right");
5500         }
5501       }
5502     }
5503   }
5504
5505   W_L("<span");
5506   if (attr_color || attr_size || attr_align || attr_blink || attr_marquee) {
5507     W_L(" style=\"");
5508     if (attr_color) {
5509       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
5510       W_L("color:");
5511       W_V(attr_color);
5512       W_L(";");
5513     }
5514     if (attr_size) {
5515       W_L("font-size:");
5516       W_V(attr_size);
5517       W_L(";");
5518     }
5519     if (attr_align) {
5520       W_L("text-align:");
5521       W_V(attr_align);
5522       W_L(";");
5523     }
5524     if (attr_blink) {
5525       W_L("text-decoration:");
5526       W_V("blink");
5527       W_L(";");
5528     }
5529     if (attr_marquee) {
5530       W_L("display:-wap-marquee;");
5531       if (attr_marquee_dir) {
5532         W_L("-wap-marquee-dir:");
5533         W_V(attr_marquee_dir);
5534         W_L(";");
5535       }
5536       if (attr_marquee_style) {
5537         W_L("-wap-marquee-style:");
5538         W_V(attr_marquee_style);
5539         W_L(";");
5540       }
5541       if (attr_marquee_loop) {
5542         W_L("-wap-marquee-loop:");
5543         W_V(attr_marquee_loop);
5544         W_L(";");
5545       }
5546     }
5547     W_L("\"");
5548   }
5549   W_L(">");
5550   return jxhtml->out;
5551 }
5552
5553
5554 /**
5555  * It is a handler who processes the SPAN tag.
5556  *
5557  * @param pdoc  [i/o] The pointer to the JHTML structure at the output
5558  *                     destination is specified.
5559  * @param node   [i]   The SPAN tag node is specified.
5560  * @return The conversion result is returned.
5561  */
5562 static char *
5563 s_jxhtml_end_span_tag(void *pdoc, Node *UNUSED(node))
5564 {
5565   jxhtml_t *jxhtml = GET_JXHTML(pdoc);
5566   Doc *doc = jxhtml->doc;
5567
5568   W_L("</span>");
5569   if (IS_CSS_ON(jxhtml->entryp)) {
5570     chxj_css_pop_prop_list(jxhtml->css_prop_stack);
5571   }
5572   return jxhtml->out;
5573 }
5574
5575
5576 /**
5577  * It is a handler who processes the STYLE tag.
5578  *
5579  * @param pdoc  [i/o] The pointer to the SoftBank XHTML structure at the output
5580  *                     destination is specified.
5581  * @param node   [i]   The STYLE tag node is specified.
5582  * @return The conversion result is returned.
5583  */
5584 static char *
5585 s_jxhtml_style_tag(void *pdoc, Node *node)
5586 {
5587   jxhtml_t     *jxhtml;
5588   Doc           *doc;
5589   Attr          *attr;
5590   char          *type = NULL;
5591
5592   jxhtml = GET_JXHTML(pdoc);
5593   doc     = jxhtml->doc;
5594
5595   if (! IS_CSS_ON(jxhtml->entryp)) {
5596     return jxhtml->out;
5597   }
5598
5599   for (attr = qs_get_attr(doc,node);
5600        attr;
5601        attr = qs_get_next_attr(doc,attr)) {
5602     char *name  = qs_get_attr_name(doc,attr);
5603     char *value = qs_get_attr_value(doc,attr);
5604     if (STRCASEEQ('t','T',"type", name)) {
5605       if (value && *value && STRCASEEQ('t','T',"text/css",value)) {
5606         type = value;
5607       }
5608     }
5609   }
5610
5611   Node *child = qs_get_child_node(doc, node);
5612   if (type && child) {
5613     char *name  = qs_get_node_name(doc, child);
5614     if (STRCASEEQ('t','T',"text", name)) {
5615       char *value = qs_get_node_value(doc, child);
5616       DBG(doc->r, "start load CSS. buf:[%s]", value);
5617       jxhtml->style = chxj_css_parse_style_value(doc, jxhtml->style, value);
5618       DBG(doc->r, "end load CSS. value:[%s]", value);
5619     }
5620   }
5621   return jxhtml->out;
5622 }
5623 /*
5624  * vim:ts=2 et
5625  */