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