[comp.sys.mac.hypercard] HC find quirks

shawn@e40-008-11.bloom-beacon (Shawn O'Donnell) (09/15/90)

I haven't been able to determine how HyperCard knows whether to find a 
string of text on the same card or on later cards.

In my database, I have a hierarchical table of contents like this:
    HEADING 1
        Subheading  1.a
        Subheading  1.b...
    HEADING 2
	    Subheading  2.a... 
          etc.
When people click on a line in the table of contents, the program takes 
them to the appropriate card.  Suppose someone clicks on Subheading 2.a.  
I have Hypercard find HEADING 2 in the heading field, and then find 
Subheading 2.a in the subheading in the subheading field.  

This works fine so long as 
    (a) The Subheading you are looking for is not the first one under that 
        heading, 
and
    (b) the same subheading does not appear under any other headings

The 'Find "Heading 2" in background field Heading' command works, but the 
'Find "Subheading 2.a" in background field Subheading' command jumps ahead 
to a "Subheading 2.a" card under another Heading.  Why isn't it beginning 
it's search on the present card like I thought it was supposed to?  

Thanks

Shawn O'Donnell
shawn@athena.mit.edu

chh9@quads.uchicago.edu (Conrad Halton Halling) (09/15/90)

In article <1990Sep14.223831.17977@athena.mit.edu> 
        shawn@athena.mit.edu (Shawn O'Donnell) writes:
>I haven't been able to determine how HyperCard knows whether to find a 
>string of text on the same card or on later cards.
>

In my experience, I have found that the find command searches the fields
in field order (that is, field number 1 is searched before field number 2).
Probably, the first field you look for has a higher number than the second
field you look for.  (I'm not talking about the ID number, I'm talking
about the "field number" as given in the "field info..." dialog box.)

This may mean that after you do your find and get a hit in the first field
(with the higher field number), the next search won't continue on the same
card but will go to the next card before the field you limited your search
to is examined.  (Oh, boy!  That isn't very clear.  Anyway, try my suggestion
below to see if it works, and let me know if it does.)

To decrease the number of a field, choose the field tool,
click on the appropriate field, then type command-hyphen.  To increase the
number of a field, type command-equals.  I would just keep doing this
until the first field you want to search has become field number 1.

--
Conrad Halling
chh9@midway.uchicago.edu

shawn@e40-008-11.athena (Shawn O'Donnell) (09/17/90)

When I read Conrad's suggestion concering my Hypercard find problems, I 
thought he had the answer--my fields were numbered such that the first 
search (find the right HEADING) took me to a field with a higher number
than that for the second field (find the right Subheading,) and so 
HyperCard went to the next card before it began its search.  

I quickly gave his suggestion a try.  I was sad to find that I had my 
fields numbered in the order that _should_ work.  

I tried the two searches manually, and they worked properly.  In the 
script, though, they don't work.  I don't think I'm doing anything 
between the two find commands that should disturb the process...
Here are a few lines from the script:

    repeat [until you find a subject line]
        ...
        if (char 1 of theSubject <> space) then
->        find theSubject in bg fld Subject
          exit repeat
        else
          (look a line earlier for the SUBJECT line)
        end if...
    end repeat
    
    --   First, we get the contents of the line, from after the last space
    --   to the first period of the leader;

    put offset (".",theTopicLineText) into length
    put char 3 to (length-1) of theTopicLineText into theTopic
    
    --   then we find the first card with it in the topic field.
    
->  find theTopic in bg fld Topic

I can get it to work by throwing in a "go previous card/go next card" pair,
but that clutters up the recent card list.  

What gives?  

Shawn O'Donnell
shawn@athena.mit.edu

chh9@quads.uchicago.edu (Conrad Halton Halling) (09/18/90)

In article <1990Sep17.134816.4589@athena.mit.edu>
shawn@e40-008-11.athena [signed:  shawn@athena.mit.edu]
(Shawn O'Donnell) writes:

>[stuff deleted]
>I tried the two searches manually, and they worked properly.  In the 
>script, though, they don't work.  I don't think I'm doing anything 
>between the two find commands that should disturb the process...
>[stuff deleted]

After much experimentation, I have found the answer to Shawn's problem:

*** Have the script click at some safe location (such as 0, 0) after ***
*** the first find command.  This resets some internal marker in     ***
*** HyperCard (what, I don't know, but it works!).  The next find in ***
*** a different field will begin on the same card.                   ***

Lengthy details follow:

When the two searches are done manually, as soon as you begin typing in
the message box, you'll notice that the box around the text from the
first find disappears; the result is that you have reset the find command
simply by typing into the text box. 

Here is how I set up my experimental stack:

Background "Index" contains a single card which contains 
bg fld "index" with the following contents:

Subject_1
  Topic_1
  Topic_2
  Topic_3
Subject_2
  Topic_1
  Topic_2
  Topic_3
Subject_3
  Topic_1
Subject_4
  Topic_1
  Topic_2
  
Background "ItemCards" contains as many cards as you like, with
bg fld "subject" and bg fld "topic".
     put "Subject_1" into fld "subject" of cd 1 of bg "itemCards"
     put "Topic_1" into fld "topic" of cd 1 of bg "itemCards"
     put "Topic_2" into fld "topic" of cd 2 of bg "itemCards"
          [if the cards are in order, the subject field can remain empty.]
     etc.

Lock the text of fld "index" of bg "index" and place the following
handler into the script of fld "index":

on mouseUp
  -- put the selectedLine into variable lineSelection and highlight
  -- the selectedLine for visual feedback
  set cursor to watch
  lock screen
  get the clickLoc
  set lockText of field "Index" to false
  click at it
  put the selectedLine into lineSelection
  set the lockText of field "index" to true
  unlock screen
  select lineSelection
  
  -- hide results of find commands and card movements
  lock screen
  
  -- put the contents of the selectedLine into variable lineText
  -- the "do" command is necessary here; otherwise lineText will
  -- contain the text in lineSelection ("line X of bkgnd fld 1").
  do "put " & lineSelection & " into lineText"
  
  -- find the subject and topic; topics begin with space & space
  put empty into subjectText
  put empty into topicText
  if char 1 of lineText is space then
    put lineSelection into tempSelection
    repeat until subjectText is not empty
      -- back up one line
      put ((word 2 of tempSelection) - 1) into word 2 of tempSelection
      do "put " & tempSelection & " into tempText"
      if char 1 of tempText <> space then
        put tempText into subjectText
        put lineText into topicText
      end if
    end repeat
  else
    put lineText into subjectText
  end if
  
  -- find the first card with the subject
  -- You have to go to the first card of bg "itemCards" before
  -- performing the find; if you don't, even though you have requested 
  -- 'bg fld "subject"', for some reason this gets translated by HyperCard
  -- into "bkgnd fld 1", and HyperCard simply finds the subject in 
  -- fld "index" of bg "index" (which is "bkgnd fld 1").
  go to card 1 of bg "ItemCards"
  find subjectText in fld "subject"

  -- click at a safe location where there is no button or field that
  -- will respond to a mouseDown or mouseUp; this resets the find
  -- command so it will begin the next search with the current card
  click at 0, 0
  
  -- find the first card with the topic
  if topicText is not empty then
    find topicText in fld "topic"
    click at 0,0
  end if
  
  unlock screen
  
end mouseUp


This script has been tested, and I know it works.  Many odd things
about the behavior of HyperCard turned up during my experimentation;
these are described in the comments of the script.

Since I don't have a definitive description of HyperCard, my approach
to writing scripts is to experiment until I find what works.  Everytime
I try something, I learn something new.

I saved my stack; if you, Shawn (or anyone else), want it, e-mail a request
BY FRIDAY (after which I will discard the stack) and I will send you a
binHexed Stuffit archive by e-mail.

--
Conrad Halling
chh9@midway.uchicago.edu