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 » 19 Feb 2016 19:36

@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: 2575
Joined: 21 Nov 2005 20:39
Location: Germany

Re: User Functions Exchange

Post by PeterH » 19 Feb 2016 22:39

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.
W7(x64) SP1 German
( +WXP SP3 )

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

Re: User Functions Exchange

Post by Filehero » 20 Feb 2016 18:51

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: 2283
Joined: 27 Feb 2012 18:50
Location: Windows 10 Pro x64

Re: User Functions Exchange

Post by Filehero » 20 Feb 2016 19:00

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.

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

Re: User Functions Exchange

Post by SammaySarkar » 21 Feb 2016 11:18

Code: Select all

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

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

Re: User Functions Exchange

Post by Filehero » 21 Feb 2016 11:42

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: 8152
Joined: 06 Feb 2011 00:33

Re: User Functions Exchange

Post by highend » 21 Feb 2016 11:53

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 or highend (at) web (dot) de

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

Re: User Functions Exchange

Post by SammaySarkar » 22 Feb 2016 09:50

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.

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

Re: User Functions Exchange

Post by highend » 22 Feb 2016 10:37

@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 or highend (at) web (dot) de

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

Re: User Functions Exchange

Post by SammaySarkar » 22 Feb 2016 10:58

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.

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

Re: User Functions Exchange

Post by TheQwerty » 22 Feb 2016 16:01

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: 2283
Joined: 27 Feb 2012 18:50
Location: Windows 10 Pro x64

Re: User Functions Exchange

Post by Filehero » 22 Feb 2016 18:53

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: 4353
Joined: 03 Aug 2007 22:30

Re: User Functions Exchange

Post by TheQwerty » 22 Feb 2016 19:04

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: 2283
Joined: 27 Feb 2012 18:50
Location: Windows 10 Pro x64

Re: User Functions Exchange

Post by Filehero » 22 Feb 2016 19:12

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.

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

Re: User Functions Exchange

Post by SammaySarkar » 23 Feb 2016 15:41

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';

Post Reply