%{ #define COLOR_Milestone "gtcMilestone" #define COLOR_BOX_HEAVY "gtcBoxHeavy" #define COLOR_BOX_LIGHT "gtcBoxLight" #define PICT_TOPSEP 3 #define PICT_BOTSEP 3 #define PICT_LEFTSEP 3 #define PICT_RIGHTSEP 3 #define PICT_VSEP 2 #define PICT_HSEP 2 #define PICT_MONTHHEIGHT 5 // police height #define PICT_MONTHWIDTH (10./3.) #define TASK_VSEP 2 #define TASK_BGC0 "gtcTaskBG0" #define TASK_BGC1 "gtcTaskBG1" #define DELIVRABLE_VSEP 1 #define DELIVRABLE_HEIGHT 3 #define DELIVRABLE_LABELWIDTH 10 #define DELIVRABLE_LABELHEIGHT DELIVRABLE_HEIGHT #define DELIVRABLE_TITLEWIDTH 35 #define DELIVRABLE_TITLEHEIGHT DELIVRABLE_HEIGHT #define DELIVRABLE_BOXHEIGHT (DELIVRABLE_HEIGHT) typedef struct _Tlivrable { int tn,stn,dn,vn; // task, sub-task, number char v; // 0, 1, 2, ..., F char* title; int bm,em; // mois de bebut et de fin // these fields are filled by the program for data[tn][0][0][0] double task_y; // top of task double task_dy; // bot of task is task_y+task_dy // these fields are filled by the program for data[tn][stn][dn][0] struct _Tlivrable **vers; // null termiated (vers[i] = &data[tn][stn][dn][i]) int nbvers; // nombre de vers double height; // height of livrable // int del_bm,del_em; // mois de bebut et de fin cummule // these fields are filled by the program for all elements int nbTitleLines; char* titleLines[5]; // null termiated } Tlivrable; #define T_MAX 10 #define S_MAX 10 #define D_MAX 10 #define V_MAX 10 Tlivrable* data[T_MAX][S_MAX][D_MAX][V_MAX]; int milestones[100]; char* gen_label_base(char* buf,Tlivrable*p) { sprintf(buf,"D%d%d%d",p->tn,p->stn,p->dn); return buf; } char* gen_label_vers(char* buf,Tlivrable*p) { if (p->nbvers<=1) sprintf(buf,""); else sprintf(buf,"V%c",p->v); return buf; } char* gen_label_full(char* buf,Tlivrable*p) { char b[100],v[100]; gen_label_base(b,p); gen_label_vers(v,p); sprintf(buf,"%s%s%s",b,*v?"-":"",v); return buf; } void print_put(double x,double y, const char* object) { printf("\\put(%.2f,%.2f){%s}\n",x,y,object); } void print_hline(double x,double y, double len, const char* color) { char object[1024]; if (color!=0) { printf("\\bgroup\\color{%s}\n",color); } sprintf(object,"\\line(1,0){%.2f}",len); print_put(x,y,object); if (color!=0) { printf("\\egroup\n"); } } void print_vline(double x,double y, double len, const char* color) { char object[1024]; if (color!=0) { printf("\\bgroup\\color{%s}\n",color); } sprintf(object,"\\line(0,1){%.2f}",len); print_put(x,y,object); if (color!=0) { printf("\\egroup\n"); } } void print_box( int filled, char* vers, // vers may be 0, double x,double y, double dx, double dy, const char* boxcolor, // may be 0 (default COLOR_BOX_HEAVY) const char* bgcolor, // may be 0 (not set) const char* textcolor // may be 0 (black) ){ double tn=.4; char object[1024]; if ( boxcolor==0 ) boxcolor = COLOR_BOX_HEAVY; if ( filled==1 ) { sprintf(object, "\\fcolorbox{black}{%s}{\\makebox(%.2f,%.2f){}}", boxcolor,dx-2-tn,dy-2-tn); print_put(x,y+1,object); } else { double tn2=tn/2; double e=.1; printf("\\bgroup\\color{%s}\n",boxcolor); printf("\\linethickness{%.2fmm}\n",tn); print_hline(x+tn2-e ,y, dx ,0); print_hline(x+tn2-e ,y+dy, dx ,0); print_vline(x+tn-e ,y+e, dy-2*e ,0); print_vline(x+dx-2*e,y+e, dy-2*e ,0); printf("\\egroup\n"); } if (vers) { sprintf(object,"\\begin{tiny}\\textbf{%s}\\end{tiny}",vers); print_put(x+1,y+.5,object); } } void gen_titleLines(Tlivrable*p) { const char* macro="\\ganttlf"; char* pc = p->title; char* pc2; if (pc==0) return; while ( (pc2=strstr(pc,macro))!=0 ) { char c = *pc2; *pc2 = 0; p->titleLines[p->nbTitleLines]=strdup(pc); p->nbTitleLines+=1; *pc2=c; pc=pc2+strlen(macro); } p->titleLines[p->nbTitleLines]=strdup(pc); p->nbTitleLines+=1; } %} %option noyywrap %% int tn,stn,dn,v,bm,em; char* title; #.*\n ; T=[0-9]+ { tn=atoi(yytext+2); } T=D[0-9]+ { tn=atoi(yytext+3); } S=[0-9]+ { stn=atoi(yytext+2); } D=[0-9]+ { dn=atoi(yytext+2); } V=V. { v=yytext[3]; } V= { v='F'; } ML=[0-9]+ { int i; for (i=0 ; milestones[i]!=0 ; i++); milestones[i] = atoi(yytext+3); } BM=[0-9]+ { bm=atoi(yytext+3); } EM=[0-9]+ { em=atoi(yytext+3); } TITLE=.*\n { char* pc=yytext+6; yytext[yyleng-1]=0; while ( *pc==' ' || *pc=='\t' ) pc+=1; title=strdup(pc); Tlivrable* p= (Tlivrable*) calloc(sizeof(*p),1); p->tn = tn; p->stn = stn; p->dn = dn; p->v = v; p->title = title; p->bm = bm; p->em = em; gen_titleLines(p); for (v=0; data[tn][stn][dn][v]!=0 ; v++); data[tn][stn][dn][v] = p; fprintf(stderr,"ADDED: %d %d %d %d\n",tn,stn,dn,v); //{int i,tn=0; fprintf(stderr,"CURR:t=%d:: ",tn); for (i=0; i=D_MAX) break; // shift for (i=0 ; (i1+i)=S_MAX) break; // shift for (i=0 ; (i1+i)nbvers=0 ; for (vn=0 ; vnnbvers+=1; p->vers=(Tlivrable**)malloc(sizeof(*p->vers)*(p->nbvers+1)); for (vn=0 ; vnnbvers ; vn+=1) { p->vers[vn] = data[tn][stn][dn][vn]; data[tn][stn][dn][vn]->nbvers = p->nbvers; } p->vers[vn] = 0; p->height = 1.0*DELIVRABLE_HEIGHT; if (p->nbTitleLines>=1) { double h=0; h += p->vers[p->nbvers-1]->nbTitleLines*DELIVRABLE_TITLEHEIGHT; h += (p->vers[p->nbvers-1]->nbTitleLines-1)*(DELIVRABLE_TITLEHEIGHT/5.); if ( h>p->height) p->height=h; } } } double task_livrable_height(int tn) { int stn,dn,nblivrables=0; double height=0; for (stn=0 ; data[tn][stn][0][0]!=0 ; stn++) for (dn=0 ; data[tn][stn][dn][0]!=0 ; dn++) { nblivrables += 1; height+=data[tn][stn][dn][0]->height; } height += DELIVRABLE_VSEP/2; height += (nblivrables-1)*DELIVRABLE_VSEP; height += DELIVRABLE_VSEP/2; return height; } void task_box(double pictwidth) { int tn; for ( tn=0 ; data[tn][0][0][0]!=0 ; tn++ ) { const char* color= (tn%2)!=0 ? TASK_BGC1 : TASK_BGC0 ; printf( "\\put(%.2f,%.2f){\\fcolorbox{black}{%s}{\\makebox(%5.2f,%5.2f){}}}\n", 0.0,data[tn][0][0][0]->task_y, color, pictwidth,data[tn][0][0][0]->task_dy ); } } void month_grid(double x, double y, double dx, double dy) { int i; for (i=0 ; i<=36 ; i+=1,x+=PICT_MONTHWIDTH) { if ( (i%3)!=0 ) continue; printf( "\\put(%5.1f,%5.1f){\\line(0,1){%5.1f}}\\put(%5.1f,%5.1f){%d}\n", x,y,dy-PICT_MONTHWIDTH-PICT_VSEP, x-2,y+dy-PICT_MONTHHEIGHT, i ); } } void print_milestones(double x, double y, double dx, double dy) { int i; double tn=.3; //x=x-tn/2; printf("\\bgroup\n"); printf("\\color{red}\n"); printf("\\linethickness{%.2fmm}\n",tn); for (i=0 ; milestones[i]!=0 ; i+=1) { double xx= x + milestones[i]*PICT_MONTHWIDTH; print_vline(xx,y,dy-PICT_MONTHWIDTH-PICT_VSEP,0); } printf("\\egroup\n"); } double delivrable( double label_x, double box_x, double title_x, double y, int tn, int stn, int dn) { Tlivrable* top=data[tn][stn][dn][0]; Tlivrable* last=data[tn][stn][dn][top->nbvers-1]; char tmp[1000],label[1000],title[1000]; double y0; int v; double label_dx = DELIVRABLE_LABELWIDTH ; double label_dy = DELIVRABLE_LABELHEIGHT ; double boxx,box_dx; double box_dy = DELIVRABLE_BOXHEIGHT ; double title_dx = DELIVRABLE_LABELWIDTH ; double title_dy = DELIVRABLE_TITLEHEIGHT ; //print_hline(0,y,180,0); gen_label_base(label,top); // y -= DELIVRABLE_HEIGHT; y -= top->height ; //print_hline(0,y,180,0); printf("% Delivrable %s (tn=%d stn=%d dn=%d\n",label,tn,stn,dn); // print label //y0 = (DELIVRABLE_HEIGHT-DELIVRABLE_LABELHEIGHT)/2; y0 = (top->height-DELIVRABLE_LABELHEIGHT)/2; sprintf(tmp,"\\ganttlabelstyle{%s}",label); print_put(label_x,y+y0,tmp); // print title if (last->nbTitleLines==1) { y0 = (DELIVRABLE_HEIGHT-DELIVRABLE_TITLEHEIGHT)/2; y0 += DELIVRABLE_TITLEHEIGHT/5. ; sprintf(tmp,"\\gantttitlestyle{%s}",last->title); print_put(title_x,y+y0,tmp); } else if (last->nbTitleLines>1) { int i; // y0 = (DELIVRABLE_HEIGHT-DELIVRABLE_TITLEHEIGHT)/2; y0=DELIVRABLE_TITLEHEIGHT/5.; sprintf(tmp,"\\gantttitlestyle{\\shortstack[l]{%s",last->titleLines[0]); for (i=1 ; inbTitleLines ; i+=1) { strcat(tmp,"\\\\"); strcat(tmp,last->titleLines[i]); } strcat(tmp,"}}"); print_put(title_x,y+y0,tmp); } // print box //y0 = (DELIVRABLE_HEIGHT-DELIVRABLE_BOXHEIGHT)/2; y0 = (top->height-DELIVRABLE_BOXHEIGHT)/2; if ( last==top ) { Tlivrable* l=top; boxx = box_x + l->bm*PICT_MONTHWIDTH ; box_dx = (l->em - l->bm) * PICT_MONTHWIDTH; print_box(1,0,boxx,y+y0,box_dx,box_dy,COLOR_BOX_LIGHT,0,0); print_box(0,0,boxx,y+y0,box_dx,box_dy,0,0,0); } else for (v=0 ; vnbvers ; v+=1) { Tlivrable* l=data[tn][stn][dn][v] ; gen_label_vers(tmp,l); boxx = box_x + l->bm*PICT_MONTHWIDTH ; box_dx = (l->em - l->bm) * PICT_MONTHWIDTH; print_box(1,0,boxx,y+y0,box_dx,box_dy,COLOR_BOX_LIGHT,0,0); print_box(0,tmp,boxx,y+y0,box_dx,box_dy,0,0,0); } y -= DELIVRABLE_VSEP; return y; } void task_delivrable(double label_x, double box_x, double title_x, int tn) { int stn,dn; double y = data[tn][0][0][0]->task_y+data[tn][0][0][0]->task_dy; //y += DELIVRABLE_VSEP/2. ; for (stn=0 ; data[tn][stn][0][0]!=0 ; stn++) for (dn=0 ; data[tn][stn][dn][0]!=0 ; dn++) { y=delivrable(label_x,box_x,title_x,y,tn,stn,dn); } } int main() { int tn; double pictwidth, pictheight; double gantt_x,gantt_y; double gantt_dx,gantt_dy; double label_x,title_x; yylex(); prepare0(); prepare1(); prepare2(); pictheight=0 ; pictheight += PICT_BOTSEP ; for ( tn=0 ; data[tn][0][0][0]!=0 ; tn++ ); for ( tn=tn-1 ; tn>=0 ; tn-- ) { data[tn][0][0][0]->task_y = pictheight; data[tn][0][0][0]->task_dy = task_livrable_height(tn); pictheight += data[tn][0][0][0]->task_dy; pictheight += TASK_VSEP; } pictheight += PICT_MONTHHEIGHT; pictheight += PICT_TOPSEP ; gantt_y = PICT_BOTSEP ; gantt_dy = pictheight-PICT_TOPSEP-PICT_BOTSEP ; pictwidth=0; pictwidth += PICT_LEFTSEP; label_x = pictwidth; pictwidth += DELIVRABLE_LABELWIDTH; pictwidth += PICT_HSEP; gantt_x = pictwidth ; gantt_dx = 36*PICT_MONTHWIDTH ; pictwidth += gantt_dx ; pictwidth += PICT_HSEP; title_x = pictwidth; pictwidth += DELIVRABLE_TITLEWIDTH; pictwidth += PICT_RIGHTSEP; printf("\\setlength{\\unitlength}{1.0mm}\n"); printf("\\begin{picture}(%.1f,%.1f)\n",pictwidth,pictheight); task_box(pictwidth); month_grid(gantt_x,gantt_y,gantt_dx,gantt_dy); for ( tn=0 ; data[tn][0][0][0]!=0 ; tn++ ) { task_delivrable(label_x,gantt_x,title_x,tn); } print_milestones(gantt_x,0,gantt_dx,gantt_dy+gantt_y); printf("\\end{picture}\n"); return 0; }