OSDN Git Service

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