40 character label box with 10 character indent

So what I am trying to do is create a label template that has a 40 character “limit.” Not really a limit per say but where I can put 40 characters within the text field and have it formatted at 10 character intervals correctly.

At first I tried to do it in expression language which was not working very well at all. This is the code.

switch(
	20 <= len({textField.Text})>10,
	30 <= len({textField.Text})>20,
	40 <= len({textField.Text})>30,
	
	event.source.text = "<html>"+ left({textField.Text},10)+" 
        <br>"+right(left({textField.Text},len({textField.Text})), 20- 
         len({textField.Text})),

	event.source.text = "<html>"+ left({textField.Text},10)+"<br>"+right(left({textField.Text},20), 10)+" 
        <br>"+right(left({textField.Text},len({textField.Text})), 30-len({textField.Text})),

	event.source.text = "<html>"+ left({textField.Text},10)+"<br>"+right(left({textField.Text},20), 10)+" 
        <br>"+right(left({textField.Text},30), 10)+"<br>"+right(left({textField.Text},len({textField.Text})), 40- 
         len({textField.Text})),

	event.source.text = "<html>"+ left({textField.Text},10))

Note that the each of the return lines were in single lines in the code. Also the errors that I got from this were either that I can’t use 7 arguments with a switch function or that the left cannot use 3 arguments. The code was slightly different each time as I had tried to modify it in between to solve my problem so I can’t be sure this is the exact code that tripped said error. I do know when there was the 7 arguments error I hadn’t defined event.source.text to equal the formatted text field though I can’t be sure that the 7 arg. error didn’t throw afterwards as it was a constant flurry of errors and I can’t check the errors without copying my code, removing the binding, and exiting the expression popup.

After I banged my head on that for a bit I tried scripting. Both property change scripting and through a runScript() function in the expression binding. The property change scripting didn’t do a whole lot as the binding to whatever property change was being used didn’t trigger when I put text into the template parameter.

The closest I seemed to get was through the runScript() in the expression binding but I have the problems where my designer froze and I am lost as to what I am doing wrong with my code.

Script code:

def labelWrap(input, output):
        # On line 1 I defined the 2 variables. Input is where the string is coming from and 
	# output is where the string is being written to in formatted form
        text = input
	strLength = len(text)
	# In lines 4-6 I defined the variables to be used and took the len, or string length, of the input 
        # string.
	
	if 20 < strLength > 10: 
		output = "<html>"+text[:10]+"<br>"+text[11:20]
	elif 30 < strLength > 20:
		output = "<html>"+text[:10]+"<br>"+text[11:20]+"<br>"+text[21:30]
	elif strLength > 30:
		output = "<html>"+text[:10]+"<br>"+text[11:20]+"<br>"+text[21:30]+"<br>"+text[31:]
	else:
		output = "<html>"+text[:10]
	# The rest of this code just wraps the text in html format depending on the length of the string.
	# Any string above 40 characters long will make the breaks act funky so don't do that.

template text field code(bound through expression property:

runScript("labelTextWrap.labelWrap", 0, {textField.Text}, {textField.Label.text})

If there is anything that I need to elaborate on or if there is simply a better way to do this lmk.

Okay so I just realized that I had been not assigning a value to the switch function.
updated code

switch({textField.Label.text},
	20 <= len({textField.Text})>10,
	30 <= len({textField.Text})>20,
	40 <= len({textField.Text})>30,
	
	"<html>"+ left({textField.Text},10)+"<br>"+right(left({textField.Text},len({textField.Text})), 20-len({textField.Text})),
	"<html>"+ left({textField.Text},10)+"<br>"+right(left({textField.Text},20), 10)+"<br>"+right(left({textField.Text},len({textField.Text})), 30-len({textField.Text})),
	"<html>"+ left({textField.Text},10)+"<br>"+right(left({textField.Text},20), 10)+"<br>"+right(left({textField.Text},30), 10)+"<br>"+right(left({textField.Text},len({textField.Text})), 40-len({textField.Text})),
	"<html>"+ left({textField.Text},10))

The only thing is now all it does is return the first 10 digits of the text field and doesn’t add on the rest of it.

import textwrap

def delimit(string):
	return "<html>" + "<br>".join(textwrap.wrap(string, width=10))
	
print delimit("lorem ipsum some long text")

>>> <html>lorem<br>ipsum some<br>long text

Perhaps close enough for your purposes?

See textwrap: 7.7. textwrap — Text wrapping and filling — Python 2.7.18 documentation

Yes that’s exactly what I wanted. Good to know that there is a pylib function for text wrapping. That makes this much easier to do. Thank you.

edit: I put the code into the project library as a script and then used runScript(“textWrap.delimit”, 0, {textField.Text}) in the expression binding. It worked like a charm.

That’s… weird looking.
It means: strLength is bigger than 10 AND bigger than 20. Are you sure that’s what you meant ?

You’re using the same thing with the expressions, and that’s where it might get much hairier. Python is nice that way, and allows chaining comparisons. Most languages don’t, and from some basic tests I just did, expressions don’t. In most cases, one of the comparisons is evaluated, and the result is then used in the next comparison, with false = 0 and 1 = true:
if (1 < 3 > 2, true, false) returns false
if (1 < 3 < 2, true, false) returns true
While you may expect the opposite, it makes sense if you consider that 1 < 3 is true, and thus returns 1, which is then used in 1 > 2 or 1 < 2.

Oh good point thanks for the correction. My goal had been to use less than or equal to 20 and bigger than 10 but the logic wasn’t sound as I put the wrong symbol there.

With your correction this is good as a workaround but as @PGriffith pointed out there is a pylib function textwrap that has similar functions as this code plus much more. With just a little scripting in the project library you get the same functionality as this code with much less coding. Plus you could add another parameter to the delimit function to make the width dynamic as well.

edit: grammar