Commit | Line | Data |
---|---|---|
363b9db8 | 1 | #ifndef lint |
95f51977 | 2 | static 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 | ||
10 | struct 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 | ||
25 | int entries = 10; /* total number of entries in bibskel */ | |
26 | int abstract = 1; /* asking for abstracts is the default */ | |
27 | ||
28 | usage() /* 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 | ||
36 | main(argc, argv) /* addbib: bibliography entry program */ | |
37 | int argc; | |
38 | char *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 | ||
88 | addbib(fp, argv) /* add entries to a bibliographic database */ | |
89 | FILE *fp; | |
90 | char *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 | ||
186 | trim(line) /* trim line of trailing white space */ | |
187 | char 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 | ||
201 | bibedit(fp, cmd, arg) /* edit database with edit, ex, or vi */ | |
202 | FILE *fp; | |
203 | char *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 | ||
230 | instruct() /* 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 | ||
247 | rd_skel(arg) /* redo bibskel from user-supplied file */ | |
248 | char *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 | } |