Page 1 of 2

LineOffset change the desired word to new colour

Posted: Mon Aug 24, 2009 2:38 pm
by hamlynart
Hi Folks,

I'd like to be able to scan the text across multiple fields and colour specific words. So far I've managed to change the line colour but not individual words:

Code: Select all

   repeat with x=1 to the number of fields in this stack
      repeat with j=1 to the number of lines in fld x
         if the line lineOffset("Urgent", (fld x)) of fld x = "Urgent need to change colour" then
            set the foregroundColor of the word lineOffset("Urgent", (fld x)) of fld x to red
         end if
      end repeat
   end repeat
Any thoughts?

Thanks in advance

Jim H

Posted: Mon Aug 24, 2009 3:03 pm
by hamlynart
Sorry,

I thought I'd run out of possibilities but then I discovered "wordOffset" - lovely!!!

Code: Select all

   repeat with x=1 to the number of fields in this stack
      repeat with j=1 to the number of lines in fld x
         if the word wordOffset("brief", (fld x)) of fld x = "brief" then
            beep
            set the foregroundColor of the word wordOffset("brief", (fld x)) of fld x to red
         end if
      end repeat
   end repeat
I'm not sure if this is a very elegant way of doing it but it works!

Best

Jim H

LineOffset change the desired word to new colour

Posted: Mon Aug 24, 2009 4:45 pm
by jmburnod
Hi Jim,

be careful about the number of fields in this stack

the number of fields in this stack return the number of fields of this card

Best

Jean-Marc

Posted: Mon Aug 24, 2009 4:51 pm
by Mark
Dear Jim,

What about this?

Code: Select all

put "brief%255,0,0" & cr & "urgent%0,255,0" into myColorArray
split myColorArray by "%" and cr
repeat with x = 1 to number of fields
  put 0 into myCounter
  repeat for each word myWord in fld x
    add 1 to myCounter
    if myWord is among the items of "brief,urgent" then
      set the textColor of word myCounter of fld x to myColorArray[myWord]
    end if
  end repeat
end repeat
(untested, please mind typos)

Best,

Mark

Posted: Mon Aug 24, 2009 6:53 pm
by bn
Jim,

there is a typo in Mark's script

Code: Select all

on mouseUp
   put "brief%255,0,0" & cr & "urgent%0,255,0" into myColorArray 
   split myColorArray by cr and "%" 
   
   -- alternatively you could write
   --  put "255,0,0" into myColorArray["brief"]
   --  put "0,255,0" into myColorArray["urgent"]
   
   -- or you could put a color name into the array
   --  like: put "blue" into myColorArray["urgent"]
   
   repeat with x = 1 to number of fields 
      put 0 into myCounter 
      repeat for each word myWord in fld x 
         add 1 to myCounter 
         if myWord is among the items of "brief,urgent" then 
            set the textColor of word myCounter of fld x to myColorArray[myWord]
         end if 
      end repeat 
   end repeat
end mouseUp
The beauty of Mark's script is that you can easily add words you want to color. And with the "for each word" construct it is fast.
regards
Bernd

Posted: Mon Aug 24, 2009 6:58 pm
by SparkOut
That's very nice Mark, there is a typo though. Swap the split divisors so:

Code: Select all

put "brief%255,0,0" & cr & "urgent%0,255,0" into myColorArray 
   split myColorArray by cr and "%"
   repeat with x = 1 to number of fields 
      put 0 into myCounter 
      repeat for each word myWord in fld x 
         add 1 to myCounter 
         if myWord is among the keys of myColorArray then 
            set the foreColor of word myCounter of fld x to myColorArray[myWord] 
         end if 
      end repeat 
   end repeat
Also, may I respectfully suggest that you test for myWord being "among the keys of myColorArray" so as to prevent having to maintain that word list, as above. Just set the words and colours in the array itself.

Posted: Mon Aug 24, 2009 7:30 pm
by Mark
Hi all,

Please refer to the disclaimer ;-)

Checking the keys instead of a list of items is a good alternative when the list of items gets longer. Thanks for the suggestion Sparkout.

Mark

Posted: Mon Aug 24, 2009 7:44 pm
by hamlynart
Mark and SparkOut - that's brilliant!

I've never used arrays before so I was struggling with Mark's code. I'd managed to get the keys read out and had realised that something was amiss. I was getting the following in the message window:
brief
0,255,0
255,0,0
I couldn't understand why "brief" was at the top of the list and the other 2 were reversed. I was just considering switching the split terms when I checked the forum again and saw SparkOut's solution.

Thanks to you both for the challenge and the lesson - Arrays fantastic!

Jim H

Posted: Mon Aug 24, 2009 7:56 pm
by bn
Jim,

arrays are very powerful once you get the idea, and they are not that hard to figure out.
here is an old-fashioned version to solve your problem

Code: Select all

on mouseUp
   put "brief,urgent" into tWords -- add words here
   put "blue,red" into tColors  -- add colors here
   
   repeat with i = 1 to the number of fields of this card
      put field i of this card into tText
      
      repeat with k = 1 to the number of items of  tWords
         put 0 into tWordsToSkip
         put empty into tFoundOne
         
         repeat
            put wordOffset(item k of tWords,tText, tWordsToSkip) into tFoundOne
            if tFoundOne = 0 then exit repeat
            add tFoundOne to twordsToSkip
            set the foregroundcolor of word tWordsToSkip of field i to item k of tColors
         end repeat
      end repeat
   end repeat
end mouseUp
it is also fast and expandable, when coloring many words arrays may be faster.
regards
Bernd

Posted: Mon Aug 24, 2009 8:54 pm
by hamlynart
Hi again,

You know how it is - once you learn something it starts you thinking about other possibilities:
Currently I have something like this:

Code: Select all

on mouseUp
   put "speed 255,0,0_risk 0,255,0_danger 0,0,255" into myColorArray
   split myColorArray by "_" and " " 
   repeat with x = 1 to number of fields 
      put 0 into myCounter 
      repeat for each word myWord in fld x 
         add 1 to myCounter 
         if myWord is among the keys of myColorArray then 
            set the foreColor of word myCounter of fld x to myColorArray[myWord] 
         end if 
      end repeat 
   end repeat
end mouseUp
However I'd also need to colourize some speeds ie 120mph, 55mph, 20mph etc. How can I create a "if >= then" structure with the array?

Thanks also Bernd - nice "items" based solution.

Cheers

Jim

Posted: Mon Aug 24, 2009 9:07 pm
by bn
Jim,
if you do not have a space between 120 and mph then you can just add it to the array

Code: Select all

 put "120mph 0,255,0_speed 255,0,0_risk 0,255,0_danger 0,0,255" into myColorArray
regards
Bernd

Posted: Mon Aug 24, 2009 9:24 pm
by hamlynart
Hi again Bernd,

That's right the speeds are not separated but what I'd like to do is read the any random speed, evaluate if it is higher than say 40mph and then colour it red.

I could type each speed in manually, which is what I was intending to do, but I'm guessing there's a more elegant way?

Best

Jim H

Posted: Mon Aug 24, 2009 9:37 pm
by bn
Jim,
you could add a line:

Code: Select all

  if myWord ends with "mph" then set the forecolor of word myCounter of fld x to "255,127,127"
that would set every word that ends with mph to the color indicated. There are not terribly many words that do that to my limited knowledge of the English language. (umph comes to mind).
Unless you want a color scheme for different speeds....
regards
Bernd

if you dont like umph to be colored try:

Code: Select all

 if myWord ends with "mph" and char 1 to -4 of myWord is a number then set the forecolor of word myCounter of fld x to "255,127,127"
regards
Bernd

Posted: Mon Aug 24, 2009 9:42 pm
by hamlynart
Triumph!

That's just all I think I need to work out how to do it.

Thanks a million

Jim H

Posted: Mon Aug 24, 2009 9:55 pm
by bn
Jim,
I forgot that you only wanted the speeds above a certain limit to be colored:

Code: Select all

 repeat for each word myWord in fld x 
            add 1 to myCounter 
            if myWord is among the keys of myColorArray then 
                set the forecolor of word myCounter of fld x to myColorArray[myWord] 
            end if 
            if myWord ends with "mph" and char 1 to -4 of myWord is a number then 
                if char 1 to - 4 of myWord > 30 then
                    set the forecolor of word myCounter of fld x to "255,127,127"
                end if
            end if
        end repeat 
etc.
that should do it
regards
Bernd