Highlight Words in a Text Member
August 9, 2001
by Will Turnage
Dear Multimedia Handyman,
I have a project that acts as a text reader for files on people's computers. I want to add the option where you can search for a word inside the text that you're viewing. Is this hard? Do you know an easy way to do this?
Thomas
Dear Thomas,
If you want to hilight all of the words in a certain paragraph, then there are several ways you can do it. Some require using an Xtra, some don't. If your project uses a large amount of text and requires extremely fast searching capabilities, then you should consider using a third party database Xtra or the TextCruncher Xtra from updateStage. These Xtras are designed from the ground up for performing lightning fast text searches which might be much more appropriate for your particular project.
But if you don't have a lot of text and just want to do something quick, then you can do the text searching yourself in Lingo. The key is using the offset function to find your specific text inside a larger string. Unfortunately, offset only finds the first instance of a string inside the text. To find all instances, you have to write a routine to keep searching through the text string. A simple function to do so looks like this:
wordSearch = member ("searchWord").text
pMemRef = sprite (me.spriteNum).member
tempStr = pMemRef.text
hiliteList = []
counter = 0
repeat while offset (wordSearch, tempStr)
startChar = offset (wordSearch, tempStr)
endChar = startChar + wordSearch.char.count - 1
hiliteList.append ([counter + startChar, counter + endChar])
delete char 1 to endChar of tempStr
counter = counter + endChar
end repeat
The beginning of this function initializes a few variables. The first variable, wordSearch, contains the string that you are going to search for inside your text member. The next variable, tempStr, is a string of the text that you are searching through. Next you create an empty list called hiliteList. This list will be used later to store the absolute locations of your text. Finally, you set a variable named counter to zero. The counter variable will be used to keep track of your absolute position in the text you're searching through.
Once your variables are initialized, then you're ready to start searching for your word. You start by checking to see if your word exists inside the text string. If it does, then you find the exact location of where the word starts. Next you calculate the location of where your word ends in the text string. Then you take these two variables, and place them inside the hiliteList you created earlier. After you've done this, delete the first part of your text string up to the point where your search word was. On the next pass of the repeat loop, you're able to check for the next instance of your word rather than finding the same instance over and over. The last step is to increment the counter variable. This allows you to keep track of how much text you've deleted so that you have an absolute character location to use when highlighting the text later.
When this handler is done running, you're left with a list of number pairs. These number pairs represent the absolute location of your search word within your text member. So if you want to highlight all of these characters in a text member, then you could use a handler like this:
pMemRef.color = color (#rgb, 0, 0, 0)
repeat with i in hiliteList
pMemRef.char[i[1]..i[2]].color = color (#rgb, 255, 0, 0)
end repeat
This code starts by setting the color of all the text to black, effectively resetting any highlighting you had done previously. Then it repeats through your list of number pairs and sets the color of those characters to red. When that's done, all of your search words will be highlighted inside your original text field.
In case your projects needs something more specific, there are several variations on this function you could create. One possible enhancement is the ability to search for whole words only. To do that, you would just add the following code inside the original function.
flag = true
prevChar = tempStr.char[startChar - 1]
nextChar = tempStr.char[startChar + wordSearch.char.count]
charString = "abcdefghijklmnopqrstuvwxyz"
if charString contains prevChar or charString contains nextChar then
flag = false
end if
if flag then
hiliteList.append( [counter + startChar, counter + endChar] )
end if
This code starts by getting the character located before and after the search term within the text you're searching. It checks to see if either one of these characters is a letter, and if it is, then it sets a flag so that the location of your search word isn't added to the master list of numbers.
The final result looks something like this:
A sample Director 8 movie is available for download in Macintosh or Windows format.
Copyright 1997-2024, Director Online. Article content copyright by respective authors.