Word wrapping a string to arbitrary position?
- Fangbeast
- PureBasic Protozoa
- Posts: 4789
- Joined: Fri Apr 25, 2003 3:08 pm
- Location: Not Sydney!!! (Bad water, no goats)
Word wrapping a string to arbitrary position?
I like the word wrapping of the editor gadget and I'd like to apply that logic to strings of arbitrary length.
Given a string such as:
Stringy.s = "Wrap me baby but don't hurt me, I'll
be good like a long stringy should and would!"
and an arbitrary 'wrap column' of 30, how would I go about something like this?
I'd feed a string somewhere that calculates the number of words and spaces to that position, adds the CRLF and then I could use that string where it needed that wrap space.
Given a string such as:
Stringy.s = "Wrap me baby but don't hurt me, I'll
be good like a long stringy should and would!"
and an arbitrary 'wrap column' of 30, how would I go about something like this?
I'd feed a string somewhere that calculates the number of words and spaces to that position, adds the CRLF and then I could use that string where it needed that wrap space.
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
Re: Word wrapping a string to arbitrary position?
I'd imagine using the Textwidth function would do the job, assuming you could startdrawing to it.
Otherwise a google search returned this for the WINAPI.
Otherwise a google search returned this for the WINAPI.
Try using GetTextExtentPoint32. That uses the current font for the given device context to measure the width and height of the rendered string in logical units. For the default mapping mode, MM_TEXT, 1 logical unit is 1 pixel.
However, if you've changed the mapping mode for the current device context, a logical unit may not be the same as a pixel. You can read about the different mapping modes on MSDN. With the mapping mode, you can convert the dimensions returned to you by GetTextExtentPoint32 to pixels.
----------------------------------------------------------------------------
Commenting your own code is admitting you don't understand it.
----------------------------------------------------------------------------
Commenting your own code is admitting you don't understand it.
----------------------------------------------------------------------------
Re: Word wrapping a string to arbitrary position?
Not exact but it will do your request
190 = Right Margin to select (in pixel)
It depends on the width of your EditGadget & the font size used
190 = Right Margin to select (in pixel)
It depends on the width of your EditGadget & the font size used
Code: Select all
If OpenWindow(1, 40, 40, 400, 400, "Editor Test", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget)
EditorGadget(1, 10, 10, 380, 300)
SendMessage_(GadgetID(1), #EM_SETTARGETDEVICE, #Null, 0)
SendMessage_(GadgetID(1), #EM_SETMARGINS, #EC_RIGHTMARGIN, 0 | (190<<16))
Repeat
Event=WaitWindowEvent(10)
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case 1
EndSelect
EndSelect
Until Event=#PB_Event_CloseWindow
EndIf
Egypt my love
- Fangbeast
- PureBasic Protozoa
- Posts: 4789
- Joined: Fri Apr 25, 2003 3:08 pm
- Location: Not Sydney!!! (Bad water, no goats)
Re: Word wrapping a string to arbitrary position?
I want the wrap calculated to be at a certain arbitrary column.
Not in the editorgadget, just like the way the editorgadget does it.
The new string would be calculated at the given border and CRLF pairs added at the right point and the string rejoined.
Old string. Wrap border at 30 chars.
String.s = "Stringy.s = "Wrap me baby but don't hurt me, I'll
be good like a long stringy should and would!"
New string?
NewString.s = "Wrap me baby but don't hurt me' + CRLF + , I'll be good like a long " + #CRLF$ + "stringy should and would!"
Not in the editorgadget, just like the way the editorgadget does it.
The new string would be calculated at the given border and CRLF pairs added at the right point and the string rejoined.
Old string. Wrap border at 30 chars.
String.s = "Stringy.s = "Wrap me baby but don't hurt me, I'll
be good like a long stringy should and would!"
New string?
NewString.s = "Wrap me baby but don't hurt me' + CRLF + , I'll be good like a long " + #CRLF$ + "stringy should and would!"
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
-
- Addict
- Posts: 1482
- Joined: Tue Feb 22, 2011 1:16 pm
Re: Word wrapping a string to arbitrary position?
I just knocked this up in 5 minutes but it may not be reliable.
[Edit] It wasn't.
[Edit] It wasn't.

Last edited by MachineCode on Mon Mar 04, 2013 12:21 pm, edited 1 time in total.
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
PureBasic: Born in 1998 and still going strong to this very day!
-
- Addict
- Posts: 4779
- Joined: Thu Jun 07, 2007 3:25 pm
- Location: Berlin, Germany
Re: Word wrapping a string to arbitrary position?
Code: Select all
EnableExplicit
Procedure.s WordWrap (source$, width.i, delimList$="- "+Chr(9), nl$=#LF$)
Protected.i posn, found, i
Protected ret$=""
If width <= 0
ProcedureReturn source$
EndIf
posn = Len(source$)
While posn > width
For i = width To 1 Step -1
found = FindString(delimList$, Mid(source$,i,1))
If found > 0
posn = i
Break
EndIf
Next
If found = 0
For i = width+1 To posn
found = FindString(delimList$, Mid(source$,i,1))
If found > 0
posn = i
Break
EndIf
Next
EndIf
ret$ + RTrim(Left(source$, posn)) + nl$
source$ = LTrim(Mid(source$, posn+1))
posn = Len(source$)
Wend
ProcedureReturn ret$ + source$
EndProcedure
;-- Demo
Define source$, msg$
source$ = "Wrap me baby but don't hurt me, I'll be good like a long stringy should and would!"
msg$ = WordWrap(source$, 30)
MessageRequester("Word wrap demo", msg$)
msg$ = WordWrap(source$, 1)
MessageRequester("Word wrap demo", msg$)
Re: Word wrapping a string to arbitrary position?
@Little John:
Problem is long texts don't get wrapped at all, see:
source$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmneopqrstuvwxyz"
I think if no word boundary (space or tab) is found, there should be a hard wrap, so it is still maximum requested line length.
Problem is long texts don't get wrapped at all, see:
source$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmneopqrstuvwxyz"
I think if no word boundary (space or tab) is found, there should be a hard wrap, so it is still maximum requested line length.
-
- Addict
- Posts: 4779
- Joined: Thu Jun 07, 2007 3:25 pm
- Location: Berlin, Germany
Re: Word wrapping a string to arbitrary position?
This is by design.Danilo wrote:@Little John:
Problem is long texts don't get wrapped at all, see:
source$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmneopqrstuvwxyz"
Yes, that would be an option, but not the way I personally normally would like such a routine to work.Danilo wrote:I think if no word boundary (space or tab) is found, there should be a hard wrap, so it is still maximum requested line length.
For instance in e-mails normally a line shouldn't be longer than about 70 to 80 characters. But what about a very long URL? A good e-mail program doesn't wrap it, so that it will remain "clickable".
It depends on the context where Fangbeast needs it.
- Fangbeast
- PureBasic Protozoa
- Posts: 4789
- Joined: Fri Apr 25, 2003 3:08 pm
- Location: Not Sydney!!! (Bad water, no goats)
Re: Word wrapping a string to arbitrary position?
It depends on the context where Fangbeast needs it.
I'm going to use it on the text for the balloon tooltips that RASHAD wrote for us because some of the tip text might be very long.
Instead of manually figuring out where to throw in CRLF pairs which never look right, I want code to do it for me properly during the balloon creation.
It will make all the ballons look the same size and more professional (Dare I really use that word in context with me???)
This recipe program is getting better and better with all of your help. Now I just hope I get feedback from it:):)
Last edited by Fangbeast on Sun Mar 03, 2013 11:27 am, edited 1 time in total.
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
-
- Addict
- Posts: 4779
- Joined: Thu Jun 07, 2007 3:25 pm
- Location: Berlin, Germany
Re: Word wrapping a string to arbitrary position?
This is almost the same function as above, but always forcing a wrap, even if there is no delimiter (like Danilo suggested):
I leave combining both functions, using an additional parameter as a flag, as an exercise for the reader. 
Code: Select all
EnableExplicit
Procedure.s WordWrap (source$, width.i, delimList$="- "+Chr(9), nl$=#LF$)
Protected.i posn, found, i
Protected ret$=""
If width <= 0
ProcedureReturn source$
EndIf
posn = Len(source$)
While posn > width
For i = width To 1 Step -1
found = FindString(delimList$, Mid(source$,i,1))
If found > 0
posn = i
Break
EndIf
Next
If found = 0
posn = width
EndIf
ret$ + RTrim(Left(source$, posn)) + nl$
source$ = LTrim(Mid(source$, posn+1))
posn = Len(source$)
Wend
ProcedureReturn ret$ + source$
EndProcedure
;-- Demo
Define source$, msg$
source$ = "Wrap me baby but don't hurt me, I'll be good like a long stringy should and would!"
msg$ = WordWrap(source$, 10)
MessageRequester("Word wrap demo", msg$)
source$ = "Wrapmebabybutdon'thurtme, I'll be good like a long stringy should and would!"
msg$ = WordWrap(source$, 10)
MessageRequester("Word wrap demo", msg$)

Re: Word wrapping a string to arbitrary position?
[offtopic]
on all wrapped lines. Didn't think about that because Outlook 2010 just does it as expected by me, so it is wrapped and clickable.
[/offtopic]
Anyway, thanks for your codes! I tried 2 hours but always something did not work correctly. Didn't get it to work perfectly for all cases I tested,
especially long strings without any word boundaries had always some problems with hard wrap.
The good e-mail program should hard wrap the line at the requested boundary in my opinion and it should still be clickableLittle John wrote:Yes, that would be an option, but not the way I personally normally would like such a routine to work.Danilo wrote:I think if no word boundary (space or tab) is found, there should be a hard wrap, so it is still maximum requested line length.
For instance in e-mails normally a line shouldn't be longer than about 70 to 80 characters. But what about a very long URL? A good e-mail program doesn't wrap it, so that it will remain "clickable".
on all wrapped lines. Didn't think about that because Outlook 2010 just does it as expected by me, so it is wrapped and clickable.

[/offtopic]
Anyway, thanks for your codes! I tried 2 hours but always something did not work correctly. Didn't get it to work perfectly for all cases I tested,
especially long strings without any word boundaries had always some problems with hard wrap.

- Fangbeast
- PureBasic Protozoa
- Posts: 4789
- Joined: Fri Apr 25, 2003 3:08 pm
- Location: Not Sydney!!! (Bad water, no goats)
Re: Word wrapping a string to arbitrary position?
For me, getting help like this is fantastic. My life is full of doctors, surgeons and insurance claims so I don't think very well lately.
No comments from the peanuts gallery!
RASHAD, if you are still there: If balloon tooltips are on, sometimes ButtonImageGadget images don't appear.
You told me what could be safely disabled but I don't remember?
No comments from the peanuts gallery!
RASHAD, if you are still there: If balloon tooltips are on, sometimes ButtonImageGadget images don't appear.
You told me what could be safely disabled but I don't remember?
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
-
- Addict
- Posts: 4779
- Joined: Thu Jun 07, 2007 3:25 pm
- Location: Berlin, Germany
Re: Word wrapping a string to arbitrary position?
Danilo wrote:[offtopic]
The good e-mail program should hard wrap the line at the requested boundary in my opinion and it should still be clickableLittle John wrote:Yes, that would be an option, but not the way I personally normally would like such a routine to work.Danilo wrote:I think if no word boundary (space or tab) is found, there should be a hard wrap, so it is still maximum requested line length.
For instance in e-mails normally a line shouldn't be longer than about 70 to 80 characters. But what about a very long URL? A good e-mail program doesn't wrap it, so that it will remain "clickable".
on all wrapped lines. Didn't think about that because Outlook 2010 just does it as expected by me, so it is wrapped and clickable.
[/offtopic]

I didn't know that e.g. Outlook 2010 can handle URLs this way. Yes, that's fine for the users of Outlook.
But when you are writing (or forwarding) a mail with a long URL using Outlook 2010, and Outlook will insert hard line breaks into the URL, then the risk is high that in the mail client of the recipient that URL will not be clickable any more! (Not only) IMHO a good mail program should be conservative and rather strict when creating mails, and flexible and tolerant when receiving and displaying mails.
Anyway, I almost forgot that in mails there really is a line length limit that HAS TO be considered:
So when I previously thought of never inserting a hard line break in an e-mail, that was wrong.RFC 2822 wrote:There are two limits that this standard places on the number of
characters in a line. Each line of characters MUST be no more than
998 characters, and SHOULD be no more than 78 characters, excluding
the CRLF.
When I wrote that, my idea was to use a flag that just tells whether or not to use hard wraps.Little John wrote:I leave combining both functions, using an additional parameter as a flag, as an exercise for the reader.
But after recalling the above section of RFC 2822, I thought that it is more flexible to allow different positions for soft and for hard wraps!
So for creating an e-mail, e.g. you could use softWrapPosn=70, hardWrapPosn=70, and I can use say softWrapPosn=70, hardWrapPosn=998.
Because of this additional idea, I've now written a new WordWrap function.
My first attempt also did not work. Then I recalled the KISS principle.Danilo wrote:Anyway, thanks for your codes! I tried 2 hours but always something did not work correctly. Didn't get it to work perfectly for all cases I tested,
especially long strings without any word boundaries had always some problems with hard wrap.

Danilo, I have to thank you, because discussing with you is always interesting, and often gives me a deeper understanding of a problem, or like in this case gave me some inspiration.
@Fangbeast:
People who throw hamsters at srod or some such thing are more than welcome!

- RichAlgeni
- Addict
- Posts: 935
- Joined: Wed Sep 22, 2010 1:50 am
- Location: Bradenton, FL
Re: Word wrapping a string to arbitrary position?
Just wanted to offer a quick tip from my experience. This is will only work with the new Bool function.
This method will count the number of fields in a string using a delimiter, but won't give a false count greater than 0 when the string is null.
This method will count the number of fields in a string using a delimiter, but won't give a false count greater than 0 when the string is null.
Code: Select all
CountString(test$, " ") + Bool(test$ <> "")
-
- Addict
- Posts: 4779
- Joined: Thu Jun 07, 2007 3:25 pm
- Location: Berlin, Germany
Re: Word wrapping a string to arbitrary position?
I am sorry: I almost forgot (but jassing reminded me) that the code which I had written mainly was intended for text files or windows/gadgets with fixed-width fonts. With a variable-width font (which is probably used by the tooltips) the result might not be satisfying.Fangbeast wrote:I'm going to use it on the text for the balloon tooltips that RASHAD wrote for us because some of the tip text might be very long.
Instead of manually figuring out where to throw in CRLF pairs which never look right, I want code to do it for me properly during the balloon creation.
Therefore now I wrote new code that can be used with variable-width fonts. Unfortunately, I wasn't able to give an example with a tooltip, because I don't know how to use PB's built-in function TextWidth() with tooltips.