OSDN Git Service

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