Page 5 of 7
Re: User Functions Exchange
Posted: 19 Feb 2016 19:36
by totmad1
@Sammay
Thanks had problem with "." so had avoided. From PeterH 's post now know what I had wrong.
The naming convention I have now changed it to, I had avoided because to me REM is still
in my mind a REMark (old BASIC).
Changed check to your suggestion, makes more sense .
minor point took out -1 from $index > $len -1 , it stopped adding $token to end.
@PeterH
Thanks for your explanation , seems to be far more useful.
I shall be making a special note for future reference.
Re: User Functions Exchange
Posted: 19 Feb 2016 22:39
by PeterH
totmad1 wrote:@PeterH
Thanks for your explanation , seems to be far more useful.
Hm - sorry: no. I think, both types are of use. And
the dot is the default method of concatenation!
There are situations where you can't avoid the "dot method" - for example if one token is a function, or if a character or a digit has to be suffixed to a variable, and whatever.
So
*all* situations can be solved with concatenation by dots. But in some situations it can be shorter, and can be more elegant to concatenate inside double quotes.
Re: User Functions Exchange
Posted: 20 Feb 2016 18:51
by Filehero
Edit: release 2.0 - all improvements by Sammay! (thanks )
But: the function comment must stay outside - it's part of the API!
Code: Select all
/* Returns a tab ID for the given location and pane. If such a tab exists
* its idx is returned. Optionally a new tab may be created if not found.
*
* @$location: the location for the tab.
* @$pane: the pane the tab should be located/created in (a/i/1/2)
* @$newtab: whether a new tab is created for missing location (0/1)
*
* @return: the index of the tab, or 0 if not found
*/
function getTabIdx($location=<curpath>, $pane='a', $newtab=0) {
$allTabsInPane = get("Tabs", "|", $pane);
$tabIdx = 1; $needsNewTab = TRUE;
foreach ($path, $allTabsInPane, "|") {
if ($path == trim($location, "\", "R")) {
$needsNewTab = FALSE;
break;
}
$tabIdx++;
}
if ($needsNewTab) {
// store current focus
$actCtrl=(get('FocusedControl')=='L')?('P'.get('pane')):get('FocusedControl');
// focus specified pane
//nothing to do if pane == 'a'
if ($pane == 'i'){focus 'PI';} //magnum!
elseif ($pane == '1'){focus 'P1';}
elseif ($pane == '2'){focus 'P2';}
// create new tab in specified pane
$tabIdx = ($newtab)?tab("new", "$location"):0;
//restore focus
focus $actCtrl;
}
return $tabIdx;
}
Original snippets
Code: Select all
if ($path == trim($location, "\" , [mode="R"]))
-----------------------------------^^^^^^^^^^ // that's a real cool one
Code: Select all
/**
* Returns a tab for the given location and pane. If such a tab already exists it idx
* simply is returned, else it is created prior to.
*
* @$location: the location for the tab (if invalid or missing tab creation will follow XY's default behavior when hitting the <+>-button)
* @$pane: the pane the tab should be located (1|2 = pane 1|2)
*
* @return: the index of the tab
*/
function getTabIdx($location, $pane) {
$allTabsInPane = get("Tabs", "|", $pane);
$tabIdx = 1; $needsNewTab = TRUE;
foreach ($path, $allTabsInPane, "|") {
if ($path == trim($location, "\" , [mode="R"])) {
seltab($tabIdx);
$needsNewTab = FALSE;
break;
}
$tabIdx++;
}
if ($needsNewTab) {
seltab(-1);
$tabIdx = tab("new", "$location");
}
return $tabIdx;
}
[/size]
Re: User Functions Exchange
Posted: 20 Feb 2016 19:00
by Filehero
Edit: fixed error and made checking a bit more forgiving
Code: Select all
/**
* Filters and returns the input list as requested, that is either a file or folder list only.
*
* @$input: input list, separated by $separator
* @$filter: "file" or "folder" are allowed
* @$separator: separator used in input and(!) result list
*
*/
function filterFileitemsList($input, $filter, $separator="<crlf>") {
end($filter UnLikeI "file" && $filter UnLikeI "folder", "Error: Invalid filter string, only 'file' or 'folder' are supported!");
$typeNumber = ($filter == "file") ? 1 : 2;
$result = "";
foreach($item, $input, $separator) {
if (exists($item) == $typeNumber) {
$result = $result.$separator.$item;
}
}
return trim($result, $separator);
}
I mainly use it like
Code: Select all
$selFiles = filterFileitemsList("<selitems <crlf>>", "file");
or
Code: Select all
$selFolders = filterFileitemsList("<selitems <crlf>>", "folder");
Re: User Functions Exchange
Posted: 21 Feb 2016 11:18
by bdeshi
Code: Select all
ERROR: Call to undefined function
SOURCE: FUNCTION filterFileitemsList(), line 11
>return trimListSeparator($result, $separator);
--------^
Re: User Functions Exchange
Posted: 21 Feb 2016 11:42
by Filehero
Darned be my code!
- will fix it later
SammaySarkar wrote:Code: Select all
ERROR: Call to undefined function
SOURCE: FUNCTION filterFileitemsList(), line 11
>return trimListSeparator($result, $separator);
--------^
Re: User Functions Exchange
Posted: 21 Feb 2016 11:53
by highend
Regarding input parameters (like "file" or "folder").
I would design them a bit more forgivingly
At least for those where upper / lower-case doesn't matter.
Either by using LikeI or a regexmatch().
Re: User Functions Exchange
Posted: 22 Feb 2016 09:50
by bdeshi
readline()Code: Select all
readline($file, [$line=1], [$br=<crlf>])
Returns specified line or total line count of a
text file.
$file The source *text* file to read from.
$line integer Line number to read and return. Default is 1.
count Returns total number of lines in $file
$br Line-breaker, case-sensitive. Defaults to <crlf>.
Code: Select all
FUNCTION readline($file, $line=1, $br=<crlf>) {
/* Returns specified line or total line count of a _text_ file.
** $file The source *text* file to read from.
** $line integer Line number to read and return. Default is 1.
** `count` Returns total number of lines in $file.
** $br Line-breaker, case-sensitive. Defaults to <crlf>.
*/
if !($file){return '';}
if gettoken(filetype($file),'Binary|Cannot|Nofile'){return '';}
$return=($line LikeI "count")?0:''; //default return
$size = filesize($file); //length of file
$brLen = strlen($br); //length of linebreaker
/***return line count***/
if ($line LikeI "count") {
if ($size>0){$return++;} //>= 1 line if $file !empty
while ($pos <= $size) {
if !(replace(readfile($file,, $brLen,, $pos),$br)) {
$return++; //found a linebreak so linecount+1
$pos = $pos+$brLen; //jump over found linebreak
} else { $pos++; }
}
return $return;
}
/***return specified line***/
if ($line < 1) {$return '';} //cannot read anti-lines
$lines = 1; //lines found so far. At least 1 (even empty)
$start = 1; $end = 1; //start-end marker of specified line
$pos = 1; //reading position in $file
if ($line == 1) {$start = 1;} //1st line starts at beginning/end
while ($lines < $line) && ($pos <= $size) {
if !(replace(readfile($file,, $brLen,, $pos),$br)) {
$lines++; $pos = $pos + $brLen; //jump over found $br
} else {$pos++;}
}
$start = $pos;
while ($lines < $line+1) && ($pos <= $size) {
if !(replace(readfile($file,, $brLen,, $pos),$br))
|| !(replace(readfile($file,, $brLen,, $pos), '')) {
$lines++; $pos = $pos; //no jumping @ end marker
} else {$pos++;}
}
$end = $pos;
$return = readfile($file, 't', $end-$start,, $start);
return $return;
}
Examples
assuming the function is saved in <xyscripts>\inc\readline.xyi
Code: Select all
INCLUDE "inc\readline.xyi";
"readline test"
readline("<xyscripts>\inc\readline.xyi", 'count'); //56
readline("<xyscripts>\inc\readline.xyi", 34);
Note: This function is fairly slow in that it reads each
byte character in file one by one.
Re: User Functions Exchange
Posted: 22 Feb 2016 10:37
by highend
@Sammay
Isn't this a bit complex (and way too much time consuming)?
Overly simplified versions (because for count you'd need to check if there is a following line after the last linebreak)
\r?\n already catches all normal linebreak versions (Linux, Mac, Windows)
Code: Select all
return gettoken(regexmatches(readfile($file), "\r?\n"), "count", "|");
A combination with a regexmatch would be necessary to generalize it a bit further for the linebreak char but over all:
Code: Select all
return gettoken(readfile($file), $line, "<crlf>");
regexmatches + gettoken() = nearly instant even on larger files
Re: User Functions Exchange
Posted: 22 Feb 2016 10:58
by bdeshi
Yeah. This was more like an exercise in long-winded scripting.
I wanted to read parts of a file without reading in *all* of it. This is way too slow anyway, but can be considerably sped up by reading in small chunks.
Re: User Functions Exchange
Posted: 22 Feb 2016 16:01
by TheQwerty
Filehero wrote:I mainly use it like
Code: Select all
$selFiles = filterFileitemsList("<selitems <crlf>>", "file");
or
Code: Select all
$selFolders = filterFileitemsList("<selitems <crlf>>", "folder");
Code: Select all
$selFiles = Report("{Dir |{Fullname}|}<crlf>", 1);
$selFolders = Report("{Dir {Fullname}||}<crlf>", 1);
The only problem with this approach is there's a trailing <crlf>, but that can easily be handled using FormatList to remove empties or SubStr($list, 0, -2).
Re: User Functions Exchange
Posted: 22 Feb 2016 18:53
by Filehero
TheQwerty wrote:The only problem with this approach is there's a trailing <crlf>, but that can easily be handled using FormatList to remove empties or SubStr($list, 0, -2).
Why is it a "problem"? In my given example that's intentional because the entire downstream processing is line based.
Re: User Functions Exchange
Posted: 22 Feb 2016 19:04
by TheQwerty
Filehero wrote:TheQwerty wrote:The only problem with this approach is there's a trailing <crlf>, but that can easily be handled using FormatList to remove empties or SubStr($list, 0, -2).
Why is it a "problem"? In my given example that's intentional because the entire downstream processing is line based.
It wasn't in reference to your original functions or examples.
I was only pointing out that my alternatives using
Report leave the trailing separator/empty item.
How/when/if I handle this later largely depends on what I'm doing with the lists next.
Re: User Functions Exchange
Posted: 22 Feb 2016 19:12
by Filehero
Uff, I thought you've spotted another error. Cool, all good then.
TheQwerty wrote:I was only pointing out that my alternatives using Report leave the trailing separator/empty item.
How/when/if I handle this later largely depends on what I'm doing with the lists next.
Re: User Functions Exchange
Posted: 23 Feb 2016 15:41
by bdeshi
dlbtn() Don foresaw this!
Downloads and adds a CTB from a snippet URL.
Not just that -- this adds buttons with <BLINK>special effect</BLINK> too! Whoa!
$url The snippet URL. The content should be a valid CTB snippet, and only that.
$pos New CTB's position on toolbar. Negative numbers count from toolbar's right end. Default is -1 (add as last button).
$utf 1: read URL content in utf8, 0: readurl() default. (Because readurlutf8 is there!)
Returns added CTB's ctbindex, else 0 in case of failure.
Code: Select all
FUNCTION dlbtn($url, $pos=-1, $utf=0){
/*creats a new ctb from snippet at $url
** $url snippet source.
** $pos position on toolbar. Default -1 == last.
** $utf read url content in utf8. Default 0 == no.
**Returns added ctbindex, or 0 for failure
*/
$return = 0;
$snippet = ($utf==1)?readurlutf8($url):readurl($url);
//basic test for valid ctb. Extensive checks not done
if (regexmatches($snippet, '^[\s\t]*Snip\:\sCTB\s\d+')) {
$tb = toolbar(); //store current toolbar
snippet $snippet; //apply snippet
if (toolbar() == $tb) {return 0;} //nothing added
//ctbs by default added to end of toolbar
//get last element of toolbar for return
$return = gettoken(toolbar(), -1, ',');
//put new ctb at specified $pos
if ($pos!=-1) {
//count toolbar buttons
$btn_cnt = gettoken($tb, 'count', ',');
//normalize $pos
if ($pos < 0){$pos = $btn_cnt+$pos+1;} //absolute position
if ($pos == 0){$pos = 1;}
if ($pos > $btn_cnt){$pos = $btn_cnt;}
$tb_pre = gettoken($tb, $pos-1, ',',, 1); //before $pos
$tb_post = gettoken($tb, $pos, ',',, 2); //after $pos
$tb = toolbar(trim("$tb_pre,$return,$tb_post", ','));
}
$return = replace($return, 'ctb'); //get ctbindex
//bling-bling :) | 0<t<1 sec delayed return of control :(
$k=7;while($k>=0){ctbstate($k%2,$return);wait 100;$k--}
}
return $return;
}
Examples
assuming the function is saved in <xyscripts>\inc\dlbtn.xyi
Code: Select all
INCLUDE 'inc\dlbtn.xyi'
"dlbtn() test"
status dlbtn('http://pastebin.com/raw/PMwL8NNt', 1); //adds ctb at the start of toolbar
Or "
paste something like this into the Address Bar and press ENTER. ... Woosh. Slick user experience..."
Code: Select all
::load "INCLUDE 'inc\dlbtn.xyi';<crlf>dlbtn('http://pastebin.com/raw/PMwL8NNt');" ,,'s';