Since we learned about file paths, external files, and the URL keyword in the last lesson, we can now introduce a new way of accessing remote stacks from anywhere on the internet. If you have LiveCode running, and you have a connection to the internet, you can open any stack on any web server, simply by referencing its URL. For instance, there is a stack called "TextLecture.rev" on this web server at the address:
http://livecode.byu.edu/textfind/TextLecture.revThis stack contains many examples of the concepts being discussed in this reading. To open this stack in LiveCode, simply enter this command in the message box:
go to stack URL "http://livecode.byu.edu/textfind/TextLecture.rev"LiveCode will find it on the internet and download it into memory on your computer. When you're finished with it you can simply close it, or you can choose to save the stack to your local disk.
For the remainder of the term you will often see references to example stacks in the readings. Any of those stack references can be accessed as described above.
By the end of this reading you should know the following:
The example stack for this section can be accessed at
http://livecode.byu.edu/textfind/TextLecture.rev. To access it enter in the message box:
go to stack URL "http://livecode.byu.edu/textfind/TextLecture.rev"
LiveCode recognizes the basic units of text: characters, words, lines, etc. While our human definition of these units can be a bit fuzzy, LiveCode defines these terms in a precise way:
A "chunk" is LiveCodes generic term for a substring of a longer text string; i.e., runs of text described by the units characters, words, lines, etc. You refer to chunks of text by specifying the sub-units as needed. For example, the statement
select word 5 of line 3 of field "myField"
will highlight the fifth word of the third line of the field.
LiveCode recognizes the ordinals first through tenth, which means that
fourth word = word 4 (i.e., they are functional equivalents, the former being somewhat more readable). NOTE: It is not
the fourth word ("the" cannot be used; it will result in a horrible error).
Other forms in the same class provide some extra capabilities:
the middle word of "red yellow green mauve"is "green")
You can specify a range of text using the
to keyword. For example,
word 5 to 7 or
char 14 to 29. Note that you do not repeat "word" (e.g., you don't say
word 5 to word 7 and you do not use an "s" in the character range (e.g., you don't say
chars 14 to 29 but you do say
LiveCode provides some useful functions you can use to handle text
put the length of line 12 of field "whatever". Note: "the" is required before length in this construct.
the number of lines in field whateveror
the number of words of field whateverin this construct. The prepositions
ofare completely interchangable in this context.
put offset("crown",field "whatever") into myVarwhere "crown" is the string you are looking for and field "whatever" is the container you are searching in.)
Note the following features of the
There are three other related offset functions:
These all work the same as
offset, except instead of returning the number of characters from the beginning of the search container, they return the number of items, lines, or words, respectively, from the beginning of the string to the first occurrence of the search string. These functions are extremely useful, for instance, for discovering what line in a container a certain word is found on. The offset functions are also the only way to search for strings in variables rather than fields.
Here is an example of the use of the
Problem: find the first line where the word "red" appears in field "colors". Let's say the field "colors" contains the following:
blue pink orange green red black yellow
put lineOffset("red",fld "colors") into theLine
will return the value 5 to the variable
But what if you want to find just the whole word "red" in a field with the following contents:
blue pink reddish orange orange green red black yellowThe statement above would match line 3 first instead of line 6. To force the
lineOffsetfunction to only match lines where the word "red" appears by itself, use the
set the wholeMatches to true put lineOffset("red",fld "colors") into theLineNow the result returned is 6, as desired, rather than 3. Keep in mind that the
wholeMatchesproperty only keeps its value for the duration of the current handler. When the handler ends,
wholeMatchesis set back to false. This property also works with the
wordOffsetfunctions in cases where you only want to find items or words that exactly match the search string.
There are several boolean operators that allow you to make true/false comparisons between strings or containers holding strings:
is not in
is not among
The text boolean operators
is in and
contains allow you to test for a pattern in a text string. Both have the same purpose and they reflect the logic of English syntax. For example, the expressions:
if "bob" is in fld 1 then beep
if fld 1 contains "bob" then beep
say exactly the same thing. Case is ignored (it can be capitalized in the field and not capitalized in your script), but accents are not. Spaces and punctuation are not ignored, either. It handles
empty in a predictable way: a field with anything at all in it does not contain
The inverse of
is in is the operator
is not in.
begins with and
ends with are similar to the
contains operator, except that they only report true is the string you're testing for comes at the very beginning or the very end of the string being checked.
put "My dog has fleas." into tRover
if tRover begins with "my dog" then -- this condition is true
put "Get me a ." into field "dog" end if if tRover ends with "fleas" then -- this condition is false because the sentence ends with a period--"...fleas." put "flea collar!" after field "dog" end if
is among and
is not among allow you to check for the presence of text strings by looking at specific text chunk types. For example, referring to the color list example above, if I wanted to know whether one of the lines contained exactly the string "red" I could use:
if "red" is among the lines of field "colors" then
This would only be true if one of the lines of field "colors" held exactly the word "red", with nothing else on the line.
You can also use
is [not] among with the chunk types
items. The expression:
"hello" is among the items of field "stuff"
true if field "stuff" contained this text:
but would return
false if field "stuff" contained this text:
The negative expression:
"world" is not among the words of field "otherstuff"
true if field "otherstuff" contained the text
"many wordly pleasures";
but would return
false if field "otherstuff" contained
"The pleasures of the world beckon."
An example stack for the find command, selection functions and click functions sections can be viewed by entering in the message box:
go stack URL "http://livecode.byu.edu/textfind/FindLecture.rev"
In most cases the offset functions described above provide all the search capability you need. However, there may be some cases when you need to specify very exacting search requirements, such as the need to search for two words in some text that are not adjacent to each other. In these cases you may want to look at the find command. The find command is a formal LiveCode command used to locate a certain string or strings in the fields within a stack. This is the basic syntax:
find [form] <textToBeFound> [in field]
[form] is any of the form words described below.
<textToBeFound> is any expression that evaluates to a string.
[in field] a specfic field optionally specified in which the search will be confined.
When the command is executed, LiveCode places a box around the first instance of the string that it locates. It keeps track of latest find, and subsequent finds continue from most recent. Otherwise it begins with the first field on the current card. The command follows a certain hierarchy as it searches: first, grouped fields in order; second, non-grouped fields in order; then on to subsequent cards.
As stated earlier the search can be confined to a specific field. When no field is specified, LiveCode finds the first occurrence in search order. With a field specified, then the search is confined to that field alone. If not found and the field is part of a group, then it continues searching that field on subsequent cards.
find empty clears the current find operation, meaning a subsequent search will begin all over again in the search hierarchy, rather than beginning from the most recently found text. Consequently, the box drawn around the text found is removed.
There are five forms of the find command:
Find uses a complex technique to speed searching through large amounts of data. However, its behavior with the different forms may seem somewhat peculiar when the search text consists of more than one word (i.e., it contains a space). With normal, chars, and word, LiveCode breaks the search into words and performs a subordinate search as necessary: It looks for first word and then looks for the second word within same scope. That is, if a field is specified, they must be in the same field; otherwise they can be present on the same card for the search to be successful. Note: the found word rectangle is placed only around the first word. The other two forms (string and whole) do not break this way (but also do not take full advantage of search speed).
The find command, if successful, results in a box being drawn around the text found. This is done to give a visual indication of where the found text is on the card. Often we also want access in a script to the chunk of text that was found. Several functions exist to achieve that end:
If the search is not successful (i.e., the text was not found), then
not found is returned in the
While the text chunk may have been found, it is not automatically selected; i.e., you cant cut, copy, paste, etc. In order for that to happen, you must use the
select command, like this:
select the foundChunk
This command selects a chunk of text the same as if you clicked in the field and dragged the mouse across the text. You can then cut/copy/paste, etc. You can use the select command as long as the field's
traversalOn property is true (indicated by the "Focusable" checkbox in the field property inspector,) even if the field is locked.
Several functions give access to the selected chunk. They are similar to the found functions:
You can select the entire contents of a field, but not with
select field, as this selects the field just as if you had clicked on it with the edit tool (e.g., to edit its properties). To accomplish the former you must use:
select the text of field "whatever"
You can also use
select before or
select after to exert greater control over where the insertion point is placed in the text. The selection functions can be used in conjunction with the found functions to find and copy a string or unit:
select the foundChunk put the selectedText into thisVariable
Note that for all of these functions,
the is required.
Click functions are a set of functions similar to found and selected functions. They return information from clicks on a locked text field:
the clickText, words are delimited by punctuation in addition to space, tab, and return.
The values, of course, vary depending upon what is clicked. Note that some of the functions are empty in special cases: clicking on a space, clicking at the end of a line, clicking in an empty field, etc.