OSDN Git Service

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