Word wrap

Share your advanced PureBasic knowledge/code with the community.
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Word wrap

Post by Little John »

Works also with PB 5.20

Hi,

this is a function for word wrap of a line or complete paragraphs in a text file, or in a window with a fixed-width font. It can even indent bullet lists correctly.
See also the corresponding function in the 3rd post.

I hope the code contains enough comments. If you wonder why the function deals with "soft wraps" and "hard wraps", you can read the background in this discussion.

Have fun!

Include file:

Code: Select all

; v1.01, tested with PB 5.10 on Windows XP x86 (should be cross-platform, though)

Procedure.s LineWrap (line$, softWrapPosn.i, hardWrapPosn.i=-1, delimList$=" "+Chr(9), nl$=#LF$, indent$="")
   ; -- Word wrap in *one line* of a text file, or in a window with a fixed-width font
   ; in: line$  : line which is to be wrapped
   ;     indent$: "" or a string consisting of blanks, used for indenting lines of list items
   ;
   ;     For the meaning of the other parameters see function WordWrap().
   Protected.i posn, found, i, firstChar=Len(indent$)+1
   Protected ret$=""
   
   If softWrapPosn < firstChar
      ProcedureReturn line$
   EndIf
   
   posn = Len(line$)
   While posn > softWrapPosn
      ; search for rightmost delimiter <= softWrapPosn:
      For i = softWrapPosn To firstChar Step -1
         found = FindString(delimList$, Mid(line$,i,1))
         If found
            posn = i
            Break
         EndIf
      Next
      
      If found = 0    ; if there is no delimiter <= softWrapPosn
         If hardWrapPosn < 0
            ; insert hard wrap at position of soft wrap:
            posn = softWrapPosn
         Else
            ; search for leftmost delimiter > softWrapPosn:
            For i = softWrapPosn+1 To posn
               found = FindString(delimList$, Mid(line$,i,1))
               If found
                  posn = i
                  Break
               EndIf
            Next
            If hardWrapPosn > 0 And hardWrapPosn < posn
               ; insert hard wrap at given position:
               posn = hardWrapPosn
            EndIf
         EndIf
      EndIf
      
      ret$ + RTrim(Left(line$, posn)) + nl$
      line$ = LTrim(Mid(line$, posn+1))
      If line$ <> ""
         line$ = indent$ + line$
      EndIf

      posn = Len(line$)
   Wend
   
   ProcedureReturn ret$ + line$
EndProcedure


Procedure.s WordWrap (text$, softWrapPosn.i, hardWrapPosn.i=-1, delimList$=" "+Chr(9), nl$=#LF$, liStart$="")
   ; ## Main function ##
   ; -- Word wrap in *one or more lines* of a text file, or in a window with a fixed-width font
   ; in : text$       : text which is to be wrapped;
   ;                    may contain #CRLF$ (Windows), or #LF$ (Linux and modern Mac systems) as line breaks
   ;      softWrapPosn: the desired maximum length (number of characters) of each resulting line
   ;                    if a delimiter was found (not counting the length of the inserted nl$);
   ;                    if no delimiter was found at a position <= softWrapPosn, a line might
   ;                    still be longer if hardWrapPosn = 0 or > softWrapPosn
   ;      hardWrapPosn: guaranteed maximum length (number of characters) of each resulting line
   ;                    (not counting the length of the inserted nl$);
   ;                    if hardWrapPosn <> 0, each line will be wrapped at the latest at
   ;                    hardWrapPosn, even if it doesn't contain a delimiter;
   ;                    default setting: hardWrapPosn = softWrapPosn
   ;      delimList$  : list of characters which are used as delimiters;
   ;                    any delimiter in line$ denotes a position where a soft wrap is allowed
   ;      nl$         : string to be used as line break (normally #CRLF$ or #LF$)
   ;      liStart$    : string at the beginning of each list item
   ;                    (providing this information makes proper indentation possible)
   ;
   ; out: return value: text$ with given nl$ inserted at appropriate positions
   ;
   ; <http://www.purebasic.fr/english/viewtopic.php?f=12&t=53800>
   Protected.i numLines, i, indentLen=-1
   Protected line$, indent$, ret$=""

   numLines = CountString(text$, #LF$) + 1
   For i = 1 To numLines
      line$ = RTrim(StringField(text$, i, #LF$), #CR$)

      If FindString(line$, liStart$) = 1
         If indentLen = -1
            indentLen = Len(liStart$)
         EndIf
         indent$ = Space(indentLen)
      Else
         indent$ = ""
      EndIf

      ret$ + LineWrap(line$, softWrapPosn, hardWrapPosn, delimList$, nl$, indent$)
      If i < numLines
         ret$ + nl$
      EndIf
   Next

   ProcedureReturn ret$
EndProcedure
Demo code:

Code: Select all

EnableExplicit

XIncludeFile "WordWrap.pbi"

Define line$, text$

line$ = "Wrap me baby but don't hurt me, I'll be good like a long stringy should and would! And here is a URL: http://www.purebasic.com/download.php"

MessageRequester("Word wrap demo 1/7", WordWrap(line$, 8, 0))    ; no hard wrap
MessageRequester("Word wrap demo 2/7", WordWrap(line$, 8, 998))  ; "security hard wrap" (will normally not emerge)
MessageRequester("Word wrap demo 3/7", WordWrap(line$, 8))       ; default: hard wrap position = soft wrap position
MessageRequester("Word wrap demo 4/7", WordWrap(line$, 1))       ; extreme wrapping :-)


text$ = "PureBasic is a native 32 bit and 64 bit programming language based on established BASIC rules. The key features of PureBasic are portability (Windows, Linux, MacOS X and AmigaOS are currently supported), the production of very fast and highly optimized executables and, of course, the very simple BASIC syntax. PureBasic has been created for the beginner and expert alike. We have put a lot of effort into its realization to produce a fast, reliable system friendly language." + #LF$
text$ + #LF$
text$ + "In spite of its beginner-friendly syntax, the possibilities are endless with PureBasic's advanced features such as pointers, structures, procedures, dynamically linked lists and much more. Experienced coders will have no problem gaining access to any of the legal OS structures or API objects and PureBasic even allows inline ASM." + #LF$
text$ + #LF$
text$ + "The main features of PureBasic" + #LF$
text$ + #LF$
text$ + "   - Huge set of internal commands (1100+) to quickly and easily build any application or game" + #LF$
text$ + "   - All BASIC keywords are supported" + #LF$
text$ + "   - Very fast compiler which creates highly optimized executables" + #LF$
text$ + "   - No external DLLs, runtime interpreter or anything else required when creating executables" + #LF$
text$ + "   - Procedure support for structured programming with local and global variables" + #LF$
text$ + "   - Full unicode support" + #LF$
text$ + "   - Access to full OS API for advanced programmers" + #LF$
text$ + "   - Easy but very fast 2D game support through dedicated libraries (DirectX, SDL, ...)" + #LF$
text$ + "   - Easy and high quality 3D support based on OGRE" + #LF$
text$ + "   - Optimal use of the available hardware by using highly optimized (assembly) commands" + #LF$
text$ + "   - Source code is portable between AmigaOS, Windows, MacOS X and Linux" + #LF$
text$ + "   - Dedicated editor and development environment" + #LF$
text$ + "   - Powerful integrated debugger and profiler to easily trace and analyze code" + #LF$
text$ + #LF$
text$ + "   - And here is a long URL: http://www.prettylongdomainname.com/level1/level2/level3/level4/level5/index.php"

MessageRequester("Word wrap demo 5/7", WordWrap(text$, 50))
MessageRequester("Word wrap demo 6/7", WordWrap(text$, 50,  -1, " "+Chr(9), #LF$, "   - "))
MessageRequester("Word wrap demo 7/7", WordWrap(text$, 50, 998, " "+Chr(9), #LF$, "   - "))
Last edited by Little John on Mon Aug 19, 2013 7:41 pm, edited 4 times in total.
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: Word wrap

Post by jassing »

wouldn't you want the length to be in pica's or inches or mm? the character length would only be good for fixed-width fonts...
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Word wrap

Post by Little John »

Works also with PB 5.20
jassing wrote:wouldn't you want the length to be in pica's or inches or mm? the character length would only be good for fixed-width fonts...
It depends on the situation, and what you want to do ...

Here is a function for word wrap of a line or complete paragraphs in a window which can have a variable-width font.
The underlying logic is the same as in the function above.

(Note: For 100% precise aligning of indented lines with a variable-width font, use DrawText().)

Include file:

Code: Select all

; v1.01, tested with PB 5.10 on Windows XP x86 (should be cross-platform, though)

Procedure.i GetTextWidth (window.i, gadget.i, text$)
   ; in : window: window number
   ;      gadget: gadget number
   ;      text$ : This function does not require that the text is
   ;              actually shown in the gadget.
   ; out: width of text$ in pixels
   Protected width.i=-1

   If StartDrawing(WindowOutput(window))
      DrawingFont(GetGadgetFont(gadget))
      width = TextWidth(text$)
      StopDrawing()
   EndIf

   ProcedureReturn width  ; -1 on error
EndProcedure

Procedure.i GetTextLen (window.i, gadget.i, text$, width.i)
   ; in : window: window number
   ;      gadget: gadget number
   ;      width : available width in pixels
   ;      text$ : This function does not require that the text is
   ;              actually shown in the gadget.
   ; out: maximum number of characters of text$ (counted from the left)
   ;      which fit into the available width
   Protected length.i=-1

   If StartDrawing(WindowOutput(window))
      DrawingFont(GetGadgetFont(gadget))
      length = Len(text$)
      While length > 0 And TextWidth(Left(text$, length)) > width
         length - 1
      Wend
      StopDrawing()
   EndIf

   ProcedureReturn length  ; -1 on error
EndProcedure


Procedure.s LineWrapW (window.i, gadget.i, line$, softWrapWidth.i, hardWrapWidth.i=-1, delimList$=" "+Chr(9), nl$=#LF$, indent$="")
   ; -- Word wrap in *one line* in a window (can have a variable-width font)
   ; in: line$  : line which is to be wrapped
   ;     indent$: "" or a string consisting of blanks, used for indenting lines of list items
   ;
   ;     For the meaning of the other parameters see function WordWrapW().
   Protected.i posn, found, i, softWrapPosn, hardWrapPosn, firstChar=Len(indent$)+1
   Protected ret$=""

   softWrapPosn = GetTextLen(window, gadget, line$, softWrapWidth)
   If softWrapPosn < firstChar
      ProcedureReturn line$
   EndIf

   posn = Len(line$)
   While posn > softWrapPosn
      ; search for rightmost delimiter <= softWrapPosn:
      For i = softWrapPosn To firstChar Step -1
         found = FindString(delimList$, Mid(line$,i,1))
         If found
            posn = i
            Break
         EndIf
      Next

      If found = 0    ; if there is no delimiter <= softWrapPosn
         If hardWrapWidth < 0
            ; insert hard wrap at position of soft wrap:
            posn = softWrapPosn
         Else
            ; search for leftmost delimiter > softWrapPosn:
            For i = softWrapPosn+1 To posn
               found = FindString(delimList$, Mid(line$,i,1))
               If found
                  posn = i
                  Break
               EndIf
            Next
            If hardWrapWidth > 0
               hardWrapPosn = GetTextLen(window, gadget, line$, hardWrapWidth)
               If hardWrapPosn < posn
                  ; insert hard wrap at given position:
                  posn = hardWrapPosn
               EndIf
            EndIf
         EndIf
      EndIf

      ret$ + RTrim(Left(line$, posn)) + nl$
      line$ = LTrim(Mid(line$, posn+1))
      If line$ <> ""
         line$ = indent$ + line$
      EndIf

      softWrapPosn = GetTextLen(window, gadget, line$, softWrapWidth)
      posn = Len(line$)
   Wend

   ProcedureReturn ret$ + line$
EndProcedure


Procedure.s WordWrapW (window.i, gadget.i, text$, softWrapWidth.i, hardWrapWidth.i=-1, delimList$=" "+Chr(9), nl$=#LF$, liStart$="")
   ; ## Main function ##
   ; -- Word wrap in *one or more lines* in a window (can have a variable-width font)
   ; in : window       : window number
   ;      gadget       : gadget number
   ;      text$        : text which is to be wrapped;
   ;                     may contain #CRLF$ (Windows), or #LF$ (Linux and modern Mac systems) as line breaks
   ;      softWrapWidth: the desired maximum width (pixels) of each resulting line
   ;                     if a delimiter was found (not counting the length of the inserted nl$);
   ;                     if no delimiter was found at a position <= softWrapWidth, a line might
   ;                     still be longer if hardWrapWidth = 0 or > softWrapWidth
   ;      hardWrapWidth: guaranteed maximum width (pixels) of each resulting line
   ;                     (not counting the length of the inserted nl$);
   ;                     if hardWrapWidth <> 0, each line will be wrapped at the latest at
   ;                     hardWrapWidth, even if it doesn't contain a delimiter;
   ;                     default setting: hardWrapWidth = softWrapWidth
   ;      delimList$   : list of characters which are used as delimiters;
   ;                     any delimiter in line$ denotes a position where a soft wrap is allowed
   ;      nl$          : string to be used as line break (normally #CRLF$ or #LF$)
   ;      liStart$     : string at the beginning of each list item
   ;                     (providing this information makes proper indentation possible)
   ;
   ; out: return value : text$ with given nl$ inserted at appropriate positions
   ;
   ; <http://www.purebasic.fr/english/viewtopic.php?f=12&t=53800>
   Protected.i numLines, i, indentPixels, indentLen=-1
   Protected line$, indent$, ret$=""

   numLines = CountString(text$, #LF$) + 1
   For i = 1 To numLines
      line$ = RTrim(StringField(text$, i, #LF$), #CR$)

      If FindString(line$, liStart$) = 1
         If indentLen = -1
            indentPixels = GetTextWidth(window, gadget, liStart$)
            indentLen = GetTextLen(window, gadget, Space(Len(text$)), indentPixels)
         EndIf
         indent$ = Space(indentLen)
      Else
         indent$ = ""
      EndIf

      ret$ + LineWrapW(window, gadget, line$, softWrapWidth, hardWrapWidth, delimList$, nl$, indent$)
      If i < numLines
         ret$ + nl$
      EndIf
   Next

   ProcedureReturn ret$
EndProcedure
Demo code:

Code: Select all

EnableExplicit

XIncludeFile "WordWrapW.pbi"

Procedure ShowWindow (title$, text$, softWrapWidth.i, hardWrapWidth.i=-1, delimList$=" "+Chr(9), nl$=#LF$, liStart$="")
   If OpenWindow(0, 0, 0, 450, 650, title$, #PB_Window_SystemMenu | #PB_Window_ScreenCentered) = 0
      MessageRequester("Fatal error", "Program terminated.")
      End
   EndIf

   TextGadget(0, 10, 10, 430, 630, "")
   text$ = WordWrapW(0, 0, text$, softWrapWidth, hardWrapWidth, delimList$, nl$, liStart$)
   SetGadgetText(0, text$)

   Repeat
   Until WaitWindowEvent() = #PB_Event_CloseWindow
   CloseWindow(0)
EndProcedure


Define line$, text$

line$ = "Wrap me baby but don't hurt me, I'll be good like a long stringy should and would! And here is a long URL: http://www.purebasic.com/download.php"

ShowWindow("Word wrap demo 1/7", line$, 30, 0)     ; no hard wrap
ShowWindow("Word wrap demo 2/7", line$, 30, 5000)  ; "security hard wrap" (will normally not emerge)
ShowWindow("Word wrap demo 3/7", line$, 30)        ; default: hard wrap position = soft wrap position
ShowWindow("Word wrap demo 4/7", line$, 11)        ; extreme wrapping :-)


text$ = "PureBasic is a native 32 bit and 64 bit programming language based on established BASIC rules. The key features of PureBasic are portability (Windows, Linux, MacOS X and AmigaOS are currently supported), the production of very fast and highly optimized executables and, of course, the very simple BASIC syntax. PureBasic has been created for the beginner and expert alike. We have put a lot of effort into its realization to produce a fast, reliable system friendly language." + #LF$
text$ + #LF$
text$ + "In spite of its beginner-friendly syntax, the possibilities are endless with PureBasic's advanced features such as pointers, structures, procedures, dynamically linked lists and much more. Experienced coders will have no problem gaining access to any of the legal OS structures or API objects and PureBasic even allows inline ASM." + #LF$
text$ + #LF$
text$ + "The main features of PureBasic" + #LF$
text$ + #LF$
text$ + "   - Huge set of internal commands (1100+) to quickly and easily build any application or game" + #LF$
text$ + "   - All BASIC keywords are supported" + #LF$
text$ + "   - Very fast compiler which creates highly optimized executables" + #LF$
text$ + "   - No external DLLs, runtime interpreter or anything else required when creating executables" + #LF$
text$ + "   - Procedure support for structured programming with local and global variables" + #LF$
text$ + "   - Full unicode support" + #LF$
text$ + "   - Access to full OS API for advanced programmers" + #LF$
text$ + "   - Easy but very fast 2D game support through dedicated libraries (DirectX, SDL, ...)" + #LF$
text$ + "   - Easy and high quality 3D support based on OGRE" + #LF$
text$ + "   - Optimal use of the available hardware by using highly optimized (assembly) commands" + #LF$
text$ + "   - Source code is portable between AmigaOS, Windows, MacOS X and Linux" + #LF$
text$ + "   - Dedicated editor and development environment" + #LF$
text$ + "   - Powerful integrated debugger and profiler to easily trace and analyze code" + #LF$
text$ + #LF$
text$ + "   - And here is a long URL: http://www.prettylongdomainname.com/level1/level2/level3/level4/level5/index.php"

ShowWindow("Word wrap demo 5/7", text$, 250)
ShowWindow("Word wrap demo 6/7", text$, 250,  -1, " "+Chr(9), #LF$, "   - ")
ShowWindow("Word wrap demo 7/7", text$, 250, 998, " "+Chr(9), #LF$, "   - ")
Last edited by Little John on Mon Aug 19, 2013 7:42 pm, edited 3 times in total.
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Word wrap

Post by Little John »

In the first post, I fixed a bug and added a short description.
The third post now contains a new function for word wrap in a window which can have a variable-width font.
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Word wrap

Post by Danilo »

Thanks Little John, very useful! So much new cool stuff coming in here atm, just can't follow everything. :)
MachineCode
Addict
Addict
Posts: 1482
Joined: Tue Feb 22, 2011 1:16 pm

Re: Word wrap

Post by MachineCode »

Danilo wrote:So much new cool stuff coming in here atm
Yes, there's a lot of string-parsing going on lately. :)
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
MachineCode
Addict
Addict
Posts: 1482
Joined: Tue Feb 22, 2011 1:16 pm

Re: Word wrap

Post by MachineCode »

Little John, I just tested your procedure and it fails with multi-line blocks of text. Observe:

Code: Select all

Procedure.s WordWrap (source$, softWrapPosn.i, hardWrapPosn.i=-1, delimList$=" "+Chr(9), nl$=#LF$)

 Protected.i posn, found, i
 Protected ret$=""

 If softWrapPosn <= 0
    ProcedureReturn source$
 EndIf

 If hardWrapPosn < 0
    hardWrapPosn = softWrapPosn
 EndIf

 posn = Len(source$)
 While posn > softWrapPosn
    ; search for rightmost delimiter <= softWrapPosn:
    For i = softWrapPosn To 1 Step -1
       found = FindString(delimList$, Mid(source$,i,1))
       If found
          posn = i
          Break
       EndIf
    Next

    If found = 0    ; if there is no delimiter <= softWrapPosn
       ; search for leftmost delimiter > softWrapPosn:
       For i = softWrapPosn+1 To posn
          found = FindString(delimList$, Mid(source$,i,1))
          If found
             posn = i
             Break
          EndIf
       Next
       If hardWrapPosn <> 0 And hardWrapPosn < posn
          ; insert hard wrap at given position:
          posn = hardWrapPosn
       EndIf
    EndIf

    ret$ + RTrim(Left(source$, posn)) + nl$
    source$ = LTrim(Mid(source$, posn+1))

    posn = Len(source$)
 Wend

 ProcedureReturn ret$ + source$
EndProcedure

text$="Here's a short block of text that we want to"+#CRLF$
text$+"wrap at the 30 position. As you'll see in the"+#CRLF$
text$+"message requester, it fails to do so, with some"+#CRLF$
text$+"single words on a line by themselves."+#CRLF$

MessageRequester("Word Wrap failure",WordWrap(text$,30,0))
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Word wrap

Post by Little John »

MachineCode wrote:Little John, I just tested your procedure and it fails with multi-line blocks of text.
You can just use ReplaceString() before passing the text to my procedure. The last lines of the code will then look like this:

Code: Select all

text$ = ReplaceString(text$, #CRLF$, " ")
MessageRequester("Word Wrap", WordWrap(text$,30,0))
Yes, maybe something like that could/should be built into the procedure.
MachineCode
Addict
Addict
Posts: 1482
Joined: Tue Feb 22, 2011 1:16 pm

Re: Word wrap

Post by MachineCode »

Little John wrote:You can just use ReplaceString() before passing the text to my procedure.
I knew you were going to say that, but I was hoping you wouldn't. :) Doing that ruins any text formatting by turning any paragraphs of text into one single long paragraph of word-wrapped text, which is not really a solution. I'm not trashing you; I'm trying to solve it myself, but it's proving to be hard.
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Word wrap

Post by Little John »

MachineCode wrote:turning any paragraphs of text into one single long paragraph of word-wrapped text
I believed that that is your goal. If that's not the case, then I don't know what you exactly want to achieve.
MachineCode
Addict
Addict
Posts: 1482
Joined: Tue Feb 22, 2011 1:16 pm

Re: Word wrap

Post by MachineCode »

Word-wrap isn't mean to destroy paragraphs. Take PureBasic's home page for example. Let's say you want to word-wrap the following text into 50-char column widths, and keep it as formatted. That's the goal of any word-wrap function. Why turn it into one long ugly paragraph and break all formatting?

Code: Select all

PureBasic is a native 32 bit and 64 bit programming language based on established BASIC rules. The key features of PureBasic are portability (Windows, Linux, MacOS X and AmigaOS are currently supported), the production of very fast and highly optimized executables and, of course, the very simple BASIC syntax. PureBasic has been created for the beginner and expert alike. We have put a lot of effort into its realization to produce a fast, reliable system friendly language.

In spite of its beginner-friendly syntax, the possibilities are endless with PureBasic's advanced features such as pointers, structures, procedures, dynamically linked lists and much more. Experienced coders will have no problem gaining access to any of the legal OS structures or API objects and PureBasic even allows inline ASM.

The main features of PureBasic

   - Huge set of internal commands (1100+) to quickly and easily build any application or game
   - All BASIC keywords are supported
   - Very fast compiler which creates highly optimized executables
   - No external DLLs, runtime interpreter or anything else required when creating executables
   - Procedure support for structured programming with local and global variables
   - Full unicode support
   - Access to full OS API for advanced programmers
   - Easy but very fast 2D game support through dedicated libraries (DirectX, SDL, ...)
   - Easy and high quality 3D support based on OGRE
   - Optimal use of the available hardware by using highly optimized (assembly) commands
   - Source code is portable between AmigaOS, Windows, MacOS X and Linux
   - Dedicated editor and development environment
   - Powerful integrated debugger and profiler to easily trace and analyze code
To see what I mean, look how Notepad word-wraps it, yet keeps the formatting:

Image
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Word wrap

Post by Little John »

MachineCode wrote:Why turn it into one long ugly paragraph and break all formatting?
As I already wrote, I just suggested to use ReplaceString() because I assumed that it would give you the desired result. I had to guess because you previously didn't write exactly want you want.

However, thanks for this new example.
My procedures were originally intended for one line only. Complete paragraphs like in your above example can be handled by splitting them into separate lines, and then do word wrapping for each line. Below you see a code example for this.

Maybe I'll build this functionality directly into both procedures.

Code: Select all

EnableExplicit

XIncludeFile "wordwrap.pbi"     ; <= PROCEDURE FROM THE FIRST POST IN THIS THREAD

Define numLines.i, i.i, text$, msg$=""

text$ = "PureBasic is a native 32 bit and 64 bit programming language based on established BASIC rules. The key features of PureBasic are portability (Windows, Linux, MacOS X and AmigaOS are currently supported), the production of very fast and highly optimized executables and, of course, the very simple BASIC syntax. PureBasic has been created for the beginner and expert alike. We have put a lot of effort into its realization to produce a fast, reliable system friendly language." + #LF$
text$ + #LF$
text$ + "In spite of its beginner-friendly syntax, the possibilities are endless with PureBasic's advanced features such as pointers, structures, procedures, dynamically linked lists and much more. Experienced coders will have no problem gaining access to any of the legal OS structures or API objects and PureBasic even allows inline ASM." + #LF$
text$ + #LF$
text$ + "The main features of PureBasic" + #LF$
text$ + #LF$
text$ + "   - Huge set of internal commands (1100+) to quickly and easily build any application or game" + #LF$
text$ + "   - All BASIC keywords are supported" + #LF$
text$ + "   - Very fast compiler which creates highly optimized executables" + #LF$
text$ + "   - No external DLLs, runtime interpreter or anything else required when creating executables" + #LF$
text$ + "   - Procedure support for structured programming with local and global variables" + #LF$
text$ + "   - Full unicode support" + #LF$
text$ + "   - Access to full OS API for advanced programmers" + #LF$
text$ + "   - Easy but very fast 2D game support through dedicated libraries (DirectX, SDL, ...)" + #LF$
text$ + "   - Easy and high quality 3D support based on OGRE" + #LF$
text$ + "   - Optimal use of the available hardware by using highly optimized (assembly) commands" + #LF$
text$ + "   - Source code is portable between AmigaOS, Windows, MacOS X and Linux" + #LF$
text$ + "   - Dedicated editor and development environment" + #LF$
text$ + "   - Powerful integrated debugger and profiler to easily trace and analyze code"

numlines = CountString(text$, #LF$) + 1
For i = 1 To numLines
   msg$ + WordWrap(StringField(text$, i, #LF$), 50) + #LF$
Next
MessageRequester("Demo",  msg$)
MachineCode
Addict
Addict
Posts: 1482
Joined: Tue Feb 22, 2011 1:16 pm

Re: Word wrap

Post by MachineCode »

Little John wrote:Complete paragraphs like in your above example can be handled by splitting them into separate lines, and then do word wrapping for each line.
Thank you! :D I appreciate you taking the time to help.
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Word wrap

Post by Little John »

Changes in the new version 1.00:
  • extended the demo codes, and moved them to separate code blocks
  • rearranged some lines in the procedures, so that they work more effectively
  • renamed the original procedures to LineWrap() and LineWrapW(), respectively; also edited the comments for better documentation that these procedures do word wrap of a single line only
  • introduced new main functions WordWrap() and WordWrapW(), respectively; they can do proper word wrap also in complete paragraphs, and can even indent bullet lists correctly:

    Image
Thanks for all questions and comments, which motivated me to improve the code!
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: Word wrap

Post by davido »

Just tried out version 1.00 - Very nice.

Thank you very much for sharing. :D
DE AA EB
Post Reply