diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/pstab/PStab |
Initial commit
Diffstat (limited to 'support/pstab/PStab')
-rw-r--r-- | support/pstab/PStab | 1027 |
1 files changed, 1027 insertions, 0 deletions
diff --git a/support/pstab/PStab b/support/pstab/PStab new file mode 100644 index 0000000000..74bf88c619 --- /dev/null +++ b/support/pstab/PStab @@ -0,0 +1,1027 @@ +%! +%%Title:PStab 2.0 +%%Creator:Baz +%%CreationDate:14 March 1994 +%PStab 2.0 (first full release) +% +% +% Copyright (C) 1994 Brian Ewins. All rights reserved. +% +%PStab is distributed in the hope that it will be useful, but +%WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +%to anyone for the consequences of using it or for whether it serves any +%particular purpose or works at all, unless he says so in writing. Refer +%to the PStab General Public License for full details. +% +%Everyone is granted permission to copy, modify and redistribute +%PStab, but only under the conditions described in the PStab +%General Public License. A copy of this license is supposed to have been +%given to you along with PStab so you can know your rights and +%responsibilities. It should be in a file named COPYING. Among other +%things, the copyright notice and this notice must be preserved on all +%copies. +% +%------------------------------------------------------------------------------- +%Revision History: started Friday, 2 March 1994. +%------------------------------------------------------------------------------- +% 0.1 :Friday: crap program for lining numbers up in columns +% 0.2 :Sunday: complete rewrite. chord table program only +% 0.3 :Tuesday: reorganized into core & styles. +% Centred,Columns,ChordTable supplied. +% ifcase added to core. +% 0.4 :Wednesday: rethink on text styles.easier method of entry. +% Verses replaced Columns +% ChordPro style provides compatability. +% ChordTable renamed Chords, now has +% huge table of chords you can use. +% Handles VM restore properly !!! +% added revision history. +% 0.5 :Thursday: Back to doing tablature (again) +% Chords now size-independent +% Verbatim made default style. +% Verbatim-equivalent defs removed.(shortens prog} +% Tablature works! hooray!!! +% Many marks allowed in music. +% 0.6 :Friday: added default case to ifcase +% finished Parser. program is still buggy. +% 0.7 :: Due to a hitch, there was no alpha 7. +% 0.8 :Sunday: Commented. +% fbox made internal size. +% Manual doubles as torture test. +% manual nearly complete, program debugged +% completely except for Tablature. +% 1.0 :Monday: It all works!!! I'll type last man page & post. +% 1.1 :Tuesday: the '2nd last page' bug fixed. +% fingermark bug fixed. top , bottom, rows set +% once only in Tablature. +% Parsers now separate part of the program. +% Font sizes reduced:I was viewing on A3!!! +% Errors in manual fixed. +% Only things left to do now are ASCII tab reader, +% and more complete manual. +% 1.2: :Tuesday: ASCII parser started. buggy. remembered to fix bug +% for looooong bars.incidentally, redundant defs were +% placed back in at 1.0. ASCII parser works. WOW! +% manual to do. ASCII parser now does an excellent +% job of it. only two pathogenic cases I can think of. +% 2.0: :Wednesday: ASCII parser fixed so it split up 'bars'. this +% is truly monumental: ASCII'd tab now looks +% _nice_ (!)... almost worth using... +% manual finished. +%------------------------------------------------------------------------------- +%-CORE-------------------------------------------------------------------------- +%Contains idioms, and other stuff essential for +%the program to break lines, pages, etc. +%------------------------------------------------------------------------------- +%-------Idioms +%------------------------------------------------------------------------------- +/debug {dup 20 string cvs show ( ) show} def +/edef {exch def} def +/max { 2 copy gt {pop} {exch pop} ifelse } def +/min { 2 copy lt {pop} {exch pop} ifelse } def +/inch {72 mul} def +/plus +{ % x y plus is equivalent to x+=y; in C + 1 index cvx exec add def +} def +/minus +{ % x y minus is equivalent to x-=y; in C + 1 index cvx exec exch sub def +} def +/ifcase +{ % syntax: pattern { {match1 {proc1}} {match2 {proc2}} ...} ifcase + % if match is /default, it will be executed immediately + % pattern is on the stack at the start of any proc. + % proc should really remove it. + exch /pattern edef + { + aload pop exch dup + /default eq {pop pattern exch exec exit} if + pattern eq {pattern exch exec exit} {pop} ifelse + } forall +} def +/ToString {3 string cvs} def +/ChooseFont +{ % selects font and sets fbox + /fbox edef + findfont fbox scalefont setfont +} def +%------------------------------------------------------------------------------- +%-------Sizes: internal unit is font size. +%------------- also here is code to use real page size. +%------------------------------------------------------------------------------- +/ptof {fbox div exch fbox div exch} def +/ftop {fbox mul exch fbox mul exch} def +/moverel {ftop rmoveto} def +/linerel {ftop rlineto} def +/StringWidth {stringwidth pop fbox div} def +/GetPageMargins +{ + clippath pathbbox %get page size + /TopMargin edef + /RightMargin edef %put it where I can use it. + /BottomMargin edef + /LeftMargin edef + newpath %stops me strokeing the clipping path +} def +/PageWidth {RightMargin LeftMargin ptof sub} def +/smaller +{ + exch + { {/LeftMargin {exch plus}} + {/RightMargin {exch minus}} + {/TopMargin {exch minus}} + {/BottomMargin {exch plus}} + } ifcase +} def +%------------------------------------------------------------------------------- +%-------Line,Page breaking code. +%------------------------------------------------------------------------------- +/Atom +{ + GetAtom + currentpoint pop + hbox fbox mul add + RightMargin gt + {NewLine} if + currentpoint + vbox fbox mul sub + BottomMargin lt + {NewPage} if pop +} def +/NewDoc +{ % begin a document + % assumes margins have been set + LeftMargin TopMargin moveto + Verbatim %default style + /Home save def + /StyleDict 128 dict def + StyleDict begin +} def +/NewStyle +{ % clean up and start again + Flush end + currentpoint + Home restore + /Home save def + moveto + /StyleDict 128 dict def + StyleDict begin +} def +/EndDoc +{ + Flush end + showpage %show what's left. + Home + restore +} def +/PageBreak +{ % when the user wants to insert a page break. + EndDoc NewDoc +} def +%------------------------------------------------------------------------------- +%-------Chord data: a table taken from ChordPro, and put in +%------------------ the simpler format used here. Some mistakes corrected. +%------------------ Chordpro is (c) Mario Dorion & Martin Leclerc +%------------------------------------------------------------------------------- +/Chordata % this is spinal tap! +[ + [(Ab)[ 4 6 6 5 4 4 ]] [(Abm)[ 4 6 6 4 4 4 ]] + [(Ab7)[ -1 -1 1 1 1 2 ]] [(Abm7)[ -1 -1 4 4 4 4 ]] + [(Absus)[ -1 -1 1 1 2 4 ]] [(Ab+)[ -1 -1 2 1 1 0 ]] + [(Abdim)[ -1 -1 0 1 0 1 ]] [(Abmaj7)[ -1 -1 1 1 1 3 ]] + [(A)[ -1 0 2 2 2 0 ]] [(Am)[ -1 0 2 2 1 0 ]] + [(A7)[ -1 0 2 0 2 0 ]] [(Am7)[ -1 0 2 2 1 3 ]] + [(Asus)[ -1 -1 2 2 3 0 ]] [(A+)[ -1 0 3 2 2 1 ]] + [(Adim)[ -1 -1 1 2 1 2 ]] [(Amaj7)[ -1 0 2 1 2 0 ]] + [(A#)[ -1 1 3 3 3 1 ]] [(A#m)[ -1 1 3 3 2 1 ]] + [(A#7)[ -1 -1 3 3 3 4 ]] [(A#m7)[ -1 1 3 1 2 1 ]] + [(A#sus)[ -1 -1 3 3 4 1 ]] [(A#+)[ -1 -1 0 3 3 2 ]] + [(A#dim)[ -1 -1 2 3 2 3 ]] [(A#maj7)[ -1 1 3 2 3 -1 ]] + [(Bb)[ -1 1 3 3 3 1 ]] [(Bbm)[ -1 1 3 3 2 1 ]] + [(Bb7)[ -1 -1 3 3 3 4 ]] [(Bbm7)[ -1 1 3 1 2 1 ]] + [(Bbsus)[ -1 -1 3 3 4 1 ]] [(Bb+)[ -1 -1 0 3 3 2 ]] + [(Bbdim)[ -1 -1 2 3 2 3 ]] [(Bbmaj7)[ -1 1 3 2 3 -1 ]] + [(B)[ -1 2 4 4 4 2 ]] [(Bm)[ -1 2 4 4 3 2 ]] + [(B7)[ 0 2 1 2 0 2 ]] [(Bm7)[ -1 2 4 2 3 2 ]] + [(Bsus)[ -1 -1 4 4 5 2 ]] [(B+)[ -1 -1 1 0 0 4 ]] + [(Bdim)[ -1 -1 0 1 0 1 ]] [(Bmaj7)[ -1 2 4 3 4 -1 ]] + [(C)[ 0 3 2 0 1 0 ]] [(Cm)[ -1 1 5 5 4 3 ]] + [(C7)[ 0 3 2 3 1 0 ]] [(Cm7)[ -1 1 5 3 4 3 ]] + [(Csus)[ -1 -1 3 0 1 3 ]] [(C+)[ -1 -1 2 1 1 0 ]] + [(Cdim)[ -1 -1 1 2 1 2 ]] [(Cmaj7)[ -1 3 2 0 0 0 ]] + [(C#)[ -1 -1 3 1 2 1 ]] [(C#m)[ -1 -1 2 1 2 0 ]] + [(C#7)[ -1 -1 3 4 2 4 ]] [(C#m7)[ -1 -1 2 4 2 4 ]] + [(C#sus)[ -1 -1 6 6 7 4 ]] [(C#+)[ -1 -1 3 2 2 1 ]] + [(C#dim)[ -1 -1 2 3 2 3 ]] [(C#maj7)[ -1 4 3 1 1 1 ]] + [(Db)[ -1 -1 3 1 2 1 ]] [(Dbm)[ -1 -1 2 1 2 0 ]] + [(Db7)[ -1 -1 3 4 2 4 ]] [(Dbm7)[ -1 -1 2 4 2 4 ]] + [(Dbsus)[ -1 -1 6 6 7 4 ]] [(Db+)[ -1 -1 3 2 2 1 ]] + [(Dbdim)[ -1 -1 2 3 2 3 ]] [(Dbmaj7)[ -1 4 3 1 1 1 ]] + [(D)[ -1 -1 0 2 3 2 ]] [(Dm)[ -1 -1 0 2 3 1 ]] + [(D7)[ -1 -1 0 2 1 2 ]] [(Dm7)[ -1 -1 0 2 1 1 ]] + [(Dsus)[ -1 -1 0 2 3 3 ]] [(D+)[ -1 -1 0 3 3 2 ]] + [(Ddim)[ -1 -1 0 1 0 1 ]] [(Dmaj7)[ -1 -1 0 1 1 1 ]] + [(D#)[ -1 -1 5 3 4 3 ]] [(D#m)[ -1 -1 4 3 4 2 ]] + [(D#7)[ -1 -1 1 3 2 3 ]] [(D#m7)[ -1 -1 1 3 2 2 ]] + [(D#sus)[ -1 -1 1 3 4 4 ]] [(D#+)[ -1 -1 1 0 0 4 ]] + [(D#dim)[ -1 -1 1 2 1 2 ]] [(D#maj7)[ -1 -1 1 3 3 3 ]] + [(Eb)[ -1 -1 6 4 5 4 ]] [(Ebm)[ -1 -1 4 3 4 2 ]] + [(Eb7)[ -1 -1 1 3 2 3 ]] [(Ebm7)[ -1 -1 1 3 2 2 ]] + [(Ebsus)[ -1 -1 1 3 4 4 ]] [(Eb+)[ -1 -1 1 0 0 4 ]] + [(Ebdim)[ -1 -1 1 2 1 2 ]] [(Ebmaj7)[ -1 -1 1 3 3 3 ]] + [(E)[ 0 2 2 1 0 0 ]] [(Em)[ 0 2 2 0 0 0 ]] + [(E7)[ 0 2 2 1 3 0 ]] [(Em7)[ 0 2 2 0 3 0 ]] + [(Esus)[ 0 2 2 2 0 0 ]] [(E+)[ -1 -1 2 1 1 0 ]] + [(Edim)[ -1 -1 2 3 2 3 ]] [(Emaj7)[ 0 2 1 1 0 -1 ]] + [(F)[ 1 3 3 2 1 1 ]] [(Fm)[ 1 3 3 1 1 1 ]] + [(F7)[ 1 3 1 2 1 1 ]] [(Fm7)[ 1 3 1 1 1 1 ]] + [(Fsus)[ -1 -1 3 3 1 1 ]] [(F+)[ -1 -1 3 2 2 1 ]] + [(Fdim)[ -1 -1 0 1 0 1 ]] [(Fmaj7)[ -1 3 3 2 1 0 ]] + [(F#)[ 2 4 4 3 2 2 ]] [(F#m)[ 2 4 4 2 2 2 ]] + [(F#7)[ -1 -1 4 3 2 0 ]] [(F#m7)[ -1 -1 2 2 2 2 ]] + [(F#sus)[ -1 -1 4 4 2 2 ]] [(F#+)[ -1 -1 4 3 3 2 ]] + [(F#dim)[ -1 -1 1 2 1 2 ]] [(F#maj7)[ -1 -1 4 3 2 1 ]] + [(Gb)[ 2 4 4 3 2 2 ]] [(Gbm)[ 2 4 4 2 2 2 ]] + [(Gb7)[ -1 -1 4 3 2 0 ]] [(Gbm7)[ -1 -1 2 2 2 2 ]] + [(Gbsus)[ -1 -1 4 4 2 2 ]] [(Gb+)[ -1 -1 4 3 3 2 ]] + [(Gbdim)[ -1 -1 1 2 1 2 ]] [(Gbmaj7)[ -1 -1 4 3 2 1 ]] + [(G)[ 3 2 0 0 0 3 ]] [(Gm)[ 3 5 5 3 3 3]] + [(G7)[ 3 2 0 0 0 1 ]] [(Gm7)[ 3 5 3 3 3 3 ]] + [(Gsus)[ -1 -1 0 0 1 3 ]] [(G+)[ -1 -1 1 0 0 4 ]] + [(Gdim)[ -1 -1 2 3 2 3 ]] [(Gmaj7)[ -1 -1 5 4 3 2 ]] + [(G#)[ 4 6 6 5 4 4 ]] [(G#m)[ 4 6 6 4 4 4 ]] + [(G#7)[ -1 -1 1 1 1 2 ]] [(G#m7)[ -1 -1 4 4 4 4]] + [(G#sus)[ -1 -1 1 1 2 4 ]] [(G#+)[ -1 -1 2 1 1 0 ]] + [(G#dim)[ -1 -1 0 1 0 1 ]] [(G#maj7)[ -1 -1 1 1 1 3 ]] +] def +%------------------------------------------------------------------------------- +%-PARSERS----------------------------------------------------------------------- +% This new section is to allow different methods of entry in different styles. +% There is a plan to allow the program to parse ASCII tab, and also for +% a possible interface with TabEdit, or other programs. +%------------------------------------------------------------------------------- +/StdParser +{ %the usual parser, for tablature. + /Parse + { + /lastwasname false def + /barcols 0 def + { % open ({) loop + ({) search exch + { % open (,) loop + (,) search exch + { %loop again + (\n) search exch + { %loop again + ( ) search exch + dup length 0 ne + {TabHandler} + {pop} ifelse + {pop}{exit} ifelse + } loop + {pop}{exit} ifelse + } loop + {pop WriteColumn}{exit} ifelse + } loop + {pop}{exit} ifelse + (}) search % assumed true + pop exch pop + (:) search + {exch pop TextHandler} + {MarkHandler} ifelse + } loop + WriteColumn + 0 1 barcols 1 sub + { + BarArray exch get + } for % get everything back + barcols array astore + Atom % linebreaks do printing. + /cols barcols plus %more columns... + /bars 1 plus %and another bar. + } def + /WriteColumn + { %push column to stack; make a fresh column + lastwasname + { + DefaultColumn DefaultString get + dup length array copy + CurrentColumn DefaultString + 3 -1 roll put + } if + /lastwasname false def + BarArray barcols [0 CurrentColumn] put + /barcols barcols 1 add def + /CurrentColumn BlankColumn rows array + copy def %Do this every time. + } def + /IsTextRow + { % put text into column. + CurrentColumn exch 3 -1 roll put + } def + /IsRow + { %if last was row too, fill it in. + lastwasname + { + DefaultColumn DefaultString get + dup length array copy + CurrentColumn DefaultString + 3 -1 roll put + } if + /DefaultString edef + /lastwasname true def + } def + /IsFret + { + /lastwasname false def + 1 array dup 0 3 index put + CurrentColumn DefaultString + 2 index put + DefaultColumn DefaultString + 2 index put + pop pop + } def + /MarkHandler + {% what to do with special marks. + CurrentColumn DefaultString get + 0 get % for sensible use, we must set this + dup length 0 eq % if it's not already set. + { pop DefaultColumn DefaultString get + 0 get /lastwasname false def} if + exch + { + { (tie) {pop 1 2} } { (up) {pop 2 2} } + { (down) {pop 3 2} } { (h) {pop 4 2} } + { (p) {pop 5 2} } { (harm){pop 6 2} } + { (vib) {pop 8 2} } { (0) {pop 7 (0) 3} } + { (1) {pop 7 (1) 3} } { (2) {pop 7 (2) 3} } + { (3) {pop 7 (3) 3} } { (4) {pop 7 (4) 3} } + } ifcase + array astore CurrentColumn DefaultString 3 -1 roll put + } def +} def +%------------------------------------------------------------------------------- +%-------ASCIIparser: puts any marks that aren't - into the tab. ignores first +%------------------- and last thing to avoid spurious barlines. +%------------------------------------------------------------------------------- +/ASCIIparser +{ + /WholeBar rows array def + /WholeLine rows array def + BlankColumn WholeLine copy /WholeLine def + BlankColumn WholeBar copy /WholeBar def + /Parse + { %parse ascii tab. + 0 1 rows 2 sub + { + exch + (\n) search pop %must be true + WholeLine exch 5 -1 roll exch put + pop + } for + %tab now split into rows. now generate columns. + WholeLine rows 1 sub 3 -1 roll put + { + + /barcols 0 def /alldone true def + /row 0 def + { + WholeLine row get (|) search + { /alldone false def + WholeBar row 3 -1 roll put + pop WholeLine row 3 -1 roll put + } + { WholeBar row 3 -1 roll put + WholeLine row () put + } ifelse + /row 1 plus + row rows eq {exit} if + } loop + WholeBar + { + (-) search + { 3 1 roll pop pop + dup length 1 sub 0 1 3 -1 roll + {1 index exch (-) 0 get put} for pop + }{pop} ifelse + } forall + { + /finished true def + /makecolumn false def + /row 0 def + WholeBar + { + (-) search + { + /finished false def + pop 0 ( ) 0 get put + (-) search dup + {4 1 roll exch pop exch pop} + {exch} ifelse + dup dup 4 1 roll length dup 0 ne + {3 -1 roll makecolumn or /makecolumn edef} + {3 -1 roll pop} ifelse + % stick it in the column. + string copy 1 array dup 0 4 -1 + roll put + CurrentColumn row + 3 -1 roll put + %left with a copy of the string + %fill it with minus signs. + dup length 1 sub 0 1 3 -1 roll + {1 index exch (-) 0 get put} for pop + } + { + pop + } ifelse + /row 1 plus + } forall + makecolumn + { % write a column ! + /row 0 def + %needs to blank out later columns. + BarArray barcols [0 CurrentColumn] put + /barcols barcols 1 add def + /CurrentColumn BlankColumn rows array + copy def %Do this every time. + } if + finished {exit} if + } loop + barcols 0 ne + { + 0 1 barcols 1 sub + { + BarArray exch get + } for % get everything back + barcols array astore + Atom % linebreaks do printing. + /cols barcols plus %more columns... + /bars 1 plus %and another bar. + } if + alldone {exit} if + } loop + } def +} def +%------------------------------------------------------------------------------- +%-STYLES------------------------------------------------------------------------ +% In this section I define some styles in which +% the program will print. You can add more, but +% don't change these. +%------------------------------------------------------------------------------- +%-------Tablature: this is an engine for printing tablature +%----------------- in a very general way. It needs some externally +%----------------- supplied information to work. +%------------------------------------------------------------------------------- +/Tablature +{ + /BlankColumn edef + /rows BlankColumn length def + /DefaultColumn BlankColumn rows array copy def %One-shot initalise + /DefaultString 1 def% first string. + /CurrentColumn BlankColumn rows array copy def %Do this every time. + /BarArray 128 array def %very generous too! + % Initialise variables. + /hbox 0 def /cols 0 def /bars 0 def + BlankColumn + 0 1 rows 1 sub + { dup 2 index exch get type cvlit + /arraytype eq + {neg 0.25 add /top edef exit} + {pop} ifelse + } for + rows 1 sub -1 0 + { dup 2 index exch get type cvlit + /arraytype eq + {neg 0.25 add /bottom edef exit} + {pop} ifelse + } for + /bottom top minus + pop + /vbox {rows 1 add} def + /, {Parse} def + /NewPage {showpage LeftMargin TopMargin moveto} def + /NewLine + { + bars 0 eq + { %very long bar. attempts to recover, + %but an extra bar line gets drawn. + /bars 1 def /cols barcols def + /Justify PageWidth hbox sub cols div def + Display + /bars -1 def /cols barcols neg def /hbox 0 def + } + { %/Justify 0 def + /hbox barbox minus + /Justify PageWidth hbox sub cols div def + bars 1 add 1 roll % stick this one on the bottom + Display + /bars 0 def /cols 0 def /hbox barbox def + } ifelse + LeftMargin currentpoint vbox fbox mul sub + exch pop moveto %usual newline + } def + /Flush + { + Parse + /Justify 0 def % Don't justify + Display %don't bother cleaning up-we're outta here + LeftMargin currentpoint vbox fbox mul sub + exch pop moveto %usual newline + } def + /Display + { %Draw bar line, tab all columns, draw bar line.. + gsave + 0 top moverel + 0 bottom linerel + stroke grestore + bars 1 sub -1 0 + { index % ...not reverse order + [2 BlankColumn] TabColumn + { %tab a single column. + TabColumn + } forall gsave + 0 top moverel + 0 bottom linerel + stroke grestore + } for + bars {pop} repeat + } def + /TabColumn + { /finger (x) def + dup 0 get /cbox edef 1 get gsave + { %forall loop + gsave dup type cvlit + /arraytype eq + { + /tie 0 def dup length + {{1 {pop}} + {2 {pop dup 1 get /tie edef}} + {3 {pop dup dup 1 get /tie + edef 2 get /finger edef}} + } ifcase + 0 get dup StringWidth + cbox exch sub Justify add /rbox edef + show gsave 0 0.25 moverel + rbox 0 linerel stroke grestore + SpecialMarks + }{show} ifelse + grestore 0 -1 moverel + } forall + grestore cbox Justify add 0 moverel + } def + /GetAtom + { % needs to set: top,bottom,barcols,barbox,vbox + dup %leave a copy on the stack. + dup length 1 add /barcols edef + /barbox 0 def %1 down! + /previous [0] def + /oldsbox 0 def /oldcbox 0 def + { %forall + /cbox 0 def + /sbox 0 def + 0 1 rows 1 sub + { % for loop... + 1 index 1 get% copy of array + exch get % get this row + dup type cvlit + /arraytype eq + { + 0 get %get the string + StringWidth cbox max /cbox edef + } + { + StringWidth sbox max /sbox edef + } ifelse + } for + sbox 0 gt + {%there is a string + oldsbox oldcbox max 2 add + dup barbox add /barbox edef + previous 0 3 -1 roll put + /oldsbox sbox def + /oldcbox cbox def + } + {%there is no string! + previous 0 oldcbox 2 add put + oldcbox 2 add barbox add /barbox edef + /oldsbox oldsbox oldcbox sub 2 sub def + /oldcbox cbox def + } ifelse + /previous edef + } forall + previous 0 oldsbox oldcbox max 2 add put + oldsbox oldcbox max 2 add barbox add /barbox edef + /hbox barbox plus + } def + /SpecialMarks + { % produce all the extra bits of notation. + gsave tie + { {1{pop % code to do ties + 0.25 0 moverel + rbox 0.5 sub 3 div -0.25 ftop + rbox 0.5 sub 3 div 2 mul -0.25 ftop + rbox 0.5 sub 0 ftop rcurveto stroke}} + {2{pop % code to do slides up + 0.25 0 moverel + rbox 0.5 sub 0.5 linerel stroke}} + {3{pop % code to do slides down + 0.25 0.5 moverel + rbox 0.5 sub -0.5 linerel stroke}} + {4{pop % code to do hammer on + 0.5 0.5 moverel 0.25 -0.5 linerel + 0.25 0.5 linerel stroke}} + {5{pop % code to do pull off + 0.5 0 moverel + 0.25 0.5 linerel + 0.25 -0.5 linerel stroke}} + {6{pop % code to do harmonic + 0.5 0.25 moverel 0.25 0.25 linerel + 0.25 -0.25 linerel -0.25 -0.25 linerel + closepath stroke}} + {7{pop % code to do finger mark (specify fingering) + gsave 1 0.25 moverel + currentpoint newpath + fbox 2 div 0 360 arc + gsave 1 setgray fill grestore + stroke grestore + 13 16 div 0 moverel + finger ToString show}} + {8{pop % code to do vibrato + 0.25 0.5 moverel + 3 {0.125 -0.125 linerel 0.125 0.125 linerel} + repeat stroke}} + } ifcase grestore + } def +} def +%------------------------------------------------------------------------------- +%-------Verbatim: this is the default style. It's intended for reproducing +%---------------- blocks of text directly, such as an ASCII tab file. +%------------------------------------------------------------------------------- +/Verbatim +{ + /, {Parse} def + /vbox 1 def + /Courier 8 ChooseFont + /Parse + { % breaks into words. + { + (\n) search exch + { + ( ) search exch + Atom Display + {Atom Display}{exit} ifelse + } loop + {pop} {exit} ifelse + NewLine + } loop + NewLine + } def + /GetAtom {dup StringWidth /hbox edef} def + /Display {gsave 0 -1 moverel show grestore hbox 0 moverel} def + /NewLine + { LeftMargin currentpoint vbox fbox mul sub + exch pop moveto + } def + /NewPage {showpage LeftMargin TopMargin moveto} def + /Flush {Parse NewLine} def +} def +%------------------------------------------------------------------------------- +%-------Centred: This style produces centred text. It's intended for +%--------------- making titles. +%------------------------------------------------------------------------------- +/Centred +{ + /, {Parse} def + /vbox 1 def + /Helvetica 12 ChooseFont + /Parse + { % breaks into words. + { + (\n) search exch + { + dup + ( ) search + { + 3 1 roll + 0 (\267) putinterval + pop + Atom pop dup + (\267) search pop + exch pop + ( ) search + { + pop pop pop + exch pop + } + { + pop pop + } ifelse + } + { + pop Atom exit + } ifelse + } loop + NewLine pop + {pop} {exit} ifelse + } loop + } def + /GetAtom {dup StringWidth /hbox edef} def + /Display + { + dup dup + { + (\267) search + {pop 0 ( ) putinterval} + {pop exit} ifelse + } loop + gsave PageWidth hbox sub 2 div -1 moverel + show grestore + }def + /NewLine + { + Display + LeftMargin currentpoint vbox fbox mul sub + exch pop moveto + } def + /NewPage {showpage LeftMargin TopMargin moveto} def + /Flush {Parse} def +} def +%------------------------------------------------------------------------------- +%-------Verses: Each block of text is assumed to be a verse, and this +%-------------- style tries to place as many verses horizontally as it can. +%------------------------------------------------------------------------------- +/Verses +{ + /rows 0 def + /vbox 0 def + /Times-Roman 8 ChooseFont + /, {Parse} def + /Parse + { /hbox 0 def + { + (\n) search exch Atom exch + {exch pop exch} {exit} ifelse + } loop + Display + } def + /GetAtom + { dup StringWidth + hbox max /hbox edef + /rows 1 plus + rows vbox max /vbox edef + } def + /NewLine + { + LeftMargin currentpoint vbox 1 add fbox mul sub + exch pop moveto %usual def ... + /vbox rows def % and reset vbox + } def + /NewPage + { + showpage + LeftMargin TopMargin moveto %usual def.. + /vbox rows def % and reset vbox + } def + /Display + { % show whole verse + rows -1 1 + { + gsave + neg 0 exch moverel + show grestore %start popping strings + } for + /rows 0 def % reset rows + hbox 1 add 0 moverel + /hbox 0 def % reset hbox too. + } def + /Flush {Parse NewLine} def +} def +%------------------------------------------------------------------------------- +%-------Chords: This style prints chord diagrams. It 'knows' over +%-------------- 130 chords, but you can use your own. +%------------------------------------------------------------------------------- +/Chords +{ + /, {Parse} def + /vbox 9 def + /Times-Roman 8 ChooseFont + /Parse {Atom Display} def + /Flush {Parse NewLine} def + /CentreShow + { % centre a string horizontally and vertically + gsave + dup StringWidth + 2 div neg -0.3 moverel% horizontal + show grestore %back to centre + } def + /GetAtom + { % first pass, find range, also diagram width. + dup type cvlit + /stringtype eq + { %find it in Chordata + Chordata + { + dup 0 get 2 index eq + { %found it + 1 get + exit % stop search + } + {pop} ifelse + } forall + dup type cvlit /stringtype eq + { %there was no match + [-1 -1 -1 -1 -1 -1] % rescue program + } if + } if % no action otherwise + dup dup length /cols edef % width of diagram. + /top -2 def + /bottom 99 def + { + dup type cvlit + /arraytype eq + { 0 get } if + %pop % don't want string this time round. + dup + top max /top edef %highest fret + dup + 0 gt %ignore 0 fret, unplayed strings + { bottom min /bottom edef } + { pop } ifelse + } forall + top 5 le + { /top 5 def /bottom 0 def } + { /top bottom 5 add def + bottom 1 sub /bottom edef + } ifelse + /hbox cols 2 add def + } def + /Display + { %style object. + gsave + 0.5 -1 moverel + gsave + -1 -1 -6 + { + 1 exch moverel + cols 1 sub 0 linerel stroke + grestore gsave + } for + bottom 0 eq + { % gotta draw extra line. + 1 -0.875 moverel cols 1 sub 0 linerel stroke % ok that's it. + } if %label first fret elsewhere... + grestore gsave 1 -0.5 moverel + { + dup type cvlit + /arraytype eq + { aload pop ToString } + { () } ifelse + exch dup gsave % draw string + 0 -0.5 moverel 0 -5 linerel stroke + grestore gsave 0 le + { % something is printed here + -1 eq + { (x) CentreShow } + { (o) CentreShow } + ifelse pop % if we did that,that's this string done. + } + { % figure out where to put this string + bottom sub neg 0 exch moverel + gsave currentpoint newpath + 0.5 fbox mul 0 360 arc + gsave 1 setgray fill grestore + stroke grestore CentreShow + } ifelse + grestore + 1 0 moverel + } forall + bottom 0 ne + { % label first fret. + 0 -0.5 moverel + bottom ToString CentreShow + } if + grestore + cols 1 add 2 div -7 moverel + CentreShow %write name centred. + grestore + cols 2 add 0 moverel + } def + /NewLine + { LeftMargin currentpoint vbox fbox mul sub + exch pop moveto + } def + /NewPage {showpage LeftMargin TopMargin moveto} def +} def +%------------------------------------------------------------------------------- +%-------ChordPro: This style prints chords above lyrics, a la ChordPro +%------------------------------------------------------------------------------- +/ChordPro +{ + /vbox 3 def + /Times-Roman 8 ChooseFont + /, {Parse} def + /Flush {Parse NewLine} def + /Parse + { %split into atoms + { + (\n) search exch + { + ([) search + { + dup length 0 ne + { Atom Display } + { pop } ifelse + pop + } + { Atom Display exit } ifelse + } loop + {pop NewLine} {exit} ifelse + } loop + } def + /GetAtom + { % get width attributes of atom + /hbox 0 def + dup + (]) search % contains a chord ? + { StringWidth 1 add /hbox edef pop + StringWidth hbox max /hbox edef } + { StringWidth /hbox edef } ifelse + }def + /Display + { + (]) search % contains a chord ? + { gsave 0 -1 moverel + show grestore pop } if + gsave 0 -2 moverel + show grestore hbox 0 moverel + } def + /NewLine + { + LeftMargin currentpoint vbox fbox mul sub + exch pop moveto + } def + /NewPage {showpage LeftMargin TopMargin moveto} def +} def +%------------------------------------------------------------------------------- +%-------Guitar: an example of a style that uses Tablature. It defines the +%-------------- things that Tablature needs to know, for printing guitar +%-------------- tab with a row of text above & below. +%------------------------------------------------------------------------------- +/Guitar +{ % a tab style. this must come BEFORE 'Tablature' + + /Times-Roman 8 ChooseFont + StdParser % usual method of entry. + /TextHandler + {% what to do with text.depends how many text objects you have. + { + { (chord) {pop 0 IsTextRow} } + { (lyric) {pop 7 IsTextRow} } + } ifcase + } def + + /TabHandler + {% what you call the rows that contain strings. + { + { (e) {pop 1 IsRow} } + { (B) {pop 2 IsRow} } + { (G) {pop 3 IsRow} } + { (D) {pop 4 IsRow} } + { (A) {pop 5 IsRow} } + { (E) {pop 6 IsRow} } + { /default {IsFret}} + } ifcase + } def + %template + + [() [()][()][()][()][()][()] ()] +} def +/ASCIItab +{ % a tab style. this must come BEFORE 'Tablature' + + /Times-Roman 8 ChooseFont + [[()][()][()][()][()][()]] + Tablature + ASCIIparser +} def +%------------------------------------------------------------------------------- +%-DOCUMENT SETUP---------------------------------------------------------------- +%This section defines the margins of the page, and +%the line thickness used in the program. you may want +%to change some of this. +%------------------------------------------------------------------------------- +GetPageMargins +/LeftMargin 1 inch smaller +/RightMargin 1 inch smaller +/TopMargin 1 inch smaller +/BottomMargin 1 inch smaller +0.1 setlinewidth +/Text +{ + /Times-Roman 8 ChooseFont +} def +%------------------------------------------------------------------------------- +%-DOCUMENT---------------------------------------------------------------------- +% Your PStab files are added beyond this point. +%------------------------------------------------------------------------------- |