Article View: comp.lang.postscript
Article #4163Re: text formatters written in PostScript?
From: Lance R. Bailey
Date: Fri, 16 Oct 1992 10:33
Date: Fri, 16 Oct 1992 10:33
320 lines
13514 bytes
13514 bytes
In article <1bkhvdINNdku@gap.caltech.edu> carl@SOL1.GPS.CALTECH.EDU (Carl J
Lydick) writes:
>No, we're not. We realize that were such a program available, one could
simply
>download the program and the text to the PostScript printer and let IT do the
>formatting. If we use more than one operating system in our work, it wouldn't
>be necessary to port the code for the formatter to each operating system.
well, this is NOT an automajik text formatter in PS, but it is the latest
(as of last night) version of ParaShow, my easyformatter in PostScript.
The problem was that when creating slides, or summat with BASIC text
formatting, I would be pulling out my hair while manually linebreaking and
positioning. adding a single word could cause 10 minutes of shuffling "moveto"s
to get things lined up again.
ParaShow takes some simple definitions such as margins, linespacing, format
style and "what to do with the currentpoint after the text"
ParaShow will not stay within the page edges. ParaShow will not do page
breaking. ParaShow DOES allow you to quickly format sections of text on
a page.
There are couple of improvements over the last version,
- the line spacing is no longer negative. I kept going "up" the page,
so allowed a positive line spacing to be "up"
- instead of specifying the maximum line width, and working from the
currentpoint, you specify the left and right margin. the Y value is
still pulled from currentpoint.
- the currentpoint may be placed in 4 different ways after the text is
printed (see below)
usage::
int int int int int int string ParaShow -
CP LS LM RM I FT S ParaShow -
CP is where the currentpoint will be located after the text is printed.
0 - place where the next line of text would have gone.
1 - place where the next line of text would have gone, BUT with one blank
line insterted (useful for leaving blank line betwixt blocks of text)
2 - leave at the end of the last line
3 - as with '2', but with a single space added. makes it possible to change
fonts in the middle of a paragraph.
LS is the linespaceing. a positive integer means DOWN the page
LM is the left margin
RM is the right margin
I is the indent on the first line. a negative gives hanging paragraphs
FT is the format type
0 - is filled text (acheived by stretching the text)
1 - is left justified
2 - is right justified
3 - is centered
S is the string. preceeding spaces are removed, multiple spaces are compacted
There are two test pages: the first shows each of the four format styles with
each of the four "where to leave currentpoint treatments". An X marks the
position of currentpoint.
the second page shows how to use the code to handle font changes in mid
paragraph.
--
Lance R. Bailey System/Network Manager Robarts Research Institute
NeXT/email: zaphod@ctrg.rri.uwo.ca box: Clinical Trials Resources Group
fax: +1 519 663 3789 P.O. Box 5015, 100 Perth Dr.
vox: +1 519 663 3787 x4108 London, Canada N6A 5K8
My Canada Includes the World Series
-------cut-here-------------------------------------------------------
%!PS-Adobe-2.0 EPSF-2.0
% ParaShow -- take a string and format it into a paragraph
% realized by lance bailey (zaphod@uuserve.on.ca, lrb@rri.uwo.ca)
%
%lineAfterText linespace maxlen indent text formattype ParaShow -
%boolean int int int string int ParaShow -
/ParaShowDict 10 dict def
ParaShowDict begin
/showIT {} def
/concatonate % string1 string2 CONCATONATE string2string2
{ 2 copy length exch length dup 5 1 roll add string
dup dup 6 1 roll 4 1 roll
5 -1 roll 3 -1 roll putinterval 0 exch putinterval
}bind def
/length2 % string string LENGTH2 int
{stringwidth pop exch stringwidth pop add}def
/isblank % string ISBLANK boolean is the supplied
*character* a string?
{(\t\n\r\f ) exch search {pop pop pop true}{pop false} ifelse } def
/getword % string GETWORD remainingstring word true
% string GETWORD string false
{ dup dup () eq
{pop false}
{ 0 { 2 copy get ( ) dup 0 4 -1 roll put isblank not
{exit}if 1 add 2 copy exch length ge {pop pop -1 exit} if
} loop
dup -1 eq{pop pop () false}
{ dup 4 1 roll { 2 copy get ( ) dup 0 4 -1 roll put isblank
{exch pop exit}if 1 add 2 copy exch length ge {pop pop -1 exit} if
} loop
dup -1 eq{ pop dup length 3 -1 roll dup 3 -1 roll sub neg
getinterval()exch true}
{ 2 copy 2 copy 7 -1 roll dup 3 1 roll sub getinterval 5 1 roll
{ 2 copy get ( ) dup 0 4 -1 roll put isblank not
{exch pop exit}if 1 add 2 copy exch length ge {pop pop 0 exit}
if
} loop
dup 0 eq {pop pop pop () exch true}
{ exch pop exch dup length 3 -1 roll dup 3 1 roll sub
getinterval exch true
} ifelse
} ifelse
} ifelse
} ifelse
} def
/buildline % maxlen builtline text BUILDLINE maxlen remainder string
{ { getword % stack is maxlen builtline string word true
% OR stack is string () false
{ exch 4 1 roll % stack is string maxlen builtline word
2 copy length2 ( ) exch % stack is string maxlen builtline word ( )
lenofnew
5 -1 roll dup 3 -1 roll % stack is string builtline word ( ) maxlen
maxlen lenofnew
gt % stack is string builtline word ( ) maxlen
{ 5 -1 roll dup () eq {5 2 roll pop ()}{5 2 roll}ifelse concatonate
concatonate exch % stack is maxlen string new-builtline
}
{ 5 1 roll concatonate % stack is maxlen string builtline word( )
exch dup length 1 sub dup 0 lt{pop 0}if 0 exch getinterval exch
3 -1 roll concatonate % stack is maxlen builtline word string( )
exit
}ifelse
}
{exit}ifelse
} loop
exch
} def
/textshow
[{dup stringwidth pop 3 -1 roll exch div 1 scale show}
{show pop}
{dup stringwidth pop 2 div neg 0 rmoveto show pop}
{dup stringwidth pop neg 0 rmoveto show pop}
] def %fill leftjustified centered rightjustified
/LLS %last line show, how to show the last line of text
[{dup stringwidth pop exch show}
{dup stringwidth pop exch show}
{dup stringwidth pop dup -2 div 0 rmoveto exch show 2 div}
{dup stringwidth pop dup neg 0 rmoveto exch show neg}
] def %fill leftjustified centered rightjustified
/LLP %last line pos, how to place currentpoint after the last line of text
[ {pop dup add 0 exch rmoveto}
{pop 0 exch rmoveto}
{0 rmoveto pop}
{dup 0 lt ( ) stringwidth pop exch {neg}if add 0 rmoveto}
] def % Extra line, no Extra line, just after text, after text with a blank
/FLP %first line pos, how to place currentpoint before the first line of text
[ {exch dup currentpoint exch pop moveto sub}
{exch dup currentpoint exch pop moveto sub}
{2 copy add 2 div currentpoint exch pop moveto exch sub}
{dup currentpoint exch pop moveto exch sub}
] def %fill leftjustified centered rightjustified
end
%stack should contain (from top down)
% format int: 0=filled, 1=left justified, 2=centered, 3=right justified
% text string: all blanks, tabs and newlines reduced to single blank
% indent int: indent of first line measured in pts, use 0 on centered
text
% leftmarg int: left margin
% rightmarg int: right margin
% linespace int: line spacing desired
% extra line boolean: do we print a blank line after the paragraph
%we calculate
% maxlen int: maximum length of a line
% showIT proc: how to show the lastline
/ParaShow %currentpoint linespace leftmarg rightmarg indent formattype text
PARASHOW -
%int int int int int int string
PARASHOW -
%CP LS LM RM I FT S
PARASHOW -
{ ParaShowDict
begin
exch dup 6 4 roll 4 -1 roll %stack is CP LS I text FT LM RM
FT
FLP exch get exec %stack is CP LS I text FT ML
4 1 roll %stack is CP LS ML I text FT
dup 7 1 roll %stack is FT CP LS ML I text FT
5 -1 roll neg 5 1 roll % "fix" (negate) the linespacing
textshow exch get/showIT exch def %stack is FT CP LS ML I text
{ 3 1 roll 2 copy %stack is FT CP LS text ML I ML I
8 -1 roll dup 9 1 roll 3 eq{dup neg exch}{dup}ifelse %tweek indenting on
rightjustify
0 rmoveto sub %stack is FT CP LS text ML I ML-I
4 -1 roll %stack is FT CP LS ML I ML-I text
() exch buildline %stack is SLL CP LS ML I ML-I
remainder text
2 copy pop length 0 eq % END IF REMAINDER NULL
{ 8 1 roll 4{pop}repeat 4 2 roll % stack is CP LS text FT
LLS exch get gsave exec grestore % get and exec proc to show
lastline
3 -1 roll % stack is LL LS CP,currentpoint
is end of text
LLP exch get exec % get and exec the proc to place
currentpoint
exit % EXIT POINT!!!
} if
3 -1 roll exch dup()eq %stack is FT CP LS ML I
remainder ML-I text
{pop pop}{gsave showIT grestore}ifelse %stack is SLL CP LS ML I
remainder
exch dup neg 0 rmoveto 3 -1 roll %stack is FT CP LS remainder I ML
exch pop 0 %stack is FT CP LS remainder 0 ML
4 -1 roll dup 0 exch rmoveto %stack is FT LS remainder 0 ML CP
4 1 roll 3 -1 roll %stack is FT CP LS ML 0 remainder
} loop
end
} def
% sample test stuff
{ /X {-3 -3 rlineto 6 6 rlineto -3 -3 rlineto -3 3 rlineto 6 -6 rlineto stroke}
def
gsave
/Time-Roman findfont 10 scalefont setfont 200 780 moveto
0.9 dup scale
0 12 200 400 0 0 (this is some text for a test of the code we are testing)
ParaShow
gsave X grestore 0 -30 rmoveto
0 12 200 400 0 1 (this is some text for a test of the code we are testing)
ParaShow
gsave X grestore 0 -30 rmoveto
0 12 200 400 0 2 (this is some text for a test of the code we are testing)
ParaShow
gsave X grestore 0 -30 rmoveto
0 12 200 400 0 3 (this is some text for a test of the code we are testing)
ParaShow
gsave X grestore 0 -30 rmoveto
1 12 200 400 0 0 (this is some text for a test of the code we are testing)
ParaShow
gsave X grestore 0 -30 rmoveto
1 12 200 400 0 1 (this is some text for a test of the code we are testing)
ParaShow
gsave X grestore 0 -30 rmoveto
1 12 200 400 0 2 (this is some text for a test of the code we are testing)
ParaShow
gsave X grestore 0 -30 rmoveto
1 12 200 400 0 3 (this is some text for a test of the code we are testing)
ParaShow
gsave X grestore 0 -30 rmoveto
2 12 200 400 0 0 (this is some text for a test of the code we are testing)
ParaShow
gsave X grestore 0 -30 rmoveto
2 12 200 400 0 1 (this is some text for a test of the code we are testing)
ParaShow
gsave X grestore 0 -30 rmoveto
2 12 200 400 0 2 (this is some text for a test of the code we are testing)
ParaShow
gsave X grestore 0 -30 rmoveto
2 12 200 400 0 3 (this is some text for a test of the code we are testing)
ParaShow
gsave X grestore 0 -30 rmoveto
3 12 200 400 0 0 (this is some text for a test of the code we are testing)
ParaShow
gsave X grestore 0 -30 rmoveto
3 12 200 400 0 1 (this is some text for a test of the code we are testing)
ParaShow
gsave X grestore 0 -30 rmoveto
3 12 200 400 0 2 (this is some text for a test of the code we are testing)
ParaShow
gsave X grestore 0 -30 rmoveto
3 12 200 400 0 3 (this is some text for a test of the code we are testing)
ParaShow
gsave X grestore 0 -30 rmoveto
grestore
showpage
} exec
{ /ROMAN {/Times-Roman findfont 20 scalefont setfont}def
/BOLD {/Times-Bold findfont 20 scalefont setfont}def
100 740 moveto 400 740 lineto stroke
200 720 moveto
ROMAN
3 22 100 400 0 1 (this is some text which preceeds a bold word. Here is the
word:)ParaShow
BOLD
3 22 100 400 currentpoint pop 100 sub 1 ( bold ) ParaShow
ROMAN
2 22 100 400 currentpoint pop 100 sub 1 (and here we are continuing
onwards.) ParaShow
showpage
} exec
Technical Details
Message-ID:
<1992Oct16.103330.14581@julian.uwo.ca>Path:
arc1-ca.pugleaf.net!sparky!uunet!gatech!destroyer!cs.ubc.ca!utcsri!torn!newshost.uwo.ca!newsReferences:
<1bkhvdINNdku@gap.caltech.edu>Show Full Headers
Complete Article Headers
Newsgroups: comp.lang.postscript Path: arc1-ca.pugleaf.net!sparky!uunet!gatech!destroyer!cs.ubc.ca!utcsri!torn!newshost.uwo.ca!news From: zaphod@ctrg.rri.uwo.ca (Lance R. Bailey) Subject: Re: text formatters written in PostScript? Reply-To: zaphod@ctrg.rri.uwo.ca Organization: University of Western Ontario Distribution: na Date: Fri, 16 Oct 1992 10:33:30 GMT Message-ID: <1992Oct16.103330.14581@julian.uwo.ca> References: <1bkhvdINNdku@gap.caltech.edu> Keywords: long Sender: news@julian.uwo.ca (USENET News System) Nntp-Posting-Host: cupoftea.ctrg.rri.uwo.ca Lines: 324