add word wrap to a string

Post your working scripts, libraries and tools
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

add word wrap to a string

29 Nov 2018, 17:01

- Here's a function to split a string into multiple lines. Not tested extensively.
- E.g. if you specify a space and 50 characters, it will start at character 51 and look backwards for the first space to the left, if not found: it will start at character 1 and look for the first space to the right, if not found: it will treat the text as one line.
- Do post any links to relevant functions/threads. Cheers.

Code: Select all

vText := "aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa"
MsgBox, % JEE_StrWrap(vText, 17)
MsgBox, % ";" JEE_StrWrap(vText, 17, " ", "`r`n;")

;==================================================

; ;e.g.
; vText := "aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa"
; MsgBox(JEE_StrWrap(vText, 17))
; MsgBox(";" JEE_StrWrap(vText, 17, " ", "`r`n;"))

;split one line into multiple lines
;vMaxLen: maximum length in characters per line
JEE_StrWrap(vText, vMaxLen, vNeedle:=" ", vSep:="`r`n")
{
	local
	static vIsV1 := InStr(1, 1,, 0)
	vOutput := ""
	VarSetCapacity(vOutput, StrLen(vText)*2*2)
	Loop
	{
		vLen := StrLen(vText)
		if (vLen <= vMaxLen)
			return vOutput vText
		;e.g. AHK v2: abcdefghij ;h is position 8 aka -3=-len+8-1=-10+8-1
		;vPos := JEE_InStr(vText, vNeedle, 1, vMaxLen - vLen)
		vPos := InStr(vText, vNeedle, 1, vMaxLen - vLen + vIsV1) ;find first occurrence at vMaxLen+1 or before
		if !vPos
			vPos := InStr(vText, vNeedle)
		if !vPos
			return vOutput vText
		vOutput .= SubStr(vText, 1, vPos-1) vSep
		vText := SubStr(vText, vPos+StrLen(vNeedle))
	}
}
- Similar code:
Edit some text files, string length - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=33520
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
SL5
Posts: 879
Joined: 12 May 2015, 02:10
GitHub: sl5net
Contact:

Re: add word wrap to a string

30 Nov 2018, 12:18

pretty nice :-)
my review: https://youtu.be/NOCiV85Od6U
just me
Posts: 8526
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: add word wrap to a string

01 Dec 2018, 03:30

Hi jeeswg,

just two notes:
  1. Code: Select all

    		vPos := InStr(vText, vNeedle, 1, vMaxLen - vLen + vIsV1) ;find first occurrence at vMaxLen+1 or before
    is case-sensitive. Why isn't

    Code: Select all

    			vPos := InStr(vText, vNeedle)
  2. Code: Select all

    		vPos := InStr(vText, vNeedle, 1, vMaxLen - vLen + vIsV1) ;find first occurrence at vMaxLen+1 or before
    will find the needle within the first vMaxLen characters. So

    Code: Select all

    			vPos := InStr(vText, vNeedle)
    should start the search at position vMaxLen + 1. (I know, it's somewhat fussy.)
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: add word wrap to a string

01 Dec 2018, 09:57

- @just me. Thanks. Fussy is good! I meant to give the function a further review.
- Here's a fixed function.
- I've added both changes, I intended to add the 2nd change anyway but kept the script simpler initially as a fallback ...
- I was concerned about handling all multiple-character needle scenarios, but in a way that didn't drastically overcomplicate the script. I.e. to keep it more maintainable, and make it easier to spot any bugs and to avoid introducing new bugs. I was yet to settle on the best (clear yet short) approach.
- I've done a few more changes re. handling multiple-character needles, and improved the comments a bit. Cheers.

Code: Select all

vText := "aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa"
MsgBox, % JEE_StrWrap(vText, 17)
MsgBox, % ";" JEE_StrWrap(vText, 17, " ", "`r`n;")

;==================================================

; ;e.g.
; vText := "aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa"
; MsgBox(JEE_StrWrap(vText, 17))
; MsgBox(";" JEE_StrWrap(vText, 17, " ", "`r`n;"))

;split one line into multiple lines
;vMaxLen: maximum length in characters per line
;vNeedle: can be multiple characters (and is case sensitive)
JEE_StrWrap(vText, vMaxLen, vNeedle:=" ", vSep:="`r`n")
{
	local
	static vIsV1 := InStr(1, 1,, 0)
	vOutput := ""
	VarSetCapacity(vOutput, StrLen(vText)*2*2)
	vLenNeedle := StrLen(vNeedle)
	Loop
	{
		vLen := StrLen(vText)
		if (vLen <= vMaxLen)
			return vOutput vText
		if (vLen <= vMaxLen + vLenNeedle)
			vPos := InStr(vText, vNeedle, 1, -1 + vIsV1)
		else
			;e.g. AHK v2: abcdefghij ;h is position 8 aka -3=-len+8-1=-10+8-1
			;e.g. AHK v1: abcdefghij ;h is position 8 aka -2=-len+8-1=-10+8-1+isv1
			;find first occurrence ending at vMaxLen+vLenNeedle or before: pos=-len+(maxlen+lenneedle)-1+isv1
			;vPos := JEE_InStr(vText, vNeedle, 1, vMaxLen + vLenNeedle - vLen - 1)
			vPos := InStr(vText, vNeedle, 1, vMaxLen + vLenNeedle - vLen - 1 + vIsV1)
		if !vPos
			vPos := InStr(vText, vNeedle, 1, vMaxLen + 1)
		if !vPos
			return vOutput vText
		vOutput .= SubStr(vText, 1, vPos-1) vSep
		vText := SubStr(vText, vPos+vLenNeedle)
	}
}
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Scripts and Functions”

Who is online

Users browsing this forum: Bing [Bot], haichen, joedf, JoeWinograd, robodesign and 32 guests