RegEx word wrap

Technical support and scripting issues

Moderators: JRL, Dorian (MJT support)

Post Reply
User avatar
JRL
Automation Wizard
Posts: 3532
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

RegEx word wrap

Post by JRL » Thu Jul 23, 2009 1:16 pm

I confess I've been negligent. I have not looked into RegEx at all. Still, I'm wondering if anyone knows how RegEx could be used to create WordWrap for dialog labels?

Imagine a user input line that allows the user to type several hundred characters. Then I want to display that typing on a label, but I want to limit the length of each displayed line to 100 characters. Can regex be used to replace a space with CRLF at a max of 100 characters?

Hope this makes sense.
Dick

User avatar
Bob Hansen
Automation Wizard
Posts: 2475
Joined: Tue Sep 24, 2002 3:47 am
Location: Salem, New Hampshire, US
Contact:

Post by Bob Hansen » Thu Jul 23, 2009 2:19 pm

I will try to take a look at the RegEx expression. Putting %CRLF% in position 100 is quite easy, but making it happen at the previous natural space break will take some more effort.

But in the meantime, how about looping, getting Position of each space char. Record position and go to next space char. When position of space char is >100 then we know the position of the last space char should be replaced with %CRLF%. You could use two MidStrings separated with the %CRLF. MidString1 = position1 to last space char. MidString2 = last space char to end of line.
Hope this was helpful..................good luck,
Bob
A humble man and PROUD of it!

User avatar
JRL
Automation Wizard
Posts: 3532
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Post by JRL » Thu Jul 23, 2009 3:17 pm

Bob,
Not exactly your suggestion, but here is a working sample primarily using separate> and length>. I still think it would be cool (and much more concise) to have a one line RegEx word wrap

Code: Select all

//Sample Text String
Let>text=WE ARE TO PROVIDE FORMED BLANK WITH OPENINGS, SECOND MACHINE SETUP TO TRIM AFTER FORM, NO VIBRATORY DEBUR AFTER SECOND MACHINE TRIM, MATERIAL CUSTOMER PROVIDED.

//Maximum text line length
Let>WrapLength=60

//Define a few variables
Let>lineLength=0
Let>NewText=
Let>NewLine=
Let>kk=0

//Divide the text string up using spaces
Separate>text,%SPACE%,word

/*
Put the individual words back together into a continuous string
adding back the spaces.  When the string exceeds the defined Wrap
Length, replace a space with a CRLF so that the continuous string
wraps when displayed as a dialog label.
*/
Repeat>kk
  add>kk,1
  Let>value=word_%kk%
  Length>value,long
  Add>LineLength,%long%
  Add>LineLength,1
  If>%LineLength%>%WrapLength%
    ConCat>NewText,%NewLine%%CRLF%
    Let>NewLine=%value%%SPACE%
    Length>NewLine,lineLength
  Else
    ConCat>NewLine,%value%%SPACE%
  EndIF
Until>kk,word_count
  ConCat>NewText,%NewLine%
  StringReplace>NewText,%SPACE%%CRLF%,%CRLF%,NewText

//Display the sample text wrapped
Dialog>Dialog1
   Caption=View Sample Text... Wrapped
   Width=445
   Height=250
   Top=189
   Left=41
   Label=msLabel1,32,32
EndDialog>Dialog1

Show>Dialog1
Let>Dialog1.msLabel1=%NewText%

Label>Loop
  GetDialogAction>Dialog1,res1
  If>res1=2
    Exit>0
  EndIf
Goto>Loop


User avatar
Bob Hansen
Automation Wizard
Posts: 2475
Joined: Tue Sep 24, 2002 3:47 am
Location: Salem, New Hampshire, US
Contact:

Post by Bob Hansen » Fri Jul 24, 2009 12:52 am

Hello Dick.

Here is a RegEx that may do it for you.

Code: Select all

// 7/23/09 http://www.mjtnet.com/usergroup/viewtopic.php?t=5626
// Inserting a line break for word wrap length 100

Let>vSample=This is some dummy text just to test how the words will look after we do some modifications.  This is some dummy text just to test how the words will look after we do some modifications.  This is some dummy text just to test how the words will look after we do some modifications.

// Next lines are to capture the last word in a paragraph.
// Insert a SPACE at the end of the paragraph, or replace %CRLF% in a real text file with %SPACE%%CRLF%
Let>vSample=%vSample%%SPACE%
// StringReplace>%vsample%,%CRLF%,SPACE%%CRLF%,vSample

Let>vNeedle=(.{1,98})%SPACE%
Let>vHaystack=%vSample%
Let>vReplacement=$1%CRLF%
RegEx>%vNeedle%,%vHaystack%,0,matches,matchnum,1,%vReplacement%,vNewData
MessageModal>New data is %vNewData%
Exit>0
Comments:
1. The margin can be changed by modifying the "98" in the Needle. Just make it 2 chars less than the desired word wrap width.
2. The basic replacement worked fine except for the last word in a paragraph. Because there is no trailing space for the Needle match, then the last word did not get included. So I have added a SPACE to the end of the Sample text. But this sample is discreet. If the Sample was a file, then you need to replace all of the CRLF with a leading SPACE. Kind of kludgy, but it seems to work right now.
3. This is not a true Word Wrap because it ends up with Hard Return codes at the end of each line. Would need to remove them and replace with SPACE chars if you decide to edit/reformat the document.
===========================================

7/24/09 ... EDITED NOTE: I submitted an improved version of this script on 7/24. It is a few posts down from here. It handles the trailing last word and eliminates the extra steps I used here to handle that.
Last edited by Bob Hansen on Fri Jul 24, 2009 1:22 pm, edited 1 time in total.
Hope this was helpful..................good luck,
Bob
A humble man and PROUD of it!

User avatar
JRL
Automation Wizard
Posts: 3532
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Post by JRL » Fri Jul 24, 2009 5:16 am

Wow... regex is like magic.

I did some experimenting with your original code (making the line length smaller so it wasn't so hard to count characters). Also made the Message box wider so I knew the wrap wasn't being caused by the message box. It appears to be working very well.
3. This is not a true Word Wrap because it ends up with Hard Return codes at the end of each line. Would need to remove them and replace with SPACE chars if you decide to edit/reformat the document.
Good information but for my purposes it is irrelevant. All I want to do is wrap long dialog labels automatically so I can pull router descriptions from a data base and display them as dialog labels. In This post, Migro is asking for a similar solution for tooltip creation.

Nice work Bob. I greatly appreciate your creation.

User avatar
jpuziano
Automation Wizard
Posts: 1085
Joined: Sat Oct 30, 2004 12:00 am

Post by jpuziano » Fri Jul 24, 2009 7:21 am

Great use of regex, thanks Bob.
jpuziano

Note: If anyone else on the planet would find the following useful...
[Open] PlayWav command that plays from embedded script data
...then please add your thoughts/support at the above post - :-)

User avatar
Bob Hansen
Automation Wizard
Posts: 2475
Joined: Tue Sep 24, 2002 3:47 am
Location: Salem, New Hampshire, US
Contact:

Post by Bob Hansen » Fri Jul 24, 2009 1:19 pm

Here is an improved solution that handles the trailing word without extra steps:

Code: Select all

// 7/24/09 http://www.mjtnet.com/usergroup/viewtopic.php?t=5626
// Inserting a line break for word wrap length 100

Let>vSample=This is some dummy text just to test how the words will look after we do some modifications.  This is some dummy text just to test how the words will look after we do some modifications.  This is some dummy text just to test how the words will look after we do some modifications.

Let>vNeedle=(.{1,98})(%SPACE%|$)
Let>vHaystack=%vSample%
Let>vReplacement=$1%CRLF%
RegEx>%vNeedle%,%vHaystack%,0,matches,matchnum,1,%vReplacement%,vNewData
MessageModal>New data is %vNewData%
Exit>0
You had asked for on one line RegEx, and this is the best I can do, using the code from above:

Code: Select all

RegEx>(.{1,98})(%SPACE%|$),This is some dummy text just to test how the words will look after we do some modifications.  This is some dummy text just to test how the words will look after we do some modifications.  This is some dummy text just to test how the words will look after we do some modifications.,0,matches,matchnum,1,$1%CRLF%,vNewData
MessageModal>New data is %vNewData%
I find it easier to read and modify by breaking out the Sample, Needle, Haystack, and Replacement values, so the first version here is my preferred format.
=====================
EDITED NOTE: JRL pointed out that this single-line RegEx did not work because of the comma in the beginning( 1,98 ). I guess we could use %COMMA% and still stay with a one-liner, but I am not going to test it :twisted: , will just show the result:

Code: Select all

RegEx>(.{1%COMMA%98})(%SPACE%|$),This is some dummy text just to test how the words will look after we do some modifications.  This is some dummy text just to test how the words will look after we do some modifications.  This is some dummy text just to test how the words will look after we do some modifications.,0,matches,matchnum,1,$1%CRLF%,vNewData
MessageModal>New data is %vNewData%
This is another reason to keep the command parameters outside the command line, prevent delimiter issues. I was lucky there were no commas in the Haystack. :shock:
Last edited by Bob Hansen on Sat Jul 25, 2009 6:49 am, edited 4 times in total.
Hope this was helpful..................good luck,
Bob
A humble man and PROUD of it!

User avatar
JRL
Automation Wizard
Posts: 3532
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Post by JRL » Fri Jul 24, 2009 1:34 pm

:D Thanks Bob. I knew you wouldn't rest until you figured it out. :D

User avatar
JRL
Automation Wizard
Posts: 3532
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Post by JRL » Sat Jul 25, 2009 5:47 am

Hi Bob,

FYI
Got a chance to try your one liner this evening and it does not work. I think its because of the comma in the needle. If I run:

Code: Select all

RegEx>(.{1,98})(%SPACE%|$),This is some dummy text just to test how the words will look after we do some modifications.  This is some dummy text just to test how the words will look after we do some modifications.  This is some dummy text just to test how the words will look after we do some modifications.,0,matches,matchnum,1,$1%CRLF%,vNewData
MessageModal>New data is %vNewData%
My message displays "New data is %vNewData%"

However, If I add one line from your original code and alter the line to use the variable, all works as planned.

Code: Select all

Let>vNeedle=(.{1,98})(%SPACE%|$)
RegEx>vNeedle,This is some dummy text just to test how the words will look after we do some modifications.  This is some dummy text just to test how the words will look after we do some modifications.  This is some dummy text just to test how the words will look after we do some modifications.,0,matches,matchnum,1,$1%CRLF%,vNewData
MessageModal>New data is %vNewData%
This works great, no need for further development on my account. The "one line" comment was sarcasm not necessity.

Thanks for sharing your time and talent.
Dick

User avatar
Bob Hansen
Automation Wizard
Posts: 2475
Joined: Tue Sep 24, 2002 3:47 am
Location: Salem, New Hampshire, US
Contact:

Post by Bob Hansen » Sat Jul 25, 2009 6:39 am

Thanks for catching that issue Dick. I never tested the line, just did a cut/paste from the lines above. I should know better, ALWAYS TEST BEFORE POSTING.

Just another reason to define the parameters outside the command. I usually do that for most commands with multiple commas, like HTTPRequest and SMTPMail

I have added a comment to the defective one-liner.
Hope this was helpful..................good luck,
Bob
A humble man and PROUD of it!

Post Reply
Sign up to our newsletter for free automation tips, tricks & discounts