summaryrefslogtreecommitdiff
path: root/support/pstab
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/pstab
Initial commit
Diffstat (limited to 'support/pstab')
-rw-r--r--support/pstab/PStab1027
-rw-r--r--support/pstab/copying416
-rw-r--r--support/pstab/manual.pst948
-rw-r--r--support/pstab/readme20
4 files changed, 2411 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.
+%-------------------------------------------------------------------------------
diff --git a/support/pstab/copying b/support/pstab/copying
new file mode 100644
index 0000000000..6757284672
--- /dev/null
+++ b/support/pstab/copying
@@ -0,0 +1,416 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+
+
+
+
+
+
+
+
+
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+
+
+
+
+
+
+
+
+
+
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/support/pstab/manual.pst b/support/pstab/manual.pst
new file mode 100644
index 0000000000..f7ea908598
--- /dev/null
+++ b/support/pstab/manual.pst
@@ -0,0 +1,948 @@
+NewDoc Centred
+(PStab v2.0
+A system for typesetting tablature.
+(c) 1994 Brian Ewins.
+
+Contents)
+NewStyle Text
+(
+Introduction
+Writing PStab files
+The Verbatim Style
+The Centred Style
+The Verses Style
+The ChordPro Style
+The Chords Style
+The Guitar Tablature Style
+The ASCIItab Style
+Getting Control of The Layout
+Writing Tablature Styles
+Writing General Styles
+Copyrights & Copylefts
+About the Author
+)
+NewStyle Centred
+(Introduction:
+or
+Zen and the Art of Programming)
+NewStyle Text
+(
+For me, there are some things you must obey when writing \
+a program:
+*It must be original.
+Well, that rules out most shareware stuff.
+*It must be backwards compatible.
+Hello, Microsoft?
+*It must be portable.
+*If it needs a manual, it sucks.
+Hello, Microsoft (again)?
+
+I have attempted in this program to address all these \
+questions. I've certainly never seen anything like this \
+program before, and it can make sense of ChordPro, and \
+ASCII'd tablature. \
+I chose to write it in PS and not in TeX because some \
+people out there don't have TeX, and I didn't write it \
+in C because some people don't have compilers. However, \
+almost everyone has access to a PS printer, and anyone \
+can get hold of GhostScript for free to view this stuff. \
+In fact, I didn't know PS at all before I wrote this, \
+which shows how seriously I took the choice of language. \
+As for the manual. Well, this is more of an ideal than \
+something you can ever manage to stick to. I did put \
+a lot of thought into the syntax for entering tab, chords, \
+etc, and hopefully this shows through in ease of use. \
+And now, with a tinge of regret, the manual.
+)
+NewStyle Centred
+(Writing PStab files)
+NewStyle Text
+(
+This is the manual for PStab, a program for typesetting tablature. \
+PStab is very flexible, and it's not limited to having only one \
+guitar, or to using guitar tab instead of, say, bass tab. It can also \
+typeset words of songs in a nice way, and is backwards compatible \
+with ChordPro, and can even make ASCII tablature look nice for \
+printing too. As an example of how flexible this program is: \
+since this manual contains many examples of \
+PStab's output, it seemed only natural to use PStab to typeset it, \
+and PStab was up to the task ! O.K. so TeX it ain't, but if you can \
+read this, then you can use PStab --- the program is written in \
+PostScript, and so is more portable than most.
+),
+(PStab is designed somewhat along the line of LaTeX, for those who \
+are familiar with that system.That is to say, there is a core system \
+for typesetting, on top of which you layer 'styles' which use \
+the core functions, to hide the intimate workings of the program \
+from the end user. Since the commands that you 'see' depend on which \
+style you are using, you should read the sections on each style to \
+learn how they work. To make this easy, they all follow pretty much \
+the same design.
+),
+(Firstly, though, I should describe how to write the bare bones of \
+a PStab document. Here is a small document:
+)
+NewStyle
+(GetPageMargins
+/LeftMargin 1 inch smaller
+/RightMargin 1 inch smaller
+/TopMargin 1 inch smaller
+/BottomMargin 1 inch smaller
+0.1 setlinewidth
+NewDoc
+\(Hello World\)
+EndDoc)
+NewStyle Text
+(
+What does this do? GetPageMargins is a command to find out the \
+size of page your printer uses. You don't have to tell PStab that \
+you've got A4 instead of US Letter, or any other size, it figures \
+it out for itself. You must use this command, to give values to \
+the margins. The next step was to move the margins in a bit. They're \
+only a couple of mm in on my printer, so output would look ugly if \
+I left them as they were. If you want to have them some other distance \
+than 1 inch in from the page edge, change the 1 to something else. \
+PostScript doesn't 'know' inches, or 'smaller', I put those in the \
+program to make this easier to understand. 'setlinewidth' is a \
+PostScript command to change the width of lines it draws. \
+The 0.1 sets it to be 1/720 of an inch. Next, I used NewDoc and \
+EndDoc. These set up the program to expect PStab, and clean up \
+afterwards. Notice that Hello World is enclosed in brackets.
+
+To print this '.pst' file, you attatch it to the end of the \
+program, and send the whole thing to the printer. The end of \
+the program in this case would be at the comment saying \
+'DOCUMENT SETUP'. However, you are the only person ever \
+likely to want to adjust your page margins, so '.pst' documents \
+will commonly start with a 'NewDoc' command, and should be \
+tagged on to the program after the 'DOCUMENT' comment. If you \
+look at this file with an editor, this should all become \
+clear, since the manual itself is tagged on in this way.
+
+The example described above \
+gets displayed at the top left of a page in the default style, \
+which looks like this:
+)
+NewStyle Verbatim
+(Hello World)
+NewStyle Text
+(
+This style, which I use in the manual to indicate what you should \
+type, is called Verbatim. It performs simple linebreaking on plain text.\
+In fact, all of the text in this manual uses this style, with the font \
+changed to make the difference between the text and examples clear. \
+How do you change styles then ? Here is an example:
+)
+NewStyle
+(NewStyle Verbatim)
+NewStyle Text
+(
+This cleans up after the last style used, and changes to Verbatim.\
+Generally, you replace Verbatim by the name of the style you want to \
+use. There are seven styles distributed with this program, but I expect \
+others to make up their own for particular documents, just as I did \
+to make the text you're reading appear in this font. I will describe \
+how to write a style towards the end of this document.
+
+Now I'll go on to describe all of the distributed styles individually.
+)
+NewStyle Centred
+(The Verbatim Style)
+NewStyle Text
+(
+Commands to begin Style:
+)
+NewStyle
+(NewDoc
+NewDoc Verbatim
+NewStyle
+NewStyle Verbatim)
+NewStyle Text
+(
+Any of these commands start up the Verbatim style. \
+Note however that you only use the NewDoc command at \
+the start of a PStab file: repeated use without an \
+accompanying EndDoc will cause an error. The NewStyle \
+command cleans up whats left at the end of each section \
+of a style, and then starts up in the new one. I have \
+put an identical 'commands' section at the start of each \
+style decription, the comments in this paragraph apply \
+to all of them.
+
+The Verbatim style is the is the default, since it displays \
+plain text acceptably. Here is an example of its use:
+)
+NewStyle
+((Hello \\\(),(I break lines wherever I see a comma outside),
+(the brackets ( and ), or at a newline
+in the input, or),
+(I break very very very very very very very very very\\
+ very very very very very very very very very very very\\
+ very very very very very very very very very very very\\
+ very very very very very very very very very very very\\
+ very very very very very very very very very very very\\
+ long lines up if I have to.),
+(the last piece of text has no comma after it.))
+NewStyle Text
+(
+Which displays like this:
+)
+NewStyle
+(Hello \(),(I break lines wherever I see a comma outside),
+(the brackets ( and ), or at a newline
+in the input, or),
+(I break very very very very very very very very very\
+ very very very very very very very very very very very\
+ very very very very very very very very very very very\
+ very very very very very very very very very very very\
+ very very very very very very very very very very very\
+ long lines up if I have to.),
+(the last piece of text has no comma after it.)
+NewStyle Text
+(
+Note the use of backslashes to protect unpaired brackets,\
+while paired brackets are OK. Backslashes also prevent automatic \
+line breaks at newlines in the input, in the styles which do that. \
+The backslash character itself is also has to be protected \
+by a backslash. For more about character escapes, as these \
+are called, you should read 'The PostScript Language Tutorial \
+and CookBook' by Adobe Systems Inc. You shouldn't need to \
+know these for normal use of the program.
+)
+NewStyle Centred
+(The Centred Style)
+NewStyle Text
+(
+Commands to begin Style:
+)
+NewStyle
+(NewDoc Centred
+NewStyle Centred)
+NewStyle Text
+(
+This is the style which produced the title at the top of this \
+page. It's very similar to the Verbatim style. Here is an \
+example of its use :
+)
+NewStyle
+((Hello),(I break lines wherever I see a comma outside),
+(the brackets ( and ), or at a newline
+in the input, or),
+(I break very very very very very very very very very\\
+ very very very very very very very very very very very\\
+ very very very very very very very very very very very\\
+ very very very very very very very very very very very\\
+ very very very very very very very very very very very\\
+ long lines up if I have to.),
+(the last piece of text has no comma after it.))
+NewStyle Text
+(
+Which displays like this:
+)
+NewStyle Centred
+(Hello),(I break lines wherever I see a comma outside),
+(the brackets ( and ), or at a newline
+in the input, or),
+(I break very very very very very very very very very\
+ very very very very very very very very very very very\
+ very very very very very very very very very very very\
+ very very very very very very very very very very very\
+ very very very very very very very very very very very\
+ long lines up if I have to.),
+(the last piece of text has no comma after it.)
+NewStyle Text
+(
+I'm kinda pleased with the linebreaking algorithm here, \
+it uses up very little in terms of memory. Not that anyone \
+out there really cares about this - do you ?
+)
+NewStyle Centred
+(The Verses Style)
+NewStyle Text
+(
+Commands to begin Style:
+)
+NewStyle
+(NewDoc Verses
+NewStyle Verses)
+NewStyle Text
+(
+This style is for printing the verses of songs. It tries to place as \
+many verses as it can alongside each other, and if placing the next \
+would go across the right margin, it moves down to the next available \
+space before printing it. Each verse is contained between a single \
+pair of brackets. Here is an example of its use:
+)
+NewStyle
+(I print verses in a row,
+The next line gets put down below,
+Mumble mumble rhymes with grow
+Done this verse, now on we go!),
+(I print verses in a row,
+The next line gets put down below,
+Mumble mumble rhymes with grow
+Done this verse, now on we go!
+This ones longer than the rest,
+To put my linebreaks to the test.
+Where's the next line? yes, you've guessed,
+I print it in the place that's best!),
+(I print verses in a row,
+The next line gets put down below,
+Mumble mumble rhymes with grow
+Done this verse, now on we go!),
+(I print verses in a row,
+The next line gets put down below,
+Mumble mumble rhymes with grow
+Done this verse, now on we go!)
+NewStyle Text
+(
+Which generates this:
+)
+NewStyle Verses
+(I print verses in a row,
+The next line gets put down below,
+Mumble mumble rhymes with grow
+Done this verse, now on we go!),
+(I print verses in a row,
+The next line gets put down below,
+Mumble mumble rhymes with grow
+Done this verse, now on we go!
+This ones longer than the rest,
+To put my linebreaks to the test.
+Where's the next line? yes, you've guessed,
+I print it in the place that's best!),
+(I print verses in a row,
+The next line gets put down below,
+Mumble mumble rhymes with grow
+Done this verse, now on we go!),
+(I print verses in a row,
+The next line gets put down below,
+Mumble mumble rhymes with grow
+Done this verse, now on we go!)
+NewStyle Centred
+(The ChordPro Style)
+NewStyle Text
+(
+Commands to begin Style:
+)
+NewStyle
+(NewDoc ChordPro
+NewStyle ChordPro)
+NewStyle Text
+(
+This style is meant to reproduce the output of the ChordPro program \
+directly from chordpro files. If you're not familiar with that \
+program, basically the idea is that you type the text of the \
+song with chord names in square brackets at the point where \
+you change chord. The program's main function is to place \
+these chord names above the text at that position, as you \
+would see in many guitar books. Here's an example:
+)
+NewStyle
+(({title:The Manual Song}
+{st:No-one has yet claimed responsibility}
+[D]I print verses [A7]in a [D]row,
+The next line gets put [A7]down be[D]low,
+Mumble mumble [A7]rhymes with [D]grow [G][G#][A][Bb][C][D]
+Done this verse, now [A7susX]on we [quietly]go!
+
+{c:chorus}
+
+[D]The second verse is [A7]like the [D]first,
+The music poor, the [A7]verse is [D]worse,
+I wrote this since [A7]I'd get [D]sued,
+If I used real songs. [A7]This'll [D]do.
+))
+NewStyle Text
+(
+Which generates this:
+)
+NewStyle ChordPro
+({title:The Manual Song}
+{st:No-one has yet claimed responsibility}
+[D]I print verses [A7]in a [D]row,
+The next line gets put [A7]down be[D]low,
+Mumble mumble [A7]rhymes with [D]grow [G][G#][A][Bb][C][D]
+Done this verse, now [A7susX]on we [quietly]go!
+
+{c:chorus}
+
+[D]The second verse is [A7]like the [D]first,
+The music poor, the [A7]verse is [D]worse,
+I wrote this since [A7]I'd get [D]sued,
+If I used real songs. [A7]This'll [D]do.
+)
+NewStyle Text
+(
+Note how the chord placing is done properly, but other \
+commands are ignored. Whole ChordPro files can be encapsulated \
+this way, and printed without using ChordPro at all. \
+PStab does not automatically generate a chord table, as \
+ChordPro does, even though I could support this. There are very \
+good reasons for not doing so, \
+to do with printer memory, but none for reproducing this \
+feature, other than laziness on your part, I guess.
+
+The style also spaces out the run of chords \
+in the first verse properly, which is there to \
+show you how you're supposed to type sharps and \
+flats. The line after this shows that you can put \
+anything above the text, not just chords.
+)
+NewStyle Centred
+(The Chords Style)
+NewStyle Text
+(
+Commands to begin Style:
+)
+NewStyle
+(NewDoc Chords
+NewStyle Chords)
+NewStyle Text
+(
+This style prints chord diagrams. It knows all of the chords that \
+ChordPro did, over 130 of them. There were a couple of mistakes in \
+the table in that program, which I corrected, but there may be more \
+that I haven't spotted that are still wrong. Here's the example:
+)
+NewStyle
+((A#m),(Bbm),(N),(N) [ 5 6 7 5 ], (Asus2) [ -1 [7 3] [7 4] [6 4] 0 0])
+NewStyle Text
+(
+Which displays like this:
+)
+NewStyle Chords
+(A#m),(Bbm),(N),(dunno) [ 5 6 7 5 ], (Asus2) [ -1 [7 3] [7 4] [6 4] 0 0]
+NewStyle Text
+(
+The first two are examples of chords that PStab knows, with \
+showing how to type sharps and flats. The third is a name that \
+ChordPro doesn't know, which produces a blank, labelled, chord. \
+I think this is more useful than not displaying anything. \
+The last two are examples of specifying a chord: you just type \
+the frets that are to be used, from left to right. Note that they \
+don't have to be guitar chords! The program is intended to be \
+independent of which instrument you use it for. Notice in the \
+final example, I specified which fingers I wanted to hold down \
+certain strings with. Finally, the order matters: you must give \
+the name of the chord before the fingering, if you give both.
+)
+NewStyle Centred
+(The Guitar Tablature Style)
+NewStyle Text
+(
+Commands to begin Style:
+)
+NewStyle
+(NewDoc Guitar Tablature
+NewStyle Guitar Tablature)
+NewStyle Text
+(
+Go on, admit it, you flicked straight to this page, right? \
+This is \(a\) style for setting out tablature. The Tablature \
+engine is in fact a general engine capable of printing \
+for multiple instruments, adding lyrics, comments, and \
+symbols, etc. This page actually describes a substyle I \
+wrote as an example. A substyle provides information \
+about which lines contain text, and which are frets, \
+and also what each of these are called.
+
+This particular substyle -Guitar- describes a line of text called \
+'chord', 6 rows of frets called 'e,B,G,D,A,E' in that order, \
+and a row of text called 'lyric'. Ok, now for some examples:
+)
+NewStyle Guitar Tablature
+(E 0 D 2 {lyric:see how a note run is typed}, E 3,4,5,6),
+(E 0 A 2 D 2 {lyric:here's a picking pattern}, E,A,D,E,D,A),
+(E 0 A 2 D 2 {lyric:watch me justify this}, E,A,D,E,D,A),
+(E 0 A 2 D 2 {lyric:at 12 point it happened there}, E,A,D,E,D,A),
+({lyric:heres some symbols} D {tie},{up},{down},{vib}),
+({harm} {lyric:harmonic},\(3\){tie} {lyric:bend},2),
+({chord:hammer on} {h},{lyric:pull off} {p}),
+({0}{lyric:fingering},{1},{2},{3},{4})
+NewStyle Text
+(
+That was generated from this:
+)
+NewStyle
+((E 0 D 2 {lyric:see how a note run is typed}, E 3,4,5,6),
+(E 0 A 2 D 2 {lyric:here's a picking pattern}, E,A,D,E,D,A),
+(E 0 A 2 D 2 {lyric:watch me justify this}, E,A,D,E,D,A),
+(E 0 A 2 D 2 {lyric:at 12 point it happened there}, E,A,D,E,D,A),
+({lyric:heres some symbols} D {tie},{up},{down},{vib}),
+({harm} {lyric:harmonic},\(3\){tie} {lyric:bend},2),
+({chord:hammer on} {h},{lyric:pull off} {p}),
+({0}{lyric:fingering},{1},{2},{3},{4}))
+NewStyle Text
+(
+The main things to notice here, are:
+* Bars of tablature are in brackets. The program can \
+only break lines at the end of bars. It is actually possible \
+to write a system which can optionally break anywhere, but \
+it is much more complicated.
+* Columns of tablature (notes which are played simultaneously) \
+are separated by commas.
+* Text rows and tablature rows align separately. This means \
+that song lyrics can run under several columns of tab. Unfortunately, \
+it also means that a long lyric followed by a column with a chord in \
+it will leave a big gap in the tab. I know how to fix this, but it \
+makes writing styles less idiot-proof. If I can think of a good way \
+of doing it, it may eventually appear in another release. Don't hold \
+your breath though, because it would probably involve changing how \
+you write styles, and other people will probably have written their \
+own by then.
+* lyrics, chords, etc are written in the column in which they begin.
+* PStab 'remembers' the last thing you played on each string, \
+and also the last string you picked. This is to allow easy \
+entry of note runs (you don't have to keep saying the string) \
+and picking patterns (you don't have to keep sying the notes).
+* PStab interprets anything that isn't the name of a string,
+or a 'special command' (something in curly brackets) as an object \
+to be written on a string - which is why the (3) worked. You
+could even write text in the tab this way.
+* if a special command does not include a colon, then it's some \
+mark to be placed on a string. (the ties, harmonics, etc). Some \
+of the marks I use are non-standard, but they are a compromise \
+between what I should print, and what can be programmed easily.
+* tie marks and slide marks stretch to fill the gap between notes \
+if this changes.
+
+If you use this syntax, the main advantages are that PStab \
+can align lyrics and chords, and place nice-looking marks \
+in the music. However, if you're lazy and have some ASCII'd \
+tablature you want to prettify, PStab has ways of dealing with \
+that too. This is described in the next section.
+)
+NewStyle Centred
+(The ASCIItab Style)
+NewStyle Text
+(
+Commands to begin Style:
+)
+NewStyle
+(NewDoc ASCIItab
+NewStyle ASCIItab)
+NewStyle Text
+(
+I promised I'd do this in this release, and here it is. I have \
+provided a way of defining a Tablature substyle which \
+uses the ASCIIparser instead if the StdParser (the Guitar substyle \
+in the last section used the StdParser). The ASCIIparser takes \
+several rows of text and assumes they are all tab - it doesn't care \
+how many rows there are, as long as it's been told beforehand. It
+then strips out all the minus signs and tries to recognise when objects \
+are lined up in columns. This is difficult, espescially to do quickly \
+as this program must, and there are a few cases where you can make \
+the algorithm do odd things. None of them crash the program, or stop \
+it recognising bar lines - it makes bar lines where it sees a column
+of pipe symbols ( aka logical OR signs ). In fact, a bit after \
+I wrote that piece of code, I found I could easily alter it so \
+that it actually split into lines where it thought there was a bar line, \
+and consequently would break lines better. This works so well, \
+that I can see my own format being redundant (even though it \
+does look nicer, people will always prefer to send ASCII tab). \
+The ASCIItab style I have written to demostrate this assumes that it's \
+looking at guitar tablature-ie 6 rows of text at a time. Heres an \
+example which shows off its capabilities, and its weaknesses:
+)
+NewStyle ASCIItab
+(E ||--0-2-|-3---2-0-----0-2-|---------0-------|-----------------|
+B ||------|---------4-------|-0---2-4-----3-1-|-0---------------|
+G ||@-----|-----------------|-----------------|-----2-0-----0-2-|
+D ||@-----|-----------------|-----------------|---------4-------|
+A ||------|-----0---2---0---|-----------------|-----0---2---0---|
+E ||--3-2-|-0---------------|-3---2---0---2---|-3---------------|),
+
+(|--0--2-|-
+|-------|-
+|-------|-
+|-------|-
+|-------|-
+|--3--2-|-),
+(|---------------0---|
+|-4---0---(0)-----0-|
+|-------------------|
+|-------------------|
+|-2-----3--2--0-----|
+|---------------4---|),
+(|---------------0---|-----------------|-----------------|------------------|
+|-4---0---(0)-----0-|-1---3---0---1---|-----------------|------------------|
+|-------------------|-------2-------0-|-2---4-----------|------------------|
+|-------------------|---2-4-----1-2---|-------4-5---4-2-|-1---2-4-5---4--2-|
+|-2-----3--2--0-----|-0---------------|---4-6-------0---|-2---0---2--(2)---|
+|---------------4---|---------3-------|-2-------0-------|------------------|),
+(|---------------0---|
+|-4---0---(0)-----0-|
+|-------------------|
+|-------------------|
+|-2-----3--2--0-----|
+|---------------4---|)
+NewStyle Text
+(
+Which was generated from this source:
+)
+NewStyle
+((E ||--0-2-|-3---2-0-----0-2-|---------0-------|-----------------|
+B ||------|---------4-------|-0---2-4-----3-1-|-0---------------|
+G ||@-----|-----------------|-----------------|-----2-0-----0-2-|
+D ||@-----|-----------------|-----------------|---------4-------|
+A ||------|-----0---2---0---|-----------------|-----0---2---0---|
+E ||--3-2-|-0---------------|-3---2---0---2---|-3---------------|),
+
+(|--0--2-|-
+|-------|-
+|-------|-
+|-------|-
+|-------|-
+|--3--2-|-),
+(|---------------0---|
+|-4---0---(0)-----0-|
+|-------------------|
+|-------------------|
+|-2-----3--2--0-----|
+|---------------4---|),
+(|---------------0---|-----------------|-----------------|------------------|
+|-4---0---(0)-----0-|-1---3---0---1---|-----------------|------------------|
+|-------------------|-------2-------0-|-2---4-----------|------------------|
+|-------------------|---2-4-----1-2---|-------4-5---4-2-|-1---2-4-5---4--2-|
+|-2-----3--2--0-----|-0---------------|---4-6-------0---|-2---0---2--(2)---|
+|---------------4---|---------3-------|-2-------0-------|------------------|),
+(|---------------0---|
+|-4---0---(0)-----0-|
+|-------------------|
+|-------------------|
+|-2-----3--2--0-----|
+|---------------4---|))
+NewStyle Text
+(
+Note that each set of 6 rows is enclosed by brackets. You must do this. \
+It is possible to interpret whole chunks of text and find the tab - \
+even to the extent that you wouldn't need to say how many lines to \
+expect, and so that it would handle lyrics. \
+However, that is beyond the scope of this program.
+
+Now we play spot the deliberate mistakes. There are 6. Firstly, the \
+tuning in the first line wasn't reproduced: the algorithm is to ignore \
+everything up to the first column of minus signs, so that bar lines \
+don't get displayed. Note that it ignored the 'at' symbols that \
+were intended to denote a repeat for precisely the same reason. \
+In the next line, there is an unfinished empty bar. The program \
+ignores empty bars (part of the algorithm accidentally generates \
+lots of these, so this is necessary). Finally, all of the \
+bracketed numbers appeared in the wrong place. This is because the \
+bracket sticks out over the left edge of the column of things it \
+is supposed to align with. The program decides that the object \
+with the bracket, and the one without the bracket, are in fact \
+in different coulumns, and displays them that way.
+
+All in all, this does a really good job of printing ASCII'd tab, and \
+the things that cause the errors can be easily corrected by you. \
+I think this ought to be enough to satisfy most people.
+
+Incidentally, parts of this tab were from a piece by Bach, tabbed \
+by Michael S. Zraly. Unlike Woodward & Bernstein, I always name \
+my sources !
+)
+NewStyle Centred
+(Getting Control of The Layout)
+NewStyle Text
+(
+You don't have to read this. it contains optional info on \
+generating page breaks and changing fonts.
+
+How to generate a page break: there is no way for me to safely \
+do this, generally, while preserving the current style. Instead, \
+I have written a command which basically ends the current document, \
+and starts again. As an example of how this works, if we were \
+in the Verses style and wanted a page break, we would write:
+)
+NewStyle
+(PageBreak Verses)
+NewStyle Text
+(
+Which generates the required page break, and puts us back into \
+the verses style. Of course, you can actually change to any style \
+at this point - typically you would say 'PageBreak Centred' instead \
+to put a title at the start of the new page.
+
+Changing fonts: there is a command for changing font, called \
+'ChooseFont'. For those who know some PostScript: you should use \
+this instead of 'setfont', since ChooseFont also tells the program \
+the font size for internal use. Here is an example of its use:
+)
+NewStyle
+(/Times-Roman 12 ChooseFont)
+NewStyle Text
+(
+This changes to the font this text is in, in a 12 point size. \
+A point is 1/72 of an inch, and most text in books is somewhere \
+from 8 to 12 points high. Larger sizes are generally used for \
+titles. Note the slash before the name of the font. Obviously, \
+this command will only work if your printer actually has the font. \
+PostScript printers should come with the following fonts:
+Times-Roman,Times-Italic,Times-Bold,Times-BoldItalic,
+Helvetica,Helvetica-Oblique,Helvetica-Bold,Helvetica-BoldOblique,
+Courier,Courier-Oblique,Courier-Bold,Courier-BoldOblique,
+Symbol.
+
+To give you an idea of what these are, this text is Times-Roman, \
+the Centred style produced the titles in this document by default \
+in Helvetica, and the Verbatim style produces Courier. Symbol is \
+not an appropriate font for writing text in. For more on \
+fonts, you should really read 'The PostScript Language Reference \
+Manual', by Adobe Systems Inc.
+
+WARNING:You can only use this command in certain places, or you will \
+confuse the typesetter in the program. A safe place to use it \
+is immediately after you set a style. You can also use it in \
+the Centred and Verbatim styles outside of brackets. As in LaTeX, \
+it is the intention in this program to take your mind off \
+changing fonts by using sensible ones for each section of a \
+document. Hopefully, you'll heed this and use ChooseFont sparingly, \
+but if you don't, your problems are your own. I just described this \
+command so that you know what it does. A better way of using this \
+information, would be to look for the ChooseFont command in the \
+program, in the defnition of each style, and change them there. \
+This isn't recommended, but if you have particularly small or \
+large paper you may want to scale the output accordingly.
+
+Note that the Chords style, and all of the Tablature styles, \
+take account of the font size when drawing diagrams, so they \
+are the right size to fit the characters.
+)
+NewStyle Centred
+(Writing Tablature Styles)
+NewStyle Text
+(
+As usual, I'll proceed by example. Here's a style which would work \
+for guitar and bass with lyrics:
+)
+NewStyle
+(/GtrBass
+{ % 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.
+ {
+ { (lyric) {pop 11 IsTextRow} }
+ } ifcase
+ } def
+
+ /TabHandler
+ {% what you call the rows that contain strings.
+ {
+ { (e) {pop 0 IsRow} }
+ { (B) {pop 1 IsRow} }
+ { (G) {pop 2 IsRow} }
+ { (D) {pop 3 IsRow} }
+ { (A) {pop 4 IsRow} }
+ { (E) {pop 5 IsRow} }
+ { (GG) {pop 7 IsRow} }
+ { (DD) {pop 8 IsRow} }
+ { (AA) {pop 9 IsRow} }
+ { (EE) {pop 10 IsRow} }
+ { /default {IsFret}}
+ } ifcase
+ } def
+ %template
+
+ [[()][()][()][()][()][()] () [()][()][()][()] ()]
+} def)
+
+NewStyle Text
+(
+What's going on here ? I defined the tab layout to be: 6 rows of \
+text with lines through, 1 row of text, 4 rows of text with lines \
+through, and another row of text. I gave the second purely text \
+row (row 11) a name, but not the first (row 6). Why ? Row 6 is always \
+left blank: so we should not make it possible to use it. \
+The program draws bar lines from the top of the staff to the \
+bottom ignoring any such gaps, which is what you expect to \
+see on a score. The object made purely of square and \
+round brackets, if you haven't \
+figured it, tells the program if its looking at text or \
+a fretting: its as simple as that. This line must come immediately \
+before you say 'Tablature' - look at the definitions of ASCIItab \
+and Guitar to see other examples. Normally, all of your \
+homebrew styles will look like this, adding or removing \
+lines from the case statements as necessary.
+
+This style also defines names for all the strings. I have \
+stuck to the same names for each of the guitar strings \
+as before, and have added the names 'EE' 'AA' 'DD' and 'GG' \
+for the bass strings.
+
+Finally, just to prove that the style I defined works, here \
+is a bar of it:
+)
+NewStyle
+ % 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.
+ {
+ { (lyric) {pop 11 IsTextRow} }
+ } ifcase
+ } def
+
+ /TabHandler
+ {% what you call the rows that contain strings.
+ {
+ { (e) {pop 0 IsRow} }
+ { (B) {pop 1 IsRow} }
+ { (G) {pop 2 IsRow} }
+ { (D) {pop 3 IsRow} }
+ { (A) {pop 4 IsRow} }
+ { (E) {pop 5 IsRow} }
+ { (GG) {pop 7 IsRow} }
+ { (DD) {pop 8 IsRow} }
+ { (AA) {pop 9 IsRow} }
+ { (EE) {pop 10 IsRow} }
+ { /default {IsFret}}
+ } ifcase
+ } def
+ %template
+
+ [[()][()][()][()][()][()] () [()][()][()][()] ()]
+Tablature
+( D 1 DD 7 {lyric:An example},A 5 EE 0)
+NewStyle Text
+(
+ASCIItab is different in that it uses a different parser. \
+to rewrite this style, you should just be changing the \
+number of objects in the template. Look at the definition \
+of ASCIItab to see what I mean. The number of these held in the outer \
+pair of brackets is just the number of strings used in the tab.
+)
+NewStyle Centred
+(Writing General Styles)
+NewStyle
+(
+This is very hard - it should only be attempted by PS gurus.\
+I'll explain here a little of the innards of the program, so\
+we can see what functions are essential to a working style.\
+The comma or the end of a style (which calls Flush) should\
+first cause entry to the Parse command. This usually breaks\
+down complex objects into simple objects, and in particular,\
+into objects which should not be broken up by line or page\
+breaks, such as bars or words. For each of these, you should\
+call 'Atom' -and yes, I know you can split Atoms- which\
+in turn immediately calls GetAtom. This function should\
+set, at the very minimum, hbox and vbox, the horizontal\
+and vertical sizes of the object. These should be measured\
+in units of fbox, which is the size of the font. You don't\
+need to set fbox - that gets done by ChooseFont.
+
+Atom decides, given this information, whether or not to\
+split lines, when it calls NewLine, or start a new page,\
+when it calls NewPage. Usually, you then call Display,\
+which prints the object, but some styles I have supplied\
+print out a whole line together, so that Display is\
+called by NewLine and by Flush (it must be called by\
+Flush or the last line will not appear).
+
+And that's it. To summarize, you must define:
+
+*',' (the comma)
+*Flush
+*Parse
+*GetAtom
+*NewLine
+*NewPage
+*Display
+
+Actually, you can call Display anything you like,\
+and not define comma, sice these aren't called by\
+core functions, but in the interest of legibility\
+by others you should at least consider this.
+)
+NewStyle Centred
+(Copyrights & Copylefts)
+NewStyle Text
+(
+Sorry about this, but it's got to be done.
+
+PStab is 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 \
+iven 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.
+
+This manual is part of the distribution of PStab, and is covered by \
+the same licensing agreement.
+
+ChordPro is (c) 1992 Martin Leclerc and Mario Dorion.
+
+PostScript is a registered trademark of Adobe Systems Incorporated.
+)
+NewStyle Centred
+(About the Author)
+NewStyle Text
+(
+I'm a 25 year old balding, bespectacled student, currently late \
+writing up my Ph.D. (on Computational Theoretical Nuclear \
+Physics - I kid you not). I've been playing guitar \
+since I was about 5 years old, and though I've never been \
+great, I can still hack out some Pixies or Tarrega when \
+the mood takes me. But it's always annoyed me how difficult \
+it was to get hold of tab for songs - I have for instance, \
+a copy of a Hendrix music book I got as a present, which \
+just shows the tune he sings, along with chords - and what \
+use is that? Beginners will probably disagree, but anyone can figure \
+out the chords to (most) songs - it easy. So, I was really impressed \
+when I discovered the tab I could get over the net. Never \
+satisfied, however, I thought it was a waste to print out \
+most of it as it stood, because you couldn't make it fit \
+the page properly. After a year or so of saying 'I should \
+do that' I reached breaking point when the other guy in
+my office started writing a Chinese word processor instead
+of writing _his_ thesis. As you can tell, not much real \
+work gets done round here. So, this is what I wrote, and\
+I hope you enjoy it.
+
+I'm releasing this as CardWare - it's actually freeware, \
+and there's no legal obligation on you to do this, but \
+if you liked it, send me a postcard. Preferably with \
+your favourite joke on it. (no need to translate if \
+it's not in English). My home adress is:
+
+23 Tantallon Drive
+Falkirk FK2 8DJ
+Scotland,
+U.K.
+
+I'm just curious who uses it, really.
+
+If you really feel it's worth cash, make a donation to \
+the charity of your choice. Mine would be a Multiple \
+Sclerosis charity.
+
+Comments, and suggestions for a next release, if there \
+ever is one, should be sent to:
+)
+NewStyle
+(gapv64@udcf.gla.ac.uk)
+NewStyle Text
+(
+All the best to you and yours,
+Baz.
+(Brian Ewins) March 14, 1994.
+)
+EndDoc
+
+
+
diff --git a/support/pstab/readme b/support/pstab/readme
new file mode 100644
index 0000000000..adb96a1ea5
--- /dev/null
+++ b/support/pstab/readme
@@ -0,0 +1,20 @@
+This is PStab v2.0
+A system for typesetting guitar tablature,
+(c) 1994 Brian Ewins .
+The distribution should contain:
+*PStab
+this contains the program.
+*manual.pst
+this contains the manual in PStab format.
+*copying
+this is the GNU public license , version 2.
+*readme
+this file.
+
+To print the manual, append the file manual.pst to
+the file PStab, calling it 'something.ps'.(the
+name is irrelevant) Then just print this as you would
+any other postscript file.
+
+ Baz 14/3/94.
+