OSDN Git Service

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