OSDN Git Service

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