[comp.sys.mac.hypercard] Searching a stack and creating a list of matching cards...

hovan@bgsuvax.UUCP (John Hovan) (05/05/88)

	Can anyone suggest a way to have hypercard search a stack for a key
word and print a list of all the cards that contain the word in a field?
The discussion on reports seems to be something similar to the script I need,
but can anyone be more specific?  
	Once a list of the key words is found, I would like to be able to 
print the list or click on one of the items in the list to go to that
particular card.  Currently, I have am using the "find" button to search
through the stack for a specific item.  Where is grep when you need it most ??


			Thanks,       


Replies may be sent via email or to the newsgroup.
				
				John Hovan
				Bowling Green State University
				Hardware Support
				hovan@bgsuvax.uucp
				N8JAA


--------------------------------------------------
My RAM is full... put your bits somewhere else!!!

aisl@ur-tut (Larry Landry) (05/05/88)

In article <2051@bgsuvax.UUCP> hovan@bgsuvax.UUCP (John Hovan) writes:
>
>
>	Can anyone suggest a way to have hypercard search a stack for a key
>word and print a list of all the cards that contain the word in a field?

Try this script in a button:

on mouseUp
  push card                            -- save the current card
  ask "Grep for what"                  -- what do you want to grep for?
  put empty into cardList              -- start with no cards in list

  find it                              -- find 1st occurence of text
  put the id of this card into startCard -- save it to test for end of list
  repeat
    put the id of this card & return after cardList  -- add this card to list
    find it                                          -- find the next card
    if the id of this card is startCard then exit repeat -- are we done?
  end repeat

  pop card                                      -- back to original card
  put cardList into card field "grep list"      -- display the list
end mouseUp

This does have one known limitation; if the first card on which the string
is found has more than one occurence of the string, only that card will be
shown.  This may be a major drawback for some applications and no problem
for others.  There may be a simple way around that but I haven't looked too
deeply for one yet.  The code that needs to be changed is the line
   if the id of this card is startCard then exit repeat -- are we done?

>	Once a list of the key words is found, I would like to be able to 
>print the list or click on one of the items in the list to go to that
>particular card.

This has been discussed in previous articles in this newsgroup. You should
be able to obtain a copy from people who have been reading the newsgroup.

Larry Landry
University of Rochester

edmoy@violet.berkeley.edu (05/06/88)

In article <1964@ur-tut.UUCP> aisl@tut.cc.rochester.edu.UUCP (Larry Landry) writes:
>on mouseUp
>  push card                            -- save the current card
>  ask "Grep for what"                  -- what do you want to grep for?
>  put empty into cardList              -- start with no cards in list
>
>  find it                              -- find 1st occurence of text
>  put the id of this card into startCard -- save it to test for end of list
>  repeat
>    put the id of this card & return after cardList  -- add this card to list
>    find it                                          -- find the next card
>    if the id of this card is startCard then exit repeat -- are we done?
>  end repeat
>
>  pop card                                      -- back to original card
>  put cardList into card field "grep list"      -- display the list
>end mouseUp
>
>This does have one known limitation; if the first card on which the string
>is found has more than one occurence of the string, only that card will be
>shown.  This may be a major drawback for some applications and no problem
>for others.  There may be a simple way around that but I haven't looked too
>deeply for one yet.

I've used this technique before and have also come across this problem.
Fortunately, there is an easy fix.  Simply add:

     go next card

just before the "find it" inside the repeat loop.  This even works in the
case of a single card, since the "go next card" will stay on the same card,
and the find will succeed again (assuming the initial find succeeded).

To test for the initial success, add:

  if the result is not empty then
    answer quote & it & quote && "not found."
    exit mouseUp
  end if

after the first find statement.

And to be knit-picky, you should have

  if it is empty then exit mouseUp

after the ask statement, in case they hit the cancel button or don't put in
a search string.

Edward Moy
Workstation Software Support Group
University of California
Berkeley, CA  94720

edmoy@violet.Berkeley.EDU
ucbvax!violet!edmoy

cs2531as@charon.unm.edu (Andrew Stone) (05/06/88)

In a recent article the following Grep script was suggested, I've added the 
few lines which "fix" the known limitation:

>Try this script in a button:

>on mouseUp
>  push card                            -- save the current card
>  ask "Grep for what"                  -- what do you want to grep for?
>  put empty into cardList              -- start with no cards in list
   
   domenu "New Card"
   put it into field whateveryourfieldsareNamed

>  find it                              -- find 1st occurence of text
>  put the id of this card into startCard -- save it to test for end of list
>  repeat
>    put the id of this card & return after cardList  -- add this card to list
>    find it                                          -- find the next card
>    if the id of this card is startCard then exit repeat -- are we done?
>  end repeat

   domenu "Cut Card"  -- cut the dummy card which was the first find
   put empty into line 1 of cardlist -- remove the ocurrence of this find

>
>  pop card                                      -- back to original card
>  put cardList into card field "grep list"      -- display the list
>end mouseUp.


	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	|	Andrew Stone     GEnie:ASTONE      505-345-4800		|
	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         		     cs2531as@charon.unm.edu          
	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	|      	"Science is a fable made consistent" - Edward Teller	|
	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

landman%hanami@Sun.COM (Howard A. Landman) (05/10/88)

In article <1964@ur-tut.UUCP> aisl@tut.cc.rochester.edu.UUCP (Larry Landry) writes:
>This does have one known limitation; if the first card on which the string
>is found has more than one occurence of the string, only that card will be
>shown.  This may be a major drawback for some applications and no problem
>for others.  There may be a simple way around that but I haven't looked too
>deeply for one yet.  The code that needs to be changed is the line
>   if the id of this card is startCard then exit repeat -- are we done?

The middle section of Larry's code:

>  find it                              -- find 1st occurence of text
>  put the id of this card into startCard -- save it to test for end of list
>  repeat
>    put the id of this card & return after cardList  -- add this card to list
>    find it                                          -- find the next card
>    if the id of this card is startCard then exit repeat -- are we done?
>  end repeat

needs to be changed to something like (I haven't tested this):

  find it                              -- find 1st occurence of text
  -- Should have a test here for not finding it!
  put the id of this card into startCard -- save it to test for end of list
  put the id of this card & return after cardList  -- add this card to list
  go next card  -- make sure we don't stop on first card by mistake
  repeat
    find it                                          -- find the next card
    if the id of this card is startCard then exit repeat -- are we done?
    put the id of this card & return after cardList  -- add this card to list
  end repeat

Is this simple enough?

Note that the absence of a test for not finding anything means that there is
another bug, namely that you will always find at least one card even if the
string doesn't exist anywhere.  Fixing this is left as an exercise ...

	Howard A. Landman
	landman@hanami.sun.com
	UUCP: sun!hanami!landman