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