Consultor Eletrônico



Kbase 21955: How to Parse a Large Text Block Into Separate Lines with 4GL
Autor   Progress Software Corporation - Progress
Acesso   Público
Publicação   10/04/2002
SUMMARY:

Sometimes a large block of text coming from a database field or other source needs to be displayed into a report or a Web page. To accomplish this, the text has to be divided into lines with a certain number of characters, but without breaking the words contained therein.

SOLUTION:

Here are two methods to wrap lengthy text into lines:

-- Solution Option 1

The following code divides a text block into lines having no more than 60 characters in each. You can indicate the length of the lines in the viLength variable.

DEF VAR vc AS CHAR EXTENT 16.
DEF VAR vj AS INT.
DEF VAR vmax AS INTEGER.
DEF VAR vcTemp AS CHAR.
DEF VAR vcTemp2 AS CHARACTER.
DEF VAR vi AS INTEGER.
DEF VAR vpos AS INTEGER.
DEF VAR viLength AS INTEGER.
DEF VAR vcFormat AS CHARACTER.
DEF VAR chDelimiter AS CHARACTER.

/* trying to parse the following text */
/* if you get the text in a WebSpeed application, you probably */
/* will use vcTemp = get-field( 'h_text' ) */
vcTemp =
'To build and manage cutting-edge applications, developers must stay
current on technical information and avoid problems that can lead to costly project delays. Customers rely on Progress Software Technical Support for immediate access to support solutions that span the development lifecycle.'.

/* length of the line */
viLength = 60.

/* the text might come delimited into lines longer than viLength */
/* when you get the text from a TEXTAREA field in an html page */ /* the lines are separated by CHR(10) */

chDelimiter = CHR(10).

vc = ''.
vj = 1.
vmax = IF vcTEmp <> '' THEN NUM-ENTRIES( vcTemp, chDelimiter ) ELSE 0.
num_block:
DO vi = 1 TO vmax:
vcTemp2 = ENTRY( vi, vctemp, chDelimiter ).

/* line exceeds 80 chars */
n80_block:
DO WHILE( LENGTH( vcTemp2 ) > viLength AND LENGTH( vcTemp2 ) > 0 ):
/* positions of the last word in first 80 chars */
vpos = R-INDEX( SUBSTRING(vcTemp2, 1, viLength ) , ' ' ).
IF vpos = 0 THEN DO:
/* there is one word that breaks at 80 characters in the beginning */
vc[vj] = ENTRY( 1, vcTemp2, ' ' ).
vj = vj + 1.
IF INDEX( vcTemp2, ' ') <> 0 THEN DO:
vcTemp2 = SUBSTRING( vcTemp2, INDEX( vcTemp2, ' ') + 1 ).
NEXT n80_block.
END.
ELSE NEXT num_block.
END.
vc[vj] = SUBSTRING( vcTemp2, 1, vpos ).
vj = vj + 1.
vcTemp2 = SUBSTRING( vcTemp2, vpos + 1 ).
END.

/* lines collected in vc variable */
vc[vj] = vcTemp2.

vj = vj + 1.
END.

DISPLAY vc FORMAT "x(76)" NO-LABEL
WITH FRAME xx WITH SIDE-LABEL.


-- Solution Option 2

1) Use an editor widget (that you never display) in a dummy frame
(that you never display again). Set the appropriate font (might
be a fixed one) to the editor widget and load the text in its
SCREEN-VALUE. (Or you can use the READ-FILE() method.)

2) Then sweep this editor widget by setting the CURSOR-OFFSET
attribute.

3) You then just need to check the CURSOR-LINE attribute. In other
words:

PrevPos = 1.
CurrentLine = 1.
DO i = 1 to DummyEditor:LENGTH :
IF DummyEditor:CURSOR-LINE = CurrentLine THEN NEXT.

SubString = SUBSTR(DummyEditor:SCREEN-VALUE,PrevPos,i - PrevPos + 1).
CurrentLine = CurrentLine + 1.
END.