OSDN Git Service

Merge branch 'branch_0.12.0' into branch_0.13.0
[modchxj/mod_chxj.git] / src / chxj_chtml40.c
1 /*
2  * Copyright (C) 2005-2009 Atsushi Konno All rights reserved.
3  * Copyright (C) 2005 QSDN,Inc. All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #include <apr_time.h>
18 #include "chxj_chtml40.h"
19 #include "chxj_hdml.h"
20 #include "chxj_str_util.h"
21 #include "chxj_dump.h"
22 #include "chxj_img_conv.h"
23 #include "chxj_qr_code.h"
24 #include "chxj_encoding.h"
25 #include "chxj_header_inf.h"
26 #include "chxj_conv_z2h.h"
27
28 #define GET_CHTML40(X) ((chtml40_t *)(X))
29 #undef W_L
30 #undef W_V
31 #define W_L(X)          do { chtml40->out = BUFFERED_WRITE_LITERAL(chtml40->out, &doc->buf, (X)); } while(0)
32 #define W_V(X)          do { chtml40->out = (X) ? BUFFERED_WRITE_VALUE(chtml40->out, &doc->buf, (X))  \
33                                                 : BUFFERED_WRITE_LITERAL(chtml40->out, &doc->buf, ""); } while(0)
34 #undef W_NLCODE
35 #define W_NLCODE()     do { char *nlcode = TO_NLCODE(chtml40->conf); W_V(nlcode); } while (0)
36
37 #define CHTML40_GET_CSS_COLOR_AND_LIST_STYLE_TYPE() \
38   if (IS_CSS_ON(chtml40->entryp)) { \
39     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style); \
40     if (style) { \
41       css_property_t *color_prop           = chxj_css_get_property_value(doc, style, "color"); \
42       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type"); \
43       css_property_t *cur; \
44       for (cur = color_prop->next; cur != color_prop; cur = cur->next) { \
45         if (cur->value && *cur->value) { \
46           attr_color = apr_pstrdup(doc->pool, cur->value); \
47         } \
48       } \
49       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) { \
50         if (cur->value && *cur->value) { \
51           attr_type = apr_pstrdup(doc->pool, cur->value); \
52         } \
53       } \
54     } \
55   }
56
57 static char *s_chtml40_start_html_tag     (void *pdoc, Node *node);
58 static char *s_chtml40_end_html_tag       (void *pdoc, Node *node);
59 static char *s_chtml40_start_meta_tag     (void *pdoc, Node *node);
60 static char *s_chtml40_end_meta_tag       (void *pdoc, Node *node);
61 static char *s_chtml40_start_textarea_tag (void *pdoc, Node *node);
62 static char *s_chtml40_end_textarea_tag   (void *pdoc, Node *node);
63 static char *s_chtml40_start_p_tag        (void *pdoc, Node *node);
64 static char *s_chtml40_end_p_tag          (void *pdoc, Node *node);
65 static char *s_chtml40_start_pre_tag      (void *pdoc, Node *node);
66 static char *s_chtml40_end_pre_tag        (void *pdoc, Node *node);
67 static char *s_chtml40_start_h1_tag       (void *pdoc, Node *node);
68 static char *s_chtml40_end_h1_tag         (void *pdoc, Node *node);
69 static char *s_chtml40_start_h2_tag       (void *pdoc, Node *node);
70 static char *s_chtml40_end_h2_tag         (void *pdoc, Node *node);
71 static char *s_chtml40_start_h3_tag       (void *pdoc, Node *node);
72 static char *s_chtml40_end_h3_tag         (void *pdoc, Node *node);
73 static char *s_chtml40_start_h4_tag       (void *pdoc, Node *node);
74 static char *s_chtml40_end_h4_tag         (void *pdoc, Node *node);
75 static char *s_chtml40_start_h5_tag       (void *pdoc, Node *node);
76 static char *s_chtml40_end_h5_tag         (void *pdoc, Node *node);
77 static char *s_chtml40_start_h6_tag       (void *pdoc, Node *node);
78 static char *s_chtml40_end_h6_tag         (void *pdoc, Node *node);
79 static char *s_chtml40_start_ul_tag       (void *pdoc, Node *node);
80 static char *s_chtml40_end_ul_tag         (void *pdoc, Node *node);
81 static char *s_chtml40_start_ol_tag       (void *pdoc, Node *node);
82 static char *s_chtml40_end_ol_tag         (void *pdoc, Node *node);
83 static char *s_chtml40_start_li_tag       (void *pdoc, Node *node);
84 static char *s_chtml40_end_li_tag         (void *pdoc, Node *node);
85 static char *s_chtml40_start_head_tag     (void *pdoc, Node *node);
86 static char *s_chtml40_end_head_tag       (void *pdoc, Node *node);
87 static char *s_chtml40_start_title_tag    (void *pdoc, Node *node);
88 static char *s_chtml40_end_title_tag      (void *pdoc, Node *node);
89 static char *s_chtml40_start_base_tag     (void *pdoc, Node *node);
90 static char *s_chtml40_end_base_tag       (void *pdoc, Node *node);
91 static char *s_chtml40_start_body_tag     (void *pdoc, Node *node);
92 static char *s_chtml40_end_body_tag       (void *pdoc, Node *node);
93 static char *s_chtml40_start_a_tag        (void *pdoc, Node *node);
94 static char *s_chtml40_end_a_tag          (void *pdoc, Node *node);
95 static char *s_chtml40_start_br_tag       (void *pdoc, Node *node);
96 static char *s_chtml40_end_br_tag         (void *pdoc, Node *node);
97 static char *s_chtml40_start_tr_tag       (void *pdoc, Node *node);
98 static char *s_chtml40_end_tr_tag         (void *pdoc, Node *node);
99 static char *s_chtml40_start_font_tag     (void *pdoc, Node *node);
100 static char *s_chtml40_end_font_tag       (void *pdoc, Node *node);
101 static char *s_chtml40_start_form_tag     (void *pdoc, Node *node);
102 static char *s_chtml40_end_form_tag       (void *pdoc, Node *node);
103 static char *s_chtml40_start_input_tag    (void *pdoc, Node *node);
104 static char *s_chtml40_end_input_tag      (void *pdoc, Node *node);
105 static char *s_chtml40_start_center_tag   (void *pdoc, Node *node);
106 static char *s_chtml40_end_center_tag     (void *pdoc, Node *node);
107 static char *s_chtml40_start_hr_tag       (void *pdoc, Node *node);
108 static char *s_chtml40_end_hr_tag         (void *pdoc, Node *node);
109 static char *s_chtml40_start_img_tag      (void *pdoc, Node *node);
110 static char *s_chtml40_end_img_tag        (void *pdoc, Node *node);
111 static char *s_chtml40_start_select_tag   (void *pdoc, Node *node);
112 static char *s_chtml40_end_select_tag     (void *pdoc, Node *node);
113 static char *s_chtml40_start_option_tag   (void *pdoc, Node *node);
114 static char *s_chtml40_end_option_tag     (void *pdoc, Node *node);
115 static char *s_chtml40_start_div_tag      (void *pdoc, Node *node);
116 static char *s_chtml40_end_div_tag        (void *pdoc, Node *node);
117 static char *s_chtml40_chxjif_tag         (void *pdoc, Node *node); 
118 static char *s_chtml40_text_tag           (void *pdoc, Node *node);
119 static char *s_chtml40_start_blockquote_tag (void *pdoc, Node *node);
120 static char *s_chtml40_end_blockquote_tag  (void *pdoc, Node *node);
121 static char *s_chtml40_start_dir_tag      (void *pdoc, Node *node);
122 static char *s_chtml40_end_dir_tag        (void *pdoc, Node *node);
123 static char *s_chtml40_start_dl_tag       (void *pdoc, Node *node);
124 static char *s_chtml40_end_dl_tag         (void *pdoc, Node *node);
125 static char *s_chtml40_start_dt_tag       (void *pdoc, Node *node);
126 static char *s_chtml40_end_dt_tag         (void *pdoc, Node *node);
127 static char *s_chtml40_start_dd_tag       (void *pdoc, Node *node);
128 static char *s_chtml40_end_dd_tag         (void *pdoc, Node *node);
129 static char *s_chtml40_start_marquee_tag  (void *pdoc, Node *node);
130 static char *s_chtml40_end_marquee_tag    (void *pdoc, Node *node);
131 static char *s_chtml40_start_blink_tag    (void *pdoc, Node *node);
132 static char *s_chtml40_end_blink_tag      (void *pdoc, Node *node);
133 static char *s_chtml40_start_menu_tag     (void *pdoc, Node *node);
134 static char *s_chtml40_end_menu_tag       (void *pdoc, Node *node);
135 static char *s_chtml40_start_plaintext_tag       (void *pdoc, Node *node);
136 static char *s_chtml40_start_plaintext_tag_inner (void *pdoc, Node *node);
137 static char *s_chtml40_end_plaintext_tag         (void *pdoc, Node *node);
138 static char *s_chtml40_newline_mark       (void *pdoc, Node *node);
139 static char *s_chtml40_link_tag           (void *pdoc, Node *node);
140 static char *s_chtml40_start_span_tag     (void *pdoc, Node *node);
141 static char *s_chtml40_end_span_tag       (void *pdoc, Node *node);
142 static char *s_chtml40_style_tag     (void *pdoc, Node *node);
143
144 static void  s_init_chtml40(chtml40_t *chtml, Doc *doc, request_rec *r, device_table *spec);
145
146 static int   s_chtml40_search_emoji(chtml40_t *chtml, char *txt, char **rslt);
147 static css_prop_list_t *s_chtml40_push_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value);
148 static css_prop_list_t *s_chtml40_nopush_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value);
149
150
151 tag_handler chtml40_handler[] = {
152   /* tagHTML */
153   {
154     s_chtml40_start_html_tag,
155     s_chtml40_end_html_tag,
156   },
157   /* tagMETA */
158   {
159     s_chtml40_start_meta_tag,
160     s_chtml40_end_meta_tag,
161   },
162   /* tagTEXTAREA */
163   {
164     s_chtml40_start_textarea_tag,
165     s_chtml40_end_textarea_tag,
166   },
167   /* tagP */
168   {
169     s_chtml40_start_p_tag,
170     s_chtml40_end_p_tag,
171   },
172   /* tagPRE */
173   {
174     s_chtml40_start_pre_tag,
175     s_chtml40_end_pre_tag,
176   },
177   /* tagUL */
178   {
179     s_chtml40_start_ul_tag,
180     s_chtml40_end_ul_tag,
181   },
182   /* tagLI */
183   {
184     s_chtml40_start_li_tag,
185     s_chtml40_end_li_tag,
186   },
187   /* tagOL */
188   {
189     s_chtml40_start_ol_tag,
190     s_chtml40_end_ol_tag,
191   },
192   /* tagH1 */
193   {
194     s_chtml40_start_h1_tag,
195     s_chtml40_end_h1_tag,
196   },
197   /* tagH2 */
198   {
199     s_chtml40_start_h2_tag,
200     s_chtml40_end_h2_tag,
201   },
202   /* tagH3 */
203   {
204     s_chtml40_start_h3_tag,
205     s_chtml40_end_h3_tag,
206   },
207   /* tagH4 */
208   {
209     s_chtml40_start_h4_tag,
210     s_chtml40_end_h4_tag,
211   },
212   /* tagH5 */
213   {
214     s_chtml40_start_h5_tag,
215     s_chtml40_end_h5_tag,
216   },
217   /* tagH6 */
218   {
219     s_chtml40_start_h6_tag,
220     s_chtml40_end_h6_tag,
221   },
222   /* tagHEAD */
223   {
224     s_chtml40_start_head_tag,
225     s_chtml40_end_head_tag,
226   },
227   /* tagTITLE */
228   {
229     s_chtml40_start_title_tag,
230     s_chtml40_end_title_tag,
231   },
232   /* tagBASE */
233   {
234     s_chtml40_start_base_tag,
235     s_chtml40_end_base_tag,
236   },
237   /* tagBODY */
238   {
239     s_chtml40_start_body_tag,
240     s_chtml40_end_body_tag,
241   },
242   /* tagA */
243   {
244     s_chtml40_start_a_tag,
245     s_chtml40_end_a_tag,
246   },
247   /* tagBR */
248   {
249     s_chtml40_start_br_tag,
250     s_chtml40_end_br_tag,
251   },
252   /* tagTABLE */
253   {
254     NULL,
255     NULL,
256   },
257   /* tagTR */
258   {
259     s_chtml40_start_tr_tag,
260     s_chtml40_end_tr_tag,
261   },
262   /* tagTD */
263   {
264     NULL,
265     NULL,
266   },
267   /* tagTBODY */
268   {
269     NULL,
270     NULL,
271   },
272   /* tagFONT */
273   {
274     s_chtml40_start_font_tag,
275     s_chtml40_end_font_tag,
276   },
277   /* tagFORM */
278   {
279     s_chtml40_start_form_tag,
280     s_chtml40_end_form_tag,
281   },
282   /* tagINPUT */
283   {
284     s_chtml40_start_input_tag,
285     s_chtml40_end_input_tag,
286   },
287   /* tagCENTER */
288   {
289     s_chtml40_start_center_tag,
290     s_chtml40_end_center_tag,
291   },
292   /* tagHR */
293   {
294     s_chtml40_start_hr_tag,
295     s_chtml40_end_hr_tag,
296   },
297   /* tagIMG */
298   {
299     s_chtml40_start_img_tag,
300     s_chtml40_end_img_tag,
301   },
302   /* tagSELECT */
303   {
304     s_chtml40_start_select_tag,
305     s_chtml40_end_select_tag,
306   },
307   /* tagOPTION */
308   {
309     s_chtml40_start_option_tag,
310     s_chtml40_end_option_tag,
311   },
312   /* tagDIV */
313   {
314     s_chtml40_start_div_tag,
315     s_chtml40_end_div_tag,
316   },
317   /* tagCHXJIF */
318   {
319     s_chtml40_chxjif_tag,
320     NULL,
321   },
322   /* 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(">");
3115
3116   return chtml40->out;
3117 }
3118
3119
3120 /**
3121  * It is a handler who processes the OL tag.
3122  *
3123  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3124  *                     destination is specified.
3125  * @param node   [i]   The OL tag node is specified.
3126  * @return The conversion result is returned.
3127  */
3128 static char *
3129 s_chtml40_end_ol_tag(void *pdoc, Node *UNUSED(node)) 
3130 {
3131   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3132   Doc       *doc     = chtml40->doc;
3133
3134   W_L("</ol>");
3135   if (IS_CSS_ON(chtml40->entryp)) {
3136     chxj_css_pop_prop_list(chtml40->css_prop_stack);
3137   }
3138
3139   return chtml40->out;
3140 }
3141
3142
3143 /**
3144  * It is a handler who processes the LI tag.
3145  *
3146  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3147  *                     destination is specified.
3148  * @param node   [i]   The LI tag node is specified.
3149  * @return The conversion result is returned.
3150  */
3151 static char *
3152 s_chtml40_start_li_tag(void *pdoc, Node *node) 
3153 {
3154   chtml40_t   *chtml40 = GET_CHTML40(pdoc);
3155   Doc         *doc     = chtml40->doc;
3156   Attr        *attr;
3157   char        *attr_type = NULL;
3158   char        *attr_value = NULL;
3159   char        *attr_style = NULL;
3160
3161   /*--------------------------------------------------------------------------*/
3162   /* Get Attributes                                                           */
3163   /*--------------------------------------------------------------------------*/
3164   for (attr = qs_get_attr(doc,node);
3165        attr;
3166        attr = qs_get_next_attr(doc,attr)) {
3167     char *name  = qs_get_attr_name(doc,attr);
3168     char *value = qs_get_attr_value(doc,attr);
3169     if (STRCASEEQ('t','T',"type",name)) {
3170       if (value && (*value == '1' || *value == 'a' || *value == 'A' || STRCASEEQ('d','D',"disc",value) || STRCASEEQ('s','S',"square",value) || STRCASEEQ('c','C',"circle",value))) {
3171         attr_type = value;
3172       }
3173     }
3174     else if (STRCASEEQ('v','V',"value", name) && value && *value) {
3175       attr_value = value;
3176     }
3177     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
3178       attr_style = value;
3179     }
3180   }
3181   if (IS_CSS_ON(chtml40->entryp)) {
3182     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
3183     if (style) {
3184       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type");
3185       css_property_t *cur;
3186       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3187         if (STRCASEEQ('d','D',"decimal", cur->value)) {
3188           attr_type = apr_pstrdup(doc->pool, "1");
3189         }
3190         else if (STRCASEEQ('u','U',"upper-alpha", cur->value)) {
3191           attr_type = apr_pstrdup(doc->pool, "A");
3192         }
3193         else if (STRCASEEQ('l','L',"lower-alpha", cur->value)) {
3194           attr_type = apr_pstrdup(doc->pool, "a");
3195         }
3196         else if (STRCASEEQ('d','D',"disc", cur->value)) {
3197           attr_type = apr_pstrdup(doc->pool, "disc");
3198         }
3199         else if (STRCASEEQ('s','S',"square", cur->value)) {
3200           attr_type = apr_pstrdup(doc->pool, "square");
3201         }
3202         else if (STRCASEEQ('c','C',"circle", cur->value)) {
3203           attr_type = apr_pstrdup(doc->pool, "circle");
3204         }
3205       }
3206     }
3207   }
3208
3209   W_L("<li");
3210   if (attr_type) {
3211     W_L(" type=\"");
3212     W_V(attr_type);
3213     W_L("\"");
3214   }
3215   if (attr_value) {
3216     W_L(" value=\"");
3217     W_V(attr_value);
3218     W_L("\"");
3219   }
3220   W_L(">");
3221   return chtml40->out;
3222 }
3223
3224
3225 /**
3226  * It is a handler who processes the LI tag.
3227  *
3228  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3229  *                     destination is specified.
3230  * @param node   [i]   The LI tag node is specified.
3231  * @return The conversion result is returned.
3232  */
3233 static char *
3234 s_chtml40_end_li_tag(void *pdoc, Node *UNUSED(child)) 
3235 {
3236   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3237
3238   if (IS_CSS_ON(chtml40->entryp)) {
3239     chxj_css_pop_prop_list(chtml40->css_prop_stack);
3240   }
3241   return chtml40->out;
3242 }
3243
3244
3245 /**
3246  * It is a handler who processes the H1 tag.
3247  *
3248  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3249  *                     destination is specified.
3250  * @param node   [i]   The H1 tag node is specified.
3251  * @return The conversion result is returned.
3252  */
3253 static char *
3254 s_chtml40_start_h1_tag(void *pdoc, Node *node)
3255 {
3256   chtml40_t   *chtml40;
3257   Doc         *doc;
3258   request_rec *r;
3259   Attr        *attr;
3260   char        *attr_style = NULL;
3261   char        *attr_align = NULL;
3262
3263   chtml40 = GET_CHTML40(pdoc);
3264   doc     = chtml40->doc;
3265   r       = doc->r;
3266
3267   for (attr = qs_get_attr(doc,node);
3268        attr;
3269        attr = qs_get_next_attr(doc,attr)) {
3270     char *name  = qs_get_attr_name(doc,attr);
3271     char *value = qs_get_attr_value(doc,attr);
3272     if (STRCASEEQ('a','A',"align", name)) {
3273       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3274         attr_align = value;
3275       }
3276     }
3277     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3278       attr_style = value;
3279     }
3280   }
3281   if (IS_CSS_ON(chtml40->entryp)) {
3282     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
3283     if (style) {
3284       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3285       css_property_t *cur;
3286       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3287         if (STRCASEEQ('l','L',"left", cur->value)) {
3288           attr_align = apr_pstrdup(doc->pool, "left");
3289         }
3290         else if (STRCASEEQ('c','C',"center",cur->value)) {
3291           attr_align = apr_pstrdup(doc->pool, "center");
3292         }
3293         else if (STRCASEEQ('r','R',"right",cur->value)) {
3294           attr_align = apr_pstrdup(doc->pool, "right");
3295         }
3296       }
3297     }
3298   }
3299   W_L("<h1");
3300   if (attr_align) {
3301     W_L(" align=\"");
3302     W_V(attr_align);
3303     W_L("\"");
3304   }
3305   W_L(">");
3306
3307   return chtml40->out;
3308 }
3309
3310
3311 /**
3312  * It is a handler who processes the H1 tag.
3313  *
3314  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3315  *                     destination is specified.
3316  * @param node   [i]   The H1 tag node is specified.
3317  * @return The conversion result is returned.
3318  */
3319 static char *
3320 s_chtml40_end_h1_tag(void *pdoc, Node *UNUSED(child)) 
3321 {
3322   chtml40_t   *chtml40;
3323   Doc         *doc;
3324
3325   chtml40 = GET_CHTML40(pdoc);
3326   doc     = chtml40->doc;
3327
3328   W_L("</h1>");
3329   if (IS_CSS_ON(chtml40->entryp)) {
3330     chxj_css_pop_prop_list(chtml40->css_prop_stack);
3331   }
3332
3333   return chtml40->out;
3334 }
3335
3336
3337 /**
3338  * It is a handler who processes the H2 tag.
3339  *
3340  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3341  *                     destination is specified.
3342  * @param node   [i]   The H2 tag node is specified.
3343  * @return The conversion result is returned.
3344  */
3345 static char *
3346 s_chtml40_start_h2_tag(void *pdoc, Node *node)
3347 {
3348   chtml40_t   *chtml40;
3349   Doc         *doc;
3350   request_rec *r;
3351   Attr        *attr;
3352   char        *attr_style = NULL;
3353   char        *attr_align = NULL;
3354
3355   chtml40 = GET_CHTML40(pdoc);
3356   doc     = chtml40->doc;
3357   r       = doc->r;
3358
3359   for (attr = qs_get_attr(doc,node);
3360        attr;
3361        attr = qs_get_next_attr(doc,attr)) {
3362     char *name  = qs_get_attr_name(doc,attr);
3363     char *value = qs_get_attr_value(doc,attr);
3364     if (STRCASEEQ('a','A',"align", name)) {
3365       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3366         attr_align = value;
3367       }
3368     }
3369     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3370       attr_style = value;
3371     }
3372   }
3373   if (IS_CSS_ON(chtml40->entryp)) {
3374     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
3375     if (style) {
3376       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3377       css_property_t *cur;
3378       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3379         if (STRCASEEQ('l','L',"left", cur->value)) {
3380           attr_align = apr_pstrdup(doc->pool, "left");
3381         }
3382         else if (STRCASEEQ('c','C',"center",cur->value)) {
3383           attr_align = apr_pstrdup(doc->pool, "center");
3384         }
3385         else if (STRCASEEQ('r','R',"right",cur->value)) {
3386           attr_align = apr_pstrdup(doc->pool, "right");
3387         }
3388       }
3389     }
3390   }
3391   W_L("<h2");
3392   if (attr_align) {
3393     W_L(" align=\"");
3394     W_V(attr_align);
3395     W_L("\"");
3396   }
3397   W_L(">");
3398
3399   return chtml40->out;
3400 }
3401
3402
3403 /**
3404  * It is a handler who processes the H2 tag.
3405  *
3406  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3407  *                     destination is specified.
3408  * @param node   [i]   The H2 tag node is specified.
3409  * @return The conversion result is returned.
3410  */
3411 static char *
3412 s_chtml40_end_h2_tag(void *pdoc, Node *UNUSED(child)) 
3413 {
3414   chtml40_t   *chtml40 = GET_CHTML40(pdoc);
3415   Doc         *doc     = chtml40->doc;
3416
3417   W_L("</h2>");
3418   if (IS_CSS_ON(chtml40->entryp)) {
3419     chxj_css_pop_prop_list(chtml40->css_prop_stack);
3420   }
3421
3422   return chtml40->out;
3423 }
3424
3425
3426 /**
3427  * It is a handler who processes the H3 tag.
3428  *
3429  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3430  *                     destination is specified.
3431  * @param node   [i]   The H3 tag node is specified.
3432  * @return The conversion result is returned.
3433  */
3434 static char *
3435 s_chtml40_start_h3_tag(void *pdoc, Node *node)
3436 {
3437   chtml40_t   *chtml40;
3438   Doc         *doc;
3439   request_rec *r;
3440   Attr        *attr;
3441   char        *attr_style = NULL;
3442   char        *attr_align = NULL;
3443
3444   chtml40 = GET_CHTML40(pdoc);
3445   doc     = chtml40->doc;
3446   r       = doc->r;
3447
3448   for (attr = qs_get_attr(doc,node);
3449        attr;
3450        attr = qs_get_next_attr(doc,attr)) {
3451     char *name  = qs_get_attr_name(doc,attr);
3452     char *value = qs_get_attr_value(doc,attr);
3453     if (STRCASEEQ('a','A',"align", name)) {
3454       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3455         attr_align = value;
3456       }
3457     }
3458     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3459       attr_style = value;
3460     }
3461   }
3462   if (IS_CSS_ON(chtml40->entryp)) {
3463     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
3464     if (style) {
3465       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3466       css_property_t *cur;
3467       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3468         if (STRCASEEQ('l','L',"left", cur->value)) {
3469           attr_align = apr_pstrdup(doc->pool, "left");
3470         }
3471         else if (STRCASEEQ('c','C',"center",cur->value)) {
3472           attr_align = apr_pstrdup(doc->pool, "center");
3473         }
3474         else if (STRCASEEQ('r','R',"right",cur->value)) {
3475           attr_align = apr_pstrdup(doc->pool, "right");
3476         }
3477       }
3478     }
3479   }
3480   W_L("<h3");
3481   if (attr_align) {
3482     W_L(" align=\"");
3483     W_V(attr_align);
3484     W_L("\"");
3485   }
3486   W_L(">");
3487
3488   return chtml40->out;
3489 }
3490
3491
3492 /**
3493  * It is a handler who processes the H3 tag.
3494  *
3495  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3496  *                     destination is specified.
3497  * @param node   [i]   The H3 tag node is specified.
3498  * @return The conversion result is returned.
3499  */
3500 static char *
3501 s_chtml40_end_h3_tag(void *pdoc, Node *UNUSED(child))
3502 {
3503   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3504   Doc       *doc   = chtml40->doc;
3505
3506   W_L("</h3>");
3507   if (IS_CSS_ON(chtml40->entryp)) {
3508     chxj_css_pop_prop_list(chtml40->css_prop_stack);
3509   }
3510
3511   return chtml40->out;
3512 }
3513
3514
3515 /**
3516  * It is a handler who processes the H4 tag.
3517  *
3518  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3519  *                     destination is specified.
3520  * @param node   [i]   The H4 tag node is specified.
3521  * @return The conversion result is returned.
3522  */
3523 static char *
3524 s_chtml40_start_h4_tag(void *pdoc, Node *node)
3525 {
3526   chtml40_t   *chtml40;
3527   Doc         *doc;
3528   request_rec *r;
3529   Attr        *attr;
3530   char        *attr_style = NULL;
3531   char        *attr_align = NULL;
3532
3533   chtml40 = GET_CHTML40(pdoc);
3534   doc     = chtml40->doc;
3535   r       = doc->r;
3536
3537   for (attr = qs_get_attr(doc,node);
3538        attr;
3539        attr = qs_get_next_attr(doc,attr)) {
3540     char *name  = qs_get_attr_name(doc,attr);
3541     char *value = qs_get_attr_value(doc,attr);
3542     if (STRCASEEQ('a','A',"align", name)) {
3543       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3544         attr_align = value;
3545       }
3546     }
3547     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3548       attr_style = value;
3549     }
3550   }
3551   if (IS_CSS_ON(chtml40->entryp)) {
3552     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
3553     if (style) {
3554       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3555       css_property_t *cur;
3556       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3557         if (STRCASEEQ('l','L',"left", cur->value)) {
3558           attr_align = apr_pstrdup(doc->pool, "left");
3559         }
3560         else if (STRCASEEQ('c','C',"center",cur->value)) {
3561           attr_align = apr_pstrdup(doc->pool, "center");
3562         }
3563         else if (STRCASEEQ('r','R',"right",cur->value)) {
3564           attr_align = apr_pstrdup(doc->pool, "right");
3565         }
3566       }
3567     }
3568   }
3569   W_L("<h4");
3570   if (attr_align) {
3571     W_L(" align=\"");
3572     W_V(attr_align);
3573     W_L("\"");
3574   }
3575   W_L(">");
3576
3577   return chtml40->out;
3578 }
3579
3580
3581 /**
3582  * It is a handler who processes the H4 tag.
3583  *
3584  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3585  *                     destination is specified.
3586  * @param node   [i]   The H4 tag node is specified.
3587  * @return The conversion result is returned.
3588  */
3589 static char *
3590 s_chtml40_end_h4_tag(void *pdoc, Node *UNUSED(child)) 
3591 {
3592   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3593   Doc       *doc     = chtml40->doc;
3594
3595   W_L("</h4>");
3596   if (IS_CSS_ON(chtml40->entryp)) {
3597     chxj_css_pop_prop_list(chtml40->css_prop_stack);
3598   }
3599
3600   return chtml40->out;
3601 }
3602
3603
3604 /**
3605  * It is a handler who processes the H5 tag.
3606  *
3607  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3608  *                     destination is specified.
3609  * @param node   [i]   The H5 tag node is specified.
3610  * @return The conversion result is returned.
3611  */
3612 static char *
3613 s_chtml40_start_h5_tag(void *pdoc, Node *node)
3614 {
3615   chtml40_t   *chtml40;
3616   Doc         *doc;
3617   request_rec *r;
3618   Attr        *attr;
3619   char        *attr_style = NULL;
3620   char        *attr_align = NULL;
3621
3622   chtml40 = GET_CHTML40(pdoc);
3623   doc     = chtml40->doc;
3624   r       = doc->r;
3625
3626   for (attr = qs_get_attr(doc,node);
3627        attr;
3628        attr = qs_get_next_attr(doc,attr)) {
3629     char *name  = qs_get_attr_name(doc,attr);
3630     char *value = qs_get_attr_value(doc,attr);
3631     if (STRCASEEQ('a','A',"align", name)) {
3632       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3633         attr_align = value;
3634       }
3635     }
3636     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3637       attr_style = value;
3638     }
3639   }
3640   if (IS_CSS_ON(chtml40->entryp)) {
3641     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
3642     if (style) {
3643       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3644       css_property_t *cur;
3645       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3646         if (STRCASEEQ('l','L',"left", cur->value)) {
3647           attr_align = apr_pstrdup(doc->pool, "left");
3648         }
3649         else if (STRCASEEQ('c','C',"center",cur->value)) {
3650           attr_align = apr_pstrdup(doc->pool, "center");
3651         }
3652         else if (STRCASEEQ('r','R',"right",cur->value)) {
3653           attr_align = apr_pstrdup(doc->pool, "right");
3654         }
3655       }
3656     }
3657   }
3658   W_L("<h5");
3659   if (attr_align) {
3660     W_L(" align=\"");
3661     W_V(attr_align);
3662     W_L("\"");
3663   }
3664   W_L(">");
3665
3666   return chtml40->out;
3667 }
3668
3669
3670 /**
3671  * It is a handler who processes the H5 tag.
3672  *
3673  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3674  *                     destination is specified.
3675  * @param node   [i]   The H5 tag node is specified.
3676  * @return The conversion result is returned.
3677  */
3678 static char *
3679 s_chtml40_end_h5_tag(void *pdoc, Node *UNUSED(child)) 
3680 {
3681   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3682   Doc       *doc     = chtml40->doc;
3683
3684   W_L("</h5>");
3685   if (IS_CSS_ON(chtml40->entryp)) {
3686     chxj_css_pop_prop_list(chtml40->css_prop_stack);
3687   }
3688
3689   return chtml40->out;
3690 }
3691
3692
3693 /**
3694  * It is a handler who processes the H6 tag.
3695  *
3696  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3697  *                     destination is specified.
3698  * @param node   [i]   The H6 tag node is specified.
3699  * @return The conversion result is returned.
3700  */
3701 static char *
3702 s_chtml40_start_h6_tag(void *pdoc, Node *node)
3703 {
3704   chtml40_t   *chtml40;
3705   Doc         *doc;
3706   request_rec *r;
3707   Attr        *attr;
3708   char        *attr_style = NULL;
3709   char        *attr_align = NULL;
3710
3711   chtml40 = GET_CHTML40(pdoc);
3712   doc     = chtml40->doc;
3713   r       = doc->r;
3714
3715   for (attr = qs_get_attr(doc,node);
3716        attr;
3717        attr = qs_get_next_attr(doc,attr)) {
3718     char *name  = qs_get_attr_name(doc,attr);
3719     char *value = qs_get_attr_value(doc,attr);
3720     if (STRCASEEQ('a','A',"align", name)) {
3721       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3722         attr_align = value;
3723       }
3724     }
3725     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3726       attr_style = value;
3727     }
3728   }
3729   if (IS_CSS_ON(chtml40->entryp)) {
3730     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
3731     if (style) {
3732       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3733       css_property_t *cur;
3734       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3735         if (STRCASEEQ('l','L',"left", cur->value)) {
3736           attr_align = apr_pstrdup(doc->pool, "left");
3737         }
3738         else if (STRCASEEQ('c','C',"center",cur->value)) {
3739           attr_align = apr_pstrdup(doc->pool, "center");
3740         }
3741         else if (STRCASEEQ('r','R',"right",cur->value)) {
3742           attr_align = apr_pstrdup(doc->pool, "right");
3743         }
3744       }
3745     }
3746   }
3747   W_L("<h6");
3748   if (attr_align) {
3749     W_L(" align=\"");
3750     W_V(attr_align);
3751     W_L("\"");
3752   }
3753   W_L(">");
3754
3755   return chtml40->out;
3756 }
3757
3758
3759 /**
3760  * It is a handler who processes the H6 tag.
3761  *
3762  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3763  *                     destination is specified.
3764  * @param node   [i]   The H6 tag node is specified.
3765  * @return The conversion result is returned.
3766  */
3767 static char *
3768 s_chtml40_end_h6_tag(void *pdoc, Node *UNUSED(child)) 
3769 {
3770   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3771   Doc       *doc     = chtml40->doc;
3772
3773   W_L("</h6>");
3774   if (IS_CSS_ON(chtml40->entryp)) {
3775     chxj_css_pop_prop_list(chtml40->css_prop_stack);
3776   }
3777
3778   return chtml40->out;
3779 }
3780
3781
3782 /**
3783  * It is a handler who processes the TEXTARE tag.
3784  *
3785  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3786  *                     destination is specified.
3787  * @param node   [i]   The TEXTAREA tag node is specified.
3788  * @return The conversion result is returned.
3789  */
3790 static char *
3791 s_chtml40_start_textarea_tag(void *pdoc, Node *node) 
3792 {
3793   chtml40_t     *chtml40;
3794   Doc           *doc;
3795   request_rec   *r;
3796   Attr          *attr;
3797   char          *attr_accesskey = NULL;
3798   char          *attr_name      = NULL;
3799   char          *attr_rows      = NULL;
3800   char          *attr_cols      = NULL;
3801   char          *attr_istyle    = NULL;
3802   char          *attr_style     = NULL;
3803
3804   chtml40 = GET_CHTML40(pdoc);
3805   doc     = chtml40->doc;
3806   r       = doc->r;
3807
3808   chtml40->textarea_flag++;
3809
3810   for (attr = qs_get_attr(doc,node);
3811        attr;
3812        attr = qs_get_next_attr(doc,attr)) {
3813     char *name  = qs_get_attr_name(doc,attr);
3814     char *value = qs_get_attr_value(doc,attr);
3815     if (STRCASEEQ('a','A',"accesskey",name) && value && *value != 0) {
3816       attr_accesskey = value;
3817     }
3818     else if (STRCASEEQ('i','I',"istyle", name) && value && (*value == '1' || *value == '2' || *value == '3' || *value == '4')) {
3819       attr_istyle = value;
3820     }
3821     else if (STRCASEEQ('n','N',"name", name) && value && *value) {
3822       attr_name = value;
3823     }
3824     else if (STRCASEEQ('r','R',"rows", name) && value && *value) {
3825       attr_rows = value;
3826     }
3827     else if (STRCASEEQ('c','C',"cols", name) && value && *value) {
3828       attr_cols = value;
3829     }
3830     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
3831       attr_style = value;
3832     }
3833   }
3834   if (IS_CSS_ON(chtml40->entryp)) {
3835     css_prop_list_t *style = s_chtml40_nopush_and_get_now_style(pdoc, node, attr_style);
3836     if (style) {
3837       css_property_t *wap_input_format = chxj_css_get_property_value(doc, style, "-wap-input-format");
3838       css_property_t *cur;
3839       for (cur = wap_input_format->next; cur != wap_input_format; cur = cur->next) {
3840         if (strcasestr(cur->value, "<ja:n>")) {
3841           attr_istyle = "4";
3842         }
3843         else if (strcasestr(cur->value, "<ja:en>")) {
3844           attr_istyle = "3";
3845         }
3846         else if (strcasestr(cur->value, "<ja:hk>")) {
3847           attr_istyle = "2";
3848         }
3849         else if (strcasestr(cur->value, "<ja:h>")) {
3850           attr_istyle = "1";
3851         }
3852       }
3853     }
3854   }
3855   W_L("<textarea");
3856   if (attr_accesskey) {
3857     W_L(" accesskey=\"");
3858     W_V(attr_accesskey);
3859     W_L("\"");
3860   }
3861   if (attr_name) {
3862     W_L(" name=\"");
3863     W_V(attr_name);
3864     W_L("\"");
3865   }
3866   if (attr_rows) {
3867     W_L(" rows=\"");
3868     W_V(attr_rows);
3869     W_L("\"");
3870   }
3871   if (attr_cols) {
3872     W_L(" cols=\"");
3873     W_V(attr_cols);
3874     W_L("\"");
3875   }
3876   if (attr_istyle) {
3877     W_L(" istyle=\"");
3878     W_V(attr_istyle);
3879     W_L("\"");
3880   }
3881   W_L(">");
3882   return chtml40->out;
3883 }
3884
3885
3886 /**
3887  * It is a handler who processes the TEXTAREA tag.
3888  *
3889  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3890  *                     destination is specified.
3891  * @param node   [i]   The TEXTAREA tag node is specified.
3892  * @return The conversion result is returned.
3893  */
3894 static char *
3895 s_chtml40_end_textarea_tag(void *pdoc, Node *UNUSED(child)) 
3896 {
3897   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3898   Doc       *doc     = chtml40->doc;
3899
3900   W_L("</textarea>");
3901   chtml40->textarea_flag--;
3902
3903   return chtml40->out;
3904 }
3905
3906
3907 static char *
3908 s_chtml40_chxjif_tag(void *pdoc, Node *node)
3909 {
3910   Node        *child;
3911   chtml40_t   *chtml40;
3912   Doc         *doc;
3913   request_rec *r;
3914
3915   chtml40 = GET_CHTML40(pdoc);
3916   doc     = chtml40->doc;
3917   r       = doc->r;
3918
3919   for (child = qs_get_child_node(doc, node);
3920        child;
3921        child = qs_get_next_node(doc, child)) {
3922     W_V(child->otext);
3923     s_chtml40_chxjif_tag(chtml40, child);
3924   }
3925
3926   return NULL;
3927 }
3928
3929
3930 static char *
3931 s_chtml40_text_tag(void *pdoc, Node *child)
3932 {
3933   chtml40_t   *chtml40;
3934   Doc         *doc;
3935   request_rec *r;
3936
3937   char        *textval;
3938   char        *tmp;
3939   char        *tdst;
3940   char        one_byte[2];
3941   int         ii;
3942   int         tdst_len;
3943   apr_size_t  z2h_input_len;
3944
3945   chtml40 = GET_CHTML40(pdoc);
3946   doc     = chtml40->doc;
3947   r       = doc->r;
3948   
3949   textval = qs_get_node_value(doc,child);
3950   if (strlen(textval) == 0) {
3951     return chtml40->out;
3952   }
3953   
3954   tmp = apr_palloc(r->pool, qs_get_node_size(doc,child)+1);
3955   memset(tmp, 0, qs_get_node_size(doc,child)+1);
3956   
3957   tdst     = qs_alloc_zero_byte_string(doc->buf.pool);
3958   memset(one_byte, 0, sizeof(one_byte));
3959   tdst_len = 0;
3960   
3961   for (ii=0; ii<qs_get_node_size(doc,child); ii++) {
3962     char* out;
3963     int rtn = s_chtml40_search_emoji(chtml40, &textval[ii], &out);
3964     if (rtn) {
3965       tdst = qs_out_apr_pstrcat(r, tdst, out, &tdst_len);
3966       ii+=(rtn - 1);
3967       continue;
3968     }
3969   
3970     if (is_sjis_kanji(textval[ii])) {
3971       one_byte[0] = textval[ii+0];
3972       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
3973       one_byte[0] = textval[ii+1];
3974       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
3975       ii++;
3976     }
3977     else if (chtml40->pre_flag) {
3978       one_byte[0] = textval[ii+0];
3979       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
3980     }
3981     else if (chtml40->textarea_flag) {
3982       one_byte[0] = textval[ii+0];
3983       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
3984     }
3985     else if (textval[ii] != '\r' && textval[ii] != '\n') {
3986       one_byte[0] = textval[ii+0];
3987       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
3988     }
3989   }
3990   z2h_input_len = strlen(tdst);
3991   tdst = chxj_conv_z2h(r, tdst, &z2h_input_len, chtml40->entryp);
3992   W_V(tdst);
3993   return chtml40->out;
3994 }
3995
3996
3997 /**
3998  * It is a handler who processes the BLOCKQUOTE tag.
3999  *
4000  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4001  *                     destination is specified.
4002  * @param node   [i]   The BLOCKQUOTE tag node is specified.
4003  * @return The conversion result is returned.
4004  */
4005 static char *
4006 s_chtml40_start_blockquote_tag(void *pdoc, Node *node)
4007 {
4008   chtml40_t *chtml40;
4009   Doc       *doc;
4010   Attr      *attr;
4011   char      *attr_style = NULL;
4012   char      *attr_color = NULL;
4013
4014   chtml40 = GET_CHTML40(pdoc);
4015   doc     = chtml40->doc;
4016   for (attr = qs_get_attr(doc,node);
4017        attr;
4018        attr = qs_get_next_attr(doc,attr)) {
4019     char *nm  = qs_get_attr_name(doc,attr);
4020     char *val = qs_get_attr_value(doc,attr);
4021     if (val && STRCASEEQ('s','S',"style", nm)) {
4022       attr_style = val;
4023     }
4024   }
4025   if (IS_CSS_ON(chtml40->entryp)) {
4026     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
4027     if (style) {
4028       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
4029       css_property_t *cur;
4030       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
4031         if (cur->value && *cur->value) {
4032           attr_color = apr_pstrdup(doc->pool, cur->value);
4033         }
4034       }
4035     }
4036   }
4037   W_L("<blockquote>");
4038   chtml40_flags_t *flg = (chtml40_flags_t *)apr_palloc(doc->pool, sizeof(chtml40_flags_t));
4039   memset(flg, 0, sizeof(*flg));
4040   if (attr_color) {
4041     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
4042     W_L("<font color=\"");
4043     W_V(attr_color);
4044     W_L("\">");
4045     flg->with_font_flag = 1;
4046   }
4047   node->userData = (void *)flg;
4048   return chtml40->out;
4049 }
4050
4051
4052 /**
4053  * It is a handler who processes the BLOCKQUOTE tag.
4054  *
4055  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4056  *                     destination is specified.
4057  * @param node   [i]   The BLOCKQUOTE tag node is specified.
4058  * @return The conversion result is returned.
4059  */
4060 static char *
4061 s_chtml40_end_blockquote_tag(void *pdoc, Node *node)
4062 {
4063   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4064   Doc       *doc     = chtml40->doc;
4065   chtml40_flags_t *flg = (chtml40_flags_t *)node->userData;
4066   if (flg && flg->with_font_flag) {
4067     W_L("</font>");
4068   }
4069   W_L("</blockquote>");
4070   if (IS_CSS_ON(chtml40->entryp)) {
4071     chxj_css_pop_prop_list(chtml40->css_prop_stack);
4072   }
4073   return chtml40->out;
4074 }
4075
4076
4077 /**
4078  * It is a handler who processes the DIR tag.
4079  *
4080  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4081  *                     destination is specified.
4082  * @param node   [i]   The DIR tag node is specified.
4083  * @return The conversion result is returned.
4084  */
4085 static char *
4086 s_chtml40_start_dir_tag(void *pdoc, Node *node)
4087 {
4088   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4089   Doc       *doc     = chtml40->doc;
4090   Attr      *attr;
4091   char      *attr_style = NULL;
4092   char      *attr_color = NULL;
4093   char      *attr_type  = NULL;
4094   for (attr = qs_get_attr(doc,node);
4095        attr;
4096        attr = qs_get_next_attr(doc,attr)) {
4097     char *name   = qs_get_attr_name(doc,attr);
4098     char *value  = qs_get_attr_value(doc,attr);
4099     if (STRCASEEQ('t','T',"type",name)) {
4100       if (value && (STRCASEEQ('d','D',"disc",value) || STRCASEEQ('c','C',"circle",value) || STRCASEEQ('s','S',"square",value))) {
4101         attr_type = value;
4102       }
4103     }
4104     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
4105       attr_style = value;
4106     }
4107   }
4108   CHTML40_GET_CSS_COLOR_AND_LIST_STYLE_TYPE();
4109   W_L("<dir");
4110   if (attr_type) {
4111     W_L(" type=\"");
4112     W_V(attr_type);
4113     W_L("\"");
4114   }
4115   W_L(">");
4116   chtml40_flags_t *flg = (chtml40_flags_t *)apr_palloc(doc->pool, sizeof(chtml40_flags_t));
4117   memset(flg, 0, sizeof(*flg));
4118   if (attr_color) {
4119     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
4120     W_L("<font color=\"");
4121     W_V(attr_color);
4122     W_L("\">");
4123     flg->with_font_flag = 1;
4124   }
4125   node->userData = (void *)flg;
4126   return chtml40->out;
4127 }
4128
4129
4130 /**
4131  * It is a handler who processes the DIR tag.
4132  *
4133  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4134  *                     destination is specified.
4135  * @param node   [i]   The DIR tag node is specified.
4136  * @return The conversion result is returned.
4137  */
4138 static char *
4139 s_chtml40_end_dir_tag(void *pdoc, Node *node)
4140 {
4141   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4142   Doc       *doc = chtml40->doc;
4143   chtml40_flags_t *flg = (chtml40_flags_t *)node->userData;
4144   if (flg && flg->with_font_flag) {
4145     W_L("</font>");
4146   }
4147   W_L("</dir>");
4148   if (IS_CSS_ON(chtml40->entryp)) {
4149     chxj_css_pop_prop_list(chtml40->css_prop_stack);
4150   }
4151   return chtml40->out;
4152 }
4153
4154
4155 /**
4156  * It is a handler who processes the DL tag.
4157  *
4158  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4159  *                     destination is specified.
4160  * @param node   [i]   The DL tag node is specified.
4161  * @return The conversion result is returned.
4162  */
4163 static char *
4164 s_chtml40_start_dl_tag(void *pdoc, Node *node)
4165 {
4166   chtml40_t *chtml40;
4167   Doc       *doc;
4168   Attr      *attr;
4169   char      *attr_style = NULL;
4170   char      *attr_color = NULL;
4171
4172   chtml40 = GET_CHTML40(pdoc);
4173   doc     = chtml40->doc;
4174   for (attr = qs_get_attr(doc,node);
4175        attr;
4176        attr = qs_get_next_attr(doc,attr)) {
4177     char *nm  = qs_get_attr_name(doc,attr);
4178     char *val = qs_get_attr_value(doc,attr);
4179     if (val && STRCASEEQ('s','S',"style", nm)) {
4180       attr_style = val;
4181     }
4182   }
4183   if (IS_CSS_ON(chtml40->entryp)) {
4184     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
4185     if (style) {
4186       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
4187       css_property_t *cur;
4188       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
4189         if (cur->value && *cur->value) {
4190           attr_color = apr_pstrdup(doc->pool, cur->value);
4191         }
4192       }
4193     }
4194   }
4195   W_L("<dl>");
4196   chtml40_flags_t *flg = (chtml40_flags_t *)apr_palloc(doc->pool, sizeof(chtml40_flags_t));
4197   memset(flg, 0, sizeof(*flg));
4198   if (attr_color) {
4199     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
4200     W_L("<font color=\"");
4201     W_V(attr_color);
4202     W_L("\">");
4203     flg->with_font_flag = 1;
4204   }
4205   node->userData = (void *)flg;
4206   return chtml40->out;
4207 }
4208
4209
4210 /**
4211  * It is a handler who processes the DL tag.
4212  *
4213  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4214  *                     destination is specified.
4215  * @param node   [i]   The DL tag node is specified.
4216  * @return The conversion result is returned.
4217  */
4218 static char *
4219 s_chtml40_end_dl_tag(void *pdoc, Node *node)
4220 {
4221   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4222   Doc       *doc     = chtml40->doc;
4223   chtml40_flags_t *flg = (chtml40_flags_t *)node->userData;
4224   if (flg && flg->with_font_flag) {
4225     W_L("</font>");
4226   }
4227   W_L("</dl>");
4228   if (IS_CSS_ON(chtml40->entryp)) {
4229     chxj_css_pop_prop_list(chtml40->css_prop_stack);
4230   }
4231   return chtml40->out;
4232 }
4233
4234
4235 /**
4236  * It is a handler who processes the DT tag.
4237  *
4238  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4239  *                     destination is specified.
4240  * @param node   [i]   The DT tag node is specified.
4241  * @return The conversion result is returned.
4242  */
4243 static char *
4244 s_chtml40_start_dt_tag(void *pdoc, Node *node)
4245 {
4246   chtml40_t *chtml40;
4247   Doc       *doc;
4248   Attr      *attr;
4249   char      *attr_style = NULL;
4250   char      *attr_color = NULL;
4251
4252   chtml40 = GET_CHTML40(pdoc);
4253   doc     = chtml40->doc;
4254   for (attr = qs_get_attr(doc,node);
4255        attr;
4256        attr = qs_get_next_attr(doc,attr)) {
4257     char *nm  = qs_get_attr_name(doc,attr);
4258     char *val = qs_get_attr_value(doc,attr);
4259     if (val && STRCASEEQ('s','S',"style", nm)) {
4260       attr_style = val;
4261     }
4262   }
4263   if (IS_CSS_ON(chtml40->entryp)) {
4264     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
4265     if (style) {
4266       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
4267       css_property_t *cur;
4268       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
4269         if (cur->value && *cur->value) {
4270           attr_color = apr_pstrdup(doc->pool, cur->value);
4271         }
4272       }
4273     }
4274   }
4275   W_L("<dt>");
4276   chtml40_flags_t *flg = (chtml40_flags_t *)apr_palloc(doc->pool, sizeof(chtml40_flags_t));
4277   memset(flg, 0, sizeof(*flg));
4278   if (attr_color) {
4279     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
4280     W_L("<font color=\"");
4281     W_V(attr_color);
4282     W_L("\">");
4283     flg->with_font_flag = 1;
4284   }
4285   node->userData = (void *)flg;
4286   return chtml40->out;
4287 }
4288
4289
4290 /**
4291  * It is a handler who processes the DT tag.
4292  *
4293  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4294  *                     destination is specified.
4295  * @param node   [i]   The DT tag node is specified.
4296  * @return The conversion result is returned.
4297  */
4298 static char *
4299 s_chtml40_end_dt_tag(void *pdoc, Node *node)
4300 {
4301   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4302   Doc       *doc     = chtml40->doc;
4303   chtml40_flags_t *flg = (chtml40_flags_t *)node->userData;
4304   if (flg && flg->with_font_flag) {
4305     W_L("</font>");
4306   }
4307   if (IS_CSS_ON(chtml40->entryp)) {
4308     chxj_css_pop_prop_list(chtml40->css_prop_stack);
4309   }
4310   return chtml40->out;
4311 }
4312
4313
4314 /**
4315  * It is a handler who processes the DD tag.
4316  *
4317  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4318  *                     destination is specified.
4319  * @param node   [i]   The DD tag node is specified.
4320  * @return The conversion result is returned.
4321  */
4322 static char *
4323 s_chtml40_start_dd_tag(void *pdoc, Node *node)
4324 {
4325   chtml40_t *chtml40;
4326   Doc       *doc;
4327   Attr      *attr;
4328   char      *attr_style = NULL;
4329   char      *attr_color = NULL;
4330
4331   chtml40 = GET_CHTML40(pdoc);
4332   doc     = chtml40->doc;
4333   for (attr = qs_get_attr(doc,node);
4334        attr;
4335        attr = qs_get_next_attr(doc,attr)) {
4336     char *nm  = qs_get_attr_name(doc,attr);
4337     char *val = qs_get_attr_value(doc,attr);
4338     if (val && STRCASEEQ('s','S',"style", nm)) {
4339       attr_style = val;
4340     }
4341   }
4342   if (IS_CSS_ON(chtml40->entryp)) {
4343     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
4344     if (style) {
4345       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
4346       css_property_t *cur;
4347       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
4348         if (cur->value && *cur->value) {
4349           attr_color = apr_pstrdup(doc->pool, cur->value);
4350         }
4351       }
4352     }
4353   }
4354   W_L("<dd>");
4355   chtml40_flags_t *flg = (chtml40_flags_t *)apr_palloc(doc->pool, sizeof(chtml40_flags_t));
4356   memset(flg, 0, sizeof(*flg));
4357   if (attr_color) {
4358     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
4359     W_L("<font color=\"");
4360     W_V(attr_color);
4361     W_L("\">");
4362     flg->with_font_flag = 1;
4363   }
4364   node->userData = (void *)flg;
4365   return chtml40->out;
4366 }
4367
4368
4369 /**
4370  * It is a handler who processes the DD tag.
4371  *
4372  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4373  *                     destination is specified.
4374  * @param node   [i]   The DD tag node is specified.
4375  * @return The conversion result is returned.
4376  */
4377 static char *
4378 s_chtml40_end_dd_tag(void *pdoc, Node *node)
4379 {
4380   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4381   Doc       *doc     = chtml40->doc;
4382   chtml40_flags_t *flg = (chtml40_flags_t *)node->userData;
4383   if (flg && flg->with_font_flag) {
4384     W_L("</font>");
4385   }
4386   if (IS_CSS_ON(chtml40->entryp)) {
4387     chxj_css_pop_prop_list(chtml40->css_prop_stack);
4388   }
4389   return chtml40->out;
4390 }
4391
4392
4393 /**
4394  * It is a handler who processes the MARQUEE tag.
4395  *
4396  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4397  *                     destination is specified.
4398  * @param node   [i]   The MARQUEE tag node is specified.
4399  * @return The conversion result is returned.
4400  */
4401 static char *
4402 s_chtml40_start_marquee_tag(void *pdoc, Node *node)
4403 {
4404   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4405   Doc       *doc = chtml40->doc;
4406   Attr      *attr;
4407   char      *attr_direction = NULL;
4408   char      *attr_behavior  = NULL;
4409   char      *attr_loop      = NULL;
4410   char      *attr_style     = NULL;
4411   char      *attr_color     = NULL;
4412   /*--------------------------------------------------------------------------*/
4413   /* Get Attributes                                                           */
4414   /*--------------------------------------------------------------------------*/
4415   for (attr = qs_get_attr(doc,node);
4416        attr;
4417        attr = qs_get_next_attr(doc,attr)) {
4418     char *name   = qs_get_attr_name(doc,attr);
4419     char *value  = qs_get_attr_value(doc,attr);
4420     if (STRCASEEQ('d','D',"direction", name)) {
4421       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value))) {
4422         attr_direction = value;
4423       }
4424     }
4425     else if (STRCASEEQ('b','B',"behavior",name)) {
4426       if (value && (STRCASEEQ('s','S',"scroll",value) || STRCASEEQ('s','S',"slide",value) || STRCASEEQ('a','A',"alternate",value))) {
4427         attr_behavior = value;
4428       }
4429     }
4430     else if (STRCASEEQ('l','L',"loop",name)) {
4431       if (value && *value) {
4432         attr_loop = value;
4433       }
4434     }
4435     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
4436       attr_style = value;
4437     }
4438   }
4439   if (IS_CSS_ON(chtml40->entryp)) {
4440     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
4441     if (style) {
4442       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
4443       css_property_t *direction_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-dir");
4444       css_property_t *style_prop     = chxj_css_get_property_value(doc, style, "-wap-marquee-style");
4445       css_property_t *loop_prop      = chxj_css_get_property_value(doc, style, "-wap-marquee-loop");
4446       css_property_t *cur;
4447       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
4448         if (cur->value && *cur->value) {
4449           attr_color = apr_pstrdup(doc->pool, cur->value);
4450         }
4451       }
4452       for (cur = style_prop->next; cur != style_prop; cur = cur->next) {
4453         if (cur->value && *cur->value) {
4454           attr_behavior = apr_pstrdup(doc->pool, cur->value);
4455         }
4456       }
4457       for (cur = loop_prop->next; cur != loop_prop; cur = cur->next) {
4458         if (cur->value && *cur->value) {
4459           attr_loop = apr_pstrdup(doc->pool, cur->value);
4460           if (STRCASEEQ('i','I',"infinite",attr_loop)) {
4461             attr_loop = "16";
4462           }
4463         }
4464       }
4465       for (cur = direction_prop->next; cur != direction_prop; cur = cur->next) {
4466         if (cur->value && *cur->value) {
4467           if (STRCASEEQ('l','L',"ltr",cur->value)) {
4468             attr_direction = "right";
4469           }
4470           else if (STRCASEEQ('r','R',"rtl",cur->value)) {
4471             attr_direction = "left";
4472           }
4473         }
4474       }
4475     }
4476   }
4477   W_L("<marquee");
4478   if (attr_direction) {
4479     W_L(" direction=\"");
4480     W_V(attr_direction);
4481     W_L("\"");
4482   }
4483   if (attr_behavior) {
4484     W_L(" behavior=\"");
4485     W_V(attr_behavior);
4486     W_L("\"");
4487   }
4488   if (attr_loop) {
4489     W_L(" loop=\"");
4490     W_V(attr_loop);
4491     W_L("\"");
4492   }
4493   W_L(">");
4494
4495   chtml40_flags_t *flg = (chtml40_flags_t *)apr_palloc(doc->pool, sizeof(chtml40_flags_t));
4496   memset(flg, 0, sizeof(*flg));
4497   if (attr_color) {
4498     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
4499     W_L("<font color=\"");
4500     W_V(attr_color);
4501     W_L("\">");
4502     flg->with_font_flag = 1;
4503   }
4504   node->userData = (void *)flg;
4505   return chtml40->out;
4506 }
4507
4508
4509 /**
4510  * It is a handler who processes the MARQUEE tag.
4511  *
4512  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4513  *                     destination is specified.
4514  * @param node   [i]   The MARQUEE tag node is specified.
4515  * @return The conversion result is returned.
4516  */
4517 static char *
4518 s_chtml40_end_marquee_tag(void *pdoc, Node *node)
4519 {
4520   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4521   Doc       *doc     = chtml40->doc;
4522   chtml40_flags_t *flg = (chtml40_flags_t *)node->userData;
4523   if (flg && flg->with_font_flag) {
4524     W_L("</font>");
4525   }
4526   W_L("</marquee>");
4527   if (IS_CSS_ON(chtml40->entryp)) {
4528     chxj_css_pop_prop_list(chtml40->css_prop_stack);
4529   }
4530   return chtml40->out;
4531 }
4532
4533
4534 /**
4535  * It is a handler who processes the BLINK tag.
4536  *
4537  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4538  *                     destination is specified.
4539  * @param node   [i]   The BLINK tag node is specified.
4540  * @return The conversion result is returned.
4541  */
4542 static char *
4543 s_chtml40_start_blink_tag(void *pdoc, Node *node)
4544 {
4545   chtml40_t *chtml40;
4546   Doc       *doc;
4547   Attr      *attr;
4548   char      *attr_style = NULL;
4549   char      *attr_color = NULL;
4550
4551   chtml40 = GET_CHTML40(pdoc);
4552   doc     = chtml40->doc;
4553   for (attr = qs_get_attr(doc,node);
4554        attr;
4555        attr = qs_get_next_attr(doc,attr)) {
4556     char *nm  = qs_get_attr_name(doc,attr);
4557     char *val = qs_get_attr_value(doc,attr);
4558     if (val && STRCASEEQ('s','S',"style", nm)) {
4559       attr_style = val;
4560     }
4561   }
4562   if (IS_CSS_ON(chtml40->entryp)) {
4563     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
4564     if (style) {
4565       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
4566       css_property_t *cur;
4567       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
4568         if (cur->value && *cur->value) {
4569           attr_color = apr_pstrdup(doc->pool, cur->value);
4570         }
4571       }
4572     }
4573   }
4574   W_L("<blink>");
4575   chtml40_flags_t *flg = (chtml40_flags_t *)apr_palloc(doc->pool, sizeof(chtml40_flags_t));
4576   memset(flg, 0, sizeof(*flg));
4577   if (attr_color) {
4578     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
4579     W_L("<font color=\"");
4580     W_V(attr_color);
4581     W_L("\">");
4582     flg->with_font_flag = 1;
4583   }
4584   node->userData = (void *)flg;
4585   return chtml40->out;
4586 }
4587
4588
4589 /**
4590  * It is a handler who processes the BLINK tag.
4591  *
4592  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4593  *                     destination is specified.
4594  * @param node   [i]   The BLINK tag node is specified.
4595  * @return The conversion result is returned.
4596  */
4597 static char *
4598 s_chtml40_end_blink_tag(void *pdoc, Node *node)
4599 {
4600   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4601   Doc       *doc     = chtml40->doc;
4602   chtml40_flags_t *flg = (chtml40_flags_t *)node->userData;
4603   if (flg && flg->with_font_flag) {
4604     W_L("</font>");
4605   }
4606   W_L("</blink>");
4607   if (IS_CSS_ON(chtml40->entryp)) {
4608     chxj_css_pop_prop_list(chtml40->css_prop_stack);
4609   }
4610   return chtml40->out;
4611 }
4612
4613
4614 /**
4615  * It is a handler who processes the MENU tag.
4616  *
4617  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4618  *                     destination is specified.
4619  * @param node   [i]   The MENU tag node is specified.
4620  * @return The conversion result is returned.
4621  */
4622 static char *
4623 s_chtml40_start_menu_tag(void *pdoc, Node *node)
4624 {
4625   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4626   Doc       *doc     = chtml40->doc;
4627   Attr      *attr;
4628   char      *attr_style = NULL;
4629   char      *attr_type  = NULL;
4630   char      *attr_color = NULL;
4631   /*--------------------------------------------------------------------------*/
4632   /* Get Attributes                                                           */
4633   /*--------------------------------------------------------------------------*/
4634   for (attr = qs_get_attr(doc,node);
4635        attr;
4636        attr = qs_get_next_attr(doc,attr)) {
4637     char *name   = qs_get_attr_name(doc,attr);
4638     char *value  = qs_get_attr_value(doc,attr);
4639     if (STRCASEEQ('t','T',"type",name)) {
4640       if (value && (STRCASEEQ('d','D',"disc",value) || STRCASEEQ('c','C',"circle",value) || STRCASEEQ('s','S',"square",value))) {
4641         attr_type = value;
4642       }
4643     }
4644     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
4645       attr_style = value;
4646     }
4647   }
4648   CHTML40_GET_CSS_COLOR_AND_LIST_STYLE_TYPE();
4649   W_L("<menu");
4650   if (attr_type) {
4651     W_L(" type=\"");
4652     W_V(attr_type);
4653     W_L("\"");
4654   }
4655   W_L(">");
4656   chtml40_flags_t *flg = (chtml40_flags_t *)apr_palloc(doc->pool, sizeof(chtml40_flags_t));
4657   memset(flg, 0, sizeof(*flg));
4658   if (attr_color) {
4659     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
4660     W_L("<font color=\"");
4661     W_V(attr_color);
4662     W_L("\">");
4663     flg->with_font_flag = 1;
4664   }
4665   node->userData = (void *)flg;
4666
4667   return chtml40->out;
4668 }
4669
4670
4671 /**
4672  * It is a handler who processes the MENU tag.
4673  *
4674  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4675  *                     destination is specified.
4676  * @param node   [i]   The MENU tag node is specified.
4677  * @return The conversion result is returned.
4678  */
4679 static char *
4680 s_chtml40_end_menu_tag(void *pdoc, Node *node)
4681 {
4682   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4683   Doc       *doc     = chtml40->doc;
4684   chtml40_flags_t *flg = (chtml40_flags_t *)node->userData;
4685   if (flg && flg->with_font_flag) {
4686     W_L("</font>");
4687   }
4688   W_L("</menu>");
4689   if (IS_CSS_ON(chtml40->entryp)) {
4690     chxj_css_pop_prop_list(chtml40->css_prop_stack);
4691   }
4692   return chtml40->out;
4693 }
4694
4695
4696 /**
4697  * It is a handler who processes the PLAINTEXT tag.
4698  *
4699  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4700  *                     destination is specified.
4701  * @param node   [i]   The PLAINTEXT tag node is specified.
4702  * @return The conversion result is returned.
4703  */
4704 static char *
4705 s_chtml40_start_plaintext_tag(void *pdoc, Node *node)
4706 {
4707   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4708   Doc       *doc     = chtml40->doc;
4709   W_L("<plaintext>");
4710   s_chtml40_start_plaintext_tag_inner(pdoc,node);
4711   return chtml40->out;
4712 }
4713
4714 static char *
4715 s_chtml40_start_plaintext_tag_inner(void *pdoc, Node *node)
4716 {
4717   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4718   Doc       *doc     = chtml40->doc;
4719   Node      *child;
4720   for (child = qs_get_child_node(doc, node);
4721        child;
4722        child = qs_get_next_node(doc, child)) {
4723     W_V(child->otext);
4724     s_chtml40_start_plaintext_tag_inner(pdoc, child);
4725   }
4726   return chtml40->out;
4727 }
4728
4729
4730 /**
4731  * It is a handler who processes the PLAINTEXT tag.
4732  *
4733  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4734  *                     destination is specified.
4735  * @param node   [i]   The PLAINTEXT tag node is specified.
4736  * @return The conversion result is returned.
4737  */
4738 static char *
4739 s_chtml40_end_plaintext_tag(void *pdoc, Node *UNUSED(child))
4740 {
4741   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4742   return chtml40->out;
4743 }
4744
4745
4746 /**
4747  * It is handler who processes the New Line Code.
4748  */
4749 static char *
4750 s_chtml40_newline_mark(void *pdoc, Node *UNUSED(node))
4751 {
4752   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4753   Doc *doc = chtml40->doc;
4754   W_NLCODE();
4755   return chtml40->out;
4756 }
4757
4758
4759 /**
4760  * It is a handler who processes the LINK tag.
4761  *
4762  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4763  *                     destination is specified.
4764  * @param node   [i]   The LINK tag node is specified.
4765  * @return The conversion result is returned.
4766  */
4767 static char *
4768 s_chtml40_link_tag(void *pdoc, Node *node)
4769 {
4770   chtml40_t     *chtml40;
4771   Doc           *doc;
4772   Attr          *attr;
4773   char          *rel  = NULL;
4774   char          *href = NULL;
4775   char          *type = NULL;
4776
4777   chtml40 = GET_CHTML40(pdoc);
4778   doc     = chtml40->doc;
4779
4780   if (! IS_CSS_ON(chtml40->entryp)) {
4781     return chtml40->out;
4782   }
4783
4784   for (attr = qs_get_attr(doc,node);
4785        attr;
4786        attr = qs_get_next_attr(doc,attr)) {
4787     char *name  = qs_get_attr_name(doc,attr);
4788     char *value = qs_get_attr_value(doc,attr);
4789     if (STRCASEEQ('r','R',"rel", name)) {
4790       if (value && *value && STRCASEEQ('s','S',"stylesheet", value)) {
4791         rel = value;
4792       }
4793     }
4794     else if (STRCASEEQ('h','H',"href", name)) {
4795       if (value && *value) {
4796         href = value;
4797       }
4798     }
4799     else if (STRCASEEQ('t','T',"type", name)) {
4800       if (value && *value && STRCASEEQ('t','T',"text/css",value)) {
4801         type = value;
4802       }
4803     }
4804   }
4805
4806   if (rel && href && type) {
4807     DBG(doc->r, "start load CSS. url:[%s]", href);
4808     chtml40->style = chxj_css_parse_from_uri(doc->r, doc->pool, chtml40->style, href);
4809     DBG(doc->r, "end load CSS. url:[%s]", href);
4810   }
4811
4812   return chtml40->out;
4813 }
4814
4815 static css_prop_list_t *
4816 s_chtml40_push_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value)
4817 {
4818   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4819   Doc *doc = chtml40->doc;
4820   css_prop_list_t *last_css = NULL;
4821   if (IS_CSS_ON(chtml40->entryp)) {
4822     css_prop_list_t *dup_css;
4823     css_selector_t  *selector;
4824
4825     last_css = chxj_css_get_last_prop_list(chtml40->css_prop_stack);
4826     dup_css  = chxj_dup_css_prop_list(doc, last_css);
4827     selector = chxj_css_find_selector(doc, chtml40->style, node);
4828     if (selector) {
4829       chxj_css_prop_list_merge_property(doc, dup_css, selector);
4830     }
4831     chxj_css_push_prop_list(chtml40->css_prop_stack, dup_css);
4832     last_css = chxj_css_get_last_prop_list(chtml40->css_prop_stack);
4833
4834     if (style_attr_value) {
4835       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));
4836       if (ssheet) {
4837         chxj_css_prop_list_merge_property(doc, last_css, ssheet->selector_head.next);
4838       }
4839     }
4840   }
4841   return last_css;
4842 }
4843
4844
4845 static css_prop_list_t *
4846 s_chtml40_nopush_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value)
4847 {
4848   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4849   Doc *doc = chtml40->doc;
4850   css_prop_list_t *last_css = NULL;
4851   if (IS_CSS_ON(chtml40->entryp)) {
4852     css_prop_list_t *dup_css;
4853     css_selector_t  *selector;
4854
4855     last_css = chxj_css_get_last_prop_list(chtml40->css_prop_stack);
4856     dup_css  = chxj_dup_css_prop_list(doc, last_css);
4857     selector = chxj_css_find_selector(doc, chtml40->style, node);
4858     if (selector) {
4859       chxj_css_prop_list_merge_property(doc, dup_css, selector);
4860     }
4861     last_css = dup_css;
4862
4863     if (style_attr_value) {
4864       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));
4865       if (ssheet) {
4866         chxj_css_prop_list_merge_property(doc, last_css, ssheet->selector_head.next);
4867       }
4868     }
4869   }
4870   return last_css;
4871 }
4872
4873
4874
4875 /**
4876  * It is a handler who processes the SPAN tag.
4877  *
4878  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4879  *                     destination is specified.
4880  * @param node   [i]   The SPAN tag node is specified.
4881  * @return The conversion result is returned.
4882  */
4883 static char *
4884 s_chtml40_start_span_tag(void *pdoc, Node *node)
4885 {
4886   chtml40_t *chtml40;
4887   Doc *doc;
4888   Attr *attr;
4889   char *attr_style = NULL;
4890   char *attr_color = NULL;
4891   char *attr_align = NULL;
4892   char *attr_blink = NULL;
4893   char *attr_marquee = NULL;
4894   char *attr_marquee_dir = NULL;
4895   char *attr_marquee_style = NULL;
4896   char *attr_marquee_loop = NULL;
4897
4898   chtml40 = GET_CHTML40(pdoc);
4899   doc     = chtml40->doc;
4900
4901   for (attr = qs_get_attr(doc,node);
4902        attr;
4903        attr = qs_get_next_attr(doc,attr)) {
4904     char *nm  = qs_get_attr_name(doc,attr);
4905     char *val = qs_get_attr_value(doc,attr);
4906     if (val && STRCASEEQ('s','S',"style", nm)) {
4907       attr_style = val;
4908     }
4909   }
4910   if (IS_CSS_ON(chtml40->entryp)) {
4911     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
4912     if (style) {
4913       css_property_t *color_prop = chxj_css_get_property_value(doc, style, "color");
4914       css_property_t *text_align_prop = chxj_css_get_property_value(doc, style, "text-align");
4915       css_property_t *decoration_prop = chxj_css_get_property_value(doc, style, "text-decoration");
4916       css_property_t *display_prop = chxj_css_get_property_value(doc, style, "display");
4917       css_property_t *marquee_dir_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-dir");
4918       css_property_t *marquee_style_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-style");
4919       css_property_t *marquee_loop_prop = chxj_css_get_property_value(doc, style, "-wap-marquee-loop");
4920       css_property_t *cur;
4921       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
4922         attr_color = apr_pstrdup(doc->pool, cur->value);
4923       }
4924       for (cur = decoration_prop->next; cur != decoration_prop; cur = cur->next) {
4925         if (cur->value && STRCASEEQ('b','B',"blink",cur->value)) {
4926           attr_blink = apr_pstrdup(doc->pool, cur->value);
4927         }
4928       }
4929       for (cur = display_prop->next; cur != display_prop; cur = cur->next) {
4930         if (cur->value && strcasecmp("-wap-marquee",cur->value) == 0) {
4931           attr_marquee = apr_pstrdup(doc->pool, cur->value);
4932         }
4933       }
4934       for (cur = marquee_dir_prop->next; cur != marquee_dir_prop; cur = cur->next) {
4935         if (cur->value && *cur->value) {
4936           if (STRCASEEQ('l','L',"ltr",cur->value)) {
4937             attr_marquee_dir = "right";
4938           }
4939           else if (STRCASEEQ('r','R',"rtl",cur->value)) {
4940             attr_marquee_dir = "left";
4941           }
4942         }
4943       }
4944       for (cur = marquee_style_prop->next; cur != marquee_style_prop; cur = cur->next) {
4945         if (cur->value && *cur->value) {
4946           if ( STRCASEEQ('s','S',"scroll",cur->value)
4947             || STRCASEEQ('s','S',"slide",cur->value)
4948             || STRCASEEQ('a','A',"alternate",cur->value)) {
4949             attr_marquee_style = apr_pstrdup(doc->pool, cur->value);
4950           }
4951         }
4952       }
4953       for (cur = marquee_loop_prop->next; cur != marquee_loop_prop; cur = cur->next) {
4954         if (cur->value && *cur->value) {
4955           if (STRCASEEQ('i','I',"infinite",cur->value)) {
4956             attr_marquee_loop = "16";
4957           }
4958           else {
4959             attr_marquee_loop = apr_pstrdup(doc->pool, cur->value);
4960           }
4961         }
4962       }
4963       for (cur = text_align_prop->next; cur != text_align_prop; cur = cur->next) {
4964         if (STRCASEEQ('l','L',"left", cur->value)) {
4965           attr_align = apr_pstrdup(doc->pool, "left");
4966         }
4967         else if (STRCASEEQ('c','C',"center",cur->value)) {
4968           attr_align = apr_pstrdup(doc->pool, "center");
4969         }
4970         else if (STRCASEEQ('r','R',"right",cur->value)) {
4971           attr_align = apr_pstrdup(doc->pool, "right");
4972         }
4973       }
4974     }
4975   }
4976   if (attr_color || attr_align || attr_blink || attr_marquee) {
4977     chtml40_flags_t *flg = apr_palloc(doc->pool, sizeof(*flg));
4978     memset(flg, 0, sizeof(*flg));
4979     if (attr_blink) {
4980       W_L("<blink>");
4981       flg->with_blink_flag = 1;
4982     }
4983     if (attr_marquee) {
4984       W_L("<marquee");
4985       if (attr_marquee_dir) {
4986         W_L(" direction=\"");
4987         W_V(attr_marquee_dir);
4988         W_L("\"");
4989       }
4990       if (attr_marquee_style) {
4991         W_L(" behavior=\"");
4992         W_V(attr_marquee_style);
4993         W_L("\"");
4994       }
4995       if (attr_marquee_loop) {
4996         W_L(" loop=\"");
4997         W_V(attr_marquee_loop);
4998         W_L("\"");
4999       }
5000       W_L(">");
5001       flg->with_marquee_flag = 1;
5002     }
5003     if (attr_color) {
5004       attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
5005       W_L("<font color=\"");
5006       W_V(attr_color);
5007       W_L("\">");
5008       flg->with_font_flag = 1;
5009     }
5010     if (attr_align) {
5011       W_L("<div align=\"");
5012       W_V(attr_align);
5013       W_L("\">");
5014       flg->with_div_flag = 1;
5015     }
5016     node->userData = flg;
5017   }
5018   else {
5019     node->userData = NULL;
5020   }
5021   return chtml40->out;
5022 }
5023
5024
5025 /**
5026  * It is a handler who processes the SPAN tag.
5027  *
5028  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
5029  *                     destination is specified.
5030  * @param node   [i]   The SPAN tag node is specified.
5031  * @return The conversion result is returned.
5032  */
5033 static char *
5034 s_chtml40_end_span_tag(void *pdoc, Node *node)
5035 {
5036   chtml40_t *chtml40 = GET_CHTML40(pdoc);
5037   Doc *doc = chtml40->doc;
5038
5039   chtml40_flags_t *flg = (chtml40_flags_t *)node->userData;
5040   if (flg && flg->with_div_flag) {
5041     W_L("</div>");
5042   }
5043   if (flg && flg->with_font_flag) {
5044     W_L("</font>");
5045   }
5046   if (flg && flg->with_marquee_flag) {
5047     W_L("</marquee>");
5048   }
5049   if (flg && flg->with_blink_flag) {
5050     W_L("</blink>");
5051   }
5052   if (IS_CSS_ON(chtml40->entryp)) {
5053     chxj_css_pop_prop_list(chtml40->css_prop_stack);
5054   }
5055   return chtml40->out;
5056 }
5057
5058
5059 /**
5060  * It is a handler who processes the STYLE tag.
5061  *
5062  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
5063  *                     destination is specified.
5064  * @param node   [i]   The STYLE tag node is specified.
5065  * @return The conversion result is returned.
5066  */
5067 static char *
5068 s_chtml40_style_tag(void *pdoc, Node *node)
5069 {
5070   chtml40_t     *chtml40;
5071   Doc           *doc;
5072   Attr          *attr;
5073   char          *type = NULL;
5074
5075   chtml40 = GET_CHTML40(pdoc);
5076   doc     = chtml40->doc;
5077
5078   if (! IS_CSS_ON(chtml40->entryp)) {
5079     return chtml40->out;
5080   }
5081
5082   for (attr = qs_get_attr(doc,node);
5083        attr;
5084        attr = qs_get_next_attr(doc,attr)) {
5085     char *name  = qs_get_attr_name(doc,attr);
5086     char *value = qs_get_attr_value(doc,attr);
5087     if (STRCASEEQ('t','T',"type", name)) {
5088       if (value && *value && STRCASEEQ('t','T',"text/css",value)) {
5089         type = value;
5090       }
5091     }
5092   }
5093
5094   Node *child = qs_get_child_node(doc, node);
5095   if (type && child) {
5096     char *name  = qs_get_node_name(doc, child);
5097     if (STRCASEEQ('t','T',"text", name)) {
5098       char *value = qs_get_node_value(doc, child);
5099       DBG(doc->r, "start load CSS. buf:[%s]", value);
5100       chtml40->style = chxj_css_parse_style_value(doc, chtml40->style, value);
5101       DBG(doc->r, "end load CSS. value:[%s]", value);
5102     }
5103   }
5104   return chtml40->out;
5105 }
5106 /*
5107  * vim:ts=2 et
5108  */