]> git.donarmstrong.com Git - samtools.git/blob - bam_tview_html.c
works
[samtools.git] / bam_tview_html.c
1 #include <unistd.h>
2 #include "bam_tview.h"
3
4 #define UNDERLINE_FLAG 10
5
6 typedef struct HtmlTview {
7         tview_t view;
8         int row_count;
9         tixel_t** screen;
10         FILE* out;
11         int attributes;/* color... */
12         } html_tview_t;
13
14 #define FROM_TV(ptr) ((html_tview_t*)ptr)
15
16 static void html_destroy(tview_t* base)
17         {
18         int i;
19         html_tview_t* tv=(html_tview_t*)base;
20         if(tv->screen!=NULL)
21                 {
22                 for(i=0;i< tv->row_count;++i) free(tv->screen[i]);
23                 free(tv->screen);
24                 }
25         base_tv_destroy(base);
26         free(tv);
27         }
28
29 /*
30  void (*my_mvprintw)(struct AbstractTview* ,int,int,const char*,...);
31     void (*my_)(struct AbstractTview*,int,int,int);
32     void (*my_attron)(struct AbstractTview*,int);
33     void (*my_attroff)(struct AbstractTview*,int);
34     void (*my_clear)(struct AbstractTview*);
35     int (*my_colorpair)(struct AbstractTview*,int);
36 */
37
38 static void html_mvprintw(struct AbstractTview* tv,int y ,int x,const char* fmt,...)
39         {
40         int i,nchars=0;
41         unsigned int size=tv->mcol+2;
42         char* str=malloc(size);
43         if(str==0) exit(EXIT_FAILURE);
44         va_list argptr;
45         va_start(argptr, fmt);
46         nchars=vsnprintf(str,size, fmt, argptr);
47         va_end(argptr);
48         
49         for(i=0;i< nchars;++i)
50                 {
51                 tv->my_mvaddch(tv,y,x+i,str[i]);
52                 }
53         free(str);
54         }
55
56 static void html_mvaddch(struct AbstractTview* tv,int y,int x,int ch)
57         {
58         tixel_t* row=NULL;
59         html_tview_t* ptr=FROM_TV(tv);
60         if( x >= tv->mcol ) return; //out of screen
61         while(ptr->row_count<=y)
62                 {
63                 int x;
64                 row=(tixel_t*)calloc(tv->mcol,sizeof(tixel_t));
65                 if(row==0)  exit(EXIT_FAILURE);
66                 for(x=0;x<tv->mcol;++x) {row[x].ch=' ';row[x].attributes=0;}
67                 ptr->screen=(tixel_t**)realloc(ptr->screen,sizeof(tixel_t*)*(ptr->row_count+1));
68                 ptr->screen[ptr->row_count++]=row;
69                 }
70         row=ptr->screen[y];
71         row[x].ch=ch;
72         row[x].attributes=ptr->attributes;
73         }
74         
75 static void html_attron(struct AbstractTview* tv,int flag)
76     {
77     html_tview_t* ptr=FROM_TV(tv);
78     ptr->attributes |=  flag;
79
80
81     }
82    
83 static void html_attroff(struct AbstractTview* tv,int flag)
84     {
85     html_tview_t* ptr=FROM_TV(tv);
86     ptr->attributes &= ~(flag);
87     }
88     
89 static void html_clear(struct AbstractTview* tv)
90     {
91     html_tview_t* ptr=FROM_TV(tv);
92     if(ptr->screen!=NULL)
93         {
94         int i;
95         for(i=0;i< ptr->row_count;++i) free(ptr->screen[i]);
96         free(ptr->screen);
97         ptr->screen=NULL;
98         }
99     ptr->row_count=0;
100     ptr->attributes=0;
101     }
102     
103 static int html_colorpair(struct AbstractTview* tv,int flag)
104     {
105     return (1 << (flag));
106     }
107
108 static int html_drawaln(struct AbstractTview* tv, int tid, int pos)
109     {
110     int y,x;
111     html_tview_t* ptr=FROM_TV(tv);
112     html_clear(tv);
113     base_draw_aln(tv,  tid, pos);
114     fputs("<html><head>",ptr->out);
115     fprintf(ptr->out,"<title>%s:%d</title>",
116         tv->header->target_name[tid],
117         pos+1
118         );
119     //style
120    
121     fputs("<style type='text/css'>\n",ptr->out);
122     fputs(".tviewbody { margin:5px; background-color:white;text-align:center;}\n",ptr->out);
123     fputs(".tviewtitle {text-align:center;}\n",ptr->out);
124     fputs(".tviewpre { margin:5px; background-color:white;}\n",ptr->out);
125     #define CSS(id,col) fprintf(ptr->out,".tviewc%d {color:%s;}\n.tviewcu%d {color:%s;text-decoration:underline;}\n",id,col,id,col);
126         CSS(0, "black");
127         CSS(1, "blue");
128         CSS(2, "green");
129         CSS(3, "yellow");
130         CSS(4, "black");
131         CSS(5, "green");
132         CSS(6, "cyan");
133         CSS(7, "yellow");
134         CSS(8, "red");
135         CSS(9, "blue");
136     #undef CSS
137     fputs("</style>",ptr->out);
138     
139     fputs("</head><body>",ptr->out);
140     
141       fprintf(ptr->out,"<div class='tviewbody'><div class='tviewtitle'>%s:%d</div>",
142         tv->header->target_name[tid],
143         pos+1
144         );
145     
146     fputs("<pre class='tviewpre'>",ptr->out);
147     for(y=0;y< ptr->row_count;++y)
148         {
149         
150         for(x=0;x< tv->mcol;++x)
151                 {
152                 
153                 
154                 if(x== 0 || ptr->screen[y][x].attributes != ptr->screen[y][x-1].attributes)
155                         {
156                         int css=0;
157
158                         while(css<32)
159                                 {
160                                 //if(y>1) fprintf(stderr,"css=%d pow2=%d vs %d\n",css,(1 << (css)),ptr->screen[y][x].attributes);
161                                 if(( (ptr->screen[y][x].attributes) & (1 << (css)))!=0)
162                                         {
163                                         
164                                         fprintf(ptr->out," class='tviewc%s%d",
165                                                 (( (ptr->screen[y][x].attributes) & (1 << (UNDERLINE_FLAG)) )!=0?"u":""),
166                                                 css);
167                                         fputs("'",ptr->out);
168                                         break;
169                                         }
170                                 ++css;
171                                 }
172
173
174                         fputs(">",ptr->out);
175                         }
176                 
177                 int ch=ptr->screen[y][x].ch;
178                 switch(ch)
179                         {
180                         case '<': fputs("&lt;",ptr->out);break;
181                         case '>': fputs("&gt;",ptr->out);break;
182                         case '&': fputs("&amp;",ptr->out);break;
183                         default: fputc(ch,ptr->out); break;
184                         }
185                 
186                 
187                 if(x+1 == tv->mcol  || ptr->screen[y][x].attributes!=ptr->screen[y][x+1].attributes)
188                         {
189                         fputs("</span>",ptr->out);
190                         }
191                 }
192         if(y+1 < ptr->row_count) fputs("<br/>",ptr->out);
193         }
194     fputs("</pre></div></body></html>",ptr->out);
195     return 0;
196     }
197
198
199 #define ANSI_COLOR_RED "\x1b[31m"
200 #define ANSI_COLOR_GREEN "\x1b[32m"
201 #define ANSI_COLOR_YELLOW "\x1b[33m"
202 #define ANSI_COLOR_BLUE "\x1b[34m"
203 #define ANSI_COLOR_MAGENTA "\x1b[35m"
204 #define ANSI_COLOR_CYAN "\x1b[36m"
205 #define ANSI_COLOR_BLACK "\x1b[0m"
206 #define ANSI_COLOR_RESET ANSI_COLOR_BLACK
207
208 #define ANSI_UNDERLINE_SET "\033[4m"
209 #define ANSI_UNDERLINE_UNSET "\033[0m"
210
211 static int text_drawaln(struct AbstractTview* tv, int tid, int pos)
212     {
213     int y,x;
214     html_tview_t* ptr=FROM_TV(tv);
215     html_clear(tv);
216     base_draw_aln(tv,  tid, pos); 
217     int is_term= isatty(fileno(ptr->out));
218     
219     for(y=0;y< ptr->row_count;++y)
220         {
221         for(x=0;x< tv->mcol;++x)
222                 {
223                 if(is_term)
224                         {
225                         int css=0;
226                         while(css<32)
227                                 {
228                                 if(( (ptr->screen[y][x].attributes) & (1 << (css)))!=0)
229                                         {
230                                         break;
231                                         }
232                                 ++css;
233                                 }
234                         switch(css)
235                                 {
236                                 //CSS(0, "black");
237                                 case 1: fputs(ANSI_COLOR_BLUE,ptr->out); break;
238                                 case 2: fputs(ANSI_COLOR_GREEN,ptr->out); break;
239                                 case 3: fputs(ANSI_COLOR_YELLOW,ptr->out); break;
240                                 //CSS(4, "black");
241                                 case 5: fputs(ANSI_COLOR_GREEN,ptr->out); break;
242                                 case 6: fputs(ANSI_COLOR_CYAN,ptr->out); break;
243                                 case 7: fputs(ANSI_COLOR_YELLOW,ptr->out); break;
244                                 case 8: fputs(ANSI_COLOR_RED,ptr->out); break;
245                                 case 9: fputs(ANSI_COLOR_BLUE,ptr->out); break;
246                                 default:break;
247                                 }
248                         if(( (ptr->screen[y][x].attributes) & (1 << (UNDERLINE_FLAG)))!=0)
249                                 {
250                                 fputs(ANSI_UNDERLINE_SET,ptr->out);
251                                 }
252                         
253                         }
254                 
255                 
256                 int ch=ptr->screen[y][x].ch;
257
258                 fputc(ch,ptr->out);
259                 if(is_term)
260                         {
261                         fputs(ANSI_COLOR_RESET,ptr->out);
262                         if(( (ptr->screen[y][x].attributes) & (1 << (UNDERLINE_FLAG)))!=0)
263                                 {
264                                 fputs(ANSI_UNDERLINE_UNSET,ptr->out);
265                                 }
266                         }
267                 }
268         fputc('\n',ptr->out);
269         }
270     return 0;
271     }
272
273
274 static int html_loop(tview_t* tv)
275         {
276         //tv->my_drawaln(tv, tv->curr_tid, tv->left_pos);
277         return 0;       
278         }
279
280 static int html_underline(tview_t* tv)
281         {
282         return (1 << UNDERLINE_FLAG);   
283         }
284
285 /*
286 static void init_pair(html_tview_t *tv,int id_ge_1, const char* pen, const char* paper)
287         {
288         
289         }
290 */
291
292 tview_t* html_tv_init(const char *fn, const char *fn_fa, const char *samples)
293         {
294         char* colstr=getenv("COLUMNS");
295         html_tview_t *tv = (html_tview_t*)calloc(1, sizeof(html_tview_t));
296         tview_t* base=(tview_t*)tv;
297         if(tv==0)
298                 {
299                 fprintf(stderr,"Calloc failed\n");
300                 return 0;
301                 }
302         tv->row_count=0;
303         tv->screen=NULL;
304         tv->out=stdout;
305         tv->attributes=0;
306         base_tv_init(base,fn,fn_fa,samples);
307         /* initialize callbacks */
308 #define SET_CALLBACK(fun) base->my_##fun=html_##fun;
309         SET_CALLBACK(destroy);
310         SET_CALLBACK(mvprintw);
311         SET_CALLBACK(mvaddch);
312         SET_CALLBACK(attron);
313         SET_CALLBACK(attroff);
314         SET_CALLBACK(clear);
315         SET_CALLBACK(colorpair);
316         SET_CALLBACK(drawaln);
317         SET_CALLBACK(loop);
318         SET_CALLBACK(underline);
319 #undef SET_CALLBACK
320
321         
322         if(colstr!=0)
323                 {
324                 base->mcol=atoi(colstr);
325                 if(base->mcol<10) base->mcol=80;
326                 }
327         base->mrow=99999;
328         
329 /*
330         init_pair(tv,1, "blue", "white");
331         init_pair(tv,2, "green", "white");
332         init_pair(tv,3, "yellow", "white");
333         init_pair(tv,4, "white", "white");
334         init_pair(tv,5, "green", "white");
335         init_pair(tv,6, "cyan", "white");
336         init_pair(tv,7, "yellow", "white");
337         init_pair(tv,8, "red", "white");
338         init_pair(tv,9, "blue", "white");
339         */
340         return base;
341         }
342
343
344 tview_t* text_tv_init(const char *fn, const char *fn_fa, const char *samples)
345         {
346         tview_t* tv=html_tv_init(fn,fn_fa,samples);
347         tv->my_drawaln=text_drawaln;
348         return tv;
349         }
350