|
Joined: Jul 2006
Posts: 4,145
Hoopy frood
|
OP
Hoopy frood
Joined: Jul 2006
Posts: 4,145 |
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 is 6.Added $width() and $height() sixth $true/$false parameter to enable custom window-specific measurement. But $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. 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
}
}
#mircscripting @ irc.swiftirc.net == the best mIRC help channel
|
|
|
|
Joined: Jul 2006
Posts: 4,145
Hoopy frood
|
OP
Hoopy frood
Joined: Jul 2006
Posts: 4,145 |
I'm not sure if the parameter C = 1 in future wrap call should imply that control code must be preserve on wrapped line or if a new switch should be used, but it makes sense that if you interpret control code, you want them on wrapped lines. Note that there is a $wrap2 made specifically to retain control code on $wrap here: http://hawkee.com/snippet/17956/I also made my custom wrap support control codes via a .color property, it uses the $controlat and $colorat identifiers which were suggested here, so it's not the most efficient, but it's merely there to show how to do it. 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
; var -s %w $width($1,$2,$3,$5,$6,$7)
if ($width($1,$2,$3,$5,$6,$7) <= $4) {
if ($8 == 0) return 1
if ($8 == 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 $controlat($1,%index) $+ $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
if ($prop == color) var %ctrlat $controlat($1,1)
;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 %ctrlat $+ $mid(%wt,1,%temp)
}
;we just split, so we reset the buffer
var %r
;if .color prop is used, get the control at the current position, which is the start of the future buffer.
if ($prop == color) %ctrlat = $controlat($1,%index)
}
;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 %ctrlat $+ %wt
}
}
alias colorat {
if ($prop == set) {
if ($1 != $chr(15)) {
var %i $iif($2,$2,$gettok(%colorat,2,44))
%colorat = $1 $+ $iif($1,$iif(%i,$chr(44) $+ %i))
}
else %colorat =
}
else {
set -u %colorat
var %r /(?:\x03(?:(\d+)(?:,(\d+))?)?|(\x0F))/g,%r $regsubex($left($1,$2),%r,$colorat(\1,\2).set)
%r = %colorat
unset %colorat
return $iif(%r != $null,$chr(3) $+ %r)
}
}
alias controlat {
if ($prop == set) {
if ($1 != $chr(15)) {
if ($1 isin %controlat) %controlat = $remove(%controlat,$1)
else %controlat = %controlat $+ $1
}
else %controlat =
}
else {
set -u %controlat
var %c $iif($3,$3,kubir),%r $+(/,$chr(40),$left($regsubex($remove(%c,k),/(.)/g,\x $+ $base($replace(\1,u,31,b,2,i,29,r,22),10,16,2) $+ |),-1),|\x0F,$chr(41),/g),%r $regsubex($left($1,$2),%r,$controlat(\1).set)
%r = %controlat
unset %controlat
return %r $+ $iif(k isin %c,$colorat($1,$2))
}
}
#mircscripting @ irc.swiftirc.net == the best mIRC help channel
|
|
|
|
|