OSDN Git Service

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