
        
% ************************************************************************
% ************************************************************************

% GONZO 13 JUSTIFICATION POWER TOOL

% ************************************************************************
%
% SUMMARY: Exceptionally high quality, fully device independent, and ultra
%          fast (but non-WYSIWYG) Don Lancaster text justification routines.
%
%          Includes auto drop caps, hanging punctuation, global kerning,
%          supertabs, callout modes, overstrikes, menu justify, scads more.
%
%          A Distillery-compatible compiling option is included for 
%          unbelievably fast makeready times. Gonzo can also dump
%          plain old ASCII text and can custom emulate nearly anything.
%
%          Gonzo 13 is fully open, unlocked, documented, and reprogrammable.
%
%          Reprinted from Don Lancaster's POSTSCRIPT BEGINNER STUFF.
%
%          Copyright c 1991 by Don Lancaster. All rights fully reserved.
%          Free help line and additional info: (602) 428-4073.
%
% ************************************************************************
      
% Name of textfile: GONZO13A.PTL
% Source:           SYNERGETICS
% Author:           Don Lancaster
% Desc:             Superb quality text justification
% Date:             October 15, 1990
% Release:          13.5.16 (GEnie alpha "A" release)
% Approx length:    46K
% Status:           Copyright 1990 by Don Lancaster and Synergetics.
%                   3860 West First Street, Thatcher, AZ. (602) 428-4073.
%                   All commercial rights reserved. Personal use permitted
%                   so long as this status message stays present and intact.
%                   Gonzo POSTSCRIPT BEGINNER STUFF package $39.50 VISA/MC.
%
% Keywords:         PostScript, gonzo, justification, compile, text

% Approximate NTX run time:   2.50 seconds per 1000 chars (uncompiled)
%                             0.33 seconds per 1000 chars (compiled)

% 	X E     Activate XON/XOFF if necessary.
% 	Z       Values are shown for Apple Super Serial Card


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% WARNING: This is the GEnie "alpha" release. The compile, supertab,
%          and menu justify features are not yet all there.
%
%          KEEP A WRITTEN USER LOG AND EXPECT PROBLEMS.
%
%          Report problems, corrections, questions, etc, to PSRT.
%
%          For further documentation, see PSRT #220 GONZO13A.TXT.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% GONZOJST.PTL is a series of utilities that allow ultra high quality
% text justification from within a word processor or editor environment.
% The routines are fast, fully programmable, use minimum length files, and
% use little VM. They are purposely not WYSIWYG for maximum flexibility,
% speed, and total device independence. Advanced features include auto drop
% caps, hanging punctuation, individual kerning, lastline stretch, simple
% textdumper, callout modes, macros, overstrike, and much more. The routines 
% be used WITHOUT control characters. They can emulate nearly anything.
% An internal compiler is included for extremely fast rerun times.

% Full use instructions appear in the companion file GONZO13A.TXT.
% Also see the internal notes and comments below.

% Status:           Copyright 1990 by Don Lancaster and Synergetics.
%                   3860 West First Street, Thatcher, AZ. (602) 428-4073.
%                   All commercial rights reserved. Personal use permitted
%                   so long as this status message stays present and intact.
%                   Gonzo POSTSCRIPT BEGINNER STUFF package $39.50 VISA/MC.

% Decide if you want to be persistent or not ...


/persist true def
persist {serverdict begin 0 exitserver} if

% create a working dictionary that remains closed until needed ...

1000 dict /gonzo exch def gonzo begin

% USER ALTERABLE COMMANDS - all must remain here as defaults
% =======================

/altescapechar 124 def     % alternate "escape" key for commands (|)
/cstretch  0.2 def         % minimum character kerning
/colcheck { } def          % link to page or column maker
/dropcount 3 def           % lines indented for drop cap
/dropindent 40 def         % width reserved for drop cap
/escapechar 27 def         % "escape" key for commands - can be printable
/gonzocompile false def    % compile to host or disk flag
/gonzojust true def        % allow gonzo commands? (false for text dumper)
/hangflag true def         % hang center, right, or fill punctuation?  
/hangfract 0.6 def         % amount that hung punctuation hangs
/hostcompdelay 80 def      % optional compiling character report delay
/justifylastline false def % fill justify last paragraph line?
/justx (justL) def         % running justification mode
/kern 1 def                % default individual kern amount
/lastlinestretch 0.12 def  % stretch on last line of fill just paragraph
/oktoadvance true def      % don't advance to next line if false
/oktoprint true def        % print suppression flag 
/overstrikechar (\320) def % overstrike character
/overstrikeht 5.5 def      % vertical shift of overstrike character
/pm 10 def                 % normal paragraph indent
/rslashchar 92 def         % "reverse slash" key -alterable-
/rslashok true def         % allow reverse slash processing?
/stringmode false def      % string or currentfile source?
/spacecharratio 6 def      % fill justify ratio of space to char stretch
/sstretch -0.3 def         % minimum space kerning - may be negative
/tabs [50 100 150 200] def % default tab list
/txtwide 350 def           % width of column
/txtwideadj {} def         % custom proc for keystoning, etc.
/xpos 70 def               % horizontal start of text
/yinc 11 def               % line spacing
/ypara 0 def               % additional v space at paragraph end 
/ypos 400 def              % vertical start of text
/ytop 720 def              % default top reference for template
/ybot -9999 def            % default bottom reference for template

% GONZOFONT BUILDER
% =================

% gonzo fontnames MUST be of form /fontx, where x is any printable ASCII 
% character that has also been "qualified" to be a font in the command list.
% A later gonzofont command rapidly sets the font and defines the space width.

% gonzofont accepts either 
%   /font1 /Helvetica 12 gonzofont         -- or else -- 
%   /font1 /Helvetica [wide climb slant high xshift yshift] gonzofont  

/gonzofont {dup type cvlit /arraytype eq {exch findfont exch makefont}
{exch findfont exch scalefont} ifelse setfont mark /spacewidth ( ) 
stringwidth pop /cstretch cvx /add cvx /sstretch cvx /add cvx /def
cvx currentfont dup backcdict exch (F?) dup  1 14 index (xxxxx) cvs
4 get put put /setfont cvx ] cvx def} def

50 dict /backcdict exch def  % used "backwards" during compiling to get
                             % fontname given the "made" font dictionary

% USER FONTS - all should remain here as defaults ...
% ==========

/font0 /Helvetica-Bold [36 0 0 40 0 0] gonzofont     % for drop caps

/font1 /Helvetica 9 gonzofont                        % regular text
/font2 /Helvetica-BoldOblique 9 gonzofont            % reg italic
/font3 /Helvetica-Bold 9 gonzofont                   % reg bold

/font4 /Helvetica 8 gonzofont                        % reg all caps or #s 
/font5 /Helvetica-BoldOblique 8 gonzofont            % italic all caps or #s
/font6 /Helvetica-Bold 8 gonzofont                   % bold all caps or #s

/font7 /Helvetica-Bold [6 0 0 6 0 -2] gonzofont      % subscript
/font8 /Helvetica-Bold [6 0 0 6 0 4] gonzofont       % superscript 

/font9 /Helvetica-Bold [9 0 0 9 0 4] gonzofont       % lowered bold title 

/font- /ZapfDingbats 9 gonzofont                     % Dingbats 
/font= /Symbol 9 gonzofont                           % Greek & Math

/font: /Courier 9 gonzofont                          % Spare
/font; /Courier 10 gonzofont                         % Spare
/font+ /Courier 11 gonzofont                         % Spare


font1  % set default

% SYSTEM CONSTANTS - not normally altered
% ================

/maxcharsbeforecr 6000 def  % maximum number of characters before a cr
/linestring1 maxcharsbeforecr string def % main for normal use
/linestring2 maxcharsbeforecr string def % aux to allow headers
/linestring linestring1 def              % default
/templatestartup {} def                  % default

/maxprocsperline 200 def    % maximum number of procs per print line
/printlist maxprocsperline array def

/dropflag false def         % dropcap flag

%    /exitcheck {} def           % default exit (overwritten by dump template)

      

/firstchar 0 def            % first character pointer
/numspaces 0 def            % initial number of spaces in line  
/pmrun 0 def                % running paragraph margin
/templatestartup {} def     % link to template initializer

% stack conventions during gonzojustify: all procs must restore
% top stack value = next available position in linestring
% next stack value = next available position in printlist

% COMMAND LIST:
% ============

% This command list determines the action of each [esc] selection.
% First, create the list . . .

/commands 256 array def 0 1 255 {commands exch {} put} for

% You can have as many fonts as you like, trading off room for other
% commands. Note that font1 is ASCII 49 and so on.
% Here are the current font character definitions. . .

commands (0) 0 get {font0} put
commands (1) 0 get {font1} put
commands (2) 0 get {font2} put
commands (3) 0 get {font3} put
commands (4) 0 get {font4} put
commands (5) 0 get {font5} put
commands (6) 0 get {font6} put
commands (7) 0 get {font7} put
commands (8) 0 get {font8} put
commands (9) 0 get {font9} put
commands (:) 0 get {font:} put
commands (;) 0 get {font;} put
commands (=) 0 get {font=} put
commands (-) 0 get {font-} put
commands (+) 0 get {font+} put

% justification modes for command list

commands (C) 0 get {justx 4 (C) 0 get put} put  % center justify
commands (F) 0 get {justx 4 (F) 0 get put} put  % fill justify
commands (L) 0 get {justx 4 (L) 0 get put} put  % left justify
commands (R) 0 get {justx 4 (R) 0 get put} put  % right justify 
commands (P) 0 get {justx 4 (P) 0 get put} put  % programmable just #1
commands (Q) 0 get {justx 4 (Q) 0 get put} put  % programmable just #2

% macros for command list 

commands (a) 0 get {amacro} put
commands (b) 0 get {bmacro} put
commands (c) 0 get {cmacro} put
commands (d) 0 get {dmacro} put
commands (e) 0 get {emacro} put
commands (f) 0 get {fmacro} put
commands (U) 0 get {Umacro} put
commands (V) 0 get {Vmacro} put
commands (W) 0 get {Wmacro} put
commands (X) 0 get {Xmacro} put
commands (Y) 0 get {Ymacro} put
commands (Z) 0 get {Zmacro} put

% service routines for command list

commands (h) 0 get {halflinefeedup} put   % half linefeed up 
commands (i) 0 get {initialcap} put       % initial dropcap   
commands (j) 0 get {kern+} put            % positive kerning
commands (k) 0 get {kern-} put            % negative kerning
commands (l) 0 get {linefeeddown} put     % linefeed down
commands (n) 0 get {nobreak} put          % conditional ff
commands (o) 0 get {overstrike} put       % overstrike char 
commands (p) 0 get {/pmrun pm def} put    % normal para indent
commands (s) 0 get {/ypos -10000 def} put % showpage formfeed template link
commands (t) 0 get {plainoldtab} put      % simple tabbing
commands (x) 0 get {exitproc} put         % exit to PostScript 
commands (y) 0 get {fulllinefeedup} put   % negative linefeed
commands (z) 0 get {/pmrun 0 def} put     % zero para indent


% EXPANDED SERVICE ROUTINE DEFINITIONS
% ====================================

/halflinefeedup {/ypos ypos yinc 2 div add def} def

/fulllinefeedup {/ypos ypos yinc add def} def

/linefeeddown {/ypos ypos yinc sub def} def

/nobreak {ypos yinc 6 mul sub ybot lt {/ypos ybot def} if} def

/initialcap {/ypos ypos yinc add ypara add def /pmrun 0
def /indentcount dropcount def /dropflag true def} def

% a simple tab routine for lj only. Tabs relative to xpos

/plainoldtab 

{tabs tabcount get 

dup /roomleft exch txtwide exch sub def
mark exch xpos add ypos /moveto cvx] cvx
printlist exch 3 index exch put
exch 1 add exch
tabcount tabs length 1 sub lt  {/tabcount tabcount 1 add def} if
} def

/kern- {mark kern neg 0 /rmoveto cvx ] cvx printlist exch 3 index
exch put /roomleft roomleft kern add def exch 1 add exch} bind def

/kern+ {mark kern 0 /rmoveto cvx ] cvx printlist exch 3 index
exch put /roomleft roomleft kern sub def exch 1 add exch} bind def

/overstrike {printlist 2 index 1 sub get aload pop pop pop add 1 sub
linestring exch 1 getinterval stringwidth pop dup overstrikechar 
stringwidth pop sub 2 div sub mark exch /gsave cvx exch /cfix
cvx /add cvx /neg cvx overstrikeht /rmoveto cvx overstrikechar /rshowchars
cvx /grestore cvx] cvx printlist exch 3 index exch put exch 1 add exch} def

% stringmacro lets you do a series of gonzolink commands with a single
% macro keystroke. For instance, /amacro {(z3c) stringmacro} def picks
% a centered font3 with no paragraph for an embedded [esc]-a.

/stringmacro { {commands exch get exec} forall} def

% This lets you use [esc]-g instead of startgonzo

(\033g) cvn {startgonzo} def
(|g) cvn {startgonzo} def

% CHARACTER COMMAND ARRAY (fake CASE)
% =======================

% create an executable array based on character to decide who does what

/chararray 256 array def   % decides action of each key

0 1 255 { /posn exch def chararray posn
[posn /chartolinestring cvx ] cvx put} for       % default 1:1 mapping

chararray 
dup 10 {newlineproc} put                         % lf newline
dup 13 {newlineproc} put                         % cr as newline
dup 32 {spaceproc} put                           % spaceproc

dup escapechar {gonzojust {escproc}{exitcheck} ifelse} put    % escape key
dup altescapechar {gonzojust {escproc}{exitcheck} ifelse} put % altesc key
dup rslashchar {rslashok {rslashproc}
{rslashchar chartolinestring} ifelse} put       % rslash key - can alter
pop    

% Charproc simply piles up characters into linestring.
% Other commands decide how these characters are to be used.

/chartolinestring {linestring exch 2 index exch put 1 add } bind def


% exitproc responds to [esc]-x and gets you out of gonzo after printing.

/exitproc {exit} def

% rslashproc takes care of the reverse slashes which are not active when
% not reading strings.

% create an action array 

/slashlist 256 array def 0 1 255 {slashlist exch {} put} for

slashlist 
dup 48 {0 octalnum} put % process as octal number
dup 49 {1 octalnum} put
dup 50 {2 octalnum} put
dup 51 {3 octalnum} put
dup 40 {40 chartolinestring} put % left paren
dup 41 {41 chartolinestring} put % right paren
dup 92 {92 chartolinestring} put % reverse slash 

dup 114 {chararray 13 get exec} put      % carriage return 
dup 108 {chararray 10 get exec} put      % linefeed
dup 116 {slashtab} put                   % tab someday
dup 98 {slashbs} put                     % backspace someday
dup 102 {slashformfeed} put              % formfeed someday
pop

/slashtab {nogot} def  
/slashbs {nogot} def
/slashformfeed {nogot} def
/nogot {reverse_slash _feature_not_yet_defined} def

/rslashproc { 

% currentfile read 


stringmode {getstringchar}{currentfile read} ifelse

{slashlist exch get exec}{exit} ifelse}
bind def

% octalnum handles all reverse slashes followed by three octal nuambers.

/octalproc {

stringmode {getstringchar}{currentfile read} ifelse
{ 48 sub dup dup 0 lt exch 7 gt or 
{pop 0} if} {exit} ifelse} def

/octalnum {8 mul octalproc add 8 mul octalproc add chararray exch get
exec} bind def

% TXTWIDE FITTING SERVICE UTILITIES
% ================================= 

% longstringadj currently lets an all print string longer than
% txtwide invade the margin, rather than forcing a break or error

/longstringadj {dup txtwide ge {pop txtwide 10 div} if} bind def

% doeswordfit attempts to add the length of the current trial word to
% the present line. It returns a positive value if room remains and
% a negative one if not.

/doeswordfit {linestring wordstart dup 3 index exch sub
getinterval dup dup length 0 gt 
 {stringwidth pop exch length cstretch mul add /wordroom exch def} 
 {pop pop /wordroom 0 def} ifelse
roomleft wordroom longstringadj sub dup 0 gt} bind def

% tryspacefit attempts to add a space to the end of the existing word.
% if it fits, word is accepted. If not, line ends.

/tryspacefit {roomleft spacewidth sub dup 0 ge
{/roomleft exch def dup 1 add dup /oktohere exch def /wordstart
exch def 1 add /numspaces numspaces 1 add def} 
      
{pop /wordroom 0 def /oktohere oktohere 1 add def
substart dup oktohere sub neg wordtoplist exch /plistlength exch def
0 exch endtheline /wordstart oktohere def startnextline} ifelse } bind def

% wordtoplist adds word to printlist if positive length. Start out with
% -plistpoint- -charpoint- -startchar- -length- on stack. End with 
% new word grouip in print array and -newplist- -charpoint-.

/wordtoplist {dup 0 gt {mark 3 1 roll dup numchars add /numchars exch def
currentfont /showchars cvx ] cvx printlist exch 3 index exch put exch 1
add exch } {pop pop} ifelse } bind def

% *** ESCPROC ***

% On an escape (or substitute escape) command character ...

%           yes ------ previous word fit? -------- no
%      word to printlist                       closeline
%      do escape command                word to next line always
%                                         word to new printlist
%                                           do escape command

/escproc { doeswordfit
{/roomleft exch def dup dup /oktohere exch def /wordstart exch def
substart dup oktohere sub neg wordtoplist}
{pop substart dup oktohere sub neg wordtoplist exch /plistlength exch
def 0 exch endtheline startnextline dup dup /oktohere exch def /wordstart
exch def substart dup oktohere sub neg wordtoplist /firstchar -1 def 
} ifelse /substart
oktohere def commands 

stringmode {getstringchar}{currentfile read} ifelse {get exec}{exit} ifelse

} bind def

% *** NEWLINEPROC ***

% On as carriage return or newline character ...

%           yes ------ previous word fit? -------- no
%      update word                              closeline
%         closeline                       word to next line always
%                                               closeline

/newlineproc {doeswordfit 

{/roomleft exch def dup dup /oktohere exch def /wordstart exch
def substart dup oktohere sub neg wordtoplist /lastparline true
def exch /plistlength exch def 0 exch endtheline /wordroom 0
def /firstparline true def startnextline}  % word did fit on line

{pop substart dup oktohere sub neg wordtoplist exch /plistlength
exch def 0 exch endtheline startnextline dup dup /oktohere exch
def /wordstart exch def substart dup oktohere sub neg
wordtoplist /lastparline true def exch /plistlength exch def 0
exch endtheline /firstparline true def /wordroom 0 def
startnextline  % word did not fit on line
} ifelse 

pop 0 /substart 0 def /wordstart 0 def /oktohere 0 
def /firstchar -1 def} bind def

% *** SPACE PROC ***

% Leading spaces are ignored in an ongoing paragraph with the firstchar test.
% For speed, "words" may include internal spaces if there is enough room.
%
%              yes ------ previous word fit? -------- no
%         update word                            closeline
%   yes --- word+space fit? -- no          word to next line always
%  update word             closeline     yes -- word+space fit? --- no
%                                      update word               closeline    

/spaceproc { dup firstchar ne {linestring 1 index 32 put doeswordfit
{/roomleft exch def dup 1 sub /oktohere exch def tryspacefit} 
{pop substart dup oktohere sub neg wordtoplist exch /plistlength
exch def 0 exch endtheline startnextline tryspacefit} ifelse} if} bind def

% *** SWALLOW AND HANG ***

% swallowandhang is a dual purpose proc that swallows any trailing spaces
% and optionally hangs punctuation for center, right, and fill justification.

% The swallowlist decides which characters get acted on for hanging.
% The "1" before the hung character lets you individually customize overhang.
% hangfract lets you adjust the overhang of all characters together.

/swallowlist 256 array def

0 1 255 {swallowlist exch {exit} put} for

swallowlist 
dup ( ) 0 get {swallow} put
dup (-) 0 get {1 (-) hangpunct} put
dup (.) 0 get {1 (.) hangpunct} put
dup (,) 0 get {1 (,) hangpunct} put
dup (;) 0 get {1 (;) hangpunct} put
dup (:) 0 get {1 (:) hangpunct} put
dup (") 0 get {1 (") hangpunct} put
dup (') 0 get {1 (') hangpunct} put
dup (}) 0 get {1 (}) hangpunct} put

dup 41 {1 (\051) hangpunct} put  % closing parenthesis  
dup 177 {1 (\261) hangpunct} put  % em dash
dup 208 {1 (\320) hangpunct} put  % en dash
dup 186 {1 (\272) hangpunct} put  % closing double quote
pop

% hangpunct shortens roomleft if hanging is wanted.

/hangpunct { hangflag { stringwidth pop mul hangfract mul roomleft exch
add /roomleft exch def} {pop pop} ifelse exit } bind def

% swallow removes one leading space

/swallow {/lopspaces lopspaces 1 add def} bind def

% swallowandhang first tests for a normal showchars ending. It then runs
% sandh to do the actual swallowing or punctuation hanging.

/swallowandhang {

printlist plistlength 1 sub get 
dup dup length 4 eq


{3 get cvlit /showchars eq {sandh}{pop pop} ifelse}

{pop pop}
 ifelse

} bind def

% sandh grabs the last string of characters and works backwards through
% them, providing a count of total trailing spaces, and hanging selected
% punctuation. The roomleft is then adjusted accordingly.

/sandh {/lopspaces 0 def dup 0 get exch 1 get  linestring 3 1 roll
getinterval /laststring exch def laststring length 1 sub -1 0
{laststring exch get swallowlist exch get exec} for /roomleft lopspaces
spacewidth mul roomleft add def /numchars numchars lopspaces sub
def /numspaces numspaces lopspaces sub def} bind def

% *** LINE CONTROLS ******

% startnextline resets pointers, handles indents, sets up first move.

/startnextline {

oktoadvance {/ypos ypos yinc

   lastparline {ypara add} if sub def

                            } if  % move to next line

colcheck  % link to page template


  /lastparline false def    % can't be the last line
  /substart wordstart def   % point to start of current word
  /numspaces 0 def          % character+space line count 
  /numchars 0 def           % space line count
  /tabcount 0 def           % tab count 

0 firstparline {pmrun add /firstparline false def} if % pm indent?

dropflag {dropcount 0 ge {dropindent add /dropcount dropcount 1 sub def 
dropcount 0 eq {/dropflag false def} if} if} if % indent dropcap?

dup wordroom add neg txtwide add txtwideadj /roomleft exch def
printlist 0 [ 3 index /xymove cvx ] cvx put pop exch pop 1 exch
dup /firstchar exch def} bind def

% endtheline executes a justify proc to set xfix, yfix, cfix and sfix
% and then conditionally prints the printlist ...

/endtheline { justx cvx exec oktoprint {printline} if} bind def
         
% *** JUSTIFY PROCS ********

% The justify procs take the character count, the space count, and roomleft
% and convert these into xfix and yfix entire line offsets and 
% cfix and sfix character and space kerning.

/justC {swallowandhang /sfix sstretch def /cfix cstretch def /xfix roomleft
2 div def /yfix 0 def} bind def

/justF {lastparline {justifylastline {reallyjustF} {justL adjustlastline}
ifelse }{reallyjustF} ifelse} bind def

/justL {/sfix sstretch def /cfix cstretch def /xfix 0 def /yfix 0 def} bind def

/justR {swallowandhang /sfix sstretch def /cfix cstretch def /xfix roomleft
def /yfix 0 def} bind def

/reallyjustF {swallowandhang roomleft numchars 1 sub numspaces
spacecharratio mul add dup 0 eq {pop 0.001} if div dup  cstretch
add /cfix exch def spacecharratio mul sstretch add /sfix exch
def /xfix 0 def /yfix 0 def} bind def % unconditional justF

% optional additional final line stretch is used only if it uses up less
% than 80 percent of the remaining room. Otherwise might look cramped

/adjustlastline { 
numchars 1 sub numspaces spacecharratio mul add lastlinestretch
mul roomleft 0.8 mul lt {/cfix cfix lastlinestretch add 
def /sfix sfix lastlinestretch spacecharratio mul add def} if} def 



% *** PRINT MODULE ********

% printline accepts a series of procs from the printlist and executes them
% It expects a printlist of form [{proc1}{proc2}{proc3}...{procn] and
% these variables predefined ...

%    plistlength    % length of printlist
%    sfix           % total space kerning for line
%    cfix           % total character kerning for line
%    xfix           % total x-shift for line (for centering, rj, etc.)
%    yfix           % total y-shift for line (normally zero) 
%    indent         % first line or drop cap indent 

/sfix 0 def /cfix 0 def /xfix 0 def /yfix 0 def % defaults

/printline {gsave 0 1 plistlength 1 sub {printlist exch get exec} for
grestore} bind def

% some often-used print-time macros . . .

% -stringstart- -stringlength- -madefontdict- showchars --> images string at
% the currentpoint.

/showchars { setfont linestring 3 1 roll getinterval sfix 0 32 cfix
0 6 -1 roll awidthshow1} bind def

/rshowchars {show1} def    % overstrike to compile link

% -indent- xymove ---> does absolute move to xpos + indent, ypos

/xymove {xpos add xfix add ypos yfix add moveto} bind def


% these two links have to stay unbound for Distillery or self-compiling

/show1 {show} def
/awidthshow1 {awidthshow} def

% %%% MAIN GONZO JUSTIFY ROUTINE %%%

% startgonzo reads the currentfile, either piling up printable characters
% into linestring, or acting out escape or space commands.

% and here's gonzo ...

/initgonzostuff {
  /wordroom 0 def
  /firstparline true def
  /lastparline false def
  /wordstart 0 def
  /substart  0 def
  /roomleft txtwide def
  /oksofar 0 def 
  /numchars 0 def
  /lopcount 0 def
  /firstchar -1 def
  /tabcount 0 def
  /gotcr false def
   } bind def

/startgonzo {initgonzostuff 0 0  printlist 2 index
[0 /xymove cvx] cvx put exch 1 add exch
{currentfile read {chararray exch get exec}{exit} ifelse} loop
pop pop % remove pointers from stack
} bind def

% stringgonzo is similar to startgonzo, except that it accepts an
% input string instead of the currentfile. This is handy for deferred
% or predefined uses. stringgonzo is significantly (25%) slower than
% startgonzo. An extra carriage return is always added to the string end.
% to make sure the last line prints.

% Current bugs: can't embed printable \ with \\ or \134 and an extra
% carriage return or double space MUST follow stringgonzo to stay error free.

/stringgonzo {initgonzostuff dup length 1 add dup /gslen exch def string 
dup /gonzostring exch def exch 0 exch putinterval gonzostring gslen 1
sub 13 put /gsptr 0 def /stringmode true def 0 0 printlist 2 index
[0 /xymove cvx] cvx put exch 1 add exch {getstringchar {chararray exch
get exec}{exit} ifelse} loop pop pop /stringmode false def } bind def

/getstringchar {gsptr gslen ge{ false } {gonzostring gsptr get true}
ifelse /gsptr gsptr 1 add def} bind def

% CALLOUT JUSTIFY MODES

% cl accepts an input of form xpos ypos (message) cl and shows it
% at xpos left and within xpos + textwide right.

/cl {save /snapcl exch def /linestring linestring2 def /justx (justL)
def 3 1 roll /ypos exch def /xpos exch def stringgonzo snapcl restore} def 

% cf accepts an input of form xpos ypos (message) cf and shows it
% flush left at xpos and flush right at xpos + textwide.

/cf {save /snapcf exch def /linestring linestring2 def /justx (justF)
def 3 1 roll /ypos exch def /xpos exch def stringgonzo snapcf restore} def 

% cc accepts an input of form xpos ypos (message) cc and centers it
% on xpos. txtwide IS IGNORED, AND ANY WIDTH WILL GET CENTERED.

/cc {save /snapcc exch def /linestring linestring2 def /txtwide 5000
def /justx (justC) def /pmrun 0 def 3 1 roll /ypos exch def 2500
sub /xpos exch def stringgonzo snapcc restore} def 

% cr accepts an input of form xpos ypos (message) cr and sets it
% flush right against xpos. txtwide IS IGNORED, AND ANY WIDTH
% WILL SET FLUSH RIGHT.

/cr {save /snapcm exch def /linestring linestring2 def /txtwide 5000
def /justx (justR) def /pmrun 0 def 3 1 roll /ypos exch def 5000
sub /xpos exch def stringgonzo snapcm restore} def 


% COMPILING ROUTINES

% Compiling can be done either to the host (using a two way comm 
% channel or to hard disk. The compiled files are Adobe Distillery
% compatible but slightly shorter and faster. They can be further
% sped up and shortened with an add-on utility.

% To compile, issue a compiletohost or a compiletodisk after beginning
% gonzo.

/compiletohost {/hostcompflag true def sendcompileheader} def

/compiletohost {/diskcompflag true def sendcompileheader} def

/send { dup hostcompflag { print flush hostcompdelay {37 sin pop}
        repeat}{pop} ifelse
       
        dup diskcompflag { writehere }{pop} ifelse

         pop } def
 

% TEMPLATE LOADER

% starttemplate opens a template whose name is on the top of the stack and
% executes an internally defined template command templatestartup

/starttemplate {begin templatestartup} def

%%%%%%%%%

% SIMPLE TEXT DUMPER

% This default text dumper template is useful for "just dump the text"
% applications. The | and \ characters are handled as ordinary text in
% this example. The only gonzo commands used are for the carriage return
% and the linefeed. A "double escape" | | exits you.

% This template is also useful to list your gonzo programs while PRINTING
% (rather than executing) all internal gonzo commands. (!!!)

% Note that any template MUST have an internal proc named templatestartup
% and that your template MUST NOT call gonzofont before run time.

300 dict /dumpasciitext exch def 

dumpasciitext begin

/templatefonts{
/font1 /Helvetica 8 gonzofont       % regular text (defer till run time)
/font2 /Helvetica-Bold 7 gonzofont  % header font (defer till run time)  
} def

/txtwide 230 def                    % width of column
/pm 0 def                           % no paragraph indents

/lmpos 60 def                       % horizontal left margin
/yinc 9.5 def                       % vertical line spacing
/ytop 720 def                       % top column reference
/ybot 50  def                       % bottom column reference

/pagenum 1 def                      % initial pagenumber

/numcolumns 2 def                   % number of columns
/colspace 260 def                   % spacing between columns  

% colcheck does all the work in a pagemaker. It is automatically called
% at the start of each new printable line. It can make room for figures, etc.

/colcheck {ypos ybot lt {column# numcolumns ge {showpage /ypos ytop
def /xpos lmpos def /column# 1 def header footer}{/ypos ytop def /xpos
xpos colspace add def /column# column# 1 add def} ifelse} if} def 

% This particular header puts the pagenumber into a message string and
% shows it at the right margin of the rightmost column. You can do
% left-right and otherwise get as fancy as you care to here ...

/header {gsave spacewidth font2 rpagenum (xxxxxx) cvs dup length 5 add
string dup 0 (page ) putinterval dup 5 3 index putinterval exch pop
lmpos numcolumns 1 sub colspace mul add txtwide add exch ytop yinc 2.5
mul add exch cr grestore /rpagenum rpagenum 1 add def /spacewidth exch def
} def

/footer {} def       % none today

/templatestartup { templatefonts font1 /column# 1 def /xpos lmpos
def /ypos ytop def/gonzojust false def /rslashok false def 
/rpagenum pagenum def header footer} def

% exitcheck lets you decide how to exit your ASCII text dumper, and can get
% VERY sticky. This example uses a double | | as a "double escape". This
% trick lets you use this template to print a gonzo LISTING that has all 
% of the gonzo commands in it (!), but acts improperly on none of them.

/asciiexitchar (|) def  % exit character reserved if preceeded by altescchar

/exitcheck {currentfile read {dup asciiexitchar 0 get eq {pop exitproc} 
{/chold1 exch def altescapechar chartolinestring chold1 chartolinestring} ifelse}{exitproc} ifelse} def

end  % dumpasciitext template

% Here is a PostScript "textonly" convenience operator that speeds up
% text dumping...

/textonly {dumpasciitext starttemplate startgonzo} def 


%%%%%%%%%

% SIMPLE PAGE MAKING TEMPLATE

% This default gonzo page making template is a useful starting point for
% creating your own custom templates. It handles multiple columns and
% left-right page numabered headers. All gonzo commands are supported.

% Note that there is NO difference between a pagemaker and an emulator.
% Everything is programmable, so just rearrange things to suit yourself.
% Full document control (for figures etc) is done by extending colcheck.

% Note that any template MUST have an internal proc named templatestartup
% and that your template MUST NOT call gonzofont before run time.

300 dict /simplepages exch def 

simplepages begin

/templatefonts {    % Remember: all fonts MUST defer till run time!

/font0 /Times-Bold  [54 0 0 54.2 0 -32] gonzofont  % drop cap
/font1 /Times-Roman  9.75 gonzofont                % main text
/font2 /Times-Italic 9.75 gonzofont                % main italic
/font3 /Times-Bold   9.75 gonzofont                % main bold
/font4 /Times-Roman  9 gonzofont                   % capnum text
/font5 /Times-Italic 9 gonzofont                   % capnum italic
/font6 /Times-Bold   9 gonzofont                   % capnum bold 
/font7 /Times-Bold  [9.75 0 0 9.5 0 -6] gonzofont  % lowered subheader
/font= /Symbol 9.75 gonzofont                      % its greek to me
/font- /ZapfDingbats  [9 0 0 9 0 4] gonzofont      % dingbats

} def

% values used by gonzo justify ...

/colspace 175 def                 % spacing between columns
/cstretch  0.2 def                % minimum character kerning
/dropcount 4 def                  % number of lines drop cap drops
/lastlinestretch 0.06 def         % open last paragraph line slightly
/pm 10 def                        % use paragraph indents             
/sstretch -0.3 def                % minimum space kerning
/txtwide 155 def                  % width of column
/ybot 50  def                     % bottom column reference
/yinc 10.5 def                    % vertical line spacing
/ytop 715 def                     % BASE of top column reference
/yinc 10.5 def                    % vertical line spacing

% additional values used by this template

/firstpagespecial false def       % special treatment for first page?
/lmpos 60 def                     % horizontal left margin
/numcolumns 3 def                 % number of columns
/oddpageright true def            % are odd numbered pages on the right?
/rightpage false def              % start with righthand page?
/pagenum 1 def                    % running pagenumber

% These macros handle an initial drop cap and low center subheads ...

/amacro {(zy0)  stringmacro /ypos
 ypos ypara add def} def             % start drop cap
/bmacro {(iFy1) stringmacro /ypos
 ypos ypara add def} def             % finish drop cap
/cmacro {(znyC7) stringmacro /ypos
 ypos ypara 2 mul add def} def             % centered title
/dmacro {(pF1)  stringmacro /ypos
 ypos ypara 2 mul add def} def             % normal text after centered title

% colcheck does all the work in a pagemaker. It is automatically called
% at the start of each new printable line. It can make room for figures, etc.

/colcheck {ypos ybot lt {column# numcolumns ge {showpage /ypos ytop
def /xpos lmpos def /column# 1 def header footer}{/ypos ytop def /xpos
xpos colspace add def /column# column# 1 add def} ifelse} if} def 

% This particular header picks different formats for left and right pages

/header {pagenum cvi 2 mod 0 eq rightpage {not} if {leftheader}
{rightheader} ifelse /pagenum pagenum 1 add def} def

/headerstripe {gsave xpos ytop 19 add moveto colspace numcolumns 1 sub mul
txtwide add 0 rlineto 0.5 setlinewidth stroke} def

/leftheader {gsave spacewidth font2 pagenum (xxxxxx) cvs dup length 5 add
string dup 0 (page ) putinterval dup 5 3 index putinterval exch pop
lmpos exch ytop yinc 2.5 mul add exch cl grestore headerstripe /spacewidth
exch def} def

/rightheader {gsave spacewidth font2 pagenum (xxxxxx) cvs dup length 5 add
string dup 0 (page ) putinterval dup 5 3 index putinterval exch pop
lmpos numcolumns 1 sub colspace mul add txtwide add exch ytop 25 add
exch cr grestore headerstripe /spacewidth exch def} def

/firstpageheader {} def          % nothing special today

/footer {gsave xpos ybot 6 sub moveto colspace numcolumns 1 sub mul
txtwide add 0 rlineto 1.5 setlinewidth stroke} def

/templatestartup { templatefonts font1 /column# 1 def /xpos lmpos
def /ypos ytop def /gonzojust true def /rslashok true def header
footer} def

end  % simplepages template

%%%%%%%%%%%%%%%%

end  % entire gonzo dictionary

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% END OF GURU'S GONZO JUSTIFY UTILITIES AND TEMPLATES 
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%  //// demo - remove or alter before reuse

gonzo begin
simplepages starttemplate

% These are custom to this particular file ...

/dropindent 38 def      % indent for drop cap - changes with letter


/ypara {yinc 2 div} def

/font+ /ZapfDingbats [9.5 0 0 9.5 0 0] gonzofont

/Umacro {/overstrikechar (~) def /overstrikeht 3.5 def (o) stringmacro} def

/Vmacro {gsave (h) stringmacro xpos ypos 2 add moveto txtwide 0 rlineto 0.3 setlinewidth stroke (h) stringmacro grestore} def

/Wmacro {figone} def

% This simulates a "real" figure

/figone { /figheight yinc 13.5 mul def save /figsnap exch def /ybot -9999 def
xpos ypos figheight sub translate 0 0 moveto 0 figheight 3 add 2 copy 
rlineto txtwide 0 rlineto neg rlineto closepath 0.5 setlinewidth
stroke /font1 /Helvetica-Oblique 9 gonzofont /font2 /Symbol 160 gonzofont      txtwide 2 div 9 (|1Fig. 1 - Join the Gonzo Club) cc 19 38 (|2\247) cl
figsnap restore /ypos ypos figheight sub def} def


startgonzo
|a
T
|b
his is a rather short demo of some of the more powerful features of Don Lancaster's Gonzo justification routines. Its outstanding abilities go far beyond most power applications packages.|p
|c
Gonzo  13  Features
|d
My Gonzo |413|1 features an ultra-high quality text justification that includes automatic drop caps, hanging pun- ctuation, and a global kerning. It is purposely |2not|1 |4WYSIWYG|1 for fastest speed, and total device independence.
You could, of course, pick up full |4WYSIWYG|1 on any system which can support |2Display PostScript|1. Sigh.
Naturally, everything here is fully programmable, totally unlocked, and completely documented. If you don't like what you see, just rearrange the scenery to suit yourself. You can also emulate |2anything|1 using Gonzo |413|1.
While quite fast by itself, a built-in compiler can give you an even more impressive speedup while generating files which are |2Adobe Distillery|1 com- patible. Your compiling can be either to host recorder or hard disk file.
For most pages, the apparent page makeup time will approach |2zero|1 after compiling. This becomes extremely important with any book-on-demand publishing or outputting to a glacial PostScript typesetter.
There are several gonzo modes available, ranging from a "just dump the text" emulator, raw gonzo layouts, layout using templates, layout with a full document control, string modes, and callout justification.
In its "just dump the text" mode, you could also list all of your gonzo code |2while printing and preserving all gonzo commands!|1
Among the bunches of features of interest, such neat tricks as electronic |4R|oS|oT|o|1 complements, or simply heading on down the can|Uon, are easily done from any |2unmodified|1 font|1.
So is a selective |4(A|kW|kARD)|1 kerning on the fly, even while in fill justify. A supertabbing ability lets you mix and match justification modes on a single line. A munu justify feature provides for dotted listings.
Your entire command set is fully programmable. You can redefine any character or any action at any time for any reason. An ultrafast technique known as |2action tables|1 can greatly simplify your custom programming.
If you were to add more text to this demo, it would do multiple three col- umn pages with automatic left-right headers and sequential numbering.
By going to a somewhat fancier template, a total document control including multiple figure and picture insertions is easily handled. We will see lots of examples of these in future |2GEnie|1 |4PSRT|1 uploads.
|W
Please note that, while personal use is permitted so long as all headers and credits are retained, all commercial rights to this |2Synergetics|1 copyrighted code are fully reserved, as is posting on any electronic media.
The complete Gonzo code is now available on |2GEnie|1 |4PSRT|1 library as |4GONZO13A.PTL|1 or higher, while the thorough and detailed documentation is provided as |4GONZO13A.TXT|1. Your |2GEnie|1 voice phone number is |4(800) 638-9635|1.
A complete package of detailed Gonzo use examples is available as Don Lancaster's revised |3PostScript Beginning Stuff|1 book+disk package. |4$39.50. VISA/MC|1.
|V
|2Microcomputer pioneer and guru Don Lancaster is the author of 26 books and countless articles. Don maintains a no-charge technical helpline found at (602) 428-4073, besides offering all his own books, \
reprints, and his technical services. He also has a free brochure of his insider desktop publishing secrets waiting for you. Your best calling times are often |58-5|2 on weekdays, Mountain Standard Time. \
Or you can reach Don by way of |1Synergetics|2, at Box |5809|2, Thatcher, |5AZ 85552|1. |+F|1
|x

showpage quit


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Related GEnie PSRT Downloads: 

%            #220 - GONZO13A.TXT   Gonzo Justify Documentation 
%            #109 - RAWPS.TXT      Working with raw PostScript

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Reprinted from Don Lancaster's POSTSCRIPT BEGINNER STUFF.
% Now available via GEnie email from SYNERGETICS.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

% FREE VOICE HELPLINE AND ADDITIONAL INFO: (602) 428-4073

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

