OSDN Git Service

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