Re: Unwinding the containment hierarchy of a reference
Re: Unwinding the containment hierarchy of a reference
- Subject: Re: Unwinding the containment hierarchy of a reference
- From: Michael Terry <email@hidden>
- Date: Sat, 11 Dec 2004 12:20:09 -0800
On Dec 8, 2004, at 3:31 PM, Paul Berkowitz wrote:
If you wanted to
create a more universally useful handler, and have it work with
multiple
applications, that'd require some extra work. For example, some
objects might
be specified with a name reference, so could contain the " of "
string.
I don't follow here.
I mean that if you wanted to make a routine which used vanilla AS to
parse an object specifier, you'd have to be careful not to treat all
cases of " of " in the entire object specifier string the same. If the
application supports name references, e.g., Finder, " of " could appear
in the specifier, and breaking on " of " in the name string would be a
problem.
So I decided to try to write a general handler that would return all
the specifiers--from the bottom to the top--given some reference.
Problems encountered:
1. Evaluating references--even references fully qualified up to the
application object--in the 'run script' context resulted in having the
root application object lopped off, and were unusable. So, you'd get
back:
word 1 of document 1
... rather than:
word 1 of document 1 of application "TextEdit"
And even if you tried to use them in an application 'tell', they still
didn't work.
One way to avoid that is the way you did it, getting the application
reference first, then doing the 'run script''s inside it:
On Dec 9, 2004, at 9:42 AM, Paul Berkowitz wrote:
set appRef to run script "application \"TextEdit\""
--> application "TextEdit"
tell appRef
set docRef to run script "ref to document 2"
--> document 2 of application "TextEdit"
set wordRef to run script "ref to word 12 of document 2"
--> word 12 of document 2 of application "TextEdit"
set wordRef to run script "ref to word 12"
--> word 12 of application "TextEdit"
end tell
2. When evaluating a list of references inside 'run script' that point
to AS types, the contents would always be returned, no matter how many
'ref to''s you prefixed them with:
run script "{ref to word 1 of document 1 of app \"TextEdit\"}"
--> {"hello"}
-----
It turns out, though, that both those problems are neatly solved by
returning a script from 'run script', so that you can do the
evaluations in the original context. My routine was taking like a half
second or more to run before incorporating this technique. So, here's
the handler:
--
on parseObjSpec(objSpec)
try
objSpec as reference
try
set objSpec to ({hack:objSpec} as string)'s text from character 8 to
end
on error eMsg
set objSpec to eMsg's text from character 18 to -17
end try
-- scan for delimiter matches
set {noMatch, fullMatch, matchedSoFar, quote, backslash, escaped} ¬
to {"", " of ", "", "\"", "\\", false}
set {eachAncestor, scanningOutsideOfStrings} to {"", true}
repeat with thisPos from 1 to objSpec's length
set thisChar to objSpec's character thisPos
if scanningOutsideOfStrings then
set matchedSoFar to matchedSoFar & thisChar
if matchedSoFar is fullMatch then
set eachAncestor to eachAncestor & ", ref to" & objSpec's text
thisPos thru end
set matchedSoFar to noMatch
else if fullMatch does not start with matchedSoFar then
set matchedSoFar to noMatch
if thisChar is quote then set scanningOutsideOfStrings to false
end if
else
if thisChar is quote then
if not escaped then set scanningOutsideOfStrings to true
set escaped to false
else if thisChar is backslash then
set escaped to not escaped
end if
end if
end repeat
return run (run script "script
{" & "ref to " & objSpec & eachAncestor & "}
end")
on error eMsg number eNum
error "parseObjSpec can't continue: " & eMsg number eNum
end try
end parseObjSpec
--
tell application "TextEdit" to get a reference to word 1 of document 1
parseObjSpec(result)
--> {word 1 of document 1 of application "TextEdit", document 1 of
application "TextEdit", application "TextEdit"}
It should work with standard canonical object specifiers returned by
most applications, such as ID, index, and name reference forms. That's
what I wanted it for anyway. If one intended to pass it any old
reference one could make up, it will surely fail on complex, compound
specifiers. I can't think of a good reason to do that, so I didn't
bother accounting for it.
I ran the following tests on it:
set testResults to {}
-- uses id reference form
tell application "Address Book" to get my card
set end of testResults to parseObjSpec(result)
-- uses index reference form
tell application "iCal" to get some calendar
set end of testResults to parseObjSpec(result)
-- uses name reference form with folder name containing
-- quote and " of "
tell application "Finder"
tell (make folder with properties {name:"\"Hall of Fame\""})
set end of testResults to my parseObjSpec(it)
delete it
end tell
end tell
-- reference to object that evaluates as AS built-in type
tell application "TextEdit" to get a reference to word 1 of document 1
set end of testResults to parseObjSpec(result)
set end of testResults to get contents of first item of result
-- invalid argument
try
parseObjSpec(7)
on error eMsg number eNum
set end of testResults to (eNum as string) & ": " & eMsg
end try
return testResults
--> {{person id "4909FCE2-AD59-11D8-9D0D-000393D8A740:ABPerson" of
application "Address Book", application "Address Book"}, {calendar 5 of
application "iCal", application "iCal"}, {folder "\"Hall of Fame\"" of
folder "Desktop" of folder "ellyagg" of folder "Users" of startup disk
of application "Finder", folder "Desktop" of folder "ellyagg" of folder
"Users" of startup disk of application "Finder", folder "ellyagg" of
folder "Users" of startup disk of application "Finder", folder "Users"
of startup disk of application "Finder", startup disk of application
"Finder", application "Finder"}, {word 1 of document 1 of application
"TextEdit", document 1 of application "TextEdit", application
"TextEdit"}, "hello", "-1700: parseObjSpec can't continue: Can't make 7
into a reference."}
Michael
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Applescript-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden