Just for fun and learning, I am rewriting the scripts from " the Tao of Applescript" by Derrick Schneider. It was written 10 years ago and it seem Applescript has changed a lot since then.
In this example I am numbering paragraphs in TextEdit. Now I am wondering why can’t I count paragraphs witin the “tell document” statement?
Please read the comments! Can anyone explain?
--why do I have to count paragraphs here on app level
--with trial and error I came to this solution
tell application "TextEdit"
set x to (the number of paragraphs of text of document 1)
end tell
tell document 1 of application "TextEdit"
--why on earth can't I count paragraphs here on doc level
--set x to (the number of paragraphs of text of document 1)
--I get NSCannotCreateScriptCommandError
activate
repeat with i from 1 to x
make word at beginning of paragraph i with data (i as string) & ". "
end repeat
end tell
I would prefer to have one "tell’ statement in stead of two…
Your second “tell” block doesn’t work because you are already targetting to “document 1”, so you can’t ask to “document 1” about the number of paragraphs of “document 1” (which is not an element contained by it). Perhaps some apps will understand and handle this situation without bothering you, scripter, but not TextEdit.
I would rewrite as follow:
tell application "TextEdit"
tell document 1
repeat with i from 1 to number of paragraphs of its text
make word at beginning of paragraph i with data (i as string) & ". "
end repeat
end tell
end tell
‘text’ is both an object and a property. I think they messed it up right about here.
Anyway, the reason you use nested tell statements like this is so you won’t need to write ‘of document 1’ over and over again in your references. Since ‘text’ is both a property and object (needs a reference), you can use ‘it’ in the tell document 1 block to show that it’s a reference:
tell application “TextEdit”
activate
tell document 1
set x to (number of paragraphs of text of it)
repeat with i from 1 to x
make word at beginning of paragraph i with data (i as string) & ". "
end repeat
end tell
end tell
I do not fully grasp the “scope” of a tell statement yet.
For example this bubble sort:
(a TextEdit document contains:
9
4
2
1
6
8
)
tell document 1 of application "TextEdit"
activate
copy every paragraph to thelist
repeat ((the number of items in thelist) - 1) times
repeat with i from 1 to ((the number of items in thelist) - 1)
if item i of thelist comes after item (i + 1) of thelist then
copy item i of thelist to temp
set item i of thelist to item (i + 1) of thelist
set item (i + 1) of thelist to temp
end if
end repeat
end repeat
-- why do I have to type:
----> set the text of document 1 of application "TextEdit" to (thelist as string)
--the text is within the scope of "tell document"
--so the next line should work!
----> set the text to (thelist as string)
--but it give me a syntax error!!!
end tell
then your answer gave me this idea:
set its text to (thelist as string)
And this works!?! But why?
I find this concept very hard to grasp, it is very elusive!
Here’s another example using the Finder. ‘container’ is both a property and an object of ‘folder’. When you try to get the ‘name’ of the container, you need ‘it’ in the tell block:
set the_folder to choose folder
– change to a Finder reference
set finder_ref to item (the_folder as string) of application “Finder”
tell application “Finder”
tell finder_ref
display dialog (name of container of it) as string
try
get name of container
on error err_mess
display dialog err_mess
end try
end tell
end tell