xref: /csrg-svn/old/refer/addbib/addbib.c (revision 12256)
1*12256Stut #ifndef lint
2*12256Stut static char *sccsid = "@(#)addbib.c	4.1 (Berkeley) 05/06/83";
3*12256Stut #endif
4*12256Stut 
5*12256Stut #include <stdio.h>
6*12256Stut #include <ctype.h>
7*12256Stut #include <signal.h>
8*12256Stut #define MAXENT 50
9*12256Stut 
10*12256Stut struct skeleton {
11*12256Stut 	char prompt[20];	/* prompt user for entry */
12*12256Stut 	char keylet[5]; 	/* key letter for database */
13*12256Stut } bibskel[MAXENT] = {
14*12256Stut 	"   Author:",	"%A",
15*12256Stut 	"    Title:",	"%T",
16*12256Stut 	"  Journal:",	"%J",
17*12256Stut 	"   Volume:", 	"%V",
18*12256Stut 	"    Pages:",	"%P",
19*12256Stut 	"Publisher:",	"%I",
20*12256Stut 	"     City:", 	"%C",
21*12256Stut 	"     Date:", 	"%D",
22*12256Stut 	"    Other:",	"%O",
23*12256Stut 	" Keywords:",	"%K",	};
24*12256Stut 
25*12256Stut int entries = 10;	/* total number of entries in bibskel */
26*12256Stut int abstract = 1;	/* asking for abstracts is the default */
27*12256Stut 
28*12256Stut usage()			/* print proper usage and exit */
29*12256Stut {
30*12256Stut 	puts("Usage:  addbib [-p promptfile] [-a] database");
31*12256Stut 	puts("\t-p: the promptfile defines alternate fields");
32*12256Stut 	puts("\t-a: don't include prompting for the abstract");
33*12256Stut 	exit(1);
34*12256Stut }
35*12256Stut 
36*12256Stut main(argc, argv)	/* addbib: bibliography entry program */
37*12256Stut int argc;
38*12256Stut char *argv[];
39*12256Stut {
40*12256Stut 	FILE *fp, *fopen();
41*12256Stut 	int i;
42*12256Stut 
43*12256Stut 	if (argc == 1)
44*12256Stut 	{
45*12256Stut 		puts("You must specify a bibliography file (database).");
46*12256Stut 		usage();
47*12256Stut 	}
48*12256Stut 	for (i = 1; argv[i][0] == '-'; i++)
49*12256Stut 	{
50*12256Stut 		if (argv[i][1] == 'p')
51*12256Stut 		{
52*12256Stut 			if (i >= argc - 2)
53*12256Stut 			{
54*12256Stut 				puts("Not enough arguments for -p option.");
55*12256Stut 				usage();
56*12256Stut 			}
57*12256Stut 			rd_skel(argv[++i]);
58*12256Stut 		}
59*12256Stut 		else if (argv[i][1] == 'a')
60*12256Stut 		{
61*12256Stut 			if (i >= argc - 1)
62*12256Stut 			{
63*12256Stut 				puts("No bibliofile specified after -a.");
64*12256Stut 				usage();
65*12256Stut 			}
66*12256Stut 			abstract = 0;
67*12256Stut 		}
68*12256Stut 		else  /* neither -p nor -a */
69*12256Stut 		{
70*12256Stut 			printf("Invalid command line flag: %s\n", argv[i]);
71*12256Stut 			usage();
72*12256Stut 		}
73*12256Stut 	}
74*12256Stut 	if (i < argc - 1)
75*12256Stut 	{
76*12256Stut 		puts("Too many arguments with no options.");
77*12256Stut 		usage();
78*12256Stut 	}
79*12256Stut 	if ((fp = fopen(argv[i], "a")) == NULL)
80*12256Stut 	{
81*12256Stut 		perror(argv[i]);
82*12256Stut 		exit(1);
83*12256Stut 	}
84*12256Stut 	addbib(fp, argv[i]);	/* loop for input */
85*12256Stut 	exit(0);
86*12256Stut }
87*12256Stut 
88*12256Stut addbib(fp, argv)	/* add entries to a bibliographic database */
89*12256Stut FILE *fp;
90*12256Stut char *argv;
91*12256Stut {
92*12256Stut 	char line[BUFSIZ];
93*12256Stut 	int i = 0, firstln, repeat = 0, escape = 0;
94*12256Stut 
95*12256Stut 	printf("Instructions? ");
96*12256Stut 	fgets(line, BUFSIZ, stdin);
97*12256Stut 	if (line[0] == 'y' || line[0] == 'Y')
98*12256Stut 		instruct();
99*12256Stut 	while (1)
100*12256Stut 	{
101*12256Stut 		putchar('\n');
102*12256Stut 		putc('\n', fp);
103*12256Stut 		for (i = 0; i < entries; i++)
104*12256Stut 		{
105*12256Stut 			printf("%s\t", bibskel[i].prompt);
106*12256Stut 			fgets(line, BUFSIZ, stdin);
107*12256Stut 			if (line[0] == '-' && line[1] == '\n')
108*12256Stut 			{
109*12256Stut 				i -= 2;
110*12256Stut 				if (i < -1)
111*12256Stut 				{
112*12256Stut 					printf("Too far back.\n");
113*12256Stut 					i++;
114*12256Stut 				}
115*12256Stut 				continue;
116*12256Stut 			}
117*12256Stut 			else if (line[strlen(line)-2] == '\\')
118*12256Stut 			{
119*12256Stut 				if (line[0] != '\\')
120*12256Stut 				{
121*12256Stut 					line[strlen(line)-2] = '\n';
122*12256Stut 					line[strlen(line)-1] = NULL;
123*12256Stut 					trim(line);
124*12256Stut 					fprintf(fp, "%s %s",
125*12256Stut 						bibskel[i].keylet, line);
126*12256Stut 				}
127*12256Stut 				printf("> ");
128*12256Stut 				again:
129*12256Stut 				fgets(line, BUFSIZ, stdin);
130*12256Stut 				if (line[strlen(line)-2] == '\\')
131*12256Stut 				{
132*12256Stut 					line[strlen(line)-2] = '\n';
133*12256Stut 					line[strlen(line)-1] = NULL;
134*12256Stut 					trim(line);
135*12256Stut 					fputs(line, fp);
136*12256Stut 					printf("> ");
137*12256Stut 					goto again;
138*12256Stut 				}
139*12256Stut 				trim(line);
140*12256Stut 				fputs(line, fp);
141*12256Stut 			}
142*12256Stut 			else if (line[0] != '\n')
143*12256Stut 			{
144*12256Stut 				trim(line);
145*12256Stut 				fprintf(fp, "%s %s", bibskel[i].keylet, line);
146*12256Stut 			}
147*12256Stut 		}
148*12256Stut 		if (abstract)
149*12256Stut 		{
150*12256Stut 			puts(" Abstract: (ctrl-d to end)");
151*12256Stut 			firstln = 1;
152*12256Stut 			while (fgets(line, BUFSIZ, stdin))
153*12256Stut 			{
154*12256Stut 				if (firstln && line[0] != '%')
155*12256Stut 				{
156*12256Stut 					fprintf(fp, "%%X ");
157*12256Stut 					firstln = 0;
158*12256Stut 				}
159*12256Stut 				fputs(line, fp);
160*12256Stut 			}
161*12256Stut 		}
162*12256Stut 		fflush(fp);	/* write to file at end of each cycle */
163*12256Stut 		if (ferror(fp))
164*12256Stut 		{
165*12256Stut 			perror(argv);
166*12256Stut 			exit(1);
167*12256Stut 		}
168*12256Stut 		editloop:
169*12256Stut 		printf("\nContinue? ");
170*12256Stut 			fgets(line, BUFSIZ, stdin);
171*12256Stut 		if (line[0] == 'e' || line[0] == 'v')
172*12256Stut 		{
173*12256Stut 			bibedit(fp, line, argv);
174*12256Stut 			goto editloop;
175*12256Stut 		}
176*12256Stut 		if (line[0] == 'q' || line[0] == 'n')
177*12256Stut 			return;
178*12256Stut 	}
179*12256Stut }
180*12256Stut 
181*12256Stut trim(line)		/* trim line of trailing white space */
182*12256Stut char line[];
183*12256Stut {
184*12256Stut 	int n;
185*12256Stut 
186*12256Stut 	n = strlen(line);
187*12256Stut 	while (--n >= 0)
188*12256Stut 	{
189*12256Stut 		if (!isspace(line[n]))
190*12256Stut 			break;
191*12256Stut 	}
192*12256Stut 	line[++n] = '\n';
193*12256Stut 	line[++n] = NULL;
194*12256Stut }
195*12256Stut 
196*12256Stut bibedit(fp, cmd, arg)	/* edit database with edit, ex, or vi */
197*12256Stut FILE *fp;
198*12256Stut char *cmd, *arg;
199*12256Stut {
200*12256Stut 	int i = 0, status;
201*12256Stut 
202*12256Stut 	fclose(fp);
203*12256Stut 	while (!isspace(cmd[i]))
204*12256Stut 		i++;
205*12256Stut 	cmd[i] = NULL;
206*12256Stut 	if (fork() == 0)
207*12256Stut 	{
208*12256Stut 		if (cmd[0] == 'v' && cmd[1] == 'i')
209*12256Stut 			execlp(cmd, cmd, "+$", arg, NULL);
210*12256Stut 		else /* either ed, ex, or edit */
211*12256Stut 			execlp(cmd, cmd, arg, NULL);
212*12256Stut 	}
213*12256Stut 	signal(SIGINT, SIG_IGN);
214*12256Stut 	signal(SIGQUIT, SIG_IGN);
215*12256Stut 	wait(&status);
216*12256Stut 	signal(SIGINT, SIG_DFL);
217*12256Stut 	signal(SIGQUIT, SIG_DFL);
218*12256Stut 	if ((fp = fopen(arg, "a")) == NULL)
219*12256Stut 	{
220*12256Stut 		perror(arg);
221*12256Stut 		exit(1);
222*12256Stut 	}
223*12256Stut }
224*12256Stut 
225*12256Stut instruct()		/* give user elementary directions */
226*12256Stut {
227*12256Stut 	putchar('\n');
228*12256Stut 	puts("Addbib will prompt you for various bibliographic fields.");
229*12256Stut 	puts("If you don't need a particular field, just hit RETURN,");
230*12256Stut 	puts("\tand that field will not appear in the output file.");
231*12256Stut 	puts("If you want to return to previous fields in the skeleton,");
232*12256Stut 	puts("\ta single minus sign will go back a field at a time.");
233*12256Stut 	puts("\t(This is the best way to input multiple authors.)");
234*12256Stut 	puts("If you have to continue a field or add an unusual field,");
235*12256Stut 	puts("\ta trailing backslash will allow a temporary escape.");
236*12256Stut 	puts("Finally, (without -a) you will be prompted for an abstract.");
237*12256Stut 	puts("Type in as many lines as you need, and end with a ctrl-d.");
238*12256Stut 	puts("To quit, type `q' or `n' when asked if you want to continue.");
239*12256Stut 	puts("To edit the database, type `edit', `vi', or `ex' instead.");
240*12256Stut }
241*12256Stut 
242*12256Stut rd_skel(arg)		/* redo bibskel from user-supplied file */
243*12256Stut char *arg;
244*12256Stut {
245*12256Stut 	FILE *pfp, *fopen();
246*12256Stut 	char str[BUFSIZ];
247*12256Stut 	int entry, i, j;
248*12256Stut 
249*12256Stut 	if ((pfp = fopen(arg, "r")) == NULL)
250*12256Stut 	{
251*12256Stut 		fprintf(stderr, "Promptfile ");
252*12256Stut 		perror(arg);
253*12256Stut 		exit(1);
254*12256Stut 	}
255*12256Stut 	for (entry = 0; fgets(str, BUFSIZ, pfp); entry++)
256*12256Stut 	{
257*12256Stut 		for (i = 0; str[i] != '\t' && str[i] != '\n'; i++)
258*12256Stut 			bibskel[entry].prompt[i] = str[i];
259*12256Stut 		bibskel[entry].prompt[i] = NULL;
260*12256Stut 		if (str[i] == '\n')
261*12256Stut 		{
262*12256Stut 			fprintf(stderr, "No tabs between promptfile fields.\n");
263*12256Stut 			fprintf(stderr, "Format: prompt-string <TAB> %%key\n");
264*12256Stut 			exit(1);
265*12256Stut 		}
266*12256Stut 		for (i++, j = 0; str[i] != '\n'; i++, j++)
267*12256Stut 			bibskel[entry].keylet[j] = str[i];
268*12256Stut 		bibskel[entry].keylet[j] = NULL;
269*12256Stut 
270*12256Stut 		if (entry >= MAXENT)
271*12256Stut 		{
272*12256Stut 			fprintf(stderr, "Too many entries in promptfile.\n");
273*12256Stut 			exit(1);
274*12256Stut 		}
275*12256Stut 	}
276*12256Stut 	entries = entry;
277*12256Stut 	fclose(pfp);
278*12256Stut }
279