Page 1 of 2
Whole word selection in field
Posted: Thu Jun 11, 2009 6:11 pm
by WaltBrown
Hi! I'm sure this has been asked but I couldn't find it in the forums.
I want to return the whole words when text is selected in a locked field. I have this in the field:
Code: Select all
on dragMove
select the mouseText
end dragMove
on mouseUp
answer the selectedText
end mouseUp
The user needs to be very careful to get the whole words this way. Has anyone seen a way to get the whole words if the user starts or ends in the middle of a word? I was wondering if there was a more elegant solution than:
Code: Select all
on mouseUp
put word 2 of the selectedChunk into tStartChar
put word 4 of the selectedChunk into tEndChar
put "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'-" into tTestString
// Move backward through the field to find the whole word start
put false into tFoundStart
repeat until tFoundStart = true
put char tStartChar of field fText into tChar
if tChar is not in tTestString then
put true into tFoundStart
else
subtract 1 from tStartChar
end if
end repeat
// Move forward through the field to find the whole word end
put false into tFoundEnd
repeat until tFoundEnd = true
put char tEndChar of field fText into tChar
if tChar is not in tTestString then
put true into tFoundEnd
else
add 1 to tEndChar
end if
end repeat
answer char tStartChar to tEndChar of field fText
end mouseUp
Thanks, Walt
Posted: Thu Jun 11, 2009 9:31 pm
by bn
Walt,
put this into the script of your field "ftext" (NoW is number of words)
Code: Select all
on mouseUp
put field "ftext" into tText
put the selectedchunk into tChunk
put word 2 of tChunk into tCharNumberStart
put word 4 of tChunk into tCharNumberEnd
-- if the user includes a trailing ,.?! in the selection then Rev counts that as word
if char tCharNumberStart of tText is in ".,?!" then add 1 to tCharNumberStart
put the number of words of (char 1 to tCharNumberStart-1 of tText) into tNoWUntilSelection
put the number of words of char tCharNumberStart to tCharNumberEnd of tText into tNoWSelection
put the number of words of char 1 to tCharNumberEnd of tText into tNoWStartTextUntilEndSelection
if tNoWSelection > 0 then
put word (tNoWStartTextUntilEndSelection - (tNoWSelection -1)) to tNoWStartTextUntilEndSelection of tText into ttheWords
else
put empty into tTheWords
end if
-- somehow rev takes a trailing .?! , as part of the word
if last char of tTheWords is in ".,?!" then delete last char of ttheWords
put "tNoWUntilSelection" && tNoWUntilSelection & return & \
"tNoWStartTextUntilEndSelection" && tNoWStartTextUntilEndSelection & return & \
"tNoWSelection" && tNoWSelection & return & return & \
"Words selected = " & return & tTheWords into tDisplay
answer tDisplay
end mouseUp
Your code works very well for me, but if you ask for an alternative then
this works also. But I just made this up as an exercise, I don't claim it to work flawlessly but in my limited testing it did. And I don't claim it to be 'better'/'faster' then yours. Just a little different approach.
please let me know how it works for you and if does what you want.
regards
Bernd
Posted: Fri Jun 12, 2009 3:52 am
by WaltBrown
Thanks, Bernd. I'll try yours too. I thought there might be an easier way.
On the regexp front, my automated version of this (for whole words, ie no human intervention) uses this (which I am currently experimenting with to simplify), which seems to work well in matchChunk for identifying whole words and ignoring partials, regardless of what adjacent byte codes exist:
(?i)([\s\r\n"&\(,-]+theWord[\s\x20\n\r!"&\)\x2C-\.:;\?]+)
For example, it will not find "and" in "hand" (since wholeMatches has no effect in matchChunk) or get confused if the word is preceded or followed by a control character or any punctuation. It's almost perfected

.
I tried using the regexp \w word and \c control character classes but I could not get matchChunk to like them.
Posted: Fri Jun 12, 2009 4:05 am
by WaltBrown
Simplified:
Code: Select all
// Move backward through the field to find the whole word start
repeat until char tStartChar of field fText is not in tTestString
subtract 1 from tStartChar
end repeat
// Move forward through the field to find the whole word end
repeat until char tEndChar of field fText is not in tTestString
add 1 to tEndChar
end repeat
Posted: Fri Jun 12, 2009 4:09 am
by WaltBrown
Minor correction at the end since the repeats need their last iteration rolled back:
answer char tStartChar+1 to tEndChar-1 of field fText
Posted: Fri Jun 12, 2009 10:05 am
by bn
Walt,
regarding regular Expressions: I find them hard to construct and maintain. I for my part am avoiding them. In my coding they never seem to do what I want. If I find a working long/complicated regex I admire it...
For the whole words in the selection:
One advantage of letting Rev do the finding of the whole words is that in languages other than english you would have to adjust your
Code: Select all
put "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'-" into tTestString
for each language, or if you dont know what language your dealing with you would have to provide a complete list of the possible ascii characters, that can make up words.
In my example (supposing it works correctly) it would be easy to adjust, because you only test for the punctuation marks. This would probably hold true for unicode.
Maybe some of the experts here on the forum have some insights to share.
regards
Bernd
Posted: Sat Oct 17, 2009 11:01 pm
by mtecedor
Hi,
I am trying to do something similar to what it was discussed in this topic. So I modified to fit my needs, but I still have one thing I cannot figure it out.
I want the user to be able to highlight chunks of text in a field (Text2). Then, I want these chunks to appear in another field (output). The selected chunks must appear in lines sorted in the order in which they appear in the original text, not in the order in which they were highlighted.
Everything works except when there is a change of paragraph. Then, some of the text appears at the beginning of the field (output). How can I tell revolution that it must obviate the space between paragraphs?
This is my code up until now:
on mouseUp
put hiliteCounter+1 into hiliteCounter
put word 2 of the selectedChunk into tStartChar
put word 4of the selectedChunk into tEndChar
put "1234567890.,¿!abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'-" into tTestString
put false into tFoundStart
repeat until tFoundStart = true
put char tStartChar of field Text2 into tChar
if tChar is not in tTestString then
put true into tFoundStart
else
subtract 1 from tStartChar
end if
end repeat
put false into tFoundEnd
repeat until tFoundEnd = true
put char tEndChar of field Text2 into tChar
if tChar is not in tTestString then
put true into tFoundEnd
else
add 1 to tEndChar
end if
end repeat
set backgroundColor of char tStartChar+1 to tEndChar-1 of field "Text2" to yellow
put tStartChar+1 & " " & char tStartChar+1 to tEndChar-1 of field "Text2" into line hiliteCounter of hilitedList
sort hilitedList numeric
put hilitedList into field "output"
repeat with i = 1 to the number of lines in field "output"
delete word 1 of line i in field "output"
end repeat
end mouseUp
I tried adding something like
if char is " "
then add 1 to tStartChar
but it gives me an error message.
Any idea on how I can add that detail?
Thanks
Posted: Sat Oct 17, 2009 11:34 pm
by Mark
Hey guys, why do difficult if you can do it easy? The following script only works in locked fields whose traversalOn is true.
Code: Select all
on mouseUp
put the selectedChunk into myChunk
put (number of words of char 1 to (word 2 of myChunk) of me) into myFirstWord
put (number of words of char 1 to (word 4 of myChunk) of me) into myLastWord
put myFirstWord && myLastWord
select word myFirstWord to myLastWord of me
-- now you can do with the selectedText whatever you like
end mouseUp
Best regards,
Mark
P.S. On second thought, I now see that Bernd's script is a slightly more complex version of what I just posted. Now I wonder why it is a problem that some characters are selected as if they are part of a word...?
Posted: Sat Oct 17, 2009 11:40 pm
by Mark
mtecedor,
I expect that your problem is solved by replaced returns with spaces before processing the selected text.
Code: Select all
-- replace myVar with your own var
put the selectedText into myVar
replace cr with space in myVar
-- your script follows here
Best regards,
Mark
Posted: Tue Oct 20, 2009 2:26 am
by mtecedor
Mark,
Thanks for the code, but it doesnt work exactly the way I want, becuase I would like to maintain the paragraphs in my "output field".
Right now, my code works perfectly if the user selects the end of one paragraph and the begining of the next one. Then, it messes everything up. It puts a cr and the begining of the second paragraph in the first line of my "output" field, when it should just keep it the way it appears in the original.
Any idea why this is happening?
Posted: Tue Oct 20, 2009 4:12 pm
by bn
Marta,
I modified your script to do what I --think-- what it should do:a user works on a text and can hilight words or parts of the text he wants. He can do so repeatedly and hilite stuff further up from where he hilighted before. You want this in a output list, one hilited selection on one line in the order it was in the text.
For speed I work mostly in variablesl, because accessing fields slows things down. If you click in the field with the optionkey (altkey) down it clears the counter etc. It is marked in the script.
Code: Select all
local hiliteCounter, hilitedList
on mouseUp
-- this is for debugging to reset the counter and the list and the hilites
-- you can take this out
if the optionkey is down then
set the backgroundcolor of char 1 to -1 of me to ""
put 0 into hiliteCounter
put "" into hilitedList
put "" into field "output"
exit mouseUp
end if
put hiliteCounter+1 into hiliteCounter
put word 2 of the selectedChunk into tStartChar
put word 4of the selectedChunk into tEndChar
put tStartChar && tEndChar
-- if the user clicks before the first word it selects the whole text
if tEndChar = 0 then exit mouseUp
put "1234567890.,¿!abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'-" into tTestString
put field "text2" into tTest
put false into tFoundStart
repeat until tFoundStart = true
put char tStartChar of tTest into tChar
if tChar is not in tTestString then
put true into tFoundStart
else
subtract 1 from tStartChar
end if
end repeat
put false into tFoundEnd
repeat until tFoundEnd = true
put char tEndChar of tTest into tChar
if tChar is not in tTestString then
put true into tFoundEnd
else
add 1 to tEndChar
end if
end repeat
set backgroundColor of char tStartChar+1 to tEndChar-1 of field "Text2" to yellow
put char tStartChar+1 to tEndChar-1 of tTest into tReplaceReturns
replace return with space in tReplaceReturns
replace space & space with space in tReplaceReturns
put tStartChar+1 & " " & tReplaceReturns into line hiliteCounter of hilitedList
sort hilitedList numeric
-- we leave the hilitedList alone and work on a copy of it
put hilitedList into tListToClean
repeat with i = 1 to the number of lines of tListToClean
delete word 1 of line i of tListToClean
end repeat
filter tListToClean without empty
put tListToClean into field "output"
end mouseUp
try this and let us know.
regards
bernd
Posted: Tue Oct 20, 2009 5:46 pm
by bn
Marta,
if you want to retain paragraphs in the output field then say so. The way it is now returns (which mark paragraphs) are taken out. That was the reason your original script did not work. You can not put things in "lines" and put a paragraph into that line, which will add a line.
If you want the paragraphs let me know.
regards
Bernd
Posted: Tue Oct 20, 2009 6:41 pm
by mtecedor
Bernd,
Thanks a lot for the code, it works pretty well, except that of course I dont have pragraphs in my output field. I looked in the user guide and in the dictionary for something related to that, but i havent found anything.
I also tried inserting a line if the original text contains return but it didn't work.
I would really appreciate it if you could give me a hand.
Marta
Posted: Tue Oct 20, 2009 6:47 pm
by bn
Marta,
replace the bottom part.
Code: Select all
set backgroundColor of char tStartChar+1 to tEndChar-1 of field "Text2" to yellow
put char tStartChar+1 to tEndChar-1 of tTest into tReplaceReturns
-- take returns out so it won't break the lines of the hilitedList
replace return with "|" in tReplaceReturns
put tStartChar+1 & " " & tReplaceReturns into line hiliteCounter of hilitedList
sort hilitedList numeric
put hilitedList into field 3
-- we leave the hilitedList alone and work on a copy of it
put hilitedList into tListToClean
repeat with i = 1 to the number of lines of tListToClean
delete word 1 of line i of tListToClean
end repeat
-- remove empty lines
filter tListToClean without empty
-- put the returns back in
replace "|" with return in tListToClean
put tListToClean into field "output"
end mouseUp
it inserts a 'pipe' or | instead of a return in the hilitedlist. This is than turned back into a return in the tListToClean
regards
Bernd
I noticed I had included a line of code that puts the selected chars into the message box, you might want to delete the line
Posted: Wed Oct 21, 2009 3:30 pm
by mtecedor
Thanks Bernd, that helped a lot