diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/nemocal/nemocal.c |
Initial commit
Diffstat (limited to 'support/nemocal/nemocal.c')
-rw-r--r-- | support/nemocal/nemocal.c | 615 |
1 files changed, 615 insertions, 0 deletions
diff --git a/support/nemocal/nemocal.c b/support/nemocal/nemocal.c new file mode 100644 index 0000000000..b0613bd419 --- /dev/null +++ b/support/nemocal/nemocal.c @@ -0,0 +1,615 @@ +#include <conio.h> +#include <ctype.h> +#include <malloc.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#define DEBUG + +#define EOS ('\0') +#define bool char + +#define In(x,y,z) ((x)<=(y) && (y)<=(z)) +#define Min(x,y) ((x)<(y) ? (x) : (y)) +#define Max(x,y) ((x)>(y) ? (x) : (y)) +#define streq !strcmp + +enum {weekly,monthly,yearly}; + +void create_calendar(void); +void exit_here(bool opt,const char *format,...); +int get_day_of_week(int year,int month,int day); +void get_second_field_parameters(char *string); +void get_third_field_parameters(char *string); +void get_today(void); +bool leap_year(int year); +int n_rows_in_monthly_calendar(int year,int month,int dw); +void preprocess(int argc,char *argv[]); +void show_usage(void); +int str2num(char *str); +void write_calendar_page(int n,FILE *fp_out); + + +int CalendarType; /* weekly=0, monthly=1 or yearly=2 */ +int Npages; /* -n */ +int MperPage=1; /* m in -n,m. For "monthly" only. */ +int StartYear,StartMonth,StartDay; /* [year/month/day] */ +/* Above are determined in preprocess(), + from the command line. */ + +int Days_of_month[12]={31,28,31,30,31,30,31,31,30,31,30,31}; +char *MonthName[12]={"January","February","March","April", + "May","June","July","August", + "September","October","November","December"}, + *Month_name[12]={"Jan","Feb","Mar","Apr", + "May","Jun","Jul","Aug", + "Sep","Oct","Nov","Dec"}; +char *DayName[7]={"Sunday","Monday","Tuesday","Wednesday", + "Thursday","Friday","Saturday"}, + *Day_name[7]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; +int ThisYear,ThisMonth,Today; /* Counts from one. */ + +void main(int argc,char *argv[]) +{ + char *calendartype[3]={"weekly","monthly","yearly"}; + + if(!In(2,argc,4)) show_usage(); + + get_today(); + + preprocess(argc,argv); + if(MperPage>=4) exit_here(0,"This option not available yet."); + + printf("\nWe'll create %d page",Npages); + if(Npages>1) printf("s"); + printf(" of %s calendar starting from %d", + calendartype[CalendarType],StartYear); + if(CalendarType==weekly) printf("/%d/%d.\n",StartMonth,StartDay); + else if(CalendarType==monthly){ + printf("/%d.\nMonth per page = %d.\n",StartMonth,MperPage); + } + else printf(".\n"); + + cprintf("\r\nContinue ? (y/n): "); + if(getche()!='y') exit_here(0,"\nAborted by user request."); + + create_calendar(); + + printf("\nExecute \"latex calendar\".\n"); +} + + /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +void preprocess(int argc,char *argv[]) +{ + char *p; + + /* first field, CalendarType */ + if(argv[1][0]!='-') show_usage(); + if(streq((p=&(argv[1][1])),"w") || streq(p,"weekly")) + CalendarType = weekly; + else if(streq(p,"m") || streq(p,"monthly")) CalendarType = monthly; + else if(streq(p,"y") || streq(p,"yearly")) CalendarType = yearly; + else show_usage(); + + /* give default values, tentatively */ + Npages = 1; + StartYear = ThisYear; + StartMonth = ThisMonth; + StartDay = Today; /* year day */ + + if(argv[2][0]=='-'){ + get_second_field_parameters(&(argv[2][1])); + if(argc==4) get_third_field_parameters(argv[3]); + else if(argc!=3) show_usage(); + } + else if(argc==3) get_third_field_parameters(argv[2]); + else if(argc!=2) show_usage(); +} + + /* -------------------------------------- */ + +void show_usage(void) +{ + printf("\nUsage: nemocal -options [-n[,m]] [year/month/day]\n\n\ + where -options = -w[eekly]|-m[onthly]|-y[early]\n\ + -n = number of pages\n\ + m = number of months in a page (for -monthly only)\n\ + year/month/day = start of the calendar\n\n"); + exit(0); +} + + /* -------------------------------------- */ + +void print_rows(int rows,int dw,int dmon,bool center, + int width,int height6,int height5, + int depth6,int depth5,FILE *fp_out) +{ /* for monthly calendars only */ + int x,row,i; + char xstr[21]; + + x = 0; + for(row=0;row<rows;row++){ + for(i=0;i<7;i++){ + if(i==0){ + if(rows<6) + fprintf(fp_out,"\\rule[-%dpt]{0pt}{%dpt} ",depth5,height5); + else fprintf(fp_out,"\\rule[-%dpt]{0pt}{%dpt} ",depth6,height6); + } + else fprintf(fp_out," "); + if(row==0){ + if(i<dw) x = 0; + else x++; + } + else{ + if(x!=0) x++; + if(x>dmon) x = 0; + } + if(x==0) strcpy(xstr," "); + else sprintf(xstr,"%d",x); + if(center){ + if(i<6) fprintf(fp_out,"\\makebox[%dpt]{%s} &\n",width,xstr); + else fprintf(fp_out,"\\makebox[%dpt]{%s} \\\\ \\hline\n", + width,xstr); + } + else{ + if(i<6) fprintf(fp_out,"\\makebox[%dpt][r]{%s} &\n",width,xstr); + else fprintf(fp_out,"\\makebox[%dpt][r]{%s} \\\\ \\hline\n", + width,xstr); + } + } + } +} + + /* -------------------------------------- */ + +void create_calendar(void) +{ + FILE *fp_out; + int n; + + fp_out = fopen("calendar.tex","wt"); + if(fp_out==NULL) exit_here(1,"Can't create calendar.tex."); + + cprintf("\r\n\nCreating calendar.tex"); + fprintf(fp_out,"\\documentstyle{article}\n\n"); + fprintf(fp_out,"\\oddsidemargin 0cm\n"); + fprintf(fp_out,"\\evensidemargin 0cm\n"); + if(CalendarType==weekly) fprintf(fp_out,"\\topmargin -1cm\n"); + else fprintf(fp_out,"\\topmargin -1.6cm\n"); + + fprintf(fp_out,"\\parindent 0cm\n"); + + if(CalendarType!=monthly || (MperPage!=1 && MperPage!=4)){ + /* Portrait mode */ + fprintf(fp_out,"\\textheight 11in\n"); + fprintf(fp_out,"\\textwidth 16.44cm\n"); + } + else{ /* Landscape mode */ + fprintf(fp_out,"\\textheight 7.0in\n"); + fprintf(fp_out,"\\textwidth 9.0in\n"); + } + + fprintf(fp_out,"\\pagestyle{empty}\n\n"); + fprintf(fp_out,"\\begin{document}\n\n"); + + for(n=1;n<=Npages;n++){ + write_calendar_page(n,fp_out); + cprintf(" [%d]",n); + } + + fprintf(fp_out,"\\end{document}\n\n"); + fclose(fp_out); + + printf(" Done.\n"); + if(CalendarType==monthly && (MperPage==1 || MperPage==4)) + printf("\nRemember the landscape mode!\n"); +} + + /* -------------------------------------- */ + +void write_calendar_page(int n,FILE *fp_out) +{ + int startmonth,endmonth,startyear,endyear, + d_Sun,dw,i,j,k,days_remaining,day,dmon,rows,month; + char month_str[21],year_str[21]; + + if(n>1) fprintf(fp_out,"\\newpage\n"); + + if(CalendarType==weekly){ + /* for weekly calendars, one page may have two months/years */ + dw = get_day_of_week(StartYear,StartMonth,StartDay); + if(StartDay>=dw){ + d_Sun = StartDay - dw + 1; + startyear = endyear = StartYear; + startmonth = endmonth = StartMonth; + days_remaining = Days_of_month[StartMonth-1] - StartDay; + if(StartMonth==2 && leap_year(StartYear)) days_remaining++; + if(days_remaining<7-dw){ + if(StartMonth<12) endmonth = startmonth+1; + else{ + endmonth = 1; + endyear = StartYear+1; + } + } + } + else{ + if(StartMonth>1){ + startyear = endyear = StartYear; + startmonth = StartMonth-1; + endmonth = StartMonth; + } + else{ + startyear = StartYear - 1; + endyear = StartYear; + startmonth = 12; + endmonth = 1; + } + d_Sun = Days_of_month[startmonth-1] - dw + 2; + if(startmonth==2 && leap_year(startyear)) d_Sun++; + } + if(endmonth==startmonth) + sprintf(month_str,"%s",Month_name[startmonth-1]); + else sprintf(month_str,"%s/%s", + Month_name[startmonth-1],Month_name[endmonth-1]); + if(endyear==startyear) sprintf(year_str,"%d",startyear); + else sprintf(year_str,"%d/%d",startyear,endyear); + + if(n%2==1) fprintf(fp_out, + "{\\large\\sf\n\\hfill %s \\ %s\n}\n\\vspace{1cm}\n\n", + month_str,year_str); + else fprintf(fp_out,"{\\large\\sf\n %s \\ %s\n}\n\\vspace{1cm}\n\n", + month_str,year_str); + + fprintf(fp_out,"\\begin{tabular}{|c|c|} \\hline\n"); + for(i=1;i<=7;i++){ + day = d_Sun + i - 1; + if(day>(dmon = Days_of_month[startmonth-1] + + (startmonth==2 && leap_year(startyear)))) + day -= dmon; + fprintf(fp_out,"\\rule{0cm}{1.5cm}{\\Huge %d}\ + & \\rule{13.68cm}{0cm} \\\\ \n",day); + fprintf(fp_out,"\\rule{0cm}{1cm}\\raisebox{.1cm}{\\sf %s}\ + & \\\\ \\hline \n",DayName[i-1]); + } + fprintf(fp_out,"\\end{tabular}\n\n"); + + StartDay += 7; + if(StartDay > (dmon = Days_of_month[StartMonth-1] + + (StartMonth==2 && leap_year(StartYear)))){ + StartDay -= dmon; + StartMonth++; + if(StartMonth>12){ StartMonth = 1; StartYear++; } + } + } + else if(CalendarType==monthly){ + switch(MperPage){ + case 1: + dw = get_day_of_week(StartYear,StartMonth,1) - 1; + /* Sunday=0,Monday=1 etc. for no good reason */ + rows = n_rows_in_monthly_calendar(StartYear,StartMonth,dw); + if(rows<6) fprintf(fp_out,"\\rule{0cm}{0.6cm}\n"); + fprintf(fp_out,"\\begin{center}\n\n"); + fprintf(fp_out,"{\\huge\\sf %s \\rule{1.5em}{0em} %d}\n\n", + MonthName[StartMonth-1],StartYear); + fprintf(fp_out,"\\rule{0em}{3em}\n\n"); + fprintf(fp_out,"{\\Large\\sf\n"); + fprintf(fp_out,"\\begin{tabular}{|c|c|c|c|c|c|c|} \\hline\n"); + fprintf(fp_out,"\\rule[-3mm]{0mm}{10mm}"); + for(i=0;i<7;i++){ + fprintf(fp_out,"\\makebox[71pt]{%s}",Day_name[i]); + if(i<6) fprintf(fp_out," &\n"); + } + fprintf(fp_out," \\\\ \\hline\n"); + dmon = Days_of_month[StartMonth-1] + + (StartMonth==2 && leap_year(StartYear)); + print_rows(rows,dw,dmon,0,71,65,71,48,54,fp_out); + fprintf(fp_out,"\\end{tabular}\n"); + fprintf(fp_out,"}\n\n"); + fprintf(fp_out,"\\end{center}\n\n"); + StartMonth++; + if(StartMonth>12){ StartMonth = 1; StartYear++; } + break; + case 2: + for(j=0;j<2;j++){ + if(j==0) fprintf(fp_out,"\\rule{0cm}{0.5cm}\n"); + else fprintf(fp_out,"\\rule{0cm}{1.5cm}\n"); + dw = get_day_of_week(StartYear,StartMonth,1) - 1; + /* Sunday=0,Monday=1 etc. for no good reason */ + rows = n_rows_in_monthly_calendar(StartYear,StartMonth,dw); + fprintf(fp_out,"\\begin{center}\n\n"); + fprintf(fp_out,"{\\Large\\sf %s \\rule{1.5em}{0em} %d}\n\n", + MonthName[StartMonth-1],StartYear); + fprintf(fp_out,"\\rule{0em}{2em}\n\n"); + fprintf(fp_out,"{\\large\\sf\n"); + fprintf(fp_out,"\\begin{tabular}{|c|c|c|c|c|c|c|} \\hline\n"); + fprintf(fp_out,"\\rule[-7pt]{0pt}{22pt}"); + for(i=0;i<7;i++){ + fprintf(fp_out,"\\makebox[43pt]{%s}",Day_name[i]); + if(i<6) fprintf(fp_out," &\n"); + } + fprintf(fp_out," \\\\ \\hline\n"); + dmon = Days_of_month[StartMonth-1] + + (StartMonth==2 && leap_year(StartYear)); + print_rows(rows,dw,dmon,0,43,37,43,25,31,fp_out); + fprintf(fp_out,"\\end{tabular}\n"); + fprintf(fp_out,"}\n\n"); + fprintf(fp_out,"\\end{center}\n\n"); + StartMonth++; + if(StartMonth>12){ StartMonth = 1; StartYear++; } + } + break; + /* case 4 and case 6 not available yet */ + } + } + else{ /* yearly */ + fprintf(fp_out,"\\begin{center}\n"); + fprintf(fp_out,"{\\huge\\sf %d}\n",StartYear); + fprintf(fp_out,"\\end{center}\n\n"); + for(j=0;j<4;j++){ /* each j corrsponds to three months */ + if(j==0) fprintf(fp_out,"\\rule{0cm}{3.5cm}\n"); + else fprintf(fp_out,"\\rule{0cm}{3.0cm}\n"); + for(k=0;k<3;k++){ + fprintf(fp_out,"\\parbox{4.8cm}{\n"); + /* Write a monthly calendar here. */ + month = j*3 + k + 1; + + dw = get_day_of_week(StartYear,month,1) - 1; + /* Sunday=0,Monday=1 etc. for no good reason */ + rows = n_rows_in_monthly_calendar(StartYear,month,dw); + fprintf(fp_out,"\\begin{center}\n\n"); + fprintf(fp_out,"{\\sf %s}\n\n",MonthName[month-1]); + fprintf(fp_out,"\\rule{0em}{1em}\n\n"); + fprintf(fp_out,"{\\sf\n"); + fprintf(fp_out,"\\begin{tabular}{|c|c|c|c|c|c|c|} \\hline\n"); + fprintf(fp_out,"\\rule[-3pt]{0pt}{11pt}"); + for(i=0;i<7;i++){ + fprintf(fp_out,"\\makebox[7pt]{\\footnotesize %s}",Day_name[i]); + if(i<6) fprintf(fp_out," &\n"); + } + fprintf(fp_out," \\\\ \\hline\n"); + dmon = Days_of_month[month-1] + + (month==2 && leap_year(StartYear)); + print_rows(rows,dw,dmon,1,7,8,11,-2,0,fp_out); + fprintf(fp_out,"\\end{tabular}\n"); + fprintf(fp_out,"}\n\n"); + fprintf(fp_out,"\\end{center}\n\n"); + + if(k<2) fprintf(fp_out,"}\\rule{0.9cm}{0cm}\n"); + else fprintf(fp_out,"} \\\\ \n"); + } + } + StartYear++; + } +} + +/* + * + * void exit_here(bool opt,const char *format,...) + * Prints formatted error messages on stdout and exits. + * + * int get_day_of_week(int year,int month,int day) + * Sun=1,Mon=2 etc. + * + * void get_second_field_parameters(char *string) + * Computes the global variable(s) Npages (and MperPage) from the + * input string -n[,m]. + * + * void get_third_field_parameters(char *string) + * Computes the global variables StartYear,StartMonth and StartDay + * from the input string year/month/day. The CalendarType strongly + * affects the way this routine calculates those values. + * + * void get_today(void) + * + * bool leap_year(int year) + * + * int n_rows_in_monthly_calendar(int year,int month,int dw) + * year is to determine leap year. + * dw is day of the week counting from zero. + * + * int str2num(char *str) + * + */ + +void exit_here(bool opt,const char *format,...) +{ /* opt==0 iff doesn't show !*** ERROR ***! */ + char buffer[401]; + va_list argp; + + /* write to {\tt buffer[]} */ + va_start(argp,format); + vsprintf(buffer,format,argp); + va_end(argp); + /* print the message and exit */ + printf("\n"); + if(opt) printf("!*** ERROR ***! "); + printf("%s\n\n",buffer); + exit(1); +} + + /* -------------------------------------- */ + +int get_day_of_week(int year,int month,int day) +{ /* 1994/1/1 is Saturday */ + int day_1_1, /* day of the week of Jan 1 of the input year */ + day_m_1, /* day of the week of year/month/1 */ + delta,n; + + /* get day_1_1 */ + delta = 0; + if(year>=1994){ + for(n=1994;n<year;n++){ + delta++; + if(leap_year(n)) delta++; + } + } + else{ + for(n=year;n<1994;n++){ + delta++; + if(leap_year(n)) delta++; + } + delta = -delta; + } + day_1_1 = (delta + 6)%7 + 1; + + /* get day_m_1 */ + delta = 0; + for(n=0;n<month-1;n++){ + delta += Days_of_month[n]; + if(n==1 && leap_year(year)) delta++; + } + day_m_1 = (delta+day_1_1-1)%7 + 1; + return (day_m_1 + day - 2)%7 + 1; +} + + /* -------------------------------------- */ + +void get_second_field_parameters(char *string) +{ + int x,pos,vpos; + char c,str1[11],str2[11]; + + if((x=str2num(string)) >= 0) Npages = x; + else{ + if(CalendarType!=monthly) show_usage(); + pos = vpos = 0; + while((c=string[pos++])!=',' && c!=EOS){ + if(vpos>10) show_usage(); + str1[vpos++] = c; + } + if(c!=',') show_usage(); + str1[vpos] = EOS; + if((Npages=str2num(str1))<0) show_usage(); + vpos = 0; + while((c=string[pos++])!=EOS){ + if(vpos>=10) show_usage(); + str2[vpos++] = c; + } + str2[vpos] = EOS; + if((MperPage=str2num(str2))<0) show_usage(); + if(MperPage!=1 && MperPage!=2 && MperPage!=4 && MperPage!=6) + exit_here(0,"You can have only 1,2,4 or 6 months per page."); + } +} + + /* -------------------------------------- */ + +void get_third_field_parameters(char *string) +{ + int n=0; /* number of subfields separated by / */ + char numstring[3][5]; + int pos=0,vpos=0,i; + char c; + + while((c=string[pos++])!=EOS){ + if(c=='/'){ + if(n>=2) show_usage(); + numstring[n++][vpos] = EOS; + vpos = 0; + } + else{ + if(vpos>=4) show_usage(); + numstring[n][vpos++] = c; + } + } + numstring[n++][vpos] = EOS; + for(i=0;i<n;i++){ + if(str2num(numstring[i])<=0) show_usage(); + } + + switch(CalendarType){ /* StartXxxx */ + + case weekly: + if(n==1) StartDay = str2num(numstring[0]); + else if(n==2){ + StartMonth = str2num(numstring[0]); + StartDay = str2num(numstring[1]); + } + else if(n==3){ + StartYear = str2num(numstring[0]); + StartMonth = str2num(numstring[1]); + StartDay = str2num(numstring[2]); + } + break; + + case monthly: + if(n==1) StartMonth = str2num(numstring[0]); + else if(n==2){ + StartYear = str2num(numstring[0]); + StartMonth = str2num(numstring[1]); + } + else exit_here(0,"No need to specify the day."); + break; + + case yearly: + if(n!=1) exit_here(0,"No need to specify the month or day."); + StartYear = str2num(numstring[0]); + break; + + } +} + + /* -------------------------------------- */ + +void get_today(void) +{ + time_t time_of_day; + auto struct tm *tmbuf; + + time_of_day = time(NULL); + tmbuf = localtime(&time_of_day); + Today = tmbuf->tm_mday; + ThisMonth = tmbuf->tm_mon + 1; + ThisYear = tmbuf->tm_year + 1900; +} + + /* -------------------------------------- */ + +bool leap_year(int year) +{ + if(year%4 == 0){ + if(year%100 == 0){ + if(year%400 == 0) return 1; + else return 0; + } + else return 1; + } + else return 0; +} + + /* -------------------------------------- */ + +int n_rows_in_monthly_calendar(int year,int month,int dw) +{ + int rows=1,i,dmon; + + dmon = Days_of_month[month-1] + (month==2 && leap_year(year)); + + for(i=2;i<=dmon;i++){ + if((i+dw)%7 == 1) rows++; + } + + return rows; +} + + /* -------------------------------------- */ + +int str2num(char *str) +{ /* Returns 0 <= x <= 29999 normally. + Returns -1 if input is illegal. */ + char c; + int n=0,pos=0; + + while((c=str[pos])!=EOS){ + if(!isdigit(c)) return -1; + n = n*10 + c - '0'; + pos++; + } + if(pos>5 || (pos==5 && str[0]>'2')) return -1; + else return n; +} + |