abc2ps.c - abc2ps - A powerful sheet setting tool using the simple abc notation
(HTM) git clone git://vernunftzentrum.de/abc2ps.git
(DIR) Log
(DIR) Files
(DIR) Refs
---
abc2ps.c (28538B)
---
1 /*
2 * abc2ps: a program to typeset tunes written in abc format using PostScript
3 * Copyright (C) 1996,1997,1998 Michael Methfessel
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 * The author can be contacted as follows:
20 *
21 * Michael Methfessel
22 * methfessel@ihp-ffo.de
23 * Institute for Semiconductor Physics, PO Box 409,
24 * D-15204 Frankfurt (Oder), Germany
25 */
26
27 /* Main program abc2ps.c */
28 #include <ctype.h>
29 #include <stdio.h>
30 #include <math.h>
31 #include <time.h>
32 #include <string.h>
33 #include <stdlib.h>
34
35 /* -------------- general macros ------------- */
36
37 #define VERSION "1.3" /* version */
38 #define REVISION "3" /* revison */
39 #define VDATE "Mar 17 1999" /* version date */
40 #define VERBOSE0 2 /* default verbosity */
41 #define DEBUG_LV 0 /* debug output level */
42 #define OUTPUTFILE "Out.ps" /* standard output file */
43 #define INDEXFILE "Ind.ps" /* output file for index */
44 #define PS_LEVEL 2 /* PS laguage level: must be 1 or 2 */
45
46 /* default directory to search for format files */
47 #define DEFAULT_FDIR ""
48
49
50 #define PAGEHEIGHT 29.7 /* basic page dimensions in cm .. */
51 #define LEFTMARGIN 1.8 /* .. used in all default formats */
52 #define STAFFWIDTH 17.4
53
54
55 /* ----- macros controlling music typesetting ----- */
56
57 #define BASEWIDTH 0.8 /* width for lines drawn within music */
58 #define SLURWIDTH 0.8 /* width for lines for slurs */
59 #define STEM_YOFF 1.0 /* offset stem from note center */
60 #define STEM_XOFF 3.5
61 #define STEM 20 /* standard stem length */
62 #define STEM_MIN 16 /* min stem length under beams */
63 #define STEM_MIN2 12 /* ... for notes with two beams */
64 #define STEM_MIN3 10 /* ... for notes with three beams */
65 #define STEM_MIN4 10 /* ... for notes with four beams */
66 #define STEM_CH 16 /* standard stem length for chord */
67 #define STEM_CH_MIN 12 /* min stem length for chords under beams */
68 #define STEM_CH_MIN2 8 /* ... for notes with two beams */
69 #define STEM_CH_MIN3 7 /* ... for notes with three beams */
70 #define STEM_CH_MIN4 7 /* ... for notes with four beams */
71 #define BEAM_DEPTH 2.6 /* width of a beam stroke */
72 #define BEAM_OFFSET 0.25 /* pos of flat beam relative to staff line */
73 #define BEAM_SHIFT 5.3 /* shift of second and third beams */
74 /* To align the 4th beam as the 1st: shift=6-(depth-2*offset)/3 */
75 #define BEAM_FLATFAC 0.6 /* factor to decrease slope of long beams */
76 #define BEAM_THRESH 0.06 /* flat beam if slope below this threshold */
77 #define BEAM_SLOPE 0.5 /* max slope of a beam */
78 #define BEAM_STUB 6.0 /* length of stub for flag under beam */
79 #define SLUR_SLOPE 1.0 /* max slope of a slur */
80 #define DOTSHIFT 5 /* shift dot when up flag on note */
81 #define GSTEM 10.0 /* grace note stem length */
82 #define GSTEM_XOFF 2.0 /* x offset for grace note stem */
83 #define GSPACE0 10.0 /* space from grace note to big note */
84 #define GSPACE 7.0 /* space between grace notes */
85 #define DECO_IS_ROLL 0 /* ~ makes roll if 1, otherwise twiddle */
86 #define WIDTH_MIN 1.0 /* minimal left,right width for xp list */
87 #define RANFAC 0.05 /* max random shift = RANFAC * spacing */
88 #define RANCUT 1.50 /* cutoff for random shift */
89 #define BNUMHT 32.0 /* height for bar numbers */
90
91 #define BETA_C 0.1 /* max expansion for flag -c */
92 #define ALFA_X 1.0 /* max compression before complaining */
93 #define BETA_X 1.2 /* max expansion before complaining */
94
95 #define VOCPRE 0.4 /* portion of vocals word before note */
96 #define GCHPRE 0.4 /* portion of guitar chord before note */
97
98 #define DEFVOICE "1" /* default name for first voice */
99
100
101 /* ----- macros for program internals ----- */
102
103 #define CM 28.35 /* factor to transform cm to pt */
104 #define PT 1.00 /* factor to transform pt to pt */
105 #define IN 72.00 /* factor to transform inch to pt */
106
107 #define STRL 301 /* string length in info fields */
108 #define STRL1 101 /* string length for file names */
109 #define MAXSYMST 11 /* max symbols in start piece */
110 #define MAXHD 10 /* max heads on one stem */
111 #define NTEXT 100 /* max history lines for output */
112 #define MAXINF 100 /* max number of input files */
113 #define BSIZE 4001 /* buffer size for one input string */
114 #define BUFFSZ 40000 /* size of output buffer */
115 #define BUFFSZ1 3000 /* buffer reserved for one staff */
116 #define BUFFLN 100 /* max number of lines in output buffer */
117 #define NWPOOL 4000 /* char pool for vocals */
118 #define NWLINE 5 /* max number of vocal lines per staff */
119
120 #define BASE 192 /* base for durations */
121 #define WHOLE 192 /* whole note */
122 #define HALF 96 /* half note */
123 #define QUARTER 48 /* quarter note */
124 #define EIGHTH 24 /* 1/8 note */
125 #define SIXTEENTH 12 /* 1/16 note */
126 #define THIRTYSECOND 6 /* 1/32 note */
127 #define SIXTYFOURTH 3 /* 1/64 note */
128
129 #define COMMENT 1 /* types of lines scanned */
130 #define MUSIC 2
131 #define E_O_F 4
132 #define INFO 5
133 #define TITLE 6
134 #define METER 7
135 #define PARTS 8
136 #define KEY 9
137 #define XREF 10
138 #define DLEN 11
139 #define HISTORY 12
140 #define BLANK 13
141 #define WORDS 14
142 #define MWORDS 15
143 #define PSCOMMENT 16
144 #define TEMPO 17
145 #define VOICE 18
146
147 #define INVISIBLE 1 /* valid symbol types */
148 #define NOTE 2
149 #define REST 3
150 #define BAR 4
151 #define CLEF 5
152 #define TIMESIG 6
153 #define KEYSIG 7
154 #define GCHORD 8
155
156 #define SPACE 101 /* additional parsable things */
157 #define E_O_L 102
158 #define ESCSEQ 103
159 #define CONTINUE 104
160 #define NEWLINE 105
161 #define DUMMY 106
162
163
164 #define B_SNGL 1 /* codes for different types of bars */
165 #define B_DBL 2 /* || thin double bar */
166 #define B_LREP 3 /* |: left repeat bar */
167 #define B_RREP 4 /* :| right repeat bar */
168 #define B_DREP 5 /* :: double repeat bar */
169 #define B_FAT1 6 /* [| thick at section start */
170 #define B_FAT2 7 /* |] thick at section end */
171 #define B_INVIS 8 /* invisible; for endings without bars */
172
173 #define A_SH 1 /* codes for accidentals */
174 #define A_NT 2
175 #define A_FT 3
176 #define A_DS 4
177 #define A_DF 5
178
179
180 #define D_GRACE 1 /* codes for decoration */
181 #define D_STACC 2
182 #define D_SLIDE 3
183 #define D_EMBAR 4
184 #define D_HOLD 5
185 #define D_UPBOW 6
186 #define D_DOWNBOW 7
187 #define D_ROLL 8
188 #define D_TRILL 9
189 #define D_HAT 10
190 #define D_ATT 11
191
192 #define H_FULL 1 /* types of heads */
193 #define H_EMPTY 2
194 #define H_OVAL 3
195
196 #define TREBLE 1 /* types of clefs */
197 #define BASS 2
198 #define ALTO 3
199
200 #define G_FILL 1 /* modes for glue */
201 #define G_SHRINK 2
202 #define G_SPACE 3
203 #define G_STRETCH 4
204
205 #define S_TITLE 1 /* where to do pattern matching */
206 #define S_RHYTHM 2
207 #define S_COMPOSER 3
208 #define S_SOURCE 4
209
210 #define TEXT_H 1 /* type of a text line */
211 #define TEXT_W 2
212 #define TEXT_Z 3
213 #define TEXT_N 4
214 #define TEXT_D 5
215
216 #define DO_INDEX 1 /* what program does */
217 #define DO_OUTPUT 2
218
219 #define SWFAC 0.50 /* factor to estimate width of string */
220
221 #define DB_SW 0 /* debug switch */
222
223 #define MAXFORMATS 10 /* max number of defined page formats */
224 #define STRLFMT 81 /* string length in FORMAT struct */
225
226
227 #define MAXNTEXT 400 /* for text output */
228 #define MAXWLEN 51
229 #define ALIGN 1
230 #define RAGGED 2
231 #define OBEYLINES 3
232 #define OBEYCENTER 4
233 #define SKIP 5
234
235 #define E_CLOSED 1
236 #define E_OPEN 2
237
238
239
240 /* ----- global variables ------- */
241
242 int db=DEBUG_LV; /* debug control */
243
244 int maxSyms,maxVc; /* for malloc */
245
246
247 #define NCOMP 5 /* max number of composer lines */
248
249 struct ISTRUCT { /* information fields */
250 char area [STRL];
251 char book [STRL];
252 char comp [NCOMP][STRL];
253 int ncomp;
254 char disc [STRL];
255 char eskip [STRL];
256 char group [STRL];
257 char hist [STRL];
258 char info [STRL];
259 char key [STRL];
260 char len [STRL];
261 char meter [STRL];
262 char notes [STRL];
263 char orig [STRL];
264 char rhyth [STRL];
265 char src [STRL];
266 char title [STRL];
267 char title2 [STRL];
268 char title3 [STRL];
269 char parts [STRL];
270 char xref [STRL];
271 char trans [STRL];
272 char tempo [STRL];
273 } info,default_info;
274
275 struct GRACE { /* describes grace notes */
276 int n; /* number of grace notes */
277 int p[30]; /* pitches */
278 int a[30]; /* accidentals */
279 };
280
281 struct DECO { /* describes decorations */
282 int n; /* number of grace notes */
283 float top; /* max height needed */
284 int t[10]; /* type of deco */
285 };
286
287 struct SYMBOL { /* struct for a drawable symbol */
288 int type; /* type of symbol */
289 int pits[MAXHD]; /* pitches for notes */
290 int lens[MAXHD]; /* note lengths as multiple of BASE */
291 int accs[MAXHD]; /* code for accidentals */
292 int sl1 [MAXHD]; /* which slur start on this head */
293 int sl2 [MAXHD]; /* which slur ends on this head */
294 int ti1 [MAXHD]; /* flag to start tie here */
295 int ti2 [MAXHD]; /* flag to end tie here */
296 float shhd[MAXHD]; /* horizontal shift for heads */
297 float shac[MAXHD]; /* horizontal shift for accidentals */
298 int npitch; /* number of note heads */
299 int len; /* basic note length */
300 int fullmes; /* flag for full-measure rests */
301 int word_st; /* 1 if word starts here */
302 int word_end; /* 1 if word ends here */
303 int slur_st; /* how many slurs starts here */
304 int slur_end; /* how many slurs ends here */
305 int yadd; /* shift for treble/bass etc clefs */
306 float x,y; /* position */
307 int ymn,ymx,yav; /* min,mav,avg note head height */
308 float ylo,yhi; /* bounds for this object */
309 float xmn,xmx; /* min,max h-pos of a head rel to top */
310 int stem; /* 0,1,-1 for no stem, up, down */
311 int flags; /* number of flags or bars */
312 int dots; /* number of dots */
313 int head; /* type of head */
314 int eoln; /* flag for last symbol in line */
315 struct GRACE gr; /* grace notes */
316 struct DECO dc; /* grace notes */
317 float xs,ys; /* position of stem end */
318 int u,v,w,t,q; /* auxillary information */
319 int invis; /* mark note as invisible */
320 float wl,wr; /* left,right min width */
321 float pl,pr; /* left,right preferred width */
322 float xl,xr; /* left,right expanded width */
323 int p_plet,q_plet,r_plet; /* data for n-plets */
324 float gchy; /* height of guitar chord */
325 char text[41]; /* for guitar chords etc. */
326 char *wordp[NWLINE]; /* pointers to wpool for vocals */
327 int p; /* pointer to entry in posit table */
328 float time; /* time for symbol start */
329 } ;
330
331
332 char lvoiceid[233]; /* string from last V: line */
333 int nvoice,mvoice; /* number of voices defd, nonempty */
334 int ivc; /* current voice */
335 int ivc0; /* top nonempty voice */
336
337
338 struct XPOS { /* struct for a horizontal position */
339 int type; /* type of symbols here */
340 int next,prec; /* pointers for linked list */
341 int eoln; /* flag for line break */
342 int *p; /* pointers to associated syms */
343 float time,dur; /* start time, duration */
344 float wl,wr; /* right and left widths */
345 float space,shrink,stretch; /* glue before this position */
346 float tfac; /* factor to tune spacings */
347 float x; /* final horizontal position */
348 };
349
350
351 int ixpfree; /* first free element in xp array */
352
353
354 struct METERSTR { /* data to specify the meter */
355 int meter1,meter2;
356 int mflag,lflag;
357 int dlen;
358 int insert;
359 char top[31];
360 } default_meter;
361
362 struct KEYSTR { /* data to specify the key */
363 int ktype;
364 int sf;
365 int add_pitch;
366 int root,root_acc;
367 int add_transp,add_acc[7];
368 } default_key;
369
370
371 struct VCESPEC { /* struct to characterize a voice */
372 char id[33]; /* identifier string, eg. a number */
373 char name[81]; /* full name of this voice */
374 char sname[81]; /* short name */
375 struct METERSTR meter,meter0,meter1; /* meter */
376 struct KEYSTR key,key0,key1; /* keysig */
377 int stems; /* +1 or -1 to force stem direction */
378 int staves,brace,bracket; /* for deco over several voices */
379 int do_gch; /* 1 to output gchords for this voice */
380 float sep; /* for space to next voice below */
381 int nsym; /* number of symbols */
382 int draw; /* flag if want to draw this voice */
383 int select; /* flag if selected for output */
384 int insert_btype,insert_num; /* to split bars over linebreaks */
385 int insert_bnum; /* same for bar number */
386 float insert_space; /* space to insert after init syms */
387 int end_slur; /* for a-b slurs */
388 char insert_text[81]; /* string over inserted barline */
389 };
390
391
392 /* things to alloc: */
393 struct SYMBOL *sym; /* symbol list */
394 struct SYMBOL **symv; /* symbols for voices */
395 struct XPOS *xp; /* shared horizontal positions */
396 struct VCESPEC *voice; /* characteristics of a voice */
397 struct SYMBOL **sym_st; /* symbols a staff start */
398 int *nsym_st;
399
400
401 int halftones; /* number of halftones to transpose by */
402
403 /* style parameters: */
404 float f0p,f5p,f1p,f0x,f5x,f1x; /* mapping fct */
405 float lnnp,bnnp,fnnp,lnnx,bnnx,fnnx; /* note-note spacing */
406 float lbnp,bbnp,rbnp,lbnx,bbnx,rbnx; /* bar-note spacing */
407 float lnbp,bnbp,rnbp,lnbx,bnbx,rnbx; /* note-bar spacing */
408
409
410 char wpool[NWPOOL]; /* pool for vocal strings */
411 int nwpool,nwline; /* globals to handle wpool */
412
413 struct SYMBOL zsym; /* symbol containing zeros */
414
415 struct BEAM { /* packages info about one beam */
416 int i1,i2;
417 float a,b;
418 float x,y,t;
419 int stem;
420 };
421
422 struct FONTSPEC {
423 char name [STRLFMT];
424 float size;
425 int box;
426 };
427
428 struct FORMAT { /* struct for page layout */
429 char name [STRLFMT];
430 float pageheight,staffwidth;
431 float topmargin,botmargin,leftmargin;
432 float topspace,wordsspace,titlespace,subtitlespace,partsspace;
433 float composerspace,musicspace,vocalspace,textspace;
434 float scale,maxshrink,lineskipfac,parskipfac,indent;
435 float staffsep,sysstaffsep,systemsep;
436 float strict1,strict2;
437 int landscape,titleleft,continueall,breakall,writehistory;
438 int stretchstaff,stretchlast,withxrefs,barsperstaff;
439 int oneperpage,titlecaps,barnums;
440 struct FONTSPEC titlefont,subtitlefont,vocalfont,textfont,tempofont;
441 struct FONTSPEC composerfont,partsfont,gchordfont,wordsfont,voicefont;
442 struct FONTSPEC barnumfont,barlabelfont,indexfont;
443 };
444
445 struct FORMAT sfmt; /* format after initialization */
446 struct FORMAT dfmt; /* format at start of tune */
447 struct FORMAT cfmt; /* current format for output */
448
449 char fontnames[50][STRLFMT]; /* list of needed fonts */
450 int nfontnames;
451
452 char txt[MAXNTEXT][MAXWLEN]; /* for output of text */
453 int ntxt;
454
455 char vcselstr[101]; /* string for voice selection */
456 char mbf[501]; /* mini-buffer for one line */
457 char buf[BUFFSZ]; /* output buffer.. should hold one tune */
458 int nbuf; /* number of bytes buffered */
459 float bposy; /* current position in buffered data */
460 int ln_num; /* number of lines in buffer */
461 float ln_pos[BUFFLN]; /* vertical positions of buffered lines */
462 int ln_buf[BUFFLN]; /* buffer location of buffered lines */
463 int use_buffer; /* 1 if lines are being accumulated */
464
465 char text [NTEXT][STRL]; /* pool for history, words, etc. lines */
466 int text_type[NTEXT]; /* type of each text line */
467 int ntext; /* number of text lines */
468 char page_init[201]; /* initialization string after page break */
469 int do_mode; /* control whether to do index or output */
470 char escseq[81]; /* escape sequence string */
471 int linenum; /* current line number in input file */
472 int tunenum; /* number of current tune */
473 int tnum1,tnum2;
474 int numtitle; /* how many titles were read */
475 int mline; /* number music lines in current tune */
476 int nsym; /* number of symbols in line */
477 int nsym0; /* nsym at start of parsing a line */
478 int pagenum; /* current page in output file */
479 int writenum; /* calls to write_buffer for each one tune */
480 int xrefnum; /* xref number of current tune */
481 int do_meter, do_indent; /* how to start next block */
482
483 int index_pagenum; /* for index file */
484 float index_posx, index_posy;
485 int index_initialized;
486
487 char gch[201]; /* guitar chord string */
488 int bagpipe; /* switch for HP mode */
489 int within_tune, within_block; /* where we are in the file */
490 int do_this_tune; /* are we typesetting the current one ? */
491 float posx,posy; /* overall scale, position on page */
492 int barinit; /* carryover bar number between parts */
493
494 char *p, *p0; /* global pointers for parsing music line */
495
496 int word,slur; /* variables used for parsing... */
497 int last_note,last_real_note;
498 int pplet,qplet,rplet;
499 int carryover; /* for interpreting > and < chars */
500 int ntinext,tinext[MAXHD]; /* for chord ties */
501
502 struct { /* where to draw endings */
503 float a,b; /* start and end position */
504 int num; /* number of the ending */
505 int type; /* shape: open or closed at right */
506 } ending[20];
507 int num_ending; /* number of endings to draw */
508 int mes1,mes2; /* to count measures in an ending */
509
510 int slur1[20],slur2[20]; /* needed for drawing slurs */
511 int overfull; /* flag if staff overfull */
512 int do_words; /* flag if staff has words under it */
513
514 int vb, verbose; /* verbosity, global and within tune */
515 int in_page=0;
516
517 /* switches modified by flags: */
518 int gmode; /* switch for glue treatment */
519 int include_xrefs; /* to include xref numbers in title */
520 int one_per_page; /* new page for each tune ? */
521 int pagenumbers; /* write page numbers ? */
522 int write_history; /* write history and notes ? */
523 int interactive; /* interactive mode ? */
524 int help_me; /* need help ? */
525 int select_all; /* select all tunes ? */
526 int epsf; /* for EPSF postscript output */
527 int choose_outname; /* 1 names outfile w. title/fnam */
528 int break_continues; /* ignore continuations ? */
529 int search_field0; /* default search field */
530 int pretty; /* for pretty but sprawling layout */
531 int bars_per_line; /* bars for auto linebreaking */
532 int continue_lines; /* flag to continue all lines */
533 int landscape; /* flag for landscape output */
534 int barnums; /* interval for bar numbers */
535 int make_index; /* write index file ? */
536 float alfa_c; /* max compression allowed */
537 float scalefac; /* scale factor for symbol size */
538 float lmargin; /* left margin */
539 float swidth; /* staff width */
540 float staffsep,dstaffsep; /* staff separation */
541 float strict1,strict2; /* 1stave, mstave strictness */
542 char transpose[21]; /* target key for transposition */
543
544 float alfa_last,beta_last; /* for last short short line.. */
545
546 char in_file[MAXINF][STRL1]; /* list of input file names */
547 int ninf; /* number of input file names */
548 FILE *fin; /* for input file */
549
550 char outf[STRL1]; /* output file name */
551 char outfnam[STRL1]; /* internal file name for open/close */
552 char styf[STRL1]; /* layout style file name */
553 char styd[STRL1]; /* layout style directory */
554 char infostr[STRL1]; /* title string in PS file */
555
556 int file_open; /* for output file */
557 int file_initialized; /* for output file */
558 FILE *fout,*findex; /* for output file */
559 int nepsf; /* counter for epsf output files */
560
561 char sel_str[MAXINF][STRL1]; /* list of selector strings */
562 int s_field[MAXINF]; /* type of selection for each file */
563 int psel[MAXINF]; /* pointers from files to selectors */
564
565 int temp_switch;
566
567
568 #include "style.h" /* globals to define layout style */
569
570 /* ----- include subroutine files ----- */
571 void identify_note (struct SYMBOL *s, char *q);
572 int parse_length ();
573
574 #include "syms.h"
575 #include "util.h"
576 #include "pssubs.h"
577 #include "buffer.h"
578 #include "format.h"
579 #include "subs.h"
580 #include "parse.h"
581 #include "music.h"
582
583 /* ----- start of main ------ */
584 int main(argc, argv)
585 int argc;
586 char *argv[];
587 {
588
589 char aaa[501],bbb[501],ccc[501],ext[41];
590 char xref_str[STRL1], pat[30][STRL1];
591 char *urgv[100];
592 int isel,j,npat,search_field,urgc,retcode,rc1;
593
594 /* ----- set default options and parse arguments ----- */
595
596 maxSyms = 800;
597 maxVc = 4;
598
599 init_ops (1);
600 retcode=parse_args (argc, argv);
601 if (retcode) exit (1);
602 if (interactive || (do_mode==DO_OUTPUT))
603 printf ("This is abc2ps, version %s.%s (%s)\n", VERSION, REVISION, VDATE);
604
605 alloc_structs ();
606
607 /* ----- set the page format ----- */
608 nfontnames=0;
609 if (!set_page_format()) exit (3);
610 if (help_me==2) {
611 print_format(cfmt);
612 exit (0);
613 }
614
615 /* ----- help printout ----- */
616 if (argc<=1) help_me=1;
617 if (help_me==1) {
618 write_help ();
619 exit (0);
620 }
621
622 if ((ninf==0) && (!interactive)) rx ("No input file specified", "");
623
624 isel=psel[ninf-1];
625 search_field0=s_field[isel]; /* default for interactive mode */
626 if (epsf) cutext(outf);
627
628 /* ----- initialize ----- */
629 zero_sym();
630 pagenum=0;
631 tunenum=tnum1=tnum2=0;
632 verbose=0;
633 file_open=file_initialized=0;
634 nepsf=0;
635 bposy=0;
636 posx=cfmt.leftmargin;
637 posy=cfmt.pageheight-cfmt.topmargin;
638 writenum=99;
639
640 strcpy(page_init, "");
641 strcpy (bbb,"");
642 for (j=0;j<ninf;j++) {strcat(bbb,in_file[j]); strcat(bbb," ");}
643
644 if ((do_mode == DO_OUTPUT) && make_index) open_index_file (INDEXFILE);
645
646 /* ----- start infinite loop for interactive mode ----- */
647 for (;;) {
648
649 if (interactive) {
650 printf ("\nSelect tunes: ");
651 /*| gets (aaa); |*/
652 /*| fgets (aaa, sizeof(aaa), stdin); |*/
653 abc2ps_getline(aaa,500,stdin);
654 if (str_isblank(aaa)) break;
655 sscanf(aaa,"%s",ccc);
656 if (ccc[0]=='?') {
657 printf ("%s\n", bbb);
658 continue;
659 }
660 if (ccc[0]=='*') {
661 strcat (bbb,strchr(aaa,'*')+1);
662 strcpy (aaa,bbb);
663 printf ("%s\n", aaa);
664 }
665 if (ccc[0]=='!') {
666 strcpy (bbb,"");
667 for (j=0;j<ninf;j++) {
668 strcat (bbb,in_file[j]);
669 strcat (bbb," ");
670 }
671 strcat (bbb,strchr(aaa,'!')+1);
672 strcpy (aaa,bbb);
673 printf ("%s\n", aaa);
674 }
675 strcpy(bbb,aaa);
676 urgc=make_arglist (aaa, urgv);
677 if (!strcmp(urgv[1],"q")) break;
678 if (!strcmp(urgv[1],"quit")) break;
679 init_ops(0);
680 retcode=parse_args (urgc, urgv);
681 if (retcode) continue;
682 ops_into_fmt (&cfmt);
683 if (do_mode==DO_OUTPUT) {
684 rc1=set_page_format();
685 if (rc1==0) continue;
686 }
687 if (epsf) cutext(outf);
688 if (help_me==1) {
689 write_help();
690 continue;
691 }
692 if (help_me==2) {
693 print_format(cfmt);
694 continue;
695 }
696
697 }
698
699 /* ----- loop over files in list ---- */
700 if (ninf==0) printf ("++++ No input files\n");
701 for (j=0;j<ninf;j++) {
702 getext (in_file[j],ext);
703 /* skip .ps and .eps files */
704 if ((!strcmp(ext,"ps"))||(!strcmp(ext,"eps"))) continue;
705
706 if ((fin = fopen (in_file[j],"r")) == NULL) {
707 if (!strcmp(ext,"")) strext (in_file[j],in_file[j],"abc",1);
708 if ((fin = fopen (in_file[j],"r")) == NULL) {
709 printf ("++++ Cannot open input file: %s\n", in_file[j]);
710 continue;
711 }
712 }
713 isel=psel[j];
714 search_field=s_field[isel];
715 npat=rehash_selectors (sel_str[isel], xref_str, pat);
716 dfmt=sfmt;
717 strcpy(infostr, in_file[j]);
718
719 if (do_mode==DO_INDEX) {
720 printf ("%s:\n", in_file[j]);
721 do_index (fin,xref_str,npat,pat,select_all,search_field);
722 }
723
724 else {
725 if (!epsf) {
726 strext (outf, outf, "ps", 1);
727 if (choose_outname) strext (outf, in_file[j], "ps", 1);
728 open_output_file(outf,in_file[j]);
729 }
730 printf ("%s: ", in_file[j]);
731 if ((vb>=3) || interactive) printf ("\n");
732 process_file (fin,fout,xref_str,npat,pat,select_all,search_field);
733 printf ("\n");
734 }
735
736 }
737 if (!interactive) break;
738 }
739
740 if ((!interactive) && (do_mode==DO_INDEX))
741 printf ("Selected %d title%s of %d\n", tnum1, tnum1==1?"":"s", tnum2);
742
743 close_output_file ();
744
745 if ((do_mode == DO_OUTPUT) && make_index) close_index_file ();
746
747 exit (0);
748 }
749
750
751
752
753
754