Re: Newbie3

2008-12-08 Thread Jan Schenkel
--- dunbarx [EMAIL PROTECTED] wrote:
 Feels like old times. When I get to newbie4000 I can
 start helping out around here.
 
 So, fullFind...
 
 What I like about this gadget is its ability to
 return ALL matched instances by line, item or
 character.  It returns chunk-based information about
 the location(s) of a string within a container. Even
 HC's old search XFCN from the power tools stack
 could do that.
 
 I wrote a few workarounds using the lineOffset
 function. They all do the job just fine in their own
 way, and I can implement one of them as a function
 and keep it in a library (a stack in use?). I am
 sure the other offSet functions will come in handy.
 I see there is already a native substitute
 for fullReplace. Well and good.
 
 But  I can write a substitute for fullFind in
 hypertalk, too. The lineOffset function only returns
 the first instance, so additional processing is
 required to get all of them. So, wow me with Rev's
 arsenal. How to do it without a repeat loop? Find
 all ab in:
 
 abc
 def
 abc
 
 I want 1,3 back at me, or somesuch.
 
 Jacqueline, I finally got the filter command to
 work, but this simply extracts data; I lose the
 chunk positional information present in the original
 text. How would one use it to emulate fullFind?
 
 Grudgingly learning to like Revolution. (Sob) My
 belligerent stance derives only from loyalty.
 
 Oh yes, thanks to anyone who takes the trouble...
 
 Craig Newman
 

Hi Craig,

Here's a quick attempt:
##
function MyFindLines theTextToFind, theVariable
  local theLines, theLineNumber
  put 0 into theLineNumber
  repeat for each line theLine in theVariable
add 1 to theLineNumber
if theLine contains theTextToFind then
  put theLineNumber  comma after theLines
end if
  end repeat
  delete char -1 of theLines -- remove trailing comma
  return theLines
end MyFindLines
##

The 'repeat for each' style of loop is extremely fast
- much faster than the old 'repeat with i = 1 to the
number of lines in theVariable' style.

HTH,

Jan Schenkel.

Quartam Reports  PDF Library for Revolution
http://www.quartam.com

=
As we grow older, we grow both wiser and more foolish at the same time.  (La 
Rochefoucauld)


  
___
use-revolution mailing list
use-revolution@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-revolution


Re: Newbie3

2008-12-08 Thread dunbarx
Thanks.

This is the sort of thing I wrote, too. HC code would be similar; I'll take 
your word for the speed.

I was wondering if there was something snazzy in Rev (that was not in HC) that 
did not require running through the whole body of text, in other words, 
directly, like the new replaceText function that is a one-line substitute for 
fullReplace. Very Rinaldi-like.

My initial work in Rev is getting a handle on all my HC XFCN and XCMD stuff. I 
am trying to figure out what exists in Rev that can be used directly for these 
sorts of things. After all, I hear that Rev does not need externals, because 
they basically all exist natively.

On this topic, I like the idea that ancillary windows are implemented as 
stacks. This could have been done in HC also, but not nearly as well, since the 
stack types were limited. I used megaWindow by Dan Gelder just everywhere.

Craig Newman



On Dec 8, 2008, at 10:11:37 AM, Jan Schenkel [EMAIL PROTECTED] wrote:
##
function MyFindLines theTextToFind, theVariable
local theLines, theLineNumber
put 0 into theLineNumber
repeat for each line theLine in theVariable
add 1 to theLineNumber
if theLine contains theTextToFind then
put theLineNumber  comma after theLines
end if
end repeat
delete char -1 of theLines -- remove trailing comma
return theLines
end MyFindLines
##

The 'repeat for each' style of loop is extremely fast
- much faster than the old 'repeat with i = 1 to the
number of lines in theVariable' style.

HTH,

___
use-revolution mailing list
use-revolution@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-revolution


Re: Newbie3

2008-12-08 Thread Mark Wieder
Craig-

Here's a variation using an array:

function MyFindLines pTextToFind, pVariable
  local tArray
  local tLineNumber

  put 0 into tLineNumber
  repeat for each line tLine in pVariable
if pTextToFind is in tLine then
  put tLine into tArray[tLineNumber]
end if
add 1 to tLineNumber
  end repeat
  return tArray
end MyFindLines

-- 
-Mark Wieder
 [EMAIL PROTECTED]

___
use-revolution mailing list
use-revolution@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-revolution


Re: Newbie3

2008-12-08 Thread Richard Gaskin

dunbarx wrote:

 This is the sort of thing I wrote, too. HC code would be similar
 ; I'll take your word for the speed.

 I was wondering if there was something snazzy in Rev (that was not
 in HC) that did not require running through the whole body of text,
 in other words, directly, like the new replaceText function that
 is a one-line substitute for fullReplace. Very Rinaldi-like.

While the algorithms you would use in Rev and HC may appear similar in 
some respects, don't underestimate the power of repeat for each.  This 
form of repeat was not available in HC, and is at least one or two 
orders of magnitude faster than repeat with i = 1 to the number of 
lines


The reason for the incredible speed difference between the two is that 
repeat for each makes the assumption (indeed requires) that the text 
being parsed will not change during the repeat, while repeat with... 
cannot know this in advance.


So when running repeat with i = 1 to the number of lines, each time 
through the loop it needs to count the lines from 1 to i, and then you 
can say get line i and that will once again count from 1 to i to 
obtain the line.  Lots of redundant overhead, but necessary in a form in 
which the text being parsed might be changing in each iteration.


In contrast, repeat for each counts and parses chunks as it goes, 
doing two operations at once (going to the line and parsing it out into 
the iteration variable) and never counting its way through the text 
within a given iteration, since it knows where it left off last time.



To make things even faster, a few years ago Scott Raney optimized the 
put text after othertext operation, with a dramatic speed boost. 
In most xTalks, modifying a chunk means a fair amount of overhead with 
multiple copies of the destination text to accommodate the change.  With 
put...after... the underlying pointer manipulation has been 
significantly optimized specifically for that append operation, so it's 
much faster in Rev than any other xTalk I've seen (and I've worked with 
most of them, including HC, SC, Plus, OMO, Gain Momentum, and ToolBook).


These two constructs, repeat for each... and put...after..., combine 
well for most common parsing tasks, making extraordinarily efficient 
work of slicing through even large blocks of data and combining your 
found results into a new variable.



And then there are arrays, variables with slots for each element which 
can be referenced by the element name.


In HC, multi-part data could be stored in a given variable only by 
carefully minding your chunks, e.g.:


  put tData into line 4000 of tMyVar

This means that you not only need to make sure that tData never contains 
any character you're using to delimit your chunks, but also that 
accessing it will require the overhead of counting chunks to access thte 
one you want:


  get line 4000 of tMyVar

Arrays use an internal hashing scheme so that element names are 
associated with the location of the element's data in a much more 
efficient way.  To store data you just use:


  put tData into tMyVar[4000]

And to get it:

  get tMyVar[4000]

But the real advantage of arrays is that you're not limited to indexing 
them by number; you can use names instead.


For example, if you wanted to store info about a person in a chunk, you 
might use:


  put tName into line 1 of tMyVar
  put tPhone into line 2 of tMyVar
  put tAddress into line 3 of tMyVar

Works well enough - as long as you remember which line has which data. 
So this requires adding comments in your code to remind you later on how 
the data is structured.


With arrays this is much simpler:

  put tName into tMyVar[name]
  put tPhone into tMyVar[phone]
  put tAddress into tMyVar[address]

If you need to display all of the elements of an array, you can combine 
them with the combine command:


  combine tMyVar with return and tab
  put tMyVar into fld 1

You can also convert a list into an array with the split command:

  put fld 1 into tMyVar
  split tMyVar with return and tab


In summary, there's a bit of a learning curve with picking up the most 
efficient ways to do things in Rev.  But it's time well spent, because 
in most cases you'll be free to munge data however you want right in the 
language, liberated from dependencies on externals written in C.


And given the overhead of the XCMD interface, you might even find that 
some of these operations actually run faster in Transcript than in the 
externals you used to use.


--
 Richard Gaskin
 Fourth World
 Revolution training and consulting: http://www.fourthworld.com
 Webzine for Rev developers: http://www.revjournal.com
___
use-revolution mailing list
use-revolution@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-revolution


Re: Newbie3

2008-12-08 Thread dunbarx
Richard:

Thank you.

I get all that, and must admit it sounds impressive. I'll make large piles of 
data and play around with the several forms.

My poor, neglected HC...

Craig Newman


On Dec 8, 2008, at 12:49:06 PM, Richard Gaskin [EMAIL PROTECTED] wrote:
From:   Richard Gaskin [EMAIL PROTECTED]
Subject:Re: Newbie3
Date:   December 8, 2008 12:49:06 PM EST
To: How to use Revolution use-revolution@lists.runrev.com
dunbarx wrote:

 This is the sort of thing I wrote, too. HC code would be similar
 ; I'll take your word for the speed.

 I was wondering if there was something snazzy in Rev (that was not
 in HC) that did not require running through the whole body of text,
 in other words, directly, like the new replaceText function that
 is a one-line substitute for fullReplace. Very Rinaldi-like.

While the algorithms you would use in Rev and HC may appear similar in 
some respects, don't underestimate the power of repeat for each. This 
form of repeat was not available in HC, and is at least one or two 
orders of magnitude faster than repeat with i = 1 to the number of 
lines

The reason for the incredible speed difference between the two is that 
repeat for each makes the assumption (indeed requires) that the text 
being parsed will not change during the repeat, while repeat with... 
cannot know this in advance.

So when running repeat with i = 1 to the number of lines, each time 
through the loop it needs to count the lines from 1 to i, and then you 
can say get line i and that will once again count from 1 to i to 
obtain the line. Lots of redundant overhead, but necessary
...
...
___
use-revolution mailing list
use-revolution@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-revolution


Re: Newbie3

2008-12-08 Thread Mark Wieder
Craig-

...and if you just want to display the multiple occurrences visually

on MyFindLines pTextToFind
  local tVariable

  put the htmltext of field whatever into tVariable
  replace pTextToFind with u  pTextToFind  /u in tVariable
  set the htmltext of field whatever to tVariable
end MyFindLines

-- 
-Mark Wieder
 [EMAIL PROTECTED]

___
use-revolution mailing list
use-revolution@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-revolution


Re: Newbie3

2008-12-08 Thread J. Landman Gay

dunbarx wrote:


The
lineOffset function only returns the first instance, so additional
processing is required to get all of them.


That's why the last parameter is important; it allows you to search for 
an offset starting at a particular location. If you omit the last 
parameter, the search always starts at 1.


So this:

  get lineoffset(var,ab)

will consistently return the first instance in the text variable. You 
need to set up a skip parameter:


  put 0 into skip
  repeat
   put lineoffset(ab,var,skip) into tResult
   if tResult = 0 then exit repeat
   put tResult  comma after tList
   add tResult to skip -- start next search at last found location
  end repeat


So, wow me with Rev's
arsenal. How to do it without a repeat loop? Find all ab in:

abc def abc

I want 1,3 back at me, or somesuch.


You need the repeat loop above, but it is extremely fast. You can 
process many thousands of lines in under a second, usually. The above 
gives you what you want, provided you are looking for the exact string 
match for ab. You could also get chunk info instead:


  put fld 1 into var
  put 0 into skip
  repeat
put lineoffset(ab,var,skip) into tLine
if tLine = 0 then exit repeat
add tLine to skip
get matchChunk(line skip of var,(ab),tMatchStart,tMatchEnd)
put tMatchStart  tMatchEnd  cr after tList
  end repeat

This gives the start and end position of the string you are searching 
for, within the line you are looking at. So if you get 1 3 in the 
match, then the chunk refered to would be char 1 to 3 of line skip of 
fld 1.


If you want a regex search instead of an exact match for ab then you'd 
 set up a filter first and then run a variation of the above repeat on 
the results of your filtered text. Something like this:


  put fld 1 into var
  filter var with a*b*
  repeat for each line tLine in var
get matchChunk(tLine,(a
put tMatchStart  tMatchEnd  cr after tList
  end repeat

Or you could use matchtext instead to extract the exact text.

--
Jacqueline Landman Gay | [EMAIL PROTECTED]
HyperActive Software   | http://www.hyperactivesw.com
___
use-revolution mailing list
use-revolution@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-revolution


Re: Newbie3

2008-12-08 Thread J. Landman Gay

J. Landman Gay wrote:


So this:

  get lineoffset(var,ab)


Oops, I reversed the params. The rest of my examples are correctly 
formatted though. Sorry about that; brain fart.


--
Jacqueline Landman Gay | [EMAIL PROTECTED]
HyperActive Software   | http://www.hyperactivesw.com
___
use-revolution mailing list
use-revolution@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-revolution


Re: Newbie3

2008-12-08 Thread J. Landman Gay
I'm apparently not running on all cylinders today. My copy/paste didn't. 
Here's a corrected version, after which I think I'll bow out gracefully 
for today:


If you want a regex search instead of an exact match for ab then you'd 
 set up a filter first and then run a variation of the above repeat on 
the results of your filtered text. Something like this:


  put fld 1 into var
  filter var with a*b*
  repeat for each line tLine in var
get matchChunk(tLine,(a*b*),tMatchStart,tMatchEnd)
put tMatchStart  tMatchEnd  cr after tList
  end repeat



--
Jacqueline Landman Gay | [EMAIL PROTECTED]
HyperActive Software   | http://www.hyperactivesw.com
___
use-revolution mailing list
use-revolution@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-revolution


Re: Newbie3

2008-12-08 Thread dunbarx
Thanks,

I can live with repeats if they are fast. These are. So be it.


-Original Message-
From: J. Landman Gay [EMAIL PROTECTED]
To: How to use Revolution use-revolution@lists.runrev.com
Sent: Mon, 8 Dec 2008 1:38 pm
Subject: Re: Newbie3


dunbarx wrote:?
?
 The?
 lineOffset function only returns the first instance, so additional?
 processing is required to get all of them.?
?
That's why the last parameter is important; it allows you to search for an 
offset starting at a particular location. If you omit the last parameter, the 
search always starts at 1.?
?
So this:?
?
? get lineoffset(var,ab)?
?
will consistently return the first instance in the text variable. You need to 
set up a skip parameter:?
?
? put 0 into skip?
? repeat?
? put lineoffset(ab,var,skip) into tResult?
? if tResult = 0 then exit repeat?
? put tResult  comma after tList?
? add tResult to skip -- start next search at last found location?
? end repeat?
?
 So, wow me with Rev's?
 arsenal. How to do it without a repeat loop? Find all ab in:?
  abc def abc?
  I want 1,3 back at me, or somesuch.?
?
You need the repeat loop above, but it is extremely fast. You can process many 
thousands of lines in under a second, usually. The above gives you what you 
want, provided you are looking for the exact string match for ab. You could 
also get chunk info instead:?
?
? put fld 1 into var?
? put 0 into skip?
? repeat?
? put lineoffset(ab,var,skip) into tLine?
? if tLine = 0 then exit repeat?
? add tLine to skip?
? get matchChunk(line skip of var,(ab),tMatchStart,tMatchEnd)?
? put tMatchStart  tMatchEnd  cr after tList?
? end repeat?
?
This gives the start and end position of the string you are searching for, 
within the line you are looking at. So if you get 1 3 in the match, then the 
chunk refered to would be char 1 to 3 of line skip of fld 1.?
?
If you want a regex search instead of an exact match for ab then you'd ?set 
up a filter first and then run a variation of the above repeat on the results 
of your filtered text. Something like this:?
?
? put fld 1 into var?
? filter var with a*b*?
? repeat for each line tLine in var?
? get matchChunk(tLine,(a?
? put tMatchStart  tMatchEnd  cr after tList?
? end repeat?
?
Or you could use matchtext instead to extract the exact text.?
?
-- Jacqueline Landman Gay | [EMAIL PROTECTED]
HyperActive Software | http://www.hyperactivesw.com?
___?
use-revolution mailing list?
[EMAIL PROTECTED]
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:?
http://lists.runrev.com/mailman/listinfo/use-revolution?

___
use-revolution mailing list
use-revolution@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-revolution