xref: /csrg-svn/old/refer/addbib/addbib.c (revision 48294)
1*48294Sbostic /*-
2*48294Sbostic  * %sccs.include.proprietary.c%
3*48294Sbostic  */
4*48294Sbostic 
512256Stut #ifndef lint
6*48294Sbostic static char sccsid[] = "@(#)addbib.c	4.3 (Berkeley) 04/18/91";
7*48294Sbostic #endif /* not lint */
812256Stut 
912256Stut #include <stdio.h>
1012256Stut #include <ctype.h>
1112256Stut #include <signal.h>
1212256Stut #define MAXENT 50
1312256Stut 
1412256Stut struct skeleton {
1512256Stut 	char prompt[20];	/* prompt user for entry */
1612256Stut 	char keylet[5]; 	/* key letter for database */
1712256Stut } bibskel[MAXENT] = {
1812256Stut 	"   Author:",	"%A",
1912256Stut 	"    Title:",	"%T",
2012256Stut 	"  Journal:",	"%J",
2112256Stut 	"   Volume:", 	"%V",
2212256Stut 	"    Pages:",	"%P",
2312256Stut 	"Publisher:",	"%I",
2412256Stut 	"     City:", 	"%C",
2512256Stut 	"     Date:", 	"%D",
2612256Stut 	"    Other:",	"%O",
2712256Stut 	" Keywords:",	"%K",	};
2812256Stut 
2912256Stut int entries = 10;	/* total number of entries in bibskel */
3012256Stut int abstract = 1;	/* asking for abstracts is the default */
3112256Stut 
usage()3212256Stut usage()			/* print proper usage and exit */
3312256Stut {
3412256Stut 	puts("Usage:  addbib [-p promptfile] [-a] database");
3512256Stut 	puts("\t-p: the promptfile defines alternate fields");
3612256Stut 	puts("\t-a: don't include prompting for the abstract");
3712256Stut 	exit(1);
3812256Stut }
3912256Stut 
main(argc,argv)4012256Stut main(argc, argv)	/* addbib: bibliography entry program */
4112256Stut int argc;
4212256Stut char *argv[];
4312256Stut {
4412256Stut 	FILE *fp, *fopen();
4512256Stut 	int i;
4612256Stut 
4712256Stut 	if (argc == 1)
4812256Stut 	{
4912256Stut 		puts("You must specify a bibliography file (database).");
5012256Stut 		usage();
5112256Stut 	}
5212256Stut 	for (i = 1; argv[i][0] == '-'; i++)
5312256Stut 	{
5412256Stut 		if (argv[i][1] == 'p')
5512256Stut 		{
5612256Stut 			if (i >= argc - 2)
5712256Stut 			{
5812256Stut 				puts("Not enough arguments for -p option.");
5912256Stut 				usage();
6012256Stut 			}
6112256Stut 			rd_skel(argv[++i]);
6212256Stut 		}
6312256Stut 		else if (argv[i][1] == 'a')
6412256Stut 		{
6512256Stut 			if (i >= argc - 1)
6612256Stut 			{
6712256Stut 				puts("No bibliofile specified after -a.");
6812256Stut 				usage();
6912256Stut 			}
7012256Stut 			abstract = 0;
7112256Stut 		}
7212256Stut 		else  /* neither -p nor -a */
7312256Stut 		{
7412256Stut 			printf("Invalid command line flag: %s\n", argv[i]);
7512256Stut 			usage();
7612256Stut 		}
7712256Stut 	}
7812256Stut 	if (i < argc - 1)
7912256Stut 	{
8012256Stut 		puts("Too many arguments with no options.");
8112256Stut 		usage();
8212256Stut 	}
8312256Stut 	if ((fp = fopen(argv[i], "a")) == NULL)
8412256Stut 	{
8512256Stut 		perror(argv[i]);
8612256Stut 		exit(1);
8712256Stut 	}
8812256Stut 	addbib(fp, argv[i]);	/* loop for input */
8912256Stut 	exit(0);
9012256Stut }
9112256Stut 
addbib(fp,argv)9212256Stut addbib(fp, argv)	/* add entries to a bibliographic database */
9312256Stut FILE *fp;
9412256Stut char *argv;
9512256Stut {
9612256Stut 	char line[BUFSIZ];
9712256Stut 	int i = 0, firstln, repeat = 0, escape = 0;
9812256Stut 
9912256Stut 	printf("Instructions? ");
10012256Stut 	fgets(line, BUFSIZ, stdin);
10112256Stut 	if (line[0] == 'y' || line[0] == 'Y')
10212256Stut 		instruct();
10312256Stut 	while (1)
10412256Stut 	{
10512256Stut 		putchar('\n');
10612256Stut 		putc('\n', fp);
10712256Stut 		for (i = 0; i < entries; i++)
10812256Stut 		{
10912256Stut 			printf("%s\t", bibskel[i].prompt);
11017330Sralph 			if (fgets(line, BUFSIZ, stdin) == NULL)
11117330Sralph 			{
11217330Sralph 				clearerr(stdin);
11317330Sralph 				break;
11417330Sralph 			}
11512256Stut 			if (line[0] == '-' && line[1] == '\n')
11612256Stut 			{
11712256Stut 				i -= 2;
11812256Stut 				if (i < -1)
11912256Stut 				{
12012256Stut 					printf("Too far back.\n");
12112256Stut 					i++;
12212256Stut 				}
12312256Stut 				continue;
12412256Stut 			}
12512256Stut 			else if (line[strlen(line)-2] == '\\')
12612256Stut 			{
12712256Stut 				if (line[0] != '\\')
12812256Stut 				{
12912256Stut 					line[strlen(line)-2] = '\n';
13012256Stut 					line[strlen(line)-1] = NULL;
13112256Stut 					trim(line);
13212256Stut 					fprintf(fp, "%s %s",
13312256Stut 						bibskel[i].keylet, line);
13412256Stut 				}
13512256Stut 				printf("> ");
13612256Stut 				again:
13712256Stut 				fgets(line, BUFSIZ, stdin);
13812256Stut 				if (line[strlen(line)-2] == '\\')
13912256Stut 				{
14012256Stut 					line[strlen(line)-2] = '\n';
14112256Stut 					line[strlen(line)-1] = NULL;
14212256Stut 					trim(line);
14312256Stut 					fputs(line, fp);
14412256Stut 					printf("> ");
14512256Stut 					goto again;
14612256Stut 				}
14712256Stut 				trim(line);
14812256Stut 				fputs(line, fp);
14912256Stut 			}
15012256Stut 			else if (line[0] != '\n')
15112256Stut 			{
15212256Stut 				trim(line);
15312256Stut 				fprintf(fp, "%s %s", bibskel[i].keylet, line);
15412256Stut 			}
15512256Stut 		}
15612256Stut 		if (abstract)
15712256Stut 		{
15812256Stut 			puts(" Abstract: (ctrl-d to end)");
15912256Stut 			firstln = 1;
16012256Stut 			while (fgets(line, BUFSIZ, stdin))
16112256Stut 			{
16212256Stut 				if (firstln && line[0] != '%')
16312256Stut 				{
16412256Stut 					fprintf(fp, "%%X ");
16512256Stut 					firstln = 0;
16612256Stut 				}
16712256Stut 				fputs(line, fp);
16812256Stut 			}
16917330Sralph 			clearerr(stdin);
17012256Stut 		}
17112256Stut 		fflush(fp);	/* write to file at end of each cycle */
17212256Stut 		if (ferror(fp))
17312256Stut 		{
17412256Stut 			perror(argv);
17512256Stut 			exit(1);
17612256Stut 		}
17712256Stut 		editloop:
17812256Stut 		printf("\nContinue? ");
17912256Stut 			fgets(line, BUFSIZ, stdin);
18012256Stut 		if (line[0] == 'e' || line[0] == 'v')
18112256Stut 		{
18212256Stut 			bibedit(fp, line, argv);
18312256Stut 			goto editloop;
18412256Stut 		}
18512256Stut 		if (line[0] == 'q' || line[0] == 'n')
18612256Stut 			return;
18712256Stut 	}
18812256Stut }
18912256Stut 
trim(line)19012256Stut trim(line)		/* trim line of trailing white space */
19112256Stut char line[];
19212256Stut {
19312256Stut 	int n;
19412256Stut 
19512256Stut 	n = strlen(line);
19612256Stut 	while (--n >= 0)
19712256Stut 	{
19812256Stut 		if (!isspace(line[n]))
19912256Stut 			break;
20012256Stut 	}
20112256Stut 	line[++n] = '\n';
20212256Stut 	line[++n] = NULL;
20312256Stut }
20412256Stut 
bibedit(fp,cmd,arg)20512256Stut bibedit(fp, cmd, arg)	/* edit database with edit, ex, or vi */
20612256Stut FILE *fp;
20712256Stut char *cmd, *arg;
20812256Stut {
20912256Stut 	int i = 0, status;
21012256Stut 
21112256Stut 	fclose(fp);
21212256Stut 	while (!isspace(cmd[i]))
21312256Stut 		i++;
21412256Stut 	cmd[i] = NULL;
21512256Stut 	if (fork() == 0)
21612256Stut 	{
21712256Stut 		if (cmd[0] == 'v' && cmd[1] == 'i')
21812256Stut 			execlp(cmd, cmd, "+$", arg, NULL);
21912256Stut 		else /* either ed, ex, or edit */
22012256Stut 			execlp(cmd, cmd, arg, NULL);
22112256Stut 	}
22212256Stut 	signal(SIGINT, SIG_IGN);
22312256Stut 	signal(SIGQUIT, SIG_IGN);
22412256Stut 	wait(&status);
22512256Stut 	signal(SIGINT, SIG_DFL);
22612256Stut 	signal(SIGQUIT, SIG_DFL);
22712256Stut 	if ((fp = fopen(arg, "a")) == NULL)
22812256Stut 	{
22912256Stut 		perror(arg);
23012256Stut 		exit(1);
23112256Stut 	}
23212256Stut }
23312256Stut 
instruct()23412256Stut instruct()		/* give user elementary directions */
23512256Stut {
23612256Stut 	putchar('\n');
23712256Stut 	puts("Addbib will prompt you for various bibliographic fields.");
23812256Stut 	puts("If you don't need a particular field, just hit RETURN,");
23912256Stut 	puts("\tand that field will not appear in the output file.");
24012256Stut 	puts("If you want to return to previous fields in the skeleton,");
24112256Stut 	puts("\ta single minus sign will go back a field at a time.");
24212256Stut 	puts("\t(This is the best way to input multiple authors.)");
24312256Stut 	puts("If you have to continue a field or add an unusual field,");
24412256Stut 	puts("\ta trailing backslash will allow a temporary escape.");
24512256Stut 	puts("Finally, (without -a) you will be prompted for an abstract.");
24612256Stut 	puts("Type in as many lines as you need, and end with a ctrl-d.");
24712256Stut 	puts("To quit, type `q' or `n' when asked if you want to continue.");
24812256Stut 	puts("To edit the database, type `edit', `vi', or `ex' instead.");
24912256Stut }
25012256Stut 
rd_skel(arg)25112256Stut rd_skel(arg)		/* redo bibskel from user-supplied file */
25212256Stut char *arg;
25312256Stut {
25412256Stut 	FILE *pfp, *fopen();
25512256Stut 	char str[BUFSIZ];
25612256Stut 	int entry, i, j;
25712256Stut 
25812256Stut 	if ((pfp = fopen(arg, "r")) == NULL)
25912256Stut 	{
26012256Stut 		fprintf(stderr, "Promptfile ");
26112256Stut 		perror(arg);
26212256Stut 		exit(1);
26312256Stut 	}
26412256Stut 	for (entry = 0; fgets(str, BUFSIZ, pfp); entry++)
26512256Stut 	{
26612256Stut 		for (i = 0; str[i] != '\t' && str[i] != '\n'; i++)
26712256Stut 			bibskel[entry].prompt[i] = str[i];
26812256Stut 		bibskel[entry].prompt[i] = NULL;
26912256Stut 		if (str[i] == '\n')
27012256Stut 		{
27112256Stut 			fprintf(stderr, "No tabs between promptfile fields.\n");
27212256Stut 			fprintf(stderr, "Format: prompt-string <TAB> %%key\n");
27312256Stut 			exit(1);
27412256Stut 		}
27512256Stut 		for (i++, j = 0; str[i] != '\n'; i++, j++)
27612256Stut 			bibskel[entry].keylet[j] = str[i];
27712256Stut 		bibskel[entry].keylet[j] = NULL;
27812256Stut 
27912256Stut 		if (entry >= MAXENT)
28012256Stut 		{
28112256Stut 			fprintf(stderr, "Too many entries in promptfile.\n");
28212256Stut 			exit(1);
28312256Stut 		}
28412256Stut 	}
28512256Stut 	entries = entry;
28612256Stut 	fclose(pfp);
28712256Stut }
288