This is a function I think is useful, and I hope I won't find out that one of QB/QB64pe's more than 20,000 keywords, functions and compiler directives, does the same thing. (Yes, I know it's just under 500, but sometimes it feels like it's a lot more.)
I've created a subroutine called PrintW to take a string, breaking it at the last space or hyphen, printing up to that point, then repeating with what is left of the string. In short, it provides a print with wraparound.
I have tested it with an appropriate passage, the three paragraph Gettysburg Address.
Code: (Select All)
L$ = "Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal."
PrintW L$
Print
PrintW "Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this."
Print
PrintW "But, in a larger sense, we can not dedicate, we can not consecrate, we can not hallow, this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us, that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion, that we here highly resolve that these dead shall not have died in vain, that this nation, under God, shall have a new birth of freedom, and that government of the people, by the people, for the people, shall not perish from the earth."
Print
Print "- Abraham Lincoln"
End
Sub PrintW (Msg$)
Dim Temp$, Split$, breakspace%, breakdash%
Temp$ = Msg$
While Len(Temp$) > 79
'' Print Len(Temp$)
Split$ = Left$(Temp$, 79)
breakspace% = _InStrRev(Split$, " ")
breakdash% = _InStrRev(Split$, "-")
'' Print Split$
'' Print breakspace%; breakdash%
'' Input X$
If breakspace% > breakdash% Then
Split$ = Left$(Split$, breakspace%)
Temp$ = Mid$(Temp$, breakspace% + 1, Len(Temp$))
Else
Split$ = Left$(Split$, breakdash%)
Temp$ = Mid$(Temp$, breakdash% + 1, Len(Temp$))
End If
'' Print "*"; Len(Temp$)
Print Split$
Wend
Print Temp$
End Sub
While 1
Fix Bugs
report all bugs fixed
receive bug report
end while
04-14-2024, 06:02 PM (This post was last modified: 04-14-2024, 06:08 PM by bplus.)
yes that could be handy but even more so if you can set the width ie just change 79 to something input from function call. then, you are a short step away from creating a word box of text at row, column and cutting up a long string into it.
this was maybe before -InStrRev/
Code: (Select All)
_Title "wrap$ test" 'b+ 2019-12-28 a simple way
'now test in graphics screen
'SCREEN _NEWIMAGE(640, 600, 32) 'now test in graphics screen
Print "Here is our test string:"
test$ = "12345678901234567890123456789012345678901234567890123456789012345678901234567890 Here is a super long string to test with the wrap$ Function that splits a string at first space found before the maxLen limit to keep the strings at or under the maxLen length."
Print test$
Print
Print "press any for printWrap demo... "
Sleep
Cls
Print "Here is printWrap at row = 12, col = 1, wrap length is 80:"
printWrap test$, 80, 12, 1
Locate 25, 20: Print "press any for another demo... ";
Sleep
Cls
Print "Here is printWrap at row = 9, col = 20, wrap length is 40:"
printWrap test$, 40, 9, 20
Locate 25, 20: Print "press any for another demo... ";
Sleep
Cls
Print "Here is printWrap at row = 5, col = 30, wrap length is 20:"
printWrap test$, 20, 5, 30
Locate 24, 20: Print "end of demos... ";
'This function returns the first segment of string less than or equal to maxLen AND
'the remainder of the string (if any) is returned in tail$ to be used by wrap$ again
Function wrap$ (s$, maxLen, tail$)
If Len(s$) > maxLen Then
p = maxLen + 1
While Mid$(s$, p, 1) <> " " And p > 1
p = p - 1
Wend
If p = 1 Then
wrap$ = Mid$(s$, 1, maxLen): tail$ = Mid$(s$, maxLen + 1)
Else
wrap$ = Mid$(s$, 1, p - 1): tail$ = Mid$(s$, p + 1)
End If
Else
wrap$ = s$: tail$ = ""
End If
End Function
'this sub uses the wrap$ function to print out a string with row and column offsets
Sub printWrap (s$, maxLen, rowOffset, colOffset)
ss$ = s$ 'work with copy
Do
Locate rowOffset + i, colOffset: Print wrap$(ss$, maxLen, st$)
ss$ = st$
i = i + 1
Loop Until Len(ss$) = 0
End Sub
One of my may Wrap routines, which is actually also a RAP routine!
- Use arrows right and left to narrow and widen right screen margin.
Code: (Select All)
WIDTH 160, 42
_FONT 16
_SCREENMOVE 10, 10
w = _WIDTH
DO
_LIMIT 30
REM x$ = "In West Los Angeles born and raised, at the yacht club is where I spent most of my days, 'til a couple of coders who were up to no good, started making trouble in my neighborhood. I got booted off Discord and my vids wouldn't play, so I moved to the hills in the State of VA. I pulled up to the forum 'bout a week into April and I yelled to the browser save password log in later. Now I'm able to post and my speech is still free as I sit on my throne as the Prince of P.E."
x$ = "In West Los Angeles born and raised, at the yacht club is where I spent most of my days, 'til a couple of coders who were up to no good, started making trouble in my neighborhood. I got booted off Discord and my vids won't play, so I moved to the hills in the State of VA. I pulled up to the forum 'bout a week into April and I yelled to the browser, 'save password log in later!' Now I'm able to post and my speech is still free as I sit on my throne as the Prince of P.E."
CLS
IF w < _WIDTH - 1 THEN
FOR i = 1 TO _HEIGHT: LOCATE i, w + 1: PRINT CHR$(179);: NEXT
END IF
LOCATE 1, 1
DO
WHILE -1
t$ = MID$(x$, 1, w)
chop = 1
IF w <> 1 THEN
DO
IF LEFT$(t$, 1) = " " THEN
' Only happens with more than 1 space between characters.
IF LTRIM$(t$) = "" THEN EXIT DO ELSE x$ = LTRIM$(x$): EXIT WHILE
END IF
IF MID$(x$, w + 1, 1) <> " " AND LTRIM$(t$) <> "" THEN ' Now we have to chop it.
IF INSTR(x$, " ") > 1 AND INSTR(t$, " ") <> 0 AND LEN(x$) > w THEN
t$ = MID$(t$, 1, _INSTRREV(t$, " ") - 1)
chop = 2
END IF
ELSE
chop = 2
END IF
EXIT DO
LOOP
x$ = MID$(x$, LEN(t$) + chop)
ELSE
x$ = MID$(x$, LEN(t$) + 1)
END IF
IF LEN(t$) AND CSRLIN < _HEIGHT - 1 THEN LOCATE , ml + 1: PRINT LTRIM$(t$)
EXIT WHILE
WEND
LOOP UNTIL LEN(t$) AND LEN(LTRIM$(x$)) = 0
DO
b$ = INKEY$
IF LEN(b$) THEN
IF b$ = CHR$(27) THEN SYSTEM
SELECT CASE MID$(b$, 2, 1)
CASE "K"
IF w > 1 THEN w = w - 1
EXIT DO
CASE "M"
IF w < _WIDTH - 1 THEN w = w + 1
EXIT DO
END SELECT
END IF
LOOP
LOOP
mine is easy to adapt to other people's code (and works) ;-))
Code: (Select All)
_Title "wrap$ test" 'b+ 2019-12-28 a simple way
'now test in graphics screen
'SCREEN _NEWIMAGE(640, 600, 32) 'now test in graphics screen
test$ = "Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal."
Print "Here is printWrap at row = 9, col = 10, wrap length is 60:"
printWrap test$, 60, 9, 10
Locate 25, 20: Print "press any for another demo... ";
Sleep
Cls
test$ = "Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this."
Print "Here is printWrap at row = 5, col = 40, wrap length is 20:"
printWrap test$, 40, 5, 20
Locate 25, 20: Print "press any for another demo... ";
Sleep
Cls
test$ = "But, in a larger sense, we can not dedicate, we can not consecrate, we can not hallow, this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us, that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion, that we here highly resolve that these dead shall not have died in vain, that this nation, under God, shall have a new birth of freedom, and that government of the people, by the people, for the people, shall not perish from the earth."
Print "Here is printWrap at row = 5, col = 10, wrap length is 60:"
printWrap test$, 60, 5, 10
Locate 25, 20: Print "press any for another demo... ";
Sleep
End
'This function returns the first segment of string less than or equal to maxLen AND
'the remainder of the string (if any) is returned in tail$ to be used by wrap$ again
Function wrap$ (s$, maxLen, tail$)
If Len(s$) > maxLen Then
p = maxLen + 1
While Mid$(s$, p, 1) <> " " And p > 1
p = p - 1
Wend
If p = 1 Then
wrap$ = Mid$(s$, 1, maxLen): tail$ = Mid$(s$, maxLen + 1)
Else
wrap$ = Mid$(s$, 1, p - 1): tail$ = Mid$(s$, p + 1)
End If
Else
wrap$ = s$: tail$ = ""
End If
End Function
'this sub uses the wrap$ function to print out a string with row and column offsets
Sub printWrap (s$, maxLen, rowOffset, colOffset)
ss$ = s$ 'work with copy
Do
Locate rowOffset + i, colOffset: Print wrap$(ss$, maxLen, st$)
ss$ = st$
i = i + 1
Loop Until Len(ss$) = 0
End Sub
Mine was made for and works in SCREEN 0. Eventually, I will need to make one for graphics screens that includes different text character widths, as my hypertext project.
Pete
Shoot first and shoot people who ask questions, later.
04-14-2024, 10:12 PM (This post was last modified: 04-14-2024, 10:13 PM by bplus.)
Even this one!
Code: (Select All)
_Title "wrap$ test, press w for widen, d for decrease." 'b+ 2019-12-28 a simple way
test$ = "In West Los Angeles born and raised, at the yacht club is where I spent most of my days, 'til a couple of coders who were up to no good, started making trouble in my neighborhood. I got booted off Discord and my vids won't play, so I moved to the hills in the State of VA. I pulled up to the forum 'bout a week into April and I yelled to the browser, 'save password log in later!' Now I'm able to post and my speech is still free as I sit on my throne as the Prince of P.E."
w = 60: m = 20
Do
k$ = InKey$
If k$ = "d" Then w = w - 1
If k$ = "w" Then w = w + 1
If w > 70 Then w = 70
If w < 30 Then w = 30
m = Int((78 - w) / 2)
Cls
printWrap test$, w, 5, m
_Limit 10
Loop Until _KeyDown(27)
'This function returns the first segment of string less than or equal to maxLen AND
'the remainder of the string (if any) is returned in tail$ to be used by wrap$ again
Function wrap$ (s$, maxLen, tail$)
If Len(s$) > maxLen Then
p = maxLen + 1
While Mid$(s$, p, 1) <> " " And p > 1
p = p - 1
Wend
If p = 1 Then
wrap$ = Mid$(s$, 1, maxLen): tail$ = Mid$(s$, maxLen + 1)
Else
wrap$ = Mid$(s$, 1, p - 1): tail$ = Mid$(s$, p + 1)
End If
Else
wrap$ = s$: tail$ = ""
End If
End Function
'this sub uses the wrap$ function to print out a string with row and column offsets
Sub printWrap (s$, maxLen, rowOffset, colOffset)
ss$ = s$ 'work with copy
Do
Locate rowOffset + i, colOffset: Print wrap$(ss$, maxLen, st$)
ss$ = st$
i = i + 1
Loop Until Len(ss$) = 0
End Sub
(04-14-2024, 10:07 PM)Pete Wrote: Mine was made for and works in SCREEN 0. Eventually, I will need to make one for graphics screens that includes different text character widths, as my hypertext project.
Mark, yours can be modified to print the text as a single vertical line, by taking out the width restriction; however, it won't preserve the space between words like mine does when displayed as a vertical line of text. Note to test this just REM out the IF w < 30 THEN w = 30 line and make the text string a lot shorter, so it won't go vertically off the page. Oh mine compensates for that, too!
Pete
Shoot first and shoot people who ask questions, later.
text$ = "Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal."
text$ = text$ + " " ' add space at end to catch remnant of text
LineStart = 1 ' set linelength to be 40
Print String$(40, "-") ' reference 40 char string
LineEnd = LineStart + 39 ' LineEnd is 40
FindSpace:
Ch$ = Mid$(text$, LineEnd + 1, 1)
If Ch$ <> " " Then ' Ch$ is character after LineEnd
LineEnd = LineEnd - 1 ' if it's NOT a space, move LineEnd left until it IS
GoTo FindSpace
End If
Print Mid$(text$, LineStart, LineEnd - LineStart + 1) ' print line from linestart to lineend
LineStart = LineEnd + 2
If Mid$(text$, LineStart + 1, 1) = " " Then ' if char after end is a space (it's not)
LineStart = LineStart + 1 ' step past it for new LineStart position
End If
LineEnd = LineEnd + 40
If LineStart >= Len(text$) Then Sleep
GoTo FindSpace ' go again if not at end of text
Of all the places on Earth, and all the planets in the Universe, I'd rather live here (Perth, W.A.)
Please visit my Website at: http://oldendayskids.blogspot.com/
My thinking now is that PRINT usally isn't a process that most folks really consider to be a bottleneck in a program. Sure, it's one of the slowest commands we make use of, but one doesn't really make use of it when SPEED might be a factor, such as in a racing game or first person shooter. Instead of starting at the final column of a screen, and then backing up one character a time, my new concept for word wrap is simply to start from the left, separate words one at a time from our extended text, using a list of valid separater characters (.,;- !? and such), and then if there's room on the line, print them.
This "print word by word as we go" approach offers complete flexibility to how expansive one wants to make their word-wrap and text handling.
Now, folks might know the above as simple html formatting, but if you think about what I've written above, you'll see that's how it's processed...
left to right.
look for valid word separators (only the space after hello here).
Strip out the text to the left: <color=red>Hello(space)
You can now parse the command from the actual text, and remove the <color=red> from that text, and use it to change the color on the screen.
With the Hello(space) that's left, you then see if it'll print on the existing line, and if not, then you move it down to the start of the next line.
And that now leaves you with </color><br> to continue to process on the next pass.
Word-by-word, with flexibility to add control features of any type that you might want into your text!! Sure, it's a little slower than starting at column 79 and breaking the print, counting backwards, but it's oh so worth it, IMHO, just for the variety of things that you can end up doing with it!!