OSDN Git Service

* Added img tag with CSS for SoftBank HTML converter.
[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
1451   chtml40 = GET_CHTML40(pdoc);
1452   doc     = chtml40->doc;
1453   r       = doc->r;
1454
1455   /*--------------------------------------------------------------------------*/
1456   /* Get Attributes                                                           */
1457   /*--------------------------------------------------------------------------*/
1458   for (attr = qs_get_attr(doc,node);
1459        attr;
1460        attr = qs_get_next_attr(doc,attr)) {
1461     char *name  = qs_get_attr_name(doc,attr);
1462     char *value = qs_get_attr_value(doc,attr);
1463     switch(*name) {
1464     case 'a':
1465     case 'A':
1466       if (strcasecmp(name, "action") == 0) {
1467         /*--------------------------------------------------------------------*/
1468         /* CHTML 1.0                                                          */
1469         /*--------------------------------------------------------------------*/
1470         attr_action = value;
1471       }
1472       break;
1473
1474     case 'm':
1475     case 'M':
1476       if (strcasecmp(name, "method") == 0) {
1477         /*--------------------------------------------------------------------*/
1478         /* CHTML 1.0                                                          */
1479         /*--------------------------------------------------------------------*/
1480         attr_method = value;
1481       }
1482       break;
1483
1484     case 'u':
1485     case 'U':
1486       if (strcasecmp(name, "utn") == 0) {
1487         /*--------------------------------------------------------------------*/
1488         /* CHTML 3.0                                                          */
1489         /*--------------------------------------------------------------------*/
1490         attr_utn = value;
1491       }
1492       break;
1493
1494     case 's':
1495     case 'S':
1496       if (strcasecmp(name, "style") == 0) {
1497         attr_style = value;
1498       }
1499       break;
1500
1501     default:
1502       break;
1503     }
1504   }
1505   if (IS_CSS_ON(chtml40->entryp)) {
1506     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
1507     if (style) {
1508       css_property_t *text_align_prop = chxj_css_get_property_value(doc, style, "text-align");
1509       css_property_t *color_prop      = chxj_css_get_property_value(doc, style, "color");
1510       css_property_t *cur;
1511       for (cur = text_align_prop->next; cur != text_align_prop; cur = cur->next) {
1512         if (STRCASEEQ('l','L',"left", cur->value)) {
1513           attr_align = apr_pstrdup(doc->pool, "left");
1514         }
1515         else if (STRCASEEQ('c','C',"center",cur->value)) {
1516           attr_align = apr_pstrdup(doc->pool, "center");
1517         }
1518         else if (STRCASEEQ('r','R',"right",cur->value)) {
1519           attr_align = apr_pstrdup(doc->pool, "right");
1520         }
1521       }
1522       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
1523         attr_color = apr_pstrdup(doc->pool, cur->value);
1524       }
1525     }
1526   }
1527   W_L("<form");
1528   if (attr_action) {
1529     attr_action = chxj_encoding_parameter(r, attr_action);
1530     attr_action = chxj_add_cookie_parameter(r, attr_action, chtml40->cookie);
1531     W_L(" action=\"");
1532     W_V(attr_action);
1533     W_L("\"");
1534   }
1535   if (attr_method) {
1536     W_L(" method=\"");
1537     W_V(attr_method);
1538     W_L("\"");
1539   }
1540   if (attr_utn) {
1541     W_L(" utn");
1542   }
1543   W_L(">");
1544
1545   chtml40_flags_t *flg = (chtml40_flags_t *)apr_palloc(doc->pool, sizeof(chtml40_flags_t));
1546   memset(flg, 0, sizeof(*flg));
1547   if (attr_color) {
1548     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
1549     W_L("<font color=\"");
1550     W_V(attr_color);
1551     W_L("\">");
1552     flg->with_font_flag = 1;
1553   }
1554   if (attr_align) {
1555     W_L("<div align=\"");
1556     W_V(attr_align);
1557     W_L("\">");
1558     flg->with_div_flag = 1;
1559   }
1560   node->userData = flg;
1561
1562   return chtml40->out;
1563 }
1564
1565
1566 /**
1567  * It is a handler who processes the FORM tag.
1568  *
1569  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1570  *                     destination is specified.
1571  * @param node   [i]   The FORM tag node is specified.
1572  * @return The conversion result is returned.
1573  */
1574 static char *
1575 s_chtml40_end_form_tag(void *pdoc, Node *node)
1576 {
1577   chtml40_t    *chtml40;
1578   Doc          *doc;
1579
1580   chtml40 = GET_CHTML40(pdoc);
1581   doc     = chtml40->doc;
1582
1583   chtml40_flags_t *flg = (chtml40_flags_t *)node->userData;
1584   if (flg && flg->with_div_flag) {
1585     W_L("</div>");
1586   }
1587   if (flg && flg->with_font_flag) {
1588     W_L("</font>");
1589   }
1590   W_L("</form>");
1591   if (IS_CSS_ON(chtml40->entryp)) {
1592     chxj_css_pop_prop_list(chtml40->css_prop_stack);
1593   }
1594
1595   return chtml40->out;
1596 }
1597
1598
1599 /**
1600  * It is a handler who processes the INPUT tag.
1601  *
1602  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1603  *                     destination is specified.
1604  * @param node   [i]   The INPUT tag node is specified.
1605  * @return The conversion result is returned.
1606  */
1607 static char *
1608 s_chtml40_start_input_tag(void *pdoc, Node *node) 
1609 {
1610   chtml40_t   *chtml40;
1611   Doc         *doc;
1612   request_rec *r;
1613   Attr        *attr;
1614   char        *attr_accesskey  = NULL;
1615   char        *attr_max_length = NULL;
1616   char        *attr_type       = NULL;
1617   char        *attr_name       = NULL;
1618   char        *attr_value      = NULL;
1619   char        *attr_istyle     = NULL;
1620   char        *attr_size       = NULL;
1621   char        *attr_checked    = NULL;
1622   char        *attr_style      = NULL;
1623
1624   chtml40 = GET_CHTML40(pdoc);
1625   doc     = chtml40->doc;
1626   r       = doc->r;
1627
1628   /*--------------------------------------------------------------------------*/
1629   /* Get Attributes                                                           */
1630   /*--------------------------------------------------------------------------*/
1631   for (attr = qs_get_attr(doc,node);
1632        attr;
1633        attr = qs_get_next_attr(doc,attr)) {
1634     char *name  = qs_get_attr_name(doc,attr);
1635     char *value = qs_get_attr_value(doc,attr);
1636     if (STRCASEEQ('t','T',"type",name) && value && *value) {
1637       char *tmp_type = qs_trim_string(doc->buf.pool, value);
1638       if (tmp_type && (STRCASEEQ('t','T',"text",    tmp_type) ||
1639                        STRCASEEQ('p','P',"password",tmp_type) ||
1640                        STRCASEEQ('c','C',"checkbox",tmp_type) ||
1641                        STRCASEEQ('r','R',"radio",   tmp_type) ||
1642                        STRCASEEQ('h','H',"hidden",  tmp_type) ||
1643                        STRCASEEQ('s','S',"submit",  tmp_type) ||
1644                        STRCASEEQ('r','R',"reset",   tmp_type))) {
1645         attr_type = tmp_type;
1646       }
1647     }
1648     else if (STRCASEEQ('n','N',"name",name) && value && *value) {
1649       attr_name = value;
1650     }
1651     else if (STRCASEEQ('v','V',"value",name) && value && *value) {
1652       attr_value = value;
1653     }
1654     else if (STRCASEEQ('i','I',"istyle",name) && value && *value) {
1655       attr_istyle = value;
1656     }
1657     else if (STRCASEEQ('m','M',"maxlength",name) && value && *value) {
1658       attr_max_length = value;
1659     }
1660     else if (STRCASEEQ('c','C',"checked", name)) {
1661       attr_checked = value;
1662     }
1663     else if (STRCASEEQ('a','A',"accesskey", name) && value && *value) {
1664       attr_accesskey = value;
1665     }
1666     else if (STRCASEEQ('s','S',"size", name) && value && *value) {
1667       attr_size = value;
1668     }
1669     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
1670       attr_style = value;
1671     }
1672   }
1673
1674   if (IS_CSS_ON(chtml40->entryp)) {
1675     css_prop_list_t *style = s_chtml40_nopush_and_get_now_style(pdoc, node, attr_style);
1676     if (style) {
1677       css_property_t *wap_input_format = chxj_css_get_property_value(doc, style, "-wap-input-format");
1678       css_property_t *cur;
1679       for (cur = wap_input_format->next; cur != wap_input_format; cur = cur->next) {
1680         if (strcasestr(cur->value, "<ja:n>")) {
1681           attr_istyle = "4";
1682         }
1683         else if (strcasestr(cur->value, "<ja:en>")) {
1684           attr_istyle = "3";
1685         }
1686         else if (strcasestr(cur->value, "<ja:hk>")) {
1687           attr_istyle = "2";
1688         }
1689         else if (strcasestr(cur->value, "<ja:h>")) {
1690           attr_istyle = "1";
1691         }
1692       }
1693     }
1694   }
1695
1696   W_L("<input");
1697   if (attr_type) {
1698     W_L(" type=\"");
1699     W_V(attr_type);
1700     W_L("\"");
1701   }
1702   if (attr_size) {
1703     W_L(" size=\"");
1704     W_V(attr_size);
1705     W_L("\"");
1706   }
1707   if (attr_name) {
1708     W_L(" name=\"");
1709     W_V(attr_name);
1710     W_L("\"");
1711   }
1712   if (attr_value) {
1713     W_L(" value=\"");
1714     W_V(chxj_add_slash_to_doublequote(doc->pool, attr_value));
1715     W_L("\"");
1716   }
1717   if (attr_accesskey) {
1718     W_L(" accesskey=\"");
1719     W_V(attr_accesskey);
1720     W_L("\"");
1721   }
1722   if (attr_istyle) {
1723     if (*attr_istyle == '1' || *attr_istyle == '2' || *attr_istyle == '3' || *attr_istyle == '4') {
1724       W_L(" istyle=\"");
1725       W_V(attr_istyle);
1726       W_L("\"");
1727     }
1728   }
1729   /*--------------------------------------------------------------------------*/
1730   /* The figure is default for the password.                                  */
1731   /*--------------------------------------------------------------------------*/
1732   if (attr_max_length) {
1733     if (chxj_chk_numeric(attr_max_length) != 0) {
1734       attr_max_length = apr_psprintf(doc->buf.pool, "0");
1735     }
1736     if (attr_istyle && *attr_istyle == '1') {
1737       char *vv = apr_psprintf(doc->buf.pool, " maxlength=\"%d\"", chxj_atoi(attr_max_length) * 2);
1738       W_V(vv);
1739     }
1740     else {
1741       char *vv = apr_psprintf(doc->buf.pool, " maxlength=\"%d\"", chxj_atoi(attr_max_length));
1742       W_V(vv);
1743     }
1744   }
1745   if (attr_checked) {
1746     W_L(" checked");
1747   }
1748   W_L(">");
1749
1750   return chtml40->out;
1751 }
1752
1753
1754 /**
1755  * It is a handler who processes the INPUT tag.
1756  *
1757  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1758  *                     destination is specified.
1759  * @param node   [i]   The INPUT tag node is specified.
1760  * @return The conversion result is returned.
1761  */
1762 static char *
1763 s_chtml40_end_input_tag(void *pdoc, Node *UNUSED(child)) 
1764 {
1765   chtml40_t *chtml40 = GET_CHTML40(pdoc);
1766
1767   return chtml40->out;
1768 }
1769
1770
1771 /**
1772  * It is a handler who processes the CENTER tag.
1773  *
1774  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1775  *                     destination is specified.
1776  * @param node   [i]   The CENTER tag node is specified.
1777  * @return The conversion result is returned.
1778  */
1779 static char *
1780 s_chtml40_start_center_tag(void *pdoc, Node *node)
1781 {
1782   chtml40_t   *chtml40;
1783   Doc         *doc;
1784   Attr        *attr;
1785   char        *attr_style = NULL;
1786   char        *attr_color = NULL;
1787
1788   chtml40 = GET_CHTML40(pdoc);
1789   doc     = chtml40->doc;
1790
1791   for (attr = qs_get_attr(doc,node);
1792        attr;
1793        attr = qs_get_next_attr(doc,attr)) {
1794     char *name  = qs_get_attr_name(doc,attr);
1795     char *value = qs_get_attr_value(doc,attr);
1796     if (STRCASEEQ('s','S',"style",name) && value && *value) {
1797       attr_style = value;
1798     }
1799   }
1800   if (IS_CSS_ON(chtml40->entryp)) {
1801     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
1802     if (style) {
1803       css_property_t *color_prop      = chxj_css_get_property_value(doc, style, "color");
1804       css_property_t *cur;
1805       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
1806         if (cur->value && *cur->value) {
1807           attr_color = apr_pstrdup(doc->pool, cur->value);
1808         }
1809       }
1810     }
1811   }
1812
1813   W_L("<center>");
1814   chtml40_flags_t *flg = (chtml40_flags_t *)apr_palloc(doc->pool, sizeof(chtml40_flags_t));
1815   memset(flg, 0, sizeof(*flg));
1816   if (attr_color) {
1817     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
1818     W_L("<font color=\"");
1819     W_V(attr_color);
1820     W_L("\">");
1821     flg->with_font_flag = 1;
1822   }
1823   node->userData = flg;
1824
1825   return chtml40->out;
1826 }
1827
1828
1829 /**
1830  * It is a handler who processes the CENTER tag.
1831  *
1832  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1833  *                     destination is specified.
1834  * @param node   [i]   The CENTER tag node is specified.
1835  * @return The conversion result is returned.
1836  */
1837 static char *
1838 s_chtml40_end_center_tag(void *pdoc, Node *node)
1839 {
1840   chtml40_t     *chtml40;
1841   Doc           *doc;
1842
1843   chtml40 = GET_CHTML40(pdoc);
1844   doc     = chtml40->doc;
1845
1846   if (IS_CSS_ON(chtml40->entryp)) {
1847     chxj_css_pop_prop_list(chtml40->css_prop_stack);
1848   }
1849   chtml40_flags_t *flg = (chtml40_flags_t *)node->userData;
1850   if (flg && flg->with_font_flag) {
1851     W_L("</font>");
1852   }
1853   W_L("</center>");
1854
1855   return chtml40->out;
1856 }
1857
1858
1859 /**
1860  * It is a handler who processes the HR tag.
1861  *
1862  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
1863  *                     destination is specified.
1864  * @param node   [i]   The HR tag node is specified.
1865  * @return The conversion result is returned.
1866  */
1867 static char *
1868 s_chtml40_start_hr_tag(void *pdoc, Node *node) 
1869 {
1870   Attr        *attr;
1871   chtml40_t   *chtml40;
1872   Doc         *doc;
1873   request_rec *r;
1874   char        *attr_align   = NULL;
1875   char        *attr_size    = NULL;
1876   char        *attr_width   = NULL;
1877   char        *attr_noshade = NULL;
1878   char        *attr_style   = NULL;
1879   char        *attr_color   = NULL;
1880
1881   chtml40 = GET_CHTML40(pdoc);
1882   doc     = chtml40->doc;
1883   r       = doc->r;
1884
1885   for (attr = qs_get_attr(doc,node);
1886        attr; 
1887        attr = qs_get_next_attr(doc,attr)) {
1888     char *name  = qs_get_attr_name (doc,attr);
1889     char *value = qs_get_attr_value(doc,attr);
1890     switch(*name) {
1891     case 'a':
1892     case 'A':
1893       if (strcasecmp(name, "align") == 0) {
1894         /*--------------------------------------------------------------------*/
1895         /* CHTML 1.0                                                          */
1896         /*--------------------------------------------------------------------*/
1897         if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
1898           attr_align = value;
1899         }
1900       }
1901       break;
1902
1903     case 's':
1904     case 'S':
1905       if (strcasecmp(name, "size") == 0) {
1906         /*--------------------------------------------------------------------*/
1907         /* CHTML 1.0                                                          */
1908         /*--------------------------------------------------------------------*/
1909         if (value && *value) {
1910           attr_size = value;
1911         }
1912       }
1913       else if (strcasecmp(name, "style") == 0) {
1914         if (value && *value) {
1915           attr_style = value;
1916         }
1917       }
1918       break;
1919
1920     case 'w':
1921     case 'W':
1922       if (strcasecmp(name, "width") == 0) {
1923         /*--------------------------------------------------------------------*/
1924         /* CHTML 1.0                                                          */
1925         /*--------------------------------------------------------------------*/
1926         if (value && *value) {
1927           attr_width = value;
1928         }
1929       }
1930       break;
1931
1932     case 'n':
1933     case 'N':
1934       if (strcasecmp(name, "noshade") == 0) {
1935         /*--------------------------------------------------------------------*/
1936         /* CHTML 1.0                                                          */
1937         /*--------------------------------------------------------------------*/
1938         attr_noshade = apr_pstrdup(doc->pool, "noshade");
1939       }
1940       break;
1941
1942     case 'c':
1943     case 'C':
1944       if (strcasecmp(name, "color") == 0 && value && *value) {
1945         /*--------------------------------------------------------------------*/
1946         /* CHTML 4.0                                                          */
1947         /*--------------------------------------------------------------------*/
1948         attr_color = value;
1949       }
1950       break;
1951
1952     default:
1953       break;
1954     }
1955   }
1956   if (IS_CSS_ON(chtml40->entryp)) {
1957     css_prop_list_t *style = s_chtml40_nopush_and_get_now_style(pdoc, node, attr_style);
1958     if (style) {
1959       css_property_t *border_style_prop = chxj_css_get_property_value(doc, style, "border-style");
1960       css_property_t *height_prop       = chxj_css_get_property_value(doc, style, "height");
1961       css_property_t *width_prop        = chxj_css_get_property_value(doc, style, "width");
1962       css_property_t *cur;
1963       for (cur = border_style_prop->next; cur != border_style_prop; cur = cur->next) {
1964         if (STRCASEEQ('s','S',"solid",cur->value)) {
1965           attr_noshade = "noshade";
1966         }
1967       }
1968       for (cur = height_prop->next; cur != height_prop; cur = cur->next) {
1969         char *tmp = apr_pstrdup(doc->pool, cur->value);
1970         char *tmpp = strstr(tmp, "px");
1971         if (tmpp) { 
1972           *tmpp = 0;
1973           attr_size = apr_pstrdup(doc->pool, tmp);
1974         }
1975       }
1976       for (cur = width_prop->next; cur != width_prop; cur = cur->next) {
1977         char *tmp = apr_pstrdup(doc->pool, cur->value);
1978         char *tmpp = strstr(tmp, "px");
1979         if (tmpp) {
1980           *tmpp = 0;
1981           attr_width = apr_pstrdup(doc->pool, tmp);
1982         }
1983         else {
1984           tmpp = strstr(tmp, "%");
1985           if (tmpp) {
1986             attr_width = apr_pstrdup(doc->pool, tmp);
1987           }
1988         }
1989       }
1990     }
1991   }
1992   W_L("<hr");
1993   if (attr_align) {
1994     W_L(" align=\"");
1995     W_V(attr_align);
1996     W_L("\"");
1997   }
1998   if (attr_size) {
1999     W_L(" size=\"");
2000     W_V(attr_size);
2001     W_L("\"");
2002   }
2003   if (attr_width) {
2004     W_L(" width=\"");
2005     W_V(attr_width);
2006     W_L("\"");
2007   }
2008   if (attr_color) {
2009     W_L(" color=\"");
2010     W_V(attr_color);
2011     W_L("\"");
2012   }
2013   if (attr_noshade) {
2014     W_L(" noshade");
2015   }
2016   W_L(">");
2017   return chtml40->out;
2018 }
2019
2020
2021 /**
2022  * It is a handler who processes the HR tag.
2023  *
2024  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2025  *                     destination is specified.
2026  * @param node   [i]   The HR tag node is specified.
2027  * @return The conversion result is returned.
2028  */
2029 static char *
2030 s_chtml40_end_hr_tag(void *pdoc, Node *UNUSED(child)) 
2031 {
2032   chtml40_t *chtml40 = GET_CHTML40(pdoc);
2033
2034   return chtml40->out;
2035 }
2036
2037
2038 /**
2039  * It is a handler who processes the IMG tag.
2040  *
2041  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2042  *                     destination is specified.
2043  * @param node   [i]   The IMG tag node is specified.
2044  * @return The conversion result is returned.
2045  */
2046 static char *
2047 s_chtml40_start_img_tag(void *pdoc, Node *node) 
2048 {
2049   chtml40_t   *chtml40;
2050   Doc         *doc;
2051   request_rec *r;
2052   Attr        *attr;
2053   char        *attr_src    = NULL;
2054   char        *attr_align  = NULL;
2055   char        *attr_style  = NULL;
2056   char        *attr_alt    = NULL;
2057   char        *attr_width  = NULL;
2058   char        *attr_height = NULL;
2059   char        *attr_hspace = NULL;
2060   char        *attr_vspace = NULL;
2061 #ifndef IMG_NOT_CONVERT_FILENAME
2062   device_table *spec;
2063 #endif
2064
2065   chtml40 = GET_CHTML40(pdoc);
2066 #ifndef IMG_NOT_CONVERT_FILENAME
2067   spec    = chtml40->spec;
2068 #endif
2069   doc     = chtml40->doc;
2070   r       = doc->r;
2071
2072   /*--------------------------------------------------------------------------*/
2073   /* Get Attributes                                                           */
2074   /*--------------------------------------------------------------------------*/
2075   for (attr = qs_get_attr(doc,node);
2076        attr;
2077        attr = qs_get_next_attr(doc,attr)) {
2078     char *name  = qs_get_attr_name (doc,attr);
2079     char *value = qs_get_attr_value(doc,attr);
2080     switch(*name) {
2081     case 's':
2082     case 'S':
2083       if (strcasecmp(name, "src") == 0) {
2084         /*--------------------------------------------------------------------*/
2085         /* CHTML 1.0                                                          */
2086         /*--------------------------------------------------------------------*/
2087 #ifdef IMG_NOT_CONVERT_FILENAME
2088         value = chxj_encoding_parameter(r, value);
2089         value = chxj_add_cookie_parameter(r, value, chtml40->cookie);
2090         if (value) {
2091           value = apr_psprintf(doc->buf.pool, 
2092                                "%s%c%s=true", 
2093                                value, 
2094                                (strchr(value, '?')) ? '&' : '?',
2095                                CHXJ_COOKIE_NOUPDATE_PARAM);
2096         }
2097         attr_src = value;
2098 #else
2099         value = chxj_img_conv(r, spec, value);
2100         value = chxj_encoding_parameter(r, value);
2101         value = chxj_add_cookie_parameter(r, value, chtml40->cookie);
2102         if (value) {
2103           value = apr_psprintf(doc->buf.pool,
2104                                "%s%c%s=true",
2105                                value,
2106                                (strchr(value, '?')) ? '&' : '?',
2107                                CHXJ_COOKIE_NOUPDATE_PARAM);
2108         }
2109         attr_src = value;
2110 #endif
2111       }
2112       else if (strcasecmp(name,"style") == 0 && value && *value) {
2113         attr_style = value;
2114       }
2115       break;
2116
2117     case 'a':
2118     case 'A':
2119       if (strcasecmp(name, "align" ) == 0) {
2120         /*--------------------------------------------------------------------*/
2121         /* CHTML 1.0                                                          */
2122         /*--------------------------------------------------------------------*/
2123         /*--------------------------------------------------------------------*/
2124         /* CHTML 4.0                                                          */
2125         /*--------------------------------------------------------------------*/
2126         if (value) {
2127           if (STRCASEEQ('t','T',"top",   value) ||
2128               STRCASEEQ('m','M',"middle",value) ||
2129               STRCASEEQ('b','B',"bottom",value) ||
2130               STRCASEEQ('l','L',"left",  value) ||
2131               STRCASEEQ('r','R',"right", value)) {
2132             attr_align = value;
2133           }
2134           else if (STRCASEEQ('c','C',"center",  value)) {
2135             attr_align = apr_pstrdup(doc->pool, "middle");
2136           }
2137         }
2138       }
2139       else if (strcasecmp(name, "alt"   ) == 0 && value && *value) {
2140         /*--------------------------------------------------------------------*/
2141         /* CHTML 1.0                                                          */
2142         /*--------------------------------------------------------------------*/
2143         attr_alt = value;
2144       }
2145       break;
2146
2147     case 'w':
2148     case 'W':
2149       if (strcasecmp(name, "width" ) == 0 && value && *value) {
2150         /*--------------------------------------------------------------------*/
2151         /* CHTML 1.0                                                          */
2152         /*--------------------------------------------------------------------*/
2153         attr_width = value;
2154       }
2155       break;
2156
2157     case 'h':
2158     case 'H':
2159       if (strcasecmp(name, "height") == 0 && value && *value) {
2160         /*--------------------------------------------------------------------*/
2161         /* CHTML 1.0                                                          */
2162         /*--------------------------------------------------------------------*/
2163         attr_height = value;
2164       }
2165       else
2166       if (strcasecmp(name, "hspace") == 0 && value && *value) {
2167         /*--------------------------------------------------------------------*/
2168         /* CHTML 1.0                                                          */
2169         /*--------------------------------------------------------------------*/
2170         attr_hspace = value;
2171       }
2172       break;
2173
2174     case 'v':
2175     case 'V':
2176       if (strcasecmp(name, "vspace") == 0 && value && *value) {
2177         /*--------------------------------------------------------------------*/
2178         /* CHTML 1.0                                                          */
2179         /*--------------------------------------------------------------------*/
2180         attr_vspace = value;
2181       }
2182       break;
2183
2184     default:
2185       break;
2186     }
2187   }
2188
2189   if (IS_CSS_ON(chtml40->entryp)) {
2190     css_prop_list_t *style = s_chtml40_nopush_and_get_now_style(pdoc, node, attr_style);
2191     if (style) {
2192       css_property_t *height_prop = chxj_css_get_property_value(doc, style, "height");
2193       css_property_t *width_prop  = chxj_css_get_property_value(doc, style, "width");
2194       css_property_t *valign_prop = chxj_css_get_property_value(doc, style, "vertical-align");
2195       css_property_t *cur;
2196       for (cur = height_prop->next; cur != height_prop; cur = cur->next) {
2197         attr_height = apr_pstrdup(doc->pool, cur->value);
2198       }
2199       for (cur = width_prop->next; cur != width_prop; cur = cur->next) {
2200         attr_width = apr_pstrdup(doc->pool, cur->value);
2201       }
2202       for (cur = valign_prop->next; cur != valign_prop; cur = cur->next) {
2203         attr_align = apr_pstrdup(doc->pool, cur->value);
2204       }
2205     }
2206   }
2207
2208   W_L("<img");
2209   if (attr_src) {
2210     W_L(" src=\"");
2211     W_V(attr_src);
2212     W_L("\"");
2213   }
2214   if (attr_align) {
2215     W_L(" align=\"");
2216     W_V(attr_align);
2217     W_L("\"");
2218   }
2219   if (attr_alt) {
2220     W_L(" alt=\"");
2221     W_V(attr_alt);
2222     W_L("\"");
2223   }
2224   if (attr_width) {
2225     W_L(" width=\"");
2226     W_V(attr_width);
2227     W_L("\"");
2228   }
2229   if (attr_height) {
2230     W_L(" height=\"");
2231     W_V(attr_height);
2232     W_L("\"");
2233   }
2234   if (attr_hspace) {
2235     W_L(" hspace=\"");
2236     W_V(attr_hspace);
2237     W_L("\"");
2238   }
2239   if (attr_vspace) {
2240     W_L(" vspace=\"");
2241     W_V(attr_vspace);
2242     W_L("\"");
2243   }
2244   W_L(">");
2245   return chtml40->out;
2246 }
2247
2248
2249 /**
2250  * It is a handler who processes the IMG tag.
2251  *
2252  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2253  *                     destination is specified.
2254  * @param node   [i]   The IMG tag node is specified.
2255  * @return The conversion result is returned.
2256  */
2257 static char *
2258 s_chtml40_end_img_tag(void *pdoc, Node *UNUSED(child)) 
2259 {
2260   chtml40_t *chtml40 = GET_CHTML40(pdoc);
2261
2262   return chtml40->out;
2263 }
2264
2265
2266 /**
2267  * It is a handler who processes the SELECT tag.
2268  *
2269  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2270  *                     destination is specified.
2271  * @param node   [i]   The SELECT tag node is specified.
2272  * @return The conversion result is returned.
2273  */
2274 static char *
2275 s_chtml40_start_select_tag(void *pdoc, Node *child)
2276 {
2277   chtml40_t   *chtml40  = GET_CHTML40(pdoc);
2278   Doc         *doc      = chtml40->doc;
2279   char        *size     = NULL;
2280   char        *name     = NULL;
2281   char        *multiple = NULL;
2282   Attr        *attr;
2283
2284   W_L("<select");
2285   for (attr = qs_get_attr(doc,child);
2286        attr;
2287        attr = qs_get_next_attr(doc,attr)) {
2288     char *nm  = qs_get_attr_name(doc,attr);
2289     char *val = qs_get_attr_value(doc,attr);
2290     if (STRCASEEQ('s','S',"size", nm)) {
2291       /*----------------------------------------------------------------------*/
2292       /* CHTML 1.0 version 2.0                                                */
2293       /*----------------------------------------------------------------------*/
2294       size = apr_pstrdup(doc->buf.pool, val);
2295     }
2296     else if (STRCASEEQ('n','N',"name", nm)) {
2297       /*----------------------------------------------------------------------*/
2298       /* CHTML 1.0 version 2.0                                                */
2299       /*----------------------------------------------------------------------*/
2300       name = apr_pstrdup(doc->buf.pool, val);
2301     }
2302     else if (STRCASEEQ('m','M',"multiple", nm)) {
2303       /*----------------------------------------------------------------------*/
2304       /* CHTML 1.0 version 2.0                                                */
2305       /*----------------------------------------------------------------------*/
2306       multiple = apr_pstrdup(doc->buf.pool, val);
2307     }
2308   }
2309   if (size && *size) {
2310     W_L(" size=\"");
2311     W_V(size);
2312     W_L("\"");
2313   }
2314   if (name && *name) {
2315     W_L(" name=\"");
2316     W_V(name);
2317     W_L("\"");
2318   }
2319   if (multiple) {
2320     W_L(" multiple");
2321   }
2322   W_L(">");
2323   return chtml40->out;
2324 }
2325
2326
2327 /**
2328  * It is a handler who processes the SELECT tag.
2329  *
2330  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2331  *                     destination is specified.
2332  * @param node   [i]   The SELECT tag node is specified.
2333  * @return The conversion result is returned.
2334  */
2335 static char *
2336 s_chtml40_end_select_tag(void *pdoc, Node *UNUSED(child))
2337 {
2338   chtml40_t    *chtml40 = GET_CHTML40(pdoc);
2339   Doc          *doc   = chtml40->doc;
2340
2341   W_L("</select>");
2342   return chtml40->out;
2343 }
2344
2345
2346 /**
2347  * It is a handler who processes the OPTION tag.
2348  *
2349  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2350  *                     destination is specified.
2351  * @param node   [i]   The OPTION tag node is specified.
2352  * @return The conversion result is returned.
2353  */
2354 static char *
2355 s_chtml40_start_option_tag(void *pdoc, Node *child)
2356 {
2357   Attr        *attr;
2358   chtml40_t   *chtml40;
2359   Doc         *doc;
2360   request_rec *r;
2361   char        *selected;
2362   char        *value;
2363
2364   chtml40    = GET_CHTML40(pdoc);
2365   doc        = chtml40->doc;
2366   r          = doc->r;
2367   selected   = NULL;
2368   value      = NULL;
2369
2370   W_L("<option");
2371   for (attr = qs_get_attr(doc,child);
2372        attr;
2373        attr = qs_get_next_attr(doc,attr)) {
2374     char *nm  = qs_get_attr_name(doc,attr);
2375     char *val = qs_get_attr_value(doc,attr);
2376     if (STRCASEEQ('s','S',"selected", nm)) {
2377       /*----------------------------------------------------------------------*/
2378       /* CHTML 1.0 version 2.0                                                */
2379       /*----------------------------------------------------------------------*/
2380       selected = apr_pstrdup(doc->buf.pool, val);
2381     }
2382     else if (STRCASEEQ('v','V',"value", nm)) {
2383       /*----------------------------------------------------------------------*/
2384       /* CHTML 1.0 version 2.0                                                */
2385       /*----------------------------------------------------------------------*/
2386       value = apr_pstrdup(doc->buf.pool, val);
2387     }
2388   }
2389   if (value && *value) {
2390     W_L(" value=\"");
2391     W_V(value);
2392     W_L("\"");
2393   }
2394   if (selected) {
2395     W_L(" selected");
2396   }
2397   W_L(">");
2398   return chtml40->out;
2399 }
2400
2401
2402 /**
2403  * It is a handler who processes the OPTION tag.
2404  *
2405  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2406  *                     destination is specified.
2407  * @param node   [i]   The OPTION tag node is specified.
2408  * @return The conversion result is returned.
2409  */
2410 static char *
2411 s_chtml40_end_option_tag(void *pdoc, Node *UNUSED(child))
2412 {
2413   chtml40_t *chtml40 = GET_CHTML40(pdoc);
2414
2415   /* Don't close */
2416
2417   return chtml40->out;
2418 }
2419
2420
2421 /**
2422  * It is a handler who processes the DIV tag.
2423  *
2424  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2425  *                     destination is specified.
2426  * @param node   [i]   The DIV tag node is specified.
2427  * @return The conversion result is returned.
2428  */
2429 static char *
2430 s_chtml40_start_div_tag(void *pdoc, Node *child)
2431 {
2432   Attr          *attr;
2433   chtml40_t     *chtml40;
2434   Doc           *doc;
2435   request_rec   *r;
2436   char          *align;
2437
2438   chtml40 = GET_CHTML40(pdoc);
2439   doc     = chtml40->doc;
2440   r       = doc->r;
2441   align   = NULL;
2442
2443   W_L("<div");
2444   for (attr = qs_get_attr(doc,child);
2445        attr;
2446        attr = qs_get_next_attr(doc,attr)) {
2447     char *nm  = qs_get_attr_name(doc,attr);
2448     char *val = qs_get_attr_value(doc,attr);
2449     if (STRCASEEQ('a','A',"align", nm)) {
2450       /*----------------------------------------------------------------------*/
2451       /* CHTML 1.0 (W3C version 3.2)                                          */
2452       /*----------------------------------------------------------------------*/
2453       if (val && (STRCASEEQ('l','L',"left",val) || STRCASEEQ('r','R',"right",val) || STRCASEEQ('c','C',"center",val))) {
2454         align = apr_pstrdup(doc->buf.pool, val);
2455       }
2456     }
2457   }
2458   if (align) {
2459     W_L(" align=\"");
2460     W_V(align);
2461     W_L("\"");
2462   }
2463   W_L(">");
2464   return chtml40->out;
2465 }
2466
2467
2468 /**
2469  * It is a handler who processes the DIV tag.
2470  *
2471  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2472  *                     destination is specified.
2473  * @param node   [i]   The DIV tag node is specified.
2474  * @return The conversion result is returned.
2475  */
2476 static char *
2477 s_chtml40_end_div_tag(void *pdoc, Node *UNUSED(node))
2478 {
2479   chtml40_t    *chtml40 = GET_CHTML40(pdoc);
2480   Doc          *doc     = chtml40->doc;
2481
2482   W_L("</div>");
2483
2484   return chtml40->out;
2485 }
2486
2487
2488 /**
2489  * It is a handler who processes the UL tag.
2490  *
2491  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2492  *                     destination is specified.
2493  * @param node   [i]   The UL tag node is specified.
2494  * @return The conversion result is returned.
2495  */
2496 static char *
2497 s_chtml40_start_ul_tag(void *pdoc, Node *node)
2498 {
2499   chtml40_t   *chtml40 = GET_CHTML40(pdoc);
2500   Doc         *doc     = chtml40->doc;
2501   Attr        *attr;
2502   char        *attr_type = NULL;
2503   char        *attr_style = NULL;
2504   /*--------------------------------------------------------------------------*/
2505   /* Get Attributes                                                           */
2506   /*--------------------------------------------------------------------------*/
2507   for (attr = qs_get_attr(doc,node);
2508        attr;
2509        attr = qs_get_next_attr(doc,attr)) {
2510     char *name   = qs_get_attr_name(doc,attr);
2511     char *value  = qs_get_attr_value(doc,attr);
2512     if (STRCASEEQ('t','T',"type",name)) {
2513       if (value && (STRCASEEQ('d','D',"disc",value) || STRCASEEQ('c','C',"circle",value) || STRCASEEQ('s','S',"square",value))) {
2514         attr_type = value;
2515       }
2516     }
2517     else if (value && *value && STRCASEEQ('s','S',"style", name)) {
2518       attr_style = value;
2519     }
2520   }
2521   if (IS_CSS_ON(chtml40->entryp)) {
2522     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
2523     if (style) {
2524       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type");
2525       css_property_t *cur;
2526       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
2527         if (STRCASEEQ('d','D',"disc",cur->value)) {
2528           attr_type = apr_pstrdup(doc->pool, "disc");
2529         }
2530         else if (STRCASEEQ('c','C',"circle",cur->value)) {
2531           attr_type = apr_pstrdup(doc->pool, "circle");
2532         }
2533         else if (STRCASEEQ('s','S',"square",cur->value)) {
2534           attr_type = apr_pstrdup(doc->pool, "square");
2535         }
2536       }
2537     }
2538   }
2539   W_L("<ul");
2540   if (attr_type) {
2541     W_L(" type=\"");
2542     W_V(attr_type);
2543     W_L("\"");
2544   }
2545   W_L(">");
2546
2547   return chtml40->out;
2548 }
2549
2550
2551 /**
2552  * It is a handler who processes the UL tag.
2553  *
2554  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2555  *                     destination is specified.
2556  * @param node   [i]   The UL tag node is specified.
2557  * @return The conversion result is returned.
2558  */
2559 static char *
2560 s_chtml40_end_ul_tag(void *pdoc, Node *UNUSED(child)) 
2561 {
2562   chtml40_t     *chtml40 = GET_CHTML40(pdoc);
2563   Doc           *doc     = chtml40->doc;
2564
2565   W_L("</ul>");
2566   if (IS_CSS_ON(chtml40->entryp)) {
2567     chxj_css_pop_prop_list(chtml40->css_prop_stack);
2568   }
2569
2570   return chtml40->out;
2571 }
2572
2573
2574 /**
2575  * It is a handler who processes the PRE tag.
2576  *
2577  * @param pdoc  [i/o] The pointer to the XHTML structure at the output
2578  *                     destination is specified.
2579  * @param node   [i]   The PRE tag node is specified.
2580  * @return The conversion result is returned.
2581  */
2582 static char *
2583 s_chtml40_start_pre_tag(void *pdoc, Node *node)
2584 {
2585   chtml40_t *chtml40 = GET_CHTML40(pdoc);
2586   Doc       *doc     = chtml40->doc;
2587   Attr      *attr;
2588   char      *attr_style = NULL;
2589
2590   for (attr = qs_get_attr(doc,node);
2591        attr;
2592        attr = qs_get_next_attr(doc,attr)) {
2593     char *nm  = qs_get_attr_name(doc,attr);
2594     char *val = qs_get_attr_value(doc,attr);
2595     if (val && STRCASEEQ('s','S',"style", nm)) {
2596       attr_style = val;
2597     }
2598   }
2599
2600   if (IS_CSS_ON(chtml40->entryp)) {
2601     s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
2602   }
2603
2604   chtml40->pre_flag++;
2605   W_L("<pre>");
2606
2607   return chtml40->out;
2608 }
2609
2610
2611 /**
2612  * It is a handler who processes the PRE tag.
2613  *
2614  * @param pdoc  [i/o] The pointer to the XHTML structure at the output
2615  *                     destination is specified.
2616  * @param node   [i]   The PRE tag node is specified.
2617  * @return The conversion result is returned.
2618  */
2619 static char *
2620 s_chtml40_end_pre_tag(void *pdoc, Node *UNUSED(child)) 
2621 {
2622   chtml40_t     *chtml40 = GET_CHTML40(pdoc);
2623   Doc           *doc     = chtml40->doc;
2624
2625   W_L("</pre>");
2626   chtml40->pre_flag--;
2627   if (IS_CSS_ON(chtml40->entryp)) {
2628     chxj_css_pop_prop_list(chtml40->css_prop_stack);
2629   }
2630
2631   return chtml40->out;
2632 }
2633
2634
2635 /**
2636  * It is a handler who processes the P tag.
2637  *
2638  * @param pdoc  [i/o] The pointer to the XHTML structure at the output
2639  *                     destination is specified.
2640  * @param node   [i]   The P tag node is specified.
2641  * @return The conversion result is returned.
2642  */
2643 static char *
2644 s_chtml40_start_p_tag(void *pdoc, Node *node) 
2645 {
2646   chtml40_t   *chtml40;
2647   Doc         *doc;
2648   request_rec *r;
2649   Attr        *attr;
2650   char        *attr_align = NULL;
2651   char        *attr_style = NULL;
2652   char        *attr_color = NULL;
2653   char        *attr_blink = NULL;
2654
2655   chtml40 = GET_CHTML40(pdoc);
2656   doc     = chtml40->doc;
2657   r       = doc->r;
2658
2659   for (attr = qs_get_attr(doc,node);
2660        attr;
2661        attr = qs_get_next_attr(doc,attr)) {
2662     char *nm  = qs_get_attr_name(doc,attr);
2663     char *val = qs_get_attr_value(doc,attr);
2664     if (STRCASEEQ('a','A',"align", nm)) {
2665       /*----------------------------------------------------------------------*/
2666       /* CHTML 1.0 (W3C version 3.2)                                          */
2667       /*----------------------------------------------------------------------*/
2668       if (val && (STRCASEEQ('l','L',"left",val) || STRCASEEQ('r','R',"right",val) || STRCASEEQ('c','C',"center",val))) {
2669         attr_align = apr_pstrdup(doc->buf.pool, val);
2670         break;
2671       }
2672     }
2673     else if (STRCASEEQ('s','S',"style", nm) && val && *val) {
2674       attr_style = apr_pstrdup(doc->buf.pool, val);
2675     }
2676   }
2677   if (IS_CSS_ON(chtml40->entryp)) {
2678     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
2679     if (style) {
2680       css_property_t *text_align_prop = chxj_css_get_property_value(doc, style, "text-align");
2681       css_property_t *color_prop      = chxj_css_get_property_value(doc, style, "color");
2682       css_property_t *text_deco_prop  = chxj_css_get_property_value(doc, style, "text-decoration");
2683       css_property_t *cur;
2684       for (cur = text_align_prop->next; cur != text_align_prop; cur = cur->next) {
2685         if (STRCASEEQ('l','L',"left",cur->value)) {
2686           attr_align = apr_pstrdup(doc->pool, "left");
2687         }
2688         else if (STRCASEEQ('c','C',"center",cur->value)) {
2689           attr_align = apr_pstrdup(doc->pool, "center");
2690         }
2691         else if (STRCASEEQ('r','R',"right",cur->value)) {
2692           attr_align = apr_pstrdup(doc->pool, "right");
2693         }
2694       }
2695       for (cur = color_prop->next; cur != color_prop; cur = cur->next) {
2696         if (cur->value && *cur->value) {
2697           attr_color = apr_pstrdup(doc->pool, cur->value);
2698         }
2699       }
2700       for (cur = text_deco_prop->next; cur != text_deco_prop; cur = cur->next) {
2701         if (cur->value && *cur->value && STRCASEEQ('b','B',"blink",cur->value)) {
2702           attr_blink = apr_pstrdup(doc->pool, cur->value);
2703         }
2704       }
2705     }
2706   }
2707   W_L("<p");
2708   if (attr_align) {
2709     W_L(" align=\"");
2710     W_V(attr_align);
2711     W_L("\"");
2712   }
2713   W_L(">");
2714
2715   chtml40_flags_t *flg = (chtml40_flags_t *)apr_palloc(doc->pool, sizeof(chtml40_flags_t));
2716   memset(flg, 0, sizeof(*flg));
2717   if (attr_color) {
2718     attr_color = chxj_css_rgb_func_to_value(doc->pool, attr_color);
2719     W_L("<font color=\"");
2720     W_V(attr_color);
2721     W_L("\">");
2722     flg->with_font_flag = 1;
2723   }
2724   if (attr_blink) {
2725     W_L("<blink>");
2726     flg->with_blink_flag = 1;
2727   }
2728   node->userData = (void *)flg;
2729
2730   return chtml40->out;
2731 }
2732
2733
2734 /**
2735  * It is a handler who processes the P tag.
2736  *
2737  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2738  *                     destination is specified.
2739  * @param node   [i]   The P tag node is specified.
2740  * @return The conversion result is returned.
2741  */
2742 static char *
2743 s_chtml40_end_p_tag(void *pdoc, Node *node)
2744 {
2745   chtml40_t   *chtml40;
2746   Doc         *doc;
2747
2748   chtml40 = GET_CHTML40(pdoc);
2749   doc     = chtml40->doc;
2750
2751   chtml40_flags_t *flg = (chtml40_flags_t *)node->userData;
2752   if (flg->with_font_flag) {
2753     W_L("</font>");
2754   }
2755   if (flg->with_blink_flag) {
2756     W_L("</blink>");
2757   }
2758   W_L("</p>");
2759   if (IS_CSS_ON(chtml40->entryp)) {
2760     chxj_css_pop_prop_list(chtml40->css_prop_stack);
2761   }
2762
2763   return chtml40->out;
2764 }
2765
2766
2767 /**
2768  * It is a handler who processes the OL tag.
2769  *
2770  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2771  *                     destination is specified.
2772  * @param node   [i]   The OL tag node is specified.
2773  * @return The conversion result is returned.
2774  */
2775 static char *
2776 s_chtml40_start_ol_tag(void *pdoc, Node *node)
2777 {
2778   chtml40_t   *chtml40;
2779   Doc         *doc;
2780   request_rec *r;
2781   Attr        *attr;
2782   char        *attr_style = NULL;
2783   char        *attr_start = NULL;
2784   char        *attr_type = NULL;
2785
2786   chtml40 = GET_CHTML40(pdoc);
2787   doc     = chtml40->doc;
2788   r       = doc->r;
2789
2790   /*--------------------------------------------------------------------------*/
2791   /* Get Attributes                                                           */
2792   /*--------------------------------------------------------------------------*/
2793   for (attr = qs_get_attr(doc,node);
2794        attr;
2795        attr = qs_get_next_attr(doc,attr)) {
2796     char *name = qs_get_attr_name(doc,attr);
2797     char *value = qs_get_attr_value(doc,attr);
2798     if (STRCASEEQ('t','T',"type",name) && value && (*value == '1' || *value == 'a' || *value == 'A')) {
2799       attr_type = value;
2800     }
2801     else if (STRCASEEQ('s','S',"start",name) && value && *value) {
2802       attr_start = value;
2803     }
2804     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
2805       attr_style = value;
2806     }
2807   }
2808   if (IS_CSS_ON(chtml40->entryp)) {
2809     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
2810     if (style) {
2811       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type");
2812       css_property_t *cur;
2813       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
2814         if (STRCASEEQ('d','D',"decimal", cur->value)) {
2815           attr_type = apr_pstrdup(doc->pool, "1");
2816         }
2817         else if (STRCASEEQ('u','U',"upper-alpha", cur->value)) {
2818           attr_type = apr_pstrdup(doc->pool, "A");
2819         }
2820         else if (STRCASEEQ('l','L',"lower-alpha", cur->value)) {
2821           attr_type = apr_pstrdup(doc->pool, "a");
2822         }
2823       }
2824     }
2825   }
2826   W_L("<ol");
2827   if (attr_type) {
2828     W_L(" type=\"");
2829     W_V(attr_type);
2830     W_L("\"");
2831   }
2832   if (attr_start) {
2833     W_L(" start=\"");
2834     W_V(attr_start);
2835     W_L("\"");
2836   }
2837   W_L(">");
2838
2839   return chtml40->out;
2840 }
2841
2842
2843 /**
2844  * It is a handler who processes the OL tag.
2845  *
2846  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2847  *                     destination is specified.
2848  * @param node   [i]   The OL tag node is specified.
2849  * @return The conversion result is returned.
2850  */
2851 static char *
2852 s_chtml40_end_ol_tag(void *pdoc, Node *UNUSED(node)) 
2853 {
2854   chtml40_t *chtml40 = GET_CHTML40(pdoc);
2855   Doc       *doc     = chtml40->doc;
2856
2857   W_L("</ol>");
2858   if (IS_CSS_ON(chtml40->entryp)) {
2859     chxj_css_pop_prop_list(chtml40->css_prop_stack);
2860   }
2861
2862   return chtml40->out;
2863 }
2864
2865
2866 /**
2867  * It is a handler who processes the LI tag.
2868  *
2869  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2870  *                     destination is specified.
2871  * @param node   [i]   The LI tag node is specified.
2872  * @return The conversion result is returned.
2873  */
2874 static char *
2875 s_chtml40_start_li_tag(void *pdoc, Node *node) 
2876 {
2877   chtml40_t   *chtml40 = GET_CHTML40(pdoc);
2878   Doc         *doc     = chtml40->doc;
2879   Attr        *attr;
2880   char        *attr_type = NULL;
2881   char        *attr_value = NULL;
2882   char        *attr_style = NULL;
2883
2884   /*--------------------------------------------------------------------------*/
2885   /* Get Attributes                                                           */
2886   /*--------------------------------------------------------------------------*/
2887   for (attr = qs_get_attr(doc,node);
2888        attr;
2889        attr = qs_get_next_attr(doc,attr)) {
2890     char *name  = qs_get_attr_name(doc,attr);
2891     char *value = qs_get_attr_value(doc,attr);
2892     if (STRCASEEQ('t','T',"type",name)) {
2893       if (value && (*value == '1' || *value == 'a' || *value == 'A' || STRCASEEQ('d','D',"disc",value) || STRCASEEQ('s','S',"square",value) || STRCASEEQ('c','C',"circle",value))) {
2894         attr_type = value;
2895       }
2896     }
2897     else if (STRCASEEQ('v','V',"value", name) && value && *value) {
2898       attr_value = value;
2899     }
2900     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
2901       attr_style = value;
2902     }
2903   }
2904   if (IS_CSS_ON(chtml40->entryp)) {
2905     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
2906     if (style) {
2907       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "list-style-type");
2908       css_property_t *cur;
2909       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
2910         if (STRCASEEQ('d','D',"decimal", cur->value)) {
2911           attr_type = apr_pstrdup(doc->pool, "1");
2912         }
2913         else if (STRCASEEQ('u','U',"upper-alpha", cur->value)) {
2914           attr_type = apr_pstrdup(doc->pool, "A");
2915         }
2916         else if (STRCASEEQ('l','L',"lower-alpha", cur->value)) {
2917           attr_type = apr_pstrdup(doc->pool, "a");
2918         }
2919         else if (STRCASEEQ('d','D',"disc", cur->value)) {
2920           attr_type = apr_pstrdup(doc->pool, "disc");
2921         }
2922         else if (STRCASEEQ('s','S',"square", cur->value)) {
2923           attr_type = apr_pstrdup(doc->pool, "square");
2924         }
2925         else if (STRCASEEQ('c','C',"circle", cur->value)) {
2926           attr_type = apr_pstrdup(doc->pool, "circle");
2927         }
2928       }
2929     }
2930   }
2931
2932   W_L("<li");
2933   if (attr_type) {
2934     W_L(" type=\"");
2935     W_V(attr_type);
2936     W_L("\"");
2937   }
2938   if (attr_value) {
2939     W_L(" value=\"");
2940     W_V(attr_value);
2941     W_L("\"");
2942   }
2943   W_L(">");
2944   return chtml40->out;
2945 }
2946
2947
2948 /**
2949  * It is a handler who processes the LI tag.
2950  *
2951  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2952  *                     destination is specified.
2953  * @param node   [i]   The LI tag node is specified.
2954  * @return The conversion result is returned.
2955  */
2956 static char *
2957 s_chtml40_end_li_tag(void *pdoc, Node *UNUSED(child)) 
2958 {
2959   chtml40_t *chtml40 = GET_CHTML40(pdoc);
2960
2961   if (IS_CSS_ON(chtml40->entryp)) {
2962     chxj_css_pop_prop_list(chtml40->css_prop_stack);
2963   }
2964   return chtml40->out;
2965 }
2966
2967
2968 /**
2969  * It is a handler who processes the H1 tag.
2970  *
2971  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
2972  *                     destination is specified.
2973  * @param node   [i]   The H1 tag node is specified.
2974  * @return The conversion result is returned.
2975  */
2976 static char *
2977 s_chtml40_start_h1_tag(void *pdoc, Node *node)
2978 {
2979   chtml40_t   *chtml40;
2980   Doc         *doc;
2981   request_rec *r;
2982   Attr        *attr;
2983   char        *attr_style = NULL;
2984   char        *attr_align = NULL;
2985
2986   chtml40 = GET_CHTML40(pdoc);
2987   doc     = chtml40->doc;
2988   r       = doc->r;
2989
2990   for (attr = qs_get_attr(doc,node);
2991        attr;
2992        attr = qs_get_next_attr(doc,attr)) {
2993     char *name  = qs_get_attr_name(doc,attr);
2994     char *value = qs_get_attr_value(doc,attr);
2995     if (STRCASEEQ('a','A',"align", name)) {
2996       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
2997         attr_align = value;
2998       }
2999     }
3000     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3001       attr_style = value;
3002     }
3003   }
3004   if (IS_CSS_ON(chtml40->entryp)) {
3005     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
3006     if (style) {
3007       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3008       css_property_t *cur;
3009       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3010         if (STRCASEEQ('l','L',"left", cur->value)) {
3011           attr_align = apr_pstrdup(doc->pool, "left");
3012         }
3013         else if (STRCASEEQ('c','C',"center",cur->value)) {
3014           attr_align = apr_pstrdup(doc->pool, "center");
3015         }
3016         else if (STRCASEEQ('r','R',"right",cur->value)) {
3017           attr_align = apr_pstrdup(doc->pool, "right");
3018         }
3019       }
3020     }
3021   }
3022   W_L("<h1");
3023   if (attr_align) {
3024     W_L(" align=\"");
3025     W_V(attr_align);
3026     W_L("\"");
3027   }
3028   W_L(">");
3029
3030   return chtml40->out;
3031 }
3032
3033
3034 /**
3035  * It is a handler who processes the H1 tag.
3036  *
3037  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3038  *                     destination is specified.
3039  * @param node   [i]   The H1 tag node is specified.
3040  * @return The conversion result is returned.
3041  */
3042 static char *
3043 s_chtml40_end_h1_tag(void *pdoc, Node *UNUSED(child)) 
3044 {
3045   chtml40_t   *chtml40;
3046   Doc         *doc;
3047
3048   chtml40 = GET_CHTML40(pdoc);
3049   doc     = chtml40->doc;
3050
3051   W_L("</h1>");
3052   if (IS_CSS_ON(chtml40->entryp)) {
3053     chxj_css_pop_prop_list(chtml40->css_prop_stack);
3054   }
3055
3056   return chtml40->out;
3057 }
3058
3059
3060 /**
3061  * It is a handler who processes the H2 tag.
3062  *
3063  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3064  *                     destination is specified.
3065  * @param node   [i]   The H2 tag node is specified.
3066  * @return The conversion result is returned.
3067  */
3068 static char *
3069 s_chtml40_start_h2_tag(void *pdoc, Node *node)
3070 {
3071   chtml40_t   *chtml40;
3072   Doc         *doc;
3073   request_rec *r;
3074   Attr        *attr;
3075   char        *attr_style = NULL;
3076   char        *attr_align = NULL;
3077
3078   chtml40 = GET_CHTML40(pdoc);
3079   doc     = chtml40->doc;
3080   r       = doc->r;
3081
3082   for (attr = qs_get_attr(doc,node);
3083        attr;
3084        attr = qs_get_next_attr(doc,attr)) {
3085     char *name  = qs_get_attr_name(doc,attr);
3086     char *value = qs_get_attr_value(doc,attr);
3087     if (STRCASEEQ('a','A',"align", name)) {
3088       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3089         attr_align = value;
3090       }
3091     }
3092     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3093       attr_style = value;
3094     }
3095   }
3096   if (IS_CSS_ON(chtml40->entryp)) {
3097     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
3098     if (style) {
3099       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3100       css_property_t *cur;
3101       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3102         if (STRCASEEQ('l','L',"left", cur->value)) {
3103           attr_align = apr_pstrdup(doc->pool, "left");
3104         }
3105         else if (STRCASEEQ('c','C',"center",cur->value)) {
3106           attr_align = apr_pstrdup(doc->pool, "center");
3107         }
3108         else if (STRCASEEQ('r','R',"right",cur->value)) {
3109           attr_align = apr_pstrdup(doc->pool, "right");
3110         }
3111       }
3112     }
3113   }
3114   W_L("<h2");
3115   if (attr_align) {
3116     W_L(" align=\"");
3117     W_V(attr_align);
3118     W_L("\"");
3119   }
3120   W_L(">");
3121
3122   return chtml40->out;
3123 }
3124
3125
3126 /**
3127  * It is a handler who processes the H2 tag.
3128  *
3129  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3130  *                     destination is specified.
3131  * @param node   [i]   The H2 tag node is specified.
3132  * @return The conversion result is returned.
3133  */
3134 static char *
3135 s_chtml40_end_h2_tag(void *pdoc, Node *UNUSED(child)) 
3136 {
3137   chtml40_t   *chtml40 = GET_CHTML40(pdoc);
3138   Doc         *doc     = chtml40->doc;
3139
3140   W_L("</h2>");
3141   if (IS_CSS_ON(chtml40->entryp)) {
3142     chxj_css_pop_prop_list(chtml40->css_prop_stack);
3143   }
3144
3145   return chtml40->out;
3146 }
3147
3148
3149 /**
3150  * It is a handler who processes the H3 tag.
3151  *
3152  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3153  *                     destination is specified.
3154  * @param node   [i]   The H3 tag node is specified.
3155  * @return The conversion result is returned.
3156  */
3157 static char *
3158 s_chtml40_start_h3_tag(void *pdoc, Node *node)
3159 {
3160   chtml40_t   *chtml40;
3161   Doc         *doc;
3162   request_rec *r;
3163   Attr        *attr;
3164   char        *attr_style = NULL;
3165   char        *attr_align = NULL;
3166
3167   chtml40 = GET_CHTML40(pdoc);
3168   doc     = chtml40->doc;
3169   r       = doc->r;
3170
3171   for (attr = qs_get_attr(doc,node);
3172        attr;
3173        attr = qs_get_next_attr(doc,attr)) {
3174     char *name  = qs_get_attr_name(doc,attr);
3175     char *value = qs_get_attr_value(doc,attr);
3176     if (STRCASEEQ('a','A',"align", name)) {
3177       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3178         attr_align = value;
3179       }
3180     }
3181     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3182       attr_style = value;
3183     }
3184   }
3185   if (IS_CSS_ON(chtml40->entryp)) {
3186     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
3187     if (style) {
3188       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3189       css_property_t *cur;
3190       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3191         if (STRCASEEQ('l','L',"left", cur->value)) {
3192           attr_align = apr_pstrdup(doc->pool, "left");
3193         }
3194         else if (STRCASEEQ('c','C',"center",cur->value)) {
3195           attr_align = apr_pstrdup(doc->pool, "center");
3196         }
3197         else if (STRCASEEQ('r','R',"right",cur->value)) {
3198           attr_align = apr_pstrdup(doc->pool, "right");
3199         }
3200       }
3201     }
3202   }
3203   W_L("<h3");
3204   if (attr_align) {
3205     W_L(" align=\"");
3206     W_V(attr_align);
3207     W_L("\"");
3208   }
3209   W_L(">");
3210
3211   return chtml40->out;
3212 }
3213
3214
3215 /**
3216  * It is a handler who processes the H3 tag.
3217  *
3218  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3219  *                     destination is specified.
3220  * @param node   [i]   The H3 tag node is specified.
3221  * @return The conversion result is returned.
3222  */
3223 static char *
3224 s_chtml40_end_h3_tag(void *pdoc, Node *UNUSED(child))
3225 {
3226   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3227   Doc       *doc   = chtml40->doc;
3228
3229   W_L("</h3>");
3230   if (IS_CSS_ON(chtml40->entryp)) {
3231     chxj_css_pop_prop_list(chtml40->css_prop_stack);
3232   }
3233
3234   return chtml40->out;
3235 }
3236
3237
3238 /**
3239  * It is a handler who processes the H4 tag.
3240  *
3241  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3242  *                     destination is specified.
3243  * @param node   [i]   The H4 tag node is specified.
3244  * @return The conversion result is returned.
3245  */
3246 static char *
3247 s_chtml40_start_h4_tag(void *pdoc, Node *node)
3248 {
3249   chtml40_t   *chtml40;
3250   Doc         *doc;
3251   request_rec *r;
3252   Attr        *attr;
3253   char        *attr_style = NULL;
3254   char        *attr_align = NULL;
3255
3256   chtml40 = GET_CHTML40(pdoc);
3257   doc     = chtml40->doc;
3258   r       = doc->r;
3259
3260   for (attr = qs_get_attr(doc,node);
3261        attr;
3262        attr = qs_get_next_attr(doc,attr)) {
3263     char *name  = qs_get_attr_name(doc,attr);
3264     char *value = qs_get_attr_value(doc,attr);
3265     if (STRCASEEQ('a','A',"align", name)) {
3266       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3267         attr_align = value;
3268       }
3269     }
3270     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3271       attr_style = value;
3272     }
3273   }
3274   if (IS_CSS_ON(chtml40->entryp)) {
3275     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
3276     if (style) {
3277       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3278       css_property_t *cur;
3279       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3280         if (STRCASEEQ('l','L',"left", cur->value)) {
3281           attr_align = apr_pstrdup(doc->pool, "left");
3282         }
3283         else if (STRCASEEQ('c','C',"center",cur->value)) {
3284           attr_align = apr_pstrdup(doc->pool, "center");
3285         }
3286         else if (STRCASEEQ('r','R',"right",cur->value)) {
3287           attr_align = apr_pstrdup(doc->pool, "right");
3288         }
3289       }
3290     }
3291   }
3292   W_L("<h4");
3293   if (attr_align) {
3294     W_L(" align=\"");
3295     W_V(attr_align);
3296     W_L("\"");
3297   }
3298   W_L(">");
3299
3300   return chtml40->out;
3301 }
3302
3303
3304 /**
3305  * It is a handler who processes the H4 tag.
3306  *
3307  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3308  *                     destination is specified.
3309  * @param node   [i]   The H4 tag node is specified.
3310  * @return The conversion result is returned.
3311  */
3312 static char *
3313 s_chtml40_end_h4_tag(void *pdoc, Node *UNUSED(child)) 
3314 {
3315   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3316   Doc       *doc     = chtml40->doc;
3317
3318   W_L("</h4>");
3319   if (IS_CSS_ON(chtml40->entryp)) {
3320     chxj_css_pop_prop_list(chtml40->css_prop_stack);
3321   }
3322
3323   return chtml40->out;
3324 }
3325
3326
3327 /**
3328  * It is a handler who processes the H5 tag.
3329  *
3330  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3331  *                     destination is specified.
3332  * @param node   [i]   The H5 tag node is specified.
3333  * @return The conversion result is returned.
3334  */
3335 static char *
3336 s_chtml40_start_h5_tag(void *pdoc, Node *node)
3337 {
3338   chtml40_t   *chtml40;
3339   Doc         *doc;
3340   request_rec *r;
3341   Attr        *attr;
3342   char        *attr_style = NULL;
3343   char        *attr_align = NULL;
3344
3345   chtml40 = GET_CHTML40(pdoc);
3346   doc     = chtml40->doc;
3347   r       = doc->r;
3348
3349   for (attr = qs_get_attr(doc,node);
3350        attr;
3351        attr = qs_get_next_attr(doc,attr)) {
3352     char *name  = qs_get_attr_name(doc,attr);
3353     char *value = qs_get_attr_value(doc,attr);
3354     if (STRCASEEQ('a','A',"align", name)) {
3355       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3356         attr_align = value;
3357       }
3358     }
3359     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3360       attr_style = value;
3361     }
3362   }
3363   if (IS_CSS_ON(chtml40->entryp)) {
3364     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
3365     if (style) {
3366       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3367       css_property_t *cur;
3368       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3369         if (STRCASEEQ('l','L',"left", cur->value)) {
3370           attr_align = apr_pstrdup(doc->pool, "left");
3371         }
3372         else if (STRCASEEQ('c','C',"center",cur->value)) {
3373           attr_align = apr_pstrdup(doc->pool, "center");
3374         }
3375         else if (STRCASEEQ('r','R',"right",cur->value)) {
3376           attr_align = apr_pstrdup(doc->pool, "right");
3377         }
3378       }
3379     }
3380   }
3381   W_L("<h5");
3382   if (attr_align) {
3383     W_L(" align=\"");
3384     W_V(attr_align);
3385     W_L("\"");
3386   }
3387   W_L(">");
3388
3389   return chtml40->out;
3390 }
3391
3392
3393 /**
3394  * It is a handler who processes the H5 tag.
3395  *
3396  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3397  *                     destination is specified.
3398  * @param node   [i]   The H5 tag node is specified.
3399  * @return The conversion result is returned.
3400  */
3401 static char *
3402 s_chtml40_end_h5_tag(void *pdoc, Node *UNUSED(child)) 
3403 {
3404   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3405   Doc       *doc     = chtml40->doc;
3406
3407   W_L("</h5>");
3408   if (IS_CSS_ON(chtml40->entryp)) {
3409     chxj_css_pop_prop_list(chtml40->css_prop_stack);
3410   }
3411
3412   return chtml40->out;
3413 }
3414
3415
3416 /**
3417  * It is a handler who processes the H6 tag.
3418  *
3419  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3420  *                     destination is specified.
3421  * @param node   [i]   The H6 tag node is specified.
3422  * @return The conversion result is returned.
3423  */
3424 static char *
3425 s_chtml40_start_h6_tag(void *pdoc, Node *node)
3426 {
3427   chtml40_t   *chtml40;
3428   Doc         *doc;
3429   request_rec *r;
3430   Attr        *attr;
3431   char        *attr_style = NULL;
3432   char        *attr_align = NULL;
3433
3434   chtml40 = GET_CHTML40(pdoc);
3435   doc     = chtml40->doc;
3436   r       = doc->r;
3437
3438   for (attr = qs_get_attr(doc,node);
3439        attr;
3440        attr = qs_get_next_attr(doc,attr)) {
3441     char *name  = qs_get_attr_name(doc,attr);
3442     char *value = qs_get_attr_value(doc,attr);
3443     if (STRCASEEQ('a','A',"align", name)) {
3444       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value) || STRCASEEQ('c','C',"center",value))) {
3445         attr_align = value;
3446       }
3447     }
3448     else if (STRCASEEQ('s','S',"style",name) && value && *value) {
3449       attr_style = value;
3450     }
3451   }
3452   if (IS_CSS_ON(chtml40->entryp)) {
3453     css_prop_list_t *style = s_chtml40_push_and_get_now_style(pdoc, node, attr_style);
3454     if (style) {
3455       css_property_t *list_style_type_prop = chxj_css_get_property_value(doc, style, "text-align");
3456       css_property_t *cur;
3457       for (cur = list_style_type_prop->next; cur != list_style_type_prop; cur = cur->next) {
3458         if (STRCASEEQ('l','L',"left", cur->value)) {
3459           attr_align = apr_pstrdup(doc->pool, "left");
3460         }
3461         else if (STRCASEEQ('c','C',"center",cur->value)) {
3462           attr_align = apr_pstrdup(doc->pool, "center");
3463         }
3464         else if (STRCASEEQ('r','R',"right",cur->value)) {
3465           attr_align = apr_pstrdup(doc->pool, "right");
3466         }
3467       }
3468     }
3469   }
3470   W_L("<h6");
3471   if (attr_align) {
3472     W_L(" align=\"");
3473     W_V(attr_align);
3474     W_L("\"");
3475   }
3476   W_L(">");
3477
3478   return chtml40->out;
3479 }
3480
3481
3482 /**
3483  * It is a handler who processes the H6 tag.
3484  *
3485  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3486  *                     destination is specified.
3487  * @param node   [i]   The H6 tag node is specified.
3488  * @return The conversion result is returned.
3489  */
3490 static char *
3491 s_chtml40_end_h6_tag(void *pdoc, Node *UNUSED(child)) 
3492 {
3493   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3494   Doc       *doc     = chtml40->doc;
3495
3496   W_L("</h6>");
3497   if (IS_CSS_ON(chtml40->entryp)) {
3498     chxj_css_pop_prop_list(chtml40->css_prop_stack);
3499   }
3500
3501   return chtml40->out;
3502 }
3503
3504
3505 /**
3506  * It is a handler who processes the TEXTARE tag.
3507  *
3508  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3509  *                     destination is specified.
3510  * @param node   [i]   The TEXTAREA tag node is specified.
3511  * @return The conversion result is returned.
3512  */
3513 static char *
3514 s_chtml40_start_textarea_tag(void *pdoc, Node *node) 
3515 {
3516   chtml40_t     *chtml40;
3517   Doc           *doc;
3518   request_rec   *r;
3519   Attr          *attr;
3520   char          *attr_accesskey = NULL;
3521   char          *attr_name      = NULL;
3522   char          *attr_rows      = NULL;
3523   char          *attr_cols      = NULL;
3524   char          *attr_istyle    = NULL;
3525   char          *attr_style     = NULL;
3526
3527   chtml40 = GET_CHTML40(pdoc);
3528   doc     = chtml40->doc;
3529   r       = doc->r;
3530
3531   chtml40->textarea_flag++;
3532
3533   for (attr = qs_get_attr(doc,node);
3534        attr;
3535        attr = qs_get_next_attr(doc,attr)) {
3536     char *name  = qs_get_attr_name(doc,attr);
3537     char *value = qs_get_attr_value(doc,attr);
3538     if (STRCASEEQ('a','A',"accesskey",name) && value && *value != 0) {
3539       attr_accesskey = value;
3540     }
3541     else if (STRCASEEQ('i','I',"istyle", name) && value && (*value == '1' || *value == '2' || *value == '3' || *value == '4')) {
3542       attr_istyle = value;
3543     }
3544     else if (STRCASEEQ('n','N',"name", name) && value && *value) {
3545       attr_name = value;
3546     }
3547     else if (STRCASEEQ('r','R',"rows", name) && value && *value) {
3548       attr_rows = value;
3549     }
3550     else if (STRCASEEQ('c','C',"cols", name) && value && *value) {
3551       attr_cols = value;
3552     }
3553     else if (STRCASEEQ('s','S',"style", name) && value && *value) {
3554       attr_style = value;
3555     }
3556   }
3557   if (IS_CSS_ON(chtml40->entryp)) {
3558     css_prop_list_t *style = s_chtml40_nopush_and_get_now_style(pdoc, node, attr_style);
3559     if (style) {
3560       css_property_t *wap_input_format = chxj_css_get_property_value(doc, style, "-wap-input-format");
3561       css_property_t *cur;
3562       for (cur = wap_input_format->next; cur != wap_input_format; cur = cur->next) {
3563         if (strcasestr(cur->value, "<ja:n>")) {
3564           attr_istyle = "4";
3565         }
3566         else if (strcasestr(cur->value, "<ja:en>")) {
3567           attr_istyle = "3";
3568         }
3569         else if (strcasestr(cur->value, "<ja:hk>")) {
3570           attr_istyle = "2";
3571         }
3572         else if (strcasestr(cur->value, "<ja:h>")) {
3573           attr_istyle = "1";
3574         }
3575       }
3576     }
3577   }
3578   W_L("<textarea");
3579   if (attr_accesskey) {
3580     W_L(" accesskey=\"");
3581     W_V(attr_accesskey);
3582     W_L("\"");
3583   }
3584   if (attr_name) {
3585     W_L(" name=\"");
3586     W_V(attr_name);
3587     W_L("\"");
3588   }
3589   if (attr_rows) {
3590     W_L(" rows=\"");
3591     W_V(attr_rows);
3592     W_L("\"");
3593   }
3594   if (attr_cols) {
3595     W_L(" cols=\"");
3596     W_V(attr_cols);
3597     W_L("\"");
3598   }
3599   if (attr_istyle) {
3600     W_L(" istyle=\"");
3601     W_V(attr_istyle);
3602     W_L("\"");
3603   }
3604   W_L(">");
3605   return chtml40->out;
3606 }
3607
3608
3609 /**
3610  * It is a handler who processes the TEXTAREA tag.
3611  *
3612  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3613  *                     destination is specified.
3614  * @param node   [i]   The TEXTAREA tag node is specified.
3615  * @return The conversion result is returned.
3616  */
3617 static char *
3618 s_chtml40_end_textarea_tag(void *pdoc, Node *UNUSED(child)) 
3619 {
3620   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3621   Doc       *doc     = chtml40->doc;
3622
3623   W_L("</textarea>");
3624   chtml40->textarea_flag--;
3625
3626   return chtml40->out;
3627 }
3628
3629
3630 static char *
3631 s_chtml40_chxjif_tag(void *pdoc, Node *node)
3632 {
3633   Node        *child;
3634   chtml40_t   *chtml40;
3635   Doc         *doc;
3636   request_rec *r;
3637
3638   chtml40 = GET_CHTML40(pdoc);
3639   doc     = chtml40->doc;
3640   r       = doc->r;
3641
3642   for (child = qs_get_child_node(doc, node);
3643        child;
3644        child = qs_get_next_node(doc, child)) {
3645     W_V(child->otext);
3646     s_chtml40_chxjif_tag(chtml40, child);
3647   }
3648
3649   return NULL;
3650 }
3651
3652
3653 static char *
3654 s_chtml40_text_tag(void *pdoc, Node *child)
3655 {
3656   chtml40_t   *chtml40;
3657   Doc         *doc;
3658   request_rec *r;
3659
3660   char        *textval;
3661   char        *tmp;
3662   char        *tdst;
3663   char        one_byte[2];
3664   int         ii;
3665   int         tdst_len;
3666
3667   chtml40 = GET_CHTML40(pdoc);
3668   doc     = chtml40->doc;
3669   r       = doc->r;
3670   
3671   textval = qs_get_node_value(doc,child);
3672   if (strlen(textval) == 0) {
3673     return chtml40->out;
3674   }
3675   
3676   tmp = apr_palloc(r->pool, qs_get_node_size(doc,child)+1);
3677   memset(tmp, 0, qs_get_node_size(doc,child)+1);
3678   
3679   tdst     = qs_alloc_zero_byte_string(doc->buf.pool);
3680   memset(one_byte, 0, sizeof(one_byte));
3681   tdst_len = 0;
3682   
3683   for (ii=0; ii<qs_get_node_size(doc,child); ii++) {
3684     char* out;
3685     int rtn = s_chtml40_search_emoji(chtml40, &textval[ii], &out);
3686     if (rtn) {
3687       tdst = qs_out_apr_pstrcat(r, tdst, out, &tdst_len);
3688       ii+=(rtn - 1);
3689       continue;
3690     }
3691   
3692     if (is_sjis_kanji(textval[ii])) {
3693       one_byte[0] = textval[ii+0];
3694       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
3695       one_byte[0] = textval[ii+1];
3696       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
3697       ii++;
3698     }
3699     else if (chtml40->pre_flag) {
3700       one_byte[0] = textval[ii+0];
3701       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
3702     }
3703     else if (chtml40->textarea_flag) {
3704       one_byte[0] = textval[ii+0];
3705       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
3706     }
3707     else if (textval[ii] != '\r' && textval[ii] != '\n') {
3708       one_byte[0] = textval[ii+0];
3709       tdst = qs_out_apr_pstrcat(r, tdst, one_byte, &tdst_len);
3710     }
3711   }
3712   W_V(tdst);
3713   return chtml40->out;
3714 }
3715
3716
3717 /**
3718  * It is a handler who processes the BLOCKQUOTE tag.
3719  *
3720  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3721  *                     destination is specified.
3722  * @param node   [i]   The BLOCKQUOTE tag node is specified.
3723  * @return The conversion result is returned.
3724  */
3725 static char *
3726 s_chtml40_start_blockquote_tag(void *pdoc, Node *UNUSED(child))
3727 {
3728   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3729   Doc       *doc     = chtml40->doc;
3730   W_L("<blockquote>");
3731   return chtml40->out;
3732 }
3733
3734
3735 /**
3736  * It is a handler who processes the BLOCKQUOTE tag.
3737  *
3738  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3739  *                     destination is specified.
3740  * @param node   [i]   The BLOCKQUOTE tag node is specified.
3741  * @return The conversion result is returned.
3742  */
3743 static char *
3744 s_chtml40_end_blockquote_tag(void *pdoc, Node *UNUSED(child))
3745 {
3746   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3747   Doc       *doc     = chtml40->doc;
3748   W_L("</blockquote>");
3749   return chtml40->out;
3750 }
3751
3752
3753 /**
3754  * It is a handler who processes the DIR tag.
3755  *
3756  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3757  *                     destination is specified.
3758  * @param node   [i]   The DIR tag node is specified.
3759  * @return The conversion result is returned.
3760  */
3761 static char *
3762 s_chtml40_start_dir_tag(void *pdoc, Node *node)
3763 {
3764   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3765   Doc       *doc     = chtml40->doc;
3766   Attr      *attr;
3767   W_L("<dir");
3768   for (attr = qs_get_attr(doc,node);
3769        attr;
3770        attr = qs_get_next_attr(doc,attr)) {
3771     char *name   = qs_get_attr_name(doc,attr);
3772     char *value  = qs_get_attr_value(doc,attr);
3773     if (STRCASEEQ('t','T',"type",name)) {
3774       if (value && (STRCASEEQ('d','D',"disc",value) || STRCASEEQ('c','C',"circle",value) || STRCASEEQ('s','S',"square",value))) {
3775         W_L(" type=\"");
3776         W_V(value);
3777         W_L("\"");
3778       }
3779     }
3780   }
3781   W_L(">");
3782   return chtml40->out;
3783 }
3784
3785
3786 /**
3787  * It is a handler who processes the DIR tag.
3788  *
3789  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3790  *                     destination is specified.
3791  * @param node   [i]   The DIR tag node is specified.
3792  * @return The conversion result is returned.
3793  */
3794 static char *
3795 s_chtml40_end_dir_tag(void *pdoc, Node *UNUSED(child))
3796 {
3797   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3798   Doc       *doc = chtml40->doc;
3799   W_L("</dir>");
3800   return chtml40->out;
3801 }
3802
3803
3804 /**
3805  * It is a handler who processes the DL tag.
3806  *
3807  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3808  *                     destination is specified.
3809  * @param node   [i]   The DL tag node is specified.
3810  * @return The conversion result is returned.
3811  */
3812 static char *
3813 s_chtml40_start_dl_tag(void *pdoc, Node *UNUSED(child))
3814 {
3815   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3816   Doc       *doc     = chtml40->doc;
3817   W_L("<dl>");
3818   return chtml40->out;
3819 }
3820
3821
3822 /**
3823  * It is a handler who processes the DL tag.
3824  *
3825  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3826  *                     destination is specified.
3827  * @param node   [i]   The DL tag node is specified.
3828  * @return The conversion result is returned.
3829  */
3830 static char *
3831 s_chtml40_end_dl_tag(void *pdoc, Node *UNUSED(child))
3832 {
3833   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3834   Doc       *doc     = chtml40->doc;
3835   W_L("</dl>");
3836   return chtml40->out;
3837 }
3838
3839
3840 /**
3841  * It is a handler who processes the DT tag.
3842  *
3843  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3844  *                     destination is specified.
3845  * @param node   [i]   The DT tag node is specified.
3846  * @return The conversion result is returned.
3847  */
3848 static char *
3849 s_chtml40_start_dt_tag(void *pdoc, Node *UNUSED(child))
3850 {
3851   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3852   Doc       *doc     = chtml40->doc;
3853   W_L("<dt>");
3854   return chtml40->out;
3855 }
3856
3857
3858 /**
3859  * It is a handler who processes the DT tag.
3860  *
3861  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3862  *                     destination is specified.
3863  * @param node   [i]   The DT tag node is specified.
3864  * @return The conversion result is returned.
3865  */
3866 static char *
3867 s_chtml40_end_dt_tag(void *pdoc, Node *UNUSED(child))
3868 {
3869   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3870
3871   return chtml40->out;
3872 }
3873
3874
3875 /**
3876  * It is a handler who processes the DD tag.
3877  *
3878  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3879  *                     destination is specified.
3880  * @param node   [i]   The DD tag node is specified.
3881  * @return The conversion result is returned.
3882  */
3883 static char *
3884 s_chtml40_start_dd_tag(void *pdoc, Node *UNUSED(child))
3885 {
3886   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3887   Doc       *doc     = chtml40->doc;
3888
3889   W_L("<dd>");
3890
3891   return chtml40->out;
3892 }
3893
3894
3895 /**
3896  * It is a handler who processes the DD tag.
3897  *
3898  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3899  *                     destination is specified.
3900  * @param node   [i]   The DD tag node is specified.
3901  * @return The conversion result is returned.
3902  */
3903 static char *
3904 s_chtml40_end_dd_tag(void *pdoc, Node *UNUSED(child))
3905 {
3906   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3907
3908   return chtml40->out;
3909 }
3910
3911
3912 /**
3913  * It is a handler who processes the MARQUEE tag.
3914  *
3915  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3916  *                     destination is specified.
3917  * @param node   [i]   The MARQUEE tag node is specified.
3918  * @return The conversion result is returned.
3919  */
3920 static char *
3921 s_chtml40_start_marquee_tag(void *pdoc, Node *node)
3922 {
3923   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3924   Doc       *doc = chtml40->doc;
3925   Attr      *attr;
3926   W_L("<marquee");
3927   /*--------------------------------------------------------------------------*/
3928   /* Get Attributes                                                           */
3929   /*--------------------------------------------------------------------------*/
3930   for (attr = qs_get_attr(doc,node);
3931        attr;
3932        attr = qs_get_next_attr(doc,attr)) {
3933     char *name   = qs_get_attr_name(doc,attr);
3934     char *value  = qs_get_attr_value(doc,attr);
3935     if (STRCASEEQ('d','D',"direction", name)) {
3936       if (value && (STRCASEEQ('l','L',"left",value) || STRCASEEQ('r','R',"right",value))) {
3937         W_L(" direction=\"");
3938         W_V(value);
3939         W_L("\"");
3940       }
3941     }
3942     else if (STRCASEEQ('b','B',"behavior",name)) {
3943       if (value && (STRCASEEQ('s','S',"scroll",value) || STRCASEEQ('s','S',"slide",value) || STRCASEEQ('a','A',"alternate",value))) {
3944         W_L(" behavior=\""); 
3945         W_V(value);
3946         W_L("\"");
3947       }
3948     }
3949     else if (STRCASEEQ('l','L',"loop",name)) {
3950       if (value && *value) {
3951         W_L(" loop=\"");
3952         W_V(value);
3953         W_L("\"");
3954       }
3955     }
3956   }
3957   W_L(">");
3958   return chtml40->out;
3959 }
3960
3961
3962 /**
3963  * It is a handler who processes the MARQUEE tag.
3964  *
3965  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3966  *                     destination is specified.
3967  * @param node   [i]   The MARQUEE tag node is specified.
3968  * @return The conversion result is returned.
3969  */
3970 static char *
3971 s_chtml40_end_marquee_tag(void *pdoc, Node *UNUSED(child))
3972 {
3973   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3974   Doc       *doc = chtml40->doc;
3975   W_L("</marquee>");
3976   return chtml40->out;
3977 }
3978
3979
3980 /**
3981  * It is a handler who processes the BLINK tag.
3982  *
3983  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
3984  *                     destination is specified.
3985  * @param node   [i]   The BLINK tag node is specified.
3986  * @return The conversion result is returned.
3987  */
3988 static char *
3989 s_chtml40_start_blink_tag(void *pdoc, Node *UNUSED(child))
3990 {
3991   chtml40_t *chtml40 = GET_CHTML40(pdoc);
3992   Doc       *doc = chtml40->doc;
3993   W_L("<blink>");
3994   return chtml40->out;
3995 }
3996
3997
3998 /**
3999  * It is a handler who processes the BLINK tag.
4000  *
4001  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4002  *                     destination is specified.
4003  * @param node   [i]   The BLINK tag node is specified.
4004  * @return The conversion result is returned.
4005  */
4006 static char *
4007 s_chtml40_end_blink_tag(void *pdoc, Node *UNUSED(child))
4008 {
4009   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4010   Doc       *doc = chtml40->doc;
4011   W_L("</blink>");
4012   return chtml40->out;
4013 }
4014
4015
4016 /**
4017  * It is a handler who processes the MENU tag.
4018  *
4019  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4020  *                     destination is specified.
4021  * @param node   [i]   The MENU tag node is specified.
4022  * @return The conversion result is returned.
4023  */
4024 static char *
4025 s_chtml40_start_menu_tag(void *pdoc, Node *node)
4026 {
4027   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4028   Doc       *doc     = chtml40->doc;
4029   Attr      *attr;
4030   W_L("<menu");
4031   /*--------------------------------------------------------------------------*/
4032   /* Get Attributes                                                           */
4033   /*--------------------------------------------------------------------------*/
4034   for (attr = qs_get_attr(doc,node);
4035        attr;
4036        attr = qs_get_next_attr(doc,attr)) {
4037     char *name   = qs_get_attr_name(doc,attr);
4038     char *value  = qs_get_attr_value(doc,attr);
4039     if (STRCASEEQ('t','T',"type",name)) {
4040       if (value && (STRCASEEQ('d','D',"disc",value) || STRCASEEQ('c','C',"circle",value) || STRCASEEQ('s','S',"square",value))) {
4041         W_L(" type=\"");
4042         W_V(value);
4043         W_L("\"");
4044       }
4045     }
4046   }
4047   W_L(">");
4048   return chtml40->out;
4049 }
4050
4051
4052 /**
4053  * It is a handler who processes the MENU tag.
4054  *
4055  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4056  *                     destination is specified.
4057  * @param node   [i]   The MENU tag node is specified.
4058  * @return The conversion result is returned.
4059  */
4060 static char *
4061 s_chtml40_end_menu_tag(void *pdoc, Node *UNUSED(child))
4062 {
4063   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4064   Doc       *doc = chtml40->doc;
4065   W_L("</menu>");
4066   return chtml40->out;
4067 }
4068
4069
4070 /**
4071  * It is a handler who processes the PLAINTEXT tag.
4072  *
4073  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4074  *                     destination is specified.
4075  * @param node   [i]   The PLAINTEXT tag node is specified.
4076  * @return The conversion result is returned.
4077  */
4078 static char *
4079 s_chtml40_start_plaintext_tag(void *pdoc, Node *node)
4080 {
4081   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4082   Doc       *doc     = chtml40->doc;
4083   W_L("<plaintext>");
4084   s_chtml40_start_plaintext_tag_inner(pdoc,node);
4085   return chtml40->out;
4086 }
4087
4088 static char *
4089 s_chtml40_start_plaintext_tag_inner(void *pdoc, Node *node)
4090 {
4091   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4092   Doc       *doc     = chtml40->doc;
4093   Node      *child;
4094   for (child = qs_get_child_node(doc, node);
4095        child;
4096        child = qs_get_next_node(doc, child)) {
4097     W_V(child->otext);
4098     s_chtml40_start_plaintext_tag_inner(pdoc, child);
4099   }
4100   return chtml40->out;
4101 }
4102
4103
4104 /**
4105  * It is a handler who processes the PLAINTEXT tag.
4106  *
4107  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4108  *                     destination is specified.
4109  * @param node   [i]   The PLAINTEXT tag node is specified.
4110  * @return The conversion result is returned.
4111  */
4112 static char *
4113 s_chtml40_end_plaintext_tag(void *pdoc, Node *UNUSED(child))
4114 {
4115   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4116   return chtml40->out;
4117 }
4118
4119
4120 /**
4121  * It is handler who processes the New Line Code.
4122  */
4123 static char *
4124 s_chtml40_newline_mark(void *pdoc, Node *UNUSED(node))
4125 {
4126   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4127   Doc *doc = chtml40->doc;
4128   W_NLCODE();
4129   return chtml40->out;
4130 }
4131
4132
4133 /**
4134  * It is a handler who processes the LINK tag.
4135  *
4136  * @param pdoc  [i/o] The pointer to the CHTML structure at the output
4137  *                     destination is specified.
4138  * @param node   [i]   The LINK tag node is specified.
4139  * @return The conversion result is returned.
4140  */
4141 static char *
4142 s_chtml40_link_tag(void *pdoc, Node *node)
4143 {
4144   chtml40_t     *chtml40;
4145   Doc           *doc;
4146   Attr          *attr;
4147   char          *rel  = NULL;
4148   char          *href = NULL;
4149   char          *type = NULL;
4150
4151   chtml40 = GET_CHTML40(pdoc);
4152   doc     = chtml40->doc;
4153
4154   if (! IS_CSS_ON(chtml40->entryp)) {
4155     return chtml40->out;
4156   }
4157
4158   for (attr = qs_get_attr(doc,node);
4159        attr;
4160        attr = qs_get_next_attr(doc,attr)) {
4161     char *name  = qs_get_attr_name(doc,attr);
4162     char *value = qs_get_attr_value(doc,attr);
4163     if (STRCASEEQ('r','R',"rel", name)) {
4164       if (value && *value && STRCASEEQ('s','S',"stylesheet", value)) {
4165         rel = value;
4166       }
4167     }
4168     else if (STRCASEEQ('h','H',"href", name)) {
4169       if (value && *value) {
4170         href = value;
4171       }
4172     }
4173     else if (STRCASEEQ('t','T',"type", name)) {
4174       if (value && *value && STRCASEEQ('t','T',"text/css",value)) {
4175         type = value;
4176       }
4177     }
4178   }
4179
4180   if (rel && href && type) {
4181     DBG(doc->r, "start load CSS. url:[%s]", href);
4182     chtml40->style = chxj_css_parse_from_uri(doc->r, doc->pool, chtml40->style, href);
4183     DBG(doc->r, "end load CSS. url:[%s]", href);
4184   }
4185
4186   return chtml40->out;
4187 }
4188
4189 static css_prop_list_t *
4190 s_chtml40_push_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value)
4191 {
4192   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4193   Doc *doc = chtml40->doc;
4194   css_prop_list_t *last_css = NULL;
4195   if (IS_CSS_ON(chtml40->entryp)) {
4196     css_prop_list_t *dup_css;
4197     css_selector_t  *selector;
4198
4199     last_css = chxj_css_get_last_prop_list(chtml40->css_prop_stack);
4200     dup_css  = chxj_dup_css_prop_list(doc, last_css);
4201     selector = chxj_css_find_selector(doc, chtml40->style, node);
4202     if (selector) {
4203       chxj_css_prop_list_merge_property(doc, dup_css, selector);
4204     }
4205     chxj_css_push_prop_list(chtml40->css_prop_stack, dup_css);
4206     last_css = chxj_css_get_last_prop_list(chtml40->css_prop_stack);
4207
4208     if (style_attr_value) {
4209       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));
4210       if (ssheet) {
4211         chxj_css_prop_list_merge_property(doc, last_css, ssheet->selector_head.next);
4212       }
4213     }
4214   }
4215   return last_css;
4216 }
4217
4218
4219 static css_prop_list_t *
4220 s_chtml40_nopush_and_get_now_style(void *pdoc, Node *node, const char *style_attr_value)
4221 {
4222   chtml40_t *chtml40 = GET_CHTML40(pdoc);
4223   Doc *doc = chtml40->doc;
4224   css_prop_list_t *last_css = NULL;
4225   if (IS_CSS_ON(chtml40->entryp)) {
4226     css_prop_list_t *dup_css;
4227     css_selector_t  *selector;
4228
4229     last_css = chxj_css_get_last_prop_list(chtml40->css_prop_stack);
4230     dup_css  = chxj_dup_css_prop_list(doc, last_css);
4231     selector = chxj_css_find_selector(doc, chtml40->style, node);
4232     if (selector) {
4233       chxj_css_prop_list_merge_property(doc, dup_css, selector);
4234     }
4235     last_css = dup_css;
4236
4237     if (style_attr_value) {
4238       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));
4239       if (ssheet) {
4240         chxj_css_prop_list_merge_property(doc, last_css, ssheet->selector_head.next);
4241       }
4242     }
4243   }
4244   return last_css;
4245 }
4246 /*
4247  * vim:ts=2 et
4248  */