mline() is a bit nasty. If the last word in a line ends right at
the line length, the following space will be at the start of the next
line.
Consider the string
"This is a contrived example, but then, aren't they all?"
with a width of 19. mline() breaks it up into
"This is a contrived"
" example, but then,"
" aren't they all?"
My routine does it right:
"This is a contrived"
"example, but then,"
"aren't they all?"
Here is the code:
***** Start of Included Code *****
* mtolines
* Convert a Memo Value to Lines of Specified Length
* Last Modification: 2007-04-18
*
* This function is necessary, because the way the mline() splits up
memos can
* result in blanks at the start of a mid-paragraph line.
procedure mtolines
lparameters;
physlines,; && C: 1-D array by reference: returns the lines. It
will be
; && dimensioned to the number of lines, but if memo is
empty,
; && one blank line will returned. Leading and
trailing empty
; && lines will be suppressed.
thememo,; && M/C: the memo (or string) to convert
linewidth,; && N: the line width to use
maxlines,; && N: the maximum number of lines to return. (This must
be at
; && least 1.) If there is still more memo, put "..."
at the
; && end of the last line. The "..." may overwrite
characters
; && so that it will fit in linewidth characters.
fpad && L: whether to pad the end of each line with spaces.
This is
; && done before the "..." is placed.
*
* Returns the number of lines. This is the same as alen(physlines).
local rawlines(1) && holds the unbroken-up lines (paragraphs)
local crawlines && size of rawlines()
crawlines=alines(rawlines,thememo,0) && 3rd: do not trim
local cretlines && numbers of lines returned, but 0 if empty
memo
* Determine start of non-empty lines.
local startline
startline=1
do while startline<=crawlines and empty(rawlines(startline))
startline=startline+1
enddo
* Determine end of non-empty lines.
local endline
endline=crawlines
do while endline>=startline and empty(rawlines(endline))
endline=endline-1
enddo
* If memo is all empty lines, simple exit.
if endline<startline
dimension thearray(1)
if fpad
thearray(1)=space(linewidth)
else
thearray(1)=""
endif
return 0
endif
* Parse each raw line.
* Trailing spaces will be trimmed. Leading spaces will not be
trimmed.
* Breaks will usually occur at spaces, rag right, and the following
* physical line will not have leading spaces. If a word is too
long to
* fit on one line, it will be hyphenated (at the last position) and
* continued on the next physical line.
local cphyslines
cphyslines=0
local i, currraw, rawlinelen, physstart, lineend, currchar,
gotspace
i=startline
do while i<=endline and cphyslines<=maxlines+1
&& The second conjunct catches the situation of too many lines. The
&& condition is not caught right away, but only after at least one
too
&& many lines has been parsed (ensuring that there really are too
many)
&& and an entire paragraph has been finished (so it might be more
than one
&& too many lines).
currraw=rtrim(rawlines(i))
rawlinelen=len(currraw)
if empty(currraw) && empty raw line
cphyslines=cphyslines+1
dimension physlines(cphyslines)
physlines(cphyslines)=""
else && raw line not empty
physstart=1
do while physstart<=rawlinelen
lineend=physstart+linewidth-1
if lineend>rawlinelen && last fragment
cphyslines=cphyslines+1
dimension physlines(cphyslines)
physlines(cphyslines)=substr(currraw,physstart)
physstart=rawlinelen+1
else && a full physical line
currchar=lineend
gotspace=.f.
if rawlinelen>lineend and
substr(currraw,currchar+1,1)=" "
&& Handle case of next char after segment is a space.
gotspace=.t.
currchar=currchar+1
endif
do while currchar>=physstart and not gotspace
if substr(currraw,currchar,1)=" "
gotspace=.t.
else
currchar=currchar-1
endif
enddo
if gotspace
cphyslines=cphyslines+1
dimension physlines(cphyslines)
physlines(cphyslines)=;
rtrim(substr(currraw,physstart,currchar-physstart+1))
physstart=currchar
else
cphyslines=cphyslines+1
dimension physlines(cphyslines)
physlines(cphyslines)=;
substr(currraw,physstart,linewidth-1)+"-"
physstart=lineend
endif
do while;
physstart<=rawlinelen and
substr(currraw,physstart,1)=" "
physstart=physstart+1
enddo
endif
enddo
endif
i=i+1
enddo
*
* Pad if desired.
if fpad
for i=1 to cphyslines
physlines(i)=padr(physlines(i),linewidth)
endfor
endif
* Add "..." if memo continues.
if cphyslines>maxlines
cphyslines=maxlines
dimension physlines(cphyslines)
physlines(cphyslines)=left(physlines(cphyslines),linewidth-3)+"..."
endif
*
return cphyslines
endproc
***** End of Included Code *****
Sincerely,
Gene Wirchenko
Computerese Irregular Verb Conjugation:
I have preferences.
You have biases.
He/She has prejudices.


|