User Tools

Site Tools


outputting_20text_20with_20word-wrap

Outputting text with word-wrap

by Richard Russell, August 2009

BBC BASIC (by default) automatically 'wraps' text that is output to the screen or the printer. If a character will not fit on the current line (or within the current text viewport) a 'new line' is generated and the character is displayed or printed at the beginning of the next line. The text viewport scrolls, or a new page is ejected from the printer, if necessary.

Although this ensures that all text output is visible, it does often result in a word being split between two lines. It would usually be more desirable to perform a word wrap, that is if a character will not fit the entire word containing that character is moved to the next line. This is the kind of behaviour that a word processor usually has.

The routines listed below implement word-wrap for text output to the screen or the printer. There are four procedures: PROCww outputs a string to the screen, PROCvww outputs a single character to the screen, PROCwwp outputs a string to the printer and PROCvwwp outputs a single character to the printer:

       PROCww(A$)   : REM Equivalent to PRINT A$;
       PROCvww(C%)  : REM Equivalent to VDU C%
       PROCwwp(A$)  : REM Equivalent to OSCLI "OUTPUT 15" : PRINT A$; : OSCLI "OUTPUT 0"
       PROCvwwp(C%) : REM Equivalent to VDU 2,1,C%,3

Note that PROCww and PROCwwp do not output a newline after the string; to do that you must concatenate CHR$13+CHR$10 to the end of the string (or output them separately using PROCvww or PROCvwwp).

Here are the routines necessary to implement word-wrap:

        DEF PROCww(A$)
        LOCAL I%
        IF A$ = "" THEN ENDPROC
        FOR I% = 1 TO LEN(A$)
          PROCvww(ASCMID$(A$,I%))
        NEXT
        ENDPROC
 
        DEF PROCvww(C%)
        PRIVATE X%, Y%, B$
        VDU C%
        IF C% > 32 B$ += CHR$C% ELSE B$ = "" : X% = @vdu.c.x% : Y% = @vdu.c.y%
        IF X% > @vdu.c.x% IF B$ <> "" THEN
          LOCAL @vdu%!216 : @vdu%!216 = 1
          IF Y% = @vdu.c.y% Y% -= @vdu%!220
          REPEAT
            @vdu.c.x% = X% : @vdu.c.y% = Y%
            VDU 32 : X% += 1
          UNTIL X% > @vdu.tr%
          PRINT B$;
          X% = -1
        ENDIF
        ENDPROC
 
        DEF PROCwwp(A$)
        LOCAL I%
        IF A$ = "" THEN ENDPROC
        FOR I% = 1 TO LEN(A$)
          PROCvwwp(ASCMID$(A$,I%))
        NEXT
        ENDPROC
 
        DEF PROCvwwp(C%)
        PRIVATE X%, B$
        LOCAL M%, ?444 : ?444 = 64
        M% = @vdu%!-12
        VDU 2,1,C%,3
        IF C% > 32 B$ += CHR$C% ELSE B$ = "" : X% = @vdu%!-12
        IF @vdu%!-12 > @vdu%!236 IF B$ <> "" THEN
          IF X% < 0 X% = M% : B$ = RIGHT$(B$)
          SWAP @vdu%!-12, X%
          SYS "SetBkMode", @prthdc%, 2
          REPEAT
            VDU 2,1,32,3
          UNTIL @vdu%!-12 > X%
          SYS "SetBkMode", @prthdc%, 1
          ?444 = 0
          *OUTPUT 15
          PRINT 'B$;
          *OUTPUT 0
          X% = -1
        ENDIF
        ENDPROC

Note that the usual restrictions caused by the use of PRIVATE apply. You must not attempt to resume execution if an error occurs (even an ESCape error) within the PROCvww or PROCvwwp routines, unless you execute a RESTORE LOCAL as part of your error handler. Ensure that any ON ERROR handler in your program aborts execution in such a case.

This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information
outputting_20text_20with_20word-wrap.txt · Last modified: 2018/04/16 14:55 by richardrussell