$wrap improvement - 25/04/20 03:22 AM
As discussed in this thread, $wrap needs to support the new $width parameter.
In fact, $wrap does not support the current B and C $width's parameter, which is also a problem to correctly calculate a width.
Also, in the beta change log, there isBut $height is only documented with 3 parameters currently, would be nice to update the help file regarding $height.
It looks like the word parameter could be extended:
However I'm not too sure how you would pass the B C D parameter of $width inside that word parameter, bNcNdN where N are numbers?
So with an alternative mode 'a' and 'w' for word wrap, the parameter word would be like $wrap(text,font,size,maxwidth,awb0c0d0,N) for 'default' value of B C D, but maybe simple allow 'aw' with default value for B C D
I'd add a 't' switch to change the code point value at which the word wrap occurs: $wrap(text,font,size,maxwidth,awt160,N)
Below is an update of the custom wrap alias, I commented it fully in case that can help.
It uses regex for word wrapping and always wrap on space, but it will also wrap on the character passed as $10 as well, it won't wrap only at the character you passed, but this can easily be modified by removing \x20 everywhere when $10 is passed.
In fact, $wrap does not support the current B and C $width's parameter, which is also a problem to correctly calculate a width.
Also, in the beta change log, there is
Quote
6.Added $width() and $height() sixth $true/$false parameter to enable custom window-specific measurement.
It looks like the word parameter could be extended:
However I'm not too sure how you would pass the B C D parameter of $width inside that word parameter, bNcNdN where N are numbers?
So with an alternative mode 'a' and 'w' for word wrap, the parameter word would be like $wrap(text,font,size,maxwidth,awb0c0d0,N) for 'default' value of B C D, but maybe simple allow 'aw' with default value for B C D
I'd add a 't' switch to change the code point value at which the word wrap occurs: $wrap(text,font,size,maxwidth,awt160,N)
Below is an update of the custom wrap alias, I commented it fully in case that can help.
It uses regex for word wrapping and always wrap on space, but it will also wrap on the character passed as $10 as well, it won't wrap only at the character you passed, but this can easily be modified by removing \x20 everywhere when $10 is passed.
Code
alias wrap2 { ;$1 = text $2 = font $3 = size, $4 = maxwidth, $5 = $width's B $6 = $width's C $7 = $width's D $8 = N $9 = wordwrap $10 = optional C ;when word wrapping and the words are too big to fit, it tries to split the words ;whenever maxwidth is too small to fit the smallest character, return 0 for N = 0 and $null for N > 0 if ($1 == $null) || ($2 == $null) || ($3 == $null) || ($4 == $null) || ($8 == $null) { echo -s * $!wrap2: insufficient params | return } ;if the width of text fits maxwidth, we can return immediately if ($width($1,$2,$3,$5,$6,$7) <= $4) { if ($8 == 0) return 1 return $1 } ;if no word wrap if (!$9) { var %index 1,%n 0,%seek,%len $len($1),%len1 ;as long as there are character left to process, left from right while (%index <= %len) { %seek = 1 %len1 = $calc(%len - %index + 1) ;as long as the width of the current text is smaller or equal to maxwidth, we get more characters while (%seek <= %len1) && ($width($mid($1,%index,%seek),$2,$3,$5,$6,$7) <= $4) inc %seek dec %seek ;if %seek is 0, the character at %index doesn't fit into maxwidth, it's an error if (%seek == 0) { if ($8 == 0) return 0 return } ;otherwise we increment the line number inc %n ;if the N parameter equals the line number, we save the data to a temp variable because we still have to process the rest of the character: it's possible that later chunk won't fit maxwidth (fseek = 0 above) and it should report an error then if (%n == $8) var -p %item $mid($1,%index,%seek) ;increment the index %index = %index + %seek } ;if no error, we reach this point, if %item is there, return it if (%item != $null) returnex %item ;otherwise if N is 0, return the number of wrapped lines if ($8 == 0) return %n } else { ;word wrap, delimiters are always trimmed from result when N > 0 ;prepare regex pattern, trim consecutives delimiters (either space or $chr($10)) var %n 0,%rp $iif($chr($10) isin \[]-,\ $+ $v1,$v1),%p /(*UTF8)([^\x20 $+ %rp $+ ]+)([\x20 $+ %rp $+ ]+|$)/,%re $regex(wrap2,$1,/(*UTF8)^([\x20 $+ %rp $+ ]+)/),%index $len($regml(wrap2,1)) + 1,%temp ;as long as they are regex match which find the next 'token' separated by space/$chr($10) ;build a buffer of tokens with their delimiter while ($regex(wrap2,$mid($1,%index),%p)) { ;$regml(1) = token ;$regml(2) = consecutives delimiter, at least one char ;if the width of what's currently in the buffer + the current token without its delimiters, is greater than maxwidth, we split var -p %wt %r $+ $regml(wrap2,1) if ($width(%wt,$2,$3,$5,$6,$7) > $4) { inc %n ;%r is the full buffer, if %r is $null, it means we needs to split but there are no token to report, because the maxwidth is too small to contain the smallest token if (%r == $null) { ;in this case, we do it smart like $wrap, and we try to split the token itself (%wt), this finds the biggest width which fits, for that token var %len $len(%wt) while (%len) && ($width($left(%wt,%len),$2,$3,$5,$6,$7) > $4) dec %len ;if %len is 0, it means that the smallest portion of the token, the first character, does not fit into maxwidth, we report an error if (%len == 0) { if ($8 == 0) return 0 return } ;otherwise we modify %temp, which hold the number of character we get for that chunk (%wt) %temp = %len ;we increment the index accordingly so that the next token start from the end of that current token inc %index %len } ;if the N parameter equals the line number, we save the data to a temp variable because we still have to process the rest of the character: it's possible that later chunk won't fit maxwidth (fseek = 0 above) and it should report an error then if (%n == $8) var -p %item $mid(%wt,1,%temp) ;we just split, so we reset the buffer var %r } ;otherwise we keep adding the token to a buffer and we store (%temp) the number of character the current chunk contains (to account for consecutive delimiters), which will be used for the split else { var -p %r %r $+ $regml(wrap2,1) $+ $regml(wrap2,2) inc %index $len($regml(wrap2,1) $+ $regml(wrap2,2)) %temp = $len(%r) - $len($regml(wrap2,2)) } } inc %n ;if no error, we reach this point, if %item is there, return it if (%item) returnex %item ;otherwise if N is 0, return the number of wrapped lines if ($8 == 0) return %n ;if maxwidth is greater than what's left of the input after a wrap occured, the main loop above will stop without setting %item, we return what's left. if (%n == $8) returnex %wt } }