Re: Newbie3
--- 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
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
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
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
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
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
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
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
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
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