If all you want is a simple routine to wrap some text in a given window, then this little number - more or less as it was typed in from some magazine back in the day - will, for most practical purposes, do the trick:
100 DEFine PROCedure Wrap(ch,str$) 110 LOCal first,second,loop,screen$(40) 120 IF LEN(str$)=0:RETurn 130 first=0 140 REPeat loop 150 first=first+1 160 FOR second=first TO LEN(str$) 170 IF str$(second)=' ' THEN 180 screen$=str$(first TO second-1) 190 PRINT#ch;!screen$; 200 first=second 210 EXIT second 220 END IF 230 IF second=LEN(str$) THEN 240 screen$=str$(first TO LEN(str$)) 250 PRINT#ch;!screen$; 260 EXIT loop 270 END IF 280 END FOR second 290 IF first=LEN(str$):EXIT loop 300 END REPeat loop 310 END DEFine Wrap 320 :
Its not perfect, but it works. It uses S*BASIC's line handling rules to do its magic. Great if you know exactly what text is to be displayed, and test it beforehand so you know it looks ok.
This next routine has a few extras thrown in. It also breaks lines at the last possible space character, but the line length can be shorter than the width of the window. Also it allows for linefeeds, which you indicate by including actual linefeed characters, CHR$(10), in your string, or use a symbol instead, such as '\'.
The previously published routine showed up some bugs in actual use :o( so this is a complete re-think and re-write! For starters it is more compact and does the number-of-lines calculation on the fly by altering the parameter string itself. Words longer than width are simply hyphened and split. Hyphens in the text are ignored, while they could be used as alternative split points. That obvious improvement may perhaps be included another time.
SuperBASIC adaptors will need to make a few changes. Eg SuperBASIC doesnt allow integer SELect, or dots in variable names, but apart from that it should work; Turbo users may have to find another solution altogether, due to the routine altering a parameter.
Please let me know if you discover any problems with this code! (Especially if you managed to find a fix!).
rem + ------------------------------------------------------------------------ + rem |< Wrap% >| rem + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + rem | Reformat a string to conform to width restraint | rem | and return the number of lines it will take to display it | rem | | rem | Given | rem | wid% = field width in char | rem | split$ = split character - an optional alternative character to LF | rem | r.txt$ = the text to be wrapped. (Note this text is altered by Wrap!) | rem | the Wrap function returns the number of max width-sized segments of the | rem | reformatted string r.txt$. The calling parameter of r.txt$ can be | rem | printed to screen directly, or easily parsed for justification. | rem | | rem |If split$ is given as "" then the split character reverts to LF/chr$(10) | rem + ------------------------------------------------------------------------ + rem | V0.04, pjw, 2017 Feb/Jun, Complete re-write | rem | V0.06, pjw, 2021 Apr 12, Complete re-write (again!) | rem + ------------------------------------------------------------------------ + : DEFine FuNction Wrap%(wid%, split$, r.txt$) LOCal wl, i%, c%, h%, p%, s%, e%, lf% : lf% = CODE(split$): IF lf% = 0: lf% = 10 h% = 1: e% = LEN(r.txt$) : i% = 0: p% = 0: s% = 0 REPeat wl i% = i% + 1: IF i% > e%: EXIT wl c% = CODE(r.txt$(i%)) SELect ON c% = 10: h% = h% + 1: p% = 0: s% = 0: NEXT wl = lf%: r.txt$(i%) = CHR$(10) h% = h% + 1: p% = 0: s% = 0: NEXT wl = 32: s% = i% END SELect : p% = p% + 1 IF p% = wid% THEN IF s% = 0 THEN r.txt$ = r.txt$(1 TO i% - 1) & '-' & CHR$(10) & r.txt$(i% TO e%) e% = e% + 2 ELSE IF (i% + 1) > e%: EXIT wl IF CODE(r.txt$(i% + 1)) = 32 THEN r.txt$(i% + 1) = CHR$(10) ELSE r.txt$(s%) = CHR$(10) h% = h% + 1: i% = s% END IF s% = 0 END IF p% = 0 END IF END REPeat wl RETurn h% END DEFine Wrap% : :