User Functions Exchange

Discuss and share scripts and script files...
totmad1
Posts: 131
Joined: 24 Jun 2013 12:37

Re: User Functions Exchange

Post 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.
totmad1 (totally mad one)

PeterH
Posts: 2785
Joined: 21 Nov 2005 20:39
Location: Germany

Re: User Functions Exchange

Post 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.
Win11 Pro 223H2 Gerrman

Filehero
Posts: 2644
Joined: 27 Feb 2012 18:50
Location: Windows 10 Pro x64

Re: User Functions Exchange

Post by Filehero »

Edit: release 2.0 - all improvements by Sammay! (thanks :D)
But: the function comment must stay outside - it's part of the API! :lol:


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
:lol:

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]
Last edited by Filehero on 21 Feb 2016 11:50, edited 2 times in total.

Filehero
Posts: 2644
Joined: 27 Feb 2012 18:50
Location: Windows 10 Pro x64

Re: User Functions Exchange

Post 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");
Last edited by Filehero on 21 Feb 2016 12:06, edited 2 times in total.

bdeshi
Posts: 4249
Joined: 12 Mar 2014 17:27
Location: Asteroid B-612 / Dhaka
Contact:

Re: User Functions Exchange

Post by bdeshi »

Code: Select all

ERROR:  Call to undefined function
SOURCE: FUNCTION filterFileitemsList(), line 11
>return trimListSeparator($result, $separator);
--------^
Icon Names | Onyx | Undocumented Commands | xypcre
[ this user is asleep ]

Filehero
Posts: 2644
Joined: 27 Feb 2012 18:50
Location: Windows 10 Pro x64

Re: User Functions Exchange

Post by Filehero »

Darned be my code! :mrgreen: - will fix it later
SammaySarkar wrote:

Code: Select all

ERROR: Call to undefined function
SOURCE: FUNCTION filterFileitemsList(), line 11
>return trimListSeparator($result, $separator);
--------^

highend
Posts: 13309
Joined: 06 Feb 2011 00:33

Re: User Functions Exchange

Post by highend »

Regarding input parameters (like "file" or "folder").

I would design them a bit more forgivingly :biggrin:

At least for those where upper / lower-case doesn't matter.

Either by using LikeI or a regexmatch().
One of my scripts helped you out? Please donate via Paypal

bdeshi
Posts: 4249
Joined: 12 Mar 2014 17:27
Location: Asteroid B-612 / Dhaka
Contact:

Re: User Functions Exchange

Post 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.
Icon Names | Onyx | Undocumented Commands | xypcre
[ this user is asleep ]

highend
Posts: 13309
Joined: 06 Feb 2011 00:33

Re: User Functions Exchange

Post 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
One of my scripts helped you out? Please donate via Paypal

bdeshi
Posts: 4249
Joined: 12 Mar 2014 17:27
Location: Asteroid B-612 / Dhaka
Contact:

Re: User Functions Exchange

Post by bdeshi »

Yeah. This was more like an exercise in long-winded scripting. :kidding:
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.
Icon Names | Onyx | Undocumented Commands | xypcre
[ this user is asleep ]

TheQwerty
Posts: 4373
Joined: 03 Aug 2007 22:30

Re: User Functions Exchange

Post 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).
:wink:

Filehero
Posts: 2644
Joined: 27 Feb 2012 18:50
Location: Windows 10 Pro x64

Re: User Functions Exchange

Post 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).
:wink:
Why is it a "problem"? In my given example that's intentional because the entire downstream processing is line based.

TheQwerty
Posts: 4373
Joined: 03 Aug 2007 22:30

Re: User Functions Exchange

Post 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).
:wink:
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.

Filehero
Posts: 2644
Joined: 27 Feb 2012 18:50
Location: Windows 10 Pro x64

Re: User Functions Exchange

Post by Filehero »

Uff, I thought you've spotted another error. Cool, all good then. :D
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.

bdeshi
Posts: 4249
Joined: 12 Mar 2014 17:27
Location: Asteroid B-612 / Dhaka
Contact:

Re: User Functions Exchange

Post by bdeshi »

dlbtn()          Don foresaw this! :wink:

Code: Select all

dlbtn($url, [$pos=-1], [$utf=0])
Downloads and adds a CTB from a snippet URL.
Not just that -- this adds buttons with <BLINK>special effect</BLINK> too! Whoa!  :ugeek: 

$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';
Icon Names | Onyx | Undocumented Commands | xypcre
[ this user is asleep ]

Post Reply