From: stolte@irit.irit.fr (Nilo STOLTE)
Newsgroups: comp.lang.postscript
Subject: POSTSCRIPT TEXT FORMATTER --> PROG LISTING
Date: 15 Nov 92 19:02:06 GMT
Organization: IRIT-UPS, Toulouse, France

Run the program and the instructions to use it are given. The text is an exemple
of text to be formatted by the program. To put another text, just delete the
given one and put yours...

Nilo.


%!PS-Adobe-1.0
%%Title: Postscript text formatter
%%Author: Nilo Stolte
%%Page:
/reencsmalldict 12 dict def
/ReEncodeSmall
 { reencsmalldict begin
   /newcodesandnames exch def
   /newfontname exch def
   /basefontname exch def
   /basefontdict basefontname findfont def
   /newfont basefontdict maxlength dict def
   basefontdict
   { exch dup /FID ne
     { dup /Encoding eq
       { exch dup length array copy
         newfont 3 1 roll put
       }
       { exch newfont 3 1 roll put
       }
       ifelse
     }
     { pop pop }
     ifelse
   } forall
   newfont /FontName newfontname put
   newcodesandnames aload pop
   newcodesandnames length 2 idiv
   { newfont /Encoding get 3 1 roll put
   }
   repeat
   newfontname newfont definefont pop
   end
 } def
/scandvec [
 8#300 /Oacute
 8#311 /Atilde
 8#321 /oacute
 8#322 /Otilde
 8#323 /Ccedilla
 8#324 /otilde
 8#325 /ccedilla
 8#330 /Eacute
 8#331 /atilde
 8#332 /eacute
 8#333 /Udieresis
 8#334 /udieresis
 8#340 /Aacute
 8#342 /Acircumflex
 8#344 /Iacute
 8#347 /ecircumflex
 8#360 /aacute
 8#362 /acircumflex
 8#364 /iacute
 8#367 /eacute
 8#374 /uacute
 8#375 /ocircumflex
 8#376 /egrave
] def
/Times-Roman /Times-Roman-Scand scandvec
ReEncodeSmall
/Times-Roman-Scand findfont
13 scalefont setfont

/normalwidth ( ) stringwidth pop def
/maxbreakwidth 8 def
/maxlinesinpage 50 def

/tabwidth 30 def
/wordbreak ( ) def
/BreakIntoLines
  { /proc (nova_linha) cvx cvn def
    /linewidth (tamanho_linha) cvx cvn def
    /textstring exch def
    
    /breakwidth maxbreakwidth def
    /curwidth 0 def
    /lastwordbreak 0 def
    /startchar 0 def
    /restoftext textstring def
    /wordcount 0 def
    
    { restoftext wordbreak search
      { /nextword exch def pop
        /restoftext exch def
        /wordwidth nextword stringwidth pop def
        nextword (\011) eq
        { /curwidth curwidth tabwidth add def
          /wordwidth 0 def
        } if
        curwidth wordwidth add linewidth gt
        breakwidth  maxbreakwidth lt 
        nextword (\001) eq
        nextword (\015) eq
        or or or
        { textstring startchar
          lastwordbreak startchar sub
          getinterval /curline exch def
          nextword (\015) eq
          { curline () ne
            { { curline wordbreak search
                { /palavra exch def pop
                  /curline exch def
                  palavra () ne palavra (\011) ne and
                  { palavra show
                    normalwidth 0 rmoveto
                  } if
                  palavra (\011) eq
                  { tabwidth 0 rmoveto } if
                }
                { pop exit}
                ifelse
              } loop
            } if
          }
          { { curline wordbreak search
              { /palavra exch def pop
                /curline exch def
                palavra () ne palavra (\011) ne and
                { palavra show
                  breakwidth 0 rmoveto
                } if
                palavra (\011) eq
                { tabwidth 0 rmoveto } if
              }
              { pop exit}
              ifelse
            } loop
          } ifelse 
          yline maxlinesinpage lt
          { textstring dup length lastwordbreak sub lastwordbreak exch 
            getinterval
            /yline 0 def exit
          } if
          nextword (\001) ne nextword (\015) ne and
          { /startchar lastwordbreak def              
            /lastwordbreak lastwordbreak nextword length add 1 add def
          }
          { /lastwordbreak lastwordbreak nextword length add 1 add def
            /startchar lastwordbreak def
            /wordwidth 0 def
            /nextword () def
          } ifelse
          proc
          nextword () eq
          { /wordcount 0 def }
          { /wordcount 1 def } ifelse
          /curwidth wordwidth def
          /breakwidth maxbreakwidth def
        }
        { /curwidth curwidth wordwidth add def
          wordwidth 0 gt
          { /wordcount wordcount 1 add def
            wordcount 2 gt
            { /breakwidth linewidth curwidth sub wordcount 1 sub div def
            }
            { /breakwidth linewidth curwidth sub def
            } ifelse
          } if
          /lastwordbreak lastwordbreak nextword length add 1 add def
        }
        ifelse
      }
      { pop exit
      }
      ifelse
    } loop
    /lastchar textstring length def
    lastchar startchar gt yline 0 ne and
    { textstring startchar lastchar startchar sub getinterval show proc } if
 } def
/yinic 755 def
/yline yinic def
/ydec 13.07 def
/xrightmargin 72 def
/nova_linha {/yline yline ydec sub def
              xrightmargin yline moveto
            } def
/tamanho_linha 470 def
/alinha_dir { dup stringwidth pop tamanho_linha exch sub 0 rmoveto } def

xrightmargin yinic moveto

(November, 15th 1992.)  alinha_dir show 

/yline yline 15 sub def
nova_linha

(Hi everybody: \015 \015 \
\011 There is someboby that has asked me for a copy of the PostScript \
formatter I've written. So I send a copy of it. It is really a modification of \
a program in the Cookbook. \(Program 12 / A simple line breaking algorithm\). \
It also contains the program 18 to add accents to foreign languages. \015 \
\011 There are some very important variables to define the format of the \
resulting text. They are \(to change, locate /<variable name>\): \015 \015 \
\011 - yinic, inicial "y" value; \015 \
\011 - tamanho_linha, the size of the line; \015 \
\011 - tabwidth, the size of the tab spacing; \015 \
\011 - xrightmargin, the right margin; \015 \
\011 - ydec, the amount decremented from yline at each new line; \015 \
\011 - yline, variable that has the current line "y" value; \015 \
\011 - maxbreakwidth, maximal admitted space between words; \015 \
\011 - maxlinesinpage, maximal number of lines in a page. \015 \
\015 \011 In adittion there are values that should be set into the commands, \
like the size of the characters. It should be set in the "scalefont" command. \
\015 \011 Although this example is pretty clear, some comments should be done \
to use it correctly. The text to be formatted must be into a string pushed \
onto the stack as a parameter to the BreakIntoLines procedure. Inside this \
string is imperative the use of white space followed by a back slash \
in each line end. If the formatting fails this is most of the times the main \
reason. Inside this string many commands can be used to indicate special \
format characteristics. These commands are octal numbers, which in PostScript \
are represented as a backslash followed by three octal digits. It is \
imperative to separate these commands from the text before and after by one \
space. This is the second main source of errors. These commands should not be \
confused with the special characters also represented as octal numbers, \
that CAN be joined to the words. These commands are: \015 \015 \
\011 - \134001, Breaks the line and justify; \015 \
\011 - \134011, TAB character. Most used as paragraph; \015 \
\011 - \134015, CR character. Breaks the line, but doesn't justify. \015 \
\015 \011 Page breaks are automatic, but there must be at least the same \
number of "%%Page:" comments as the number of pages of the formatted text. \ Observation of the code can give some \
more help. Here it can process 2 pages. Extension to more pages is  \
straightforward. Just copy the lines from "%%Page:" following this text in the \
program until the end as many times the number of extra pages is. \
The names of the special characters to change them, can be found \
in the red book under the title of "Codes and Names" in the appendix A. \
Bug reports please mail to stolte@irit.fr. \
It is not what it could be called an \
ultimate text formatter and have its limitations. I count on you all to \
extend this program to a more complete set of comands to turn it \
more  flexible and usefull. Any changing should be mailed to me. \
\015 \015  Abra\325os, \015 \015 Nilo Stolte. )
BreakIntoLines
showpage

%%Page:
/yline yinic def
xrightmargin yinic moveto
BreakIntoLines
showpage
Newsgroups: comp.lang.postscript