1 /******************************************************************************
2 
3  #    #    ##    #    #  ######  #    #  ######  #       #####            ####
4  ##  ##   #  #   #   #   #       #    #  #       #       #    #          #    #
5  # ## #  #    #  ####    #####   ######  #####   #       #    #          #
6  #    #  ######  #  #    #       #    #  #       #       #####    ###    #
7  #    #  #    #  #   #   #       #    #  #       #       #        ###    #    #
8  #    #  #    #  #    #  ######  #    #  ######  ######  #        ###     ####
9 
10 POSTSCRIPT VERSION
11 
12 ******************************************************************************/
13 /* This file is part of MAPMAKER 3.0b, Copyright 1987-1992, Whitehead Institute
14    for Biomedical Research. All rights reserved. See READ.ME for license. */
15 
16 /* Makes help files (.code and .help) from a template. This is a
17    quick-and-dirty program with lots of globals and other ickiness. Sorry. */
18 
19 /* The syntax of the input file is as follows in this example:
20 
21    @title MY MANUAL
22    @topic Some Commands
23    $Here is a summary of these commands
24 
25    @cmd do this (dt) 	name needs to be uniquely parsable by shell, options
26 			are  @cmd, @opt, @param, @info, @topic, or @end
27    $one line text
28    <1 			<n UPTO n args; =n EXACTLY n args; >n at least n args
29    %<arg1> <arg2>
30    ^default1 default2	default values
31 
32    Text describing command - one blank line is REQUIRED?
33 
34    @cmd next command
35    # comment line ignored
36 
37    !system output
38    !more system output
39    ...
40 
41    @end
42 */
43 
44 #define INC_LIB
45 #define INC_SHELL   /* for various definitions */
46 #include "system.h"
47 
48 typedef char STRING[MAXLINE+1];
49 
50 /*** stuff for PostScript formatted manual ***/
51 #define FONT_SIZE   10
52 #define LEFT_MARGIN 80   /* 1.12 inch */
53 #define TOP_MARGIN  62   /* = page ht - margin  - font size*PAGE_LINES */
54 #define FOOT_MARGIN 50
55 /*********************************************/
56 
57 #ifndef _TEXT_MANUAL
58 #define PAGE_LINES  68   /* NOT including FOOTER */
59 #define FOOTER "%-30s    %20s                    Page %s\n"
60 #define MAN_TAB 36
61 #else
62 #define PAGE_LINES  60
63 #define FOOTER "    %-30s %20s              Page %s\n"
64 #define MAN_TAB "    "
65 #endif
66 
67 #define PAGE_NUM "%d"
68 /*1234567890123456789012345678901234567*9012345678901234567890123456789012345*/
69 /*    MAPMAKER/EXP V3.0 Manual  12345678901234567890 Commands  ------Page xx*/
70 #define CONTENTS_LEFT    70
71 
72 #ifdef _SYS_DOS
73 #define LINE_BREAK_LEN   2l  /* nl or cr-nl, change for DOS */
74 #else
75 #define LINE_BREAK_LEN   1l
76 #endif
77 
78 #define SPACE "    "
79 #define HLP_TAB "    "
80 
81 
82 /**** other defs ****/
83 
84 FILE *file=NULL, *code=NULL, *hlp=NULL;
85 STRING file_name, code_name, hlp_name, final_hlp_name, code_failed;
86 long pos;
87 int num_args, prefix, topic;
88 char **entry;
89 int entry_type[MAX_COMMANDS+1];
90 STRING cmd_description[MAX_COMMANDS+1];
91 STRING str, type, name, arguments, defaults, description, title;
92 STRING abbreviation, sequence, results, section[MAX_COM_TOPICS];
93 long position[MAX_COM_TOPICS];
94 
95 void nextstr(), parse_error(), parse_entry(), close_files();
96 void write_mkhelp(), write_topics_and_end();
97 
98 void ps_file_start(), ps_file_end(), ps_page_start(), ps_page_end();
99 char *ps_string();
100 
101 /**** defs for man_stuff ****/
102 int lines, page=0, start_page=0, ps_page=0;
103 int entries, pending, entry_page[MAX_COMMANDS+1];
104 FILE *man=NULL;
105 STRING save, man_name, chapter_title;
106 #define make_man (!nullstr(man_name))
107 
108 void man_write_line(), man_write_done(), man_new_entry(), man_new_page();
109 void man_new_topic(),  man_write_contents(), man_write_title();
110 
111 
nextstr()112 void nextstr()
113 {
114     do finput(file,str,MAXLINE); /* crunches */
115     while (str[0]=='#');
116 }
117 
118 
parse_error(msg,punt)119 void parse_error(msg,punt)
120 char *msg;
121 int punt; /* 0= no, 1= this-entry, 2= entirely */
122 {
123     sf(ps,"%s  ",msg); pr();
124     if (punt>0) do nextstr(); while (str[0]!='@');
125     if (punt==2) send(QUIT);
126 }
127 
128 
close_files(name)129 void close_files(name)
130 char *name;
131 {
132     close_file(file);
133 
134     fwrite(hlp,WRS("@end\n"));
135     close_file(hlp);
136 
137     write_topics_and_end();
138     close_file(code);
139 
140     man_write_contents();
141 
142 #ifndef _TEXT_MANUAL
143     /* POSTSCRIPT postscript */
144     ps_page_end(man);
145     ps_file_end(man);
146 #endif
147 
148     close_file(man);
149 
150     sf(ps,"%s done\n",name); pr();
151 }
152 
153 
main(argc,argv)154 int main(argc,argv)
155 int argc;
156 char *argv[];
157 {
158     int i, j;
159 
160     lib_init();
161 
162     if (argc!=5) {
163 	sf(ps,"usage: %s source code help doc dir\n",argv[0]);
164 	fprint(stderr,ps);
165 	abnormal_exit();
166     }
167 
168     run {
169 	strcpy(file_name,argv[1]);
170 	strcpy(code_name,argv[2]);
171 	strcpy(hlp_name, argv[3]);
172 	strcpy(man_name, argv[4]);
173 
174 	strcpy(code_failed,code_name);
175 	make_filename(code_failed,FORCE_EXTENSION,WRS("failed"));
176 	strcpy(final_hlp_name,hlp_name);
177 	make_filename_in_dir(final_hlp_name,FORCE_EXTENSION,WRS("help"),
178 			     FORCE_DIR,argv[5]);
179 
180 	file= open_file(file_name,READ);
181 	code= open_file(code_name,WRITE);
182 	hlp=  open_file(hlp_name, WRITE);
183 	man=  open_file(man_name,WRITE);
184 
185 	topic= 0;
186 	entries= 0;
187 	matrix(entry,MAX_COMMANDS,MAXLINE+1,char);
188 
189 	/* start help file 12345678901234567890123456789012345 */
190 	fwrite(hlp,WRS("#MAPMAKER help file - do not edit!\n"));
191 	pos= 34l + LINE_BREAK_LEN;
192 
193 	/* code file */
194 	fwrite(code,WRS("/* MAPMAKER help code file - do not edit! */ \n\n"));
195 	fwrite(code,WRS("#define INC_LIB \n#define INC_SHELL \n"));
196 	fwrite(code,WRS("#include \"system.h\" \n\n"));
197 	/* sf(ps,"char help_filename[]= \"%s\";\n\n",final_hlp_name);
198 	   fwrite(code,ps); */
199 	fwrite(code,WRS("void make_help_entries()\n{\n"));
200 
201 	/* man file */
202 	man_write_title();
203 
204 	/* get title */
205 	while (nullstr(str)) nextstr();
206 	if (str[0]!='@' || sscanf(str+1,"%s",type)!=1 || !streq(type,"title"))
207 	  parse_error("need to start with a title",2);
208 	i=0; while (str[i++]!=' ') {}
209 	strcpy(title,str+i);
210 
211 	/* get starting page# */
212 	do nextstr(); while (nullstr(str));
213 	if (str[0]!='@' || sscanf(str+1,"%s %d",type,&start_page)!=2 ||
214 	    !streq(type,"page"))
215 	  parse_error("need a page number",2);
216 
217 	nextstr();
218 	while (TRUE) {
219 	    while (nullstr(str)) nextstr();
220 
221 	    if (str[0]!='@' || sscanf(str+1,"%s",type)!=1) {
222 		sf(ps,"error:  bad header:%s\n",str); pr();
223 		close_files(argv[0]);
224 		return(1);
225 	    } else if (streq(type,"end")) {
226 		close_files(argv[0]);
227 		return(0);
228 	    } else if (topic==0 && !streq(type,"topic"))
229 	        parse_error("need to start with a topic",2);
230 
231 	    i=0; while (str[i++]!=' ') {}
232 	    j=i; while (str[j]!='(' && str[j]!='\0') j++;
233 	    if (str[j]=='(') {
234 		str[j]='\0';
235 		if (sscanf(str+j+1,"%s",abbreviation)!=1 ||
236 		    len(abbreviation)>4 ||
237 		    abbreviation[len(abbreviation)-1]!=')')
238 		  parse_error("bad abbreviation",1);
239 		else abbreviation[len(abbreviation)-1]='\0'; /* end ')' */
240 	    } else abbreviation[0]='\0';
241 
242 	    strcpy(name,str+i); despace(name);
243 	    nextstr();
244 	    sf(ps,"\t%s...  ",name); pr(); flush();
245 
246 	    if      (streq(type,"cmd"))   parse_entry(CMD,name,abbreviation);
247 	    else if (streq(type,"opt"))   parse_entry(OPT,name,abbreviation);
248 	    else if (streq(type,"param")) parse_entry(PAR,name,abbreviation);
249 	    else if (streq(type,"info"))  parse_entry(HLP,name,abbreviation);
250 	    else if (streq(type,"topic")) parse_entry(TOP,name,abbreviation);
251 	    else 	     		  parse_error("unknown type",1);
252 	    nl();
253 	}
254 
255     } on_exit {
256 	if (msg==ENDOFILE) print("error:  unexpected end of file\n");
257 	else print("error: makehelp failed");
258 	close_files(argv[0]);
259 	rename_file(code_name,code_failed);
260 	return(1);
261     }
262     return(1); /* not reached */
263 }
264 
265 
parse_entry(kind,name,abbrev)266 void parse_entry(kind,name,abbrev)
267 int kind;
268 char *name, *abbrev;
269 {
270     bool rest=FALSE, need_break;
271     int i;
272     STRING line, key;
273 
274     /* get stuff for cmd/opt */
275     description[0]= arguments[0]= defaults[0]= '\0';
276     num_args=-1; prefix=0;
277 
278     while (!rest) {
279 	switch(str[0]) {
280 
281 	    case '@':
282 	      rest=TRUE; break; /* the while loop */
283 
284 	    case '$': 		/* $ - one line description */
285 	      if (len(str+1)>MAX_COM_HELP_LEN)
286 	        parse_error("description too long",0);
287 	      nstrcpy(description,str+1,MAX_COM_HELP_LEN);
288 	      nextstr(); break;
289 
290 	    case '<':       /* <,=,> */
291 	    case '=':
292 	    case '>':
293 	      if (white(str[1]) || sscanf(str+1,"%d",&num_args)!=1 ||
294 		  num_args>9 || num_args<0) parse_error("bad digit",0);
295 	      else {
296 		  if (str[0]=='<') prefix= UPTO;
297 		  else if (str[0]=='=') prefix= EXACTLY;
298 		  else if (str[0]=='<') prefix= ATLEAST;
299 		  for (i=2; str[i]!='\0'; i++) if (!white(str[i])) break;
300 		  if (len(str+i)>MAX_ARG_HELP_LEN)
301 		    parse_error("arguments too long",0);
302 		  else strcpy(arguments,str+i);
303 	      }
304 	      nextstr(); break;
305 
306 	    case '%':  		/* % - defaults */
307 	      if (len(str+1)>MAX_ARG_HELP_LEN)
308 	        parse_error("defaults too long",0);
309 	      strcpy(defaults,str+1);
310 	      nextstr(); break;
311 
312 #ifdef UNUSED_THIS
313 	    case '&': 		/* & - sequence */
314 	      if (len(str+1)>MAX_ARG_HELP_LEN)
315 	        parse_error("sequence too long",0);
316 	      strcpy(sequence,str+1);
317 	      nextstr(); break;
318 #endif
319 	    case '*': 		/* * - results */
320 	      if (len(str+1)>MAX_ARG_HELP_LEN)
321 	        parse_error("results too long",0);
322 	      strcpy(results,str+1);
323 	      nextstr(); break;
324 
325 	    case '#': 		/* # comment - ignore */
326 	      nextstr(); break;
327 
328 	    default:
329 	      rest=TRUE; break;
330 	  }
331     }
332     /* now rest=TRUE, meaning there is more text */
333     while (nullstr(str)) nextstr();
334     if (str[0]=='@') { parse_error("null help text",0); rest=FALSE; }
335     strcpy(key,name); crunch(key);
336 
337     /* check for bogasity - WANT MORE? */
338     if (num_args>0  &&  nullstr(arguments)) parse_error("no args text",0);
339     if (num_args==0 && !nullstr(arguments)) parse_error("extra args text",0);
340     if (num_args==0 && !nullstr(defaults)) parse_error("extra default text",0);
341     if (kind==TOP && (!nullstr(arguments) || !nullstr(defaults) ||
342 		      !nullstr(results) || !nullstr(sequence) || num_args>0))
343       parse_error("improper entries for topic",0);
344     if (nullstr(description)) parse_error("no description",0);
345 
346     /* save info and write help file key */
347     strcpy(entry[entries],name);
348     entry_type[entries]=kind;
349 
350     if (kind==TOP) {
351 	sf(ps,"%cTOPIC %s\n",'@',key); fwrite(hlp,ps);
352 	pos+= (long)(len(name)+1+6)+LINE_BREAK_LEN; /* after writing above! */
353 	topic++; strcpy(section[topic],description); position[topic]=pos;
354     } else {
355 	/* write code, doc file entries */
356 	sf(ps,"%c%s\n",'@',key); fwrite(hlp,ps);
357 	pos+= (long)(len(name)+1)+LINE_BREAK_LEN; /* after writing above! */
358 	write_mkhelp(key,abbrev,pos,prefix,num_args,description,arguments,
359 		     defaults,topic,kind);
360 	strcpy(cmd_description[entries],description);
361     }
362     if (kind==TOP) man_new_topic(name,description,str[0]!='@');
363       else man_new_entry(kind,name,str[0]!='@');
364 
365     /* write long text, if any */
366     if (rest)
367       while (str[0]!='@') {
368 	  if (str[0]=='!') sprintf(line,"%s%s",HLP_TAB,str+1);
369 	    else if (str[0]=='^') { strcpy(line,str+1); uppercase(line); }
370 	    else strcpy(line,str);
371 	  nextstr();
372 	  if (!(nullstr(line) && str[0]=='@')) { /* punt last line if blank */
373 	      fwrite(hlp,line); fnl(hlp);
374 	      pos+= (long)len(line) + LINE_BREAK_LEN;
375 	      man_write_line(line);
376 	  }
377       }
378     man_write_done();
379     entries++;
380 }
381 
382 
write_mkhelp(cmd,abbrev,pos,prefix,num_args,desc,args,defs,topic,kind)383 void write_mkhelp(cmd,abbrev,pos,prefix,num_args,desc,args,defs,topic,kind)
384 char *cmd, *abbrev;
385 long pos;
386 int prefix, num_args;
387 char *desc, *args, *defs;
388 int topic, kind;
389 {
390     STRING temp;
391 
392     switch (kind) {
393 	case TOP: strcpy(temp,"TOP"); break;
394 	case CMD: strcpy(temp,"CMD"); break;
395 	case OPT: strcpy(temp,"OPT"); break;
396 	case PAR: strcpy(temp,"PAR"); break;
397 	case HLP: strcpy(temp,"HLP"); break;
398     }
399     sf(ps," mkhelp(\"%s\",\"%s\",%ldl,%s,%d,%s,%d,\n",
400        cmd,abbrev,pos,
401        (prefix==EXACTLY ? "EXACTLY":(prefix==UPTO ? "UPTO":"ATLEAST")),
402        num_args,temp,topic); fpr(code);
403     sf(ps,"        \"%s\",\n", desc); fpr(code);
404     sf(ps,"        \"%s\",\n", args); fpr(code);
405     sf(ps,"        \"%s\");\n",defs); fpr(code);
406     /* need to add sequence, results, etc */
407 }
408 
409 
write_topics_and_end()410 void write_topics_and_end()
411 {
412     int i, s, k;
413     STRING temp;
414     if (!make_man) return;
415 
416     fnl(code);
417     for (i=0, s=1; i<entries; i++) if (entry_type[i]==TOP) {
418 	strcpy(temp,section[s]); /* uppercase(temp); */
419 	sf(ps," mktopic(%d,\"%s\",TOP,%ldl);\n",s,temp,position[s]);
420 	fpr(code); s++;
421     }
422     fprint(code,WRS("}\n"));
423 }
424 
425 
426 
427 /*****************************************************************************/
428 
429 
man_new_page()430 void man_new_page()
431 {
432     STRING p, temp, foot;
433     if (!make_man) return;
434 
435 #ifndef _TEXT_MANUAL
436     /******* POSTSCRIPT VERSION *******/
437     if (page==0)
438       { page=start_page; lines=PAGE_LINES;
439 	ps_page=1; ps_page_start(man,ps_page); return; }
440 
441     sf(p,PAGE_NUM,abs(page)); if (page>0) page++; else page--;
442     ps_page++;
443     sf(temp,"%s",title);
444     sf(foot,FOOTER,temp,chapter_title,p);
445 
446     fprintf(man,"GS %d %d moveto /Courier FF 9 SF F (%s)S GR\n",
447 	    LEFT_MARGIN,FOOT_MARGIN,foot);
448     lines=PAGE_LINES;
449 
450     ps_page_end(man);
451 
452     ps_page_start(man,ps_page);
453 
454 #else
455     /********** ASCII VERSION *********/
456     if (page==0)
457       { fprintf(man,"\n"); page=start_page; lines=PAGE_LINES; return; }
458 
459     while (lines>0) { fprintf(man,"\n"); lines--; }
460     sf(p,PAGE_NUM,abs(page)); if (page>0) page++; else page--;
461     fprintf(man,"\n\n\n");
462     sprintf(temp,"%s",title);
463     fprintf(man,FOOTER,temp,chapter_title,p);
464     lines= PAGE_LINES;
465     fprintf(man,"\n");
466 #endif
467 
468 }
469 
470 
man_write_line(line)471 void man_write_line(line)
472 char *line;
473 {
474     if (!make_man) return;
475 
476 #ifndef _TEXT_MANUAL
477     /******** POSTSCRIPT VERSION ********/
478     if (pending) {
479         if (lines <= 1) man_new_page();
480 	if (save[0]=='!') {
481 	  fprintf(man,"GS %d %d moveto /Courier FF 10 SF F (%s)S GR\n",
482 		  LEFT_MARGIN+MAN_TAB, (lines*FONT_SIZE)+TOP_MARGIN,
483 		  ps_string(save+1));
484         } else {
485 	  fprintf(man,"GS %d %d moveto /Courier FF 10 SF F (%s)S GR\n",
486 		  LEFT_MARGIN, (lines*FONT_SIZE)+TOP_MARGIN, ps_string(save));
487 	}
488 	lines--;
489     }
490 #else
491     /********** ASCII VERSION **********/
492     if (pending) {
493 	if (lines<=1) man_new_page();
494 	fprintf(man,SPACE);
495 	if (save[0]=='!') { fprintf(man,MAN_TAB); fprintf(man,save+1); }
496 	else fprintf(man,save);
497 	fprintf(man,"\n"); lines--;
498     }
499 #endif
500 
501     strcpy(save,line); pending=TRUE;
502 }
503 
504 
man_write_done()505 void man_write_done()
506 {
507     if (!make_man) return;
508 
509 #ifndef _TEXT_MANUAL
510     /******** POSTSCRIPT VERSION ********/
511     if (save[0]=='!') {
512         fprintf(man,"GS %d %d moveto /Courier FF 10 SF F (%s)S GR\n",
513 		LEFT_MARGIN+MAN_TAB, (lines*FONT_SIZE)+TOP_MARGIN,
514 		ps_string(save+1));
515     } else {
516         fprintf(man,"GS %d %d moveto /Courier FF 10 SF F (%s)S GR\n",
517 		LEFT_MARGIN, (lines*FONT_SIZE)+TOP_MARGIN, ps_string(save));
518     }
519     lines--; pending=FALSE;
520 
521 #else
522     /********** ASCII VERSION **********/
523     fprintf(man,SPACE);
524     if (save[0]=='!') { fprintf(man,MAN_TAB); fprintf(man,save+1); }
525     else fprintf(man,save);
526     fprintf(man,"\n"); lines--;
527     pending=FALSE;
528 #endif
529 
530 }
531 
532 
man_new_entry(kind,name,has_description)533 void man_new_entry(kind,name,has_description) /* only CMD or OPT */
534 int kind;
535 char *name;
536 bool has_description;
537 {
538     STRING temp0, temp1, temp2, templine;
539     int n= num_args; /* -1 => plural */
540     int need=5;  /* name + space + args + defs + (space or no_desc line) */
541     bool blank=FALSE;
542     if (!make_man) return;
543 
544     if (n>0 && !nullstr(arguments) && !nullstr(defaults)) need++;
545     if (has_description) need+=2;
546     if (lines!=PAGE_LINES) need+=3; /* if not 1st on page */
547 
548     if (need>lines) { man_new_page(); }
549     else {
550       lines-=3;
551 #ifdef _TEXT_MANUAL
552       fprintf(man,"\n\n\n");
553 #endif
554     }
555     entry_page[entries]= page;
556 
557     if (kind==CMD) strcpy(temp1,"Command");
558     else if (kind==OPT) strcpy(temp1,"Option");
559     else if (kind==PAR) strcpy(temp1,"Parameter");
560     else if (kind==HLP) strcpy(temp1,"Information");
561     else strcpy(temp1,"???");
562     strcpy(temp0,name); uppercase(temp0);
563     if (nullstr(abbreviation)) temp2[0]='\0';
564     else sf(temp2," (abbreviation '%s')",abbreviation);
565 
566 #ifndef _TEXT_MANUAL
567     sf(templine,"%s %s%s",temp0,temp1,temp2);
568     fprintf(man,"GS %d %d moveto /Courier-Bold FF 10 SF F (%s)S GR\n",
569 	    LEFT_MARGIN,(lines*FONT_SIZE)+TOP_MARGIN,ps_string(templine));
570     fprintf(man,"GS .5 LW %d %d moveto /Courier-Bold FF 10 SF F (%s)US GR\n",
571 	    LEFT_MARGIN,(lines*FONT_SIZE)+TOP_MARGIN-1,ps_string(templine));
572     lines-=2;
573 
574     if (!nullstr(description)) {
575         sf(templine,"Summary:     %s",description);
576         fprintf(man,"GS %d %d moveto /Courier FF 10 SF F (%s)S GR\n",
577 		LEFT_MARGIN,(lines*FONT_SIZE)+TOP_MARGIN,
578 		ps_string(templine));
579 	lines--;
580 	blank=TRUE;
581     }
582 
583     if (n==0) {
584         fprintf(man,"GS %d %d moveto /Courier FF 10 SF F (%s)S GR\n",
585 		LEFT_MARGIN,(lines*FONT_SIZE)+TOP_MARGIN,"No Arguments");
586 	lines--; blank=TRUE;
587     }
588     else if (!nullstr(arguments)) {
589         sf(templine,"Argument%s:%s   %s",maybe_s(n),maybe_sp(n),arguments);
590 	fprintf(man,"GS %d %d moveto /Courier FF 10 SF F (%s)S GR\n",
591 		LEFT_MARGIN,(lines*FONT_SIZE)+TOP_MARGIN,ps_string(templine));
592 	lines--;
593 	blank=TRUE;
594 
595 	if (!nullstr(defaults)) {
596 	  sf(templine,"Default%s:%s    %s",maybe_s(n),maybe_sp(n),defaults);
597 	  fprintf(man,"GS %d %d moveto /Courier FF 10 SF F (%s)S GR\n",
598 		  LEFT_MARGIN,(lines*FONT_SIZE)+TOP_MARGIN,
599 		  ps_string(templine));
600 	  lines--;
601 	}
602     }
603     if (blank) lines--;
604 
605 #else
606     fprintf(man,"%s%s %s%s\n",SPACE,temp0,temp1,temp2); lines-=1;
607     fprintf(man,"\n",temp0); lines-=1;
608 
609     if (!nullstr(description)) {
610 	fprintf(man,"%sDescription: %s\n",SPACE,description); lines--;
611 	blank=TRUE;
612     }
613 
614     if (n==0) { fprintf(man,"%sNo Arguments\n",SPACE); lines--; blank=TRUE; }
615     else if (!nullstr(arguments)) {
616 	fprintf(man,"%sArgument%s:%s   %s\n",SPACE,maybe_s(n),maybe_sp(n),
617 	       arguments); lines--;
618 	blank=TRUE;
619 	if (!nullstr(defaults)) {
620 	    fprintf(man,"%sDefault%s:%s    %s\n",SPACE,maybe_s(n),maybe_sp(n),
621 		   defaults); lines--;
622 	}
623     }
624     if (blank) { fprintf(man,"\n"); lines--; }
625 #endif
626 
627 }
628 
629 
man_new_topic(name,description,has_description)630 void man_new_topic(name,description,has_description)
631 char *name;
632 char *description;
633 bool has_description;
634 {
635     STRING upcase,templine;
636 
637     if (!make_man) return;
638 
639     man_new_page();
640     strcpy(chapter_title,name);
641     entry_page[entries]= page;
642 
643     strcpy(upcase,description); uppercase(upcase);
644 
645 #ifndef _TEXT_MANUAL
646     sf(templine,"(%d) %s",topic,upcase);
647     fprintf(man,"GS %d %d moveto /Courier-Bold FF 10 SF F (%s)S GR\n",
648 	    LEFT_MARGIN,(lines*FONT_SIZE)+TOP_MARGIN,ps_string(templine));
649     fprintf(man,"GS .5 LW %d %d moveto /Courier-Bold FF 10 SF F (%s)US GR\n",
650 	    LEFT_MARGIN,(lines*FONT_SIZE)+TOP_MARGIN-1,ps_string(templine));
651     lines--;
652     if (has_description) { lines--; }
653 #else
654     fprintf(man,"%s(%d) %s\n",SPACE,topic,upcase); lines--;
655     if (has_description) { fprintf(man,"\n"); lines--; }
656 #endif
657 }
658 
659 
man_write_contents()660 void man_write_contents()
661 {
662     int i, s, k;
663     STRING temp, upcase, templine;
664     if (!make_man) return;
665 
666     man_new_page();
667     strcpy(upcase,title); uppercase(upcase);
668 
669 #ifndef _TEXT_MANUAL
670     sf(templine,"%s COMMAND REFERENCE:",upcase);
671     fprintf(man,"GS %d %d moveto /Courier-Bold FF 10 SF F (%s)S GR\n",
672 	    LEFT_MARGIN,(lines*FONT_SIZE)+TOP_MARGIN,ps_string(templine));
673 #else
674     fprintf(man,"%s%s COMMAND REFERENCE:\n\n",SPACE,upcase);
675 #endif
676 
677     lines-=2;
678     strcpy(chapter_title,"Command Reference"); page= -2;
679     for (i=0, s=1; i<entries; i++) {
680 	switch(entry_type[i]) {
681 	    case TOP:
682 	      man_write_line("");
683 	      strcpy(upcase,section[s]); uppercase(upcase);
684 	      sf(temp," %s(%d) %s ",(s>=10 ? "":" "),s,upcase); s++; break;
685 	    case CMD:
686 	      strcpy(upcase,entry[i]); uppercase(upcase);
687 	      sf(temp,"      %s Command ",upcase); break;
688 	    case OPT:
689 	      strcpy(upcase,entry[i]); uppercase(upcase);
690 	      sf(temp,"      %s Option ",upcase); break;
691 	    case PAR:
692 	      strcpy(upcase,entry[i]); uppercase(upcase);
693 	      sf(temp,"      %s Parameter ",upcase); break;
694 	    case HLP:
695 	      strcpy(upcase,entry[i]); uppercase(upcase);
696 	      sf(temp,"      %s Information ",upcase); break;
697 	}
698 	for (k=len(temp); k<CONTENTS_LEFT; k++) temp[k]='.';
699 	sprintf(temp+k," %d",entry_page[i]);
700 	man_write_line(temp);
701     }
702 
703     man_write_line("");
704     man_new_page();
705     strcpy(upcase,title); uppercase(upcase);
706 
707 #ifndef _TEXT_MANUAL
708     sf(templine,"%s QUICK REFERENCE:",upcase);
709     fprintf(man,"GS %d %d moveto /Courier-Bold FF 10 SF F (%s)S GR\n",
710 	    LEFT_MARGIN,(lines*FONT_SIZE)+TOP_MARGIN,ps_string(templine));
711     lines-=1;
712 #else
713     fprintf(man,"%s%s QUICK REFERENCE:\n\n",SPACE,upcase);
714     lines-=2;
715 #endif
716     strcpy(chapter_title,"Quick Reference");
717     for (i=0, s=1; i<entries; i++) {
718 	if (entry_type[i]==TOP) {
719 	    man_write_line("");
720 	    strcpy(upcase,section[s]); uppercase(upcase);
721 	    sf(temp,"%s(%d) %s ",(s>=10 ? "":""),s,upcase); s++;
722 	    man_write_line(temp);
723 	} else {
724 	    sf(temp,"%s%s",entry[i],(entry_type[i]==HLP ? "*":""));
725 	    for (k=len(temp); k<MAX_COM_NAME_LEN+1; k++) temp[k]='.';
726 	    sprintf(temp+k,"%s",cmd_description[i]);
727 	    man_write_line(temp);
728 	}
729     }
730     man_write_line("");
731     man_write_line("");
732     sf(temp,"* = reference information only - not a command");
733     man_write_line(temp);
734     man_write_line("");
735     man_new_page();
736     man_write_done();
737 }
738 
739 
man_write_title()740 void man_write_title()
741 {
742     if (!make_man) return;
743 
744 #ifndef _TEXT_MANUAL
745     ps_file_start(man);
746 #endif
747 }
748 
749 /********** POSTSCRIPT STUFF **********/
750 
ps_file_start(fp)751 void ps_file_start(fp)
752 FILE *fp;
753 {
754     fprintf(fp,"%%!PS-Adobe-3.0\n");
755     fprintf(fp,"%%%%Creator: MAPMAKER\n");
756     fprintf(fp,"%%%%LanguageLevel: 1\n");
757     fprintf(fp,"%%%%PageOrder: Special\n");
758 
759     fprintf(fp,"%%%%BeginProlog\n");
760     fprintf(fp,"%%%%BeginResource: procset Map_Painter_prolog\n");
761     fprintf(fp,"/Map_Painter_prolog 100 dict def\n");
762     fprintf(fp,"Map_Painter_prolog begin\n");
763     fprintf(fp,"/CF {dup 0 eq\n");
764     fprintf(fp,"       {pop /Times-Bold}\n");
765     fprintf(fp,"       {1 eq {/Times-Roman} {/Times-Italic} ifelse}\n");
766     fprintf(fp,"     ifelse} def\n");
767     fprintf(fp,"/F {setfont} def\n");
768     fprintf(fp,"/FF {findfont} def\n");
769     fprintf(fp,"/GM {restore} def\n");
770     fprintf(fp,"/GR {grestore} def\n");
771     fprintf(fp,"/GS {gsave} def\n");
772     fprintf(fp,"/LC {currentpoint pop dup /l exch def add /r exch def\n");
773     fprintf(fp,"     counttomark 3 idiv {\n");
774     fprintf(fp,"       currentpoint pop r ge {l currentpoint exch pop LLD sub moveto} if\n");
775     fprintf(fp,"       LD\n");
776     fprintf(fp,"     } repeat pop} def\n");
777     fprintf(fp,"/LD {/f exch def /n exch def /p exch def\n");
778     fprintf(fp,"     p length 0 ne {\n");
779     fprintf(fp,"       /Times-Roman findfont LFS 1 sub scalefont setfont p show\n");
780     fprintf(fp,"       2.5 0 rmoveto\n");
781     fprintf(fp,"     } if\n");
782     fprintf(fp,"     f CF findfont LFS scalefont setfont\n");
783     fprintf(fp,"     n show 6 0 rmoveto} def\n");
784     fprintf(fp,"/LM {save} def\n");
785     fprintf(fp,"/LW {setlinewidth} def\n");
786     fprintf(fp,"/S {show} def\n");
787     fprintf(fp,"/SF {scalefont} def\n");
788     fprintf(fp,"/SR {dup stringwidth pop neg 0 rmoveto show} def\n");
789     fprintf(fp,"/TR {translate} def\n");
790     fprintf(fp,"/XY {moveto} def\n");
791     fprintf(fp,"/US {stringwidth pop 0 rlineto stroke} def\n");
792     fprintf(fp,"end\n");
793     fprintf(fp,"%%%%EndResource\n");
794     fprintf(fp,"%%%%EndProlog\n");
795 
796     fprintf(fp,"/LFS 8 def /LLD 7.5 def\n");
797     fprintf(fp,"%%%%BeginSetup\n");
798     fprintf(fp,"Map_Painter_prolog begin\n");
799     fprintf(fp,"gsave\n");
800     fprintf(fp,"%%%%EndSetup\n");
801 }
802 
ps_file_end(fp)803 void ps_file_end(fp)
804 FILE *fp;
805 {
806     fprintf(fp,"%%%%Trailer\n");
807     fprintf(fp,"grestore\n");
808     fprintf(fp,"end %% Map_Painter_prolog\n");
809     fprintf(fp,"%%%%EOF\n");
810 }
811 
ps_page_start(fp,pagenum)812 void ps_page_start(fp,pagenum)
813 FILE *fp;
814 int pagenum;
815 {
816     fprintf(fp,"%%%%Page: ? %d\n",pagenum);
817     fprintf(fp,"%%%%BeginPageSetup\n");
818     fprintf(fp,"LM\n");
819     fprintf(fp,"%%%%EndPageSetup\n");
820 }
821 
ps_page_end(fp)822 void ps_page_end(fp)
823 FILE *fp;
824 {
825     fprintf(fp,"GM showpage\n");
826 }
827 
828 char newstr[MAXLINE];
829 
ps_string(str)830 char *ps_string(str)
831 char *str;
832 {
833     int sl, i, j;
834 
835     sl=strlen(str);
836 
837     for (i=0,j=0; i<sl; i++) {
838       if (str[i]=='(' || str[i]==')' || str[i]==92)
839           newstr[j++] = 92;
840       newstr[j++] = str[i];
841     }
842     newstr[j] = '\0';
843     return(newstr);
844 }
845 
846 
847 
848 
849 
850 
851 
852