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